HTML5編程之旅 第1站 Geolocation

HTML5 Geolocation 初探javascript

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

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

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

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

1、地理位置數據的獲取web

獲取地理位置數據的方法有如下幾種:瀏覽器

IP地址地理定位:自動查找用戶的IP地址,而後檢索其註冊的物理地址;函數

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

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

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

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

2、地理位置數據的隱私

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

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

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

2) 應用程序Web頁面加載,而後經過Geolocation函數調用請求位置座標。瀏覽器攔截這一請求,而後請求用戶受權。咱們假設用戶贊成;

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

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>
相關文章
相關標籤/搜索