GCJ-02是由中国国家测绘局(G表示Guojia国家,C表示Cehui测绘,J表示Ju局)制订的地理信息系统的坐标系统。
它是一种对经纬度数据的加密算法,即加入随机的偏差。
国内出版的各种地图系统(包括电子形式),必须至少采用GCJ-02对地理位置进行首次加密。
保密插件,也叫做加密插件或者加偏或者SM模组,是对真实地图或者导航坐标系统进行人为的加偏处理,按照一定的加偏算法,将真实的坐标加密成虚假的坐标。加偏处理不是线性的加偏,所以各地的偏移情况都会有所不同。加密后的坐标也常被人称为火星坐标系统。
所有的电子地图、导航设备,都需要加入该保密插件。第一步,地图公司测绘地图,测绘完成后,送到国家测绘局,将真实坐标的电子地图,加密成“火星坐标”,这样的地图才是可以出版和发布的,然后才可以让GPS公司处理。第二步,所有的GPS公司,只要需要汽车导航的,需要用到导航电子地图的,都需要在软件中加入该保密算法,将COM口读出来的真实的坐标信号,加密转换成ZF要求的保密的坐标。这样,GPS导航仪和导航电子地图就可以完全匹配,GPS也就可以正常工作了。
GCJ-02只是一种坐标偏移标准(算法),对投影没有任何限制,如果再以投影为基础作细分,则可以分为GCJ-02经纬度投影和GCJ-02 Web 墨卡托投影。在水经注万能地图下载器无论是导入或导出矢量数据时都可以对GCJ-02经纬度投影和GCJ-02墨卡托投影进行很好的支持。
python转换代码:
# -*- coding: utf-8 -*-
# author:zhoulong_GISER
import math
a = 6378245.0 # 克拉索夫斯基椭球参数长半轴a
ee = 0.00669342162296594323 # 克拉索夫斯基椭球参数第一偏心率平方
pi = 3.14159265358979324 # 圆周率
PI = 3.14159265358979324 # 圆周率
def wgs84togcj02(lon, lat):
dLat = transform_lat(lon - 105.0, lat - 35.0)
dLon = transform_lon(lon - 105.0, lat - 35.0)
radLat = lat / 180.0 * pi
magic = math.sin(radLat)
magic = 1 - ee * magic * magic
sqrtMagic = math.sqrt(magic)
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi)
dLon = (dLon * 180.0) / (a / sqrtMagic * math.cos(radLat) * pi)
mgLat = lat + dLat
mgLon = lon + dLon
return mgLon,mgLat
def transform_lat(x, y):
ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(abs(x))
ret += (20.0 * math.sin(6.0 * x * pi) + 20.0 * math.sin(2.0 * x * pi)) * 2.0 / 3.0
ret += (20.0 * math.sin(y * pi) + 40.0 * math.sin(y / 3.0 * pi)) * 2.0 / 3.0
ret += (160.0 * math.sin(y / 12.0 * pi) + 320 * math.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 * math.sqrt(abs(x))
ret += (20.0 * math.sin(6.0 * x * pi) + 20.0 * math.sin(2.0 * x * pi)) * 2.0 / 3.0
ret += (20.0 * math.sin(x * pi) + 40.0 * math.sin(x / 3.0 * pi)) * 2.0 / 3.0
ret += (150.0 * math.sin(x / 12.0 * pi) + 300.0 * math.sin(x / 30.0 * pi)) * 2.0 / 3.0
return ret
def gcj02wgs84(x,y):
lon = float(x)
lat = float(y)
# 以下为转换公式
x = lon - 105.0
y = lat - 35.0
# 经度
dLon = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * math.sqrt(abs(x));
dLon += (20.0 * math.sin(6.0 * x * PI) + 20.0 * math.sin(2.0 * x * PI)) * 2.0 / 3.0;
dLon += (20.0 * math.sin(x * PI) + 40.0 * math.sin(x / 3.0 * PI)) * 2.0 / 3.0;
dLon += (150.0 * math.sin(x / 12.0 * PI) + 300.0 * math.sin(x / 30.0 * PI)) * 2.0 / 3.0;
# 纬度
dLat = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * math.sqrt(abs(x));
dLat += (20.0 * math.sin(6.0 * x * PI) + 20.0 * math.sin(2.0 * x * PI)) * 2.0 / 3.0;
dLat += (20.0 * math.sin(y * PI) + 40.0 * math.sin(y / 3.0 * PI)) * 2.0 / 3.0;
dLat += (160.0 * math.sin(y / 12.0 * PI) + 320 * math.sin(y * PI / 30.0)) * 2.0 / 3.0;
radLat = lat / 180.0 * PI
magic = math.sin(radLat)
magic = 1 - ee * magic * magic
sqrtMagic = math.sqrt(magic)
dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * PI);
dLon = (dLon * 180.0) / (a / sqrtMagic * math.cos(radLat) * PI);
wgsLon = lon - dLon
wgsLat = lat - dLat
return wgsLon, wgsLat
if __name__=="__main__":
xylist = [113.923745,22.530824]
transform1 = gcj02wgs84( xylist[0], xylist[1])
print('gcj02坐标:',xylist[0], xylist[1])
print('转换后WGS84坐标:',transform1[0],transform1[1])
lonlatlist = [113.9188845730701,22.533867387389293]
transform2 = wgs84togcj02(lonlatlist[0], lonlatlist[1])
print('WGS84坐标:',lonlatlist[0], lonlatlist[1] )
print('转换后gcj02坐标:',transform2[0],transform2[1] )
结果:
# 验证地址:http://www.gpsspg.com/maps.htm