Maputnikで地理院地図Vectorのスタイルを作成する

# 0. はじめに
ベクトルタイルのスタイル作成の練習をするために、Maputnikを利用して地理院地図Vectorのスタイルを作成してみます。

## Maputnikとは
Maputnikはオープンソースの[MapLibre Style Specification](https://maplibre.org/maplibre-style-spec/)のためのビジュアルエディタです。Maputnikを使用することで、JSONファイルを編集することなく、地図が表示されている画面で編集結果を確認しながらスタイル編集をすることが出来て便利です。

# 1. Maputnikで地理院地図Vectorのベクトルタイルを読み込む
まずは、[Maputnikのオンラインエディタ](https://maplibre.org/maputnik/
)を開きましょう。以下のようなサイトが開くと思います。
![maputnik1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/67f0fbcd-5ec8-3717-77b0-d90e738d2069.jpeg)

今回は、一から地図を作っていきたいので、「Open」を押して、一番下の「Empty Style」をクリックしましょう。そうすると、白い画面が表示されます。この時に気を付けることは、次のステップで日本付近を読み込んでいくので、日本付近にズームしてから、「Empty Style」をクリックすることです、そうしないと、地理院地図Vectorのスタイルを読み込んだ時に、その地図が表示されている領域がどこか分からなくなります。
![maputnik2edit.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/535e76c6-5c69-57e2-fa04-76dbc69f899a.jpeg)

次に「Data Sources」をクリックして、「Add New Srouce」に以下のように入力します。
![maputnik3edit.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/126e21e8-abeb-7559-6093-419c6da2df53.jpeg)


| プロパティ  | 値 | 説明 |
|:-:|:-:|:-:|
| Source ID  | v | 任意の値  |
| Source Type  | Vector(XYZ URLs)  | 既定値  |
| Tile URL | https\://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf  | [地理院地図VectorのタイルURL](https://github.com/gsi-cyberjapan/gsimaps-vector-experiment) |
| Min Zoom | 4 | 最小ズーム値  |
| Max Zoom | 16 | 最大ズーム値  |

:::note info
Source Typeは、Vector(XYZ URLs)とありますが、Tile URLは、{z}/{x}/{y}の順番となることに注意してください。
:::

最後に「Add Source」をクリックすると、以下の通り「Active Sources」として加えられます。
![maputnik4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/38acf892-56fc-ac0f-47cc-8892d4eed380.jpeg)


# 2. Maputnikで地理院地図Vectorのスタイルを作成する
では、次にデータソースからレイヤを追加しましょう。①Add Layerをクリックして、
ID: bg（任意の値でOK）
Type: Background
として、背景を設定します。

![maputnik5edit.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/6269f891-0782-d842-e9a0-e019aa6d189d.jpeg)

その後、①bgレイヤをクリックして選択し、②色を適当な値に設定します。
![maputnik6edit.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/c0ab9a51-faa1-262a-cbca-a4555d53f372.jpeg)

次に地理院地図Vectorのベクトルタイルのレイヤを読み込んでいきます。その際には、[地理院地図Vector提供実験](https://github.com/gsi-cyberjapan/gsimaps-vector-experiment?tab=readme-ov-file)のウェブサイトの[属性等の仕様詳細](https://maps.gsi.go.jp/help/pdf/vector/dataspec.pdf)の内容を読む必要があります。
![maputnik7edit.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/b29ae1a9-6da6-fca0-1e45-2017aefcc3e8.jpeg)

今回は、海岸線と水域を読み込むことにします。source-layerがそれぞれ、「coastline」、「waterarea」とあるので、これらをMaputnikに読み込む時の「source layer」とします。

まずは海岸線を読み込みます。

![maputnik8.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/a932512c-2b0f-f62a-94bc-d7481e5f5654.jpeg)

ID: coastline（任意の値、今回はSource Layerと同じ名前とした）
Type: Line（データタイプが線であるため）
Source: v（先ほど追加したソースを指定）
Source Layer: coastline（上記のレイヤの名称を記載）

次に水域を読み込みます。
![maputnik9.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/8aaabc42-e3ae-e15d-b361-27db0d784917.jpeg)

ID: waterarea（任意の値、今回はSource Layerと同じ名前とした）
Type: Fill（データタイプが面であるため）
Source: v（先ほど追加したソースを指定）
Source Layer: waterarea（上記のレイヤの名称を記載）

水域の色を以下のように青色に変化させました。
![maputnik10edit.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/f6ff9201-6b26-83f4-6d51-73337bc08859.jpeg)

ちなみに、レイヤーのリストはそのままレンダリングされるレイヤーの階層になっていて、一番下にあると一番上にレンダリングされます。

# 3. MapLibre GL JSで表示する
最後に作成したスタイルをMapLibre GL JSで表示してみましょう。まずは作成したスタイルファイルをダウンロードします。①「Export」をクリックして、②「Download Style」をクリックするとスタイルファイルがダウンロード出来ます。

![maputnik11edit.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/9b0cede8-2074-18fb-6092-c9bf5eb6ba02.jpeg)

ダウンロードされたスタイルファイルに、出典の追記をしたファイルが以下です。

```json:test_style.json
{
  "version": 8,
  "name": "Empty Style",
  "metadata": { "maputnik:renderer": "mlgljs" },
  "sources": {
    "v": {
      "type": "vector",
      "tiles": [
        "https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf"
      ],
      "minzoom": 4,
      "maxzoom": 16,
      "attribution": "<a href=\"https://maps.gsi.go.jp/vector/\" target=\"_blank\">国土地理院ベクトルタイル提供実験</a>"
    }
  },
  "sprite": "",
  "glyphs": "https://orangemug.github.io/font-glyphs/glyphs/{fontstack}/{range}.pbf",
  "layers": [
    {
      "id": "bg",
      "type": "background",
      "paint": { "background-color": "rgba(232, 225, 225, 1)" }
    },
    {
      "id": "coastline",
      "type": "line",
      "source": "v",
      "source-layer": "coastline"
    },
    {
      "id": "waterarea",
      "type": "fill",
      "source": "v",
      "source-layer": "waterarea",
      "paint": { "fill-color": "rgba(20, 101, 223, 1)" }
    }
  ],
  "id": "hfkgus5"
}
```

次に[こちらの記事](https://qiita.com/k96mz/items/c3bf08affc60164ca3da)で作成したHTMLファイルの中身を少し修正して、以下のようにします。style, center, zoomを変更しています。また、出典を明示するため、「maplibreLogo: true,」をコメントアウトしています。

```html:index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Using Maputnik</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" />
    <link
      rel="stylesheet"
      href="https://unpkg.com/maplibre-gl@4.1.3/dist/maplibre-gl.css"
    />
    <script src="https://unpkg.com/maplibre-gl@4.1.3/dist/maplibre-gl.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: "./text_style.json", // style URL
        center: [138.34, 35.66], // starting position [lng, lat]
        zoom: 5, // starting zoom
        // maplibreLogo: true,
      });
    </script>
  </body>
</html>
```

GigHub Pagesでアップロードした地図は[こちら](https://k96mz.github.io/20240514MaputnikQiita/)から見られます。

![maputnik12.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3684675/e14b8261-7165-49d9-7f4b-20b67e8191a1.jpeg)

# 4. まとめ
Maputnikで地理院地図Vectorのスタイルを作成して、MapLibre GL JSで表示しました。Maputnikを使えば、色々なスタイリングが出来るので今後試していこうと思います。

# 5. リファレンス

https://qiita.com/asahina820/items/250a51ecacd8423d1a76

https://qiita.com/T-ubu/items/59ce878b2b19d5bad141

https://blog.geolonia.com/2020/03/20/add-source-from-gsi-japan.html