html5 Geolocation(地理位置定位)學習


1、html5 Geolocation

html5 Geolocation API 使用很簡單,請求一個位置信息,如果用戶同意,瀏覽器會返回一個位置信息,該位置是通過用戶的底層設備(手機,電腦)
提供給瀏覽器。位置信息一般包括經度和緯度信息!
經度和緯度坐標信息一般由兩種方式表示
a、十進制表示:39.17222
b、DMS角度格式表示:39°10'20"

2、位置從哪里來

html5 Geolocation API不指定設備使用哪種底層技術來定位應用程序的用戶,相反,它只是用於檢索位置信息的API,而且通過該API檢索到的數據只具有某種程度的准確性!它並不能保證設備返回的數據就是精確的。

設備可以使用的數據源如下所示:

IP地址
三維坐標
  1、GPS(全球定位系統)
  2、從RFID、Wi-FI和藍牙到Wi-FI的MAC地址
  3、GSM或CDMA手機的ID
用戶自定義數據

2.1 IP地址地理定位數據

過去,基於IP的地址的地理定位方法是獲得位置信息的唯一方式。但其返回的數據通常是不靠譜的,基於IP的地理位置定位方式是:自動查找用戶的IP地址然后檢索其注冊的物理地址,因此如果用戶的ip地址是ISP提供的,其位置往往由服務器供應商的物理地址決定!因此這個地址和用戶實際的地址可能相差很大。

2.2 GPS地理定位數據

GPS是通過搜集運行在地球周圍的多個GPS衛星信號實現的,但是,它的定位時間可能較長,不太適合快速響應的應用程序。而且在室內效果不是很好。

2.3 WI-FI地理定位數據

基於WIFI的地理定位數據是通過三角距離計算得到的,這個三角距離是指用戶當前位置已知的多個wifi接入點的距離。不同於GPS,wifi在室內也非常准確。

2.4 手機地理定位數據

基於手機的地理定位數據是通過用戶到一些基站的三角距離確定。這種方法可提供相當准確的位置結果。這種方法通常和基於WIFI基於GPS地位結合使用。

2.5 用戶自定義數據
用戶自己輸入的一些地理位置信息

3、處理位置信息

由於位置信息數據屬於敏感信息,所以在接到之后必須小心處理,存儲和重傳。如果用戶沒有授權存儲這些信息,那么應用程序在相應任務完成后立即刪除它。

如果需要最位置信息重傳,建議先對其進行加密。

4、瀏覽器支持性檢測

function loaddemo(){
            if(navigator.geolocation){
                alert('瀏覽器支持html5 geolocation');
            }else{
                alert('瀏覽器不支持html5 geolocation');
            }
        }
        loaddemo();

5、位置請求

  位置請求有兩種

  1、單次定位請求
  2、重復性位置更新請求

5.1 單次定位請求

我們看下這個核心函數的調用

void getCurrentPosition(in PositionCallback successCallback,in optional PositionErrorCallback errorCallback,in optional PositionOptions options);
這個方法是通過navigator.geolocation調用的。所以在腳本中需要先取得此對象。
這個方法接收一個必選參數和兩個可選的參數
successCallback 必選參數,位置信息請求成功后處理的地方
errorCallback 可選參數,位置信息請求錯誤后處理的函數
options 可選參數,這個對象可以調整數據搜集的方式

var nvaga = navigator.geolocation;
    nvaga.getCurrentPosition(updatPos,errorLoca);
    function updatPos(position){
        var latitude = position.coords.latitude;//十進制單位
        var longitude = position.coords.longitude;//十進制單位
        var accuracy = position.coords.accuracy;//以m為單位制定緯度和經度與實際位置的差距
        var timestamp = position.timestamp;
        console.log('經度坐標' + latitude);
        console.log('緯度坐標' + longitude);
        console.log('准確度' + accuracy);
        console.log('獲取位置數據的時間' + timestamp);//時間戳
    }
    function errorLoca(error){
        switch(error.code){
            case 0:
                console.log('位置信息獲取失敗,失敗原因'+error.message);
            break;
            case 1://錯誤編碼 PERMISSION_DENIED
                console.log('用戶拒絕共享其位置信息');
            break;
            case 2://錯誤編碼 POSITION_UNAVAILABLE
                console.log('嘗試獲取用戶位置數據,但失敗了');
            break;
            case 3://錯誤編碼 TIMEOUT
                console.log('嘗試獲取用戶的位置數據超時');
            break;
        }
    }

5.2 可選的地理定位請求特性

geolocation 三個可選的參數(enableHighAccuracy,timeout和maximumAge),將這三個參數傳遞給html5 geolocation服務以調整數據收集的

