055-【保姆级教程】手把手教你如何抓取高德全部POI-基于ArcGIS 渔网分割

3,904 阅读3分钟

这是坚持技术写作计划(含翻译)的第55篇,定个小目标999,每周最少2篇。


工作原因需要获取本地全部poi,直接调用高德api会有数量限制(理论上超过1000条就容易丢失部分数据,而且这种丢失很隐蔽,难以校验)

最终经过一番周折,基于网上资料进行了整理

  1. 注册高德账号,获取高德key
  2. 下载安装ArcMap/ArcGIS
  3. 将抓取区域等距分割并导出多边形经纬度
  4. 基于切割后的经纬度重新轮高德api



前置准备


注册高德账号,并创建应用,获得key ,这个看官网文档或者网上自己搜就行,不多说了

获取行政区划点位,lbs.amap.com/api/webserv…
image.png
复制出polyline,用任何一个现代化编辑器(vs code,notepad++等)将 ; 替换成换行符,在第一行插入 x,y 保存成 jn.csv 

根据 ArcMap 0 (ArcGIS10.2安装(完善版--能解决常见问题)) 下载并安装ArcMap 10.2,并破解,但别汉化(后边点集转线的时候会报错)

获取分割后的坐标点位

导入点集

File->Add Data->Add XY Data...
image.png
建议如果不会用arcmap切换文件夹的,直接将文件放入 文档\ArcGIS\  下,自动带入 x,y 字段,点OK即可
image.png
出现行政区划点图像了
image.png

点集转线

ArcToolbox -> Data Management Tools -> Features ->Points To Line
image.png
image.png

使用渔网功能等分切割行政区域

image.png
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
image.png

取渔网和行政区划交集(擦除行政区划外的渔网网格部分)

image.png
将其导出后边要用
image.png

获取网格点位的经纬度

参考大佬的文章 Python3爬取高德地图POI ,下载作者开发的 渔网对角坐标获取工具
链接:链接:pan.baidu.com/s/11nwWHDf7…
提取码:rduv
image.png
获取对角坐标
image.png
image.png

抓取高德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程序员,大数据工程师,运维工程师,前端工程师。

参考资料