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

SQL Server 的多边形算法中的点

如何创建特定大小的 SQL Server 地理多边形?

SQL Server 不识别多边形

如何反转 JSON 多边形顺序以调整 SQL Server 中的环方向

SQL Server 2016,2014 无法找到数据库引擎启动句柄

完美卸载SQL Server2014数据库