python通过高德地图接口获取指定范围POI

参考出处: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检索功能

  1. 渔网生成

arctoolbox >> data management tools >> feature class >> create fishnet

在这里插入图片描述配置行列

在这里插入图片描述最终得到渔网如图
在这里插入图片描述删除多余网格外的点位,减少对多余数据的下载。最终结果如下

在这里插入图片描述

查看fish net的四至范围extent,确定每个网格的四至,从而给中心点赋值四至经纬度坐标
在这里插入图片描述

  1. 计算渔网中心点的经纬度和四至坐标
    在这里插入图片描述
    然后昆明市的四至坐标,计算每个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

  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值