シェープファイルからベクタータイルを作成しTileServer GLで地図表示します。また、Maputnikでスタイルファイルを作成して地図にスタイルを適用します。
目次
シェープファイルを用意
シェープファイルとして今回は以下のデータを利用します。
- 国土数値情報ダウンロードサイト(国土交通省) / 行政区域 / 北海道(平成31年)N03-190101_01_GML.zip(2020/6/4取得)
$ ls -l 合計 41428 -rw-rw-r-- 1 ubu ubu 42415745 6月 4 19:34 N03-190101_01_GML.zip $ unzip N03-190101_01_GML.zip Archive: N03-190101_01_GML.zip inflating: KS-META-N03-19_01_190101.xml inflating: N03-19_01_190101.dbf inflating: N03-19_01_190101.geojson inflating: N03-19_01_190101.prj inflating: N03-19_01_190101.shp inflating: N03-19_01_190101.shx inflating: N03-19_01_190101.xml
GeoJSON に変換
シェープファイルをGeoJSONファイルに変換します。同時に、空間参照をEPSG:4326(WGS84)に変換します。
$ ogr2ogr -f GeoJSON Hokkaido.json -t_srs EPSG:4326 N03-19_01_190101.shp
mbtiles に変換
GeoJSONファイルをmbtilesファイルに変換します。
$ tippecanoe -o Hokkaido.mbtiles Hokkaido.json For layer 0, using name "Hokkaido" 9587 features, 4796684 bytes of geometry, 3454 bytes of separate metadata, 4722 bytes of string pool 99.9% 14/14849/5929
TileServer GL で地図表示
TileServer GLを起動してmbtilesを地図表示します。上記で作成したmbtilesファイルを--mbtiles
オプションで指定します。ちなみにオプションは他にも色々あります。
$ docker run -it -v $(pwd):/data -p 8080:80 klokantech/tileserver-gl --mbtiles Hokkaido.mbtiles Starting Xvfb on display 99 xdpyinfo: unable to open display ":99". Starting tileserver-gl v2.6.0 Automatically creating config file for Hokkaido.mbtiles WARN: MBTiles not in "openmaptiles" format. Serving raw data only... Run with --verbose to see the config file here. Starting server Listening at http://[::]:80/ Startup complete
http://localhost:8080
にアクセスするとトップページが表示されます。

トップページの「Inspect」ボタンを押すと地図表示されます。

トップページの「TileJSON」リンクを押すとJSONファイルの内容が表示されます。このTileJSONのURL(TileJSONの中に書かれているURLではなくTileJSON自体のURL、ここではhttp://localhost:8080/data/Hokkaido.json
)は後でスタイルを設定する際に使用します。

