🙂

Mapbox Newsletter WEEKLY TIPSの解説 -「ボタンでレイヤーの色を変更」

2023/07/14に公開

はじめに

この記事は、先日配信されたMapbox NewsletterのWEEKLY TIPSで紹介されていた「ボタンでレイヤーの色を変更」についての解説です。このサンプルでは動的にPaintプロパティを変更する方法を例示しています。また、Newsletterの購読はこちらからお申し込みいただけます。

コードを確認

まずExamplesのコードを見に行きましょう。

日本語サイト

英語サイト

基本的に同じコードですが、英語版はスタイルがMapbox Light v11にアップグレードされているのでこちらを使用します。Mapbox Light v10ではデフォルトのプロジェクションがWebメルカトルであるのに対し、Mapbox Light v11ではGlobe(3D表示された地球)なので、印象がかなり異なります。

今回はコードが少し長めでドキッとしますが、順番に見ていけば大丈夫です。

HTML/CSS

まずHTMLを見ていきましょう。

以下は地図を表示するエレメントです。

<div id="map"></div>

以下は左上に表示されているコントロール部分です。

<div class="map-overlay top">
  <div class="map-overlay-inner">
    <fieldset>
      <label>Select layer</label>
      <select id="layer" name="layer">
        <!-- Each value matches a layer ID. -->
        <option value="water">Water</option>
        <option value="building">Buildings</option>
        <option value="triangles">Triangles</option>
      </select>
    </fieldset>
    <fieldset>
      <label>Choose a color</label>
      <div id="swatches"></div>
    </fieldset>
  </div>
</div>

CSSはコントロール部分のスタイリングなので省略します。

Mapの作成

次にJavaScriptのコードを見ていきます。以下のコードはいつも通り、Mapオブジェクトを作成しています。containerで地図を表示するHTMLエレメントのidを指定します。

const map = new mapboxgl.Map({
  container: 'map',
  // Choose from Mapbox's core styles, or make your own style with Mapbox Studio
  style: 'mapbox://styles/mapbox/light-v11', // style URL for Mapbox Light
  center: [12.338, 45.4385],
  zoom: 18
});

loadイベントでレイヤーを一つ作っています。このレイヤーは川の中にいくつかある黒い三角形を表現しているレイヤーです。いつもはaddSourceで先にソースを登録していますが、ここではaddLayer内で直接sourceを定義する方法を採用しています。

map.on('load', () => {
  // Add a custom layer that uses
  // a vector tileset source.
  map.addLayer({
    id: 'triangles',
    source: {
      type: 'vector',
      url: 'mapbox://examples.ckv9z0wgf5v7c27p7me2mf0l9-9wrve' // custom tileset
    },
    'source-layer': 'triangles',
    type: 'fill'
  });
});

次はコントロール部分のコードです。

swatchesは"Choose a color"の下に表示されているdevタグ(カラーパレット)の部分です。

const swatches = document.getElementById('swatches');

layerは"Select layer"の下のselectタグの部分です。

const layer = document.getElementById('layer');

devタグ(カラーパレット)に表示する色の定義です。

const colors = [
  '#ffffcc',
  '#a1dab4',
  '#41b6c4',
  '#2c7fb8',
  '#253494',
  '#fed976',
  '#feb24c',
  '#fd8d3c',
  '#f03b20',
  '#bd0026'
];

定義された色でループを回します。各色に対応したボタンを作成(document.createElement('button'))し、そのボタンがクリックされたときの挙動(swatch.addEventListener('click',()=>{}))を定義しています。このサンプルで最も大事なコードがこのクリックイベントの中で呼ばれているMap#setPaintPropertyです。このメソッドはレイヤーのPaintプロパティの値を動的に変更します。第一引数にレイヤーID、第二引数にプロパティ名、第三引数に値を設定します。ここでは第一引数はlayer.valueとなっていますが、これはselectタグで選択された値(water, building, triangles)が格納されています。第二引数はfill-colorなのでポリゴンの塗りつぶしの色を指定してます。第三引数はcolorなのでボタンの色がそのまま入ります。

for (const color of colors) {
  const swatch = document.createElement('button');
  swatch.style.backgroundColor = color;
  swatch.addEventListener('click', () => {
    map.setPaintProperty(layer.value, 'fill-color', color);
  });
  swatches.appendChild(swatch);
}

サンプルは長めでしたが本当に言いたいことはmap.setPaintProperty(layer.value, 'fill-color', color);の一行でした。

まとめ

Map#setPaintPropertyを使うと動的にレイヤーのPaintプロパティを変更できることがわかりました。

GitHubで編集を提案
マップボックス・ジャパン合同会社

Discussion