OpenLayersとLeafletの比較(2)

この記事は1年以上前に書かれました。
内容が古くなっている可能性がありますのでご注意下さい。


単発記事のつもりだったOpenLayersとLeafletの比較調査の続編です。今回は、地理空間情報のマークアップ言語KMLで記述されたファイルを表示してみます。

※OpenLayers 3については、現在公開されている正式版とは仕様が異なる点がありますのでご注意下さい。

比較調査のために作成したKMLファイル(東海道.kml)には、旧東海道の川崎宿から藤沢宿までのルートと、街道沿いにある公園のトイレ数箇所の情報が入っています。OpenStreetMapの上にKMLファイルの情報を重ね、KMLファイルがカバーする範囲(川崎宿から藤沢宿まで)に合わせて地図をズームします。

まずは、OpenLayers2から。(JavaScriptプログラムのみ示します)

var map = new OpenLayers.Map('mapdiv');

var osmLayer = new OpenLayers.Layer.OSM();
var kmlLayer = new OpenLayers.Layer.Vector('KML', {
  strategies: [new OpenLayers.Strategy.Fixed()],
  protocol: new OpenLayers.Protocol.HTTP({
    url: '東海道.kml',
    format: new OpenLayers.Format.KML({
      extractStyles: true, 
      extractAttributes: true,
      maxDepth: 2
    })
  })
});

map.addLayer(osmLayer);
map.addLayer(kmlLayer);

kmlLayer.events.register('loadend', kmlLayer, function(e) {
  map.zoomToExtent(kmlLayer.getDataExtent())
})

KMLファイルを表示するレイヤOpenLayers.Layer.Vectorを作成し、OpenLayers.Protocol.HTTPでKMLファイルを読み込みます。KMLレイヤをMapに追加し、loadendイベントのコールバックでKMLレイヤに合わせてMapをズームします。

Googleマップを使用して作成したとおりに、旧東海道のルートを表す赤い線とトイレのアイコンが表示されました。
実際のHTMLによる表示はこちら

次はOpenLayers 3です(ベータ版を使用しているため、今後リリースされる版では仕様が変わる可能性があります)。

var map = new ol.Map({
  target: 'mapdiv',
  view: new ol.View2D({
    center: [0, 0],
    zoom: 1
  })
});

var osmLayer = new ol.layer.Tile({
  source: new ol.source.OSM()
});
var kmlLayer = new ol.layer.Vector({
  source: new ol.source.KML({
    projection: 'EPSG:3857',
    url: '東海道.kml'
  })
});

map.addLayer(osmLayer);
map.addLayer(kmlLayer);

kmlLayer.once('postcompose', function(evt) {
  var extent = kmlLayer.getSource().getExtent();
  map.getView().fitExtent(extent, map.getSize());
});

前回も書いたとおり、MapにはViewも追加します。
KMLファイルの読み込みにはol.source.KML()を用います。OpenStreetMapのタイル読み込みにはol.source.OSM()を用いますので、仕様に統一感があって良いと思います。
KMLレイヤのpostcomposeイベントを1回だけ(once)フックして、KMLレイヤのソース(KMLファイル)のカバーする範囲を取得し、Viewを範囲に合わせます。
実行すると、

ルートは表示できましたが、トイレのアイコンが全く表示されていません。
→後日解決しました。追記参照。

Leafletでは、プラグインを用いてKMLファイルを表示します。何種類かのプラグインを利用できますが、今回はleaflet-omnivoreを利用します。

var map = L.map('mapdiv');

var osmLayer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
  attribution: 'Map data © <a href="http://openstreetmap.org">OpenStreetMap</a> contributors'
});
var kmlLayer = omnivore.kml('東海道.kml');

map.addLayer(osmLayer);
map.addLayer(kmlLayer);

kmlLayer.on('ready', function() {
  map.fitBounds(kmlLayer.getBounds());
});

KMLレイヤの作成も、地図をKMLレイヤの範囲に合わせるのも非常に簡単に記述できました。
しかし、実行すると、

トイレのアイコンが別のアイコンに変わってしまいました。また、ルートを表す線の色も変わってしまいました。
実際のHTMLによる表示はこちら

OpenLayers 3とLeafletについては、調査を継続する必要があります。

追記

KMLファイルを編集し、

<Icon>
  <href>http://www.gstatic.com/mapspro/images/stock/1219-fac-wc-unisex.png</href>
</Icon>

となっていたトイレのアイコン定義を

<Icon>
  <href>1219-fac-wc-unisex.png</href>
</Icon>

と修正し、1219-fac-wc-unisex.pngファイルをKMLファイルと同じサーバに置いたところ、OpenLayers 3でもトイレのアイコンが表示されるようになりました。

実際のHTMLによる表示はこちら

追記2

OpenLayers 3.5.0でol.source.KMLは廃止され、代わりにol.source.Vectorを使うことになりました。

追記3

その後、Leafletをメインに使用するようになりました。
例:江戸後期 武蔵・相模国 村名マップ

OpenLayersとLeafletの比較 12