2012-03-06 19 views
8

que tienen una longitud y latitud como una cadena en PHP, como a continuación¿Encontrar la longitud y la latitud más cercanas en el conjunto?

49.648881 
-103.575312 

y quiero tomar ese y mirar en una matriz de valores para encontrar la más cercana. La matriz se ve como

array(
'0'=>array('item1','otheritem1details....','55.645645','-42.5323'), 
'1'=>array('item1','otheritem1details....','100.645645','-402.5323') 
); 

Quiero devolver la matriz que tiene la longitud más cercana y lad. En este caso, sería el primero (y sí, sé que -400 no es un valor posible).

¿Hay alguna manera rápida y fácil de hacer esto? Intenté buscar en array pero eso no funcionó.

código Diferencia

function distance($lat1, $lon1, $lat2, $lon2, $unit) { 

    $theta = $lon1 - $lon2; 
    $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); 
    $dist = acos($dist); 
    $dist = rad2deg($dist); 
    $miles = $dist * 60 * 1.1515; 
    $unit = strtoupper($unit); 

    if ($unit == "K") { 
    return ($miles * 1.609344); 
    } else if ($unit == "N") { 
     return ($miles * 0.8684); 
    } else { 
     return $miles; 
     } 
} 
+0

¿Puede usted por favor proporcione su código de donde se obtiene la distancia entre dos pares de latitud/longitud como 'distancia función ($ Lat1, $ long1, $ lat2, $ long2) {... '? – hakre

+0

Eso no tiene sentido, ¿es matemática simple? 55 - 49 = 6, 55-100 = 45 6 es más pequeño que 45. – Steven

+0

¿Sabes realmente cómo calcular la distancia entre dos puntos del globo? – hakre

Respuesta

20

Es necesario asignar la distancia de cada elemento al punto de referencia primero.

Luego se ordena el mapa y luego se puede decir que tiene el más bajo (o más alto si se invierte la búsqueda) distancia:

$ref = array(49.648881, -103.575312); 

$items = array(
    '0' => array('item1','otheritem1details....','55.645645','-42.5323'), 
    '1' => array('item1','otheritem1details....','100.645645','-402.5323') 
); 

$distances = array_map(function($item) use($ref) { 
    $a = array_slice($item, -2); 
    return distance($a, $ref); 
}, $items); 

asort($distances); 

echo 'Closest item is: ', var_dump($items[key($distances)]); 

Salida:

Closest item is: array(4) { 
    [0]=> 
    string(5) "item1" 
    [1]=> 
    string(21) "otheritem1details...." 
    [2]=> 
    string(9) "55.645645" 
    [3]=> 
    string(8) "-42.5323" 
} 

Cuida usted tiene la orden correcto de lat y largo.

La función de distancia (sólo la cabecera ligeramente cambiados y unidades han sido retirados):

function distance($a, $b) 
{ 
    list($lat1, $lon1) = $a; 
    list($lat2, $lon2) = $b; 

    $theta = $lon1 - $lon2; 
    $dist = sin(deg2rad($lat1)) * sin(deg2rad($lat2)) + cos(deg2rad($lat1)) * cos(deg2rad($lat2)) * cos(deg2rad($theta)); 
    $dist = acos($dist); 
    $dist = rad2deg($dist); 
    $miles = $dist * 60 * 1.1515; 
    return $miles; 
} 
+0

¡Brillante! ¡Gran respuesta! – nickspiel

1

No hay manera rápida y fácil de hacer eso. Debe recorrer todos los elementos y calcular la distancia entre ellos y el punto de partida, guardar el resultado y repetir, guardando el resultado solo si es menor que el anterior.

0

Itere a través de la matriz, comparando los valores con los que tiene. Si el valor es más pequeño que el valor almacenado actualmente (o si no tiene un valor actualmente almacenado), almacene ese valor en su lugar, de lo contrario, deséchelo.

$closest = null; 
foreach($array as $key => $value){ 
    $distance = //compare distance here; 
    if ($closest === null || $closest > $distance) { 
     $closest = $distance; 
    }; 
}; 

Por supuesto, esto se hará más difícil por el hecho de que la latitud y longitud están en una esfera, y las longitudes 179 y -179 están más cerca de un 90 y 179.

+0

He actualizado su respuesta significativamente, agregando 'null' como valor predeterminado en lugar de cadena vacía, comprobación estricta explícita de ser' null', estableciendo claramente que '179' y' -179' son sobre longitudes. – Tadeck

+0

Y es por eso que soy un desarrollador front-end, y no un gurú de PHP. Gracias. :) –

4

Más bien usando la ley de los cosenos para la distancia, puede utilizar la aproximación tierra plana. Las ecuaciones de tierra plana reducen el número de funciones trigonométricas en el cálculo. El Δlat, Δlon es la diferencia entre su punto de referencia y el punto de prueba.

Esta fórmula no sería precisa para la navegación a larga distancia (miles de millas) pero para este problema en particular, no está realmente interesado en la distancia exacta, pero ¿quién es el punto más cercano a mí? Esta es una formulación más simple que debería darte eso.

x = Δlon * cos(lat) // lat/lon are in radians! 
y = Δlat 
distance = R * sqrt(x² + y²) // R is radius of the earth; 
           // typical value is 6371 km 

Referencia:http://www.movable-type.co.uk/scripts/latlong.html

código Distancia

function distanceMeters($lat1, $lon1, $lat2, $lon2) { 
    $x = deg2rad($lon1 - $lon2) * cos(deg2rad($lat1)); 
    $y = deg2rad($lat1 - $lat2); 
    $dist = 6371000.0 * sqrt($x*$x + $y*$y); 

    return $dist; 
} 
+0

LOL nvm, acabo de leer que su nombre de función es distanceMeters ... Ignore me. – Steven

+0

Si no le preocupa la distancia real (es decir, simplemente ordenando), también puede soltar 'R *' del último paso ya que es una multiplicación constante para todas las entradas – MatsLindh

Cuestiones relacionadas