使用 Geolocation API 的简单里程表

Michael Mahemoff
Michael Mahemoff

简介

借助 Geolocation API,您可以找出用户所在位置,并密切关注他们的动向,这一切都要征得用户同意。此功能可以作为用户查询的一部分,例如指引某人到达目的地。它还可用于为用户创建的某些内容添加“地理位置标记”,例如标记照片的拍摄地点。该 API 与设备无关;它不关心浏览器如何确定位置,只要客户端能够以标准方式请求和接收位置数据。其底层机制可能是通过 GPS、Wi-Fi,或只是要求用户手动输入其位置。由于所有这些查找都需要花费一些时间,因此该 API 是异步进行的;每当您请求位置时,您都可以通过回调方法来传递该 API。

此处的行程表会显示初始位置,并保持显示用户在网页加载后经过的距离。

第 1 步:检查兼容性

浏览器支持

  • 5
  • 12
  • 3.5
  • 5

来源

您可以通过测试是否存在 Geolocation 对象,轻松检查兼容性:

// 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 实现基于采用知识共享许可可移动类型提供的脚本

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;
}