高血压专题网,内容丰富有趣,生活中的好帮手!
高血压专题网 > 【数据技术】利用Python获取高德地图POI数据——以上海瑞幸门店为例

【数据技术】利用Python获取高德地图POI数据——以上海瑞幸门店为例

时间:2024-02-23 12:37:29

相关推荐

【数据技术】利用Python获取高德地图POI数据——以上海瑞幸门店为例

一、概述

本文讲述利用Python获取高德地图POI数据的思路以及具体步骤。

此处以上海瑞幸门店为例,目的是同时讲述多边形搜索关键词搜索以及POI类型搜索的具体用法。

本文完整代码的获取方式在文末,有需求的小伙伴自取。

上海瑞幸门店地图可视化

上海瑞幸门店地图可视化

二、获取思路

通过调用高德地图API中的搜索POI(多边形搜索)接口来获取POI数据。

搜索POI接口

/api/webservice/guide/api/search#around

理论上来说,只需要将接口输入参数中的polygon设置为上海边界经纬度值,将keywords设置为瑞幸,将types设置为餐饮服务(编码:050000),就能够获取上海范围内的瑞幸咖啡门店数据。

GeoJSON格式的上海边界数据

但在多边形搜索接口中每个边界范围能够获取到的POI数量是有限制的,超过该限制的POI数据则不会返回。

因此,想要获取全量POI数据,需要将一个大多边形切割成若干个符合数量限制的小多边形。

此处,引入四叉树索引的概念,将大的多边形不断四分,直到所有小多边形均满足数量限制为止。

完成上述操作后,遍历所有小多边形并获取瑞幸POI,即可得到全量的上海瑞幸POI数据。

三、具体步骤

步骤1:申请高德地图API密钥

高德地图API密钥需要通过高德官网申请

高德地图API官网(/)

具体操作步骤可参考下面链接:/l/coOAaCYwW0tg

步骤2:获取上海边界范围外接矩形的坐标值

# 通过读取GeoJSON格式的上海边界数据# 获取上海边界外接矩形的最小经度、最大经度、最小纬度、最大纬度​import geopandas as gp​# 结果变量resultMinLon = 99999.0 # 最小经度resultMaxLon = 0.0 # 最大经度resultMinLat = 99999.0 # 最小纬度resultMaxLat = 0.0 # 最大纬度​# 读取上海边界数据loadGeoData = gp.read_file("D:\\上海边界数据.geojson")for i in range(0, len(loadGeoData)):# 读取几何数据loadGeometry = loadGeoData.loc[i, "geometry"]# 上海边界的几何数据是由多个多边形组成,如崇明岛、长兴岛、上海市区等# 所以需要遍历所有多边形# 多边形的类型是Polygon或者MultiPolygonfor j in range(0, len(loadGeometry)):loadPolygon = loadGeometry[j]# 读取多边形的边界# 边界的类型是LineString(单线)或MultiLineString(多线)if loadPolygon.boundary.geom_type == 'LineString':# 读取边界中的每个坐标点for z in range(0, len(loadPolygon.boundary.coords)):loadLon = loadPolygon.boundary.coords[z][0] # 经度loadLat = loadPolygon.boundary.coords[z][1] # 纬度# 进行大小判断,并替换结果if loadLon <= resultMinLon:resultMinLon = loadLonif loadLon >= resultMaxLon:resultMaxLon = loadLonif loadLat <= resultMinLat:resultMinLat = loadLatif loadLat >= resultMaxLat:resultMaxLat = loadLatelif loadPolygon.boundary.geom_type == 'MultiLineString':# 如果边界是MultiLineString,则需要遍历其中的每条LineStringfor z in range(0, len(loadPolygon.boundary[0].coords)):loadLon = loadPolygon.boundary[0].coords[z][0]loadLat = loadPolygon.boundary[0].coords[z][1]if loadLon <= resultMinLon:resultMinLon = loadLonif loadLon >= resultMaxLon:resultMaxLon = loadLonif loadLat <= resultMinLat:resultMinLat = loadLatif loadLat >= resultMaxLat:resultMaxLat = loadLat# 结果输出print("上海最小经度:", resultMinLon)print("上海最大经度:", resultMaxLon)print("上海最小纬度:", resultMinLat)print("上海最大纬度:", resultMaxLat)

步骤2输出结果

步骤3:以四叉树索引的方式不断四分矩形,直到所有矩形符合POI数量限制

