社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

Python实现高德坐标到WGS-84的转换

小猿猴GISer • 3 周前 • 42 次点击  

· 地理、遥感数据下载/处理 ·

联系我们微信号






xiaoguotmd

国内用GPT4-o、GPTs等模型的网址:

createchat.cn

01

高德地图(GCJ-02)坐标系转换为WGS-84坐标系的方法通常需要进行数学变换。高德地图使用的坐标系是中国的“火星坐标系”(GCJ-02),而WGS-84是全球通用的坐标系。因此,直接使用两者的坐标会有偏差,尤其是在中国大陆地区。


今天我们介绍一下如何将在 Python 中进行转换。


import math
# 定义常数PI = 3.1415926535897932384626AXIS = 6378245.0 # 长半轴OFFSET = 0.00669342162296594323 # 偏心率平方
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_lng(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 gcj02_to_wgs84(lat, lng): if out_of_china(lat, lng): return lat, lng dlat = transform_lat(lng - 105.0, lat - 35.0) dlng = transform_lng(lng - 105.0, lat - 35.0) radlat = lat / 180.0 * PI magic = math.sin(radlat) magic = 1 - OFFSET * magic * magic sqrtmagic = math.sqrt(magic) dlat = (dlat * 180.0) / ((AXIS * (1 - OFFSET)) / (magic * sqrtmagic) * PI) dlng = (dlng * 180.0) / (AXIS / sqrtmagic * math.cos(radlat) * PI) mglat = lat + dlat mglng = lng + dlng return lat * 2 - mglat, lng * 2 - mglng
def out_of_china(lat, lng): # 判断是否在中国范围外 return not (73.66 < lng < 135.05 and 3.86 < lat < 53.55)
# 示例:将GCJ-02转换为WGS-84 gcj_lat, gcj_lng = 39.908823, 116.397470 # 这是北京天安门的GCJ-02坐标wgs_lat, wgs_lng = gcj02_to_wgs84(gcj_lat, gcj_lng)print(f"WGS-84坐标: 纬度 {wgs_lat}, 经度 {wgs_lng}")

代码解释:

  • transform_lat 和 transform_lng 函数用于对经纬度进行变换,计算偏移量。

  • gcj02_to_wgs84 函数是核心部分,计算GCJ-02到WGS-84的转换。

  • out_of_china 函数用于排除不在中国范围内的坐标,因为这些地区不需要进行转换。



02

这里我们选取北京的一个点进行验证,这个点位置为一个角点(红框框选区域)。


该点通过高德坐标拾取显示经纬度为(116.397594, 39.904949)

经过转换,经纬度坐标为(116.391351,39.903546)。

谷歌地球上该点坐标为:(116.391222,39.903468),


可以通过下面代码计算谷歌地球坐标点(WGS84)与转换前后的距离。


from math import radians, sin, cos, sqrt, atan2
# Haversine公式计算两点之间的地球距离def haversine(lat1, lon1, lat2, lon2): # 地球半径(单位:公里) R = 6371.0
# 将经纬度从度数转换为弧度 lat1, lon1, lat2, lon2 = map(radians, [lat1, lon1, lat2, lon2])
# Haversine公式 dlat = lat2 - lat1 dlon = lon2 - lon1 a = sin(dlat / 2)**2 + cos(lat1) * cos(lat2) * sin(dlon / 2)**2 c = 2 * atan2(sqrt(a), sqrt(1 - a)) distance = R * c return distance
# 输入坐标google_lat, google_lng = 39.90492, 116.39758 gcj_lat, gcj_lng = 39.904949, 116.397594 # 原始高德(GCJ-02)坐标wgs_lat, wgs_lng = 39.90354564401196, 116.39135088735438 # 转换后的WGS-84坐标
# 计算Google坐标到原始高德坐标的距离distance_to_gcj = haversine(google_lat, google_lng, gcj_lat, gcj_lng)
# 计算Google坐标到转换后WGS-84坐标的距离distance_to_wgs = haversine(google_lat, google_lng, wgs_lat, wgs_lng)
distance_to_gcj, distance_to_wgs



根据计算结果:


谷歌地球坐标到原始高德(GCJ-02)坐标的距离约为 567.93 米。

谷歌地球坐标到转换后的 WGS-84 坐标的距离约为 13.98 米。



03

可以看出,经过转换后高德坐标和WGS84之间的差异已经减少了很多。

这种差别应该是可以进一步减少的,因为这种转方法是针对于整个中国的。如果我们需要对特定区域的坐标进行转换,可以选取一系列均匀分布的控制点,反算出转换的参数,可以对局部区域进行更精准的转换

微信号 xiaoguotmd

微信公众号|智行探幽

随时可联系

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/173458
 
42 次点击