MySQL geospacial search using haversine formula returns null on same point

匿名 (未验证) 提交于 2019-12-03 10:10:24

问题:

I'm trying to implement a geospacial search in a php application. Currently, I'm using the following query to find points within 10km of a given latitude and longitude:

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

This works fine as long I don't search for the exact latitude and longitude that is stored into the POI's table.

So for example if I have in my poi table the following entry

id     name     latitude    longitude 1      Paris    48.856614   2.3522219000000177

And I call the query with lat = 48.856614 and long = 2.3522219000000177 I won't get any results. As far as I see this happens because the following operation returns NULL and not 0 in 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)))) 

Running the same in Chrome Calculator I get 0 rad.

Is there something wrong in the query or do I need to include the NULL results as well using "OR IS NULL"

回答1:

IFNULL( ... ),0) AS Distance will also help you to get around the error.



回答2:

The problem is that acos is invoked with a value which is not in the range of -1 and 1, so it returns 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

It seems to be some sort of rounding issue.

Since, arc cos is defined only between -1 and 1, you probably should pre-check its parameter or be prepared that it can return null if something is wrong with the calculation.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!