アプリで使える日本国内の地形/建物の3Dモデルをつくる

  日本国内でも様々なデータが公開されるようになってきました。今回はこのうちプレゼン資料やXRなどにも利用できそうな地形データや建物データについてアプリケーションで利用しやすいWavefront OBJ (.obj)形式に変換することを試してみました。
  出力される.objファイルは、PowerPoint などの Microsoft Office 製品やUnityなどのゲームエンジン、各種3Dソフトウェアなどで開けるよう互換性を考慮しています(例えば、PLATEAUで配布されている.objファイルはそのままでは読めないアプリケーションがあります) ので、いろいろ活用してみてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/5c28a906-b016-e550-c8dc-360b77d90db8.png)


## 地形の3Dモデルを利用する

[地理院地図](https://maps.gsi.go.jp/)は、従来よりSTL, VRML, WebGL向けの3Dモデルを作成することができるようになっています。このうち他のアプリケーションで利用可能そうに見えるVRMLは、最近(2.79より新しい)のBlenderでは下記のようなエラーで開くことができなくなっています。このエラーは~~どうやら[しばらく修正されなさそう](https://developer.blender.org/T83428#1206406)なため~~3.0で修正されましたが、~~[GitHubで公開されている地理院地図のコード](https://github.com/gsi-cyberjapan/gsimaps)をOBJ形式で出力できるように[修正してみました](https://github.com/ksasao/gsimaps/commit/6500935bee2aad55be56fee52f0fb90601594219)。~~
2022年3月に[地理院地図](https://maps.gsi.go.jp/)にOBJ形式の出力がマージされましたので、ご利用ください。

```text
appearance_LoadTexture
   bpyima.use_clamp_x = not repeat_s
AttributeError: 'Image' object has no attribute 'use_clamp_x'

location: <unknown location>:-1
```

### 利用方法
1. ~~[https://ksasao.github.io/gsimaps/](https://ksasao.github.io/gsimaps/)~~ [地理院地図](https://maps.gsi.go.jp/) を開き、左上の**地図**をクリック、**写真**を選択、右上の**ツール**をクリック、右側のバーの**3D**をクリック、**カスタム**をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/d14c7020-2f3c-b31a-cf8c-fa4f3c09f8b7.png)
2. 緯度・経度の範囲を指定して **OK** をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/2db27467-5e1d-9b76-7fc6-183f3fe84bae.png)
3. 一番下にあるOBJファイルのダウンロードをクリックして、dem.obj, dem.mtl, texture.png の3ファイルを同じフォルダにダウンロード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/1d84dac1-3562-c3c6-351b-b1c014ec013d.png)
4. アプリケーションで開く

#### Windowsの場合
dem.obj をクリックすると 3Dビューアーが起動します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/6fc1f48b-4a0f-464a-d584-76ec7a1ce053.png)

#### PowerPoint の場合(他のMicrosoft Office製品でも同様)
dem.obj をドラッグ&ドロップすれば開けます。向きなどを調整可能です。PowerPointを保存すると、内部では .glb 形式で保持されます(.pptxの拡張子を.zipに変更して解凍し、ppt/media フォルダに格納)。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/c64950eb-2697-1012-cd94-bb3feee82f22.png)

#### Unity の場合
dem.obj, dem.mtl, texture.png を Project の Assets フォルダ以下にドラッグ&ドロップするとインポートできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/1d25bdb0-9983-08bf-6c6d-d27879b95893.png)


## Project PLATEAU の3D都市モデルを利用する

