SQL Сервер 2014 найти точку в многоугольнике - PullRequest
0 голосов
/ 05 августа 2020

Я не знаю, почему 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 отображает многоугольник:

SSMS result of polygon

My point is also located in center of the polygon via Google Maps:

google map result

Here is the tools I used to detect if my points are correct: 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, результат будет истинным.

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 ]

1 голос
/ 05 августа 2020

Текстовые строковые представления Geometry / Geography всегда используют соглашение X Y для указания координат. Это означает, что при интерпретации как география это противоречит обычному соглашению о размещении Latitude на первом месте.

Поэтому вам нужно использовать Long Lat при указании POLYGON в строке.

Вы можете см. это в выходных данных SSMS, где можно увидеть, что многоугольник расположен к югу от экватора, где-то на ~ 51 ° восточной долготы, а не где-то в Лондоне.

0 голосов
/ 05 августа 2020

Вы должны перевернуть значения на geography::Point, так как первое значение - это долгота, а второе значение - широта:

Тип Point для типа данных geography представляет одно местоположение, где x и y представляют значения долготы и широты соответственно.

источник: https://docs.microsoft.com/en-us/previous-versions/sql/sql-server-2008-r2/bb964737 (v = sql .105)

См. Следующее сравнение между использованием типа данных Point напрямую или получением объекта Point с geometry::STGeomFromText. Порядок долготы и долготы различается .

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