Martinで行政界ポリゴンのベクトルタイルサーバーを構築してみた

## はじめに
今回はMartinを使って、ベクトルタイルサーバーをローカル環境に構築してみました。Martinの入門的な内容ですが、つまづくこともあったので書き残したいと思いました。

### Martinとは
> Martin is a tile server able to generate and serve vector tiles on the fly from large PostGIS databases, PMTiles (local or remote), and MBTiles files, allowing multiple tile sources to be dynamically combined into one. Martin optimizes for speed and heavy traffic, and is written in Rust.

Martinとは、PostGISデータベース、PMTiles（ローカルまたはリモート）、MBTilesファイルからベクトルタイルを提供するサーバーであり、複数のタイルソースをまとめたり、速度面やトラフィックの増加にも最適化されたものとあります。

今回はPostGISデータベースを対象としています。

https://maplibre.org/martin/
## 環境・利用したもの

 <table>
    <tr>
      <td>OS</td>
      <td>Windows 10 (64bit)</td>
    </tr>
    <tr>
      <td>Martin</td>
      <td>Dockerイメージ　ghcr.io/maplibre/martin</td>
    </tr>
    <tr>
      <td>Database</td>
      <td>Dockerイメージ　postgis/postgis<br>（ PostgreSQL16.2 / PostGIS3.4 ）</td>
    </tr>
 </table>

PostGISデータベースには、TerraMap API と同じ行政界ポリゴンのテーブルを以下の名前で登録し、Martinのタイルソースとしました。データベース構築に関する詳細な手順は、今回割愛させていただきます。

- city_polygon（市区町村ポリゴンテーブル）
- chomoku_polygon（町丁目ポリゴンテーブル）

https://www.mapmarketing.co.jp/terramap-api?grid=qiita&utm_source=qiita.com&utm_medium=referral&utm_campaign=qiita_martin_polygon_server_283ae01f05a901dc4fab_01

## Martin のサーバー起動まで
### 設定ファイルの出力
Martinの便利な機能の一つは、データベースさえ準備されていれば、ほぼ自動でタイル公開まで設定してくれる点だと思います。今回は以下のようなコマンドで、まず初期の設定ファイル（config.yaml）を出力してみました。

```:config.yamlの出力
docker run ^
  --network my-postgis-network ^
  -p 3000:3000 ^
  -v ホスト側の作業ディレクトリパス:/files ^
  -e DATABASE_URL=postgresql://user:password@postgis-container-name/db-name ^
  ghcr.io/maplibre/martin --save-config files/config.yaml --auto-bounds=skip
```

:::note info
**コマンドの補足：**
doker runに関するオプション設定が4つ並んでおり、最後の行はmartinコマンドとそのオプション設定になります。
MartinとPostGISはDockerコンテナで実現しているので、同じDockerネットワークに接続することで、コンテナ間の直接通信を可能にしています。
:::

### 設定ファイルの編集
公開したくないテーブルや関数がある場合は、出力された設定ファイルを編集する必要があります。今回は、最終的に以下のような設定ファイルになりました。公開したいテーブルは2つに絞り、auto_publishはfalseにしておきました。

```yaml:config.yaml
postgres:
  connection_string: postgresql://user:password@postgis-container-name/db-name
  auto_bounds: skip
  auto_publish: false
  tables:
    chomoku_polygon:
      schema: public
      table: chomoku_polygon
      srid: 4326
      geometry_column: geom
      geometry_type: MULTIPOLYGON
      properties:
        geocode: varchar
        gid: int4
        name: varchar
    city_polygon:
      schema: public
      table: city_polygon
      srid: 4326
      geometry_column: geom
      geometry_type: MULTIPOLYGON
      properties:
        geocode: varchar
        gid: int4
        name: varchar
  functions: {}
```

### サーバー起動（設定ファイルを指定）
以下のようなコマンドで、設定ファイルに従ったベクトルタイルサーバーを起動させることができます。

```:サーバー起動
docker run ^
  --network my-postgis-network ^
  -p 3000:3000 ^
  -v ホスト側の作業ディレクトリパス:/files ^
  ghcr.io/maplibre/martin --config files/config.yaml
```

今回の各エンドポイントは以下になります。
 <table>
    <tr>
      <td>localhost:3000/catalog</td>
      <td>ソースリスト</td>
    </tr>
    <tr>
      <td>localhost:3000/city_polygon/{z}/{x}/{y}</td>
      <td>市区町村タイル</td>
    </tr>
    <tr>
      <td>localhost:3000/chomoku_polygon/{z}/{x}/{y}</td>
      <td>町丁目タイル</td>
    </tr>
 </table>

## 町丁目タイルの表示例
町丁目タイルを、OpenStreetMapのWeb地図にオーバーレイさせてみると、以下のようになりました。
![martin_chomoku_polygon.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2893989/5ab2be2a-b118-6669-d1f3-30d182d8116c.gif)


:::note info
フロントエンド（MapLibre）のソースについては、以下の記事をご参照ください。URLとsource-layerを変更するだけで済みます。

[PostGISのST_AsMVTを使用してベクトルタイルサーバーを構築し、地図に表示させてみた](https://qiita.com/y-mto/items/f62d4410e063ee98baa7)
:::

## その他、わかったこと
最後ですが、Martinを使ってみて以下のようなことも分かりました。

**Webメルカトルでなくてもズレていない**
今回のジオメトリ(EPSG: 4326)は、Webメルカトルではありませんでしたが、背景地図とのズレは見受けられません。これはMartin側で変換を行っているからで、便利なところだと思いました。

https://github.com/maplibre/martin/blob/main/martin/src/pg/query_tables.rs

**ビューやマテリアライズドビューも指定できる**
設定ファイルの編集で、tableに対してビューやマテリアライズドビューも指定できるようです。そうなると、ポリゴンといろいろな属性データを結合することも可能で、これも便利だと思いました。

入門したばかりでまだ分からないことも多いですが、Martinは洗練されたベクトルタイルサーバーだと感じました。使いこなすことで、他にもいろいろなことができそうです。

最後まで読んでいただきまして、ありがとうございました。