055-【保姆级教程】手把手教你如何抓取高德全部POI-基于ArcGIS 渔网分割
这是坚持技术写作计划(含翻译)的第55篇,定个小目标999,每周最少2篇。
工作原因需要获取本地全部poi,直接调用高德api会有数量限制(理论上超过1000条就容易丢失部分数据,而且这种丢失很隐蔽,难以校验) 最终经过一番周折,基于网上资料进行了整理
- 注册高德账号,获取高德key
- 下载安装ArcMap/ArcGIS
- 将抓取区域等距分割并导出多边形经纬度
- 基于切割后的经纬度重新轮高德api
前置准备
注册高德账号,并创建应用,获得key ,这个看官网文档或者网上自己搜就行,不多说了
获取行政区划点位,lbs.amap.com/api/webserv…复制出polyline,用任何一个现代化编辑器(vs code,notepad++等)将
;
替换成换行符,在第一行插入 x,y
保存成 jn.csv
根据 ArcMap 0 (ArcGIS10.2安装(完善版--能解决常见问题)) 下载并安装ArcMap 10.2,并破解,但别汉化(后边点集转线的时候会报错)
获取分割后的坐标点位
导入点集
File->Add Data->Add XY Data...建议如果不会用arcmap切换文件夹的,直接将文件放入
文档\ArcGIS\
下,自动带入 x,y
字段,点OK即可出现行政区划点图像了
点集转线
ArcToolbox -> Data Management Tools -> Features ->Points To Line
使用渔网功能等分切割行政区域
cell size width/height这俩别选,因为高德导入的是火星坐标,不属于标准gps坐标,ArcGis 不识别
所以只能自行计算,假设我需要将济南切割成3km X 3km的小格子,参考 经纬度1度等于多少米,经度1度=85.39km,纬度1度 = 大约111km。那就拿出计算器算呗,(Right-Left)*85.39/3=49.78826191,取整用50就行,同理 (Top-Bottom)*111/3=57.060475,取整用57就行,我截图用的58,懒得换了。
注意别选
Create Label Points(optional)
选项,因为用不到
将行政区划填充颜色
ArcToolbox -> Data Management Tools -> Features -> Feature To Polygon
取渔网和行政区划交集(擦除行政区划外的渔网网格部分)
将其导出后边要用
获取网格点位的经纬度
参考大佬的文章 Python3爬取高德地图POI ,下载作者开发的 渔网对角坐标获取工具链接:链接:pan.baidu.com/s/11nwWHDf7…提取码:rduv获取对角坐标
抓取高德POI
98%都是抄自 Python3爬取高德地图POI 代码,只是稍微处理了下从dict获取字段防止抛异常部分,以及加了省字段
import requests
import json
from pymongo import MongoClient
import time
client = MongoClient('localhost',27017)
db = client.POI_Jinanshi
collection = db.table_1
polygon_list = list()
with open("jn2.txt", 'r', encoding='UTF-8') as txt_file:
for each_line in txt_file:
if each_line != "" and each_line != "\n":
fields = each_line.split("\n")
polygon = fields[0]
polygon_list.append(polygon)
def getjson(polygon, page):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36'
}
pa = {
'key': 'xxxxxxxxxxxxxxxxxxxxxx', #从控制台申请
'polygon': polygon,
'types':'970000|990000', #不要过多
'city':'0531',
'offset': 20,
'page': page,
'extensions': 'all',
'output': 'JSON'
}
r = requests.get('https://restapi.amap.com/v3/place/polygon?', params=pa, headers=headers)
decodejson = json.loads(r.text)
return decodejson
for each_polygon in polygon_list:
not_last_page = True
page = 1
while not_last_page:
decodejson = getjson(each_polygon, page)
print(decodejson)
count = decodejson.get('count',0)
print(each_polygon, page)
if decodejson['pois']:
for eachone in decodejson['pois']:
data={
'name':eachone.get('name',None), #POI名称
'types':eachone.get('type',None), #POI所属类别
'address':eachone.get('address',None), #POI地址
'location':eachone.get('location',None), #POI坐标
'city':eachone.get('cityname',None), #城市
'county':eachone.get('adname',None), #区县
'province':eachone.get('pname',None), # 省份
'count':count, # 条数
'polygon':each_polygon # 多边形经纬度,便于后边再次抓取
}
collection.insert_one(data)
time.sleep(0.2)
page += 1
else:
not_last_page = False
招聘小广告
山东济南的小伙伴欢迎投简历啊 加入我们 , 一起搞事情。长期招聘,Java程序员,大数据工程师,运维工程师,前端工程师。
参考资料
转载自:https://juejin.cn/post/6919393638149521415