UN Clear Mapを作ってみる

# はじめに
今までベクトルタイル作成等の練習をしてきましたが、今回はUN Clear Mapをベクトルタイルで作成してみたいと思います。UN Clear Mapは[こちらのページ](https://www.un.org/geospatial/mapsgeo/webservices)から見る事が出来ます。参考にさせていただいた[記事はこちら](https://qiita.com/T-ubu/items/5092eabb6d1dae3cc6e4)です。Clear Mapの説明などは、参考記事をご覧ください。
Esriのベクトルタイルのスタイルは、Map Libre GL JSのものとは異なるので、その辺りを学びながらまとめようと思います。

## 環境
macOS Sonoma: 14.6.1
unvt/charites 0.5.4
zsh 5.9（コマンドラインインターフェース）
私はmacを使用していますので、curlのコマンドなどがwindowsのものとは異なると思います。

# MapLibreでのWeb地図作成作業
参考記事と同様のステップでWeb地図作成作業を行っていきます。

## Step 1. GitHubのレポジトリを作る
作成したWeb地図をGitHubのPagesからホストするため、まずはGitHubレポジトリを作成します。

## Step 2. MapLibre GL JSとプラグインを準備する
MapLibre GL JS と使いたいプラグインをダウンロードしてきます。

### 2-1. MapLibre GL JS をダウンロード
2024年9月現在、最新版は4.7.0のようです。curlコマンド使ってダウンロードしていきます。unpkg.comさんのところからダウンロードすると便利です。

```
mkdir docs
cd docs
mkdir maplibre-gl@4.7.0
cd maplibre-gl@4.7.0
curl -O https://unpkg.com/maplibre-gl@4.7.0/dist/maplibre-gl.js
curl -O https://unpkg.com/maplibre-gl@4.7.0/dist/maplibre-gl.js.map
curl -O https://unpkg.com/maplibre-gl@4.7.0/dist/maplibre-gl.css
curl -O https://unpkg.com/maplibre-gl@4.7.0/dist/LICENSE.txt
cd ..
```

:::note info
https://unpkg.com/browse/maplibre-gl@4.7.0/dist/
上記URLのようにunpkg.comさんのページを普通にブラウザで見ると、URLの中にbrowseという文字が入りますが、これを除かないとcurlがうまく利用できません。curlは、指定されたURLからファイルを直接ダウンロードするためのツールです。browseを含んだURLはダウンロードリンクではなくウェブページのリンクになるため、curlは正しいファイルパスを見つけられず、エラーが発生します。
:::


**オプションの説明**
**-O**:  このオプションは、指定されたURLからファイルをダウンロードし、URLの最後の部分に基づいたファイル名で保存することを意味します。

**maplibre-gl.js.map**
maplibre-gl.js.mapはソースマップ(source map)ファイルです。ソースマップは、圧縮されたJavaScriptファイル（例: maplibre-gl.js）を元の読みやすいソースコードに対応させるためのファイルであり、開発者がデバッグ時に使うためのファイルです。


### 2-2. ExportプラグインとLegendプラグインのURL
参考記事にもある通り、watergisで開発された２つのプラグイン、[watergis/maplibre-gl-export](https://maplibre-gl-export.water-gis.com/)と[watergis/maplibre-gl-legend](https://github.com/watergis/maplibre-gl-legend/tree/main/packages/maplibre-gl-legend)を使いたいと思います。
2024年9月11日現在、最新バージョンはそれぞれ3.8.3と2.0.5です。マップの出力ができたり、レイヤのオンオフができるようになります。
まずはExportプラグインの方をダウンロードしようと思ったのですが、参考記事に記載された以下のコマンドを実行してもうまくいきませんでした。バージョンが変わり、URLの構成が変更になったのかもしれません。

```
curl -O https://watergis.github.io/maplibre-gl-export/maplibre-gl-export.js
```

そのため、以下のとおり、URLの参照で対応することにします。こちらのURLは上記のExportプラグインのリンクURLのページに記載されているものです。

```
<link href="https://cdn.jsdelivr.net/npm/@watergis/maplibre-gl-export@3.8.3/dist/maplibre-gl-export.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/@watergis/maplibre-gl-export@3.8.3/dist/maplibre-gl-export.umd.js"></script>
```

同様にLegendプラグインの方についても、以下のURLの参照で対応します。
```
<link href='https://www.unpkg.com/@watergis/maplibre-gl-legend@latest/dist/maplibre-gl-legend.css' rel='stylesheet' />
<script src="https://www.unpkg.com/@watergis/maplibre-gl-legend@latest/dist/maplibre-gl-legend.umd.js"></script>
```


<!--
```
コメントアウトされている行
mkdir watergis
cd watergis
mkdir maplibre-gl-export@3.8.3
cd maplibre-gl-export@3.8.3
curl -O https://raw.githubusercontent.com/watergis/maplibre-gl-export/main/LICENSE
curl -O https://watergis.github.io/maplibre-gl-export/maplibre-gl-export.css
curl -O https://watergis.github.io/maplibre-gl-export/maplibre-gl-export.js
cd ..
mkdir maplibre-gl-legend@2.0.5
cd maplibre-gl-legend@2.0.5
curl -O https://raw.githubusercontent.com/watergis/maplibre-gl-legend/main/LICENSE
curl -O https://watergis.github.io/maplibre-gl-legend/maplibre-gl-legend.js
curl -O https://watergis.github.io/maplibre-gl-legend/maplibre-gl-legend.css
```
-->


## Step 3. スタイルファイルを準備
次にスタイルファイルを準備します。
EsriさんのスタイルをMaplibre用に改変していきます。Esriさんのベクトルタイルサーバーだと、サーバーの下の VectorTileServer/resources/styles/root.json にスタイルファイルがあります。以下のとおり、curlコマンドでダウンロードします。

```
curl -O https://pro-ags2.dfs.un.org/arcgis/rest/services/Hosted/Clearmap_Webplain/VectorTileServer/resources/styles/root.json
```

スタイルファイルの一部は以下のようなものです。全体は非常に長く4667行もあります。

![スクリーンショット 2024-09-11 13.22.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/3625faa4-ebfe-33dc-2c5d-c201d3dc9b80.png)

スタイルファイルを簡単に改変するためにunvt/charitesを使用します。unvt/charitesについては[こちらの記事](https://qiita.com/k96mz/items/7577a309bb8b32fe0daa)をご覧ください。

charitesのconvertコマンドを使用して、jsonファイルをymlファイルに変換します。

```
charites convert root.json
```

このコマンドを実行することで、root.ymlというスタイルを取りまとめるYAMLファイルと、layerというレイヤを格納しているフォルダが作成されます。layerフォルダの中身を見てみることで、多くのレイヤがどのようなsource-layerを持っているのかが分かります。同一のsource-layerから複数のレイヤが作成されていることなどが分かり、charitesを用いることでレイヤ構造を理解しやすくなることが実感出来ます。以下はroot.ymlの一部です。

![スクリーンショット 2024-09-11 13.42.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/a0e6b95b-d95b-9807-047b-7d8672aef236.png)

参考記事では、
「Esri用のスタイルだと、往々にしてスタイルレイヤ名が長くなります。unvt/charitesは一行が長いときは、YAMLの">"（折り返し形式のブロックスカラー）を使って見やすくしてくれるのですが、これがあるとレイヤ一覧としてうまく働かないので">"があるところは消して、一行に戻しました。」
と記載されています。
charitesの最新のバージョンでもこの問題がまだ残っているのか確かめるために、以下のコマンドを実行して、とりあえずjsonファイルに再変換してみました。

```
charites build root.yml root2.json
```

そうすると、
Annotations/L05/BNDA_CTY_ANNO_L05_POINT/label/DEMOCRATIC PEOPLE'S_LV05(Memeber State_AVG SURF_LV05).yml
のファイルの「text-max-width」の値に数値ではなく文字列が入っているというエラーが発生しました。確認してみると確かに以下のように文字列が入っていました。

![スクリーンショット 2024-09-11 14.02.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/90d0d290-f38a-8960-ffef-ad65c87c0a6f.png)

こちらの「'」マークを削除して、数値として扱い、再度コマンドを実行すると無事に通りました。つまり、以前に存在した折り返し形式のブロックスカラー問題は解消されたようです。


### 修正すべき点
Esriさんのスタイルでは、参照url、sprite、glyphsが相対パスで記載されています。そこで、Maplibreでも参照しやすいように、絶対パスに修正します。絶対パスはスタイルファイルからの相対パスがspriteは「../sprites/sprite」、glyphsは「../fonts/{fontstack}/{range}.pbf」と記載されていることを考えることで、以下だと分かります。

spriteのURL: 
https://pro-ags2.dfs.un.org/arcgis/rest/services/Hosted/Clearmap_Webplain/VectorTileServer/resources/sprites/sprite

glyphsのURL:
https://pro-ags2.dfs.un.org/arcgis/rest/services/Hosted/Clearmap_Webplain/VectorTileServer/resources/fonts/{fontstack}/{range}.pbf

次にベクトルタイルのソースの場所を指定します。この部分が理解出来ていませんが、参考記事において、
「esriのスタイルではVectorTileSeverのindex.jsonを返すパスを指定していると思うので、VectorTileServer/tile/{z}/{y}/{x}.pbf とパスを指定してあげる必要があります（urlでなく、tileとして書く）」
とのことなので、以下のパスを指定します。
ベクトルタイルのソース: 
https://pro-ags2.dfs.un.org/arcgis/rest/services/Hosted/Clearmap_Webplain/VectorTileServer/tile/{z}/{y}/{x}.pbf

YAMLファイルを上記の通り修正すると以下のようになります。ベクトルタイルのソースについては、tilesとして、さらに改行し「-」をつけることで、配列形式にする必要があることに注意が必要です。

![スクリーンショット 2024-09-11 14.35.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/7f9df31a-d4f0-f3d7-0fdc-2da8784b2cfd.png)

これらの修正をするとcharitesのライブプレビューが以下のコマンドで利用出来るようになります。

```
charites serve root.yml
```

以下の通り無事に地図が見られました。

![スクリーンショット 2024-09-11 14.47.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/a8526735-c7fa-f86b-2b5c-70f57e26cc15.png)

### YAMLからjsonへの出力
作業を終えたら、YAMLファイルからjsonファイルに再変換します。
```
charites build root.yml root2.json
```

# Step 4. HTMLファイルの準備
マップライブラリとプラグインの準備が出来たので、map.htmlというHTMLファイルを準備します。

[こちらの記事](https://qiita.com/k96mz/items/588a5241327f51cb5f9f)で使用したindex.htmlを改変して以下のように記載します。


```html:map.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Display a map</title>
    <meta
      property="og:description"
      content="Initialize a map in an HTML element with MapLibre GL JS."
    />
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <script src="./maplibre-gl@5.3.0/maplibre-gl.js"></script>
    <link href="./maplibre-gl@5.3.0/maplibre-gl.css" rel="stylesheet" />
    <link
      href="./watergis/maplibre-gl-export@4.0.1/maplibre-gl-export.css"
      rel="stylesheet"
    />
    <script src="./watergis/maplibre-gl-export@4.0.1/maplibre-gl-export.umd.js"></script>
    <link
      href="./watergis/maplibre-gl-legend@2.0.5/maplibre-gl-legend.css"
      rel="stylesheet"
    />
    <script src="./watergis/maplibre-gl-legend@2.0.5/maplibre-gl-legend.umd.js"></script>
    <style>
      body {
        margin: 0;
        padding: 0;
      }
      html,
      body,
      #map {
        height: 100%;
      }
    </style>
  </head>
  <body>
    <div id="map"></div>
    <script>
      const map = new maplibregl.Map({
        container: "map", // container id
        style: "./root2.json", // style URL
        center: [0, 0], // starting position [lng, lat]
        zoom: 1, // starting zoom
        maplibreLogo: true,
        hash: true,
      });

      //UI
      map.addControl(new maplibregl.NavigationControl(), "bottom-right");
      map.addControl(new maplibregl.ScaleControl());

      //Export
      map.addControl(
        new MaplibreExportControl.MaplibreExportControl({
          PageSize: MaplibreExportControl.Size.A4,
          PageOrientation: MaplibreExportControl.PageOrientation.Landscape,
          Format: MaplibreExportControl.Format.PNG,
          DPI: MaplibreExportControl.DPI[300],
          Crosshair: true,
          PrintableArea: true,
          Local: "en",
        }),
        "top-right"
      );

      //legend
      map.addControl(
        new MaplibreLegendControl.MaplibreLegendControl(
          {},
          {
            showDefault: false,
            onlyRendered: true,
            reverseOrder: true,
          }
        ),
        "bottom-left"
      );

      //debug
      map.showTileBoundaries = true;
      map.showCollisionBoxes = false;
    </script>
  </body>
</html>

```

legendについて、参考URLにはデフォルトで記載のあったshowCheckboxのプロパティを削除することで、デフォルトでレイヤのオンオフが出来るようにしています。また、配置場所を"bottom-left"とすることで左下にしています。


# Step 5. GitHubページの設定
GitHubレポジトリにpushすることで、地図が見られるようになります。

![スクリーンショット 2024-09-11 15.50.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/6dc5eb19-7fb9-2483-a9ef-0987d378bbfe.png)

# Step 6. 作業結果の確認
以下のURLから地図が見られます。
https://k96mz.github.io/20240911ClearMap/map.html

![スクリーンショット 2024-09-11 17.05.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/91b362cb-5ca2-1dc4-eedb-074b58b67b00.png)

左下にlegendを見るためのアイコンがあり、さらに右上にはexport用のアイコンがあるので、正常にプラグインが読み込まれていることが分かります。



# まとめ
UN Clear Mapをベクトルタイルで作成してみました。Esriさんのベクトルタイルの構造をまだ詳しく見ていないので、別記事を作成してMaplibreとの違いを理解したいと思います。


# Reference

https://qiita.com/T-ubu/items/5092eabb6d1dae3cc6e4

https://www.un.org/geospatial/mapsgeo/webservices

https://maplibre-gl-export.water-gis.com/

https://github.com/watergis/maplibre-gl-legend/tree/main/packages/maplibre-gl-legend


Clear mapのベクトルタイルのメインページ？

https://pro-ags2.dfs.un.org/arcgis/rest/services/Hosted/Clearmap_Webplain/VectorTileServer/

ベクトルタイルのダウンロードを確認出来るURL

https://pro-ags2.dfs.un.org/arcgis/rest/services/Hosted/Clearmap_Webplain/VectorTileServer/tile/1/1/1.pbf

Esriスタイルファイルのページ

https://pro-ags2.dfs.un.org/arcgis/rest/services/Hosted/Clearmap_Webplain/VectorTileServer/resources/styles/root.json

ベクトルタイルのClear Mapが見られるページ

https://pro-ags2.dfs.un.org/arcgis/rest/services/Hosted/Clearmap_Webplain/VectorTileServer?f=jsapi