ベクトルタイルをDocker（unvt/nanban）で作る（Windowsユーザー向け）

# はじめに
ベクトルタイルはウェブ地図分野で注目されている技術です。しかし、ベクトルタイルを作る方法はすこし難しく感じる方が多いかもしれません。
ここでは、Windows上で、簡単なデータをベクトルタイルに変換した方法を記録しておきます。

### ベクトルタイル作成ツールについて
ベクトルタイルを効率よく作るためのツールとして、[Tippecanoe](https://github.com/mapbox/tippecanoe)(mapbox)があります。これは自由に使える(BSD 2-Clause Simplified License)ツールで、変換速度も非常に速く、大きなデータに対してもしっかり働いてくれるツールです。ただし、Linux環境やOSX with homebrewの環境で動きますので、Windowsユーザーには最初のハードルが高いかもしれません。

### 簡単に作るための工夫
今回は Windowsで動くDocker（Docker Desktop on Windows）を使って、シェープファイルからベクトルタイルを作ってみました。
[UN Vector Tile Toolkit (unvt)](https://github.com/unvt)のツールの一つである [unvt/nanban](https://github.com/unvt/nanban) というものを使います。これはUbuntu/Intelに基づいて作成していますので、Windowsでも仮想的なLinux環境を提供してくれますし、このなかにTippecanoeなどのツールが入っています。


# 作業した環境
* Windows 10 (Enterprise)
* Docker version 20.10.8
* PowerShell version 5.1.19041.1237

# ソースデータ
[Natural Earth](https://www.naturalearthdata.com/) というパブリックドメインのデータを使いました。
小縮尺の海岸線、陸域、河川のデータ（シェープファイル形式）をダウンロードして使いました。 

- ne_110m_coastline.shp
- ne_110m_land.shp
- ne_110m_rivers_lake_centerlines.shp

練習用のデータとしては、なんでもいいのですが、ソースデータの投影法はWGS84かウェブメルカトルものがよいと思います。Tippecanoeの入力データとしてそのままで対応できる投影法のためです。 EPSG 4326とかEPSG 3857というものならOKです。（違うものなら投影変換すればよいだけですが。）

# ベクトルタイルの構成
ベクトルタイルを変換する前に、ベクトルタイルのレイヤ名、ソースデータ、ズームレベルを整理しておくとよいです。今回は以下の通りにしました。

| レイヤ名 | ソース | Min Zoom | Max Zoom |
| ---- | ---- | ---- | ---- |
| coastl |  ne_110m_coastline.shp | 0 | 4 |
| landmass |  ne_110m_land.shp | 0 | 4 | 
| riverl |  ne_110m_rivers_lake_centerlines.shp | 0 | 4 |

 

# 作業手順
ダウンロードしたデータを特定のフォルダに保存し、パワーシェルを立ち上げて以下の手順を実施しています。（※Docker Desktop for windows のインストールについてはここでは説明しません。）

## Docker （unvt/nanban）の開始
データを保存したディレクトリで以下のコマンドを実行。unvt/nanbanが立ち上がります。なお、Docker を走らせた時にフォルダをシェアするか聞かれたらシェアします。

```
docker pull unvt/nanban
docker run -it --rm -v ${PWD}:/data unvt/nanban
```
-itでインタラクティブなコマンド入力を出来るようにします。-vでは現在のディレクトリを、Dockerの中で/dataというフォルダに関連付けます。

このunvt/nanbanの中には、gdal(ogr2ogr)やTippecanoeがすでに入っていますので、特段のインストール作業なしに変換が出来ます。（下の図でも、ogr2ogrやtippecanoeのバージョンが確認できています。）
![2021-11-02-qiita01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/b7e2ce6d-221d-3091-464c-2a7d15452b2d.png)


## シェープファイルからGeoJSONへの変換（gdal）
Dockerが立ち上がったら、/dataディレクトリに移動します。ここはデータを保存したディレクトリですので、シェープファイルのデータが保存されています。

gdalが使えますので、以下のようにシェープファイルからGeoJSONファイルを作りました。3つのGeoJSONファイルができました。

```
cd /data
ogr2ogr -f GeoJSON coastl.geojson ne_110m_coastline.shp
ogr2ogr -f GeoJSON landmass.geojson ne_110m_land.shp
ogr2ogr -f GeoJSON riverl.geojson ne_110m_rivers_lake_centerlines.shp
```

こんな感じになりました。
![2021-11-02-qiita02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/a0a79395-6142-30a2-d008-7927a57b39d7.png)



## GeoJSON からベクトルタイルへの変換（Tippecanoe）
次に、3つのGeoJSONファイルからベクトルタイルを作成します。以下のようにコマンドを実行するとVTPracticeというフォルダにベクトルタイルがpbf形式で出来ました。終わったらexitでDockerを終了しましょう。

```
tippecanoe -e VTpractice --no-tile-compression --no-feature-limit --no-tile-size-limit --drop-rate=1 -Z0 -z4 -L coastl:coastl.geojson -L landmass:landmass.geojson -L riverl:riverl.geojson  
```

![2021-11-02-qiita03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/679143/e2532759-6ec1-d848-6866-b008741a9340.png)

（オプションの説明）

* -eはpbf形式です。mbtiles形式がいい場合は-oにして引数をファイル名.mbtilesにしてください。
* マップライブラリでベクトルタイルを読む場合に、pbfが圧縮されていると表示できない場合があるので、--no-tile-compressionをつけておきます。
* --no-feature-limitと--no-tile-size-limitは、今回のようなデータでは必要ないですが、大きいサイズのデータを扱う際には念のためつけておくとよいと思います。（データを失うことはないですが、データサイズは大きくなります。）
* -Z0 -z4　のところで最大・最小ズームレベルを指定しています。（この単純な変換ではレイヤや地物ごとにズームレベルを指定できませんが、javascriptsやtile-join（Tippecanoeの一部）を使うことでそのようなことも出来ます。）
* -Lでベクトルタイルのレイヤを指定しています。「-L レイヤ名：ソース」の順です。

（pbfとmbtilesフォーマットについて）

* pbfはバイナリーのタイルデータです。フォルダ構造の中に保存されます（z/x/y.pbf）。mvtと同じ形式です。ウェブサーバーで静的にホスティングするだけでいいので、GitHubページなどでも配信できます。一方で、ファイルの数や合計サイズが大きくなるという点もありますので、大きすぎるデータにでは難しい場合もあります。
* MbtilesはSQLiteデータベースです。一つのmbtilesファイルが複数のpbfタイルを格納していると考えるとわかりやすいと思います。ファイル数やサイズを節約できますが、mbtilesからpbfタイルを配信するために、ホスティングサーバーを準備する必要があります。

# その他
最近、RHELではDockerがサポートされなくなっています。その場合、podmanが代替として使えます。しかし、せっかく本物のLinux環境があるなら、自分で必要なツールをインストールして変換した方が良いと思います。
Dockerはコンテナで同じ環境を再現できますから、Tippecanoeの練習などの入門用としてよいと思います。

# References
* https://speakerdeck.com/ubukawa/2021-06-17-unvt-exercise-day02
* https://github.com/mapbox/tippecanoe