Mapboxには、MarkerとLayerの概念があり、どちらもマップ上にポイントデータとして配置ができる。
この2つのアプローチ、何が違うのか?というのを公式を参照しながらまとめた。
本記事のコードは、Mapbox GL JSをラップしたreact-map-glを利用しています。
Marker
MarkerはポイントをDOM(HTML要素)として追加されます。
マップにデータソースを追加する必要がないため、CSSや画像、SVGなど簡単に追加・編集することができます。
クリックイベントなども個別に設定することができ、とても便利です。
サンプルコードを見ても、Marker毎にイベントや表示を簡単に変えることができます。
CirclePinコンポーネントを呼んでいる箇所に表示したい画像やSVGを入れるだけです。
<Marker
draggable={false}
longitude={wayPoint.LatLng.lng}
latitude={wayPoint.LatLng.lat}
anchor='center'
popup={popup({ lat: wayPoint.LatLng.lat, lng: wayPoint.LatLng.lng }, wayPoint.address)}
>
<CirclePin
onClick={() => {
console.log("Maker onClick!!")
}}
/>
</Marker>
Layer
Layerはsourceにdataを追加することで、マップのcanvas上にレンダリングされます。
DOMが生成されない分、描画コストが低く、大量データの表示に向いています。
いくつかのカテゴリ分けをするなどはLayerが向いてそうです。
Layerの更新(たとえば色など)をするときは、setPaintPropertyや、setDataで更新します。Layer単位で更新するため、簡単に全てのデータを更新することができます。
イベントの追加は少し工夫が必要です。クリック操作もマップのclickイベントを定義する必要があります。
queryRenderedFeaturesを利用して対象レイヤーを指定して検索をします。
map.on('click', e => {
const result = map.queryRenderedFeatures(e.point, { layers: ['circle-point'] })
})
}
サンプルコードでは、geojson形式のデータをポイントとしてマップに表示しています。
const unclusteredPointLayer: LayerProps = {
id: 'circle-point',
type: 'circle',
source: 'pointData',
paint: {
'circle-color': '#11b4da',
'circle-radius': 8,
'circle-stroke-width': 3,
'circle-stroke-color': '#fff'
}
}
<Source
id='pointData'
type='geojson'
data={featureCollection.current}
>
<Layer {...unclusteredPointLayer} />
</Source>
MarkerとLayerの違いを比較
データセットのサイズ
MarkerはDOMを作成するため、数百のマーカーを追加すると、動作が遅くなったり応答しなくなったりする可能性があります。
逆にLayerはキャンバス上でレンダリングされるため、数百を追加してもパフォーマンスには影響しずらいです。
いくつのデータをポイントとして描画するか?がMarkerとLayerを選択する一つの指標になります。
Maker or Layer ?
MarkerとLayerのどちらを選択したら良いのか、公式の一覧表です。
Capability | Markers | Layers |
---|---|---|
ローカルデータを任意の形式で表示可能 | ✅ | |
ローカルgeojsonデータを表示可能 | ✅ | ✅ |
ベクタータイルから表示可能 | ✅ | |
マップにsourceを追加する必要がある | ✅ | |
CSSでスタイル設定可能 | ✅ | |
スタイル仕様によるスタイル設定 | ✅ | |
数十点の表示に最適 | ✅ | ✅ |
数百点の表示に最適 | ✅ | |
個別に作成と更新 | ✅ | |
一括作成と更新 | ✅ |
Summary
個別に、インタラクティブに表示したいときはMarker、大量データで個別に変化しないのであればLayerが適しているとのことでした。
とはいえ、Layerもデータポイントが500000以上になる場合はクラスター表示にするなどしないと描画速度が重く感じます。
作りたいものの設計をしてから、Marker or Layerを選択しましょう。