指向SQL Server的多边形算法

时间:2013-10-27 17:02:48

标签: sql-server algorithm sql-server-2008 polygons point-in-polygon

我试图编写一个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

以下链接中给出的程序回答点不是多边形,而是...... 这是输出(使用我自己的格式文本):
false output
(多边形20是上面的多边形)

但是如果你扩大了方形(在我的测试中大10倍),程序就会回答我的观点。在广场上。

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

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

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

概要

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

1 个答案:

答案 0 :(得分:7)

您的问题是您已向后定义多边形。让我们用原生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的行,它将会运行。

定义地理(图形/度量)多边形时有一个“右手”规则。想象一下,你在一辆汽车中按照你指定的顺序访问这些点。你所定义的区域是你看到汽车右侧时所看到的区域。