多个多边形的点入多边形算法


11

我有一张Google地图,上面有一堆多边形。

这是我感兴趣的一个问题:给定一个纬度点,确定该点所在的所有多边形的最佳方法是什么?

一种明显的方法是为每个多边形迭代运行“多边形中的点”算法,但是我想知道是否存在一种有效的算法来回答此类查询,尤其是在您有数千个多边形的情况下。


我对Google Maps API知之甚少,但浏览器往往不是进行此类大型查询的最佳场所。PostGIS(免费),ArcServer或Oracle Spatial倾向于更好地处理此类请求。
canisrufus 2011年

我对算法最感兴趣。顺便说一句,您将如何在PostGIS中做到这一点。
numan 2011年

以下网址讲述了多​​边形中的点。(我从未使用过)..尝试一下..它可能会提供一些帮助。eriestuff.blogspot.com/2008/02/…–

3
这是我的强制性评论,“多边形中的点”对于球体上的一个点毫无意义,因为球体上的多边形会将球体分为两部分,其中任何一个都有权称为“内部”。北极或南极位于定义赤道的多边形内吗?记住,
经纬度

4
@Spaced您将“多边形”与“折线”混淆了。多边形点在球体上非常有意义。多边形不仅仅是边界(闭合的折线):还包括内部。尽管多边形边界将球体划分为两个相连的组件,但是有很多方法可以将其中一个指定为多边形的内部,例如通过一种定向约定(例如,内部越过边界,则该内部位于左侧) )或使用栅格表示形式。
ub

Answers:


12

与几乎所有此类问题一样,最佳方法取决于“用例”以及如何表示功能。 用例通常通过以下方式加以区分:(a)每层中是否有很多或很少的对象,以及(b)是否其中一层(或两层)都允许预计算某些数据结构;也就是说,它们中的一个或两个是否足够静态并且保持不变以使对预计算的投资值得。

在当前情况下,这产生了以下情形。通常,这些点是动态的:也就是说,这些点是事先没有给出的。(如果预先提供了它们,或者以非常大的组提供它们,则可以使用基于对它们进行排序的一些优化。)令Q为查询点数,P为多边形顶点数。

矢量多边形数据

(1)几个点,toto中的多边形顶点很少。使用暴力破解程序,例如经典的行刺算法。对于任何体面的方法,成本为O(P * Q),因为将点与多边形边缘进行比较需要花费O(1)时间,并且必须进行所有此类比较。

(2)可能有很多多边形顶点,但是它们是动态的:每次在查询中使用一个点时,这些多边形可能都已改变。再次使用蛮力算法。成本仍然是O(P * Q),这会很大,因为P会很大,但是这无济于事。如果变化很小或受到控制(例如,多边形的形状略有变化或只是缓慢地移动),则可以使用下一个解决方案的版本,并找到一种有效的方式来随着多边形的变化而更新数据结构。这可能是原始研究的问题。

(3)许多多边形顶点和静态多边形(即多边形层很少改变)。预计算数据结构以支持搜索(它可以基于行扫描四叉树算法)。这些算法的预计算成本为O(P * log(P)),但查询的成本为O(Q * log(P)),因此总成本为O((P + Q)* log( P))。

在某些特殊情况下可以进行一些改进,例如

(a)所有多边形都是凸的可以更快地完成多边形的预处理),

(b)所有多边形内部都是不相交的,在这种情况下,您可以将它们的并集视为单个多边形(这允许使用简单有效的算法,例如基于三角剖分的算法,以及

(c)大多数多边形不是很曲折 -也就是说,它们占据了边界框的大部分-在这种情况下,您可以仅基于边界框进行初始测试,然后优化该解决方案。这是一个流行的优化。

(d)点数很多。 对它们进行排序可能会改善时间。例如,当实现从左到右的线扫描多边形中点算法时,您将在其第一个坐标上对点进行排序,从而可以在扫描多边形边缘的同时对这些点进行扫描。我不知道这种优化已经发布。不过,已经发布的一种方法是对所有点和多边形顶点的并集进行约束三角剖分:一旦完成三角剖分,识别内部点应该很快。计算成本将缩放为O(Q * log(Q)+(P + Q)* log(P + Q))。

栅格面数据

这非常简单:将多边形图层视为二进制指示器栅格(1 =多边形内部,0 =外部)。(这可能需要一个查找表才能将栅格值转换为内部/外部指示符。)现在,每个点探针都需要O(1)才能为栅格像元建立索引并读取其值。总努力为O(Q)。

一般来说

一个不错的混合解决方案在许多静态矢量多边形的情况下(上面的矢量情况3)最初是为了对多边形进行栅格化,甚至可能具有较粗的分辨率,这一次可以区分与多边形边界的任何部分相交的所有像元(将其值设为2,例如) 。使用栅格探针(成本:O(1))通常会得到确定的答案(已知该点在内部还是外部),但有时会导致不确定的答案(该点落在至少一个边沿通过的像元中),则需要进行更昂贵的O(log(P))向量查询。此方法为栅格增加了一些额外的存储成本,但是在许多情况下,即使是很小的栅格(一个MB将允许2000 x 2000栅格存储{0,1,2,null}值)可以在计算时间上带来巨大优势。 。渐近地


7

如果您将多边形边界框存储在诸如四叉树之类的东西中,则可以使用它来快速确定要检查的多边形。至少,您只能看到该点是否在每个多边形边界框内,而不是对每个多边形在多边形中做一个完整的点。我个人将设置一个Web服务,该服务将在内存中缓存多边形,并使用诸如JTS或NetTopology套件之类的东西为我做交集查询。


1

在postgis中,ST_Intersects使用索引首先查找该点是否在多边形的边界框内,然后重新检查该点是否确实在多边形内。那很快,通常非常快。

如果您已将数据存储在PostGIS中,那么毫无疑问,数据库是进行计算的正确位置。在其他情况下,您将不得不将多边形发送到某个中间程序或客户端程序。那本身将比进行计算花费更多的时间,并且仅获得相关的多边形。

/尼克拉斯

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.