Географический поиск MySQL с использованием формулы haversine возвращает ноль в той же точке

Я пытаюсь реализовать геопространственный поиск в приложении PHP. В настоящее время я использую следующий запрос, чтобы найти точки в пределах 10 км от заданной широты и долготы:

SELECT * FROM (
SELECT *,
(6378.1 * ACOS(
COS(RADIANS(48.856614)) * COS(RADIANS(latitude))
* COS(RADIANS(2.3522219) - RADIANS(longitude))
+ SIN(RADIANS(48.856614))
* SIN(RADIANS(latitude)))
) AS distance
FROM `destinations_info`
WHERE latitude BETWEEN 48.856614  - (10 / 69)
AND 48.856614  + (10 / 69)
AND longitude BETWEEN 2.3522219 - (10 / (69 * COS(RADIANS(48.856614))))
AND 2.3522219 + (10 / (69 * COS(RADIANS(48.856614))))
) d
WHERE distance <= 10
LIMIT 1

Это прекрасно работает, пока я не ищу точную широту и долготу, которые хранятся в таблице POI.

Так, например, если у меня есть в моей таблице poi следующую запись

id     name     latitude    longitude
1      Paris    48.856614   2.3522219000000177

И я называю запрос с lat = 48.856614 а также long = 2.3522219000000177 Я не получу никаких результатов. Насколько я вижу, это происходит потому, что следующая операция возвращает NULL, а не 0 в MySQL:

SELECT (6378.1 * acos(cos(radians(48.856614)) * cos(radians(48.856614)) * cos( radians(2.3522219) - radians(2.3522219)) + sin(radians(48.856614)) * sin(radians(48.856614))))

Запуск того же в Chrome Calculator Я получаю 0 рад.

Что-то не так в запросе или мне нужно включить результаты NULL, используя «OR IS NULL»

2

Решение

IFNULL (…), 0) AS Distance также поможет вам обойти ошибку.

3

Другие решения

Проблема в том, что экоса вызывается со значением, которое не находится в диапазоне -1 и 1, поэтому он возвращает ноль.

SELECT cos(radians(48.856614)) * cos(radians(48.856614)) * cos( radians(2.3522219) - radians(2.3522219)) + sin(radians(48.856614)) * sin(radians(48.856614))

1.0000000000000002

Кажется, это какая-то проблема округления.

Поскольку дуга cos определена только в диапазоне от -1 до 1, вам, вероятно, следует предварительно проверить ее параметр или быть готовым к тому, что он может вернуть ноль, если что-то не так с расчетом.

1

По вопросам рекламы [email protected]