PLATEAUの3D建物をMapboxで手軽に可視化する
mapチームのエンジニアの火原です。 今回は、国土交通省が提供する3D都市モデルデータ「PLATEAU」を使って、Web上で3D地図を作成する方法をご紹介します。
ポイントは、従来のUnityやUnreal Engineではなく、Mapboxを使用したアプローチです。これにより、より手軽で低コストな実装が可能になります。
なぜMapboxなのか?
従来のPLATEAU可視化では、以下のような課題がありました:
- Unityの場合、WebGLビルドの容量が大きい
- Unreal Engineの場合、サーバーリソースが必要
- どちらも開発コストと実行環境の要件が高い
- 私はUnityもUnreal Engineも使ったことがないので、私にとって学習コストが高い
一方、Mapboxを使用すると:
- ブラウザだけで動作(追加のプラグイン不要)
- 軽量で高速な表示が可能
- Reactで実装可能
実装例
今回は、PLATEAUの建物用途に応じて建物を色塗りした地図を作成します。
- 地図の範囲は東京都23区、川崎市、横浜市にしてみました。
- マウスを建物の上に置くと、建物の情報が追加されるホバー機能もつけてみました。
- mapboxの地図を使うので、mapboxのアクセストークンが必要になりますが、無料の範囲でもたっぷり使えます。
1. 基本的なセットアップ
mapboxの地図に、PLATEAUの建物のレイヤーを追加するシンプルなモデルはこちらです。

PLATEAUのCityGMLデータをmapbox向けのMVTタイル形式に変換して読み込むことで、サクサク描画するようにしています。
// App.tsx import 'mapbox-gl/dist/mapbox-gl.css' import Map from 'react-map-gl' import DeckGL from '@deck.gl/react/typed' const MAPBOX_TOKEN = 'YOUR_MAPBOX_TOKEN' # 初期視点は東京駅に設定しました const INITIAL_VIEW_STATE = { longitude: 139.7670, latitude: 35.6810, zoom: 14, pitch: 45, bearing: 0 } export default function App() { const [viewState, setViewState] = useState(INITIAL_VIEW_STATE) const plateauLayer = usePlateauBuildingLayer('plateau-buildings') return ( <DeckGL viewState={viewState} onViewStateChange={({ viewState }) => setViewState(viewState)} layers={[plateauLayer]} controller={true} getTooltip={({object}) => object && ({ html: formatTooltip(object.properties) })} > <Map mapboxAccessToken={MAPBOX_TOKEN} mapStyle="mapbox://styles/mapbox/light-v10" /> </DeckGL> ) }
2. 建物用途による色分け
- 東京都23区は、2023年版で、建物のプロパティの'buildingDetailAttribute.0.detailedUsage'を参照して、建物用途の種類を決めて色を決めます。
- 川崎市は、2022年版で、建物のプロパティの'usage.0'を参照して、建物用途の種類を決めて色を決めます。
- 横浜市は、2023年版で、建物のプロパティには用途が記述されていないので、デフォルトで全て灰色で描画します。
legendはこんな感じにしました。
3D建物レイヤーを表示しないプレーンなMapbox地図の様子もご覧ください

- 建物用途の種類が多いので、グループ分けをして、グループごとに色を決めました。
const getBuildingUsage = (properties: BuildingProperties): string | undefined => { // 23区と川崎市で異なる属性名に対応 if (properties['buildingDetailAttribute.0.detailedUsage']) { return properties['buildingDetailAttribute.0.detailedUsage'] } if (properties['usage.0']) { return properties['usage.0'] } return undefined }
- 色設定は用途ごとにグループ化して管理:
export const PLATEAU_USEING_COLORS = { // 商業系は赤系統 商業施設: [235, 85, 85, 200], 事務所建築物: [235, 145, 145, 200], // 公共系は青系統 医療施設: [65, 105, 225, 200], 教育施設: [85, 120, 225, 200], // 住宅系は緑系統 独立住宅: [95, 185, 95, 200], 集合住宅: [115, 185, 115, 200] // ... }
3. 災害リスク情報の表示
建物の保持している情報には、災害リスク情報があります。
東京都23区、川崎市、横浜市の今回の対象エリアは、全て、災害リスク情報は保持していました。
建物によって、災害リスクがなしのものも、複数のものもあり、災害リスク情報の件数が決まっていないことを前提に対応します。
- 建物ごとの複数の災害リスク情報を効率的に取得:
const getAllDisasterRisks = (properties: BuildingProperties): DisasterRisk[] => { const risks: DisasterRisk[] = [] let index = 0 while (true) { const description = properties[`buildingDisasterRiskAttribute.${index}.description`] if (!description) break risks.push({ description, rank: properties[`buildingDisasterRiskAttribute.${index}.rank`], depth: properties[`buildingDisasterRiskAttribute.${index}.depth`], scale: properties[`buildingDisasterRiskAttribute.${index}.scale`] }) index++ } return risks }
PLATEAUデータの準備と注意点
データ変換時のプロセス
PLATEAUデータをWeb表示用に変換する際は、以下のステップが必要です:
- CityGML → GeoJSON変換
- GeoJSON → MVT(Mapbox Vector Tile)変換
この変換プロセスでは、特に以下の点に注意が必要です:
- 高いメモリ要求
- GeoJSON変換時に大量のメモリを消費
- 32GB以上のメモリを搭載したマシンでの作業を推奨
- MVT形式はタイルを作成するので、隣接区域はまとめて処理する必要があります
- データサイズ
- テクスチャを除いた建物データのみでも、MVTファイルは約2.4GB
$ du -sh public/mvt > 2.4G public/mvt
- データを以下の形式で置くだけで、サーバーを立てるような手間なく、建物が描画されます。
public/mvt/{z}/{x}/{y}.pbf. - ここがMVTタイル形式のメリットだと感じました。
CityGMLからMVTへの変換に関するtipsは、ニーズが高いようでしたら、別の機会に書かせていただきますね。
まとめ
PLATEAUの3D都市モデルデータをMapboxで表示することで、以下のメリットが得られました:
開発期間の短縮
- 一般的なWebフレームワーク(React)が使用可能
- 豊富なサンプルコードやライブラリが利用可能(DeckGLのMVTレイヤーは事例豊富です)
運用コストの削減
- ReactプロジェクトのpublicフォルダにPLATEAUの建物データを置くだけで済みます
メンテナンス性の向上
- Webの標準技術での実装
- データの動的更新が容易
- 描画エリアの拡大も、PLATEAUデータを変換して、publicに置くだけです
従来のゲームエンジンを使用した実装と比べ、より手軽にPLATEAUデータの可視化が実現できます。
ぜひ皆さんもMapboxでの実装を検討してみてください!
なお、私は10月からTypeScript, Reactを始めたばかりで、それまではPython中心にコーディングをしてきたので、TypeScriptのルールやマナーを知らず色々と苦労しましたが、このような地図が作成できました。
豊富なデータを提供してくださるPLATEAUプロジェクト、どんどん機能が拡充しているMapboxに、とてもとても感謝しております。
地図の沼へ、一緒にハマりましょう!
参考リンク
- PLATEAU:https://www.mlit.go.jp/plateau/
- Mapbox GL JS:https://docs.mapbox.com/mapbox-gl-js/
- deck.gl:https://deck.gl/
