← 精品代码功能 · 可复用实现库

精品功能 01:坐标系转换与球面几何

直接把 GPS 点画到微信地图上会整体偏移几百米。另外要算折线长度、多边形面积。

核心实现

坐标系转换里的反向解最见功力(coord.js 第 48-65 行):

/**
 * GCJ-02 -> WGS-84:反解没有闭式解,用不动点迭代。
 * 偏移本身是米级小量且连续,迭代 3~5 次就收敛到厘米内。
 */
function gcj02ToWgs84(lng, lat) {
  if (outOfChina(lat, lng)) return { longitude: lng, latitude: lat };
  let wLng = lng, wLat = lat;
  for (let i = 0; i < 8; i++) {
    const g = wgs84ToGcj02(wLng, wLat);      // 正向转一遍,看差多少
    const dLng = g.longitude - lng;
    const dLat = g.latitude - lat;
    wLng -= dLng;                            // 反向修正
    wLat -= dLat;
    if (Math.abs(dLng) < 1e-10 && Math.abs(dLat) < 1e-10) break;
  }
  return { longitude: wLng, latitude: wLat };
}

球面距离与面积(geo.js):

function haversine(a, b) {
  const lat1 = a.latitude * D2R, lat2 = b.latitude * D2R;
  const dLat = lat2 - lat1, dLng = (b.longitude - a.longitude) * D2R;
  const s = Math.sin(dLat/2)**2 + Math.cos(lat1)*Math.cos(lat2)*Math.sin(dLng/2)**2;
  return 2 * EARTH_R * Math.asin(Math.min(1, Math.sqrt(s)));
}

面积用"以首点纬度做等距圆柱投影 + 平面鞋带公式"(geo.js 第 26-45 行)。

设计亮点

  1. 不动点迭代解无闭式反函数:把"求解"变成"猜测 → 正向验证 → 修正"
  2. 往返测试保证正确:GCJ → WGS → GCJ 误差 < 1 厘米(有测试)
  3. 统一入口:toGcj02() / fromGcj02() 让调用方不用记六个函数名
  4. 境外不偏移:outOfChina() 快速判断,避免错误偏移
  5. 误差有说明:面积算法注明"公里级误差远小于 GPS 噪声,够用"——取舍写在注释里

可复用性评估

开源化建议

对照开源

相关课程

第 18 课(纯函数与脱离平台测试)