Reputation: 27185
I just have latitude and longitude of a store, now I want to find out all the stores near by in 1 hour drive or say at 10 KM distance.
I have table as,
Id, storeName, store_lat, store_lng
Say I have selected lat and lng of store 1 and I want to find out all the nearby stores. How to do that using php/mysql.
I have checked many post on SO but when I am running query, it's returning 0 results all the time.
Please help, thanks!
Upvotes: 2
Views: 5192
Reputation: 2466
Assuming you get $lat and $long as latitidue/longitude of your starting point:
$sql = 'SELECT *, (6371 * acos(cos(radians(' . $lat . ')) * cos(radians(latitude)) * cos(radians(longitude) - radians(' . $lng . ')) + sin(radians(' . $lat . ')) * sin(radians(latitude)))) AS distance from table_name WHERE distance < 10';
Upvotes: 4
Reputation: 6346
SELECT * FROM `table` WHERE acos(sin(LATITUDE) * sin(`store_lat`) + cos(LATITUDE) * cos(`store_lat`) * cos(`store_lng` - (LONGITUDE))) * 6371 <= 1000;
Just replace LONGITUDE and LATITUDE.
Distance here is in km - it's currently set to 1000. This can be changed as needed too.
I've used this on a few scripts so far, seems to work pretty well, although can be slow sometimes. The issue I believe is that it can't utilize indices because the WHERE clause is so complex.
Upvotes: 2
Reputation: 93565
One approach is to take your input lat/long pair, create a range, then query for all records that fall in that range:
Distance = 0.1; // Range in degrees (0.1 degrees is close to 11km)
LatN = lat + Distance;
LatS = lat - Distance;
LonE = lon + Distance;
LonW = lon - Distance;
...Query DB with something like the following:
SELECT *
FROM table_name
WHERE
(store_lat BETWEEN LatN AND LatS) AND
(store_lon BETWEEN LonE AND LonW)
The query should find everything where the stored lat is less than LatN and greater than LatS, and where the stored lon is less than LonE and greater than LonW.
You might then do a real distance calcuation for the returned results because the above search gives you a box, and locations in the corner will be greater than 0.1 degrees away, as the crow flies.
Use a map API with directions to get the driving distance, if "as the crow flies" isn't good enough.
Upvotes: 1
Reputation: 2493
function inRange ( $lat1, $lng1, $lat2, $lng2, $range = 100 )
{
return ( 6371 * acos( cos( deg2rad( $lat1 ) ) *
cos( deg2rad( $lat2 ) ) *
cos( deg2rad( $lng2 ) -
deg2rad( $lng1 ) ) +
sin( deg2rad( $lat1 ) ) *
sin( deg2rad( $lat2 ) ) ) ) <= $range;
}
This generates distance. You can convert it to MySQL query.
Upvotes: 0