SQL Server 的多边形算法中的点

Posted

技术标签:

【中文标题】SQL Server 的多边形算法中的点【英文标题】:Point in polygon algorithm for SQL Server 【发布时间】:2013-10-27 17:02:47 【问题描述】:

我正在尝试编写一个 SQL 查询来确定给定点是否在多边形中。 (我使用的是 SQL Server 2008 R2)。

我在关注 this tutorial (只需复制/粘贴它并更改一些表名),它几乎可以工作,但它根本不精确。例如,让我们考虑一个坐标为 :P = 45.7664, 4.87383 的给定点。 如果你用 4 个顶点坐标在这个点周围画一个小多边形(一个近似正方形):S = 45.97215 4.693909, 45.687 4.674683, 45.73302 5.460205, 46.05227 5.366821, 45.97215 4.693909

下面链接中给出的过程回答了该点不在多边形中,而它是... 这是输出(带有我自己的格式文本):(多边形 20 是上面的多边形)

但是,如果您将正方形放大(在我的测试中放大了 10 倍),则程序会回答我的观点在正方形中。

所以,我正在寻找另一种更精确的算法。 这是我的 VERTICE 表,包含我的数据库的每个多边形的所有顶点坐标

我需要检查所有多边形(有几千个),如果传入参数的给定点在多边形中(如果是,是哪一个)。我可以自己完成循环,但我错过了正确的 Point in polygon 算法。

有人可以帮我吗? 非常感谢。

摘要

对应的SQL提琴:http://sqlfiddle.com/#!3/0caa4/1

【问题讨论】:

如果数据库中有大量记录,它的性能很差,我尝试了超过 1600000 条记录的查询,平均需要 2 分钟才能完成。 嗨 Jitendra,这是一个老问题,但该项目仍在开发中(这是一个个人项目)。我用@Ben Thul 的解释实现了我的链接中给出的算法,它完美地工作,但我从来没有尝试过这么多的记录。您可以建议一个更好的算法作为答案,欢迎! 【参考方案1】:

您的问题是您已经向后定义了多边形。让我们用原生 SQL 地理类型来探索这个

declare @s geography, @t geography, @p geography;
select @s = geography::STPolyFromText('POLYGON((45.97215 4.693909, 45.687 4.674683, 45.73302 5.460205, 46.05227 5.366821, 45.97215 4.693909))', 4326);
select @t = geography::STPolyFromText('POLYGON((46.05227 5.366821, 45.73302 5.460205, 45.687 4.674683, 45.97215 4.693909, 46.05227 5.366821))', 4326);
select @p = geography::STPointFromText('POINT(45.7664 4.87383)', 4326);

select @p.STIntersects(@s), @p.STIntersects(@t);
select @p.STBuffer(10), @s, @t;

如您所见,@s 几乎拥有整个世界。在结果集查看器中,如果您放大“正方形”应该在的位置,您会发现一个洞。与 @t 进行对比,这是您所期望的区域。另请注意,我在 SQL 2012 中运行了这个,它改进了 2012 年之前存在的限制,即地理空间实例不能跨越半球边界。如果您在 2008 实例上运行上述内容,您可能会收到@s 的错误。注释掉定义@s 的行,它就会运行。

定义地理(地理/几何)多边形时有一个“右手”规则。想象一下,您正在按照您指定的顺序访问这些点的汽车中。您定义的区域是您从汽车右侧向外看时所看到的区域。

【讨论】:

感谢您的回答。但我不明白为什么在你定义的@s 中,你正在跨越一个半球边界......这只是北半球的一个小多边形!?!?否则,STIntersects 似乎比我的算法更好,我想该功能已经过测试和重新测试...... 因为你已经定义了多边形,@s 是整个世界减去你想要的正方形。 你会认为我是个白痴,但我仍然不明白一件事:你告诉我@s 是整个世界减去我想要的正方形。但是@s 是一个位于法国的多边形,这是一个 100% 位于北半球的国家,那我为什么要跨越半球边界呢?那么,如果我理解你的话,当我在另一个多边形内绘制一个多边形时,最大的多边形本身就是减去那个小的?如果是这样,我怎样才能叠加两个多边形? 你不是白痴,我只是解释得不好。你有一个四边形。如果你顺时针遍历这些点,你会得到你期望的区域。然而,如果你逆时针遍历这些点,你会得到整个世界减去四边形。简而言之,在多边形中定义角的顺序很重要; A-B-C-D-A != A-D-C-B-A 本...我真的很爱你!感谢您的回答,首先,我了解了多边形的新知识,然后,您刚刚消除了我项目中的很多问题(这是一个个人项目,但我希望有一天它会起作用)。所以,非常感谢你:-)

以上是关于SQL Server 的多边形算法中的点的主要内容,如果未能解决你的问题,请参考以下文章

当测试点位于多边形边缘时,多边形算法中的点返回真

顶点定义框算法中的点?

多边形特例中的点

如何反转 JSON 多边形顺序以调整 SQL Server 中的环方向

在 SQL Server 中查找多边形内/最近的纬度/经度

不相交多边形中的点