2012-06-26 30 views
5

Tengo problemas para intentar devolver la ubicación más cercana al usuario a través de una declaración SQL. Para probar que estoy usando las mismas coordenadas exactas, esto es lo que tengo:Medir la distancia entre dos puntos Lat/Lng

SQL:

SELECT `companies`.`customerName` , 
    (3959 * 
     ACOS(
      COS(
       RADIANS(37.367485) * COS(RADIANS(`locations`.`gps_lat`)) * 
       COS(
        RADIANS(`locations`.`gps_lng`) - RADIANS(-77.399994) + 
        SIN(RADIANS(37.367485)) * SIN(RADIANS(`locations`.`gps_lat`)) 
       ) 
      ) 
     ) 
    ) 
AS `distance` 
FROM `locations` 
JOIN `companies` ON `locations`.`co_id` 
HAVING `distance` > 25 
ORDER BY distance 
LIMIT 0 , 10 

Resultados:

| customerName | distance   | 
| SOME COMPANY | 1914.41747964854 | 


locationsvalores de la tabla :

gps_lat | gps_lng 
37.367485 | -77.399994 


he utilizado el ejemplo de Google, he comprobado la fórmula un par de veces y me parece que no puede llegar a que hice mal. Cualquier ayuda es apreciada.


EDIT:
Dado que parece que hay cierta confusión en mí saber lo que estoy haciendo:

El > fue sustituido para producir un resultado, 1914 es obviamente mayor que 25.

La aplicación de esto es pasar las coordenadas del usuario de una aplicación de Android a nuestro servidor web. La Latitud y la Longitud se extraerán de los valores $_GET y se realizarán referencias cruzadas de las empresas en nuestra base de datos MYSQL de servidores web.

La sintaxis anterior es solo yo para verificar mi declaración de SQL en Mysql Workbench. Obviamente estoy buscando un resultado de valor cero.

+3

Si desea que el más cercano, ¿por qué se restringe a "distancia > 25 "? –

+0

Sí lo hice, devolvió cero resultados. Tenga en cuenta la distancia que me dio por encima de – jnthnjns

+2

Dependiendo de qué RDBMS esté utilizando, puede haber formas considerablemente más simples (y más rápidas) de hacerlo. Ejemplo: [MySQL] (http://dev.mysql.com/doc/refman/5.0/en/spatial-extensions.html), [SQL Server] (http://msdn.microsoft.com/en-us/ library/bb933876% 28v = sql.105% 29.aspx), [PostgreSQL] (http://postgis.refractions.net/). –

Respuesta

5

Creo que he resuelto este problema cambiando el ejemplo de Google a la fórmula proporcionada por "Aventuras de un yooper adoptado". Usando su versión del Haversine Formula.
Nota: El ejemplo de Google anterior también usa Haversine.

SQL:

SELECT `companies`.`customerName` , 
(2 * (3959 * ATAN2(
      SQRT(
      POWER(SIN((RADIANS(37.367485 - `locations`.`gps_lat`))/2), 2) + 
      COS(RADIANS(`locations`.`gps_lat`)) * 
      COS(RADIANS(37.367485)) * 
      POWER(SIN((RADIANS(-77.399994 - `locations`.`gps_lng`))/2), 2) 
     ), 
      SQRT(1-(
      POWER(SIN((RADIANS(37.367485 - `locations`.`gps_lat`))/2), 2) + 
      COS(RADIANS(`locations`.`gps_lat`)) * 
      COS(RADIANS(37.367485)) * 
      POWER(SIN((RADIANS(-77.399994 - `locations`.`gps_lng`))/2), 2) 
     )) 
     ) 
    )) 
AS 'distance' 
FROM `locations` 
JOIN `companies` ON `locations`.`co_id` 
HAVING distance < 25 
ORDER BY distance 
LIMIT 0 , 10 



Para los curiosos en mi solicitud, Final PHP:

GET Valor: ?lat=37.367485&lng=-77.399994

$earth_radius_miles = 3959; // Earth radius in miles 
$earth_radius_kilometers = 6371; // Earth radius in kilometers 
$result_radius = 10000; // Maximum distance in either miles or kilometers 

$get_lat = $_GET["lat"]; 
$get_lng = $_GET["lng"]; 

$dbSelect = mysql_query("SELECT `companies`.`customerName`, 
(2 * (".$earth_radius_miles." * ATAN2(
      SQRT(
      POWER(SIN((RADIANS(".$get_lat." - `locations`.`gps_lat`))/2), 2) + 
      COS(RADIANS(`locations`.`gps_lat`)) * 
      COS(RADIANS(".$get_lat.")) * 
      POWER(SIN((RADIANS(".$get_lng." - `locations`.`gps_lng`))/2), 2) 
     ), 
      SQRT(1-(
      POWER(SIN((RADIANS(".$get_lat." - `locations`.`gps_lat`))/2), 2) + 
      COS(RADIANS(`locations`.`gps_lat`)) * 
      COS(RADIANS(".$get_lat.")) * 
      POWER(SIN((RADIANS(".$get_lng." - `locations`.`gps_lng`))/2), 2) 
     )) 
     ) 
    )) 
AS 'distance' 
FROM `locations` 
JOIN `companies` ON `locations`.`co_id` 
HAVING distance < ".$result_radius." 
ORDER BY distance 
LIMIT 0 , 10") 
or die(mysql_error()); 

Resultados:

[{"customerName":"SOME COMPANY","distance":"0"}] 

he probado estos resultados con otras coordenadas y parece estar funcionando perfectamente.No he probado nada con gran distancia entre los dos puntos, pero mi aplicación no requiere que lo haga.

+1

No se puede validar, pero +1 para la presentación – Smandoli

1

Ashok, se puede calcular la distancia entre dos cordinates utilizando la siguiente fórmula:

enter image description here

donde

R = radius of the earth (6,371 km) 
Δlat = |lat2- lat1| 
Δlong = |long2- long1| 
Cuestiones relacionadas