Hay i want to find the distance (in miles) between 2 locations using lat and long values, and check if they are within a 10 mile radius of each other.
When a user lo
Origin point of the latitude and longitude
$orig_lat=23.04988655049843;
$orig_lon= 72.51734018325806;
$dist=10; // Radius;
//Latitude = database field name;
//Longitude = database field name;
$query = SELECT *, 3956 * 2 * ASIN(SQRT( POWER(SIN(($orig_lat -abs(dest.Latitude)) * pi()/180 / 2),2) + COS($orig_lat * pi()/180 ) * COS( abs(dest.Latitude) * pi()/180) * POWER(SIN(($orig_lon - dest.Longitude) * pi()/180 / 2), 2) )) as distance FROM tbl_name dest having distance < 10 ORDER BY distance limit 10
Find all location those are in Radius 10 miles.
Working fine!
You probably don't need to do this in code, you can probably do this all in the DB. if you use a spatial index. MySQL docuemtnation for spatial index
EDIT to reflect your edit:
I think you want something like this:
SELECT *, ((ACOS(SIN($lat * PI() / 180) * SIN(lat * PI() / 180) + COS($lat * PI() / 180) * COS(lat * PI() / 180) * COS(($lon - lon) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance FROM locations HAVING distance<='10' ORDER BY distance ASC
VIA: http://www.zcentric.com/blog/2007/03/calculate_distance_in_mysql_wi.html:
Before your query, calculate the maximum and minimum latitude and longitude of your ten-mile circle. This will give you four numbers so the first part of your where clause will exclude any rows which fall outside of an approximate 10 mile-each way box.
Then the complicated real distance where clause checks only the ones inside the square, to see if they're also inside the circle.
Read your DBMS's docs to see whether lazy evaluation will apply or if you will need to arrange it as
SELECT *
FROM (SELECT *
FROM table
WHERE (simple rough box clause)
)
WHERE (complex clause)
instead of the usual
SELECT * FROM table WHERE (simple clause) AND (complex clause)
Searching in KM: ($LATITUDE
-> Your latitude, $LONGITUDE
-> Your longitude, latitud_fieldname
-> Your latitude database fieldname, longitude_fieldname
-> Your longitude database fieldname)
SELECT * FROM (
SELECT *,
(
(
(
acos(
sin(( $LATITUDE * pi() / 180))
*
sin(( `latitud_fieldname` * pi() / 180)) + cos(( $LATITUDE * pi() /180 ))
*
cos(( `latitud_fieldname` * pi() / 180)) * cos((( $LONGITUDE - `longitude_fieldname`) * pi()/180)))
) * 180/pi()
) * 60 * 1.1515 * 1.609344
)
as distance FROM `myTable`
) myTable
WHERE distance <= $DISTANCE_KILOMETERS;
Searching in Miles:
SELECT * FROM (
SELECT *,
(
(
(
acos(
sin(( $LATITUDE * pi() / 180))
*
sin(( `latitud_fieldname` * pi() / 180)) + cos(( $LATITUDE * pi() /180 ))
*
cos(( `latitud_fieldname` * pi() / 180)) * cos((( $LONGITUDE - `longitude_fieldname`) * pi()/180)))
) * 180/pi()
) * 60 * 1.1515
)
as distance FROM `myTable`
) myTable
WHERE distance <= $DISTANCE_MILES;
For full info, follow the link: https://ourcodeworld.com/articles/read/1019/how-to-find-nearest-locations-from-a-collection-of-coordinates-latitude-and-longitude-with-php-mysql
This should point you in the right direction - no pun intended.
Mysql function to find distance between two places using lat/long
Sometimes we need to find out list of places that are within a certain radius from a center place where coordinates of the places are saved in the database. Now we have 2 solutions for this – either loop through all the places find the distance from the center point and keep the places that have distance less or equal to the radius, or make an sql function to find the distance of two places, and select the places having distance less or equal to the radius. Obviously the second option is better than the first one. So I have written a Mysql function that does the work for you. In my case, the coordinates were saved in the database as a string of the form "10.1357002, 49.9225563, 0". This is the standard format of coordinates that is used by many (for example Google map). The first element is the longitude, second one is latitude and we can ignore the third (always 0). So here is the Mysql function that returns the distance between 2 coordinates in Miles.
DELIMITER $$
DROP FUNCTION IF EXISTS `GetDistance`$$
CREATE FUNCTION `GetDistance`(coordinate1 VARCHAR(120), coordinate2 VARCHAR(120))
RETURNS VARCHAR(120)
BEGIN
DECLARE pos_comma1, pos_comma2 INT;
DECLARE lon1, lon2, lat1, lat2, distance DECIMAL(12,8);
select locate(',', coordinate1) into pos_comma1;
select locate(',', coordinate1, pos_comma1+1) into pos_comma2;
select CAST(substring(coordinate1, 1, pos_comma1-1) as DECIMAL(12,8)) into lon1;
select CAST(substring(coordinate1, pos_comma1+1, pos_comma2-pos_comma1-1) as DECIMAL(12,8)) into lat1;
select locate(',', coordinate2) into pos_comma1;
select locate(',', coordinate2, pos_comma1+1) into pos_comma2;
select CAST(substring(coordinate2, 1, pos_comma1-1) as DECIMAL(12,8)) into lon2;
select CAST(substring(coordinate2, pos_comma1+1, pos_comma2-pos_comma1-1) as DECIMAL(12,8)) into lat2;
select ((ACOS(SIN(lat1 * PI() / 180) * SIN(lat2 * PI() / 180) + COS(lat1 * PI() / 180) * COS(lat2 * PI() / 180) * COS((lon1 - lon2) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) into distance;
RETURN distance;
END$$
DELIMITER ;
Example Usage:
Lets say you have to find out all the postcodes that are in 40 miles radius from a place having coordinate "10.1357002, 49.9225563, 0". You have a table POSTCODES having fields id, postcode, coordinates. So your sql should look like this:
select id, postcode from POSTCODES where GetDistance("10.1357002, 49.9225563, 0", coordinates) <= 40;
I'm just going to leave this here:
https://gist.github.com/899413
it's an example on how to query within a square (BETWEEN) on integers and cut down the results with SQRT() to have the output return a round radius of results. (it also returns the distance in kilometer)
to do this you need to convert all points, when inserting, to kilometers to lay them out on a flat map. (see php functions)
the result is an incredible fast integer lookup - MUCH faster than doing all the calculations within the query like every single answer here states.
(I built this exactly 10 years ago... seems like it's still the smartest solution with mysql)