简体   繁体   English

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

[英]SQL Server 2014 find a point in polygon

I do not know why SQL does not detect this point in my 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))

My polygon is valid in result of STIsValid() and also is in right direction which SSMS display the polygon:我的多边形在STIsValid()的结果中有效,并且在 SSMS 显示多边形的正确方向上:

多边形的 SSMS 结果

My point is also located in center of the polygon via Google Maps:我的点也通过谷歌地图位于多边形的中心:

谷歌地图结果

Here is the tools I used to detect if my points are correct: https://www.doogal.co.uk/polylines.php这是我用来检测我的观点是否正确的工具: https://www.doogal.co.uk/polylines.php

With these data in text input:在文本输入中使用这些数据:

51.561283,-0.199251
51.562136,-0.045443
51.468985,-0.045443
51.472407,-0.197878
51.561283,-0.199251
51.519425,-0.127029

The strange thing is that when I change lat and long to geography::Point function the result is true.奇怪的是,当我将 lat 和 long 更改为geography::Point function 结果是真的。

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

The Text string representations of Geometry/Geography always uses the XY convention for specifying coordinates. Geometry/Geography 的文本字符串表示始终使用XY约定来指定坐标。 This means, when interpreted as geography, it defies the usual convention of putting Latitude first.这意味着,当解释为地理时,它违反了将纬度放在首位的通常惯例。

So you need to use Long Lat in specifying your POLYGON in a string.因此,您需要使用Long Lat在字符串中指定您的POLYGON

You can see this in your SSMS output, where you can see that the polygon is located just south of the equator, somewhere ~51° East, and not somewhere in London.您可以在 SSMS output 中看到这一点,您可以在其中看到多边形位于赤道以南,东约 51° 的某个地方,而不是伦敦的某个地方。

You have to flip the values on the geography::Point since the first value is the longitude and the second value is the latitude:您必须翻转geography::Point上的值,因为第一个值是经度,第二个值是纬度:

The Point type for geography data type represents a single location where x and y represent longitude and latitude values respectively.地理数据类型的点类型表示单个位置,其中 x 和 y 分别表示经度和纬度值。

source: https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/bb964737(v=sql.105)来源: https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/bb964737(v=sql.105)

See the following comparison between using the Point data type directly or getting the Point object with geometry::STGeomFromText .请参阅以下直接使用Point数据类型或使用geometry::STGeomFromText STGeomFromText 获取Point object 之间的比较。 The order of langitude and longitude is different .经度和经度的顺序不同

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

So you have two possibilities to solve this:所以你有两种可能来解决这个问题:

1. flip the values of the Point : 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. specify the Point using text: 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))

Since you are working with geographical data, make sure the polygon matches the correct area to get the correct data.由于您使用的是地理数据,因此请确保多边形与正确的区域匹配以获取正确的数据。 You can use the following polygon to match the expected area:您可以使用以下多边形来匹配预期区域:

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
)

Now you can use the following solution to check if the Point is inside the polygon:现在您可以使用以下解决方案来检查点是否在多边形内:

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

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

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