H5 页面可以通过 navigator.geolocation.getCurrentPosition
方法获取用户的经纬度,虽然这是个简单方便的办法,但如果你对精度有更高要求,你可能需要进一步处理这些位置信息,尤其是在中国,因为这里用的是火星坐标系(GCJ-02)。本文将带你了解如何在 H5 页面上精准获取经纬度,并妥善处理可能遇到的问题。
基本用法
通过 navigator.geolocation.getCurrentPosition
,你可以获得用户的实时位置,语法非常直白:
js
navigator.geolocation.getCurrentPosition(success, error, options);
其中:
- success(必选):这个是当获取位置成功时的回调函数,它会返回一个对象,里面包含了位置信息。比如:
json
{
"timestamp": 1727062253486,
"coords": {
"accuracy": 28.1,
"latitude": 32.3113001,
"longitude": 111.7724135,
"altitude": null,
"altitudeAccuracy": null,
"heading": null,
"speed": null
}
}
这里的 accuracy
表示精度,单位是米,数值越小表示位置越精确。不过别太过迷信这个数值,尤其是在室内或者信号差的地方,定位的误差可能会很大。
- error(可选):当位置获取失败时会调用这个函数,错误信息会通过 PositionError 对象传递。常见的错误代码包括:
值 | 相关联的常量 | 描述 |
---|---|---|
1 | PERMISSION_DENIED | 用户拒绝了获取位置信息的请求。 |
2 | POSITION_UNAVAILABLE | 无法获取位置信息,可能是设备的问题。 |
3 | TIMEOUT | 获取位置信息超时,设备响应太慢了。 |
- options(可选):这是一些额外的配置选项,允许你定制获取位置信息的方式。常用配置如下:
json
{
"enableHighAccuracy": true, // 是否开启高精度模式,精度更高但耗时可能更长
"timeout": 10000, // 10秒超时时间
"maximumAge": 0 // 禁用缓存,每次都获取实时位置
}
为什么有时候定位偏差很大?
如果你发现通过 getCurrentPosition
获取的 GPS 坐标跟地图上显示的位置有偏差,别慌,这在中国是“正常现象”。原因是中国的地图数据使用的是 GCJ-02 火星坐标系,而全球普遍使用的 GPS 是 WGS-84 坐标系。这两个坐标系不兼容,导致位置显示有偏移。
解决方法
- 如果你要在中国使用准确的地图位置,可能需要进行坐标转换。幸运的是,有很多开源工具可以帮助你将 WGS-84 转换为 GCJ-02。比如
coordtransform
这样的 JavaScript 库就可以轻松完成这个任务。 - 使用本地地图 API:高德地图、百度地图等都提供了 API,直接获取 GCJ-02 格式的坐标。使用这些 API 时,坐标会自动纠偏。
js
AMap.plugin("AMap.Geolocation", function () {
const geolocation = new AMap.Geolocation({
enableHighAccuracy: true, // 是否使用高精度定位
timeout: 10000, // 10秒超时
});
geolocation.getCurrentPosition(function (status, result) {
if (status === "complete") {
console.log("高德坐标:", result.position);
} else {
console.error("定位失败:", result);
}
});
});
未开启定位权限,也没有触发错误回调
在一些 Android 设备上,如果未授予定位权限时,geolocation.getCurrentPosition
既不返回位置,也不触发错误回调,这可能与设备或浏览器的权限管理方式有关。
解决方案
- 可以通过设置
timeout
参数,确保在超时后触发错误回调。
js
navigator.geolocation.getCurrentPosition(
function (position) {
console.log("定位成功:", position);
},
function (error) {
console.error("定位失败:", error);
},
{
enableHighAccuracy: true,
timeout: 5000, // 设置超时时间为 5 秒
maximumAge: 0, // 禁用缓存
}
);
- 手动检查定位权限状态 可以使用
Permissions API
来检查地理位置的权限状态,提前引导用户进行权限管理,不过要注意这个 API 的设备兼容性。
js
navigator.permissions.query({ name: "geolocation" }).then(function (result) {
if (result.state === "denied") {
alert("定位权限被拒绝,请在设置中开启定位权限。");
} else if (result.state === "granted") {
navigator.geolocation.getCurrentPosition(
function (position) {
console.log("定位成功:", position);
},
function (error) {
console.error("定位失败:", error);
}
);
}
});
- 使用 HTTPS 协议
如果你在 HTTP 页面上使用 geolocation.getCurrentPosition
,浏览器将拒绝定位请求且可能不会触发任何回调。