Leafletで地図をいじるときにハマったこと（1/3）

#概要
Google　Maps　APIの料金体制が変わったので無料で使えるLeafletに初挑戦しました。ハマったこととか調べたことをまとめていきます。
Yahoo! Open Local Platform（YOLP）のYahoo! JavaScriptマップAPIも2020年10月31日でサービス提供終了しました。世知辛いです。

#作ったwebページ
地図をタップしてみんなの中間地点を表示するwebシステムです。「飲食店を探す」機能でで中間地点もよりの飲食店を検索できます。もともとGoogle　Maps　APIで作ってたものをLeafletに移植しました.

https://atsumaru.nomaki.jp/

『[ぼくらの重心](https://atsumaru.nomaki.jp/)』
![sam_yoko.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590787/e5fa4676-b2f7-99ed-9844-b501055cd8e2.png)


#今後の予定
今回の記事を第一段として、今後も『[ぼくらの重心](https://atsumaru.nomaki.jp/)』の機能改善に合わせて、ハマったところ、工夫したところを第ニ段、第三段と公開していきます。

#ハマったこと

##クリックしたところにMarkerを落としたい
友達がいる場所にMarkerを落としました。クリックした座標を拾ってそれをそのままMarkerの緯度軽度にセットします。ついでにこのMarkerをクリックした時の処理を追加できるように処理を書いておく。
![スクリーンショット 2021-06-24 0.50.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590787/b80cb58c-6649-390e-7e5f-bf593fccb872.png)

あとから消したり、中間地点を算出するために使うためにMarkerを配列に追加しておくと便利です。
`marker_list.push(marker);`

```javascript:sample.js
var map;
var marker_list =[];

function initialize(){
	  map = L.map('mapid', {
		//初期表示の座標
		center: [35.68956144616128, 139.70105409622192],
		//初期表示の縮尺
		zoom: 11,
		});

	var tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
		attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
	});
	tileLayer.addTo(map);

	//クリックした時のイベント
	map.on('click',function ( e ) {
			//クリックした座標を取得してMarkerを落としつつ、このMarkerをクリックした時のイベントを追加
			marker = L.marker([e.latlng.lat, e.latlng.lng],{}).addTo(map).on('click', function(e) {
					alert('Markerをクリックしたよ');
				}
			);
		}
	)
	//あとでMarkerをコントロールするために配列に入れておく
	marker_list.push(marker);
}

```

##Markerをオリジナルiconに変えたい
友達がいるところに人型icon、中間地点に画鋲型icon、飲食店はジャンルごとのiconを表示できるようにしています。
![スクリーンショット 2021-06-24 0.43.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590787/39985911-df6b-4008-58e8-a0c671a0fc46.png)

`L.icon`でオリジナルアイコンの画像URLやサイズを指定します。

```javascript:sample.js
	//L.iconでオリジナルアイコンを定義
	var iconStyle = L.icon({
			iconUrl: './img/human2.png',
			iconRetinaUrl: './img/human2.png',
			iconSize: [20, 48],
			iconAnchor: [10, 48],
			popupAnchor: [0, -48],
	});

```

`L.marker`でマーカーを作る時のオプションで`icon: iconStyle`を指定すればOK。

```javascript:sample.js
			marker = L.marker([e.latlng.lat, e.latlng.lng],{icon: iconStyle}).addTo(map).on('click', function(e) {
					alert('Markerをクリックしたよ');
				}
			);
```

デモ： 『[ぼくらの重心](https://atsumaru.nomaki.jp/)』

参考： https://qiita.com/hsgucci/items/c47057268af1416a18c2


##Markerの重ね順をコントロールしたい
友達iconとお店iconが重なる場合とかコントロールするため、z-indexを指定します。
https://lendl.sakura.ne.jp/journals/leaflet-layer-ordering/

##全てのMarkerを表示できるように縮尺やカメラ位置を移動したい
お店検索したときに、いい感じのカメラワークにパンさせようとしました。それなりの結果に出来ましたが、もう１歩俯瞰的に表示したいので引き続き研究します。

```javascript:
function zoom(){
	var bound = L.latLngBounds();
	//画面に収めたいマーカーの座標をboundにextendしていく
	shop_list.forEach(function(l_shopmarker,idx){
		bound.extend(l_shopmarker._latlng);
	});
  //グループが全て収まるカメラ位置にパンしてズーム
  map.fitBounds(bound);
}
```

###デモ
地図のどこかをクリックした後に「飲食店を探す」ボタンを押した後の動きです。

デモ： 『[ぼくらの重心](https://atsumaru.nomaki.jp/)』

https://www.achiachi.net/blog/leaflet/autocenter

##指定した緯度経度にカメラを移動したい
２種類の移動方法を紹介します。
###指定された緯度経度まで空を飛ぶように美しく移動します。

```javascript:sample.js
var x = 35.68956144616128;
var y = 139.70105409622192;
map.flyTo(new L.LatLng(x,y));
```

デモ： 『[ぼくらの重心](https://atsumaru.nomaki.jp/)』


###指定された緯度経度まで一気にパンします。

```javascript:sample.js
var x = 35.68956144616128;
var y = 139.70105409622192;
map.panTo(new L.LatLng(x,y));
```


移動後のズームレベルや移動時間も指定できます。

```javascript:sample.js
//ズームレベル15にしつつ時間7掛けて移動する
map.flyTo(new L.LatLng(x,y), 15, { duration: 7 });
```

参考： https://day-journal.com/memo/leaflet-045/


##マーカー、ポリゴンの削除
マーカーとポリゴンで消し方です。

マーカーの消し方

```javascript:
//マップ上からマーカーを削除するのと
map.removeLayer(marker);
//マーカー自体をnullにしておく
marker = null;
```
ポリゴンの消し方

```javascript:
//マップ上からポリゴンを削除するのと
map.removeLayer(cirlce);
//ポリゴン自体をnullにしておく
circle　=　null;
```

デモ： 『[ぼくらの重心](https://atsumaru.nomaki.jp/)』
参考： https://medium-company.com/leaflet-remove-removelayer/#i-2

##ボタンの設置と削除
地図上にボタンを表示したのですが、削除ができませんでした。なのでボタンの非表示で乗り切ります。

![スクリーンショット 2021-06-24 1.50.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/590787/e75ad458-5d18-88a9-3a06-f62654d7c95e.png)

[Leaflet.EasyButton](https://github.com/CliffCloud/Leaflet.EasyButton) プラグインを使用してボタンを表示するのは簡単でしたが、ボタンをremoveする方法がわからず、CSSを組み合わせて消すようにしました。

```javascript:JavaScript
btn_search = L.easyButton('<div id="button-text">飲食店を探す</div>', function(btn_search, easyMap){
	search();
});
btn_search.addTo(map);
```

```css:css
  .easy-button-button.disabled {
   display: none;
 }
```

```javascript:JavaScript
//ボタンをCSSで非表示する
btn_search.disable();

//ボタンを表示する
btn_search.enable();
```
デモ： 『[ぼくらの重心](https://atsumaru.nomaki.jp/)』

#第二段の予告
##Markerをアニメーションで動かしたい
友達のいる場所を増やしたり、減らしたりするごとに中間地点は変わります。中間地点のMarkerがアニメーションで動くようにしました。

##スマホだけMarkerをクリックした時のポップアップが一瞬で消える問題
私の環境だけだろうか？スマホでテストすると、ポップアップが一瞬しか開かない事象が発生しました。一瞬で消えます。クリックのイベントを使って無理矢理開くように対応しました。

##地図に縮尺を表示したい
駅からどれくらい距離があるとか、地図の縮尺って大事ですよね。
参考： https://waq3-travelog.com/how-to-use-leaflet-and-gsi-map-vol2/#toc15

##ポリゴンを表示する
中間地点から1000mの範囲を赤い円で囲います。


つづく