GoogleMapsAPI version3/watchPosition()で位置情報を取得し続ける。

GoogleMapAPIで、watchPosition()を用い総移動距離を計算するサンプルを作ってみました。ちなみに、version3では、distanceFrom()メソッドが使えず、2点間の距離を計算するには、prototypeを使用せねばならないようです。


■参考
Google MAPS API v3でdistanceFrom(二点間の距離を求める)

手軽になった!Google Maps API V3

Google Maps API V3 リファレンス(非公式)2点間の距離を求める

サンプルコード

<html>
    <head>
        <meta  charset="utf-8" />
		<title>watchPosition()サンプル</title>
		<!-- GoogleMap javascrpt -->
		<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true"></script>
		<script type="text/javascript" src="APIキー"></script> 
  		<script type="text/javascript" >
  		
  		//LocationDataクラスのコンストラクタ
		var LocationData = function(latitude, longitude, accuracy, time) {
			this.lat = latitude;
			this.lng = longitude;
			this.accuracy = accuracy;
			this.time = time;
			this.latlng = new google.maps.LatLng(this.lat, this.lng);
		}

		//一つ前の位置情報オブジェクト
		var previousLocationData;
		//現在の位置情報オブジェクト
		var currentLocationData;
		//カウント
		var watchPositionCount = 0;
		//移動距離
		var distance = 0;
  		
  		window.onload = function() {
			if (navigator.geolocation == undefined) {
				alert("位置情報が利用できません。");
				return;
			}
			
			navigator.geolocation.watchPosition(update, errorGettingWatchPosition);
			
			//トレースが成功している場合のコールバック関数。位置が検出されたら緯度、経度、誤差と時間を表示
			function update(position){
			    //currentLocationData
			    currentLocationData = new LocationData(position.coords.latitude, position.coords.longitude, position.coords.accuracy, new Date());
    		            document.getElementById("pos").innerHTML = "緯度: "+currentLocationData.lat+","+ "経度: " +currentLocationData.lng+","+"正確さ: "+currentLocationData.accuracy+"<br>"+(new Date());
    		
    		            //count
    		            watchPositionCount ++;
    		            document.getElementById("count").innerHTML = watchPositionCount;
		
			    if (watchPositionCount == 1) {
				previousLocationData = currentLocationData;
				return;
			     }
			
			     var currentPoint = currentLocationData.latlng; //今回の位置
    		             var previousPoint = previousLocationData.latlng; //前回の位置
    		             distance = distance + currentPoint.distanceFrom(previousPoint);
   			     document.getElementById("distance").innerHTML = distance;
   			     previousLocationData = currentLocationData;
                        }
    
	                    // 失敗したとき
	                 function errorGettingWatchPosition(err) {
		              alert("watchPositisionの失敗("+err.code+")"+err.message);
	                 }
                   }

	         //2点間の距離を追加するメソッドを追加
	         google.maps.LatLng.prototype.distanceFrom = function(newLatLng) {
   	         var lat1 = this.lat();
   	         var radianLat1 = lat1 * ( Math.PI  / 180 );
   	         var lng1 = this.lng();
   	         var radianLng1 = lng1 * ( Math.PI  / 180 );
  	         var lat2 = newLatLng.lat();
	         var radianLat2 = lat2 * ( Math.PI  / 180 );
   	         var lng2 = newLatLng.lng();
   	         var radianLng2 = lng2 * ( Math.PI  / 180 );
   	         var earth_radius = 6378.1;
   	         var diffLat =  ( radianLat1 - radianLat2 );
   	         var diffLng =  ( radianLng1 - radianLng2 );
   	         var sinLat = Math.sin( diffLat / 2  );
   	         var sinLng = Math.sin( diffLng / 2  );
   	         var a = Math.pow(sinLat, 2.0) + Math.cos(radianLat1) * Math.cos(radianLat2) * Math.pow(sinLng, 2.0);
   	         var distance = earth_radius * 2 * Math.asin(Math.min(1, Math.sqrt(a)));
   	         return distance;
                 }
  		</script>
	</head>
	
	<body>
		<div id="pos">lat, long, accuracy</div>
		<div id="count">count</div>
		<div id="distance">distance</div>
	</body>
</html>

→ とりあえずiPhoneでは動作を確認しています。

課題

・privateとpubulic
→このままだと緯度経度を途中で変更できてしまうので、情報隠蔽のところを学ばねば。ただ、prototype.jsでプライベートメソッドを持つクラスを作る方法 を参考にしたのですが、うまく起動しませんでした。。


しかし、javascriptのprototypeはまだよくわからんことだらけです。