登記所備付地図の「法務省地図XMLアダプトプロジェクト」をコンテナにする試み

# 概要
登記所備付地図の「法務省地図XMLアダプトプロジェクト」をコンテナにする試みです。

- [amx-project/a](https://github.com/amx-project/a)で公開されている`pmtiles`ファイル([`a.pmtiles`](https://github.com/amx-project/a))が便利だなぁと思っていたら、地物のIDが無くて困ったため、`pmtiles`づくりに初挑戦しました
- 自前で`pmtiles`を作ろうとして、『G空間情報の[変換済みGeoJSON](https://front.geospatial.jp/moj-chizu-xml-readme/moj-chizu-shp-download/)で行けるのでは？』と思い大量のファイルをかき集めたが`daihyo`レイヤーを作れないことが判明した（『[地図XML](https://front.geospatial.jp/moj-chizu-xml-readme/moj-chizu-xml-download/)』ならOK）
- コンテナ化もしたくなったので、forkしてとりあえずコンテナで動くようにした

https://github.com/shinyanakashima/amx-a

## 前段
3月末ということで、次年度の登記所備付地図の更新に向けた準備を始めている方、お疲れ様です。~~もう1年近く前のことでほぼ記憶がないので~~、いつもの[MIERUNE](https://qiita.com/organizations/MIERUNE)さんの投稿を参考に、どういった方法が良いのか検討します。

https://qiita.com/Kanahiro/items/ceeb20c158b4c70b62b6

https://qiita.com/Kanahiro/items/09abaa4ed80429b3ef28

すると、おぼろげながら浮かんできたんです。『MapLibre GL JS + pmtiles』という文字が...💭

### 🗺️コンテナ着手まで（`amx-project/a`の利用）

[法務省地図XMLアダプトプロジェクト](https://github.com/amx-project/)の[amx-project/a](https://github.com/amx-project/a)では、地図XMLを(※下記参照)`pmtiles`形式に変換して配布しており、気軽に利用することができます。[【中級編】MapLibre GL JSを使ったWebGIS作成](https://zenn.dev/asahina820/books/071ba23476fdc4/viewer/4aaf61)を参考にお手軽に試すことができます。

https://zenn.dev/asahina820/books/071ba23476fdc4/viewer/4aaf61

### :thinking:トラブル発生
無事に表示されると、今度は地物（地番のポリゴン）を選択したくなったのです。

下記の記事を参考に地物（地番のポリゴン）を選択しようとすると、IDがないために選択できません。どうやら`a.pmtiles`では、特定の[属性を除外](https://github.com/amx-project/a-spec?tab=readme-ov-file#%E5%B1%9E%E6%80%A7-1)しているようです。

- `Leaflet`だとclickした地物(feature)にそのまま色付けできますが、`MapLibre GL JS`では[`setFeatureState`に対して、地物(feature)のIDを渡す](https://qiita.com/4gou/items/e2e0b355858602882384#%E6%96%B9%E6%B3%951setfeaturestate%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B)という方法のようです

- ⚠️`MapLibre GL JS`公式の[example](https://maplibre.org/maplibre-gl-js/docs/examples/hover-styles/)でもこのような方法を取っています

- `地番 + 小字コード`をIDにしたりしたが、同じ小字内に同じ地番名があるとアウトです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30994/51f5c0f3-5ff5-43c9-b151-19323f96203f.png)

## 自分で作る`pmtiles`

### 📄ファイルの入手

[amx-project/a](https://github.com/amx-project/a)は、『[地図XML](https://front.geospatial.jp/moj-chizu-xml-readme/moj-chizu-xml-download/)』を変換してデータ提供しています。
そのため、G空間情報で公開されている[変換済みGeoJSON](https://front.geospatial.jp/moj-chizu-xml-readme/moj-chizu-shp-download/)ではなく、『[地図XML](https://front.geospatial.jp/moj-chizu-xml-readme/moj-chizu-xml-download/)』が必要です。
自分でかき集めるのは辛すぎるので、[amx-project/kuwanauchi](https://github.com/amx-project/kuwanauchi)を利用しましょう。北海道などは、[2024年度データに対応](https://github.com/amx-project/kuwanauchi01hokkaido/pull/3)しているようです。

:::note info
`amx-project/a`で作る`mbtiles`は、`daihyo`レイヤー（地番を`Point`で表現）、`fude`レイヤー（地番を`Polygon`で表現）の2種類のレイヤーを持つ構造で、地図のzoomレベルに応じて切り替わります。この`daihyo`レイヤーを生成するときに、「代表点経度」や「代表点緯度」という属性情報を利用するのです。
しかし、G空間情報の『変換済みGeoJSON』には「代表点経度」や「代表点緯度」は含まれていません（え、マジ...🥲）。`daihyo`レイヤーが必要なら「代表点経度」や「代表点緯度」を含んだデータが必要です。

「代表点経度」や「代表点緯度」というのは、内部で使われているデジ庁の[mojxml2geojson](https://github.com/digital-go-jp/mojxml2geojson)が作ってくれる属性なので、`amx-project/a`の`Rakefile`をそのまま利用したい場合は、変換済みGeoJSONではなく、[地図XML](https://front.geospatial.jp/moj-chizu-xml-readme/moj-chizu-xml-download/)を使いましょう。

もちろん、変換済みGeoJSON等他のファイルでも、ジオメトリから代表点を求めれば対応できます。
:::


また、変換済みGeoJSONなら[【法務省登記所備付地図（通称：地図XML）】WindowsPowershellでG空間情報センターから一括ダウンロード](https://qiita.com/T-ubu/items/466ee9fcaad8345e1c77)を参考に自動ダウンロードできたのですが...必要なのは『[地図XML](https://front.geospatial.jp/moj-chizu-xml-readme/moj-chizu-xml-download/)』です。

:::note warn
備忘的内容ですが、ファイルの入手については、GeoJSONではスクリプトで一括ダウンロードする方法などが紹介されています。世間様にご迷惑をかけないよう、一括ダウンロードするときは、API Keyを入れたり、sleepを入れる等の注意をしましょう。

:::

### ℹ️amx-project/aの仕様を確認

[amx-project/a-spec](https://github.com/amx-project/a-spec)にまとめられていますが、
もう少し細かいことを調べたので下記にまとめます。

[amx-project/a](https://github.com/amx-project/a)では、[Rakefile](https://github.com/amx-project/a/blob/main/Rakefile)に5つのタスクが定義されています。
私の[amx-a](https://github.com/shinyanakashima/amx-a)では、プロジェクト直下ではなく`output`ディレクトリに全出力ファイルを出すようにしました。

#### タスク：mbtiles
都道府県毎に`src`ディレクトリに置かれた地図XMLを処理。
- データをストリームとして入力し、`tippecanoe` に渡して、都道府県毎の`mbtiles`を生成
- `to_geojson.rb`では、デジ庁の`mojxml2geojson`を利用して、`src`配下のディレクトリに置かれた各zipファイル（[地図XML](https://front.geospatial.jp/moj-chizu-xml-readme/moj-chizu-xml-download/)）を一時ディレクトリに解凍しつつ、`GeoJSON`に変換して標準出力に出す
- `{都道府県コード}-daihyo.mbtiles`,  `{都道府県コード}-fude.mbtiles`を生成し、最後にそれらをまとめた `{都道府県コード}.mbtiles`を生成

#### タスク：pmtiles
rubyスクリプト呼び出しは無し。`tippecanoe`で処理。
- zoomレベル用に、2〜13 用にデコード＆再生成して`a-daihyo.mbtiles`を出力
- zoomレベル用に、14〜16のタイルをそのまま結合して、`a-fude.mbtiles`を出力
- いずれも入力ファイルは同じ（`mbtiles`タスクで出力した`{都道府県コード}.mbtiles`）
- `a-daihyo.mbtiles`と`a-fude.mbtiles`を結合して統合版`mbtiles`(`a.mbtiles`)を作成
    - ※私の[amx-a](https://github.com/shinyanakashima/amx-a)ではファイル名を変更
- 最後に、統合版`mbtiles`から、統合版`pmtiles`に変換

#### タスク：style
`charites`を使用して`style.yml`から`style.json`をビルド＆デプロイします。`ruby`スクリプト呼び出しは無し。
- `layers`というディレクトリを探しにいくが、シンボリックリンクがコミットされているため、自分でシンボリックリンクかディレクトリを作成する必要があります
- 何を指しているのか不明でしたが、[optgeo/optbv-intl.git](https://github.com/optgeo/optbv-intl.git)ぽいなと予想

#### タスク：host
budo を使ってローカルサーバーをホストする。rubyスクリプト呼び出しは無し。

#### タスク：rebuild
echo コマンドで files を表示。rubyスクリプト呼び出しは無し。

:::note info
👉主なものは、`mbtiles`, `pmtiles`だと思います。地図のstyleを変更する場合は`style`タスクを実行します。私の環境では、北海道（都道府県コード=01）を対象に、これら3つを実行したところ1時間程度かかりました。
:::

### 🐋コンテナ化
勢いだけで作ったので、いろいろ直していかないといけません。

https://github.com/shinyanakashima/amx-a/tree/feature/add-container

- `image`の作成は、`podman compose build`
- 実行は、`podman compose up`

なるべく構成を変えないよう、気を付けたことをまとめます。

- `Rakefile`のタスクにはなるべく手を入れないが、都道府県（のコード）を環境引数で渡すようにした
- rubyファイルは直下のものをそのまま利用。
    - `src`はコピーしない（`volume`でマウント）
    - コピーさせたくないものは[.dockerignore](https://github.com/shinyanakashima/amx-a/blob/c9f146f3d7072f6315dc22725450c7ea125faaf1/.dockerignore)で指定しておく
    - layersはシンボリックリンクなのでコピーしない
- `podman`やら`docker`コマンドで`build`や`run`するのはオプションを忘れてしまうため、`compose`を使った