HTML5 Geolocation 初探javascript
讓咱們假設這樣一個場景,有一個web應用程序,它能夠向用戶提供附近不遠處某商場的打折優惠信息。使用HTML5 Geolocation API(地理定位API),能夠請求用戶共享他們的位置信息。css
HTML5 Geolocation技術應用的場景比較多,好比構建計算行走路程、GPS導航的社交應用等。html
本文主要探討HTML5 Geolocation API,包括獲取地理位置數據的途徑,地理位置數據的隱私以及在實際中的應用等。java
目前存在兩種地理定位請求:單次定位請求和重複性的位置更新請求。git
1、地理位置數據的獲取web
獲取地理位置數據的方法有如下幾種:瀏覽器
u IP地址地理定位:自動查找用戶的IP地址,而後檢索其註冊的物理地址;函數
u GPS地理定位:經過收集運行在地球周圍的多個GPS衛星信號來實現;this
u Wi-Fi地理定位:經過三角距離計算得出(三角距離:用戶當前位置到已知的多個Wi-Fi接入點的距離);編碼
u 手機地理定位:經過用戶到一些基站的三角距離肯定;
u 用戶自定義地理定位:用戶本身輸入地址、郵政編碼和其餘一些詳細信息。
2、地理位置數據的隱私
HTML5 Geolocation規範提供了一套保護用戶隱私的機制,除非獲得用戶明確許可,不然不可能獲取位置信息。
HTML5地理定位瀏覽器和設備之間的交互以下所述:
1) 用戶從瀏覽器中打開位置感知應用程序;
2) 應用程序Web頁面加載,而後經過Geolocation函數調用請求位置座標。瀏覽器攔截這一請求,而後請求用戶受權。咱們假設用戶贊成;
3) 瀏覽器從其宿主設備中檢索座標信息。例如,IP地址、Wi-Fi或GPS座標。這是瀏覽器內部功能;
4) 瀏覽器將座標發送給受信任的外部定位服務,它返回一個詳細位置信息,並將該位置信息發回給HTML5 Geolocation應用程序。
3、HTML5 Geolocation API介紹
在訪問使用HTML5 Geolocation API的頁面時,會觸發隱私保護機制。可是若是僅僅是添加代碼,而不被任何方法調用,則不會才觸發隱私保護機制。
要使用 HTML5 Geolocation API,首先要檢查瀏覽器是否支持,代碼以下:
function loadDemo(){ If(navigator.geolocation){ document.getElementById("support").innerHTML = "HTML5 Geolocation supported.」 }else{ ocument.getElementById("support」).innerHTML = "HTML5 Geolocation is not supported in your browser.」 } }
單次定位請求API
Void getCurrentPosition(in PositionCallback successCallBack, in optional PositionErrorCallBack errorCallback, in optiona PositionOptions options)
上述的函數要經過navigator.geolocation來調用,各個參數解釋以下:
successCallBack:瀏覽器指明位置數據可用時調用的函數,即收到實際位置信息並進行處理的地方,此函數只接受一個參數:位置對象,包含座標和一個時間戳;
errorCallback:在獲取位置數據出錯時的處理地方,向用戶說明失敗緣由,可選參數,可是建議使用;
Options:此對象可調整HML5 Geolocation服務的數據收集方式,可選;能夠經過JSON對象進行傳遞,主要包括enableHighAccuracy(啓用HML5 Geolocation服務的高精確度模式、timeout(當前位置所容許的最長時間)、maximumAge(瀏覽器從新計算位置的時間間隔)。
function successCallBack(position){ var latitude = position.coords.latitude; var longitude = position.coords.longitude; var accuracy = position.coords.accuracy; //此處能夠添加代碼,把上述三個值顯示到頁面中。 } ffunction errorCallback(error){ switch(error.code){ //UNKNOWN_ERROR = 0 須要經過message參數查找錯誤的更多信息 case 0: updateStatus("There was an error while retrieving your location:" + error.message); break; //PERMISSION_DENIED = 1 用戶拒絕瀏覽器得到其共享位置 case 1: updateStatus("The user prevented this page form retrieving a location!"); break; //POSITION_UNAVAILABLE = 2 嘗試獲取用戶位置,但失敗 case 2: updateStatus("The browser was unable to determine your location:" + error.message); break; //TIMEOUT = 3 設置了可選的timeout值,嘗試肯定用戶位置的過程超時 case 3: updateStatus("The browser timed out before retriveing the !"); break; } }
重複性位置請求API:
var watchId = navigator.geolocation.watchPosition(updateLocation,handleLocationError); //中止接收位置更新信息 navigator.geolocation.clearWatch(watchId);
4、使用HML5 Geolocation構建應用
使用上述講解的HML5 Geolocation API來實現 一個簡單有用的Web應用程序—距離追蹤器,以瞭解HML5 Geolocation 的強大之處。
本例主要講述從網頁被加載的地方到目前所在位置所通過的距離。使用衆所周知的Haversine公式,其可以根據經緯度來計算地球上兩點間的距離。以下:
關於上述原理,請參考網上其餘教程。
使用js實現的Haversine公式以下:
function toRadians(degree){ return degree * Math.PI / 180 ; } function distance(latitude1,longitude1,latitude1,longitude1){ //R是地球的半徑,以km爲單位 var R = 6371; var deltaLatitude = toRadians(latitude2 - latitude1); var deltaLongitude = toRadians(longitude2 - longitude1); latitude1 = toRadians(latitude1); latitude2 = toRadians(latitude2); var a = Math.sin(deltaLatitude / 2) * Math.sin(deltaLatitude / 2) + Math.cos(latitude1) * Math.cos(latitude2) * Math.sin(deltaLongitude / 2) * Math.sin(deltaLongitude / 2); var c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a)); var d = R * c; return d; }
HTML網頁代碼入下:
<!DOCTYPE html> <head> <meta charset="utf-8"> <title>HTML5 地理定位</title> <link rel="stylesheet" href="styles.css"> </head> <body onload="loadDemo()"> <h1>HTML5 地理位置追蹤器</h1> <p id="status">你的瀏覽器不支持HTML5地理定位</p> <h2>當前位置:</h2> <table border="1"> <tr> <th width="40" scope="col"><h5>緯度</h5></th> <td width="114" id="latitude">?</td> </tr> <tr> <td> 經度</td> <td id="longitude">?</td> </tr> <tr> <td>準確度</td> <td id="accuracy">?</td> </tr> <tr> <td>最近的時間戳</td> <td id="timestamp">?</td> </tr> </table> <h4 id="currDist">當前旅行的距離: 0.0 km</h4> <h4 id="totalDist">總的旅行距離: 0.0 km</h4> </body> <script text="text/javascript"> var totalDistance = 0; var lastLat; var lastLong; Number.prototype.toRadians = function() { return this * Math.PI / 180; } function loadDemo(){ If(navigator.geolocation){ updateSatus("你的瀏覽器支持HTML5地理定位"); navigator.geolocation.watchPosition(updateLocation,handleLocationError,{maximumAge:20000}); } } function updateSatus(message){ document.getElementById("status").innerHTML = message; } function distance(latitude1,longitude1,latitude1,longitude1){ //R是地球的半徑,以km爲單位 var R = 6371; var deltaLatitude = toRadians(latitude2 - latitude1); var deltaLongitude = toRadians(longitude2 - longitude1); latitude1 = toRadians(latitude1); latitude2 = toRadians(latitude2); var a = Math.sin(deltaLatitude / 2) * Math.sin(deltaLatitude / 2) + Math.cos(latitude1) * Math.cos(latitude2) * Math.sin(deltaLongitude / 2) * Math.sin(deltaLongitude / 2); var c = 2 * Math.atan2(Math.sqrt(a),Math.sqrt(1-a)); var d = R * c; return d; } function updateLocation(position){ var latitude = position.coords.latitude; var longitude = position.coords.longitude; var accuracy = position.coords.accuracy; var timestamp = position.timestamp; document.getElementById("latitude").innerHTML = latitude; document.getElementById("longitude").innerHTML = longitude; document.getElementById("accuracy").innerHTML = accuracy; document.getElementById("timestamp").innerHTML = timestamp; if(accuracy >= 500){ updateStatus("不須要計算精確距離"); return; } if((lastLat != null) && (lastLong !=null)){ var currentDistance = distace(latitude, longitude, lastLat, lastLong); document.getElementById("currDist").innerHTML = "當前旅行的距離: " + currentDistance.toFixed(4) + " km"; totalDistance += currentDistance; document.getElementById("totalDist").innerHTML = "總的旅行距離: " + currentDistance.toFixed(4) + " km"; } lastLat = latitude; lastLong = longitude; updateStatus("成功更新位置。"); } function handleLocationError(error) { switch(error.code) { case 0: updateStatus("檢索位置發生錯誤:" + error.message); break; case 1: updateStatus("用戶阻止檢索位置信息。"); break; case 2: updateStatus("瀏覽器不能檢索位置信息:" + error.message); break; case 3: updateStatus("瀏覽器檢索位置信息超時。"); break; } } </script> </html>