使用 Geolocation API 的簡單行程計量器

Michael Mahemoff
Michael Mahemoff

簡介

Geolocation API 一律先取得使用者同意,有助您找出使用者的位置,並掌握他們移動到的位置。這項功能可用於使用者查詢內容 (例如將有人帶往目的地)。這項功能也可用於「為」使用者建立的部分內容「加上地理標記」,例如標記相片的拍攝地點。這個 API 適用於各種裝置,不在乎瀏覽器如何判斷位置,只要用戶端能以標準方式要求及接收位置資料即可。基本機制可能是透過 GPS 和 WiFi,也可能只是要求使用者手動輸入位置。由於上述任何查詢都需要一點時間才能完成,因此 API 是非同步的,每當您要求位置時,就會傳遞回呼方法。

以下範例使用行程計量器,顯示初始位置,並持續顯示網頁載入後移動的距離。

步驟 1:檢查相容性

瀏覽器支援

  • 5
  • 12
  • 3.5
  • 5

資料來源

測試地理位置物件是否存在,即可輕鬆檢查相容性:

// check for Geolocation support
if (navigator.geolocation) {
  console.log('Geolocation is supported!');
}
else {
  console.log('Geolocation is not supported for this Browser/OS version yet.');
}

步驟 2:宣告行程計量 HTML

在這個範例中,您可以建構行程計量器,因此宣告下列 HTML:

<div id="tripmeter">
<p>
Starting Location (lat, lon):<br/>
<span id="startLat">???</span>°, <span id="startLon">???</span>°
</p>
<p>
Current Location (lat, lon):<br/>
<span id="currentLat">???</span>°, <span id="currentLon">???</span>°
</p>
<p>
Distance from starting location:<br/>
<span id="distance">0</span> km
</p>
</div>

接下來的幾個步驟會使用 Geolocation API 填入所有空白的 Span。

步驟 3:判斷使用者目前的位置

getCurrentPosition() 會以非同步方式回報使用者目前的所在位置。網頁載入後立即呼叫,讓系統正確填入內容,並儲存供日後使用;起始位置如下:

window.onload = function() {
var startPos;
navigator.geolocation.getCurrentPosition(function(position) {
startPos = position;
document.getElementById('startLat').innerHTML = startPos.coords.latitude;
document.getElementById('startLon').innerHTML = startPos.coords.longitude;
});
};

如果此網域上的應用程式首次要求權限,瀏覽器通常會檢查使用者同意。視瀏覽器而定,系統可能也會偏好設定一律允許或不允許權限查詢,在這種情況下,就會略過確認程序。

執行這段程式碼後,您應該會看到起始位置。視瀏覽器使用的位置而定,位置物件可能不僅包含經緯度,還包含其他資料,例如包含海拔高度或方向。如要進一步探索,可以將位置變數記錄至主控台。

步驟 4:處理錯誤

很抱歉,並非所有位置查詢皆成功。這可能是因為 GPS 無法定位,或是使用者突然停用位置查詢功能。如果發生錯誤,系統會呼叫 getCurrentPosition() 的第二個選用引數,以便在回呼中通知使用者:

window.onload = function() {
var startPos;
navigator.geolocation.getCurrentPosition(function(position) {
// same as above
}, function(error) {
alert('Error occurred. Error code: ' + error.code);
// error.code can be:
//   0: unknown error
//   1: permission denied
//   2: position unavailable (error response from locaton provider)
//   3: timed out
});
};

步驟 5:監控使用者的位置

上一個對 getCurrentPosition() 的呼叫只會在網頁載入時執行一次。如要追蹤變更,請使用 watchPosition()。使用者移動時,這項功能會自動通知回呼函式:

navigator.geolocation.watchPosition(function(position) {
document.getElementById('currentLat').innerHTML = position.coords.latitude;
document.getElementById('currentLon').innerHTML = position.coords.longitude;
});

步驟 6:顯示移動距離

這個步驟與 Geolocation API 直接相關,而是無條件四捨五入,並舉例說明如何使用位置資料。在 watchPosition() 處理常式中新增一行額外行,填入移動距離:

navigator.geolocation.watchPosition(function(position) {
// same as above
document.getElementById('distance').innerHTML =
    calculateDistance(startPos.coords.latitude, startPos.coords.longitude,
                    position.coords.latitude, position.coords.longitude);
});

calculateDistance() 函式會執行幾何演算法,判斷兩個座標值之間的距離。JavaScript 實作是根據可移動類型提供的指令碼,根據創用 CC 授權調整而成:

function calculateDistance(lat1, lon1, lat2, lon2) {
var R = 6371; // km
var dLat = (lat2 - lat1).toRad();
var dLon = (lon2 - lon1).toRad();
var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
        Math.cos(lat1.toRad()) * Math.cos(lat2.toRad()) *
        Math.sin(dLon / 2) * Math.sin(dLon / 2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
var d = R * c;
return d;
}
Number.prototype.toRad = function() {
return this * Math.PI / 180;
}