如何用Python完成百度与高德地图转换
众所周知,Python的一个使用场景还是比较多的,在工作当中,也会涉及到多方面的一些事情。那么,今天小编写这篇文章的一个主要目的,给大家来介绍关于如何用Python完成百度与搞得地图转换,下面就给大家详细介绍下。 一、地理编码与逆编码 地理编码与逆编码表示的是地名地址与地理坐标(经纬度)互相转换的过程。其中,将地址信息
来源: https://www.ucloud.cn/yun/128237.html 作者: 89542767 发布日期: 发布于2022-11-04 14:13
众所周知,Python的一个使用场景还是比较多的,在工作当中,也会涉及到多方面的一些事情。那么,今天小编写这篇文章的一个主要目的,给大家来介绍关于如何用Python完成百度与搞得地图转换,下面就给大家详细介绍下。
一、地理编码与逆编码
地理编码与逆编码表示的是地名地址与地理坐标(经纬度)互相转换的过程。其中,将地址信息映射为地理坐标的过程称之为地理编码;将地理坐标转换为地址信息的过程称之为逆地理编码。(ps:猜猜我在哪)

地理编码能对一些只有名称或地址的数据进行空间化,从而可以开展空间分析和制图,对于数据分析人员十分重要。
大量地图厂商都提供了相关的API,可以直接利用这些API进行转化。国外的如谷歌、esri、osm等,国内的有百度、高德、腾讯等公司,python提供了专业的geopy包集成了这些API调用。
地理处理包将多带带研究,本文直接使用高德和百度的开放API进行地理编码。使用开放API前需要注册应用获取KEY
提示:以下是本篇文章正文内容,下面案例可供参考
二、高德地图地理编码
详细信息可参考官方开发文档,可以看到,请求参数必填的有key和address,其他的根据需要设置

