HTML5 Geolocation 初探

jopen 10年前發布 | 35K 次閱讀 HTML5 前端技術

HTML5 Geolocation 初探

讓我們假設這樣一個場景,有一個web應用程序,它可以向用戶提供附近不遠處某商場的打折優惠信息。使用HTML5 Geolocation API(地理定位API),可以請求用戶共享他們的位置信息。

HTML5 Geolocation技術應用的場景比較多,比如構建計算行走路程、GPS導航的社交應用等。

本文主要探討HTML5 Geolocation API,包括獲取地理位置數據的途徑,地理位置數據的隱私以及在實際中的應用等。

目前存在兩種地理定位請求:單次定位請求和重復性的位置更新請求。

一、地理位置數據的獲取

獲取地理位置數據的方法有以下幾種:

IP地址地理定位:自動查找用戶的IP地址,然后檢索其注冊的物理地址;

GPS地理定位:通過收集運行在地球周圍的多個GPS衛星信號來實現;

Wi-Fi地理定位:通過三角距離計算得出(三角距離:用戶當前位置到已知的多個Wi-Fi接入點的距離);

手機地理定位:通過用戶到一些基站的三角距離確定;

用戶自定義地理定位:用戶自己輸入地址、郵政編碼和其他一些詳細信息。

二、地理位置數據的隱私

HTML5 Geolocation規范提供了一套保護用戶隱私的機制,除非得到用戶明確許可,否則不可能獲取位置信息。

HTML5地理定位瀏覽器和設備之間的交互如下所述:

1) 用戶從瀏覽器中打開位置感知應用程序;

2) 應用程序Web頁面加載,然后通過Geolocation函數調用請求位置坐標。瀏覽器攔截這一請求,然后請求用戶授權。我們假設用戶同意;

3) 瀏覽器從其宿主設備中檢索坐標信息。例如,IP地址、Wi-FiGPS坐標。這是瀏覽器內部功能;

4) 瀏覽器將坐標發送給受信任的外部定位服務,它返回一個詳細位置信息,并將該位置信息發回給HTML5 Geolocation應用程序。

三、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);

 

四、使用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>

 

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!