Newer
Older
2021-koki / map / game / game.js
@ITO Koki ITO Koki on 27 Jan 2022 6 KB game.jsにgpsの追加
document.addEventListener("DOMContentLoaded", () => {
    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);
    
    var gpsmarker = L.marker(mymap.getCenter()).addTo(mymap);
    gpsmarker.bindPopup("STARTを押してね").openPopup();
    
    var nTrial = 100
    var watchId = null;
    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 latlngdist(pos1, pos2) {	// leaflet.js標準 distanceTo()
	return pos1.distanceTo(pos2);	// を利用して距離(m)を求める
    }
    function updatedistance(delta) {	// 距離の加算を行ない結果を
	totalDist += delta;			// info要素に距離を表示する
	info.innerHTML = '距離: '+Math.round(totalDist*100)/100+'m';
    }
    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 stopGPS() {
	console.log("watchId="+watchId);
	if (watchId != null) {
	    navigator.geolocation.clearWatch(eatchId);
	    document.getElementById("title").textContent = "stop";
	    gpsmarker.setPopupContent("停めました");
	}
	watchId = null;
    }
    function tryWatchGPS() {
	stopGPS();
	watchId = navigator.geolocation.watchPosition(
	    onSuccess, onError,{
		maximumAge: 0, timeout: 3000, enableHighAccuracy: true});
	document.getElementById("title").textContent = "START";
    }
    function onSuccess(pos) {
	var latlng = L.latLng([pos.coords.latitude, pos.coords.longitude]);
	mymap.panTo(latlng);
	console.log(latlng);
    }
    function onError(err) {
	restN = "あと"+(--nTrial)+"回試行します。";
	gpsmarker.setPopupContent("捕捉失敗:"+restN).openPopup();
	if (nTrial <= 0) {
	    navigator.geolocation.clearWatch(watchId);
	}
    }
    
    function measurePath(pos) {		// クリック時の主となる処理
	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]));
	}
	if (e.originalEvent.shiftKey) {	// SHIFT+クリックで
	    resetPath(e);			// 終了
	}
    }
    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 latlngdist(pos1, pos2) {	// leaflet.js標準 distanceTo()
	return pos1.distanceTo(pos2);	// を利用して距離(m)を求める
    }
    function updatedistance(delta) {	// 距離の加算を行ない結果を
	totalDist += delta;			// info要素に距離を表示する
	info.innerHTML = '距離: '+Math.round(totalDist*100)/100+'m';
    }
    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]));
	}
	if (e.originalEvent.shiftKey) {	// SHIFT+クリックで
	    resetPath(e);			// 終了
	}
    }    
    mymap.on('click', measurePath);	// クリックイベントで measurePath()
    // id="finish" のボタンクリックで「終了」
    document.getElementById('stop').addEventListener('click', resetPath);
},false);