view event/oasis2017/gpsquiz/minato/catgps2.js @ 1712:afcc7ed107e7

Add GPS quiz program
author houtin <c115080@g.koeki-u.ac.jp>
date Fri, 28 Jul 2017 15:20:41 +0900
parents
children
line wrap: on
line source

function distance(x1, y1, x2, y2) {	// ヒュベニ式による距離概算
    rx = 6378137;			// 赤道半径(m) WGS84
    ry = 6356752.314;			// 極半径(m)   WGS84
    e2=(rx*rx-ry*ry)/rx/rx;		// 離心率 E^2
    dx = (x2-x1)*Math.PI/180;		// 経度の差をラジアン変換
    dy = (y2-y1)*Math.PI/180;		// 緯度の差をラジアン変換
    my = (y1+y2)/2.0*Math.PI/180;	// 緯度の平均をラジアン変換
    w = Math.sqrt(1-e2*Math.sin(my)*Math.sin(my));
    m = rx*(1-e2)/Math.pow(w,3);		// 子午線曲率半径
    n = rx/w;				// 卯酉線曲率半径
    return Math.sqrt(Math.pow(dy*m,2) + Math.pow(dx*n*Math.cos(my),2));
}


function game(){
    var threshold = 15;		// 何m接近をゴールとするか

    var timerInterval = 10000;	// GPS失敗で何秒後に再取得か
    var tmId = null;
    var i = 0, countD = document.getElementById("countdown");

    var mymap = L.map("mymap").setView(abcd[0].GPS, 14);
    L.tileLayer('//{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
	attribution:
	'&copy; <a href="http://osm.org/copyright">\
	OpenStreetMap</a> contributors',
	maxZoom: 20, maxNativeZoom: 18
    }).addTo(mymap);

    var info = document.getElementById("info");
    var point = L.marker(mymap.getCenter()).addTo(mymap);
    var stop = document.getElementById("stp");
    document.getElementById("clr").addEventListener("click", clearWebStorage, false);
    var gps = document.getElementById("str");
    var ser = document.getElementById("serif");
    var tm = document.getElementById("time");
    var nowTrying = null;
    var questionIcon = L.icon({
	iconUrl:'../red-icon.png',
	iconSize:[25, 41],
	iconAnchor:[19, 19],
	popupAnchor: [0, -60],
	shadowUrl:'../marker-shadow.png',
	shadowSize:[41, 41],
	shadowAnchor:[19, 19]
    });
    doflag=true;
    function tryGetGPS() {
	clearTimer();
	ser.textContent = "GPS取得..."
	nowTrying = navigator.geolocation.getCurrentPosition(
    	    onSuccess, onError,{
    		maximumAge: 0, timeout: 3000, enableHighAccuracy: true})
    }
    
    function onemore() {
	if (nowTrying || tmId) {
	    info.textContent = "既にGPS取得試行or待機中です";
	} else {
	    startTimer();
	}
    }
    function startTimer() {
	if (tmId==null){
	    tmId = setTimeout(tryGetGPS, 5000);
    	    ser.textContent = "5秒後にGPS取得…";
	    tm.textConent= "周りに注意して楽しく遊びましょう!";
    	}
    }
    function clearTimer() {
     	if (tmId) {
	    clearTimeout(tmId);
	    //nowTrying=nil;
	}
    }
    function countDown(){
	if (doflag){
	    alert("遊ぶときは周りに注意して遊びましょう");
	    tryGetGPS();
	} else{
	    tryGetGPS();
	    doflag=true;
	    tmId=null;
    }
    
    function stopCountDown() {
	//alert("dsafuilj");
	//clearTimeout();
	doflag=false;
	countD.textContent = "stop!";
     	ser.innerHTML = "startボタンをもう一度押すと始まります";
    }

    function clearWebStorage() {
	if (confirm("クイズ関連のデータをリセットします")) {
	    localStorage.clear();
	    info.textContent = "クリアしました。最初からお楽しみください。"
	}
    }
    function qdisp(nth) {
	qinfo = abcd[nth];
	// qinfo = {"GPS":[lng,lat], "mondai":QQQQ, "nanmojime":2,
	//	    "hint":HINT}
	toi = qinfo['mondai'];
	moji = qinfo['nanmojime'];
	markers[nth].bindPopup(qinfo['hint']).setIcon(
	    questionIcon).openPopup();
	info.innerHTML = toi;
	info.style.color="red";
	tm.innerHTML ="問題を解いて使う文字を並び変えて言葉にしよう!";
	countD.innerHTML = "この問題の答で使う文字は"+moji+"文字目の文字だよ!"
	countD.innerHTML += "<br>\n次の地点に近づいたら再度STARTを押してください"
	//以下、WebStorageに取得したものを追加する
	localStorage.setItem(nth , true);
	
    }
    function onSuccess(pos) {
	nowTrying = null;
	var latlng = L.latLng([pos.coords.latitude, pos.coords.longitude]);
	ser.textContent = "現在の位置は"+latlng+"です。";
	mymap.panTo(latlng);	
	point.setPopupContent("now").openPopup().setLatLng(latlng);
	var lat = latlng.lat, lng = latlng.lng;
	
	for (i = 0; i<abcd.length; i++) {
	    var gpos = abcd[i].GPS,
	    glat = gpos[0],
	    glng = gpos[1];
	    d = distance(glng,glat,lng,lat);	// 距離を計算
	    d = Math.floor(d*100)/100;
	    //alert(i);
	    if (d <= threshold) {
		ser.textContent += d+"m";
		qdisp(i);
		
		break;
	    }
	}
	if (i == abcd.length) {			// 見つかってbreakした場合
	    info.innerHTML = "距離: "+Math.round(d*100)/100+"m";	// 表示
	    info.style.color="black";
	    onemore();				// 接近しなければもう一回
	}
    }
    function onError(err) {			// 失敗時
	nowTrying = null;
	ser.textContent = "現在位置の取得失敗.10秒後にもう一回";
	tmId = setTimeout(tryGetGPS, timerInterval);
    }
    //初期化 - abcdすべての位置にマーカを打つ
    var markerPoints = [], markers = [];
    for (var i=0; i<abcd.length; i++) {
	q = abcd[i];
	latlng = L.latLng(q['GPS']);
	markerPoints.push(latlng);
	var m = L.marker(latlng);
	markers.push(m.addTo(mymap));
	if (localStorage.getItem(i)) {		// 既に訪れた場所なら
	    m.bindPopup(q['hint']).setIcon(questionIcon); // ヒントを提示
	} else {
	    m.bindPopup("この場所に行けば問題とヒントがゲットできます")
	}
    }
    mymap.fitBounds(markerPoints);
    gps.addEventListener("click", countDown, false);
    stop.addEventListener("click", stopCountDown, false);
};
document.addEventListener("DOMContentLoaded", game, false);

yatex.org