Newer
Older
2021-reiji / map / kyori / measure-path.js
@Takeuchi Reiji Takeuchi Reiji on 23 Dec 2021 4 KB a
// 例
// 折れ線(PolyLine)の長さ

var mymap = L.map('mymap').setView([38.891, 139.824], 16);
L.tileLayer('http://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
 attribution:
   '<a href="http://maps.gsi.go.jp/development/ichiran.html">国土地理院</a>'
}).addTo(mymap);

function latlngdist(pos1, pos2) {	// leaflet.js標準 distanceTo()
    return pos1.distanceTo(pos2);	// を利用して距離(m)を求める
}
var path = [];				// クリックしたすべての点を保持する
var line = null;			// polylineオブジェクトを保持する
var lineprop = {			// polylineのプロパティ
    color: 'navy', opacity: 0.6, weight: 8
};
var sMarker, gMarker;			// 始点終点マーカ
var totalDist = 0;			// 積算距離
var info = document.getElementById('info');	// 情報表示用要素
function updatedistance(delta) {	// 距離の加算を行ない結果を
    totalDist += delta;			// info要素に距離を表示する
    info.innerHTML = '距離: '+Math.round(totalDist*100)/100+'m';
}
var info2 = document.getElementById('info2')
function updatedistances(delta){
    totalDist += delta;
    info2.innerHTML = '歩いて'+Math.round((totalDist*100)/100)/80+'分';
}

    //var toho = docuemnt.getElementById('toho');
//function walk_time(delta){
//totalDist +=delta;
//toho.innerHTML = '歩いて' +Math.round((totalDist*100)/100)/80+'分';
//}

function resetPath() {			// 初期状態に戻す
    sMarker.remove(mymap);		// 始点マーカの除去
    gMarker.remove(mymap);		// 終点マーカの除去
    line.remove(mymap);			// 軌跡Polylineの除去
    line = sMarker = gMarker = null;
    path = [];
    totalDist = 0;
    mymap.doubleClickZoom.enable();	// ダブルクリックズーム許可
    info.innerHTML = 'クリアしました';
}
function measurePath(e) {		// クリック時の主となる処理
    var imsg = '北緯 '+e.latlng.lat+' 東経 '+e.latlng.lng;
    mymap.doubleClickZoom.disable();	// ダブルクリックズーム禁止
    if (path.length > 1
	&& e.latlng.lat == path[path.length-1].lat
	&& e.latlng.lng == path[path.length-1].lng) {
	// ダブルクリック等により同じ箇所で2度クリックが起きた場合は
	return null;	// 何もせず return
    }
    path.push(e.latlng);		// クリック緯度経度を配列に追加
    if (path.length == 1) {		// 始点未設定なら
	// 始点終点マーカを生成しマップに貼り付けポップアップ文字列を登録
	sMarker = L.marker(path[0]).addTo(mymap).bindPopup(imsg);
	gMarker = L.marker(path[0]).addTo(mymap).bindPopup(imsg);
	line = L.polyline(path, lineprop).addTo(mymap)	// polyline生成
	info.innerHTML = imsg;		// 情報表示
    } else {				// 2個目以後のポイント打ちなら
	line.addLatLng(e.latlng);	// polylineにクリック点を追加
	gMarker.setLatLng(e.latlng);	// 終点マーカをそこに移動
    }
    if (path.length > 1) {	// 2個以上点が打たれたら計算
	updatedistance(latlngdist(path[path.length-2], path[path.length-1]));
	updatedistances(latlngdist(path[path.length-2], path[path.length-1]));
	//walk_time(latlngdist(path[path.length-2], path[path.length-1]));
    }
    if (e.originalEvent.shiftKey) {	// SHIFT+クリックで
	resetPath(e);			// 終了
    }
}
function removePoint(e) {		// 1つ取消
    if (path.length > 1) {		// 2つ以上点があれば
	let rm = path.pop();		// 点保持配列の末尾を抜き取る
	updatedistance(-latlngdist(rm, path[path.length-1])); // 引き算
	updatedistances(-latlangdist(rm, path[path.length-1]));
	//walk_time(-latlngdist(rm, path[path.length-1]));
	line.setLatLngs(path);		// polylineの点リストを更新
	gMarker.setLatLng(path[path.length-1]);	// 終点マーカを最終点に移動
	mymap.panTo(path[path.length-1]);	// 最終点が見えるようにする
    } else {				// polylineの点が1つ以下なら
	info.innerHTML = '始点は削れません。'
    }
}
mymap.on('click', measurePath);		// クリックイベントで measurePath()
mymap.on('contextmenu', removePoint);	// 右クリックで removePoint()
// id="undo" のボタンクリックで「1つ取消」
document.getElementById('undo').addEventListener('click', removePoint);
// id="finish" のボタンクリックで「終了」
document.getElementById('finish').addEventListener('click', resetPath);