PLATEAUのDEMファイルに空中写真のテクスチャを貼りたい

## はじめに

国土交通省都市局の [PLATEAU](https://www.mlit.go.jp/plateau/) プロジェクトで公開されているデータは、社会的課題の解決や新しいサービスの創出といった当初の目的の範囲を超えて、映像作品やWebコンテンツの素材としても利用されるなど、様々な分野での利用が進んでいます。

PLATEAUで公開されているデータには、建物や橋梁のデータのほか、道路や標高、土地利用などのデータも含まれています。その中で、建物(bldg)のLOD2データや橋梁(brid)データはテクスチャが貼られていますが、道路(tran)や標高データ(dem)にはテクスチャが貼られていません。
そこで今回は、demデータを使用して地形図の3Dメッシュを作り、さらに国土地理院が公開する空中写真をテクスチャデータとして使用し、3D表示用のデータを作成してみたいと思います。

## PLATEAUの公開データのタイプ

PLATEAUでは、全国56都市のデータが公開されていますが、東京23区とそれ以外では公開されているデータのフォーマットが異なります。

| 地区 |公開データ種別 |
|:-|:-|
| 東京23区  | CityGML, 3DTiles/GeoPackage/JSON, FBX, OBJ, GeoTIFF |
| その他　  | CityGML, 3DTiles/GeoPackage/JSON, Shapefile, GeoTIFF, 他 |

実際にどのフォーマットのデータが公開されているかは、地区によって異なりますが、共通しているのはCityGMLと3DTilesです。CityGMLは[OGC (Open Geospatial Consortium)](https://www.ogc.org) の標準フォーマットであり、PLATEAUの要である都市活動情報を記述するデータとして作成されています。また、3DTilesはPLATEAUのWeb上でのプレビューアーである [PLATEAU VIEW](https://www.mlit.go.jp/plateau/app/) での表示用のデータとして作成されていると思われます。

東京23区については、FBX, OBJフォーマットが公開されており、CADや3D-Modelerに読み込んで編集を行えたり、UnityやUnrealEngineのアセットとして利用することが容易に(?)行えます。
一方、その他の地区については、CityGMLや3DTiles等のGIS系のデータを扱えるツールを使用する必要が出てきます。
PLATEAUでは、東京23区のFBX/OBJデータを生成するのに [FME-Desktop](https://www.safe.com/fme/fme-desktop/) というソフトウエアを使用しており、CityGMLからFBX/OBJに変換するためのワークフローファイルも[Githubで公開](https://github.com/Project-PLATEAU/Data-Conversion-Manual-for-3D-City-Model) されています。

## DEMデータ

DEM(Digital Elevation Model)データは、地表面を等間隔の正方形に区切り、それぞれの正方形に中心点の標高値を持たせたデータです。等間隔メッシュで標高データが並んでいるので、ビットマップのようなデータになります。
下図は、PLATEAUの東京23区のFBX(３次メッシュ)データで、533946番のデータをダウンロードし、Zipファイルを展開した中に含まれるdem.zipを更に展開すると含まれるFBXファイル(533946_dem_6677.fbx)を、Mac上で[bim.aero](https://www.iluac.com/bim.aero/)を使用して表示したものです。
![sshot-bim.aero.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183092/fa9182dc-ab56-8afe-68b4-22d4cc5f51f1.png)

見て分かる通り、テクスチャが貼られていないポリゴンメッシュ(実際には三角形メッシュ)となっています。ここに、空中写真のテクスチャを貼り付けたい、ということです。

## CityGML→3Dメッシュデータへの変換
東京23区以外では、基本的にFBX/OBJファイルは提供されていないので、CityGMLファイルを3Dメッシュデータに変換する必要があります。
ここではPLATEAUプロジェクトでも使用されていたFME-Desktopを使用して、DEMのCityGMLファイルをFBXに変換してみます。FME-Desktopは商用ソフトですが、無料のパーソナルユース・ライセンスがあるので、今回はそれを利用しました。

FME-DesktopによるCityGML→{FBX, OBJ}の変換は、PLATEAUのページで公開されている[3D都市モデルの変換マニュアル](https://www.mlit.go.jp/plateau/file/libraries/doc/plateau_doc_0007_ver01.pdf)の記載に基づいて行います。
(詳しいやり方は変換マニュアルを参照してください。)

まず、変換を行いたいCityGMLデータを[G空間情報センター](https://www.geospatial.jp/ckan/dataset/plateau)からダウンロードし、zipファイルの展開を行います。展開すると、次のようなディレクトリが作られます。
```<ルートディレクトリ>
　 └─ udx
　　　 ├─ bldg
　　　 │　　└─ xxx.gml, ...
　　　 ├─ dem
　　　 │　　└─ xxx.gml, ...
　　　 ├─ tran
　　　 │　　└─ xxx.gml, ...
　　　 └─ ...
```
zipファイル名と同じ`<ルートディレクトリ>`配下に`udx`ディレクトリがあり、その配下に`bldg`や`dem`等のディレクトリがあって、それぞれの配下にCityGMLファイル(.gml)やその付属ファイルが置かれています。`bldg`が建物のデータ、`dem`が標高データで、その他データが作成された目的などに応じてさまざまな種別のデータが含まれます。
zipファイルの中身を全て展開するとかなり大きなサイズになるので、注意が必要です。また、全てのデータを変換する場合はかなりの時間がかかるため、変換前に必要なデータ以外は削除しておく方が無難です。

次に、Github上で公開されているFME-Desktopのワークフローファイルを取得します。以下のコマンドを実行してください。
```$ git clone https://github.com/Project-PLATEAU/Data-Conversion-Manual-for-3D-City-Model
$ cd Data-Conversion-Manual-for-3D-City-Model/Sample\ Workspace
```
このディレクトリにある`citygml2fbx.fmwt`(FBX変換用)または`citygml2obj.fmwt`(OBJ変換用)を、FME-Desktop(FME Workbench)で開くと、下図のようなウインドウが表示されます(ここでは`citygml2fbx.fmwt`を開いています)。
![FME.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183092/8b8b9f33-565c-302e-ec03-f0c53dfdf7e3.png)
ここで、図中の赤線で囲まれた各項目(`Input: bldg [CITYGML]`, `input: dem [CITYGML]`, `Output: bldg_lod2 [FBX]`, `Output: bldg_lod1 [FBX]`, `Output: dem [FBX]`)について、それぞれマウス右ボタンクリックで表示されるメニューから`Edit '項目名' Parameters`を選択すると表示されるウインドウの"Source"または"Destination"パラメータに、入力ファイルが置かれたディレクトリ(`bldg`および`dem`)または変換後のFBXファイルを出力するディレクトリを指定します。
5項目全て設定し終えたら、ウインドウ上部の▷(Run)ボタンをクリックすると、変換が実行されます(結構時間がかかります)。

`Output: dem [FBX]`で指定したディレクトリ配下のdem.fbxと、`Output: bldg_lod2 [FBX]`配下のlod2.fbxを重ねて表示すると、下図のようになります(松本市中心市街地；bim.aeroでの表示)。
![sshot1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183092/1516b437-a35b-00ae-6831-b417107eae86.png)
LOD2のモデルにはテクスチャが設定されているのですが、DEMにはテクスチャが無いので、グレーの地面の上に建物が浮かんでいるような印象になってしまいます。

## テクスチャデータの取得

ようやく本題です。DEMの3Dメッシュデータに、空中写真のテクスチャを貼ります。
空中写真のテクスチャデータには[地理院タイル](https://maps.gsi.go.jp/development/ichiran.html)を使用します。地理院タイルとは、[国土地理院](https://www.gsi.go.jp)が配信するタイル状の地図データです。
タイルは256x256のイメージデータで、標準地図や白地図、空中写真などの種類があります。タイルにはレベルという概念があり、レベル0が世界全体で、レベルが1上がるごとに解像度が縦横それぞれ2倍になります。レベルは最大18で、この場合タイルの一片の長さは北緯35度では約125mになります(合ってるかな?)。

タイルは以下のURLで取得できます。
`https://cyberjapandata.gsi.go.jp/xyz/{t}/{z}/{x}/{y}.{ext}`
ここで、ユーザが指定できる項目は以下のようになります。

| 項目 | 内容 |
|:-:|:-|
| `{t}` |  データ種別(`'std'`, `'blank'`, `'seamlessphoto'`, etc) |
| `{z}` | ズームレベル(0〜18) |
| `{x}` | タイル座標(X) |
| `{y}` | タイル座標(Y) |
| `{ext}` | ファイル拡張子(`'png'`, `'jpg'`; `{t}`に応じて決まる) |

今回は地理院タイルのうち、レベル18の空中写真を使用しますので、`{t}='seamlessphoto'`、`{z}=18`、`{ext}='jpg'`となります。
`{x}, {y}`については、国土地理院の[タイル座標確認ページ](https://maps.gsi.go.jp/development/tileCoordCheck.html#5/35.362/138.731)で緯度経度から調べることができます。
ちなみに、DEMファイルの緯度経度範囲については、CityGLMファイル中の`<gml:lowerCorner>`および`<gml:upperCorner>`の値から得ることができます。

通常、緯度経度範囲に含まれる地理院タイルは複数枚になります。
　＜例＞松本城天守閣付近
　`{x}`：231537〜231538
　`{y}`：102724〜102725
この例では画像は4枚だけですが、実際にはPLATEAUのサブタイル1枚分でも地理院タイルは数十枚必要になります(レベルを小さくすれば、枚数は減ります)。
これらの画像を`bash`の`for`ループで回して`curl`コマンドで取得し、[ImageMagick](https://imagemagick.org/index.php)の`montage`コマンドで縦横に繋げて一枚のイメージファイルにすると、テクスチャとして使えるようになります。

```#!/bin/bash
for x in {231537..231538}; do
  for y in {102724..102725}; do
    url=https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/18/${x}/${y}.jpg
    curl -o ${y}-${x}.jpg ${url}
  done
done
montage *.jpg -tile 2x2 -geometry 512x512+0+0 combined.jpg
```
`curl`で取得する際のファイル名で`{y}`を先にしているのは、`montage`コマンドに`*.jpg`で入力できるようにするためです。

## テクスチャマッピング

作成したテクスチャイメージをDEMのメッシュにマッピングする作業は[Blender](https://blender.jp)上で行いました。
Blenderの使用方法については色々なところで説明されているので、ここでは詳細な説明は省きますが、Blenderで`dem.fbx`を読み込み、全タイルを選択した状態でEdit Modeにし、真上から見た状態にしてUV設定から`Project from View(Bounds)`でテクスチャ座標の展開をした後、`UV Editing`で調整(拡大縮小/回転/平行移動)を行う、という感じです。
![blender.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183092/4080288e-76cb-f82b-561f-7d74ecacab28.png)

上手く位置の調整ができたら、FBXファイルにエクスポートしておきます。

## LOD2データと合成してみる
こんな感じになりました。
![sshot2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/183092/31f1cff1-bb28-0f9f-4e33-8d8c36d20782.png)
先に挙げたイメージと比べて、建物と地形が馴染んでいる...気がします。