PLATEAUのデータを3DCityDatabaseに入れてみた

# 概要
都会ではPLATEAU Projectが盛り上がっているらしく、田舎に住んでいて目ぼしいビルもなく税金だけ国土交通省配下の企業に使われてももったいないので、PLATEAUのデータ使って何かし始めよう。
という崇高な思いでとりあえずなにかデータベースに突っ込んでみることにしました。

# 何を準備するか
あれこれ１から準備するのは面倒です。
今回はWindow11のWSL2(WSLg対応)で使ってみることにしました。

WSL2のインストールについてはたくさん記事がでています。
下記をご参照ください。
https://qiita.com/yugo-yamamoto/items/28e3d2a090f8f546f3ec



後学のためDockerイメージは使用せず、じかにインストールしてみます。

OS：Ubuntu20.04（Windows11/WSL2)
3DCityDatabaseプロダクトサイト：https://www.3dcitydb.org/3dcitydb/3ddatabase/
データベース：postgresql14

## WSL2の日本語対応
日本語じゃないとダメっていう人は下記を実行しましょう。

```:WSL2(Ubuntu 20.04)
sudo apt install language-pack-ja
sudo update-locale LANG=ja_JP.UTF-8

# デフォルトキーボードを変更する
sudo nano /etc/default/keyboard
| XKBMODEL="jp106"
| XKBLAYOUT="jp"

# いったんWSL2を再起動してから、キーボード選択を行う
sudo dpkg-reconfigure keyboard-configuration

| Keyboard model:Generic 105-key (Intl) PC
| Country of origin for the keyboard:Japanese
| Keyboard layout:Japanese
| Key to function as AltGr:The default for the keyboard layout
| Compose Key:No compose key
| Use Control+Alt+Backspace to terminate the X server?  <No>
```
参照：https://qiita.com/boonrew/items/c502faca401930947206
　　　　https://golang.hateblo.jp/entry/ubuntu-keyboard-layout

## データベースインストール

WSL2のUbuntu上で下記を実行します。

```:WSL2(Ubuntu 20.04)
# 証明やらパッケージリストの作成
sudo apt update
sudo apt -y upgrade
sudo apt install curl ca-certificates gnupg
curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg >/dev/null
deb http://apt.postgresql.org/pub/repos/apt buster-pgdg main
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
sudo vi /etc/apt/sources.list.d/pgdg.list

# ここからインストール
sudo apt update
sudo apt install postgresql-14
#インストールしたサービスが動いているかどうか確認
sudo service --status-all
sudo /etc/init.d/postgresql restart
```

postgresql-14-contrib インストールする記事があるのですが、postgresql10からはパッケージに同梱になっているという話がstack exchangeにあったので、ヨシとします。

## JAVAをインストールする
はあ、JAVAが入ってなかったのです。インストールします。
3DCityDB-Importer-Exporterというツールを使用するのですが、プラグインがJava17以降には対応していないとドキュメントに書いてあるので、とりあえずUbunt 20.04デフォルトのOpenJava 11をインストールします。

```:WSL2(Ubuntu 20.04)
sudo apt install -y default-jdk
```

# postgresqlの設定
先ほどインストールしたpostgresqlにユーザーを追加します。
```:WSL2(Ubuntu 20.04)
sudo -i
# su - postgres
postgres@:~$ psql 
psql (14.5 (Ubuntu 14.5-2.pgdg20.04+2))
"help"でヘルプを表示します。

# ユーザー追加、とりあえずなんでもありアカウントなので、必要に応じで変更してください。
postgres=# CREATE ROLE citydb_user WITH 
	SUPERUSER
	CREATEDB
	CREATEROLE
	INHERIT
	LOGIN
	NOREPLICATION
	NOBYPASSRLS
	CONNECTION LIMIT -1;

# データベース作成
postgres=# CREATE DATABASE citydb_v4 WITH TEMPLATE = template0 ENCODING = 'UTF8' LOCALE = 'C.UTF-8';
postgres=# ALTER DATABASE citydb_v4 OWNER TO citydb_user;


# エクステンション追加
postgres=# \c citydb_v4
postgres=# CREATE EXTENSION postgis;
postgres=# CREATE EXTENSION postgis_sfcgal;
postgres=# CREATE EXTENSION postgis_raster;

# ユーザにパスワードを設定
ALTER ROLE citydb_user WITH PASSWORD 'お好きなパスワード文字列'

postgres=#\q
```

