Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to measure distance using Haversine formula with MySQL?

I get Latitude and Longitudes from Google Maps Reverse-Geocoding API and then I need something like this:

mysql_query("SELECT users.*, ".mysql_distance_column($lat,$lng)." FROM users ORDER BY DISTANCE";

function mysql_distance_column($lat=40 , $lng=-73) {

   $defaultLatitudeColumn = 'user_lat'; 
   $defaultLongitudeColumn='user_lng';
   $defaultColumnName='user_distance';
    return  "(( 
(3956 * 2 * ASIN(SQRT( POWER(SIN(({$lat} - abs({$defaultLatitudeColumn})) 
* pi()/180 / 2), 2) + COS({$lat} * pi()/180 ) 
* COS(abs({$defaultLatitudeColumn}) * pi()/180) 
* POWER(SIN(({$lng} - {$defaultLongitudeColumn}) * pi()/180 / 2), 2) ))
 )) ) as {$defaultColumnName} ";

}

UPDATE I cant ge this to work

delimiter //
CREATE FUNCTION `GeoDistMiles`( lat1 FLOAT (10,6), lon1 FLOAT (10,6), lat2 FLOAT (10,6), lon2 FLOAT (10,6) ) 
RETURNS FLOAT 
DETERMINISTIC 
NO SQL
BEGIN
  DECLARE pi, q1, q2, q3 FLOAT (10,6);
  DECLARE rads FLOAT (10,6) DEFAULT 0;
  SET pi = PI();
  SET lat1 = lat1 * pi / 180;
  SET lon1 = lon1 * pi / 180;
  SET lat2 = lat2 * pi / 180;
  SET lon2 = lon2 * pi / 180;
  SET q1 = COS(lon1-lon2);
  SET q2 = COS(lat1-lat2);
  SET q3 = COS(lat1+lat2);
  SET rads = ACOS( 0.5*((1.0+q1)*q2 - (1.0-q1)*q3) );
  RETURN 3963.346 * rads;
END
like image 426
Neo Avatar asked Feb 02 '11 18:02

Neo


1 Answers

Here is the formula I use. Remember that the Earth is not a perfect sphere, so the results will never be perfect.

CREATE DEFINER=`root`@`localhost` FUNCTION `GeoDistMiles`( lat1 FLOAT, lon1 FLOAT, lat2 FLOAT, lon2 FLOAT ) RETURNS float
BEGIN
  DECLARE pi, q1, q2, q3 FLOAT;
  DECLARE rads FLOAT DEFAULT 0;
  SET pi = PI();
  SET lat1 = lat1 * pi / 180;
  SET lon1 = lon1 * pi / 180;
  SET lat2 = lat2 * pi / 180;
  SET lon2 = lon2 * pi / 180;
  SET q1 = COS(lon1-lon2);
  SET q2 = COS(lat1-lat2);
  SET q3 = COS(lat1+lat2);
  SET rads = ACOS( 0.5*((1.0+q1)*q2 - (1.0-q1)*q3) );
  RETURN 3963.346 * rads;
END
like image 161
anon Avatar answered Sep 24 '22 18:09

anon