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

Я пытаюсь выполнить геопространственный поиск в 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, я получаю 0 рад .

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

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

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

 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 

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

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