SQL Server 2014 在多边形中找到一个点

SQL Server 2014 find a point in polygon

我不知道为什么 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 显示多边形的正确方向上:

通过 Google 地图,我的点也位于多边形的中心:

以下是我用来检测我的观点是否正确的工具: 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

奇怪的是,当我将纬度和经度更改为 geography::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))

您必须翻转 geography::Point 上的值,因为第一个值是经度,第二个值是纬度:

The Point type for geography data type represents a single location where x and y represent longitude and latitude values respectively.

source: 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
)

现在您可以使用以下解决方案来检查点是否在多边形内:

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))

Geometry/Geography 的文本字符串表示始终使用 X Y 约定来指定坐标。这意味着,当解释为地理时,它违背了将纬度放在首位的通常惯例。

因此您需要使用 Long Lat 在字符串中指定您的 POLYGON

您可以在 SSMS 输出中看到这一点,您可以在其中看到多边形位于赤道以南,东 51° 左右,而不是伦敦的某个地方。