radius search with google maps and mysql

Let’s say you’re building a wepapp and you want to give your users the ability to do a radius search for something (e.g. gas stations) in a specific location. On top of that you want your users to provide your app with new gas stations anywhere. First of all you obviously need some kind of form users can post new gas stations to. This step is easy: get the latitude and longitude of the gas station and save it with all other relevant information (e.g. name, address etc.) to your database. The way to do this is Google Maps. Get an api key from Google for your domain and you’re good to go. Now, whenever a user submits a new gas station, you get the coordinates by giving Google the address your user submitted. Here’s how you do that:

$handle = fopen("http://maps.google.com/maps/geo?q=".urlencode($q)."&sensor=false&oe=utf8&gl=en&output=csv&key=".$api_key,"r");
$data = fgetcsv($handle);

where $q is your query (the address of the gas station)  and $api_key your Google Maps Api-Key. Now you have in $data[1] your latitude and in $data[2] your longitude. Additionally Google provides you with an accuracy for your search in $data[0]. I strongly recommend using this detail. For more information go to the Maps Api Reference. That’s it, you now got your coordinates and should save them to your database.

radius search with mysql

Now comes the search part. It’s not tricky at all, a little math will do the thing. First of all you need a search form. When the form is submitted you should begin with once again querying Google maps for the coordinates your user submitted in the search form. This step is easy, since it is the same as above (and this time you should really consider using the accuracy Google gives you back!!!).

Now that you have the coordinates of the searchers position, you query your database for any gas stations in the circumference of the given coordinates. I’ll do it within a range of ten kilometers, but this is of course at your choice (better: at your user’s choice). Let’s say you have a table called `stations`, with a primary key called `id` and the station’s `name`, additionaly the coordinates are saved in `latitude` and `longitude`. Here’s how you do your query:

SELECT
`id`,
`name`,
ACOS( SIN( RADIANS( `latitude` ) ) * SIN( RADIANS( $fLat ) ) + COS( RADIANS( `latitude` ) )
* COS( RADIANS( $fLat )) * COS( RADIANS( `longitude` ) - RADIANS( $fLon )) ) * 6380 AS `distance`
FROM `stations`
WHERE
ACOS( SIN( RADIANS( `latitude` ) ) * SIN( RADIANS( $fLat ) ) + COS( RADIANS( `latitude` ) )
* COS( RADIANS( $fLat )) * COS( RADIANS( `longitude` ) - RADIANS( $fLon )) ) * 6380 < 10
ORDER BY `distance`

where $fLat is the searchers latitude and $fLon the searchers longitude. The ten in the where clause is the range you want to search within. Remember: This search is based on kilometers. If you want to search in miles, you need to change the 6380 (whoch is our earths radius) to its respective value in miles. That’s it! You now got your result set with all stations in the ambit of ten kilometers.


Posted

in

by

Comments

4 responses to “radius search with google maps and mysql”

  1. Ravi Avatar
    Ravi

    This is very very informative and very useful to find the address with in the radius.

    I was looking for the similar article or help for my next assignment.

    Please keep spreading knowledge.

    Thanks again.

  2. Franz Avatar
    Franz

    Thank you so much for this magical query !!
    Exactly what i was looking for, unsuccessfuly…

  3. Steven Shi Avatar
    Steven Shi

    This is very helpful. Thank you!

  4. Fabio Teixeira Avatar
    Fabio Teixeira

    Endeed a magical query! What if I want to search an address in a route. How do I do that?
    I have to design a web app that enables users to save as many routes as they need. Once saved, given an random address, I need to know whether this address is within any route of any user.

    I need some serious assistance on that so any help will be really appreciated.

Leave a Reply

Your email address will not be published. Required fields are marked *