微信小程序设备位置上报:BD09 与 WGS84 的那点事

2026-09-28 · 微信小程序 / IoT
微信小程序定位坐标系

小程序里要做设备位置上报,最常见的坑不是 API 调用,而是坐标系对不上。这里把链路讲清楚,并给一个「失败就静默降级」的稳妥写法。

1. 三种坐标系

也就是说:小程序拿到的是 GCJ-02,如果你要把点打到百度地图上,得先转 BD09;如果你的后端/地图用的是 WGS84,就得反向解密回 WGS84。别直接混用,否则偏移几百米。

2. 取位置并上报 MQTT

wx.getLocation({
  type: 'gcj02',
  success(res) {
    const { longitude, latitude } = res;
    const [bdLng, bdLat] = gcj02ToBd09(longitude, latitude); // 转 BD09
    mqttPublish({ lng: bdLng, lat: bdLat, ts: Date.now() });
  },
  fail() {
    // 静默降级:拿不到位置也别卡住业务流程
    mqttPublish({ lng: 0, lat: 0, ts: Date.now() });
  }
});

3. 静默降级的理由

设备可能在地下室、没授权定位、或系统定位服务被关。这些情况 fail 很正常。直接弹错或中断上报反而不好——所以约定 0,0 表示「未知位置」,后端照常接收,只是地图上不标点。这样链路永远不断。

别忘了:wx.getLocation 需要在小程序后台配置 requiredPrivateInfos 并完成隐私保护指引审核,否则真机会调不起来。

4. GCJ-02 → BD09 转换

function gcj02ToBd09(lng, lat) {
  const x = lng, y = lat;
  const z = Math.sqrt(x*x + y*y) + 0.00002 * Math.sin(y * Math.PI);
  const theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * Math.PI);
  return [z * Math.cos(theta) + 0.0065, z * Math.sin(theta) + 0.006];
}
← 返回首页