简体   繁体   English

指向SQL Server的多边形算法

[英]Point in polygon algorithm for SQL Server

I'm trying to write a SQL query which determine if a given point is into a polygon. 我正在尝试编写一个SQL查询,用于确定给定点是否为多边形。 (I'm using SQL Server 2008 R2). (我正在使用SQL Server 2008 R2)。

I was following this tutorial (just copy / paste it and change some table name) and it approximatively works BUT it is not precise at all. 我正在按照这个教程 (只是复制/粘贴它并更改一些表名),它近似地工作,但它根本不精确。 For example, let's considerate a given point which coordinates are : 例如,让我们考虑一个给定点,其坐标是:
P = 45.7664, 4.87383 . P = 45.7664, 4.87383

If you draw a little polygon (an approximate square) around this point with 4 vertices coordinates : 如果使用4个顶点坐标在此点周围绘制一个小多边形(近似正方形):
S = 45.97215 4.693909, 45.687 4.674683, 45.73302 5.460205, 46.05227 5.366821, 45.97215 4.693909

the procedure given in the link below answers the point is NOT in polygon, whereas it is... This is the output (with my own formatting text) : 在下面的链接中给出的过程回答点不是多边形,而它是...这是输出(使用我自己的格式文本):
错误输出
(Polygon 20 is the polygon above) (多边形20是上面的多边形)

But if you enlarged the square (10 times bigger in my test), the procedure answers my point is in the square. 但是如果你扩大了方形(在我的测试中大10倍),程序回答我的观点就在广场上。

So, I'm seeking for another algorithm, more precise. 所以,我正在寻找另一种算法,更精确。
Here is my VERTICE table, containing all vertices coordinates of each polygon of my DB 这是我的VERTICE表,包含我的DB的每个多边形的所有顶点坐标 顶点表

I need to check, for ALL polygons (there are a few thousands) if a given point passed in parameter is in a polygon (and if yes, which one(s)). 如果参数中传递的给定点在多边形中(如果是,哪一个),我需要检查所有多边形(有几千个)。 I can do the loop by myself, but I miss a correct Point in polygon algorithm. 我可以自己做循环,但我错过了一个正确的多边形算法

Could someone help me ? 有人能帮助我吗? Thank you very much. 非常感谢你。

SUMMARY 摘要

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

Your problem is that you've defined the polygon backwards. 您的问题是您已向后定义多边形。 Let's explore this with the native SQL geography types 让我们使用本机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;

As you can see, @s holds pretty much the whole world. 正如你所看到的, @s几乎占据了整个世界。 In the result set viewer, if you zoom into where your "square" should be, you'll find a hole. 在结果集查看器中,如果你放大你的“正方形”所在的位置,你会找到一个洞。 Contrast that with @t which is the area that you expect. @t对比,这是您期望的区域。 Also note that I ran this in SQL 2012 which improved on a limitation that existed pre-2012 that says that a geospatial instance can't cross a hemisphere boundary. 另请注意,我在SQL 2012中运行此功能,该功能改进了2012年之前存在的限制,该限制表明地理空间实例无法跨越半球边界。 If you run the above on a 2008 instance, you'll likely get an error to that effect for @s . 如果在2008实例上运行上述操作,则可能会对@s产生错误。 Comment out the line defining @s and it'll run. 注释掉定义@s的行并且它将运行。

There's a "right-hand" rule when defining geo(graphy/metry) polygons. 定义地理(图形/度量)多边形时有一个“右手”规则。 Imagine that you were in a car visiting the points in the order you've specified. 想象一下,你在一辆汽车中按照你指定的顺序访问这些点。 The area that you're defining is what you'd see if you were looking out the right side of the car. 您定义的区域是您从汽车右侧看时所看到的区域。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM