一、首先展示最终的效果
对二手房房源的分析,将分析后的结果用热力图显示:
显示效果如下所示:
heatMap参考代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=xzjQRq0KqoPbRG340r22ndL8VkbZIS3S"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/Heatmap/2.0/src/Heatmap_min.js"></script>
<title>热力图功能示例</title>
<style type="text/css">
ul,li{list-style: none;margin:0;padding:0;float:left;}
html{height:100%}
body{height:100%;margin:0px;padding:0px;font-family:"微软雅黑";}
#container{height:100%;width:100%;}
#r-result{width:100%;}
</style>
</head>
<body>
<div id="container"></div>
<script type="text/javascript">
var map = new BMap.Map("container"); // 创建地图实例
var point = new BMap.Point(118.760547,31.995307);
map.centerAndZoom(point, 10); // 初始化地图,设置中心点坐标和地图级别
map.setCurrentCity("南京"); //设置当前显示城市
map.enableScrollWheelZoom(); // 允许滚轮缩放
var points =[
<!--data中数据-->
{"lng":"118.760547","lat":"31.995307","count":"1"},
{"lng":"118.76127240000001","lat":"31.99646666","count":"13"},
{"lng":"118.763391","lat":"31.994544","count":"7"},
{"lng":"118.764602","lat":"31.99557132","count":"12"},
{"lng":"118.764628","lat":"31.993465999999998","count":"2"},
{"lng":"118.765818","lat":"31.997544","count":"6"},
{"lng":"118.76630800000001","lat":"32.002635","count":"13"},
{"lng":"118.766849","lat":"31.998096999999998","count":"2"},
{"lng":"118.76711999999999","lat":"31.999557","count":"8"},
{"lng":"118.77068500000001","lat":"32.001864000000005","count":"5"}
];//这里面添加经纬度
<!--半径 可见度-->
heatmapOverlay = new BMapLib.HeatmapOverlay({"radius":100,"maxOpacity":0.6,"visible":true});
map.addOverlay(heatmapOverlay);
heatmapOverlay.setDataSet({data:points,max:100});
</script>
</body>
</html>
二、在百度平台注册开发者账户
1)进入百度开放平台:
百度开发平台
2)注册个人开发者账户(选择个人使用)参考下面的界面:
3)注册登录后点击控制台
(https://lbsyun.baidu.com/apiconsole/key#/home)
三、实现地理编码
实验目的:输入地址,输出该地址对应的经纬度。
1)在控制台看板中点击应用管理--》创建应用,如下图所示。
设置完成点击提交按钮,就完成了应用的创建。
2)创建后的应用如下图所示:
3)地理编码
选择页面导航栏中的开发文档-->服务接口-->Web服务API,显示界面如下图所示:
选择Web服务API菜单中的正/逆地理编码-->地理编码.如下图所示:
选择导航栏上的服务文档,如下图所示(在服务文档里可以查看api的各个参数):
根据地址实现地理编码的参考代码:
import json
import requests
def getknglat(address):
url="https://api.map.baidu.com/geocoding/v3/?address=南京市&output=json&ak=3wFhBw4kBi56MelWGmqSsU1Uy9xiqot4"
res=requests.get(url).text
print(res)
temp=json.loads(res)#将字符串转化为json
print(temp["result"])
lat=temp["result"]["location"]["lat"]
lng=temp["result"]["location"]["lng"]
return lng,lat #经度 longitude 纬度 latitude
#print(getknglat("南京大学"))
'''
输出的结果样例
{"status":0,"result":{"location":{"lng":118.80242172124585,"lat":32.06465288561847},"precise":0,"confidence":20,"comprehension":100,"level":"城市"}}
{'location': {'lng': 118.80242172124585, 'lat': 32.06465288561847}, 'precise': 0, 'confidence': 20, 'comprehension': 100, 'level': '城市'}
(118.80242172124585, 32.06465288561847)
'''
四、WEB开发
1)选择开发文档中的WEB 开发-->JavaScript API,界面如下图所示:
在这之前需要创建热力图服务的浏览器端
注:百度地图开放平台的账户注册参考开发指南中的账号和获取密钥操作。
浏览器端应用的设置,可参考下图的设置:
2)找到百度地图的demo,并复制相应的代码(这里面有详细的代码介绍)
3)在pycharm中创建Html文件,如下图所示:
将helloworld中的源码拷到baidumapDemo.html文件中。
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=p8cynEzrMX2IkDEN5fH4BFkOGjQjtBFx"></script>
<script type="text/javascript" src="http://api.map.baidu.com/library/Heatmap/2.0/src/Heatmap_min.js"></script>
<title>热力图功能示例</title>
<style type="text/css">
ul,li{list-style: none;margin:0;padding:0;float:left;}
html{height:100%}
body{height:100%;margin:0px;padding:0px;font-family:"微软雅黑";}
#container{height:90%;width:100%;}
#r-result{width:100%;}
</style>
</head>
<body>
<div id="container"></div>
<div id="r-result">
<input type="button" onclick="openHeatmap();" value="显示热力图"/><input type="button" onclick="closeHeatmap();" value="关闭热力图"/>
</div>
</body>
</html>
<script type="text/javascript">
var map = new BMap.Map("container"); // 创建地图实例
var point = new BMap.Point(118.760547,31.995307);
map.centerAndZoom(point, 12); // 初始化地图,设置中心点坐标和地图级别
map.enableScrollWheelZoom(); // 允许滚轮缩放
var points =[{'lat':31.994641031479546,'lng':118.76338396886818,'counts': 7},
{'lat': 31.99515825934137,'lng': 118.76239331755178, 'counts': 13},
{'lat': 31.993956289530654,'lng': 118.76082128290932, 'counts': 2},
{'lat': 31.99245265021546,'lng': 118.7558879803876, 'counts': 12},
{'lat': 31.999432855702388,'lng': 118.76741691145524, 'counts': 8},
{'lat': 32.00193148289008,'lng':118.76625576175304, 'counts': 13},
{'lat': 31.99919622550667,'lng':118.76354530453779, 'counts': 6},
{'lat': 32.00215593416205,'lng':118.77065027230785, 'counts': 5},
{'lat': 31.995390000354142,'lng':118.75996699436934, 'counts': 1},
{'lat': 31.99827833030048,'lng':118.76686714848313, 'counts': 2}];
if(!isSupportCanvas()){
alert('热力图目前只支持有canvas支持的浏览器,您所使用的浏览器不能使用热力图功能~')
}
//详细的参数,可以查看heatmap.js的文档 https://github.com/pa7/heatmap.js/blob/master/README.md
//参数说明如下:
/* visible 热力图是否显示,默认为true
* opacity 热力的透明度,1-100
* radius 势力图的每个点的半径大小
* gradient {JSON} 热力图的渐变区间 . gradient如下所示
* {
.2:'rgb(0, 255, 255)',
.5:'rgb(0, 110, 255)',
.8:'rgb(100, 0, 255)'
}
其中 key 表示插值的位置, 0~1.
value 为颜色值.
*/
heatmapOverlay = new BMapLib.HeatmapOverlay({"radius":45});
map.addOverlay(heatmapOverlay);
heatmapOverlay.setDataSet({data:points,max:100});
//是否显示热力图
function openHeatmap(){
heatmapOverlay.show();
}
function closeHeatmap(){
heatmapOverlay.hide();
}
closeHeatmap();
function setGradient(){
/*格式如下所示:
{
0:'rgb(102, 255, 0)',
.5:'rgb(255, 170, 0)',
1:'rgb(255, 0, 0)'
}*/
var gradient = {};
var colors = document.querySelectorAll("input[type='color']");
colors = [].slice.call(colors,0);
colors.forEach(function(ele){
gradient[ele.getAttribute("data-key")] = ele.value;
});
heatmapOverlay.setOptions({"gradient":gradient});
}
//判断浏览区是否支持canvas
function isSupportCanvas(){
var elem = document.createElement('canvas');
return !!(elem.getContext && elem.getContext('2d'));
}
</script>
提示:注意修改您的AK
在浏览器中运行页面,如果显示如下提示信息:
解决方案将地址栏中的localhost修改为:127.0.0.1,修改后的界面如下图所示:
五、文件的处理与读入 (数据处理操作)
import numpy as np
import json
import requests
import pandas as pd
def getknglat(adress):
#url = f'http://api.map.baidu.com/geocoding/v3/?city=南京市&address={adress}&ak=InTptui6skOcBML4iHGlhBml2srxz3mo&output=json&callback=showLocation'
url="https://api.map.baidu.com/geocoding/v3/?city=南京市&address="+adress+"&ak=InTptui6skOcBML4iHGlhBml2srxz3mo&output=json"
res=requests.get(url).text
res=res.strip('showLocation&&showLocation(').strip(')')
temp=json.loads(res)#将字符串转化为json
#print(temp["result"])
lat=temp["result"]["location"]["lat"]
lng=temp["result"]["location"]["lng"]
return lng,lat #经度 longitude 纬度 latitude
#print(getknglat("德盈菁华园"))
#print(getknglat("江苏警官学院家属区"))
wb=pd.read_csv("house.csv",encoding="utf-8")
ws=wb["community"]
#计数
counts={}#定义一个字典
for i in ws:
counts[i]=counts.get(i,0)+1
counts=counts.items()#取出字典的元组
counts_list=list(counts)#将counts转化为列表,此时列表中元素为(小区名,出现的次数)这种形式
num=len(counts_list)#计算出列表中的元素个数
list_all=[]#存放所有地点的经纬度、出现次数信息
lat_lng_counts={}#字典每次临时存放这种类型{"lat":34.34672364986643,"lng":108.96549386128427,"count":2}数据
#更新list_all
#print(getknglat("柏悦澜庭"))
#print(getknglat("德安花园"))
for i in range(0,num):
#print(getknglat(counts_list[i][0]))
lng,lat=getknglat(counts_list[i][0])
#print(lng,lat)
lat_lng_counts["lat"]=lat
lat_lng_counts["lng"]=lng
lat_lng_counts["counts"]=counts_list[i][1]
list_all.append(lat_lng_counts)#将数据加入到list_all内
lat_lng_counts={}#清空字典
#异常处理
for i in range(0,num):
try:
if list_all[i]["lat"]=="暂无数据" or list_all[i]["lng"]=="暂无数据":
del list_all[i]
continue
else:
pass
except:
continue
#将数据写入到文件中
for it in list_all:
if it == list_all[0]:
with open("data123.txt", mode="w", encoding="utf-8") as f: #a可以续写,w则是清空再写
it = str(it)
f.write("["+it + ",")
f.write("\n")
else:
with open("data123.txt", mode="a", encoding="utf-8") as f:
if it == list_all[-1]:
it = str(it)
f.write(it + "];")
else:
it = str(it)
f.write(it+",")
f.write("\n")
'''
#输出json格式数据
print("[",end="")
for i in range(0,num):
if i==num-1:
print(list_all[i],end="")
else:
print(list_all[i])
print("]")
'''
附加(下面的代码可以忽略,博主仅用于记录思路)
import pandas as pd
c = pd.read_csv("result.csv",encoding="utf-8",low_memory=False)
num=len(c)
print(num)
info = []
#perpect
def add_info(lng,lat):
for stu in info:
if lng == stu["lng"] and lat ==stu["lat"]:
stu['count'] += 1
return
stuDict = {'lat': lat,'lng': lng,'count': 1}
info.append(stuDict)
return
pass
for it in range(num):
try:
if c.iloc[it]["longitude"] == "暂无数据" or c.iloc[it]["latitude"] == "暂无数据" :
continue
else:
add_info(float(c.iloc[it]["longitude"]), float(c.iloc[it]["latitude"]))
except:
continue
for it in info:
if it == info[0]:
with open("data123.txt", mode="w", encoding="utf-8") as f: #a可以续写,w则是清空再写
it = str(it)
f.write(it + ",")
f.write("\n")
else:
with open("data123.txt", mode="a", encoding="utf-8") as f:
if it == info[-1]:
it = str(it)
f.write(it + ";")
else:
it = str(it)
f.write(it+",")
f.write("\n")
print("over")
六、展示结果