0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PLATEAUの3D建物データを用途別に色分けして地図表示する

Posted at

PLATEAUの3D建物をMapboxで手軽に可視化する

こちらはtoggle engineer blogで2024年12月6日(金)にポストした記事です。

トグルホールディングスのグループ会社つくるAIの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の建物のレイヤーを追加するシンプルなモデルはこちらです。

初期ビュー
スクリーンショット 2024-12-01 18.19.20.png

レイヤー作成にはDeckGLを使います。
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地図の様子もご覧ください

Legend表示かつ3D建物レイヤーなしのMapbox
スクリーンショット 2024-12-01 18.23.16.png

  • 建物用途の種類が多いので、グループ分けをして、グループごとに色を決めました。
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
}

横浜市、川崎市、東京23区の対比と災害リスク情報
スクリーンショット 2024-12-01 18.24.14.png

PLATEAUデータの準備と注意点

データ変換時のプロセス

PLATEAUデータをWeb表示用に変換する際は、以下のステップが必要です:

  1. CityGML → GeoJSON変換
  2. 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で表示することで、以下のメリットが得られました:

  1. 開発期間の短縮

    • 一般的なWebフレームワーク(React)が使用可能
    • 豊富なサンプルコードやライブラリが利用可能(DeckGLのMVTレイヤーは事例豊富です)
  2. 運用コストの削減

    • ReactプロジェクトのpublicフォルダにPLATEAUの建物データを置くだけで済みます
  3. メンテナンス性の向上

    • Webの標準技術での実装
    • データの動的更新が容易
      • 描画エリアの拡大も、PLATEAUデータを変換して、publicに置くだけです

従来のゲームエンジンを使用した実装と比べ、より手軽にPLATEAUデータの可視化が実現できます。
ぜひ皆さんもMapboxでの実装を検討してみてください!

なお、私は10月からTypeScript, Reactを始めたばかりで、それまではPython中心にコーディングをしてきたので、TypeScriptのルールやマナーを知らず色々と苦労しましたが、このような地図が作成できました。
豊富なデータを提供してくださるPLATEAUプロジェクト、どんどん機能が拡充しているMapboxに、とてもとても感謝しております。
地図の沼へ、一緒にハマりましょう!

参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?