【问题标题】:Match housenumbers on buildings (special case of point-in-polygon-test)匹配建筑物上的门牌号(多边形点测试的特殊情况)
【发布时间】:2014-10-30 10:15:38
【问题描述】:

任务示例

我正在处理来自 openstreetmap 的地理数据(国家/地区大小)。建筑物通常是没有门牌号的多边形,并且带有门牌号的单个点放置在建筑物的多边形内。建筑物可能有多个门牌号。

我想将门牌号与建筑物的多边形相匹配。

简单的解决方案

Foreach housenumber 对每个建筑物多边形执行多边形点测试。

问题

对于大约 50,000,000 个建筑物和 10,000,000 个地址点来说太慢了。

想法

为建筑物多边形构建和索引,以加速搜索每个门牌号点的周围多边形。

问题

对于这种多边形结构,您会推荐什么索引或策略?多边形从不重叠,并且该区域很少被覆盖。


这个问题被复制到 gis.stackexchange.com。建议在此处发布问题。

【问题讨论】:

  • 这个问题最好属于gis.stackexchange.com。此外,您可以查看其他search engines for OSM 选择的策略,例如Nominatim
  • 我应该在 gis.stackexachange.com 上发布一个副本吗?如果不是,我该如何移动问题?
  • 据我所知你不能移动它。要么创建一个副本,但在两个问题中都提到它,要么关闭这个。
  • 使用更高的数据结构(例如四叉树)
  • 该问题旨在讨论使用哪种结构(例如四叉树、r-tree、...)。

标签: algorithm indexing geospatial openstreetmap computational-geometry


【解决方案1】:

因为听起来您需要测试格式良好的多边形,所以我会使用空间散列和 AABB 检查,最后是完整的多边形内点测试。希望到那时您将平均每个地址进行三个或更少的多边形点测试。

  • 将您的数据所在的区域划分为一个简单的网格,其中一个网格是建筑物中位数大小的小倍数(2 到 4)。 (可能 100-200 米?)
  • 计算每个多边形的轴对齐边界框,将其(及其边界框)添加到边界框相交的每个网格位置。 (找出轴对齐边界框与常规轴对齐网格单元重叠的位置非常简单。我不会将网格存储在简单的二维数组中——我会使用映射二维整数网格坐标的哈希表,例如( 1023, 301), 到多边形列表)
  • 然后遍历所有地址点。在哈希表中查找该点所在的单元格。遍历该单元格中的所有多边形,如果该点位于任何多边形的轴对齐边界框内,请执行完整的多边形点测试。

这有几个优点:

  • 数据结构很简单——不需要花哨的库(除了处理多边形)。使用 C++、您的多边形库和 std 命名空间,这可以在不到一个小时内实现。
  • 空间结构不是分层的——当您查找点时,您只需在哈希表中进行一次 O(1) 查找。

当然,网格作为空间结构的通常缺点:

  • 不能很好地处理大小变化很大的多边形。不过,我希望由于您使用的是地图数据,因此大小几乎总是在一个数量级之内,而且可能要小得多。

假设您最终在每个网格中都有N 的最大多边形,并且每个多边形都有P 点,并且您有B 建筑物和A 地址,那么您正在查看O(B*P + N*A)。由于BP 可能相对较小,尤其是平均而言,您可以考虑这个O(B + N)——几乎是线性的。

【讨论】:

  • 为什么不使用二维数组?是不是因为多边形的稀疏而节省内存?
  • 是的。我会假设你有大片乡村和人口密集的社区——但我承认,我有偏见,因为我住的地方就是这样。老实说,如果您认为内存限制不是问题,那么使用数组会更简单一些。但是哈希表让您几乎是无限的——您不必担心您的数组大小。我不确定您是否会注意到任何情况下的速度差异。
  • 我想我会将它存储在一维数组中,以提高缓存效率,从而获得更快的速度。我会做一些内存使用的计算和测试,然后告诉你。
  • 如果您使用的是快速语言(例如 C++、D、Fortran,我们甚至还会计算 Java、Javascript 和 C#),通常您不会注意到访问速度数组与哈希表。我可以在一秒钟内用 C# 敲击一个哈希表 5000 万次。 (那是一些相当复杂的键——不是整数对。)
  • 我在 C# 中使用了您的解决方案,并编写了一个具有 X 和 Y 成员的类 Pixel 并覆盖了 GetHashCode 方法。光栅化非常快,只需要几分钟。让我们看看点定位的速度有多快……
猜你喜欢
  • 2012-12-17
  • 2021-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-04
  • 1970-01-01
相关资源
最近更新 更多