I am developing a PHP application which works with a set of locations provided via Latitude, Longitude-Coordinates in a MySQL-Table. As those locations are imported via external sources, I wanna provide a "merge"-view to the user where they can see groups of locations that are within X meters of each other and merge them into one.
The problem of implementing proximity search has been discussed a lot, for example:
- Fastest Way to Find Distance Between Two Lat/Long Points
- PHP / MySQL - Find all items in 500 meters radius from actual gps coordinates
Most of them use the standard haversine formula to calculate distances:
SELECT
-- stuff here
, ( 6371000 * acos( cos( radians($LAT) ) * cos( radians( stuff.lat ) ) * cos( radians( stuff.lng ) - radians($LNG) ) + sin( radians($LAT) ) * sin(radians(stuff.lat)) ) ) AS distance
FROM
stuff
HAVING
distance < $distance
However this only works if I have one point to search around, but I wanna find ALL groups of locations, that are within X meters to each other.
My simple solution would be to fetch all locations to PHP-code, then iterate over them and use above query to find all nearby locations for each location. Afterwards I clean duplicate groups. But this solution has a cost of n², because I create n queries that need to calculate the distance to all other locations. The second part might be improved with a bounding box, however I still need to execute n queries (to get all nearby locations for each location).
Is there a more performant method? Maybe even inside one MySQL Query (to just output the ids of the locations per group)?
The table with the locations is just 'id', 'name', 'lat' and 'lng'.