SQL Server 2014 在多边形中找到一个点
Posted
技术标签:
【中文标题】SQL Server 2014 在多边形中找到一个点【英文标题】:SQL Server 2014 find a point in polygon 【发布时间】:2020-08-05 08:24:09 【问题描述】:我不知道为什么 SQL 没有在我的多边形中检测到这个点
select geography::STGeomFromText('POLYGON ((51.561283 -0.199251
,51.562136 -0.045443
,51.468985 -0.045443
,51.472407 -0.197878
,51.561283 -0.199251))', 4326).STIntersects(geography::Point(51.519425,-0.127029, 4326))
我的多边形在STIsValid()
的结果中有效,并且在 SSMS 显示多边形的方向上也是正确的:
通过谷歌地图,我的点也位于多边形的中心:
这是我用来检测我的观点是否正确的工具: https://www.doogal.co.uk/polylines.php
在文本输入中使用这些数据:
51.561283,-0.199251
51.562136,-0.045443
51.468985,-0.045443
51.472407,-0.197878
51.561283,-0.199251
51.519425,-0.127029
奇怪的是,当我将 lat 和 long 更改为 geography::Point
函数时,结果为 true。
select geography::STGeomFromText('POLYGON ((51.561283 -0.199251
,51.562136 -0.045443
,51.468985 -0.045443
,51.472407 -0.197878
,51.561283 -0.199251))', 4326).STIntersects(geography::Point(-0.127029,51.519425, 4326))
【问题讨论】:
【参考方案1】:几何/地理的文本字符串表示始终使用X Y
约定来指定坐标。这意味着,当解释为地理时,它违反了将纬度放在首位的通常惯例。
因此您需要使用Long Lat
在字符串中指定您的POLYGON
。
您可以在 SSMS 输出中看到这一点,您可以在其中看到多边形位于赤道以南,东约 51° 的某个地方,而不是伦敦的某个地方。
【讨论】:
你是对的。问题是我正在从 mysql 迁移,它可以在转换为地理数据类型时指定轴顺序 [链接] (dev.mysql.com/doc/refman/8.0/en/…)。你知道我怎样才能拥有相同的多边形信息与纬度、经度对并拥有正确的地理数据?【参考方案2】:您必须翻转geography::Point
上的值,因为第一个值是经度,第二个值是纬度:
地理数据类型的点类型表示单个位置,其中 x 和 y 分别表示经度和纬度值。
来源: https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/bb964737(v=sql.105)
请参阅以下直接使用Point
数据类型或使用geometry::STGeomFromText
获取Point
对象之间的比较。 经度和经度顺序不同。
-- get the Point from text using geography::STGeomFromText
SELECT geography::STGeomFromText('POINT(51.519425 -0.127029)', 4326).Lat -- -0,127029
SELECT geography::STGeomFromText('POINT(51.519425 -0.127029)', 4326).Long -- 51,519425
-- get the Point directly using geography::Point
SELECT geography::Point(51.519425, -0.127029, 4326).Lat -- 51,519425
SELECT geography::Point(51.519425, -0.127029, 4326).Long -- -0,127029
所以你有两种可能解决这个问题:
1.翻转Point
的值:
SELECT geography::STGeomFromText('POLYGON ((51.561283 -0.199251
,51.562136 -0.045443
,51.468985 -0.045443
,51.472407 -0.197878
,51.561283 -0.199251))', 4326
).STIntersects(geography::Point(-0.127029, 51.519425, 4326))
2。使用文本指定Point
:
SELECT geography::STGeomFromText('POLYGON ((51.561283 -0.199251
,51.562136 -0.045443
,51.468985 -0.045443
,51.472407 -0.197878
,51.561283 -0.199251))', 4326
).STIntersects(geography::STGeomFromText('POINT(51.519425 -0.127029)', 4326))
由于您使用的是地理数据,因此请确保多边形与正确的区域匹配以获取正确的数据。您可以使用以下多边形来匹配预期区域:
SELECT geography::STGeomFromText('POLYGON((
-0.199251 51.561283,
-0.197878 51.472407,
-0.045443 51.468985,
-0.045443 51.562136,
-0.199251 51.561283))', 4326
)
现在您可以使用以下解决方案来检查 Point 是否在多边形内:
SELECT geography::STGeomFromText('POLYGON((
-0.199251 51.561283,
-0.197878 51.472407,
-0.045443 51.468985,
-0.045443 51.562136,
-0.199251 51.561283))', 4326
).STIntersects(geography::Point(51.519425, -0.127029, 4326))
【讨论】:
这是以错误的方式解决问题,因为一旦传递给任何这些方法的第二个坐标超过 90 度,它将无法工作 @ImGharavi - 还要检查 Damiens 的答案并确保您的多边形正确。看起来你的多边形是错误的,你必须翻转这些对。如果是这样:接受他的回答。 但请注意(正如我之前的评论所暗示的),只要这两个值都落在更严格的 ±90 度(经度)范围内,这只会大致起作用。在那之后,您不能忽略纬度需要作为第二个参数传递。以上是关于SQL Server 2014 在多边形中找到一个点的主要内容,如果未能解决你的问题,请参考以下文章
如何反转 JSON 多边形顺序以调整 SQL Server 中的环方向