打开封闭多边形的街道地图

时间:2014-01-17 14:22:50

标签: maps openstreetmap osmdroid

我正在开发一个在[1]使用Overpass API的Android应用程序。我的目标是获得包含特定纬度点的所有循环方式。

为了做到这一点,我构建了一个包含我的位置的矩形的请求,然后解析响应XML并运行光线投射算法来过滤包含给定lat-long位置的方式。对于我的应用程序来说,这太慢了,因为有时响应有几十或几百MB。

我是否可以调用任何OSM API来获取包含某个位置的所有方法?否则,我该如何优化流程呢?

谢谢!

[1] http://overpass-api.de/

1 个答案:

答案 0 :(得分:3)

据我所知,OSM中没有标准API来执行此操作(这确实是一个非常罕见的用例)。

我假设您将包围定义为表示当前位置的点位于多边形的内部区域内。此外,我假设优化过程可能包括改变算法的整个概念。

首先,您需要定义矩形以获取数据。为此,您需要考虑查询太大的矩形会产生太多数据。据我所知,没有特定的API只能查询循环方式,即使有,查询过大的矩形也可能被服务器拒绝,因为服务器负载会很大。

服务器端预计算/预过滤

因此,我建议进行第一次优化:使用保存在Android设备上的脱机数据库,而不是查询不适合您的API。 OsmAnd 和其他人保存离线国家/地区的整个数据库,但在您的特定用例中,您只需要保存预先过滤的循环数据库。

据我所知,OSM中只有一小部分方法是循环的。因此,我建议编写一个定期下载OSM转储的脚本,例如从Geofabrik,删除非循环方式(例如,您可以检查某个方式中的最后一个节点ID是否等于第一个节点ID,但您需要检查是否以任何方式捕获您定义为循环)。你运行它的频率取决于你的用例。

此优化解决了:

  • 下载大量数据的问题
  • 使用大请求重载API的问题
  • 无法请求大量数据的问题

如果这不适合您的用例,我建议您在服务器上为其构建一个简单的API。

将数据重新分块为适当的网格

但是,您仍需要过滤大量数据。为了部分解决这个问题,我建议进行第二次优化:重新整理数据。例如,如果您当前的位置位于弗吉尼亚州,则无需过滤区域不在德克萨斯州以外的圆形路径。因为按国家等进行过滤会依赖于国家和高难度(CPU密集型),我建议选择一个网格,例如0.05 lat / lon度(我选择一个equirectangular投影,因为如果你已经有lat / lon坐标,它很容易计算。)

预处理该数据的脚本然后将为您要使用的区域中的任何矩形创建一个数据块(可能是一个文件,但我们对于您的用例不足以讨论特定的数据结构) 。当且仅当它具有至少一个位于块区域内的节点时,此块中包含循环方式。

然后,您只会请求/过滤您当前所在位置的特定块。请根据您的应用选择适当的块大小(最好相当小,但这取决于众多因素!)。

此优化解决了:

  • 假设大多数圆形方式的边界矩形非常小,你只需要过滤一小部分的整体方式
  • IO被最小化,特别是如果你

滞后启发式

如果前面提到的优化不足以减少你的计算时间,我建议第三个优化取决于你想要找到多少循环方式(如果你真的需要找到所有,它根本没有帮助):使用滞后。保存上次计算期间的循环方式(假设新的当前位置靠近最后一个位置)并首先检查它们。如果您的位置没有太大变化,那么您很有可能在前几次光线投射中遇到一种方式。

利用不同循环方式之间的关系

此外,第四种优化是可能的:将有一些循环方式完全封闭在另一种循环方式。您可以对程序进行编码,以便它知道该关系并首先检查内部循环方式。如果此检查成功,您现在自动将当前位置也包含在外部循环方式中。我认为计算信息(服务器端)可能是CPU密集型的,并且实现它也可能是一项艰巨的任务,所以我建议只有在不可避免的情况下才使用这种优化。

调整这些优化的参数应足以显着减少计算所需的CPU时间。如果您对这些建议有任何疑问,请随时发表评论/询问。