方式,這三個參數可以使用json對象傳遞。
enableHighAccuracy:通知瀏覽器啟用高精度模式,參數的默認值為false,如果啟用該參數,可能會沒有任何差別,也可能會導致機器花費更多的時間和資源來確定位置,應謹慎使用。
timeout:告訴瀏覽器獲取當前位置信息所允許的最長時間。如果這個時間段未完成,就會調用錯誤處理函數。默認值為無窮大
maximumAge:這個值表示瀏覽器重新計算位置的時間間隔,以ms為單位,此值默認為0。
使用可選的參數的調用方式
nvaga.getCurrentPosition(updatPos,errorLoca,{timeout:10000});
告訴瀏覽器任何處理時間超過10s將會觸發錯誤事件。

5.3 重復性位置請求

navigator.geolocation.watchPosition(updatPos,errorLoca);

通過這么簡單的修改后,只要用戶位置發生變化,geolocation服務器就會調用updatPos函數。
如果不想使用更新的話可是通過下面的代碼清除實時更新
navigator.geolocation.clearWatch(watchID);
這個函數會通知geolocation服務器,程序不想要接收用戶的位置信息更新了!

watchID的使用和獲取
var watchId = navigator.geolocation.WatchPosition(updatPos,errorLoca);
//清除位置更新
navigator.geolocation.clearWatch(watchId);

6、實例 距離跟蹤器

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Geolocation</title>
</head>
<body onload="loadAct()">
    <div class="">
        <p id="lat"></p>
        <p id="lonat"></p>
        <p id="accur"></p>
        <p id="times"></p>
        <p id="currdis"></p>
        <p id="totalDis"></p>
    </div>
    <p id="status" style="color:#f00"></p>
</body>
<script>
//實例 距離跟蹤器
    //通過用戶的移動產生的位置更新,計算兩個坐標之間的距離,來確定在這短時間內用戶行走了多少距離,這里我們使用Haversine公式來計算
    //js實現Haversine公式
    Number.prototype.toRadians = function(){
        return this*Math.PI/180;
    }
    // 計算兩個經度和緯度之間的距離
    function distances(latitude1,longitude1,latitude2,longitude2){
        var r = 6371;//定義地球的半徑
        var deltaLatitude = (latitude2 - latitude1).toRadians();
        var deltaLongitude = (longitude2 - longitude1).toRadians();
        latitude1 = latitude1.toRadians();
        latitude2 = latitude2.toRadians();
        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;
    }
    var toldis = 0.0;
    var lastlat;
    var lastlong;
    function updateError(message){
        var status = document.querySelector('#status');
        status.innerHTML = message;
    }
    function updateStatus(message){
        var status = document.querySelector('#status');
        status.style.color = '#0f0';
        status.innerHTML = message;
    }
    function loadAct(){
        if(navigator.geolocation){
            document.querySelector('#status').innerHTML = '您的瀏覽器支持html5 地理定位';
            navigator.geolocation.watchPosition(updateLocation,errorLoca,{timeout:20000});
        }
    }
    function updateLocation(position){
        var latitude = position.coords.latitude;//十進制單位
        var longitude = position.coords.longitude;//十進制單位
        var accuracy = position.coords.accuracy;//以m為單位制定緯度和經度與實際位置的差距
        var timestamp = position.timestamp;
        document.querySelector('#lat').innerHTML = '您當前的經度位置'+latitude;
        document.querySelector('#lonat').innerHTML = '您當前的緯度度位置'+latitude;
        document.querySelector('#accur').innerHTML = '准確度'+accuracy;
        document.querySelector('#times').innerHTML = '獲取位置時間'+timestamp;
        //合理性檢測
        if(accuracy >= 30000){
            updateStatus('需要更准確的信息來計算距離');
            return;
        }
        if(latitude != null && longitude != null){
            var curdis = distances(latitude,longitude,lastlat,lastlong);
            document.querySelector('#currdis').innerHTML = '當前的行走的距離' + curdis;
            toldis += curdis;
            document.querySelector('#totalDis').innerHTML = '您當前行走的總距離為' + toldis +'km';
        }
        lastlat = latitude;
        lastlong = longitude;
    }
    function errorLoca(error){
        switch(error.code){
            case 0:
                updateError('位置信息獲取失敗,失敗原因'+error.message);
            break;
            case 1://錯誤編碼 PERMISSION_DENIED
                updateError('用戶拒絕共享其位置信息');
            break;
            case 2://錯誤編碼 POSITION_UNAVAILABLE
                updateError('嘗試獲取用戶位置數據,但失敗了');
            break;
            case 3://錯誤編碼 TIMEOUT
                updateError('嘗試獲取用戶的位置數據超時');
            break;
        }
    }
    /*
        
    */
</script>
</html>

html5 Geolocationk獲取的值也可以傳遞給谷歌或者百度的地圖API,來使用谷歌,百度他們自己的API,從而實現更復雜的應用!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM