世界の測量

Sibling of "Relevant, Timely, and Accurate, " but much lighter and shorter ※自らの所属する組織の見解を示すものでない

バイナリベクトルタイルのウェブ地図対応状況

http://vector.io/vector-map/ に学ばせて頂き、バイナリベクトルタイル(MVT; Mapnik Vector Tiles)のウェブ地図(Leaflet)対応状況を確認してみた。

結果

MVT on Leaflet 0.8
WebGLが必須となっている等するため、ブラウザによっては動かない場合もあると思う。

解説

ソースの解説を試みる。

<link rel="stylesheet" href="leaflet-0.8-dev.css">
中略
<script src="leaflet-0.8-dev.js"></script>

Leaflet の開発版 0.8 を使っている。leafletjs.com でのCDNホストはされていないので、vector.ioにホストされているものの写しを頂いている。

<script src="vector-map.debug.js"></script>
<script src="leaflet-hash.js"></script>

vector-map.debug.js がベクトルタイルの実装の多くを入れているようである。但し、これだけではない。leaflet-hash.js は、私が常用している、現在位置及び現在ズームレベルがURLに反映されるようにする拡張である。0.7で動くものがそのまま0.8-devでも動く。

function resizeMap () {
  document.getElementById('map').style.width = window.innerWidth + 'px';
  document.getElementById('map').style.height = window.innerHeight + 'px';
  map.invalidateSize(false);
}
window.addEventListener('resize', resizeMap);
resizeMap();

ここはおまじない的に頂いてきている。これを削除すると動かない。本来、Leafletの中に内包されるべき部分であるように思われる。invalidateSizeは、Leaflet 0.7にも存在するメソッド。

var layer = L.vectorTileLayer({
  vectorRenderer: '',
  vectorTileSource: {type: 'MapboxTileSource',
    url: 'http://a.tiles.mapbox.com/v3/mapbox.mapbox-streets-v4/' + 
      '{z}/{x}/{y}.vector.pbf',
    max_zoom: 14},
  vectorLayers: 'gl_layers_mvt.js',
  vectorStyles: 'gl_styles.js',
  numWorkers: 1,
  attribution: 'Map data &copy; OpenStreetMap contributors / ' + 
    'original code: http://vector.io/vector-map/',
  unloadInvisibleTiles: false,
  updateWhenIdle: false
});

ここが具体の読み込み設定部分なる。vectorRendererは、削除すると動かなかった。vectorTileSourceがデータソースの指定になっている。vectorLayersが指しているgl_layers_mvt.jsは、データの読み込み方を指定しているように見える。vectorStylesが指しているgl_styles.jsは、読み込んだデータのレイヤごとの色設定を指定しているように見える。しかし、すべての配色設定を示せていないように見える。例えば、背景色の設定は、WebGL環境のデフォルトか何かに委ねられているように見える。

window.addEventListener('load', function () {
  layer.addTo(map);
  frameLoop();
});

function frame(){layer.render();}
function frameLoop () {
  frame();
  requestAnimationFrame(frameLoop);
}

(function requestAnimationFrameCompatibility () {
    if (window.requestAnimationFrame == undefined) {
        window.requestAnimationFrame = (function () {
            return (
                window.requestAnimationFrame       ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame    ||
                window.oRequestAnimationFrame      ||
                window.msRequestAnimationFrame     ||
                function (callback) {
                   window.setTimeout(callback, 1000 / 60);
                }
            );
        })();
    }
}());

やや特有なことを書いているようにみえる。本来、Leafletの中に内包されるべき部分であるように思われる。

分析

http://vector.io/vector-map/ と比べると比較的地に足のついたユースケースを志向しているkともあり、L.VectorTileLayer について、やや先進的なvectorTileSourceとやや保守的なvectorRendererの組み合わせを試してみたいところであるが、L.VectorTileLayer が幅をもって実装されているかどうか等をつかむことはまだできていない。調査が尽くせていないところではあるが、直感的には、今すぐに採択すべき技術であるというよりは、引き続き観察を続けて、適切な時期に採択すべきようにしておく技術であるように思える。
他方、MVT形式については、かなり高速であるように思えた。