smellman.hatenablog.com
この記事にあるosm2vectortilesは古いため、Dockerのインストール方法以外は新しい記事を参考にしてください。
OpenStreetMap Advent Calendar 2016 3日目の記事です。
今回はOpenStreetMapのデータを使ってMapbox Vector Tileを自分で作ってみることに挑戦してみました。
対象となる環境はUbuntu 16.10をインストールしているThinkpad X220です。スペックは以下の通りです。
- CPU
- Intel(R) Core(TM) i5-2540M CPU @ 2.60GHz (物理2コア/論理4コア)
- Memory
- 16GB
- Storage
- SSD 240GB
なお、このマシンは本体と換装パーツ込で33000円ぐらいで揃えたものです*1
さて、余談はよいとして、Mapbox Vector Tileを作るに当たって、今回はosm2vectortilesのGenerate your own vector tilesを参考に行いました。
まず先にosm2vectortilesについて軽く紹介したいと思います。
このプロジェクトはOpenStreetMapをベースとしたMapbox Vector Tileの地図タイルを自由にダウンロードできるようにするもので、世界全域の地図タイル以外にもいろんな地域の地図タイルがmbtiles形式でホスティングされています。また、地図タイルの作成にdockerを活用しているのが特長です。また、地図タイルを長くやってる人にはMapTilerというプロダクトで有名なKlokan Technologiesがスポンサーをしていることも話題になりました。俺も久々にこのカンガルーの会社ロゴ見てびっくりした(汗
さて、さっそく作業をしていきます。まずはDockerとDocker-composeをインストールします。
sudo apt-get install docker docker-compose
sudo service docker start
sudo docker run hello-world
次に一般ユーザで作業をするためにdockerグループにユーザを追加します。
sudo usermod -aG docker $USER
これで一旦リブートをして再度ログインして、一般ユーザで動作するかを確認します。
docker run hello-world
dockerが一般ユーザで動くようになったら次にosm2vectortilesをgithubから落としてきます。
mkdir -p ~/develop/osm
cd develop/osm
git clone https://github.com/osm2vectortiles/osm2vectortiles.git
cd osm2vectortiles
今回の作業パスは ~/develop/osm/osm2vectortiles とします。
まずは手順通りにdocker-composeでPostGISのコンテナを取得します。
docker-compose up -d postgis
ここで一旦別のディレクトリを作成して、そこに今回使うファイルをダウンロードします。
まずはテストということで、bbbikeから東京の範囲のpolyファイルとPBFファイルをダウンロードします。polyファイルは後でBBOXの範囲を計算するのに使います。
mkdir -p ~/tmp/osmdata
cd ~/tmp/osmdata
wget http://download.bbbike.org/osm/bbbike/Tokyo/Tokyo.poly
wget http://download.bbbike.org/osm/bbbike/Tokyo/Tokyo.osm.pbf
次にPBFファイルをosm2vectortiles/importに配置します。
cp ~/tmp/osmdata/Tokyo.osm.pbf ~/develop/osm/osm2vectortiles/import/
次にまた別の作業ディレクトリを作成して、OpenStreetMapDataからwater-polygonsとsimplified-water-polygonsを、Natural Earthからnatural_earth_vectorのSQLiteのファイルをダウンロードします*2。
mkdir -p ~/tmp/osmpoly
cd ~/tmp/osmpoly
wget http://data.openstreetmapdata.com/water-polygons-split-3857.zip
wget http://data.openstreetmapdata.com/simplified-water-polygons-complete-3857.zip
wget http://naciscdn.org/naturalearth/packages/natural_earth_vector.sqlite.zip
これらを全てunzipしてから必要なファイルをosm2vectortiles/importにコピーします。
unzip water-polygons-split-3857.zip
unzip simplified-water-polygons-complete-3857.zip
unzip natural_earth_vector.sqlite.zip
cp ~/tmp/osmpoly/water-polygons-split-3857/water_polygons.* ~/develop/osm/osm2vectortiles/import/
cp ~/tmp/osmpoly/simplified-water-polygons-complete-3857/simplified_water_polygons.* ~/develop/osm/osm2vectortiles/import/
cp ~/tmp/osmpoly/packages/natural_earth_vector.sqlite ~/develop/osm/osm2vectortiles/import/
最終的にosm2vectortiles/importディレクトリが以下のようになります。
% ls -l import
合計 1079640
-rw-r--r-- 1 btm btm 18088604 12月 3 15:11 Tokyo.osm.pbf
-rw-r--r-- 1 btm btm 414519296 12月 3 15:16 natural_earth_vector.sqlite
-rw-r--r-- 1 btm btm 6 12月 3 15:16 simplified_water_polygons.cpg
-rw-r--r-- 1 btm btm 74837 12月 3 15:16 simplified_water_polygons.dbf
-rw-r--r-- 1 btm btm 853 12月 3 15:16 simplified_water_polygons.prj
-rw-r--r-- 1 btm btm 29614272 12月 3 15:16 simplified_water_polygons.shp
-rw-r--r-- 1 btm btm 49948 12月 3 15:16 simplified_water_polygons.shx
-rw-r--r-- 1 btm btm 6 12月 3 15:15 water_polygons.cpg
-rw-r--r-- 1 btm btm 452789 12月 3 15:15 water_polygons.dbf
-rw-r--r-- 1 btm btm 847 12月 3 15:15 water_polygons.prj
-rw-r--r-- 1 btm btm 642308932 12月 3 15:15 water_polygons.shp
-rw-r--r-- 1 btm btm 301916 12月 3 15:15 water_polygons.shx
では、またosm2vectortilesの作業ディレクトリに戻って手順書通りに作業を進めていきます。
docker-compose up import-external
docker-compose up import-osm
docker-compose up import-sql
ここまできたらあとはexportをするのみとなりますが、BBOX(範囲)のパラメータを与えないと世界中が対象となってしまうので、BBOXの値を計算します。
BBOX自体はwest,south,east,northの順にパラメータを与えます。
なので、経度180度線を気にしなければ、min(longitudes),min(latitudes),max(longitudes),max(latitudes)となります。
今回の東京の範囲のPOLYファイルをみると今回は単純な四角形なので値は簡単にわかります。
Tokyo
1
139.62 35.56
139.95 35.56
139.95 35.78
139.62 35.78
END
END
これを読めば、BBOX=139.62,35.56,139.95,35.78という値がとれるので、それを使ってドキュメントに沿ってexportを実行します。今回はzoom 9からzoom 14までを作成してみます。
docker-compose run \
-e BBOX="139.62,35.56,139.95,35.78" \
-e MIN_ZOOM="9" \
-e MAX_ZOOM="14" \
export
docker-compose up export
これらを実行するとexport以下にtiles.mbtilesというファイルができあがります*3。ただし、dockerで生成したためか所有者がrootのファイルになっているので、所有者の変更とあとでファイルを変更しても良いように別名でコピーをとっておきます。
sudo chown $USER:$USER ~/develop/osm/osm2vectortiles/export/tiles.mbtiles
cp ~/develop/osm/osm2vectortiles/export/tiles.mbtiles ~/develop/osm/osm2vectortiles/export/tokyo.mbtiles
あとは実際に動作するかをチェックします。
これはGetting Startedではtileserver-gl-lightを使うようになっているのですが、tileserver-gl-light自体はすでに古く、tileserver-glが最新になっているのでそちらを使うようにします。
ただし、tileserver-glの方は現在npm installに失敗してしまいます*4。
なので、今回はtileserver-glのdockerを使って検証してみます。
cp ~/develop/osm/osm2vectortiles/export/tokyo.mbtiles /tmp/
cd /tmp
docker run -it -v $(pwd):/data -p 8080:80 klokantech/tileserver-gl
これでサーバが動いているIPアドレスの 8080 port へアクセスします。
ここでBasicスタイルのVectorタイルを選択します。
初期状態でzoom 2なのですが、何も出ててきません。しかし、ズームアウトすると...
全球が出てきます。そこで東京の方に見ていきます
途中まではすごく雑です。
作成したズーム9からはちゃんと出てきます。
とりあえずズーム14までちゃんと作られたのが確認できます。
では、せっかくなのでズーム0〜ズーム8をマージしてみましょう。
マージはドキュメントにあるようにMapboxのmbutilにあるpatchというシェルスクリプトを使います。なお、sqlite3が入っている必要があります。また、ドキュメントにあるmbtilesのダウンロードはズームレベル5までのもの*5なので、ダウンロードページからPlanet from zoom level 0 to 8を選んでダウンロードします。
cd ~/develop/osm/osm2vectortiles/export
wget https://osm2vectortiles-downloads.os.zhdk.cloud.switch.ch/v2.0/planet_2016-06-20_7088ce06a738dcb3104c769adc11ac2c_z0-z8.mbtiles
wget https://raw.githubusercontent.com/mapbox/mbutil/master/patch
chmod +x patch
cp tokyo.mbtiles tokyo-and-planet.mbtiles
./patch planet_2016-06-20_7088ce06a738dcb3104c769adc11ac2c_z0-z8.mbtiles tokyo-and-planet.mbtiles
これも同様に動かしてみましょう。
rm /tmp/tokyo.mbtiles
cp ~/develop/osm/osm2vectortiles/export/tokyo-and-planet.mbtiles /tmp
cd /tmp
docker run -it -v $(pwd):/data -p 8080:80 klokantech/tileserver-gl
最初から全球がレンダリングされていていい感じです。
日本の形もちゃんと出てきます。
ただし、zoom 8あたりで残念なマージになりました。
まぁ、ファイルを上書きしてしまってるのでしょうがないとはいえます。
とりあえずこれである程度の地図タイルが作れるようになりました。
では、せっかくなので日本全国の地図タイルを作ってみましょう。
まずはGeofebrikのOSMデータのミラーサイトから日本全体のデータをダウンロードします。
cd ~/tmp/osmdata
wget http://download.geofabrik.de/asia/japan.poly
wget http://download.geofabrik.de/asia/japan-161202.osm.pbf
次に、以前の作業に使ったpbfファイルの削除と、以前使ったdocker-composeを全て削除します。
docker-composeを削除するのはどうもpgdataを削除したぐらいでは何かが残ってしまっていてimposm3のmergeの処理が走ってしまうためです。
ただ、すでにイメージ自体はダウンロードしてるので再構築自体は高速です。
cd ~/develop/osm/osm2vectortiles
rm import/Tokyo.osm.pbf
docker-compose stop postgis
docker-compose rm -f export
docker-compose rm -f import-sql
docker-compose rm -f import-osm
docker-compose rm -f import-external
docker-compose rm -f postgis
docker-compose rm -f pgdata
docker-compose rm -f cache
あとは以前の手順と同様に再構築を進めます。
cp ~/tmp/osmdata/japan-161202.osm.pbf import
docker-compose up -d postgis
docker-compose up import-external
docker-compose up import-osm
docker-compose up import-sql
次にBBOXを取り出したいのですが、日本の範囲として定義されているPOLYファイルはPOLYGONになっていてちょっと計算が面倒なので、とりあえずスクリプトをでっち上げたのでこれを使ってBBOXの値をゲットします。
cd ~/tmp/osmdata
wget https://gist.githubusercontent.com/smellman/a2770f3a6c4717315cc0a4538b985a1c/raw/1008b6d5f061fb7c0eeaddef86d8faf68f1a6d57/poly2bbox.py
% python poly2bbox.py japan.poly
BBOX=122.5607,21.20992,153.8901,45.80245
こんな感じで取れるのでこれをBBOXのパラメータとして使います。
なお、今回はMAX_ZOOMを13としています。というのはどうもズーム9から14で試したら17時間ぐらい処理にかかるらしく、今日のAdvent Calendarに間に合わないので...*6
docker-compose run \
-e BBOX="122.5607,21.20992,153.8901,45.80245" \
-e MIN_ZOOM="9" \
-e MAX_ZOOM="13" \
export
docker-compose up export
できあがったのはだいたい550MBぐらいのmbtilesで、 exportの処理時間はおよそ3時間ぐらい、importを含めてだいたい4時間ぐらいでいけました*7。
あとはバックアップを取ってからtileserver-glでチェックをしてみます。
rm /tmp/tokyo-and-planet.mbtiles
sudo chown $USER:$USER ~/develop/osm/osm2vectortiles/export/tiles.mbtiles
cp ~/develop/osm/osm2vectortiles/export/tiles.mbtiles ~/develop/osm/osm2vectortiles/export/japan.mbtiles
cp ~/develop/osm/osm2vectortiles/export/japan.mbtiles /tmp
cd /tmp
docker run -it -v $(pwd):/data -p 8080:80 klokantech/tileserver-gl
東京周辺はこんな感じです。
千葉市周辺、ちょっとレンダリング対象が少ない感じです。
伊豆大島も建物がレンダリングされていないので寂しいです。
三宅島も同様です。
やっぱりzoom 14の壁が厚いなーという印象ですね。
とりあえずzoom 14だけ足せるかこんなコマンド打って放置しておきます。
sudo chown root:root ~/develop/osm/osm2vectortiles/export/tiles.mbtiles
docker-compose run \
-e BBOX="122.5607,21.20992,153.8901,45.80245" \
-e MIN_ZOOM="9" \
-e MAX_ZOOM="14" \
export
あと13時間後らしいので、お楽しみですね!!!!!1