如何实现地理点缓存

时间:2015-10-20 14:57:33

标签: postgresql caching geospatial postgis geo

我正在使用地图服务,给定地理圆(由坐标和半径定义),返回该区域中的一组地点。我希望缓存此地图服务返回的结果。

我希望我的缓存存储两个表:

  • 服务返回的表格地方
  • Circles 已将地点缓存在表地方中的地区。

然后,给定一个任意的新圆圈 C ,我想有效地测试缓存是否 C 的区域完全由表格中的圆圈覆盖圆圈。如果 C 完全被覆盖,我有一个缓存命中,我不需要咨询地图服务。如果 C 未完全覆盖,我必须咨询地图服务并缓存结果。

Q1:如何存储一组地理圆圈,以便我可以有效地测试其区域的并集是否完全覆盖任意新的圆圈?

即使有Q1的解决方案,我可能会遇到性能问题,其中缓存未命中非常轻微,我向地图服务发出请求,这几乎没有添加到我的缓存区域。为了解决这个问题,我希望能够在 C 中找到一个未被圆圈覆盖的示例点,以便将其用作地图服务请求的中心。我将重复这个过程,直到完全覆盖 C

Q2:如何存储地理圈组,以便在其区域不完全覆盖给定圈 C 的情况下,我可以有效地生成 C 中未涵盖的示例点?

我希望使用PostgreSQL和PostGIS这样的东西来实现我的缓存,但我欢迎其他建议。

1 个答案:

答案 0 :(得分:1)

这是我的hacky方法,基本上是“光栅化”。

将地球区域划分为大而有限数量的小地理区域,这些小地理区域是通过在纬度/长平面上绘制网格来定义的。

我们保留一张 Tiles 的表格,而不是圈子的表格,这些表格已将地点缓存在地方表中。

给定一个地理圆圈,我们可以有效地生成部分由圆圈覆盖的地理区域集合,以及圆圈完全覆盖的集合。

将点插入缓存时,我们会将每个完全覆盖的磁贴标记为缓存。

在探测圆圈 C 的缓存时,如果 C 完全或部分覆盖的每个磁贴位于 Tiles 表中,我们有一个缓存命中。否则,我们有一个缓存未命中,以及一个未缓存的示例图块,我们可以从中选择一个点作为要从地图服务请求的圆的中心。

这种做法存在缺陷:

  • 由于投影失真,瓷砖在地球上的大小和形状各不相同。
  • 如果圆圈太小,可能无法完全覆盖任何瓷砖,因此永远不会被标记为缓存。