WGS、GCJ 和 BD 是三种不同的地理坐标系统,它们在地图和定位服务中广泛应用。了解这些坐标系统的区别和转换方法对于开发地理信息系统(GIS)和位置服务非常重要。

1. WGS84 (World Geodetic System 1984)

  • 定义:WGS84 是一种全球性的大地测量参考系统,由美国国防部开发。它是目前最常用的地理坐标系统之一,广泛应用于 GPS 设备和全球导航卫星系统(GNSS)。
  • 特点:WGS84 使用地球椭球体模型来描述地球的形状,其参数为:

  • 半长轴

  • 扁率

2. GCJ-02 (GuoJia JuWei 2002)

  • 定义:GCJ-02 是中国国家测绘局制定的一种坐标系统,主要用于在中国境内的地图服务。GCJ-02 是基于 WGS84 进行了一定的偏移处理,以保护国家安全和地理信息的准确性。
  • 特点:GCJ-02 的坐标与 WGS84 的坐标有一定的偏差,具体偏移量是保密的,但可以通过一些公开的算法进行近似转换。

3. BD-09 (Baidu 2009)

  • 定义:BD-09 是百度公司使用的坐标系统,主要用于百度地图服务。BD-09 是在 GCJ-02 的基础上进一步进行了偏移处理。
  • 特点:BD-09 的坐标与 WGS84 和 GCJ-02 的坐标都有一定的偏差,具体偏移量也是保密的,但可以通过一些公开的算法进行近似转换。

坐标转换

由于这三种坐标系统之间存在差异,因此在实际应用中经常需要进行坐标转换。以下是一些常见的转换方法:

1. WGS84 to GCJ-02

def wgs84_to_gcj02(wgs84_lon, wgs84_lat):
    if out_of_china(wgs84_lon, wgs84_lat):
        return wgs84_lon, wgs84_lat

    dlat = transform_lat(wgs84_lon - 105.0, wgs84_lat - 35.0)
    dlon = transform_lon(wgs84_lon - 105.0, wgs84_lat - 35.0)
    rad_lat = wgs84_lat / 180.0 * pi
    magic = sin(rad_lat)
    magic = 1 - ee * magic * magic
    sqrt_magic = sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrt_magic) * pi)
    dlon = (dlon * 180.0) / (a / sqrt_magic * cos(rad_lat) * pi)
    mg_lat = wgs84_lat + dlat
    mg_lon = wgs84_lon + dlon
    return mg_lon, mg_lat

def transform_lat(x, y):
    ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * sqrt(abs(x))
    ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0
    ret += (20.0 * sin(y * pi) + 40.0 * sin(y / 3.0 * pi)) * 2.0 / 3.0
    ret += (160.0 * sin(y / 12.0 * pi) + 320 * sin(y * pi / 30.0)) * 2.0 / 3.0
    return ret

def transform_lon(x, y):
    ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * sqrt(abs(x))
    ret += (20.0 * sin(6.0 * x * pi) + 20.0 * sin(2.0 * x * pi)) * 2.0 / 3.0
    ret += (20.0 * sin(x * pi) + 40.0 * sin(x / 3.0 * pi)) * 2.0 / 3.0
    ret += (150.0 * sin(x / 12.0 * pi) + 300.0 * sin(x / 30.0 * pi)) * 2.0 / 3.0
    return ret

def out_of_china(lon, lat):
    if lon < 72.004 or lon > 137.8347:
        return True
    if lat < 0.8293 or lat > 55.8271:
        return True
    return False

2. GCJ-02 to WGS84

def gcj02_to_wgs84(gcj02_lon, gcj02_lat):
    if out_of_china(gcj02_lon, gcj02_lat):
        return gcj02_lon, gcj02_lat

    dlat = transform_lat(gcj02_lon - 105.0, gcj02_lat - 35.0)
    dlon = transform_lon(gcj02_lon - 105.0, gcj02_lat - 35.0)
    rad_lat = gcj02_lat / 180.0 * pi
    magic = sin(rad_lat)
    magic = 1 - ee * magic * magic
    sqrt_magic = sqrt(magic)
    dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrt_magic) * pi)
    dlon = (dlon * 180.0) / (a / sqrt_magic * cos(rad_lat) * pi)
    mg_lat = gcj02_lat - dlat
    mg_lon = gcj02_lon - dlon
    return mg_lon, mg_lat

3. GCJ-02 to BD-09

def gcj02_to_bd09(gcj02_lon, gcj02_lat):
    z = sqrt(gcj02_lon * gcj02_lon + gcj02_lat * gcj02_lat) + 0.00002 * sin(gcj02_lat * pi)
    theta = atan2(gcj02_lat, gcj02_lon) + 0.000003 * cos(gcj02_lon * pi)
    bd09_lon = z * cos(theta) + 0.0065
    bd09_lat = z * sin(theta) + 0.006
    return bd09_lon, bd09_lat

4. BD-09 to GCJ-02

def bd09_to_gcj02(bd09_lon, bd09_lat):
    x = bd09_lon - 0.0065
    y = bd09_lat - 0.006
    z = sqrt(x * x + y * y) - 0.00002 * sin(y * pi)
    theta = atan2(y, x) - 0.000003 * cos(x * pi)
    gcj02_lon = z * cos(theta)
    gcj02_lat = z * sin(theta)
    return gcj02_lon, gcj02_lat

总结

  • WGS84 是全球标准的坐标系统,广泛应用于 GPS 和 GNSS。
  • GCJ-02 是中国的国家标准坐标系统,用于保护地理信息安全。
  • BD-09 是百度地图使用的坐标系统,基于 GCJ-02 进一步偏移。

在实际应用中,根据具体的业务需求选择合适的坐标系统,并使用上述转换方法进行坐标转换,以确保数据的一致性和准确性。