[Project PLATEAU](https://www.mlit.go.jp/plateau/) の [3D都市モデル](https://www.geospatial.jp/ckan/dataset/plateau)のうち、東京23区では、アプリケーションで利用しやすいFBX形式、OBJ形式のファイルが[提供されている](https://www.geospatial.jp/ckan/dataset/plateau-tokyo23ku)のですが、それ以外の都市では CityGML形式のみとなっています。そこで CityGML(bldg/dem)をOBJ形式に変換して表示するツールを[作成しました](https://github.com/ksasao/PlateauCityGmlSharp)。テクスチャにも対応しています。詳細な利用方法については[リンク先](https://github.com/ksasao/PlateauCityGmlSharp)を参照してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/a96ae126-8b91-27ca-cf32-657233bc7ff1.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43450/4ba9c990-d9b2-5e91-0426-16ca4484e533.png)

dem(地盤の高さを示す数値標高モデル)については前述の地理院地図のデータのほうが対応エリアが広く、また、テクスチャは別途用意する必要があるので、こちらをあえて利用する必要はないかもしれません。
なお、PLATEAU の CityGML に何種類かあるようでうまく変換されない可能性があります。そのような都市を見つけましたら [@ksasao](https://twitter.com/ksasao)までご連絡ください。

## (おまけ) 緯度・経度から住所を検索する

　住所から緯度・経度を求めることを**ジオコーディング**、緯度・経度から住所を検索することを **逆ジオコーディング** といいます。無料で利用可能なサービスとして、[国土地理院APIを利用したもの](https://www.google.com/search?q=%E5%9C%B0%E7%90%86%E9%99%A2%E5%9C%B0%E5%9B%B3+API+%E3%82%B8%E3%82%AA%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0&rlz=1C1CHZN_jaJP961JP961&sxsrf=AOaemvImfIoRcVn0NkzFVX_reMr6V4qquw%3A1638628545387&ei=wXyrYdr_FsWp2roPpKaQgAI&ved=0ahUKEwia5PaCr8r0AhXFlFYBHSQTBCAQ4dUDCA4&uact=5&oq=%E5%9C%B0%E7%90%86%E9%99%A2%E5%9C%B0%E5%9B%B3+API+%E3%82%B8%E3%82%AA%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0&gs_lcp=Cgdnd3Mtd2l6EAM6BwgjELADECc6BAgjECc6CQgAEIAEEAQQJToECAAQHjoGCAAQCBAeOgYIABAEEB46BQghEKABOgQIIRAVSgUIPBIBMkoECEEYAUoECEYYAFDxPVjCUWCBVGgCcAB4AIABZogBmwqSAQQxMy4ymAEAoAEByAEBwAEB&sclient=gws-wiz) や [OpenStreetMapを利用したもの](https://www.google.com/search?q=OpenStreetMap+%E3%82%B8%E3%82%AA%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0+python&rlz=1C1CHZN_jaJP961JP961&sxsrf=AOaemvJ_0CSZgMlWCz5647xI06nXhIQ6hA%3A1638628884438&ei=FH6rYZKHGpn1wAPW6qeIAQ&ved=0ahUKEwiS4cyksMr0AhWZOnAKHVb1CREQ4dUDCA4&uact=5&oq=OpenStreetMap+%E3%82%B8%E3%82%AA%E3%82%B3%E3%83%BC%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0+python&gs_lcp=Cgdnd3Mtd2l6EAMyBQgAEM0CMgUIABDNAjIFCAAQzQI6BwgjELADECc6BAgAEB46BAgjECc6BAghEBVKBQg8EgExSgQIQRgBSgQIRhgAUOsIWK0XYKQZaAFwAHgAgAFiiAGOBpIBATmYAQCgAQHIAQHAAQE&sclient=gws-wiz) などがあります。
　今回は、[Geolonia 住所データ](https://geolonia.github.io/japanese-addresses/)というオープンデータを利用してみます。このデータでは日本国内の住所、住所カナ、緯度経度の組み合わせが、CSV形式で提供されています。ライセンスは[CC BY 4.0](https://creativecommons.org/licenses/by/4.0/deed.ja) です。 
　以下は、緯度・経度から住所等を求めるコードです。

```python
from urllib import request
import os
import pandas as pd
from scipy import spatial

# 住所一覧をダウンロード
url = "https://raw.githubusercontent.com/geolonia/japanese-addresses/master/data/latest.csv"
file = "latest.csv"
if not os.path.exists(file):
    request.urlretrieve(url, file)

# データ読み込み
df = pd.read_csv(file).fillna("")  # データがない要素は空文字に置換
latlon_list = df[["緯度", "経度"]].values
tree = spatial.KDTree(latlon_list) # 検索用に緯度経度のkd木を作る

# 最近傍を探す(ユークリッド距離なので実際の距離とは異なるがおおよそ正しい)
latlon = [35.5311682,139.6970126] # 川崎駅付近
dist, idx = tree.query(latlon)

# 表示
d = df.iloc[idx]
name = d["都道府県名"]+d["市区町村名"]+d["大字町丁目名"]+d["小字・通称名"]
print(name)
print("---")
print(d)
```

実行結果は下記のようになります。

```text
神奈川県川崎市川崎区駅前本町
---
都道府県コード                             14
都道府県名                             神奈川県
都道府県名カナ                         カナガワケン
都道府県名ローマ字                 KANAGAWA KEN
市区町村コード                        14131.0
市区町村名                           川崎市川崎区
市区町村名カナ                     カワサキシカワサキク
市区町村名ローマ字     KAWASAKI SHI KAWASAKI KU
大字町丁目名                            駅前本町
大字町丁目名カナ                     エキマエホンチョウ
大字町丁目名ローマ字                EKIMAEHONCHO
小字・通称名
緯度                           35.532434
経度                            139.6996
Name: 115783, dtype: object
```

なお、ジオコーディングについては、[公式の JavaScript API](https://github.com/geolonia/community-geocoder) があります。こちらも静的ファイルのみで動作するようになっています。