Newer
Older
JAXAtools / GPS / gps.js
@HIROSE Yuuji HIROSE Yuuji on 9 Oct 2022 4 KB Add required files
document.addEventListener("DOMContentLoaded", ()=>{
    var gpsTimer;
    var mymap, infobox, gpsMarker, btnGet, btnMemo;
    let area = {
	iimoriyama: {
	    name: '飯森山',
	    bounds: [[38.894762, 139.818293], [38.888378, 139.826495]],
	    map: 'img/iimori.png',
	    geojson: 'data/iimoriyama.geojson'
	},
	yuza: {
	    name: '遊佐',
	    bounds: [[39.017937, 139.93102], [39.013269, 139.937029]],
	    map: 'img/yuza.png',
	    geojson: 'data/yuza.geojson'
	}}
    var gsiLayer = L.tileLayer(
	'//cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
	    attribution:
	    '<a href="http://maps.gsi.go.jp/development/ichiran.html">国土地理院</a>'
	});
    var baseLayers = {
	地理院地図: gsiLayer,
    };
    var goals = {};
    function workerInit() {
	if ('serviceWorker' in navigator) {
	    navigator.serviceWorker.register('./serviceworker.js')
		.then(function() {
		    console.log('service worker registered');
		});
	}
    }
    function loadGoals(areaname, json) {
	if (!json) return;
	fetch(json).then((resp)=>{return resp.json();}).then((r)=>{
	    console.log(JSON.stringify(r));
	    let goal={}, name, coord;
	    if (r.features) {
		for (let m of r.features) {
		    if (m.properties
			&& m.geometry && m.geometry.type=="Point") {
			name = m.properties.name;
			coord = m.geometry.coordinates;
			goal[name] = coord;
		    }
		}
		goals[areaname] = goal;
	    }
	});
    }
    function switchArea(areaname) {
	console.log(areaname);
	baseLayers[areaname].addTo(mymap);
	if (area[areaname])
	    mymap.setMaxBounds(area[areaname].bounds);
	else
	    mymap.setMaxBounds(null);
	gpsMarker.setLatLng(mymap.getCenter());
	if (goals[areaname]) {
	    let sel = document.getElementById("goals");
	    let opts = "";
	    let glist = goals[areaname];
	    for (let point of Object.keys(glist)) {
		opts += `<option value=${glist[point]}>${point}</option>\n`;
	    }
	    sel.innerHTML = opts;
	}
    }
    function mapInit() {
	infobox = document.getElementById("info");
	mymap = L.map("mymap", baseLayers).setView([38.891, 139.824], 18);
	mymap.on('click', (e)=>{onSuccess2(e)});
	gpsMarker = L.marker(mymap.getCenter()).addTo(mymap).bindPopup("");
	gpsMarker.setPopupContent("foo");
	btnGet  = document.getElementById("get");
	btnMemo = document.getElementById("memo");
	if (btnGet) btnGet.addEventListener("click", getGPS, false);
	if (btnMemo)btnMemo.addEventListener("click", stopGPS, false);
	// Create Area Selection Button
	let btnList = document.getElementById("buttons");
	for (var a of Object.keys(area)) {
	    let btn = document.createElement("button");
	    btn.innerText = area[a].name;
	    console.log(area[a].name);
	    let x=a;
	    btn.addEventListener('click', (e)=>{switchArea(x);});
	    btnList.appendChild(btn);
	    baseLayers[a] = L.imageOverlay(area[a].map, area[a].bounds);
	    loadGoals(a, area[a].geojson);
	}
	switchArea(a);
	mymap.on('baselayerchange', (e)=>{
	    switchArea(e.name);
	});
	L.control.layers(baseLayers).addTo(mymap);
    }
    function dispInfo(msg) {
	info.innerText = msg;
    }
    function getGPS(ev) {
	navigator.geolocation.getCurrentPosition(
	    onSuccess, onError, {
		maximumAge: 0, timeout: 8000, enableHighAccuracy: true
	    });
    }
    function stopGPS(ev) {
	
    }
    function onSuccessL(latlng) {
	mymap.panTo(latlng);// 地図の中心を取得した位置に
	let lat = latlng.lat, lng = latlng.lng;
	let str = `ここは北緯${lat.toFixed(5)}, 東経${lng.toFixed(5)}. `;
	gpsMarker.setPopupContent(	// ポップアップ表示を
	    str				// 更新後の緯度経度に変え、
	).openPopup().setLatLng(latlng);// ポップアップし、ポイントも変更する
	let sel = document.getElementById("goals");
	console.log("val="+sel.value);
	if (sel && sel.value) {
	    let idx = sel.selectedIndex, pname = sel.options[idx].text;
	    let lon = sel.value.split(",")[0],
		lat = sel.value.split(",")[1];
	    let distance = latlng.distanceTo([lat, lon]);
	    console.log(`DDDDDDDDD=${distance}`);
	    str += `${pname}まであと${distance.toFixed(1)}m.`;
	}
	dispInfo(str);
	console.log(latlng);
    }
    function onSuccess2(ev) {
	onSuccessL(ev.latlng);
    }
    function onSuccess(pos) { // 成功時のコールバック。関数名は何でもよい。
	// pos.coords に位置情報が入る。LeafletのLatLngに変換する。
	onSuccessL(L.latLng([pos.coords.latitude, pos.coords.longitude]));
    }
    var nTrial = 10;// 最大試行回数を決めておく
    function onError(err) {// 失敗時のコールバック
	restN = "あと"+(--nTrial)+"回試行します。";
	gpsMarker.setPopupContent("取得失敗:"+restN).openPopup();
	dispInfo(restN);
	if (nTrial > 0) {// 残り回数があれば
	    getGPS();// 再度取得を試行する
	}
    }
    workerInit();
    mapInit();
});