Найти ближайшее местоположение, используя долготу и широту по linq из базы данных - PullRequest
0 голосов
/ 31 октября 2019

Мне нужно получить местоположение поблизости, используя (долгота, широта)

У меня есть таблица, где местоположения сохраняются в базе данных с полями долготы и широты,

Я хочу получить ближайшеелокации, и у меня есть Sql-код и я хочу преобразовать его в linq, где я использую ASP.Net MVC5. Вот мой код:

SELECT Name, ( 3959 * acos( cos( radians(24.743055) ) * cos( radians( 
latitude ) ) * 
cos( radians( longitude ) - radians(46.669702) ) + sin( radians(24.743055)  
)* 
sin( radians( latitude ) ) ) ) AS distance 
FROM Event
ORDER BY distance

Я написал его в linq следующим образом:

double startlat = Convert.ToDouble(db.Users.Where(u => u.Id == 2).Select(u 
=> u.latitude).Single());


double startlng = Convert.ToDouble(db.Users.Where(u => u.Id == 2).Select(u 
=> u.longitude).Single());


var c = (from ev in db.Event
where (3959 * Math.Acos(Math.Cos((Math.PI * startlat / 180.0)) * 
Math.Cos(Math.PI * (Convert.ToDouble(ev.latitude)) / 180.0) *
Math.Cos((Math.PI * (Convert.ToDouble(ev.longitude)) / 180.0) - (Math.PI * 
(startlng) / 180.0)) + Math.Sin(Math.PI * (startlat) / 180.0)) *
Math.Sin(Math.PI * (Convert.ToDouble(ev.latitude) ) / 180.0) ) < 2500
select ev.Name).ToList();

но я получаю эту ошибку:

LINQ to Entities does not recognize the method 'Double Acos(Double)' 
method, and this method cannot be translated into a store expression.

Я пытался использовать "public static double ToRadians" и передавать значение, но это не сработало, потому что это static

Есть идеи?

1 Ответ

0 голосов
/ 31 октября 2019

Во-первых, вы должны получить данные о местоположении вашего пользователя одним ударом:

var startCoords = db.Users.Where(u => u.Id == 2).Select(u 
=> new { u.latitude, u.longitude }).Single();

Чтобы получить наиболее близкое местоположение, можно ли это упростить для суммирования дельты X и Y и получения наименьшей общей дельты?

var closestEvent = db.Event.Select(x => new { x.EventId, delta = Math.Abs(x.latitude - startCoords.latitude) + Math.Abs(x.longitude - startCoords.longitude)})
.OrderBy(x => x.delta)
.FirstOrDefault();

Это может быть чрезмерным упрощением, но, учитывая координаты X, Y, сравнение суммы абсолютной разницы даст вам приблизительное ранжирование по прямой линии. Если требуется более подробная формула или вы хотите передать их в нечто вроде Google Планета Земля для дорожной проверки или другого поиска пути, грубая проверка может вернуть в память примерно 10 событий или координаты, где может быть проведена более подробная проверка. работать против них, не беспокоясь о проблемах с преобразованием SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...