GoogleMapsAPI version3/watchPosition()で位置情報を取得し続ける。
GoogleMapAPIで、watchPosition()を用い総移動距離を計算するサンプルを作ってみました。ちなみに、version3では、distanceFrom()メソッドが使えず、2点間の距離を計算するには、prototypeを使用せねばならないようです。
■参考
・Google MAPS API v3でdistanceFrom(二点間の距離を求める)
・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はまだよくわからんことだらけです。