NetTopologySuite Distance возвращает странные результаты в .net Core 3

В моем .Net Core 3 API я установил местоположение пользователя следующим образом:

userDetails.Location = new Point(userDetails.latitude, userDetails.longitude)
{
   SRID = 4326
};

и когда я пытаюсь получить пользователей в заданном радиусе

double radiusMeters = userSettings.Radius;
var usersWithinRadius = Context.UserDetails.Where(ud => ud.Location.Distance(userDetails.Location) <= radiusMeters).ToList();

Когда я устанавливаю радиус на 75000 метров, например, с местоположением пользователя (32.600248, 35.1225), он возвращает точку на расстоянии более 90 км (31.78562, 35.115335)

Что я делаю не так?


person Zion Hai    schedule 13.10.2019    source источник


Ответы (1)


он возвращает точку на расстоянии более 90 км

Обратите внимание, что вы передаете аргументы широта и долгота, единицами измерения которых являются градусы. В результате возвращаемое значение не является длиной в метрах. Как вы можете обнаружить, расстояние между (35.1225, 32.600248) и (35.115335,31.78562), возвращаемое методом Distance(), равно 0.81465950900299355. В основном это равно:

Math.sqrt((35.1225 -35.115335)*(35.1225 -35.115335) + (32.600248 - 31.78562)*(32.600248 - 31.78562))

Если две точки достаточно близки, вы можете грубо рассматривать их единицу измерения как Градус дуги:

введите здесь описание изображения

Предполагая, что Земля является идеальной сферой и окружностью Земли это 40,075.017 km.

Согласно насколько далеко один градус:

длина дуги

мы можем приблизительно рассчитать расстояние, как показано ниже:

distance = Circumference * d /360 
    = 40,075.017 km * 0.81465950900299355 / 360 
    = 90.69km

Поскольку условие Where() 0.81465950900299355 < 75000 равно true, вы получите точку, расстояние которой превышает 90 км.

Обратите внимание, что мы предполагаем, что две точки здесь достаточно близки. Чтобы рассчитать точное расстояние, нам нужно преобразовать координату (lon,lat) в систему координат проекции, прежде чем мы вызовем метод Distance().

Цитата из Пространственные данные — EF Core

Это означает, что если вы укажете координаты в терминах долготы и широты, некоторые оцениваемые клиентом значения, такие как расстояние, длина и площадь, будут в градусах, а не в метрах. Для получения более значимых значений сначала необходимо спроецировать координаты в другую систему координат с помощью библиотеки, такой как ProjNet4GeoAPI, прежде чем вычислять эти значения.

person itminus    schedule 14.10.2019
comment
Спасибо за объяснение, но: поскольку условие Where () 0,81465950900299355 ‹ 75000 верно. Да, но тогда он также вернет другие, более удаленные точки, а это не так. Мне пришлось увеличить радиус, чтобы добраться до точек, которые находятся на расстоянии 92, 93 км. - person Zion Hai; 14.10.2019
comment
@ZionHai Вышеупомянутый способ - это грубый способ приблизительно оценить расстояние, когда две точки достаточно близки. Он не используется для расчета точного расстояния. Спроецируйте координату (lon,lat) в систему координат проекции (PCS) перед вызовом метода .Distance(). - person itminus; 15.10.2019