メッシュ状の GeoJSON データを tippecanoe で MVT にした作業記録 

# はじめに

[明治時代初期土地利用・被覆デジタルデータベース](https://github.com/wata909/habs_test) というデータを加工して最終的に [mapbox-gl-js で表示させてみた](https://github.com/frogcat/habs-mvt) のですが、この文書では mapbox vector tile への変換作業に関して記録します。

# 使用したツール

[tippecanoe](https://github.com/mapbox/tippecanoe) を手順に従ってインストールしました。
結果的には <https://github.com/mapbox/tippecanoe/blob/master/README.md> を通して全部読むことになったので、時間がある人は一通り目を通すのがよいかと思いました。

# 手順

以下の 3行 で求める結果が得られました。

```shell-session
$ git clone https://github.com/wata909/habs_test.git
$ cd habs_test
$ tippecanoe --no-tile-compression -z12 -Z12 -e output_dir -y code -l habs -ai */*/*.geojson
```

mbtiles や tile-join については知らなくても問題なさそうです。geojson から直接タイルを作ってしまいましょう。



# オプション解説

以下各オプションについて解説します。

## 1.出力フォルダの指定 【-e ${output_dir}】

<https://github.com/mapbox/tippecanoe/blob/master/README.md#output-tileset> を参照。

tippecanoe では出力結果として以下の２つの選択肢があります。

- 単独の MBTiles ファイルを出力する
- {z}/{x}/{y}.pbf のような、フォルダ構造＋PBF ファイル群を出力する (= MVT )

今回のケースは pbf を直接生成したかったので、 `-e ${output_dir}` のオプションを採用しました。
なお、 mbtiles 形式で出力する場合は `-o output.mbtiles` のように `-o` オプションを使用します。

## 2.ファイル圧縮の抑制 【--no-tile-compression】

<https://github.com/mapbox/tippecanoe/blob/master/README.md#setting-or-disabling-tile-size-limit> を参照。

tippecanoe はデフォルトでは出力を gzip 圧縮してしまうのですが、mapbox-gl-js は gzip 圧縮された pbf を扱うことができません。これを圧縮させないのが `--no-tile-compression` オプションです。
`-e` オプションを使う場合にはセットで `--no-tile-compression` を使うことになるかと思います。

## 3.出力するズームレベルの指定 【-z12 / -Z12】

<https://github.com/mapbox/tippecanoe/blob/master/README.md#zoom-levels> を参照。

tippecanoe は何も指定しないと、入力ソースを解析して適切なズームレベルの範囲で自動的に MVT を生成してくれます。ただ、今回は「100m間隔のデータ」であることが明らかで、また、データはすべて「点」で図形の単純化などの恩恵もないので、マニュアルで狙ったズームレベルのタイルだけを生成することにしました。

`-z${maxzoom}` `-Z${minzoom}` のように出力する最大ズームレベルと最小ズームレベルを指定することができます。小文字の `-z` が最大ズームレベル、大文字の `-Z` が最小ズームレベルであることに注意が必要です。

今回は `-z12 -Z12` のように、ズームレベル12 のタイルだけを出力するように指定しました。
z=12 は最終的には自分の感覚で決めていますが、上記参照情報では 各 z における precision が提供されているので参考にしてみてください。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82494/d83cdbf3-ab24-8e6a-6e27-7d9955cbc888.png)

## 4.出力に使用するレイヤ名の指定 【-l habs】

<https://github.com/mapbox/tippecanoe/blob/master/README.md#input-files-and-layer-names> を参照。

Mapbox Vector Tile スペックにおいては、すべての Feature はいずれかの（名前を持つ）レイヤーに所属することになります。
tippecanoe では「ある Feature がどのレイヤーに所属するか」を指定する方法をいくつか用意しています。

`-l habs` 指定は、処理対象とするすべての Feature の所属するレイヤーを `habs` とせよ、という指定方法になります。

もしこれを指定しなかった場合には以下のルールに従って **「入力ファイルのファイル名から拡張子を除いたもの」** がレイヤー名として採用されてしまうので注意しましょう。

>  name.json or name.geojson: Read the named GeoJSON input file into a layer called name.


## 5.出力するプロパティの限定 【-y code】

<https://github.com/mapbox/tippecanoe/blob/master/README.md#filtering-feature-attributes> を参照。

tippecanoe は何も指定しないと、入力のすべてのプロパティをエンコードして出力します。
もし残すべきプロパティが決まっている場合には `-y ${property_name}` オプションを利用することで、ホワイトリスト処理を実現できます。ブラックリスト処理の場合には `-x ${property_name}` を使用しましょう。すべてのプロパティが不要な場合には `-X` も利用できるようです。


今回の入力データでは次のように `gid` `id` `dn` `mesh2r_id` `code` `edited` の各プロパティが使用されているのですが、描画に関係があるのが `code` プロパティだけのようでした。 `code` だけを残すために `-y code` と指定しています。

```example.json
{
  "type": "Feature",
  "properties": {
    "gid": 1695147.000000,
    "id": "3007835",
    "dn": 1.000000,
    "mesh2r_id": "523926",
    "code": 4.000000,
    "edited": 1.000000
  },
  "geometry": {
    "type": "Point",
    "coordinates": [139.8682149895281, 34.916658300855211]
  }
}
```

## 6.IDの自動付番  【-ai】

<https://github.com/mapbox/tippecanoe/blob/master/README.md#adding-calculated-attributes> を参照。

[RFC7946 The GeoJSON Format](https://tools.ietf.org/html/rfc7946#section-3.2) では

>  If a Feature has a commonly used identifier, that identifier
>      SHOULD be included as a member of the Feature object with the name
>      "id", and the value of this member is either a JSON string or number.

との記述があり、GeoJSON の Feature オブジェクトは id プロパティを持ち得ます。 tippecanoe はこの id を認識してエンコードしてくれるのですが、id がなかった場合に自動補完してくれるのが `-ai` オプションです。

今回の入力は `properties` の配下に `id` が存在するのですが、これは tippecanoe からは id として認識されません。ここでは `-ai` を使用して ID を付番することにしました。

なお、サイズ抑制の面からは ID をつけないのが良いのですが、他方で描画後のインタラクションがうまくいかなくなる場合もある、ということは覚えておきましょう。今回はインタラクションの実験もしたかったので ID を付与しました。

参考) <https://github.com/gsi-cyberjapan/gsimaps-vector-experiment/issues/10>


## 7.入力ファイルの指定 【\*/\*/\*.geojson】

<https://github.com/mapbox/tippecanoe/blob/master/README.md#input-files-and-layer-names> を参照。

入力となる geojson ファイルを指定しています。これは普通ですね。


# まとめ

うまくいったケースとそのオプションについて解説しました。メッシュ統計データや格子状の DEM なども、とりあえずこの方法で MVT 化できるかもしれません。

ちなみにファイル数と合計ファイルサイズはこんなかんじでした。

|  |ファイル数  |合計ファイルサイズ (kbytes) |
|---|--:|--:|
|GeoJSON  |206  |412,338  |
|PBF  |331  |33,885  |