Reputation: 51
does anyone know how to do a query which will allow a user to specify their lat / lng and a radius, and then search what could be a very large amount of locations which also have a lat lng + a radius and see if any overlap, and then allow for sorting by distance?
We've been asked to allow for companies to place markers on a map of suburbs that they operate in, with the ability to do a radius, but I can't find any queries on Google that do this.
I'm currently using the following query which does the job,
(SELECT ( 6371.01 * acos( cos( radians( $lat ) ) * cos( radians( location.lat ) )
cos( radians( location.lng ) - radians( $lng ) )
sin( radians( $lat ) ) * sin( radians( location.lat ) ) ) ) AS distance
FROM location
HAVING distance <= $radius
ORDER BY distance ASC) as distance
But obviously this doesn't allow for the locations to have a radius.
The second part of this question, this search query is already part of a very large query.. are there any recommendations on optimizing this at all? Every time I google'd for examples on queries like the above there was always people warning about how expensive this query is. At the moment the only solution I can think of is to have a separate search server.
Upvotes: 0
Views: 796
Reputation: 17710
Very simple answer: use the spacial geometry functions in mySQL (http://dev.mysql.com/doc/refman/5.5/en/spatial-extensions.html)
These have been around for a while, but got a nice upgrade in 5.6 that will make it easier to do your select. http://www.percona.com/blog/2013/10/21/using-the-new-spatial-functions-in-mysql-5-6-for-geo-enabled-applications/ has some details on it.
If you don't have 5.6 then use a "grid" system. Basically, when you store the point (x,y), you also store a grid identifier (X,Y) that covers a larger square. When searching other points nearby you know it's within grid (X-1 to X+1) and (Y-1 to Y+1); this reduces the number of points you need to search. Then check both the actual difference for x and y are within a square in mySQL, then, once you've reduced it massively, then do your cos/sin maths.
Upvotes: 1