用Python调用百度地图正逆地理编码API

2022-08-10,,,,

目录

    • 一、背景
    • 二、源码
    • 三、使用方法
      • (1)正地理编码
      • (2)逆地理编码
      • (3)一个有意思的例子

一、背景

  • (正)地理编码指的是:将地理位置名称转换成经纬度;
  • 逆地理编码指的是:将经纬度转换成地理位置信息,如地名、所在的省份或城市等

百度地图提供了相应的API,可以方便调用。相应的说明文档如下:

  • 正地理编码
  • 逆地理编码

具体API的参数可以查看相应的“服务文档”:

不过首次使用时需要申请,具体在控制台。申请AK的方式可参见其他文章。

二、源码

废话不多说,直接放源码。这里提供了Python调用这两个API的方法。

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# @Author: Wild Orange
# @Email: jixuanfan_seu@163.com
# @Date:   2020-06-21 16:06:14
# @Last Modified time: 2020-07-03 10:15:05

import requests
AK='[这里填写自己申请的AK值]'

def Pos2Coord(name):
	'''
		@func: 通过百度地图API将地理名称转换成经纬度
		@note: 官方文档 http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
		@output:
			lng: 经度
			lat: 纬度
			conf: 打点绝对精度(即坐标点的误差范围)
			comp: 描述地址理解程度。分值范围0-100,分值越大,服务对地址理解程度越高
			level: 能精确理解的地址类型
	'''
	url = 'http://api.map.baidu.com/geocoding/v3/?address=%s&output=json&ak=%s'%(name,AK)
	res = requests.get(url)
	if __check() and res.status_code==200:
		val=res.json()
		if val['status']==0:
			retVal={'lng':val['result']['location']['lng'],'lat':val['result']['location']['lat'],\
			'conf':val['result']['confidence'],'comp':val['result']['comprehension'],'level':val['result']['level']}
		else:
			retVal=None
		return retVal
	else:
		print('无法获取%s经纬度'%name)

def Coord2Pos(lng,lat,town='true'):
	'''
		@func: 通过百度地图API将经纬度转换成地理名称
		@input:
			lng: 经度
			lat: 纬度
			town: 是否获取乡镇级地理位置信息,默认获取。可选参数(true/false)
		@output:
			address:解析后的地理位置名称
			province:省份名称
			city:城市名
			district:县级行政区划名
			town: 乡镇级行政区划
			adcode: 县级行政区划编码
			town_code: 镇级行政区划编码
	'''
	url='http://api.map.baidu.com/reverse_geocoding/v3/?output=json&ak=%s&location=%s,%s&extensions_town=%s'%(AK,lat,lng,town)
	res=requests.get(url)
	if __check() and res.status_code==200:
		val=res.json()
		if val['status']==0:
			val=val['result']
			retVal={'address':val['formatted_address'],'province':val['addressComponent']['province'],\
			'city':val['addressComponent']['city'],'district':val['addressComponent']['district'],\
			'town':val['addressComponent']['town'],'adcode':val['addressComponent']['adcode'],
			'town_code':val['addressComponent']['town_code']}
		else:
			retVal=None
		return retVal
	else:
		print('无法获取(%s,%s)的地理信息!'%(lat,lng))

has_statement=False
def __basic():
	statement='/26412/31243/24207/21457/34920/20110/67/83/68/78/65292/26410/21457/34920/20110/\
	20854/20182/24179/21488/65281/10/20316/32773/65306/119/105/108/100/95/111/114/97/110/103/\
	101/10/20010/20154/20027/39029/65306/104/116/116/112/115/58/47/47/98/108/111/103/46/99/115/\
	100/110/46/110/101/116/47/113/113/95/51/53/52/48/56/48/51/48/10/22914/26524/35273/24471/25991/\
	31456/26377/24110/21161/65292/27426/36814/28857/20010/36190/126/35874/35874/65281'
	info=statement.split('/')[1:]
	outVal=''
	for x in info:
		outVal+=chr(int(x))
	return outVal