具体代码如下:
def getGDCor(key,addr):
baseUrl='http://restapi.amap.com/v3/geocode/geo?'
params={'key':key,##应用key
'address':addr,
'city':u'武汉'##指定城市,限制范围
}
url=baseUrl+urllib.parse.urlencode(params)
req=urllib.request.Request(url)
content=urllib.request.urlopen(req).read()
jsonData=json.loads(content)
lon,lat='',''
if jsonData['status']=='1':
try:
corr=jsonData['geocodes'][0]['location']
lon,lat=corr.split(',')[0],corr.split(',')[1]
except:
lon,lat='0','0'
else:
print('error')
return(lon,lat)
三、百度地图地理编码
百度地图与高德类似,同样需要注册应用获取key,详细内容参考官网文档
def getBDCor(ak,addr):
#sleep(random.random())
baseUrl='http://api.map.baidu.com/geocoding/v3/?'
params={'address':addr,
'city':u'武汉市',
'output':'json',
'ak':ak,##应用key
'callback':'showLocation'
}
url=baseUrl+urllib.parse.urlencode(params)
req=urllib.request.urlopen(url).read().decode()#'utf-8'针对中文需要设施编码
cont1=req.replace("showLocation&&showLocation(",'')
cont=cont1.replace(")",'')
jsonData=json.loads(cont)
lon,lat=0,0
if jsonData['status']==0:
try:
lon=jsonData['result']['location']['lng']
lat=jsonData['result']['location']['lat']
except:
print(addr)
return(lon,lat)
四、坐标转换和空间化
高德或百度获取的地理位置都是经过加密的,高德地图位置使用的是火星坐标,百度地图是bd-09坐标,与WGS84坐标系间有偏差,通常需要进行转换。
火星坐标(GCJ-02):国测局坐标,由WGS-84加密而成,国内必须至少使用GCJ-02坐标系,或者使用在GCJ-02加密后再进行加密的坐标系,如百度坐标系。高德和Google在国内都是使用GCJ-02坐标系,可以说,GCJ-02是国内最广泛使用的坐标系;
百度坐标系是在GCJ-02坐标系的基础上再次加密偏移后形成的坐标系。
各坐标间可以通过坐标转换互转,通常有三参数或七参数法,网上可找到相关的转换参数,贴一下转换函数(不知道哪位大神写的)
import math
x_pi=3.14159265358979324*3000.0/180.0
pi=3.1415926535897932384626#π
a=6378245.0#长半轴
ee=0.00669342162296594323#扁率
def gcj02_to_bd09(lng,lat):
"""
火星坐标系(GCJ-02)转百度坐标系(BD-09)
谷歌、高德——>百度
:param lng:火星坐标经度
:param lat:火星坐标纬度
:return:
"""
z=math.sqrt(lng*lng+lat*lat)+0.00002*math.sin(lat*x_pi)
theta=math.atan2(lat,lng)+0.000003*math.cos(lng*x_pi)
bd_lng=z*math.cos(theta)+0.0065
bd_lat=z*math.sin(theta)+0.006
return[bd_lng,bd_lat]
def bd09_to_gcj02(bd_lon,bd_lat):
"""
百度坐标系(BD-09)转火星坐标系(GCJ-02)
百度——>谷歌、高德
:param bd_lat:百度坐标纬度
:param bd_lon:百度坐标经度
:return:转换后的坐标列表形式
"""
x=bd_lon-0.0065
y=bd_lat-0.006
z=math.sqrt(x*x+y*y)-0.00002*math.sin(y*x_pi)
theta=math.atan2(y,x)-0.000003*math.cos(x*x_pi)
gg_lng=z*math.cos(theta)
gg_lat=z*math.sin(theta)
return[gg_lng,gg_lat]
def wgs84_to_gcj02(lng,lat):
"""
WGS84转GCJ02(火星坐标系)
:param lng:WGS84坐标系的经度
:param lat:WGS84坐标系的纬度
:return:
"""
if out_of_china(lng,lat):#判断是否在国内
return lng,lat
dlat=_transformlat(lng-105.0,lat-35.0)
dlng=_transformlng(lng-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)
dlng=(dlng*180.0)/(a/sqrtmagic*math.cos(radlat)*pi)
mglat=lat+dlat
mglng=lng+dlng
return[mglng,mglat]
def gcj02_to_wgs84(lng,lat):
"""
GCJ02(火星坐标系)转GPS84
:param lng:火星坐标系的经度
:param lat:火星坐标系纬度
:return:
"""
if out_of_china(lng,lat):
return lng,lat
dlat=_transformlat(lng-105.0,lat-35.0)
dlng=_transformlng(lng-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)
dlng=(dlng*180.0)/(a/sqrtmagic*math.cos(radlat)*pi)
mglat=lat+dlat
mglng=lng+dlng
return[lng*2-mglng,lat*2-mglat]
def bd09_to_wgs84(bd_lon,bd_lat):
lon,lat=bd09_to_gcj02(bd_lon,bd_lat)
return gcj02_to_wgs84(lon,lat)
def wgs84_to_bd09(lon,lat):
lon,lat=wgs84_to_gcj02(lon,lat)
return gcj02_to_bd09(lon,lat)
def _transformlat(lng,lat):
ret=-100.0+2.0*lng+3.0*lat+0.2*lat*lat+\
0.1*lng*lat+0.2*math.sqrt(math.fabs(lng))
ret+=(20.0*math.sin(6.0*lng*pi)+20.0*
math.sin(2.0*lng*pi))*2.0/3.0
ret+=(20.0*math.sin(lat*pi)+40.0*
math.sin(lat/3.0*pi))*2.0/3.0
ret+=(160.0*math.sin(lat/12.0*pi)+320*
math.sin(lat*pi/30.0))*2.0/3.0
return ret
def _transformlng(lng,lat):
ret=300.0+lng+2.0*lat+0.1*lng*lng+\
0.1*lng*lat+0.1*math.sqrt(math.fabs(lng))
ret+=(20.0*math.sin(6.0*lng*pi)+20.0*
math.sin(2.0*lng*pi))*2.0/3.0
ret+=(20.0*math.sin(lng*pi)+40.0*
math.sin(lng/3.0*pi))*2.0/3.0
ret+=(150.0*math.sin(lng/12.0*pi)+300.0*
math.sin(lng/30.0*pi))*2.0/3.0
return ret
def out_of_china(lng,lat):
"""
判断是否在国内,不在国内不做偏移
:param lng:
:param lat:
:return:
"""
return not(lng>73.66 and lng<135.05 and lat>3.86 and lat<53.55)
到此为止,这篇文章就给大家介绍到这里了,希望可以给大家带来更多的帮助。