我试图编写一个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表,包含我的DB的每个多边形的所有顶点坐标
我需要检查所有多边形(有几千个),如果参数中传递的给定点是多边形(如果是,则是哪一个)。我可以自己做循环,但是我错过了一个正确的 Point in polygon 算法。
有人可以帮助我吗? 非常感谢你。
概要
相应的SQL小提琴:http://sqlfiddle.com/#!3/0caa4/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
的行,它将会运行。
定义地理(图形/度量)多边形时有一个“右手”规则。想象一下,你在一辆汽车中按照你指定的顺序访问这些点。你所定义的区域是你看到汽车右侧时所看到的区域。