import requests​# 上海边界经纬度值minLon = 120.859465 # 最小经度maxLon = 122.122756 # 最大经度minLat = 30.677191 # 最小纬度maxLat = 31.868458 # 最大纬度​# 存放符合POI数量限制多边形的列表resultPolygonList = []# 用来存放不符合POI数量限制多边形的列表currentPolygonList = [[minLon, maxLon, minLat, maxLat]]​# 以四叉树的方式不断四分外接矩形for currentLevel in range(1, 9999999):# 用来存放不符合POI数量限制多边形的临时列表tempPolygonList = []for z in range(0, len(currentPolygonList)):loadMinLon = currentPolygonList[z][0]loadMaxLon = currentPolygonList[z][1]loadMinLat = currentPolygonList[z][2]loadMaxLat = currentPolygonList[z][3]# 判断当前矩形是否符合POI数量限制# 如果符合则放入resultPolygonList# 如果不符合则进行四分,并将四分结果放入tempPolygonListifSatisfy = judgeIfSatisfy_GaoDe([loadMinLon, loadMaxLon, loadMinLat, loadMaxLat])if ifSatisfy == True:resultPolygonList.append([loadMinLon, loadMaxLon, loadMinLat, loadMaxLat])else:# 进行四叉树tempQuadtree = executeQuadtree(loadMinLon, loadMaxLon, loadMinLat, loadMaxLat)# 左下角tempPolygonList.append(tempQuadtree[0])# 右下角tempPolygonList.append(tempQuadtree[1])# 右上角tempPolygonList.append(tempQuadtree[2])# 左上角tempPolygonList.append(tempQuadtree[3])currentPolygonList = tempPolygonList.copy()# 如果没有多边形进入下一层级,则跳出print("第", currentLevel, "层", "......", "符合要求的矩形:", len(resultPolygonList), "......", "剩余矩形:",len(currentPolygonList))if len(currentPolygonList) == 0:break

步骤3结果

步骤4:遍历所有矩形,获取上海瑞幸POI

# 遍历所有矩形,获取上海瑞幸POI数据savePoiList = [] # 存放POI数据的结果列表for i in range(0, len(resultPolygonList)):# 读取每个矩形loadPolygon = resultPolygonList[i]# 获取矩形中的POI数据,并添加到结果列表中savePoiList.extend(getPoiFromPolygon(loadPolygon, gaodeKey))

下面代码为获取单个矩形中POI数据的方法

# 从单个矩形获取瑞幸POI的方法# 其中key为高德地图API密钥,需要自行申请def getPoiFromPolygon(inputPolygon, key):# 存放POI数据结果的列表resultList = []# 由于POI数量限制是100,每页返回POI数量是20# 因此,最大的页数为5for currentPage in range(1, 6):# 组成UrlcurrentUrl = "/v3/place/polygon?polygon=" + str(inputPolygon[0]) + "," + str(inputPolygon[2]) + "|" + str(inputPolygon[1]) + "," + str(inputPolygon[2]) + "|" + str(inputPolygon[1]) + "," + str(inputPolygon[3]) + "|" + str(inputPolygon[0]) + "," + str(inputPolygon[3]) + "|" + str(inputPolygon[0]) + "," + str(inputPolygon[2]) + "&offset=20&page=" + str(currentPage) + "&keywords=瑞幸&types=050000&output=json&key=" + key# 发送Get请求,并接收返回内容response = requests.get(currentUrl, stream=True, verify=False, timeout=60)returnData = response.json()returnPoiList = returnData['pois']if len(returnPoiList) > 0:for i in range(0, len(returnPoiList)):saveName = returnPoiList[i]['name']saveType = returnPoiList[i]['type']saveAddress = returnPoiList[i]['address']saveLocation = returnPoiList[i]['location']saveProvince = returnPoiList[i]['pname']saveCity = returnPoiList[i]['cityname']saveArea = returnPoiList[i]['adname']resultList.append([saveName, saveType, saveType, saveAddress, saveLocation, saveProvince, saveCity, saveArea])print(saveName, saveType, saveType, saveAddress, saveLocation, saveProvince, saveCity, saveArea)else:# 如果当前页POI数量为0,则返回已获取的POI数据并跳出return resultListreturn resultList

上海瑞幸POI数据

四、代码获取方式

点击下面链接获取代码

【数据技术】利用Python获取高德地图POI数据——以上海瑞幸门店为例 ()

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。