地図タイルサーバをローカル環境に立てて大量の地図画像ファイルを生成する
先日、以下のような地図を表示するOGP画像の生成しました。
このサイトの特性上、このような画像を個別に準備する必要があり、大量の地図画像ファイルを生成しなければいけません。
外部のOpenStreetMapの地図タイルサーバを使うと時間もかかり高負荷をかける可能性があり迷惑にもなりますので、ローカル環境でOSMのタイルサーバを準備してそれを使って地図画像を生成できるようにしてみました。
具体的には、以下の手順で行いました。
- OpenMapTiles で MBTiles ファイルを作成
- tileserver-gl でタイルサーバを起動
- 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
に変更して保存してください。
...
# 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 に近いものを使いたいので、以下の二つを利用できるようにします。
これらは 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/ をブラウザで開くと以下のようなページが表示されます。
Bright
か OSM Liberty
の Viewer
ボタンを押すと各スタイルの地図が表示できます。
それぞれ、以下のような地図が表示されます。
Bright
OSM Liberty
OSM Liberty
については、以下のような3D表示もできるようです。
地図画像ファイル生成
ローカル環境で起動したタイルサーバを使用して地図画像ファイルを作成してみます。
ここでは、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
で作成してみます。
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
記事参考にさせていただきました。先程実施したら、3hでダウンロードできました。
2.1Gでした。高速化されたのかな?
-rw-r--r-- 1 root root 2.1G 8月 11 19:52 tiles.mbtiles