参考出处:https://blog.csdn.net/weixin_47796965/article/details/108372378
高德地图的POI数据是开放使用的,最近看到参考文章,也决定试一下。免费使用请求最多返回1000条信息,本文主要通过对目标区域分块进行请求,实现对限制的规避,以达到解决问题的目标
步骤:
1.获取高德地图目标区域的范围
2.将目标范围内划分为适量的区域,并生成中心点
3.计算中心点的四至,并赋予中心点
4.编写程序。依据高德地图LBS开放的多边形搜索功能,实现对各区域的POI检索与获取
一、以昆明市为例-获取高德地图上的昆明市范围
打开高的lbs平台,并注册认证个人开发者和登录
https://lbs.amap.com/api/webservice/guide/api/district/
如下图录入参数
可以获取到点状的边界范围,如下图distinct中的polyline参数。我们复制到world中,查找到小块区域的坐标并删除,然后剩余数据分行再复制到excel中,再在excel中进行分列操作,并添加x,y表头保存为excel 97-2013xls文件,方便下一步arcmap操作。
在这里,原作者在深圳数据处理过程中遇到了小块区域导致异常的问题,但是在昆明市的数据处理中没有遇到,但是遇到了excel单元格中不能存下全部数据的问题,因此,本文采用csv格式进行存储,相关数据规整操作直接使用python进行处理,带来些微不同。
这里的数据规整主要为,1、将经纬度分列;2、将“;”改为换行两项。代码数据与结果如下:
#%%
with open(r"\kunming_poi.csv",'rb') as csvfile:
f.write('x,y')
for i in csvfile:
line_value = str(i,encoding='utf8')
\#print(i,type(i))
csvfile.close()
\# %%
value_list = line_value.split(';')
print(value_list)
with open(r'result.csv','w') as f:
for value in value_list:
f.write(value)
f.write('\n')
f.close()
转换结果
二、ArcGIS将坐标点转换为空间范围
将csv数据导入ArcGIS,并将数据转换为SHP文件,再将数据进行点转线操作。
都是常规操作,就不叙述了,如果有需要可以留言,我再写一篇文章补充。可以参照原作者的文章
导入数据的时候,需要将坐标系设置为WGS1984,虽然与高德地图的坐标系有差别,但是差别不太大,可能会有些误差,但是在地级市研究中可能微乎其微。
三、绘制渔网图fish net,并且获取渔网中心点坐标
目标是通过渔网构建的四至范围,采用高德地图提供的多边形POI检索功能
- 渔网生成
arctoolbox >> data management tools >> feature class >> create fishnet
配置行列
最终得到渔网如图
删除多余网格外的点位,减少对多余数据的下载。最终结果如下
查看fish net的四至范围extent,确定每个网格的四至,从而给中心点赋值四至经纬度坐标
- 计算渔网中心点的经纬度和四至坐标
然后昆明市的四至坐标,计算每个fish net的大小,这里如图:
横向我设置了10个格网,因此每个格网横向长度为:(right-left)/10
纵向我设置了15个格网,因此纵向格网长度为:(top-bottom)/15
由于点位为中心点,因为中心点坐标在上一步已知,因此每个中心点的四至,可以批量通过同规格格网参数进行设置。
Top=latitute + (top-bottom)/15/2
Bottom=latitute - (top-bottom)/15/2
Left=logitute - (right-left)/10/2
Right=logitute +(right-left)/10/2
这里有错误,可能会导致获取数据不全,只用根据生成的格网从新计算上下左右中线即可(2021/01/07)
结果举例如下:
最后附上参考文章里的代码,我这边修改过一些,但是有个问题,就是每次都遍历100页,但是有些时候并没有那么多页面,找了一下说明,也没有返回页面数量的参数,因此该代码效率还可以进一步提升。(也可以使用分段并发的方式)
这里可以先请求一次,判断数据有多少页,再进行更多请求,有助于减少无效请求,提高效率(2021/01/07)
——————————————————————————————
很遗憾,上面方法不可行,count不代表获取到的数据数量,要节约请求次数、提高效率,只能从空值判断进行,不然会导致丢数据等问题(2021年1月9日)
#%%
import pandas as pd
import requests
key = r'******************' #高德地图开发者平台申请的key
keywords = "商场|超市|商店"
types = "060000"
url_head = r"https://restapi.amap.com/v3/place/polygon?"
text1 = pd.read_csv(r"昆明市范围_高德数据采集点.txt") #从arcmap中导出的text文件地址
#%%
print(len(text1))
#输入表头
with open("poi_gaode.txt", 'a') as f:
f.write('poi_name;poi_adname;poi_address;poi_location;poi_tel\n")
f.close()
#%%
#for i in range(0, len(text1)): #获取全部矩阵数据时,有可能超过高德地图配置的每天30000条数据限额,可选择先获取前35条,第二天再获取剩余数据
for i in range(51, 124):
#经度和纬度用","分割,经度在前,纬度在后,坐标对用"|"分割,经纬度小数点后不得超过6位。
con_location = str(round(text1["long_left"][i], 6)) + ',' + str(round(text1['lat_top'][i], 6)) + '|' + str(round(
text1['long_right'][i], 6)) + ',' + str(round(text1['lat_bottom'][i], 6))
url_ttl = url_head + "polygon=" + con_location + "&keywords=" + keywords + "&key=" + key + "&types=" + types + "&output=json&offset=20&extensions=all"
# rep0 = requests.get(url_ttl)
# json0 = rep0.json()
# count0 = json0["count"]
print("开始进行第%d个网格的数据提取." % i)
# print("一共%d条数据" % int(count0))
for p in range(1, 101): #遍历100页
url = url_ttl + '&page=' + str(p)
rep1 = requests.get(url)
json1 = rep1.json()
pois_data = json1['pois']
for poi in pois_data:
poi_name = str(poi["name"])
poi_adname = str(poi["adname"])
poi_address = str(poi.get("address", "无详细地址"))
poi_location = str(poi["location"])
poi_tel = str(poi.get("tel", "无联系方式"))
poi_info = poi_name + ";" + poi_adname + ";" + poi_address + ";" + poi_location + ";" + poi_tel + "\n"
poi_info = poi_info.encode('gbk', 'ignore').decode("gbk", "ignore") #避免编码错误
with open("poi_gaode.txt", 'a') as f:
f.write(poi_info)
print("正在写入数据...")
print("数据提取完成")
f.close()
我这里商业不发达,3万次调用绰绰有余了。。
结果如下:
再次感谢原作者的付出!
@wenlulan
参考文章:https://blog.csdn.net/weixin_47796965/article/details/108372378