讓 HTML5 來為你定位


Geolocation


HTML5 的 geolocation 是一個令人興奮的 API,通過這套 API,Javascript 代碼就能夠訪問到用戶的當前位置。當然,訪問之前必須得到用戶的明確認可,即同意在頁面共享位置。如果頁面嘗試訪問地理位置信息,瀏覽器就會顯示一個對話框,請求用戶許可共享其地理位置信息,比如這樣:

用戶同意(允許)之后,Geolocation 的 api 就能起作用了。

getCurrentPosition() 方法


Geolocation API 在瀏覽器中的實現是 navigator.geolocation 對象,這個對象包含 3 個方法。第一個方法是 getCurrentPosition(),調用這個方法就會觸發請求用戶共享地理定位信息的對話框。這個方法接收 3 個參數:成功回調函數,可選的失敗回調函數和可選的選項對象。

其中,成功回調函數會接收到一個 Position 對象參數,該對象有兩個屬性:coords 和 timestamp。而 coords 對象中將包含下列與位置相關的信息。

  • latitude:以十進制度數表示的維度
  • longtitude:以十進制度數表示的經度
  • accuracy:經緯度坐標的精度,以米為單位

有些瀏覽器可能會在 coords 對象中提供如下屬性。

  • altitude:以米為單位的海拔高度,如果沒有相關數據則值為 null
  • altitudeAccuracy:海拔高度的精度,以米為單位,數值越大越不精確
  • heading:指南針的方向,0°表示正北,值為 NaN 表示沒有檢測到數據
  • speed:速度,即每秒移動多少米,如果沒有相關數據則值為 null

說了這么多,我們來簡單應用下,寫一段代碼獲取當前的經緯度,然后輸出:

navigator.geolocation.getCurrentPosition(geo_success, geo_error);

function geo_success(position) {
  console.log(position.coords.latitude, position.coords.longitude);
}

function geo_error(msg) {
  console.log(msg.code, msg.message);
}

代碼很簡單,如果請求成功了就執行 geo_success() 函數,打印經緯度,如果失敗了,輸出一些信息(失敗回調)。

getCurrentPosition() 的第二個參數,即失敗回調函數,在被調用的時候也會接收到一個參數。這個參數是一個對象,包含兩個屬性:messagecode。其中,message 屬性中保存着給人看的文本消息,解釋為什么會出錯,而 code 屬性中保存着一個數值,表示錯誤的類型:用戶拒絕共享(1),位置無效(2)或者超時(3)。實際開發中,大多數 Web 應用只會講錯誤消息保存到日志文件中,而不一定會修改用戶界面。

我們在 PC 端的 chrome 瀏覽器中執行這段代碼,結果是令人遺憾的:

掐指一算,估計是被牆了... 事實上,以 Chrome 瀏覽器為例,如果您允許 Chrome 瀏覽器與網站共享您的位置,Chrome 瀏覽器會向 Google 位置服務(此環節被牆)發送本地網絡信息,估計您所在的位置。然后,瀏覽器會與請求使用您位置的網站共享您的位置。

接着在 Android 機上測試了下,沒被牆,畢竟谷歌是 Android 的親爹啊。打印出來的信息如下:

31.188199 121.632919

當然只是知道經緯度或許不太那么直觀,如果能把位置顯示在地圖上那就直觀多了!這里我用了高德地圖的API(猛戳這里看效果):

<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
  <title>地圖顯示</title>
  <link rel="stylesheet" href="http://cache.amap.com/lbs/static/main.css?v=1.0" />
  <script src="http://webapi.amap.com/maps?v=1.3&key=您申請的key值"></script>
</head>
<body>
  <div id="mapContainer"></div>
  <script>
    navigator.geolocation.getCurrentPosition(geo_success, geo_error);

    function geo_success(position) {
      var map = new AMap.Map('mapContainer', {
        // 設置中心點
        center: [position.coords.longitude, position.coords.latitude],

        // 設置縮放級別
        zoom: 13
      });

      var marker = new AMap.Marker({
        //復雜圖標
        icon: new AMap.Icon({
            //圖標大小
            size: new AMap.Size(28, 37),
            //大圖地址
            image: "http://webapi.amap.com/images/custom_a_j.png",
            imageOffset: new AMap.Pixel(-28, 0)
        }),
        //在地圖上添加點
        position: [position.coords.longitude, position.coords.latitude]
      });

      marker.setMap(map);
    }

    function geo_error(msg) {
      console.log(msg.code, msg.message);
    }
  </script>
</body>
</html>

在手機上打開后:

我的天哪!實在是太准了!如果我把代碼里的 zoom 參數再加大點,能精確到小區了...當然,這並不奇怪,因為這本來就是高德地圖百度地圖定位的一部分嘛。

事實上,getCurrentPosition() 還有第三個參數,該參數是一個選項對象,用於設定信息的類型。可以設置的選項有三個:enableHighAccuracy 是一個布爾值,表示必須盡可能使用最精確的位置信息;timeout 是以毫秒數表示的等待位置信息的最長時間;maximumAge 表示上一次取得的坐標信息的有效時間,以毫秒表示,如果時間到則重新取得新坐標信息。

除非確實需要非常精確的信息,否則建議保持 enableHighAccuracy 的 false 值(默認值)。將這個選項設置為 true 需要更長的時候,而且在移動設備上更耗電。類似的,如果不需要頻繁更新用戶的位置信息,那么可以將 maximumAge 設置為 Infinity,從而始終都使用上一次的坐標信息。

navigator.geolocation.getCurrentPosition(locationSuccess, locationError, {
  // 指示瀏覽器獲取高精度的位置,默認為false
  enableHighAcuracy: true,
  // 指定獲取地理位置的超時時間,默認不限時,單位為毫秒
  timeout: 5000,
  // 最長有效期,在重復獲取地理位置時,此參數指定多久再次獲取位置。
  maximumAge: 3000
});

watchPosition() 方法


如果要跟蹤用戶的位置,那么可以使用 watchPosition() 方法。這個方法的使用和 getCurrentPosition() 完全相同。實際上 watchPosition() 與定時調用 getCurrentPosition() 能得到相同效果。在第一次調用 watchPosition() 方法后,會取得當前位置,執行成功回調或者錯誤回調。然后,watchPosition() 就地等待系統發出位置已改變的信號。

調用 watchPosition() 會返回一個數值標識符,用於跟蹤監控的操作。基於這個返回值可以取消監控操作,只要將其傳遞給 clearWatch() 方法即可(與使用 setTimeout() 和 clearTimeout() 類似),例如:

var watchId = navigator.geolocation.watchPosition(geo_success, geo_error);
clearWatch(watchId);

Geolocation 定位原理


Geolocation API 的數據來源可能是 GPS、IP 地址、RFID、WiFi、藍牙 MAC 地址、GSM/CDMA 卡 ID 等。因為 Geolocation API 是運行在你本地設備上的。所以,在使用 VPN 或代理的情況下,Geo API 仍能獲得你准確的 IP 地址信息(除非因為某些因素瀏覽器獲取不到這些信息)。

在HTML5的實現中,手機等移動設備當然優先使用GPS定位,而筆記本和部分平板,最准的定位是WIFI,至於網線上網的台式機,一般就只能使用IP來定位了,這個准確度最低。


read more:


免責聲明!

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



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