高德地图多边形区域搜索 POI 的划分方法

我们想要使用高德开放平台的 POI 搜索 2.0 中的多边形区域搜索来获取 POI 数据。它的传参需求类似于 114.10,30.53|114.11,30.54 的字符串,为一个矩形范围。对于个人认证的开发者,每天每个账号限制调用 100 次(实际情况可能比 100 次略多几十次),3 次每秒。且该 API 每次请求只能返回 1 页,1 页最多 25 条,到第九页必定不出数据。

  • 对于某种类型的 POI,它在地图上分布的密度不是固定的。
  • 还有一个 Web 基础服务 API - 行政区域查询,它可以返回一个行政区的边界字符串。
  • 纬线是横着的,而纬度是竖直方向上的,在竖直方向上,1 纬度约为 111 公里;经线是竖着的,而经度是水平方向上的,在水平方向上,1 经度约为 111 公里乘上纬度的余弦。
  • shapely 包的 Polygon 对象可以表示一个多边形,其 intersects 方法可以判断两个多边形是否有交。一个 list[Polygon] 可以写进 geojson 文件里。
  • geopandas 包可以读写 geojson 文件,并可以配合 plt 画出 gdf。使用 pd.concat 连接两个 gdf

解决方法

用多轮筛查,先用大网,后用小网,每轮用数天数次完成。每轮搜索之前,把待搜索的范围划分成一系列与搜索区域有交的小矩形,如在一个 0.05 范围内的经纬度网内进行第一轮筛查。专门建一个文档,用于保存在本轮搜索里每个小搜索区域的状态,是否爬完,爬到第几页了(先将其设置为空字符串)。

每个小搜索区域有这么几种状态:

  • A:已经爬完了
  • B:没有爬完,且爬到的页号 = 9(看你具体的循环逻辑)
  • C:没有爬完,且爬到的页号 < 9 或为空字符串

爬到 1 至 8 页,且本页的 poi 个数小于 25 条时,说明在这个范围内爬完了;爬到第 8 页,且本页的 poi 个数等于 25 条时,虽然是有很小的概率是爬完了的,但是我们认为它是没有爬完的。

在每次搜索的时候,遍历状态为 C 的区域,对其发请求,并更新对应的搜索区域的状态。

每轮搜索的结束条件:没有状态为 C 的区域了。这时候需要把状态为 B 的区域导出,进行下一步的划分,如划分成 0.01 的经纬度网。

示例代码。虽然写得不好看,但是当时还可以跑。