document.addEventListener("DOMContentLoaded", ()=>{
const DEBUG = document.URL.match(/debug/);
const G_KETA = 6, LSkey = "markers";
const POND = [38.892143, 139.824226], DOLL = [38.89226, 139.819763];
const goals = {pond: POND, doll: DOLL};
const points = {
"ルビー": [38.895249, 139.822126],
//"サファイヤ": [38.889365, 139.821872],
"サファイヤ": [38.889387, 139.821946],
"アメジスト": [38.929598, 139.852712]
};
const thresh = 30.0;
var gnssWatchID = null, gnssCount = {};
var mymap, infobox, btnGet, btnSTOP;
var yellowIcon;
var gsiLayer = L.tileLayer(
'https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
attribution:
'<a href="http://maps.gsi.go.jp/development/ichiran.html">国土地理院</a>',
maxZoom: 20, maxNativeZoom: 18
});
var gsiPhoto = L.tileLayer(
'https://cyberjapandata.gsi.go.jp/xyz/seamlessphoto/{z}/{x}/{y}.jpg',
{attribution: '© <a href="http://maps.gsi.go.jp/development/ichiran.html">国土地理院</a>',
maxZoom: 20, maxNativeZoom: 18});
var osmLayer = L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution:
'© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
maxZoom: 20, maxNativeZoom: 18
});
var offlineLayerGsiPhoto = L.imageOverlay(
"img/koekimap.png",
[[38.895917, 139.816078], [38.888749, 139.826029]]
);
var offlineLayerOSM = L.imageOverlay(
"img/osm-koekimap.png",
[[38.895917, 139.816078], [38.888749, 139.826029]]
);
var baseLayers = {
"(オフライン用)大学周辺地理院空中写真": offlineLayerGsiPhoto,
"(オフライン用)大学周辺OSM": offlineLayerOSM,
OpenStreetMap: osmLayer,
地理院地図: gsiLayer,
地理院空中写真: gsiPhoto,
};
function workerInit() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('./serviceworker.js')
.then(function() {
console.log('service worker registered');
});
}
}
var stoPrefix = "thg_";
var LS = {
"getItem": (i)=>{return localStorage.getItem(stoPrefix+i);},
"removeItem": (i)=>{return localStorage.removeItem(stoPrefix+i);},
"setItem": (k,v)=>{return localStorage.setItem(stoPrefix+k, v);},
"reset": ()=>{
for (let p of Object.keys(localStorage)) {
console.log(`LS=${p}`);
if (p.startsWith(stoPrefix))
localStorage.removeItem(p);
}
}
}
function mvMarker(ll) {
let info = `北緯=${ll.lat.toFixed(G_KETA)}
東経=${ll.lng.toFixed(G_KETA)}`;
let dist;
let div = document.createElement("div"),
p = document.createElement("p");
lastMarker.setLatLng(ll);
// Search nearest point and show distance
let distList = [];
for (let p in points) {
distList.push({name: p, dist: ll.distanceTo(points[p])});
}
distList = distList.sort((a,b) => {
if (a.dist < b.dist) return -1;
if (a.dist > b.dist) return 1;
return 0;
});
let d = distList[0].dist.toFixed(1);
if (d/1.0 > thresh) {
dispInfo(`一番近い石まで${d}m`);
return;
}
let here = distList[0].name, herell;
let stonePos = L.latLng(points[here]);
if (DEBUG)
herell = ll;
else
herell = stonePos;
dispInfo(`ここは${here}. 賢者への司令はマーカーに記した。タップせよ。`);
let s = `宝のありかまで`;
if (DEBUG) {
for (let target in goals) {
dist = herell.distanceTo(goals[target]).toFixed(1);
s += ", "+target.toString()+"="+dist+`\n`;
}
}
dist = stonePos.distanceTo(goals.doll).toFixed(1);
s += `あと${dist}m
ここから${dist}mの地点をくまなく調べるのじゃ。
(この場所をしっかり記録して教室にもどって地図で探そう!)`;
/*
if (ll.distanceTo(stonePos) > 5) {
L.marker(stonePos, {icon: yellowIcon}).addTo(mymap);
}
*/
p.innerText = s;
div.appendChild(p);
//div.appendChild(btn);
console.log(`s=${s}`);
lastMarker.bindPopup(div);
lastMarker.on('popupopen', (e)=>{
let p = e.target.getPopup().getContent().querySelector("p");
popupOpenedMarker = e.target;
});
lastMarker.addTo(mymap).openPopup();
}
function mvMarkerByGNSS(latlng) {
mymap.panTo(latlng);
mvMarker(latlng);
}
function mvMarkerByClick(e) {
mvMarker(e.latlng);
}
function mapInit() {
infobox = document.getElementById("info");
mymap = L.map("mymap", baseLayers).setView([38.894, 139.81976], 18);
L.control.scale().addTo(mymap); // 縮尺表示追加
lastMarker = L.marker(mymap.getCenter());
lastMarker.setPopupContent("Hi!").addTo(mymap);
btnGet = document.getElementById("get");
btnSTOP = document.getElementById("stop");
if (btnGet) btnGet.addEventListener("click", getGNSS, false);
if (btnSTOP)btnSTOP.addEventListener("click", stopGNSS, false);
// Create yellow Icon
yellowIcon = L.icon({
iconUrl: "img/Yellow.png",
iconSize: [40, 41],
iconAnchor: [10, 41],
popupAnchor: [3, -41]
});
L.control.layers(baseLayers).addTo(mymap);
// offlineLayerGsiPhoto.addTo(mymap);
osmLayer.addTo(mymap);
if (DEBUG) mymap.on('click', mvMarkerByClick);
}
function dispInfo(msg) {
info.innerText = msg;
}
function clearWatchGNSS() { // 位置取得ボタンを元に戻す
mymap.stopLocate();
gnssWatchID = null;
btnGet.classList.remove('running');
btnGet.disabled = false;
// dispInfo("衛星信号取得停止");
}
function getGNSS(ev) {
if (gnssWatchID) {
dispInfo("もう探索中なの、急かしても無駄よ.");
return;
}
gnssWatchID = mymap.locate({
watch: false,
maximumAge: 0, timeout: 8000, enableHighAccuracy: true
});
mymap.on('locationfound', onSuccess)
mymap.on('locationerror', onError)
btnGet.classList.add('running');
btnGet.disabled = true;
dispInfo("取得中...");
}
function stopGNSS(ev) {
clearWatchGNSS();
dispInfo("衛星信号捕捉を停止しました.");
}
function onSuccess(pos) { // 成功時のコールバック。関数名は何でもよい。
// pos.coords に位置情報が入る。LeafletのLatLngに変換する。
//onSuccessL(L.latLng([pos.coords.latitude, pos.coords.longitude]));
console.log(pos.latlng);
mvMarkerByGNSS(pos.latlng);
clearWatchGNSS();
}
function onError(err) {// 失敗時のコールバック
lastMarker.setPopupContent("取得失敗:").openPopup();
dispInfo("空がよく見える位置でないと駄目なのよ");
dispInfo("衛星信号捕捉は中止するわね.")
clearWatchGNSS();
}
workerInit();
mapInit();
});