使用 Geolocation API 的简单里程表

Michael Mahemoff
Michael Mahemoff

简介

借助 Geolocation API,您可以了解用户的位置,并在用户移动时密切关注他们(始终征得用户同意)。此功能可用于用户查询,例如引导用户前往目的地。它还可用于为用户创建的一些内容添加“地理位置标记”,例如标记照片的拍摄地点。该 API 与设备无关;只要客户端可以以标准方式请求和接收位置数据,它就不会关心浏览器如何确定位置。底层机制可能是通过 GPS、Wi-Fi 或仅仅让用户手动输入其位置信息。由于任何查找都需要一些时间,因此该 API 是异步的;每当您请求位置时,都需要向其传递回调方法。

此示例是一个行程计,用于显示初始位置,并持续显示自网页加载以来行驶的距离。

第 1 步:检查兼容性

Browser Support

  • Chrome: 5.
  • Edge: 12.
  • Firefox: 3.5.
  • Safari: 5.

Source

您可以通过测试是否存在地理位置对象来轻松检查兼容性:

// 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 实现改编自 Moveable Type 提供的脚本,该脚本采用了知识共享许可

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