設定ができたらカレントユーザからログインできるかどうか確認しましょう

```:WSL2(Ubuntu 20.04)

$ psql -U citydb_user
ユーザー citydb_user のパスワード:
psql (14.5 (Ubuntu 14.5-2.pgdg20.04+2))
"help"でヘルプを表示します。

citydb_user=#
citydb_user=#\q
```

ここまでで準備はOKです。

# 3DCityDatabaseをインストール
3DCityDatabaseのサイトから 3DCityDB-Importer-Exporter と i-UR 1.4拡張モジュール
 の最新バージョンのパッケージをダウンロードして展開します。

ディレクトリはとりあえず、$HOME/3DCityDB-Importer-Exporter にします。
あ、unzipをインストールしておいてくださいね。


```:WSL2(Ubuntu 20.04)
cd ~
wget https://github.com/3dcitydb/importer-exporter/releases/download/v5.2.1/3DCityDB-Importer-Exporter-5.2.1.zip
unzip 3DCityDB-Importer-Exporter-5.2.1.zip ~/.

wget https://github.com/3dcitydb/iur-ade-citydb/releases/download/v2.0.0/iur-ade-2.0.0.zip

unzip iur-ade-2.0.0.zip ~/3DCityDB-Importer-Exporter/ade-extensions/.

```



展開先のディレクトリ内の下記のディレクトリにあるシェルスクリプトを実行します。
postgresqlの接続設定を先に編集しておきましょう。

```:WSL2(Ubuntu 20.04)
cd ~/3DCityDB-Importer-Exporter/3dcitydb/postgresql/ShellScripts/Unix$

nano CONNECTION_DETAILS.sh

#!/bin/bash
# Provide your database details here ---------------------------------
export PGBIN=/usr/bin/psql
export PGHOST=localhost
export PGPORT=5432
export CITYDB=citydb_v4
export PGUSER=citydb_user
#---------------------------------------------------------------------

# 設定を保存したらデータベースを生成するスクリプトを実行します。

./CREATEDB.sh

```

3DCityDatabseのテーブルやストアドプロシージャがインストールされたら、アクセスできるかどうか確認しましょう。

```:WSL2(Ubuntu 20.04)
$ psql -U citydb_user citydb_v4

citydb_user=# SELECT * FROM citydb.building;

# カラム名が表示されます

citydb_user=# SHOW search_path;
             search_path
-------------------------------------
 citydb, citydb_pkg, "$user", public
(1 行)
citydb_user=#\q

```

# 3DCityDB-Importer-Exporter の設定とADEプラグインのインストール

データの投入には ~/3DCityDB-Importer-Exporter/ にある、3DCityDB-Importer-Exporter を使用します。Cliでの利用も可能ですが、Cliで後述するプラグインのインストール手順がわからなかったので、今回はGUIを利用します。

```:WSL2(Ubuntu 20.04)
# ファイルに実行属性をつけます
chmod u+x 3DCityDB-Importer-Exporter

# 起動します
./3DCityDB-Importer-Exporter
```
PLATEAUのCityGMLをデータベースにインストールするために、ADE Managerでi-UR 1.4用モジュールをインストールします。
i-URにご興味ありましたら、下記のリンクをご覧ください。
https://www.chisou.go.jp/tiiki/toshisaisei/itoshisaisei/index.html
![1スクリーンショット 2022-11-10 195842.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23794/b495954d-4b61-7a40-7e92-88d7c2d3eb19.png)


次に、PLATEAUのデータを3DCityDatabaseにインポートした後、PostGIS系コマンドの利用で実際困るため、緯度経度の入れ替えを設定を行います。
PLATEAUは測量座標系の座標データで記録されています。このままだとインポートした後、ほかのGISツールでデータを利用した際、いちいちXYの入れ替えを行わなければなりません。「CRSを6697に設定しているので、座標系は緯度・経度・メートルであって、正しく読み込めないのはGISツールの出来が悪いからだ、ワーワー」という方々もおられますが、実際のところほとんどのツールは「6697=緯度・経度・メートル」で座標を読み取る動作をしていません。。。
これは本当にPLATEAUデータを利用する者の心をくじく一助になっています。
3DCityDB-Importer-ExporterのPleferencesではXYを入れ替えて内部データの扱いを経度・緯度・メートルにすることができます。
![1スクリーンショット 2022-11-10 195940.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23794/62463961-3f98-a735-e64b-dd9901b0322e.png)

