Leaflet(Web地図ライブラリ)の使い方
オープンソースのWeb地図ライブラリ「Leaflet」が以前から気になっていたので、試しに使ってみました。
目次
- leafletについて
 - 最小構成(CDN)
 - 動作確認(サンプル)
 - イベント
 - マーカー
 - 緯度経度
 - ズーム
 - ポリライン
 - 参考リンク
 
leafletについて
最初はGoogle Mapの代わりに使えるものがLeafletだと思っていましたが、LeafletはあくまでオープンソースのWeb地図操作用API(JavaScriptライブラリ)であって、Leaflet自体が地図サービスを提供しているわけではありません。
Leafletのサンプルで使われている地図サービスは Mapbox で、利用する場合はMapboxにアカウントを作って、アクセストークンを取得する必要があります。
また、ArcGIS という地図サービスを利用する場合、こちらはEsri LeafletというJavaScriptライブラリが用意されていて、このライブラリを使うと、地図サービスにアカウント登録するといった手間が不要で、動作確認レベルであればすぐに利用することができます。商用利用する場合はアカウントの登録が必要です。
なお、私は試していませんが、Google Mapをベースにしてライブラリを利用することもできるようです。
Mapbox、ArcGIS、Google Map、それぞれ無料で利用できる枠が決められているので、アクセスが多かったり、商用利用する場合は注意が必要です。
最小構成(CDN)
以下は、Esri LeafletをCDNで使った際の最小構成のサンプルになります。
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>Esri Leaflet サンプル(最小構成)</title>
  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
  <link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"
    integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
    crossorigin=""/>
  <style>
    body { margin:0; padding:0; }
    #map { position: absolute; top:0; bottom:0; right:0; left:0; }
  </style>
</head>
<body>
  <div id="map"></div>
  <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"
    integrity="sha512-gZwIG9x3wUXg2hdXF6+rVkLF/0Vi9U8D2Ntg4Ga5I5BZpVkVxlJWbSQtXPSiUTtC0TjtGOmxa1AJPuV0CPthew=="
    crossorigin=""></script>
  <script src="https://unpkg.com/esri-leaflet@2.4.1/dist/esri-leaflet.js"
    integrity="sha512-xY2smLIHKirD03vHKDJ2u4pqeHA7OQZZ27EjtqmuhDguxiUvdsOuXMwkg16PQrm9cgTmXtoxA6kwr8KBy3cdcw=="
    crossorigin=""></script>
  <script>
    var map = L.map('map').setView([35.681236, 139.767125], 13);
    L.esri.basemapLayer('Topographic').addTo(map);
    </script>
</body>
</html>
Mapboxの地図サービスを利用する場合、ライブラリ(esri-leaflet.js)の参照を削除して、mapの初期化を以下のように行います。
var map = L.map('map').setView([35.681236, 139.767125], 13);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={accessToken}', {
  attribution: 'Map data © OpenStreetMap contributors, CC-BY-SA, Imagery © Mapbox',
  maxZoom: 18,
  // id: 'mapbox/streets-v11',
  // id: 'mapbox/satellite-v9',
  id: 'account/aaabbbcccdddeee',   // Your Setting Map
  tileSize: 512,
  zoomOffset: -1,
  accessToken: 'YOUR_ACCESS_TOKEN'
}).addTo(map);
Mapboxは地図のカスタマイズを細かくできることがメリットのようで、自分で設定した地図をidに指定することができます。また、accessTokenにはアカウントで登録されたものをセットします。
動作確認(サンプル)
イベント
よく使うイベント。
map.on('resize', function(e) {
  // リサイズ
});
map.on('zoomend', function(e) {
  // ズーム後
});
map.on('moveend', function(e) {
  // 移動後
});
上記以外はこちら(Leaflet|マップの状態変化イベント一覧 | kitanote)を確認。
マーカー
◆マーカーを地図上に表示
var marker1 = L.marker([35.681236, 139.767125]).addTo(map);
var marker2 = L.marker([35.690921, 139.700257]).addTo(map);
var marker3 = L.marker([35.7141, 139.7774]).addTo(map);
◆マーカークリック時のポップアップ
marker1.bindPopup("<h4>東京駅</h4><p>〒100-0005 東京都千代田区丸の内1丁目</p>");
// marker1.openPopup();
◆複数マーカーの表示・非表示の切り替え(レイヤー操作)
var markers = L.layerGroup([marker1, marker2, marker3]);
map.addLayer(markers);
// map.removeLayer(markers);
※ レイヤーでマーカーを設置する場合、マーカー単体の .addTo(map) は不要。
◆マーカーの位置に移動
map.panTo(marker1.getLatLng());
◆マーカーのアイコン変更
var markerIcon = L.icon({
  iconUrl: './images/marker-map.png',
  iconSize: [27, 32],
  iconAnchor: [12, 30],
  popupAnchor: [-3, -76],
  // shadowUrl: './images/marker-map-shadow.png',
  // shadowSize: [68, 95],
  // shadowAnchor: [22, 94]
});
marker1.setIcon(markerIcon);
マーカー作成時にアイコンをセットする場合は以下の通り。
var marker1 = L.marker([35.681236, 139.767125], {icon: markerIcon});
緯度経度
現在の地図の緯度経度を取得。
console.log(map.getBounds().getCenter());     // 中央
console.log(map.getBounds().getNorthWest());  // 左上
console.log(map.getBounds().getNorthEast());  // 右上
console.log(map.getBounds().getSouthWest());  // 左下
console.log(map.getBounds().getSouthEast());  // 右下
ズーム
現在のズームの状態を取得。
console.log(map.getZoom());
ポリライン
ポリラインの表示。
var polyline = L.polyline([
    marker1.getLatLng(), 
    marker2.getLatLng(), 
    marker3.getLatLng(), 
    marker1.getLatLng()
  ], {color: 'red'});
map.addLayer(polyline);
// map.removeLayer(polyline);