uni.getDistance需统一使用GCJ-02坐标系,避免WGS84混用导致偏差;前端仅适用于粗略预估费用,精确计价须后端调用高德/腾讯路线API;批量计算应交由后端处理,前端传参前须用Number()强制转换坐标类型。

uni.getDistance 是首选,但必须用对坐标系
跑腿场景下距离不准,八成是因为混用了 WGS84 和 GCJ-02 坐标。uni.getLocation 默认返回 WGS84(GPS 原始坐标),但 uni-app 的 map 组件、uni.openLocation、高德/腾讯地图 SDK 渲染和路线规划都默认按 GCJ-02 处理。直接拿 WGS84 坐标套公式算,结果和地图上看到的路径偏差几百米很常见。
实操建议:
- 统一用
uni.getLocation({ type: 'gcj02' })获取用户定位,确保和后台存的骑手/门店坐标(通常来自高德 API)同源 - 调用
uni.getDistance时,参数名必须是latitude1/longitude1和latitude2/longitude2,不能简写为lat1或lng2 - H5 平台下该 API 会 fallback 到浏览器原生定位 + 简化球面公式,误差略大但可接受;小程序和 App 平台走的是原生 SDK,精度更高
- 若后端返回的是百度 BD-09 坐标,必须先转 GCJ-02 再传入,否则
uni.getDistance结果失真
费用计算不能只靠直线距离
跑腿计价规则往往包含起步价、里程费、时段加价、重量加价、楼层费等,而 uni.getDistance 返回的是两点间球面距离(单位:米),不是导航路径长度。用户感知的“配送距离”其实是高德/腾讯路线规划 API 返回的 polyline 路径总长。
关键判断:
- 前端仅做预估费用时,可用
uni.getDistance结果粗略映射(比如 ≤1km 收 8 元,每超 500m +1.5 元),但需明确告知用户“实际费用以订单确认页为准” - 若需精确计价(如接单前展示准确运费),必须由后端调用高德/腾讯路线规划接口(
/direction/driving),传入 GCJ-02 坐标,取routes[0].distance字段(单位:米) - 避免在前端拼接路线 API 请求——密钥暴露风险高,且微信小程序对 request 域名有严格白名单限制
批量距离计算别在前端硬扛
智能派单或接单大厅里常需比对当前骑手与 10+ 个待派订单的距离。如果每个都调 uni.getDistance,iOS 上可能触发系统限频,Android 上则容易卡顿。
更稳的做法:
- 把骑手实时坐标(GCJ-02)和一批订单坐标(同样 GCJ-02)一次性发给后端
- 后端用 Haversine 批量计算(注意:输入必须是 Number 类型,字符串未
parseFloat会导致 NaN 静默传播) - 返回已按距离排序的订单 ID 列表,前端只负责渲染,不参与计算逻辑
- 若必须前端算,用 Web Worker 拆分计算任务,避免阻塞 UI 线程
地图组件里显示距离要绕开 polyfill 陷阱
在 组件上叠加自定义 marker 并标注“距您 1.2km”,看似简单,但容易踩两个坑:
- map 的
show-location开启后,系统定位点坐标是 GCJ-02,但某些安卓机型bindregionchange回调里的centerLat/centerLng可能仍是 WGS84,需校验 - 使用
polyline绘制导航线时,points数组里的坐标必须全部为 GCJ-02,混入 WGS84 会导致折线严重偏移 - 微信小程序中
map的markers不支持动态更新 distance 字段,得手动计算后写进callout.content
最易被忽略的一点:所有坐标值在传入任何 API 前,务必用 Number() 强制转换,尤其从后端 JSON 解析出来时,经纬度可能是字符串类型——这个细节不处理,距离就变成 NaN,而且不报错。











