Python使用百度地图API实现地点信息转换及房价指数热力地图

       基于地图的可视化数据应用方便且易于实现,有很多方法来实现地图可视化。包括excel的power map包、在线交互地图可视化工具,如Echarts、Tableau Public、polyMaps等,及地图库。
       这里实现的是通过软件调用百度地图的api,自己DIY可视化地图,这种办法需要软件编程知识,并熟悉地图api的具体用法。下面以一个简单的需求出发,通过python调用百度地图API实现地点信息转换及房价指数热力地图,这其中需要申请密钥、批量经纬度换算、转换成js数据、百度热力地图api调参等过程。

         百度地图开发平台提供了各式各样的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. 开发第一步:注册密钥

       在做所有工作之前,需要注册百度地图api(首先你要用百度的账号)以获取免费的密钥,才能完全使用该api。
       登录网址: http://lbsyun.baidu.com/   首页点击申请密钥按钮,经过填写个人信息、邮箱注册等
       注册成功之后在开放平台上点击“创建应用”,填写相关信息,填写应用的名字,并在IP白名单框里输入访问白名单,如果不清楚自己的IP地址,可设置为:0.0.0.0/0,注意:百度提醒它会有泄露使用的风险。提交后,在你创建应用的访问应用(AK)那一栏就是你的密钥。

2.  整理城市房地产数据

     初始数据为 2018年3月份70个大中城市商品住宅销售价格变动情况,国家统计局网站公布的数据链接为:http://www.stats.gov.cn/tjsj/zxfb/201804/t20180418_1594610.html,数据整理为201803house.c's'v,为两列(城市city、房价指数price),并保存为csv格式。    

3.   信息转换实现

       1)编写中文城市地址获取城市地图信息函数getBaidulnglat

       2)读201803house.csv,逐个城市调用getBaidulnglat
       3) 百度Web服务API下的Geocoding API接口来获取你所需要地址的经纬度坐标并转化为json结构的数据     
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/


4.  热点图代码中的点最大值进行修改为150。 因为 大部分price数据(也就是points里的count)都超过了100(默认最大为100)。


5.  效果展示。 运行本地HTML文件即可。 


6. 扩展说明。 这里使用本地页面进行实现, 动态页面类似,不赘述。

五  另一个例子(地址信息转换)
        另一个例子, 百度地图API可以指定JSON或者XML的返回数据,本例子展示不同返回格式的用法,Place API使用的返回格式为JSON,Geocoding API使用的返回格式为XML,两种格式的处理方法稍有不同。
#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&region=%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)#输出结构化的地址

猜你喜欢

转载自blog.csdn.net/ebzxw/article/details/80265796