昨年の11月からつい先日まで下記のようなイベントをした。

子どもたちに自分の好きな場所を取材してもらって記事を作成する。

その記事を集めて壁新聞にするというもの。


壁新聞にはWeb版があって、


osm_leaflet_ico


Web版ではOpenStreetMap + leafletで作成している。

この地図をざっと見てもらうと、


settukyo_osm_leaflet_markers

OpenStreetMap + Leafletで二つのマーカーを設置する


マーカーが今まで見てきた青いピンではなく、

acorn_ico

何を紹介しているのか?がひと目でわかるようなイラストアイコンになっている。

アイコンはフリー素材を組み合わせて自作した。


今回はマーカーをイラストアイコンに変える方法を見ていくことにする。




settukyo_osm_leaflet_markers


下のマーカーを

nature_ico

nature.pngと名付けたPNGファイルに変更してみる。

はじめにディレクトリ構造を下記のようにする。

.
├── ico
│   └── nature.png
└── index.html

アイコン用のicoディレクトリを設ける。

index.htmlでは地図を出力するためのコードが書かれていて、コードはOpenStreetMap + Leafletで二つのマーカーを設置するの記事までで作成したものとする。


アイコンを利用するためには、事前にL.icon()でアイコン用のオブジェクトを設けておく必要がある。

Markers With Custom Icons - Leaflet - a JavaScript library for interactive maps


OpenStreetMap + Leafletを試してみたの記事の時のようなシンプルな書き方であれば、

L.marker([lat, lng]).addTo(map);

の箇所を

//アイコンのオブジェクト
var natureIco = L.icon({
    iconUrl: './ico/nature.png',
    iconRetinaUrl: './ico/nature.png',
    iconSize: [50, 50],
    iconAnchor: [25, 50],
    popupAnchor: [0, -50],
});

L.marker([lat, lng], {icon: natureIco}).addTo(map);

このように事前にアイコンのオブジェクトを設けて、L.markerの第二引数にオプションでアイコンのオブジェクトを渡すように書き換えた後に表示を確認してみると、


osm_leaflet_ico1


アイコンが自作したものに変わった。




次はOpenStreetMap + Leafletで二つのマーカーを設置するまでで見てきたL.getJSONを介してマーカーを設置する方を見てみる。

var features = [
	{
		"type":"Feature",
		"properties":{
			"name":"摂津峡",
			"url":"https://goo.gl/maps/pF6ukpbgf5tLBtTb7"
		},
		"geometry": {
			"type": "Point",
			"coordinates":[135.58724326280114, 34.877647854266584]	//注意:緯度経度の渡し方が逆になる
		}
	},
	{
		"type":"Feature",
		"properties":{
			"name":"山水館",
			"url":"https://goo.gl/maps/eresbZ5H4gJBajRV8"
		},
		"geometry": {
			"type": "Point",
			"coordinates":[135.5864828823669, 34.878894143428354]	//注意:緯度経度の渡し方が逆になる
		}
	}
];

L.geoJSON(features, {
    onEachFeature: function(features, layer) {
		if (features.properties && features.properties.url) {
			layer.on('click', function(ele) {	//PCでマーカーをクリック
				location.href = features.properties.url;
			});
			layer.on('tap', function(ele) {		//スマホでマーカーをタップ
				location.href= features.properties.url;
			});
		}
	}
}).addTo(map);

上記のコードで複数マーカーを設置できるようになっている。


このコードに対して、一つのマーカーのみカスタムアイコンにするように書き換えてみる。

//アイコンのオブジェクト
var natureIco = L.icon({
    iconUrl: './ico/nature.png',
    iconRetinaUrl: './ico/nature.png',
    iconSize: [50, 50],
    iconAnchor: [25, 50],
    popupAnchor: [0, -50],
});

var features = [
	{
		"type":"Feature",
		"properties":{
			"name":"摂津峡",
			"url":"https://goo.gl/maps/pF6ukpbgf5tLBtTb7",
			"icon":natureIco
		},
		"geometry": {
			"type": "Point",
			"coordinates":[135.58724326280114, 34.877647854266584]	//注意:緯度経度の渡し方が逆になる
		}
	},
	{
		"type":"Feature",
		"properties":{
			"name":"山水館",
			"url":"https://goo.gl/maps/eresbZ5H4gJBajRV8"
		},
		"geometry": {
			"type": "Point",
			"coordinates":[135.5864828823669, 34.878894143428354]	//注意:緯度経度の渡し方が逆になる
		}
	}
];

L.geoJSON(features, {
	onEachFeature: function(features, layer) {
		if (features.properties && features.properties.url) {
			layer.on('click', function(ele) {	//PCでマーカーをクリック
				location.href = features.properties.url;
			});
			layer.on('tap', function(ele) {		//スマホでマーカーをタップ
				location.href= features.properties.url;
			});
		}
	},

	//条件によって設置するマーカーを変える
	pointToLayer: function(feature, latlng) {
		// アイコンの指定があれば指定したアイコンを設置する
		if(feature.properties.icon){
			return L.marker(latlng, {icon: feature.properties.icon});
		}else{
			return L.marker(latlng);
		}
	}
}).addTo(map);

このコードでは摂津峡の方のみfeatureでiconの値を加えた。

L.getJSONの方で、pointToLayerの処理を加え、featureの方でiconの値がある場合は指定したアイコンに変えるようにする。

Using GeoJSON with Leaflet - Leaflet - a JavaScript library for interactive maps


このコードをブラウザを介して実行してみると


osm_leaflet_ico2


指定した箇所のみカスタムアイコンに変わった。