Рассчитать расстояние между двумя географическими точками на сервере sql - PullRequest
0 голосов
/ 28 февраля 2019

Я пытаюсь вычислить расстояние от одной точки до другой точки (многоугольник / многоугольник), используя следующий запрос в SQL Server.

DECLARE @g geometry;  
DECLARE @h geometry;  
SET @g = geometry::STGeomFromText('POLYGON ((139.999722222222 40.0513888888889, 141.401111111111 40.0513888888889, 141.398333333333 39.3494444444444, 140.765 38.1005555555556, 140.766111111111 37.3333333333333, 140.314722222222 36.8161111111111, 140.316111111111 36.2841666666667, 139.050277777778 36.2847222222222, 139.049444444444 35.1669444444444, 138.499444444444 35.1669444444444, 138.499444444444 35.5852777777778, 136.816944444444 35.5830555555556, 136.034166666667 34.8980555555556, 135.732222222222 34.8997222222222, 135.732222222222 35.3827777777778, 136.431944444444 35.8013888888889, 137.365 36.5341666666667, 138.165555555556 36.9333333333333, 139.415 37.8152777777778, 140.285833333333 39.4497222222222, 140.285833333333 39.8652777777778, 139.915555555556 39.8652777777778, 139.915555555556 39.9669444444444, 139.999722222222 40.0513888888889))', 4326);
SET @h = geometry::STGeomFromText('POINT(-1.9335937499142 53.956085529457)', 4326);  
SELECT @g.STDistance(@h)/1609.344 as DistanceInMiles,@h.STDistance(@g) as DistanceInMeters

Следующие координаты в Великобритании,

ТОЧКА (-1.9335937499142 53.956085529457)

Координаты полигона находятся в Японии.Каким-то образом, когда я запускаю запрос, полученное расстояние неверно.

Вы можете проверить результат в следующей скрипте БД:

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=d6f4e3cbfa8d836c24006f6005eefc4b

Не уверен, правильно ли яя делаю что-то не так?

1 Ответ

0 голосов
/ 28 февраля 2019

У вас есть 2 вопроса здесь.Первый не работает с типами данных GEOGRAPHY и вместо этого работает с GEOMETRY, когда вы на самом деле работаете с GPS-координатами.География рассмотрит форму Земли и вернет более точные значения для этого сценария.

Вторая и самая большая проблема - это ориентация кольца вашего многоугольника Японии.Порядок расположения координат на жестко закодированной строке очень важен для определения результирующего многоугольника.Иногда SQL Server не может правильно определить, какую сторону ребер между нашими точками мы на самом деле обозначаем как многоугольник.

Это можно исправить с помощью очень аккуратного трюка, выполнив STUnion с представлением GEOMETRYодного и того же многоугольника:

DECLARE @g_metry GEOMETRY = GEOMETRY::STGeomFromText('POLYGON ((139.999722222222 40.0513888888889, 141.401111111111 40.0513888888889, 141.398333333333 39.3494444444444, 140.765 38.1005555555556, 140.766111111111 37.3333333333333, 140.314722222222 36.8161111111111, 140.316111111111 36.2841666666667, 139.050277777778 36.2847222222222, 139.049444444444 35.1669444444444, 138.499444444444 35.1669444444444, 138.499444444444 35.5852777777778, 136.816944444444 35.5830555555556, 136.034166666667 34.8980555555556, 135.732222222222 34.8997222222222, 135.732222222222 35.3827777777778, 136.431944444444 35.8013888888889, 137.365 36.5341666666667, 138.165555555556 36.9333333333333, 139.415 37.8152777777778, 140.285833333333 39.4497222222222, 140.285833333333 39.8652777777778, 139.915555555556 39.8652777777778, 139.915555555556 39.9669444444444, 139.999722222222 40.0513888888889))', 4326);

DECLARE @g GEOGRAPHY = @g_metry.MakeValid().STUnion(@g_metry.STStartPoint()).STAsText()

DECLARE @h GEOGRAPHY = GEOGRAPHY::STGeomFromText('POINT(-1.9335937499142 53.956085529457)', 4326); 

SELECT 
    @g.STDistance(@h)/1609.344 as DistanceInMiles,
    @h.STDistance(@g) as DistanceInMeters

Результат:

DistanceInMiles     DistanceInMeters
5574.53292757983    8971341.11980304

![enter image description here

Для дальнейшего чтения вы можете прочитать thisсообщение в блоге .

...