ポイントデータの3D地図表現が、Mapboxにあるようで無かったので作りました。
どんな時に使うの
棒グラフに地理情報を付けたい時に使えます。
例えば、「全国の展望台付きタワーの高さ」を比較する場合。
↓
↓ 比較する各地を、地図上に載せる時に使えます。
↓
実装例
今回はシンプルに、1層の棒グラフを地図に載せる方法を紹介します。
デモとソースコード
デモとソースコードは、こちらのリンク先に掲載しています。
要点の解説
今回の要点は、ポイントデータから3Dポリゴンデータを作る点です。
Mapboxにはポイントを直接3Dで表現するメソッドは無いのですが、3Dポリゴンを描画するメソッド自体はあります。
そこで、3Dポリゴンデータを作って描画しよう、という考えです。
なお、MapboxはGeoJSON形式であれば大概のデータをビジュアライズできるので、今回はGeoJSONで用意しました。
上記リンクに載せたソースコード内で該当するのは、次の部分です。
const qfs = mapObj.queryRenderedFeatures({ layers: ['tower_points'] }); const data = { "type": "FeatureCollection", "features": [] }; const radiusPX = 3; qfs.forEach(function (object) { const center = object.geometry.coordinates; let xy = mapObj.project(center); xy.x += radiusPX; let LL = mapObj.unproject(xy); LL = turf.point([LL.lng, LL.lat]); const radius = turf.distance(center, LL, { units: 'meters' }) + 0.00000001; object.properties.height = object.properties.full_value * 600; object.properties.base = 0; const options = { steps: 16, units: 'meters', properties: object.properties }; data.features.push(turf.circle(center, radius, options)); })
ざっくり言うと、ポイントデータで作った circle
レイヤーの円から円柱ポリゴンデータを作り、その円柱ポリゴンデータをGeoJSON形式にまとめる、という手順のコードです。
半径の計算や円柱の生成は、Turf.jsが担っています。
ここ以外のコードについては、大体 Mapboxの公式ドキュメント に載っているので、適宜調べてみてください。
もちろん、この記事への質問やコメントも歓迎です。
応用例
積み上げ表現
記事の初めにも載せた、積み上げ棒グラフ的な表現です。
Mapbox - Extruding circles (stacked) - bl.ocks.org
作りは単純で、色別にレイヤー分けした円柱を積み重ねて表示させています。
塗り分け表現
高さに合わせて、色を塗り分けた表現です。
Mapbox - Extruding circles (choropleth) - bl.ocks.org
d3.jsのカラースケールを使えば、簡単に高さに合わせた色を計算することができるのでオススメです。
グラデーション表現
円柱の縦方向にグラデーションをかける表現です。
Mapbox - Extruding circles (gradient) - bl.ocks.org
ただし、想定したグラデーション表現がMapboxの仕様になかった(参考)ため、これは円柱を多層に重ねた擬似グラデーション表現です。多層にしすぎると重くなるので注意です。