ついでに、importの際大量のデータを扱うとindex生成に大変時間がかかるので、インポート中はindexの作成を抑制するオプションも設定しておきます。
![1スクリーンショット 2022-11-10 200222.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23794/e92f659f-d6e6-5993-aadc-9057ca1d9da0.png)

ここまでで、
・citydb_v4データベースの設定
・i-UR 1.4プラグインの導入
・SWAP X-Y設定
・インデックス抑制設定
が終わり、データベースにデータを投入する準備ができました。

# PLATEAUデータの投入
3DCityDB-Importer-Exporter を起動し、Import タブでPLATEAUのデータを指定します。
あらかじめ、G空間情報センターからインポートしたいデータをダウンロードしておきます。
ここでは、東京都23区のデータを使用してインポートを行ってみます。

```:WSL2(Ubuntu 20.04)
cd ~
wget  https://gic-plateau.s3.ap-northeast-1.amazonaws.com/2020/13100_tokyo23-ku_2020_citygml_3_2_op.zip

```
3DCityDB-Importer-Exporter はzipファイルに対応しているので、ダウンロードしたzipファイルを直接指定します。
![スクリーンショット 2022-11-10 195811.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23794/d6f100f0-a072-4056-914d-ab6926d65bc2.png)
import をクリックし、終わるまで待ちましょう。
マシンスペックにもよりますが、2時間から数時間かかると思います。
そしてpostgresqlのデータベース容量は大体100GB程度になります。
なお、インポートはCliでも可能です。

# PLATEAUデータの確認
データベースにインポートしたものの、どうやって利用するの？と思うでしょう。
テーブルに格納されたオブジェクトはもとのPLATEAUのCityGMLとして一部を出力することができますし、不要なデータだけを削除することもできます。
じゃあ可視化はどうかというと、3DCityDB-Importer-ExporterのVIS Exportタブで、KMLやその他の可視化可能なデータ形式にエクスポートすることができます。
![スクリーンショット 2022-11-10 201445.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23794/5fc1d6b9-c36a-0305-31cd-0b5d74c489af.png)

エクスポートしたKMLファイルをGoogle Earth Proで表示するとこのような感じになります。
![スクリーンショット 2022-11-10 201402.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23794/ddf084f0-c149-123b-18cf-be824064b8f2.png)

# そのほかの利用
実際にCityGMLはどの様にデータベースに取り込まれているか覗いてみて、取り出し方を考えましょう。
取り込まれたデータはcityobjectテーブルにオブジェクトのカテゴリー別のコード、CityGML内のID、名称やエンベロープ（座標範囲）などの概要が格納されます。
![スクリーンショット 2022-12-04 212831.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23794/13587887-66a5-0e32-ee9e-3e487a0b1ba9.png)
例えば東京駅のビルディングを構成するオブジェクトはcityobject.id=1717650で登録されているようです。このオブジェクトの形状はsurface_geometryに格納されていて、たくさんのレコードが登録されています。
![スクリーンショット 2022-12-04 213252.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23794/343157ee-197b-e36a-a284-f0af8f6a3362.png)
これをSQLで取り出すことで、目的のビルディングや橋梁、道路などの形状を得ることができます。

```:SQL
select id,gmlid,st_npoints(sg.solid_geometry) as n,st_astext(st_transform(sg.solid_geometry,6677)) as pz
 from surface_geometry sg
 inner join (select  c.id ci 
               from  cityobject c 
               where c.objectclass_id in(26,43,44,45,46,64,85) 
                     and c.envelope &&& st_envelope('LINESTRING(139.7701263 35.6784069,139.7845459 35.687017)'::geometry)) cg 
                     on sg.cityobject_id = cg.ci where  sg.solid_geometry is not null order by sg.id
```
実行結果として下のようなテーブルが得られます。
![スクリーンショット 2022-12-04 215130.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23794/8941e43d-c604-a599-54d0-2d7a2cc265e6.png)
形状は'POLYHEDRALSURFACE Z'という方で表記されているので、この型に対応していない地理空間用ライブラリで使用するには'POLYHEDRALSURFACE Z'を'MULTIPOLYGON'にリプレイスします（力技です）。