地図上へのオブジェクト配置

直線やポリゴン(多角形)を様々な属性(色や不透明度など)に設定し、 地図レイヤ上に配置できる。

図形オブジェクト

L.polyline() で連続する線分を、 L.polygon() でポリゴンを描画し、それを含むレイヤを返す。 百聞は一見にしかずで、例を示す。

mapobj.html

<!DOCTYPE html>
<html lang="ja">
<head>
<title>マップ: Objects on a Map!</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../src/leaflet.css" />

<script src="../src/leaflet.js"></script>
<style type="text/css">
<!--
div#mymap {width: 90vw; height: 80vh; margin: 0 auto;}
-->
</style>
</head>

<body>
<h1>Objects on a Map</h1>
<div id="mymap"></div>
<!-- #mymap であるdivを配置したあとで -->
<script type="text/javascript" src="domon.js" charset="utf-8"></script>
<!-- 最初のマップ作成プログラム例をそのまま利用する -->
<script type="text/javascript" src="mapobj.js" charset="utf-8"></script>
<!-- ↑この行だけ追加 -->
</body>
</html>

この HTML ファイルで読み込む JavaScript プログラム mapobj.js を示す。

mapobj.js

/* Add some objects on a Map */

var pl = [			// Polyline: 連続線分
    [38.892123,139.818884],
    [38.891187,139.819313],
    [38.891780,139.823411]
];
var plProp = {			// polylineのプロパティを定義
    color: "red",		// 線分の色
    opacity: 0.4,		// 線分の透明度
    weight: 9			// 線分の太さ
};
var plobj = L.polyline(pl, plProp).addTo(mymap);

var pg = [			// Polygon: ポリゴン
    [38.895,139.821],
    [38.895,139.822],
    [38.894,139.822],
    [38.894,139.820],	// 終点と始点は連結される
];
var pgOpt = {			// polygonに与えるオプション
    color: "blue",		// 線分の色
    fillColor: "pink",		// 塗りつぶし部分の色
    fillOpacity: 0.2		// 塗りつぶし部分の透明度
};
var pgobj = L.polygon(pg, pgOpt).addTo(mymap);

var marker1 = pl[0], marker2 = pg[0]; // polylineとpolygon各々の始点
var m1opt = {title: "その1"}, m2opt = {title: "その2"};
var m1 = L.marker(marker1, m1opt).addTo(mymap);
var m2 = L.marker(marker2, m2opt).addTo(mymap);

/* オブジェクトレイヤ.bindPopup() でクリック時のポップアップを定義できる */
plobj.bindPopup("ポリラインですよ!");
pgobj.bindPopup("ポリゴンですよ!");
m1.bindPopup("その1ですよ!");
// 次のようにあらかじめ1つのポップアップを開いておくことも可能
m2.bindPopup("その2ですよ!").openPopup();

図形、あるいはマーカに類するものを生成するメソッド一覧を示す。 引数に指定する LatLng[緯度, 経度] であり、 直後につけた [] は緯度経度の1次元の並び、 [][] は緯度経度の2次元の並びを意味する。

パスに関連するオブジェクトの様々な属性はオプションで設定できる。 http://leafletjs.com/reference.html#path-options より主要値を抜粋しておく。

オプション既定値意味
strokeブール値 trueパスを囲む線を描くか
color文字列 '#03f'線の色
weight数値 5線の太さ(ピクセル値)
opacity数値 0.5線の不透明度
fillブール値 囲みを塗りつぶすか
fillColor文字列 線色と同じ塗りつぶしの色
fillOpacity数値 0.2塗りつぶしの不透明度
clickableブール値 trueクリック可能にするか(true)、 地図の一部とするか(false)

アイコン

マーカに付けられるアイコンのデフォルトは青の逆しずく型MarkerIconだが、これを自作アイコンに変えることもできる。 マーカ本体となる画像と、さらに欲しければそれの影となる画像を用意する。

独自アイコン使用例

アイコン q.png (50x80 q.png)
q.png (48x23 q-shadow.png)

作成した画像は、L.Icon() でアイコンオブジェクトに変換する。 上記の2枚を指定する例を示す。

var qIcon = L.Icon({
  iconUrl:	'q.png',
  iconSize:     [50, 80],
  iconAnchor:	[19, 79],
  shadowUrl:	'q-shadow.png',
  shadowSize:   [48, 23],
  shadowAnchor:	[19, 19],
});

作成したアイコンをマーカ作成時のオプションで指定し、 地図に貼り付けると図:独自アイコン使用例のようになる。

イベント処理

イベント処理例

地図に配置したオブジェクト上でのクリックやドラッグといったイベント は捕捉して、あらかじめ定めた挙動をさせることができる。

イベントに追随した処理を定義したいときは、 イベントを捕捉したいオブジェクトのもつ on() メソッドに、捕捉したいイベントの種類とそのときの処理を行なう関数を指定する。

たとえば、地図上に配置するあるマーカをドラッグしたら、 それに応じてポップアップするメッセージを変えるものを定義するとしたら 以下のようになる。

var mrk = L.marker(LatLng, {draggable: true}).addTo(map)
mrk.bindPopup("初期のポップアップメッセージ");
mrk.on('dragend', function(e) {
  /* イベントオブジェクトを持つ引数 e を用いた処理 */
});

この例では変数 mrk が保持するマーカに対し mrk.on('drag', function(e){...}) として、 ドラッグイベント発生時の処理を割り当てている。

処理を定義する無名関数が受け取る引数(この例では e)は Event Object で、以下2つのプロパティを持つ。

