# 如何用Python完成百度与高德地图转换

> 作者/来源: UCloud 运营管理员
> 发布时间: 2022-11-04T06:13:00.000Z
> 分类: 其他
> 标签: AI, Python
> 原文链接: http://117.50.162.249:3000/yun/articles/2231

---

# 如何用Python完成百度与高德地图转换

> 来源: https://www.ucloud.cn/yun/128237.html
> 作者: 89542767
> 发布日期: 发布于2022-11-04 14:13

众所周知，Python的一个使用场景还是比较多的，在工作当中，也会涉及到多方面的一些事情。那么，今天小编写这篇文章的一个主要目的，给大家来介绍关于如何用Python完成百度与搞得地图转换，下面就给大家详细介绍下。

**一、地理编码与逆编码**

　　地理编码与逆编码表示的是地名地址与地理坐标（经纬度)互相转换的过程。其中，将地址信息映射为地理坐标的过程称之为地理编码；将地理坐标转换为地址信息的过程称之为逆地理编码。(ps:猜猜我在哪)

![01.png](https://ucloud-blog.cn-bj.ufileos.com/articles/128237/images/128237_000.png)

　　地理编码能对一些只有名称或地址的数据进行空间化，从而可以开展空间分析和制图，对于数据分析人员十分重要。

　　大量地图厂商都提供了相关的API，可以直接利用这些API进行转化。国外的如谷歌、esri、osm等，国内的有百度、高德、腾讯等公司，python提供了专业的geopy包集成了这些API调用。

　　地理处理包将多带带研究，本文直接使用高德和百度的开放API进行地理编码。使用开放API前需要注册应用获取KEY

　　提示：以下是本篇文章正文内容，下面案例可供参考

**二、高德地图地理编码**

　　详细信息可参考官方开发文档，可以看到，请求参数必填的有key和address，其他的根据需要设置

![02.png](https://ucloud-blog.cn-bj.ufileos.com/articles/128237/images/128237_001.png)

　　具体代码如下：

```
　　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)
　　谷歌、高德——&gt;百度
　　: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)
　　百度——&gt;谷歌、高德
　　: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&gt;73.66 and lng&lt;135.05 and lat&gt;3.86 and lat&lt;53.55)
```

　　到此为止，这篇文章就给大家介绍到这里了，希望可以给大家带来更多的帮助。