2012-05-27 17 views
9

Tengo una tabla MySQL en un servicio web PHP que contiene longitud y latitud. Deseo enviar al usuario solo, digamos, 5 coordenadas más cercanas. Escribí el método que calcula una distancia desde las coordenadas a las que el usuario envió en la solicitud POST, pero no estoy seguro de cómo ordenarlo y solo devolver algunas.PHP Ordenando las coordenadas más cercanas

Aquí es el método de la distancia:

function distance($longToCompare,$latToCompare) { 
    $dlong = $request_long - $longToCompare; 
    $dlat = $request_lat - $latToCompare; 
    $a = pow(sin($dlat/2)) + cos($latToCompare)*cos($request_lat)*pow(sin($dlong/2)); 
    $c = 2*atan2(sqrt($a),sqrt(1-$a)); 
    return 6373*$c; 
} 

y actualmente el usuario obtiene toda la base de datos (por ahora, mientras que el desarrollo es pequeño, pero en el futuro podría ser bastante grande)

$q = mysql_query("SELECT * FROM Coordinates"); 
$coordinates = array(); 
while ($e = mysql_fetch_assoc($q)) { 
    $coordinates[] = $e; 
} 
print (json_encode($coordinates)); 

¿Alguien puede indicarme la dirección correcta? Soy bastante nuevo en PHP, sé que puedo crear una clasificación personalizada usando uasort, pero no estoy muy seguro de cómo usarlo usando esta función de distancia.

EDIT: Utilizando la solución @Norse 's, la consulta actual es:

$request_long = $_POST['longitude']; 
$request_lat = $_POST['latitude']; 
    $km = 0.5; 
     $query = "SELECT *, 
    (6373 * acos(cos(radians('$request_lat')) * 
    cos(radians(latitude)) * 
    cos(radians(longitude) - 
    radians('$request_long')) + 
    sin(radians('$request_lat')) * 
    sin(radians(latitude)))) 
    AS distance FROM Coordinates HAVING distance < '$km' ORDER BY distance ASC LIMIT 0, 5"; 
     $coordinates = array(); 
     while ($e = mysql_fetch_assoc($query)) { 
      $coordinates[] = $e; 
     } 
     print (json_encode($coordinates)); 
+0

¿Ha considerado escribir la función mysql y usarla en la consulta SQL? – WojtekT

+0

soy bastante nuevo en todo esto de DB. ¿puedes por favor elaborar? –

+0

¿es para plataforma Junaio AR? – HamZa

Respuesta

22

Usando el algoritmo de Google:

$lon = //your longitude 
$lat = //your latitude 
$miles = //your search radius 

$query = "SELECT *, 
(3959 * acos(cos(radians('$lat')) * 
cos(radians(latitude)) * 
cos(radians(longitude) - 
radians('$lon')) + 
sin(radians('$lat')) * 
sin(radians(latitude)))) 
AS distance FROM yourtable HAVING distance < '$miles' ORDER BY distance ASC LIMIT 0, 5" 

latitude y longitude en esta consulta va a ser su lat/nombres de columna lon.

+0

Gracias, Recibo un error: mysql_fetch_assoc(): el argumento proporcionado no es un resultado válido de MySQL $ lon y $ lat se reciben del GPS de un dispositivo, en la forma de 35.21371 por ejemplo –

+0

Hmm. No veo de dónde vendría el error. Acabo de ejecutar esta consulta nuevamente para estar seguro y funcionó bien para mí. – Norse

+0

Editado la pregunta para incluir el código actual. ¿Puedes verificar si hay problemas? –

3

que he encontrado últimamente mismo problema. Lo que he decidido es escribir una función mysql para calcular la distancia y luego usarla en la consulta SQL. función de MySQL:

CREATE FUNCTION distance(lat1 float, lon1 float, lat2 float, lon2 float) 
RETURNS float 
RETURN ACOS(SIN(RADIANS(lat1))*SIN(RADIANS(lat2))+COS(RADIANS(lat1))*COS(RADIANS(lat2))*COS(RADIANS(lon2-lon1)))*6371 

Si la tabla tiene columnas Coordinates F. E. latitude y longitude continuación, el código podría tener este aspecto:

$q = mysql_query("SELECT * FROM Coordinates ORDER BY 
    distance(latitude, longitude, $lat, $lon) LIMIT 5"; 

Dónde $lat y $lon contienen proporcionan ubicación.

+0

¿Dónde va CREATE FUNCTION? dentro del script PHP, o usando la consulta dentro de la administración de MySQL? –

+1

Tienes que ejecutar eso una vez usando cualquier herramienta que uses para administrar la base de datos mysql. – WojtekT

+0

Gracias, me sale un error que se niega el acceso cuando se utiliza el método dentro de SQLBuddy. –

Cuestiones relacionadas