はじめに
Mapbox社の出現により、ここれまでのウェブ地図サービスの主流であった、「ラスタータイル」方式は過去の技術になっています。
そういった世の中の流れに追従して、国土地理院からもベクトルタイルの提供が開始されました。
そこで、今回はOpenLayersを使って国土地理院のベクトルタイルを表示してみました。
OpenLayersでベクトルタイルの設定
OpenLayersでは、ベクトルタイル用のレイヤ(VectorTile)が用意されているのでそれを使用します。後は、styleをどう表示するかは、通常のベクタレイヤと同じです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
var map = new ol.Map({ layers: [], target: 'map', view: new ol.View({ center: [14715856, 3952121], zoom: 11, minZoom: 10, maxZoom: 17 }), controls: ol.control.defaults({ attributionOptions: { collapsible: false } }), }); var layer1 = new ol.layer.VectorTile({ source: new ol.source.VectorTile({ format: new ol.format.MVT({}), url: 'https://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbf', attributions: ['<a href="https://github.com/gsi-cyberjapan/gsimaps-vector-experiment" target="_blank" rel="”noopener noopener">国土地理院ベクトルタイル</a>'] }), style: function (feature, resolution) { var geom = feature.getGeometry(); var geomType = geom.getType(); var style = new ol.style.Style(); var zoom = map.getView().getZoom(); if (feature.get('layer') === 'road') { var ftCode = feature.get('ftCode'); var rdCtg = feature.get('rdCtg'); var scale = getScaleFromResolution(resolution); var strokeColor = '#fff'; var rdWidth = 0.5; var rdzIndex = 2; if (zoom >= 17) { strokeColor = '#ccc'; rdWidth = 0.5; rdzIndex = 2; if (feature.get('rdCtg') === 0) { strokeColor = '#fff'; rdzIndex = 2; } else if (feature.get('rdCtg') === 1) { strokeColor = '#fff'; rdzIndex = 2; } else if (feature.get('rdCtg') === 2) { strokeColor = '#fff'; rdzIndex = 2; } style = new ol.style.Style({ stroke: new ol.style.Stroke({ color: strokeColor, width: rdWidth }), zIndex: rdzIndex }); } else { var rdWidth = 2; strokeColor = '#fff2bd'; if (feature.get('rdCtg') === 0) { strokeColor = '#f88'; rdWidth = Math.round(20 / resolution); rdzIndex = 4; } else if (feature.get('rdCtg') === 1) { strokeColor = '#fff2bd'; rdWidth = Math.round(20 / resolution); rdzIndex = 3; } else if (feature.get('rdCtg') === 2) { strokeColor = '#ccc'; rdWidth = Math.round(5 / resolution); } else if (feature.get('rdCtg') === 3) { strokeColor = '#0c0'; rdWidth = Math.round(20 / resolution); rdzIndex = 5; } if (zoom < 15) { rdWidth = 4; } style = new ol.style.Style({ stroke: new ol.style.Stroke({ color: strokeColor, width: rdWidth }), zIndex: rdzIndex }); } } else if (feature.get('layer') === 'railway') { style = [ new ol.style.Style({ stroke: new ol.style.Stroke({ color: '#aaa', width: 4 }), zIndex: 2 }), new ol.style.Style({ stroke: new ol.style.Stroke({ color: '#fff', width: 2, lineCap: 'square', lineDash: [20, 15] }), zIndex: 2 }) ]; } else if (feature.get('layer') === 'building') { //console.log('layer=' + feature.get('layer') + ', ftCode='+ feature.get('ftCode')); var strokeColor = '#d4d6da'; var fillColor = '#f1f3f4'; if (feature.get('ftCode') === 3101) { strokeColor = '#d4d6da'; fillColor = '#f1f3f4'; } else if (feature.get('ftCode') === 3102) { strokeColor = '#d4d6da'; fillColor = '#f0f0f0'; } else if (feature.get('ftCode') === 3111) { strokeColor = '#fde7a8'; fillColor = '#fffbf0'; } style = new ol.style.Style({ stroke: new ol.style.Stroke({ color: strokeColor, width: 1, }), fill: new ol.style.Fill({ color: fillColor, }), zIndex: 0 }); } else if (feature.get('layer') === 'coastline') { style = new ol.style.Style({ stroke: new ol.style.Stroke({ color: '#9cc0f9', width: 2 }), zIndex: 0 }); } else if (feature.get('layer') === 'river' || feature.get('layer') === 'lake' || feature.get('layer') === 'waterarea') { style = new ol.style.Style({ stroke: new ol.style.Stroke({ color: '#9cc0f9', width: 1, }), fill: new ol.style.Fill({ color: '#9cc0f9', }), zIndex: 0 }); } else if (feature.get('layer') === 'label') { style = new ol.style.Style({ text: new ol.style.Text({ text: feature.get('annoChar'), }), zIndex: 0 }); } else if (feature.get('layer') === 'symbol') { console.log('layer=' + feature.get('layer') + ', ftCode=' + feature.get('ftCode')); } else if (feature.get('layer') === 'contour') { console.log('layer=' + feature.get('layer') + ', ftCode=' + feature.get('ftCode')); } else { console.log('layer=' + feature.get('layer') + ', ftCode=' + feature.get('ftCode')); } return style; } }); map.addLayer(layer1); |
地図イメージ
地図イメージ1
地図イメージ2
地図イメージ3
まとめ
OpenLayersでベクトルタイルが簡単に表示できることが分かりました。OpenLayersと国土地理院に感謝です。
ただ、地理院タイルなみの表示を行うとするとスタイルの設定がかなり難しいです。スタイルが複雑すぎるとベクトルタイルの良さである高速描画が生かせなくなるので、悩ましいところです。