百度地图开发平台提供了各式各样的API可供开发者调用,而本文则涉及到了其中的Place API和Geocoding API。
其中Place API用于查询某个地点信息的经纬度坐标;Geocoding API用于查询某个经纬度坐标的结构化地址。
参考文档如下:
Place API:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi
GeocodingAPI:http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding
一 问题需求
根据房价指数数据,进行Python编程使用百度地图API实现地点信息转换,展示房价指数热力地图
二 解决思路
百度地图api上相关位置的展现是以经纬度为基础的,如北京,其经度(longitude)为:116.395645,纬度(latitude)为:39.929986,在这里需要通过百度的Geocoding API来获取不同城市的经纬度坐标。
因此可通过csv数据文件导入python,通过调用百度地图API,批量获取所有城市的坐标信息。
根据得到得json数据绘制热力地图。
三 地点信息转换
1. 开发第一步:注册密钥
2. 整理城市房地产数据
import json,csv
from urllib.request import urlopen, quote
def getBaidulnglat(address):
url = 'http://api.map.baidu.com/geocoder/v2/'
output = 'json' # 百度地图API可以指定JSON或者XML的返回数据
ak = 'MMMMMMMMMMMs9SG539999999xxxxx'
add = quote(address) # 防止中文出现乱码,先用quote进行编码
url = url + '?' + 'address=' + add + '&output=' + output + '&ak=' + ak
req = urlopen(url)
res = req.read().decode() # 对返回的response对象,将其他编码的字符串解码成unicode
temp = json.loads(res) # 对json数据进行解析
return temp
file = open(r'files\\baiduapi_point.json','w')
file1 = open(r'files\\baiduapi_citys.json','w')
with open(r'files\\201803house.csv', 'r') as csvfile:
reader = csv.reader(csvfile)
for line in reader:
if reader.line_num == 1:
continue
b = line[0].strip() # 第一列city
c = line[1].strip()
getcity = getBaidulnglat(b) # 调用函数获取API返回包
lng = getBaidulnglat(b)['result']['location']['lng'] # 调用函数获取经度
lat = getBaidulnglat(b)['result']['location']['lat'] # 获取纬度
str_temp = '{"lat":' + str(lat) + ',"lng":' + str(lng) + ',"count":' + str(c) +'},'
file.write(str_temp)
file1.write(str(getcity))
file.close()
file1.close()
baiduapi_point.json 的输出内容如下:
四 制作热力地图
1. 从百度开发平台获取初始HTML代码
我们先建立一个html文件,将http://developer.baidu.com/map/jsdemo.htm#c1_15 网址中源代码复制过来,首先将代码中的ak换成你自己的密钥;(注意:这个密钥和前面python里面调用百度API的密钥不一样, 需要在刚才创建密钥的地方重新创建一个,并选择密钥类型为前端,用来支持调用baidu的javascriptAPI)
2. 更新数据。将前面生成的baiduapi_point.json文件里的数据复制出来,替换掉HTML代码中var points =[ ]里的内容
3. 设置热力地图中心点和地图级别,这里以西安为中心点,级别为5。 百度地图JavaScript API热力图默认的是以天安门为中心的北京区域地图,因此需要对热力图中“设置中心点坐标和地图级别”的部分进行修改成合适的中心点与地图级别。(见下图),具体设置可以参考百度创建地图api中:http://api.map.baidu.com/lbsapi/creatmap/
5. 效果展示。 运行本地HTML文件即可。
6. 扩展说明。 这里使用本地页面进行实现, 动态页面类似,不赘述。
#encoding=utf-8
'''使用Place API把从文本中提取出的地址转换为对应的经纬度坐标,再使用Geocoding API把经纬度坐标转换为结构化地址。'''
from xml.etree import ElementTree
import json
import urllib.request
search=urllib.parse.quote(u'武汉'.encode('utf-8'))
region=urllib.parse.quote(u'西安'.encode('utf-8'))
url="http://api.map.baidu.com/place/v2/search?query=%s®ion=%s&city_limit=true&output=json&ak=你的AK"%(search,region)
req = urllib.request.urlopen(url)#JSON格式的返回数据
res = req.read().decode("utf-8") #将其他编码的字符串解码成unicode
temp = json.loads(res)
print (temp)
address = temp['results'][0]['address']#地址
location = temp['results'][0]['location'] #经纬度坐标
print (address,location)
lat = str(location['lat'])#纬度坐标
lng = str(location['lng'])#经度坐标
url2 = 'http://api.map.baidu.com/geocoder/v2/?callback=renderReverse&location='+lat+','+lng+'&output=xml&pois=1&ak=你的AK'
req2 = urllib.request.urlopen(url2)#XML格式的返回数据
res2 = req2.read().decode("utf-8")#将其他编码的字符串解码成unicode
root = ElementTree.fromstring(res2)#解析XML时直接将字符串转换为一个Element,解析树的根节点
node_find = root.find('result/formatted_address')#find()用于查找属于某个tag的第一个element,这里查找结构化地址
print(node_find.text)#输出结构化的地址