type発生したイベントの種類('click'など)
targetイベント発生のオブジェクト

e.target はマーカオブジェクト自身になるので、 これから配置された緯度経度を得るには latlng プロパティにアクセスすればよい。これを利用して、 マーカをドラッグして位置を変えたら、 その位置をマーカのポップアップメッセージに示すようにイベント処理関数を定義すると以下のようになる。

/* ここまでに mymap 変数に L.map オブジェクトが代入されているとする */
center = L.latLng([38.891, 139.824]);
var dragmarker = L.marker(center, {
    draggable: true, icon: qIcon
}).addTo(mymap);
dragmarker.bindPopup("この位置は"+center+"です。");
dragmarker.on('dragend', function(e) {
    var latlng = e.target.getLatLng();
    e.target.setPopupContent("この位置は"+latlng+"です。");
});

なお、この例では e.target から緯度経度を求めたが、 この例では、発生イベントが MouseEvent であるため、e.latlng としてイベントから直接求めることもできる。 MouseEvent の場合は以下のプロパティも定義される。

latlng地図上での緯度経度位置
layerPointレイヤ上の相対ピクセル位置
containerPointマップコンテナ上の相対ピクセル位置
originalEventDOMレベルでのマウスイベント

また、受け取るイベントが LocationEvent の場合は以下のプロパティも定義される。

latlngGPSで取得した緯度経度位置
boundsGPS精度を考慮した現在位置範囲
accuracyGPS誤差(メートル)
altitudeWGS84高度
altitudeAccuracyaltitudeの誤差
heading 前回からの移動方向(北から反時計回り360度まで)
speed移動速度(m/s)
timestamp位置取得時刻

その他、イベント処理を行ないたい場合に受け取ることができる イベント一覧を示す。

イベント何で発生するか
clickクリックまたはタップ
dblclickダブルクリックまたはダブルタップ
mousedownマウスボタン押下
mouseupマウスボタン開放
mouseoverマウスポインタが地図に入ったとき
mouseoutマウスポインタが地図から出たとき
mousemove地図上でマウスが動いたとき
contextmenu右クリックまたは長タップ
focus地図にフォーカスを入れたとき
blur地図がフォーカスを失うとき
preclickクリックイベント直前
load地図ロード時
unload地図がremove()されたとき
viewreset地図再描画時
movestart移動開始時
move移動時
moveend移動終了時
dragstartドラッグ開始時
dragドラッグ中その都度
dragendドラッグ終了時
zoomstartズーム開始時
zoomendズーム終了時
zoomlevelchangeズーム変更時
resize地図リサイズ時
autopanstartポップアップによる自動パン開始時
layeraddレイヤ追加時
layerremoveレイヤ追加時
baselayerchangeベースレイヤ変更時
overlayaddオーバーレイ追加時
overlayremoveオーバーレイ削除時
locationfoundgeolocation捕捉時
locationerrorgeolocation捕捉エラー時
popupopenポップアップが開く時
popupcloseポップアップが閉じる時

名前空間を汚さない

domon-mymap.html

<!DOCTYPE html>
<html lang="ja">
<head>
<title>マップ: My First Map!</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../src/leaflet.css" />
<script src="../src/leaflet.js"></script>
<script type="text/javascript" src="mymap.js" charset="utf-8"></script>
<!-- ここで mymap.js をロードするが start() 関数が呼ばれるのは -->
<!-- HTML文書ロードが完了してから。 -->
<style type="text/css">
<!--
div#mymap {width: 90vw; height: 80vh; margin: 0 auto;}
-->
</style>
</head>

<body>
<h1>My First Map!</h1>
<div id="mymap"></div>
<!-- bodyでは #mymap であるdivを配置するのみ -->
</body>
</html>

これから呼ばれる JavaScript プログラムは以下のとおり。

mymap.js

function MyMap(id) {
    var mymap;
    function init(id) {
	mymap = L.map(id).setView([38.891, 139.824], 16);
	L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
	    attribution:
	    '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> \
		contributors'
	}).addTo(mymap);
    }
    function mapObjs() {
	var pl = [			// Polyline: 連続線分
	    [38.892123,139.818884],
	    [38.891187,139.819313],
	    [38.891780,139.823411]
	];
	var plProp = {			// polylineに与えるオプション
	    color: "red",		// 線分の色
	    opacity: 0.4,		// 線分の透明度
	    weight: 9			// 線分の太さ
	};
	L.polyline(pl, plProp).addTo(mymap);

	var pg = [			// Polygon: ポリゴン
	    [38.895,139.821],
	    [38.895,139.822],
	    [38.894,139.822],
	    [38.894,139.820],		// 終点と始点は連結される
	];
	var pgOpt = {			// polygonに与えるオプション
	    color: "blue",		// 線分の色
	    fillColor: "pink",		// 塗りつぶし部分の色
	    fillOpacity: 0.2		// 塗りつぶし部分の透明度
	};
	L.polygon(pg, pgOpt).addTo(mymap);

	var marker1 = pl[0], marker2 = pg[0];
	var m1opt = {title: "その1"}, m2opt = {title: "その2"};
	var m1 = L.marker(marker1, m1opt).addTo(mymap);
	var m2 = L.marker(marker2, m2opt).addTo(mymap);
	m1.bindPopup("その1ですよ!");
	m2.bindPopup("その2ですよ!");
    }
    // ↓初期化時にすぐ実行される
    init(id);
    mapObjs();
};
document.addEventListener("DOMContentLoaded", function(){
    MyMap("mymap");}, false);

以後は、domon-mymap.html と同様の形式で書くものとする。