🐙

地図タイルサーバをローカル環境に立てて大量の地図画像ファイルを生成する

2021/10/30に公開1

先日、以下のような地図を表示するOGP画像の生成しました。

東海道新幹線

このサイトの特性上、このような画像を個別に準備する必要があり、大量の地図画像ファイルを生成しなければいけません。

外部のOpenStreetMapの地図タイルサーバを使うと時間もかかり高負荷をかける可能性があり迷惑にもなりますので、ローカル環境でOSMのタイルサーバを準備してそれを使って地図画像を生成できるようにしてみました。

具体的には、以下の手順で行いました。

  1. OpenMapTiles で MBTiles ファイルを作成
  2. tileserver-gl でタイルサーバを起動
  3. StaticMaps で地図画像ファイルを生成

地図タイルデータ準備

OpenMapTiles を使って日本のタイルデータを作成します。
あらかじめ Docker を使えるようにしておいてください。

まず、以下の実行して OpenMapTiles が動くかどうか確認します。

$ git clone https://github.com/openmaptiles/openmaptiles.git
$ cd ./openmaptiles
$ git checkout -b v3.12.2 refs/tags/v3.12.2 // 2021年10月現在の最新のリリースバージョン
$ docker-compose pull
$ ./quickstart.sh

全ての実行が完了すると、dataディレクトリ内に、tiles.mbtilesファイルが生成されると思います。このファイルは、アルメニアのタイルデータです。

動作に問題がないことが確認できたら、次は日本のタイルデータを作成します。
実行中に日本のOSMデータを自動的にダウンロードしてくれるので、特にデータを用意する必要はありません。

その前に、作成されるタイルデータの最大ズームレベルを変更します。デフォルトは 7ですが、14に変更します。.envファイルの MAX_ZOOM=7 の値を 14 に変更して保存してください。

.env
...
# Which zooms to generate in   make generate-tiles
MIN_ZOOM=0
MAX_ZOOM=14
...

次に、以下を実行します。

$ ./quickstart.sh japan

実行すると完了まで、かなりの時間がかかります。私の環境では丸2日かかりました。一度作成しておけば、地図データを更新する必要がないのであれば毎回実行する必要はありません。
完了すると、data/tiles.mbtiles が作成されます。私が作成したときは、1.64GB のファイルができました。日本国内を網羅するタイルデータと考えるととても小さいように感じますし、PC内に置いていても気にならないレベルのサイズだと思います。

地図タイルサーバ起動

OpenMapTiles を使ってもタイルサーバを起動できるようですが、地図画像ファイルを生成するときのスタイルを指定したいので、別途、tileserver-gl を使いました。

スタイルは、できるだけ OpenStreetMap に近いものを使いたいので、以下の二つを利用できるようにします。

  1. osm-bright-gl-style
  2. osm-liberty-gl-style

これらは tileserver-gl ではそのままでは使えず、いろいろと準備や改修しないといけないようで面倒なので、docker-compose で起動すれば動くリポジトリを以下に作成しました。

https://github.com/uedayou/tileserver-gl-docker-compose

前述で作成したMBTiles ファイルがあれば簡単にタイルサーバを起動できます。

$ git clone --recursive https://github.com/uedayou/tileserver-gl-docker-compose.git
$ cd tileserver-gl-docker-compose
$ mv /[OpenMapTilesのパス]/data/tiles.mbtiles ./data/
$ docker-compose up

http://localhost:8080/ をブラウザで開くと以下のようなページが表示されます。

tileserver-gl

BrightOSM LibertyViewer ボタンを押すと各スタイルの地図が表示できます。
それぞれ、以下のような地図が表示されます。

Bright
Bright

OSM Liberty
OSM Liberty

OSM Libertyについては、以下のような3D表示もできるようです。
3D Map

地図画像ファイル生成

ローカル環境で起動したタイルサーバを使用して地図画像ファイルを作成してみます。
ここでは、Node.js 製の StaticMaps を使います。

各スタイルのタイルURLは以下になります。

Bright

http://localhost:8080/styles/osm-bright/{z}/{x}/{y}.png

OSM Liberty

http://localhost:8080/styles/osm-liberty/{z}/{x}/{y}.png

例えば以下のコードを実行して東京駅周辺の地図をOSM Libertyで作成してみます。

index.js
const StaticMaps = require('staticmaps');

(async ()=>{
  const options = {
    width: 1200,
    height: 630,
    tileUrl: 'http://localhost:8080/styles/osm-liberty/{z}/{x}/{y}.png',
  };
  const map = new StaticMaps(options);
  await map.render([139.76811, 35.68099]);
  await map.image.save('./map.png');
})();
$ npm i staticmaps
$ node index.js

以下のような地図画像が生成されます。

この画像はローカル環境にあるタイルサーバで作成したものなので、もちろんオフライン環境下でも作成できますし外部タイルサーバへの負荷をかける心配もないので、安心して大量の地図画像ファイルの生成ができるようになりました。

今回、以下のサイトがとても参考になりましたので最後に紹介させていただきます。
https://smellman.github.io/vector_tile_book/

Discussion

shrikeshrike

記事参考にさせていただきました。先程実施したら、3hでダウンロードできました。
2.1Gでした。高速化されたのかな?
-rw-r--r-- 1 root root 2.1G 8月 11 19:52 tiles.mbtiles