ここまでで、mbtilesへの変換までうまくいったことが確認できました。
Maputnik でスタイルファイルを作成
Maputnikを起動します。
$ docker run -it --rm -p 8888:8888 maputnik/editor Serving HTTP on 0.0.0.0 port 8888 (http://0.0.0.0:8888/) ...
http://localhost:8888
にアクセスするとスタイルエディタが表示されます。

デフォルトで色々とスタイルが設定されていますが、「Open」ー「Empty Style」を選択して一旦クリアします。

まっさらな状態になります。

「Data Sources」でデータソースを選択します。「TileJSON URL」には、前述のTileServer GLのトップページにあったTileJSONのURLを設定します。

まだスタイルを設定していないため、「View」がMapのままだと地図が見えません。「View」をInspectにすると地図が見えるようになります。

「Add Layer」からレイヤーを追加します。

レイヤーが追加され、スタイルを設定できるようになります。

レイヤーのスタイルを設定していきます。スタイルの反映結果が見えるようにするため「View」をMapに変更します。今回は「Color」と「Outline color」を設定してみます。スタイルをいじるとリアルタイムに地図に反映されます。うまく反映されない場合はレイヤー名の横の目の形のアイコンをクリックして表示・非表示を一度切り替えると表示されます。

スタイルの設定が完了したら「Export」でスタイルをJSONファイルとしてダウンロードします。

ダウンロードしたJSONを適当な名前に変更します。今回はHokkaido_style.json
とします。
{ "version": 8, "name": "Empty Style", "metadata": {"maputnik:renderer": "mbgljs"}, "sources": { "Hokkaido": { "type": "vector", "url": "http://localhost:8080/data/Hokkaido.json" } }, "sprite": "", "glyphs": "https://orangemug.github.io/font-glyphs/glyphs/{fontstack}/{range}.pbf", "layers": [ { "id": "layer1", "type": "fill", "source": "Hokkaido", "source-layer": "Hokkaido", "layout": {"visibility": "visible"}, "paint": { "fill-color": "rgba(168, 255, 187, 1)", "fill-outline-color": "rgba(255, 0, 0, 1)" } } ], "id": "meppdf0vz" }
スタイルを指定して TileServer GL を起動
TileServer GLにスタイルJSONの場所を指定するためにconfig.json
を作成します。config.json
では様々な設定ができますが、今回は以下のように最低限の設定を行います。スタイルのJSONファイルと地図のmbtilesファイルを指定しています。
{ "options": { "paths": { "styles": "./", "mbtiles": "" } }, "styles": { "mydesign": { "style": "Hokkaido_style.json" } }, "data": { "Hokkaido": { "mbtiles": "Hokkaido.mbtiles" } } }
TileServer GLを起動します。引数なしで起動するとデフォルトでカレントディレクトリのconfig.jsonが読み込まれて起動します。
$ docker run -it -v $(pwd):/data -p 8080:80 klokantech/tileserver-gl Starting Xvfb on display 99 xdpyinfo: unable to open display ":99". Starting tileserver-gl v2.6.0 Using specified config file from config.json Starting server Listening at http://[::]:80/ Startup complete GET /data/Hokkaido.json 200 4312 - 11.537 ms GET /data/Hokkaido.json 200 4312 - 12.097 ms GET /data/Hokkaido.json 200 4312 - 13.054 ms GET /data/Hokkaido.json 200 4312 - 20.552 ms GET /data/Hokkaido.json 200 4312 - 21.183 ms GET /data/Hokkaido.json 200 4312 - 21.755 ms GET /data/Hokkaido.json 200 4312 - 22.335 ms GET /data/Hokkaido.json 200 4312 - 22.827 ms GET /data/Hokkaido.json 200 4312 - 23.661 ms GET /data/Hokkaido.json 200 4312 - 24.502 ms GET /data/Hokkaido.json 200 4312 - 25.161 ms GET /data/Hokkaido.json 200 4312 - 25.832 ms GET /data/Hokkaido.json 200 4312 - 26.627 ms GET /data/Hokkaido.json 200 4312 - 1.207 ms
http://localhost:8080
にアクセスすると、先程は無かった「STYLES」という表示が追加されています。

「Viewer」を開くと、設定したスタイルどおりに地図が表示されます。初期表示位置や縮尺がいいかげんなので画面上のどこに地図が表示されているのか分かりにくいことがありますが、拡大・縮小(マウスホイール、+-アイコン)やスライド(マウスドラッグ、矢印キー)で調節できます。

「View」または「Vector」ではベクタータイルが、「Raster」ではラスタータイルが表示されます。ウェブブラウザの開発者ツールで見てみると、ベクタータイルの方はcanvas要素で描画されており、ラスタータイルの方はタイル画像で描画されているのが分かります。
また、ベクタータイルの方のみ、回転と視点移動(マウス右ボタンを押したままドラッグ)ができます。
Mapbox GL JS で表示
参考:OpenMapTilesのチュートリアル(Mapbox GL JS)
TestMapboxGLJS.html
<!DOCTYPE html> <html> <head> <link rel='stylesheet' href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.10.1/mapbox-gl.css'> <script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.10.1/mapbox-gl.js'></script> <script defer src="TestMapboxGLJS.js"></script> <style> html, body, #map { width: 100%; height: 100%; } </style> </head> <body> <div id='map'></div> </body> </html>
TestMapboxGLJS.js
var map = new mapboxgl.Map({ container: 'map', style: 'http://localhost:8080/styles/mydesign/style.json', center: [143, 43], zoom: 6 });
OpenLayers で表示
OpenLayersライブラリでOpenMapTilesを表示するには、ラスタータイルまたはベクタータイルを使用する2つの方法があります。
サーバーからのラスタータイル
OpenLayersは、デフォルトではベクタータイルをサポートしていません。ラスタータイルは、TileServer GLと呼ばれるオープンソースのサーバーソフトウェアを使用して、必要に応じて任意のGLスタイルで生成できます。このようなラスタータイルは、ol.source.XYZソースを使用して表示できます。
プラグイン付きのベクタータイル
ベクタータイルは、OpenMapTilesと共にol-mapboxスタイルのプラグインを使用してOpenLayersで表示できます。
https://translate.google.com/translate?sl=en&hl=ja&u=https%3A%2F%2Fopenmaptiles.org%2Fdocs%2Fwebsite%2Fopenlayers%2F
プラグインを使わない場合(ラスタータイルを使うことになる)
TestOpenLayersRaster.html
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.3.1/css/ol.css"> <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.3.1/build/ol.js"></script> <script defer src="TestOpenLayersRaster.js"></script> <style> html, body, #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TestOpenLayersRaster.js
var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.XYZ({ url: 'http://localhost:8080/styles/mydesign/{z}/{x}/{y}.png' }) }) ], view: new ol.View({ center: ol.proj.fromLonLat([143, 43]), zoom: 6 }) });
ol-mapbox-style プラグインを使う場合
参考:OpenMapTilesのチュートリアル(OpenLayers)、OpenLayersのサンプル(Vector tiles created from a Mapbox Style object)
TestOpenLayersVector.js
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.3.1/css/ol.css"> <script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.3.1/build/ol.js"></script> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans"> <script src="https://unpkg.com/ol-mapbox-style@5.0.2/dist/olms.js"></script> <script defer src="TestOpenLayersVector.js"></script> <style> html, body, #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body>
TestOpenLayersVector.js
olms('map', 'http://localhost:8080/styles/mydesign/style.json').then(function (map) { map.setView(new ol.View({ center: ol.proj.fromLonLat([143, 43]), zoom: 6 })) });
Leaflet で表示
OpenMapTilesをマップレイヤーとして使用する方法は3つあります。
・サーバーからのラスタータイル
・mapbox-gl-leafletプラグインを備えたベクタータイル
・VectorGridプラグインを使用したベクタータイル
サーバーからのラスタータイル
リーフレットは、デフォルトではベクタータイルをサポートしていません。ベースマップの場合は、従来のラスタータイル(メルカトルXYZ)で使用することをお勧めします。このようなタイルは、TileServer GLと呼ばれるオープンソースのサーバーソフトウェアを使用して、必要に応じて任意のGLスタイルで生成できます。
https://translate.google.com/translate?sl=en&hl=ja&u=https%3A%2F%2Fopenmaptiles.org%2Fdocs%2Fwebsite%2Fopenlayers%2F
プラグインを使わない場合(ラスタータイルを使うことになる)
TestLeafletRaster.html
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css" /> <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script> <script defer src="TestLeafletRaster.js"></script> <style> html, body, #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TestLeafletRaster.js
let mymap = L.map('map').setView([43, 143], 6); L.tileLayer('http://localhost:8080/styles/mydesign/{z}/{x}/{y}.png').addTo(mymap);
mapbox-gl-leaflet プラグインを使う場合
参考:OpenMapTIlesのチュートリアル(Leaflet)
TestLeafletVector1.html
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"> <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script> <link rel='stylesheet' href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.10.1/mapbox-gl.css"> <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.10.1/mapbox-gl.js"></script> <script src="https://unpkg.com/mapbox-gl-leaflet/leaflet-mapbox-gl.js"></script> <script defer src="TestLeafletVector1.js"></script> <style> html, body, #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TestLeafletVector1.js
var map = L.map('map').setView([43, 143], 6); var gl = L.mapboxGL({ style: 'http://localhost:8080/styles/mydesign/style.json' }).addTo(map);
VectorGrid プラグインを使う場合
参考:OpenMapTIlesのチュートリアル(Leaflet)
TestLeafletVector2.html
<!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"> <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script> <script src="https://unpkg.com/leaflet.vectorgrid@1.3.0"></script> <script defer src="TestLeafletVector2.js"></script> <style> html, body, #map { width: 100%; height: 100%; } </style> </head> <body> <div id="map"></div> </body> </html>
TestLeafletVector2.js
var map = L.map('map').setView([43, 143], 6); var openMapTilesLayer = L.vectorGrid.protobuf("http://localhost:8080/data/Hokkaido/{z}/{x}/{y}.pbf", { vectorTileLayerStyles: { Hokkaido: { fill: true, fillColor: 'rgba(168, 255, 187, 1)', color: 'rgba(255, 0, 0, 1)' } } }).addTo(map);