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 的多边形算法中的点的主要内容,如果未能解决你的问题,请参考以下文章