UN Clear Mapのベクトルタイルを作成して表示する（まとめ編）

# はじめに
UN Clear Mapについて、[こちらの記事](https://qiita.com/k96mz/items/9dc3d9b44432d080874a)でベクトルタイルの構造をみました。また、[こちらの記事](https://qiita.com/k96mz/items/fbbc96b183862e441337)でベクトルタイルの作成を、[こちらの記事](https://qiita.com/k96mz/items/00221897215315841e8b)でスタイルファイルの作成やHTMLファイルの作成について記載しました。
今回は今までの記事のまとめとして、pbfファイル形式とMBTilesファイル形式でUN Clear Mapのベクトルタイルを作成し、地図で表示するところまでを記載したいと思います。

今回使用するレポジトリは[こちら](https://github.com/k96mz/20241007makeClearMap)です。

# ベクトルタイルを作成する
### MbTilesファイルの作成
まずはベクトルタイルを作成します。基本的なコードはベクトルタイル作成時の記事のものと変更ありませんが、今回はPMTilesファイルではなくMBTilesファイルを作成しますのでその部分の記載を変更しています。具体的にはindex-2.jsの「pmtiles」を「mbtiles」と変更しました。また、その変更に付随して、default.hjsonの設定の記載も「pmtiles」から「mbtiles」と変更しました。
PostGISにつながっているLinuxPCにおいて、レポジトリをgit cloneして取得します。config/default.hjsonを記載して、さらにnpm installで必要なモジュールをインストールしてから実行すると、ベクトルタイルが作成出来ます。

作成されたベクトルタイルのURLは以下です。
https\://k96mz.github.io/20241007makeClearMap/mbtiles/0-0-0.mbtiles

### pbfファイルの作成
pbfファイル形式でもベクトルタイルを作成します。ファイルをコピーしてindex-2pbf.jsとファイル名を変更します。さらに、tippecanoeのオプションに以下を追記しました。
'--no-tile-compression'
'--output-to-directory=pbfFiles'

逆に以下の記載はコメントアウトしておきます。
`--output=${tmpPath}`

その他、不要なコードについてもコメントアウトしました。

LinuxPCでindex-2pbf.jsを実行し、作成されたベクトルタイルをアップロードしました。
https\://k96mz.github.io/20241007makeClearMap/pbfFiles/{z}/{x}/{y}.pbf

# スタイルファイルを準備する
まずは以前の記事と同様にMapLibre GL JS をダウンロードします。次にスタイルファイルを準備します。スタイルファイルについても以前の記事で用意した[こちらのYamlファイル](https://github.com/k96mz/20240911ClearMap/blob/main/docs/root.yml)を編集していきます。

このスタイルファイルでは計226ものレイヤが使用されていますが、今回postgreSQL/PostGISデータベースから作成したベクトルタイルは以下のテーブルの20種類のみです。

```
relations: [
    un_base::vectortile::custom_planet_land_08_a
    un_base::vectortile::custom_planet_ocean_08_a
    un_base::vectortile::custom_ne_10m_bathymetry_a
    un_base::vectortile::un_glc30_global_lc_ss_a
    un_base::vectortile::unmap_bndl_l
    un_base::vectortile::unmap_bndl05_l
    un_base::vectortile::unmap_bndl25_l
    un_base::vectortile::custom_ne_rivers_lakecentrelines_l
    un_base::vectortile::unmap_bnda_cty_anno_03_p
    un_base::vectortile::unmap_bnda_cty_anno_04_p
    un_base::vectortile::unmap_bnda_cty_anno_05_p
    un_base::vectortile::unmap_bnda_cty_anno_06_p
    un_base::vectortile::unmap_phyp_label_04_p
    un_base::vectortile::unmap_phyp_label_06_p
    un_base::vectortile::unmap_phyp_p
    un_base::vectortile::unmap_wbya10_a
    un_base::vectortile::unmap_wbya_label_05_p
    un_base::vectortile::unmap_wbya_label_06_p
    un_base::vectortile::unmap_dral10_l
    un_base::vectortile::unmap_popp_p
  ]
```

上記テーブル名、レイヤ名、minzoom、 maxzoomをmodify.jsを見ながら以下の通り表にしました。

| テーブル名 | レイヤ名 | minZoom | maxZoom | 備考 |
|:-----:|:-----:|:------:|:------:|:------:|
| custom_planet_land_08_a  | landmass  | 0 | 5 |   | 
| custom_planet_ocean_08_a  | ocean  | 0 | 5 |   | 
| custom_ne_10m_bathymetry_a  | bathymetry  | 2 | 5 | | 
| un_glc30_global_lc_ss_a  | landcover | 4 | 5 | | 
| unmap_bndl_l  | bndl | 5 | 5 | | 
| unmap_bndl05_l  | bndl  | 3 | 4 | | 
| unmap_bndl25_l  | bndl  | 0 | 2 | | 
| custom_ne_rivers_lakecentrelines_l  | un_water | 条件により3~5 | 5 | | 
| unmap_bnda_cty_anno_03_p  | lab_cty | 1 | 2 | labtypが条件により変動 | 
| unmap_bnda_cty_anno_04_p  | lab_cty | 3 | 3 | labtyp = annotationclassid | 
| unmap_bnda_cty_anno_05_p  | lab_cty | 4 | 4 | labtyp = annotationclassid | 
| unmap_bnda_cty_anno_06_p  | lab_cty | 5 | 5 | labtyp = annotationclassid | 
| unmap_phyp_label_04_p  | lab_water | 条件により1~4 | 3 | | 
| unmap_phyp_label_06_p  | lab_water | 4 | 5 | | 
| unmap_phyp_p | phyp_label | 5 | 5 | | 
| unmap_wbya10_a | wbya10 | 条件により0~6を細かく変動 | 5 | | 
| unmap_wbya_label_05_p | lab_inwater | 4 | 4 | | 
| unmap_wbya_label_06_p | lab_inwater | 5 | 5 | | 
| unmap_dral10_l | dral10 | 条件により3~6 | 5 | | 
| unmap_popp_p | un_popp | 3 | 5 | | 

重複するレイヤ名もあるので、それを考慮すると作成するレイヤ数は13となります。
それぞれのレイヤに対応すると考えられるymlファイルを参照しながら、実際のymlファイルを作成していきます。例えば、landmassレイヤであれば、以下のファイルを参照します。

```yml:BNDA_L01-L04.yml
id: Base Layers/Country areas/BNDA_L01-L04
type: fill
source: esri
source-layer: BNDA_L01-L04
maxzoom: 4
layout: {}
paint:
  fill-color: '#FCFCFA'
```

実際に作成したものは以下です。landmassはポリゴンデータで、陸域を示しています。

```yml:landmass.yml
id: landmass
type: fill
source: esri
source-layer: landmass
maxzoom: 5
layout: {}
paint:
  fill-color: '#FCFCFA'
```

oceanはポリゴンデータで、海域を示しています。

```yml:ocean.yml
id: ocean
type: fill
source: esri
source-layer: ocean
maxzoom: 5
layout: {}
paint:
  fill-color: '#D5EBF5'
```

bathymetryはポリゴンデータで等深線を示しています。clear mapにはないので、飛ばしました。
landcoverはポリゴンデータで都心域を示しているようです。こちらもclear mapにはないので、飛ばしました。

bndlは３つのテーブルが一つのレイヤになったもので、ラインデータで国境線を示しています。
実際のClear mapの国境線データは、属性bdytypによって線の種類を変えているので、bndl-0.ymlからbndl-3.ymlの４つのファイルを作成しています。line-widthなどの値は適当に設定しています。

```yml:bndl-0.yml
id: bndl-0
type: line
source: esri
source-layer: bndl
filter:
  - '=='
  - bdytyp
  - 0
minzoom: 0
maxzoom: 5
layout:
  line-cap: round
  line-join: round
paint:
  line-color: '#737B80'
  line-width: 0.2
  line-opacity: 0.9
```

```yml:bndl-1.yml
id: bndl-1
type: line
source: esri
source-layer: bndl
filter:
  - '=='
  - bdytyp
  - 1
minzoom: 0
maxzoom: 5
layout:
  line-join: round
paint:
  line-color: '#737C80'
  line-width: 0.7
  line-opacity: 0.9
```

```yml:bndl-2.yml
id: bndl-2
type: line
source: esri
source-layer: bndl
filter:
  - '=='
  - bdytyp
  - 2
minzoom: 0
maxzoom: 5
layout:
  line-join: round
paint:
  line-color: '#737C80'
  line-dasharray:
    - 8
    - 5
  line-width: 1
  line-opacity: 0.9
```

```yml:bndl-3.yml
id: bndl-3
type: line
source: esri
source-layer: bndl
filter:
  - '=='
  - bdytyp
  - 3
minzoom: 0
maxzoom: 5
layout:
  line-join: round
paint:
  line-color: '#737C80'
  line-dasharray:
    - 8
    - 5
  line-width: 1
  line-opacity: 0.9
```

un_waterはラインデータで河川を示しています。

```yml:un_water.yml
id: un_water
type: line
source: esri
source-layer: un_water
minzoom: 3
maxzoom: 5
paint:
  line-color: 'rgba(157,189,209,0.7)'
```

lab_ctyも４つのテーブルが一つのレイヤとなっており、ポイントデータで国名を示しています。どの属性がテキストとして表示されるのかを知るためにLinuxPCからPostGISを見にいき確認したところ、以下の通り「textstring」でした。

![スクリーンショット 2024-10-08 16.36.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/94f8bc89-ec5a-4309-d6d9-4f68feeddc06.png)

pmtilesをウェブ地図で表示させても、属性をみることが出来ます。

![スクリーンショット 2024-10-09 8.35.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/e9349b42-3aad-d893-e65e-cf3552478b35.png)


```yml:lab_cty.yml
id: lab_cty
type: symbol
source: esri
source-layer: lab_cty
minzoom: 0
maxzoom: 5
layout:
  text-font:
    - Open Sans Semibold Regular
  text-size: 10
  text-anchor: center
  text-letter-spacing: 0.15
  text-field: '{textstring}'
  text-allow-overlap: true
  text-optional: true
paint:
  text-color: '#6E7780'
  text-halo-color: rgba(250,251,252,0.25)
  text-halo-width: 0.733333
```

lab_waterはポイントデータで海名を表しているようです。text-sizeなどは適当な値としています。

```yml:lab_water.yml
id: lab_water
type: symbol
source: esri
source-layer: lab_water
minzoom: 0
maxzoom: 5
layout:
  text-font:
    - Open Sans Semibold Italic
  text-size: 12
  text-max-width: 15
  text-anchor: center
  text-letter-spacing: 0.3
  text-field: '{textstring}'
  text-allow-overlap: true
  text-optional: true
paint:
  text-color: '#5F93B8'
  text-halo-color: rgba(225,235,240,0.5)
  text-halo-width: 0.466667
```

phyp_labelはポイントデータで、湾名を表しています。text-field: '{name}'としています。しかし、地図には表示されませんでした。minZoomが5, maxZoomが5でベクトルタイルを作成しているためかもしれません。

wbya10はポリゴンで湖沼のデータを示しています。

```wbya10.yml
id: wbya10
type: fill
source: esri
source-layer: wbya10
minzoom: 0
maxzoom: 5
layout: {}
paint:
  fill-color: '#DFEFF7'
```

lab_inwaterはポイントデータで、湖沼名称のデータです。こちらも地図には表示されませんでした。minZoomとmaxZoomがそれぞれ4と5でベクトルタイルを作成しているためかもしれません。

dral10はラインデータで河川を示しています。地図上で見ると、un_waterとほぼ同じです。

```dral10.yml
id: dral10
type: line
source: esri
source-layer: dral10
minzoom: 3
maxzoom: 5
paint:
  line-color: rgba(157,189,209,0.7)
  line-width: 0.4
```

un_poppはポイントデータで首都を示しています。iconも表示するよう設定し、それに伴い「text-anchor: top-left」とtext-offsetも設定しました。

```un_popp.yml
id: un_popp
type: symbol
source: esri
source-layer: un_popp
minzoom: 0
maxzoom: 5
layout:
  text-font:
    - Arial Unicode MS Regular
  text-size: 9
  # text-anchor: center
  text-anchor: top-left
  text-offset: [1, 0]
  text-letter-spacing: 0.1
  text-max-width: 50
  text-field: '{romnam}'
  text-allow-overlap: true
  text-optional: true
  icon-image: POPULATED PLACES/Populated Places_SYMBOLS/National Capital
  icon-size:
    stops:
      - - 3.89
        - 1
      - - 5.89
        - 1.06667
  icon-allow-overlap: true
paint:
  text-color: '#3E3F40'
  text-halo-color: rgba(247,249,250,0.85)
  text-halo-width: 1
```

元のymlファイルは以下の通りです。ファイルの順番を上からポリゴン、ライン、ポイントとなるように調整しています。

```root2.yml
version: 8
sprite: https://pro-ags2.dfs.un.org/arcgis/rest/services/Hosted/Clearmap_Webplain/VectorTileServer/resources/sprites/sprite
glyphs: https://pro-ags2.dfs.un.org/arcgis/rest/services/Hosted/Clearmap_Webplain/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf
sources:
  esri:
    type: vector
    attribution: UN_CLEARMAP_VT
    bounds:
      - -180
      - -85.0511
      - 180
      - 85.0511
    minzoom: 0
    maxzoom: 19
    scheme: xyz
    tiles:
      - https://k96mz.github.io/20241007makeClearMap/pbfFiles//{z}/{x}/{y}.pbf
layers:
  - !!inc/file layers/ocean.yml
  - !!inc/file layers/landmass.yml
  - !!inc/file layers/wbya10.yml
  - !!inc/file layers/bndl-0.yml
  - !!inc/file layers/bndl-1.yml
  - !!inc/file layers/bndl-2.yml
  - !!inc/file layers/bndl-3.yml
  - !!inc/file layers/un_water.yml
  - !!inc/file layers/dral10.yml
  - !!inc/file layers/lab_cty.yml
  - !!inc/file layers/lab_water.yml
  - !!inc/file layers/phyp_label.yml
  - !!inc/file layers/lab_inwater.yml
  - !!inc/file layers/un_popp.yml
_ssl: true
```


```
charites serve root2.yml
```
として地図を表示してみると以下の通りとなります。

![スクリーンショット 2024-10-09 10.23.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/17f4f6cf-de68-0ff0-9ab6-fb247c2ddf14.png)

実際のclear mapと比べてみると少し違いますが、大体似ているのでとりあえずオーケーとします。

![スクリーンショット 2024-10-09 10.22.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/77eb40b2-bc24-1ba8-13b0-c6602ee08eb6.png)

ymlファイルをjsonファイルに変換します。
コマンドは以下を使います。

```
charites build root2.yml style2.json   
```

# 地図を表示する
作成したスタイルファイル（jsonファイル）を使用して地図を表示します。
[こちらの記事](https://qiita.com/k96mz/items/00221897215315841e8b)のmap.htmlを利用します。地図は[こちら](https://k96mz.github.io/20241007makeClearMap/docs/map.html)から見られます。

![スクリーンショット 2024-10-09 11.03.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/4fb017eb-b50c-5bae-6237-3402c81bcdda.png)



# mbtilesファイル形式のベクトルタイルを表示する
pbfファイル形式のベクトルタイルを表示しましたが、mbtilesファイル形式のベクトルタイルも表示したいと思います。
[こちらの記事](https://qiita.com/k96mz/items/668bee0c6d751a444b5c)でmbtilesでのホスティング方法についてまとめているので、参照しながら作業を進めます。

参照記事のapp.jsと./routes/VT.jsをコピーしてきます。次に、default.hjsonに必要な設定の追記、また必要なモジュールのインストールを行います。map_mbtiles.htmlとstyle2_mbtiles.jsonを元ファイルからコピーして作成し、そしてmap_mbtiles.htmlのスタイルファイル参照先をstyle2_mbtiles.jsonとします。スタイルファイルstyle2_mbtiles.jsonにおいて、ベクトルタイル参照先は以下に設定します。
"tiles": ["http://localhost:3000/VT/zxy/0-0-0/{z}/{x}/{y}.pbf"]

node app.jsとしてローカルサーバを起動し、以下のURLに行くと無事に地図が見られます。
http://localhost:3000/map_mbtiles.html


chromeの開発者モードでみると、「http\://localhost:3000/VT/zxy/0-0-0/3/3/4.pbf」のように、ローカルホストからタイルが返って来ていることが分かります。

![スクリーンショット 2024-10-10 10.23.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/e2b18ef1-b8ce-1290-b869-455816ee1121.png)

# まとめ
pbfファイル形式とMBTilesファイル形式でUN Clear Mapのベクトルタイルを作成し、地図で表示しました。

# Reference

https://qiita.com/k96mz/items/9dc3d9b44432d080874a

https://qiita.com/k96mz/items/fbbc96b183862e441337

https://qiita.com/k96mz/items/00221897215315841e8b

https://qiita.com/k96mz/items/668bee0c6d751a444b5c