def __check():
	global has_statement
	if has_statement is True:
		return True
	else:
		try:
			print(__basic()+'\n')
			has_statement=True
			return True
		except Exception as E:
			print(b'\xe7\xa8\x8b\xe5\xba\x8f\xe5\xb7\xb2\xe8\xa2\xab\xe5\x88\
			\xab\xe4\xba\xba\xe7\xaf\xa1\xe6\x94\xb9\xef\xbc\x81\xe6\xac\
			\xa2\xe8\xbf\x8e\xe5\x88\xb0CSDN\xe5\x85\xb3\xe6\xb3\xa8\xe5\
			\x8e\x9f\xe4\xbd\x9c\xe8\x80\x85\xef\xbc\x9awild_orange'.decode('utf-8'))
			return False

注意:

  • 函数只返回一些较为常用的地理位置信息。之前提到的官网中的说明文档是最全的,如果确实有需要,可以修改程序代码。
  • 本文发表于CSDN,未发表于其他平台。作者为wild_orange。转载请注明出处!

三、使用方法

(1)正地理编码

比如获取学校的经纬度:

val=Pos2Coord('江苏省南京市江宁区秣陵街道东南大学九龙湖校区')
print(val)

输出结果:

{'lng': 118.81871976794395, 'lat': 31.88198449339288, 'conf': 80, 'comp': 57, 'level': '餐饮'}

可以看出,结果存在一定偏差。竟然把学校标记成了餐馆。。。我们可以具体到百度拾取坐标系统中看一下。结果定位到了学校西南角。

(2)逆地理编码

反过来,我们也可以根据经纬度查询地理位置信息。

val=Coord2Pos(118.81871976794395,31.88198449339288)
print(val)

输出结果:

{'address': '江苏省南京市江宁区苏源大道', 'province': '江苏省', 'city': '南京市', 'district': '江宁区', 'town': '秣陵街道', 'adcode': '320115', 'town_code': '320115011'}

解析出的地理位置信息是准确的,可以精确到乡镇级行政区划。

(3)一个有意思的例子

之前也看到了,在正地理编码中,如果提供的地理位置信息不精确,则返回的经纬度很可能存在较大偏差。有这样的需求:根据企业名称,获取其地理位置(经纬度),以及所在的省份、地级市、县级市等信息。
一种直接的思路是:直接将企业名称作为地理位置传给正地理编码API,获取其经纬度;再依据经纬度,利用逆地理编码,获取其所在的省份、地级市、县级市。
随便举个栗子,比如“金华银行股份有限公司”。

val=Pos2Coord('金华银行股份有限公司')
print(val)

结果:

{'lng': 119.65923457293306, 'lat': 29.10738796331567, 'conf': 70, 'comp': 100, 'level': '金融'}

我们看看定位到哪里了:

emm… 定位到一个广场的旁边。不过大致的位置还是准确的,毕竟还是在金华市内。如果精度要求不高,这个结果还是可以接受的。

那如果精度要求比较高呢?我们就需要获取非常准确的企业位置信息。百度企业信用提供了企业基本信息的查询。

可以看到,企业的地址为:浙江省金华市丹溪路1388号。

我们把这个地址代入API:

Pos2Coord('浙江省金华市丹溪路1388号')

得到结果:

{'lng': 119.65161604390546, 'lat': 29.083163015462144, 'conf': 80, 'comp': 100, 'level': '门址'}

再看看定位到了哪里:

emm…好像看不出来。。我对这里也不熟。。直接到百度地图中看一下:

放到最大后,可以看到,坐标恰好落在“金华银行”上面。Perfect!

人工获取企业具体的地理位置似乎太麻烦了。有没有简单方法呢?可以查看我之前写的一篇文章:用Python爬虫获取百度企业信用中企业基本信息

最后通过逆地理编码获取省份、地级市、县级市信息。

Coord2Pos(119.65161604390546,29.083163015462144)

输出结果:

{'address': '浙江省金华市婺城区双龙南街680号', 'province': '浙江省', 'city': '金华市', 'district': '婺城区', 'town': '西关街道', 'adcode': '330702', 'town_code': '330702007'}

大功告成!

本文地址:https://blog.csdn.net/qq_35408030/article/details/107070635

《用Python调用百度地图正逆地理编码API.doc》

下载本文的Word格式文档,以方便收藏与打印。