MapLibre GLを使用した TileServer GL（地図タイルサーバー）を立ててみた 

　TileServer GL はMapbox GL JSによってサーバーサイドでベクター地図タイルをレンダリング（グーグルマップみたいなやつ）できるオープンソースの地図タイルサーバーです。
　Mapbox GL JS v1のころはMapbox側のサービスを利用しない場合、料金がかからなかったのですが、2020年12月にv2が発表されて以降は、オープンソースではなくなりMapbox独自で開発を進める方針に切り替わったため、Mapbox GL JS v2を利用するためにはMapboxサービスのアクセストークンが必須になりました。
　一方、Mapbox GL JSとは別のオープンソースプロジェクトとしてMapLibre GL JSが生まれています。
こちらは、Mapbox GL JS v1.13.0をフォークした後、マイナーアップデートが主でしたが、最近は独自の発展を遂げているといった感じです。AWSでもこのMapLibre GL JSを使った地図サービスなんかも出てたりしています。
そんなMapLibre GL JS NativeになったTileServer GLで地図タイルサーバーを立ててみました。


## 環境
AWS EC2(t4g.small)
Ubuntu22.04
docker


# 参照

```
https://github.com/maptiler/tileserver-gl
```

上記を使ってインストールをと思ったのですが、今回Graviton2(t4g.small:2022年12月末まで無料トライアル期間)で動かそうと思ったらarmプロセッサでアーキテクチャが違うからか、プラットフォームがマッチしないエラーで立ち上がりませんでした。

```bash
$ sudo docker run --name tileserver-gl -u 0 --rm -it -v $(pwd):/data -p 8080:8080 maptiler/tileserver-gl --mbtiles zurich_switzerland.mbtiles
WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
exec /usr/src/app/docker-entrypoint.sh: exec format error
```
あれこれ試してみたところ、上記のソースをフォークした以下であれば、今回のGraviton2(t4g.small)の環境でもうまくいったので、今回は↓こちらを使うことにします。

```
https://github.com/acalcutt/tileserver-gl
```

# インストール

tileserver-glをインストールしようと思えばできるのですが、Nodeをインストールしたり、依存関係のライブラリをインストールしたりと、環境構築が大変なので、今回は、Dockerでtileserver-glを起動できるようにします。

・dockerをインストール
```bash
$ sudo apt update
$ sudo apt install docker.io
```

# 地図タイルダウンロード
地図タイル（mbtiles形式）とスタイル・フォントとコンフィグ（config.json）がセットになっているテストデータを今回使用します。

```bash
$ wget https://github.com/acalcutt/tileserver-gl/releases/download/test_data/test_data.zip
$ sudo apt install unzip   #unzipがインストールされていない場合
$ unzip test_data.zip      #ファイルを解凍
```

# 地図タイル起動

```bash
$ docker run --rm -u 0 -it -v $(pwd):/data -p 8080:8080 wifidb/tileserver-gl --mbtiles zurich_switzerland.mbtiles  #地図タイルを指定
```

これで起動するはずです。
ちなみにdockerで起動するところで、githubで書かれている以下のコマンドだとpermission deniedのエラーが出てしまいました。rootユーザーで実行するオプション「-u 0」をつけてあげるとエラーせずに実行できます。

```bash
$ docker run --rm -it -v $(pwd):/data -p 8080:8080 wifidb/tileserver-gl --mbtiles zurich_switzerland.mbtiles
Starting @acalcutt/tileserver-gl v5.2.0
[INFO] Automatically creating config file for zurich_switzerland.mbtiles
[INFO] Only a basic preview style will be used.
[INFO] See documentation to learn how to create config.json file.
node:internal/fs/utils:347
    throw err;
    ^

Error: EACCES: permission denied, stat '/data/zurich_switzerland.mbtiles'
    at Object.statSync (node:fs:1583:3)
    at startWithMBTiles (file:///usr/src/app/src/main.js:86:27)
    at file:///usr/src/app/src/main.js:202:14
    at FSReqCallback.oncomplete (node:fs:202:21) {
  errno: -13,
  syscall: 'stat',
  code: 'EACCES',
  path: '/data/zurich_switzerland.mbtiles'
}
```

# 動作確認
地図タイルサーバーが起動したのでブラウザでアクセスしてみます。
デフォルトは8080番ポートで立ち上がります。
http://{IPアドレス}:8080/

![tile01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747663/a7c199f1-7d35-2ad7-8b6b-d605da4c8e4a.png)

地図タイルにもアクセスできます。
拡大縮小、マウスで動かすこともできます。
左下には、「MapLibre」のロゴなんかも表示されていたりします。

![tile02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747663/c9f63f82-0392-ea11-c9b4-628cb9247b46.png)

また、右上の方にある、以下のマークをクリックすると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747663/f2daa6ef-b4a2-fd82-4758-a7df67873526.png)

地物の情報を表示してくれるインスペクトモードに切り替えることができます。
過去のバージョンだとインスペクトモードの入り口から入ってという感じだったので、ボタン一つで地図タイルとインスペクトモードを自由に切り替えられるのは便利です。

![tile03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2747663/b9c45b7f-1326-9cf9-e47e-fd9d2659f5c4.png)


# サービス化
動作確認はできましたが、毎回Dockerコマンドを打って立ち上げるということだと面倒なので、
サービス化（今回はtileserver-gl.serviceという名前）して、サーバー起動時に自動で立ち上がるようにしておきます。

サービス起動用シェル（start.sh）サービス停止用シェル（stop.sh）を作っておきます。

```bash:start.sh
#!/usr/bin/bash
cd /home/ubuntu
sudo docker run --name tileserver-gl -u 0 --rm -v $(pwd):/data -p 8080:8080 wifidb/tileserver-gl --mbtiles zurich_switzerland.mbtiles
```
サービス起動の場合だと、インタラクティブに操作しないので、「-it」オプションは取っておきます。
サービス停止するのにコンテナを指定する必要があるので、name（今回はtileserver-glという名前）を定義しておきます。

```bash:stop.sh
#!/usr/bin/bash
sudo docker stop --time 2 tileserver-gl
```

これらのサービス起動用シェルとサービス停止用シェルを使ってtileserver-glサービスを作ります。
```bash:/lib/systemd/system/tileserver-gl.service
[Unit]
Description=tileserver-gl
Requires=docker.service
After=docker.service

[Service]
Type=simple
Restart=always
ExecStart=/home/ubuntu/start.sh
ExecStop=/home/ubuntu/stop.sh

[Install]
WantedBy=multi-user.target
```

# サービス起動
```bash
$ sudo systemctl start tileserver-gl.service   #サービス起動
$ sudo systemctl status tileserver-gl.service   #サービス確認
$ sudo systemctl enable tileserver-gl.service  #自動起動
```

これでOS再起動しても自動で地図タイルサーバーが立ち上がってくるようになりました。

今回はテストデータの地図タイルでしたが、例えばgeojsonデータをmbtiles形式に変換するなどして、自分で作った地図データを読み込んで地図タイルを表示することもできます。
試してみてはいかがでしょうか。