2012-03-06 19 views
8

Ho un longitudine e latitudine come una stringa in PHP come qui di seguitoTrova la longitudine e la latitudine più vicine nell'array?

49.648881 
-103.575312 

E voglio prendere quella e guardare in una serie di valori per trovare quello più vicino. L'array è simile a

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

Voglio restituire l'array che ha il più lungo e lad. In questo caso sarebbe il primo (e sì lo so -400 non è un valore possibile).

C'è un modo semplice e veloce per farlo? Ho provato la ricerca di array ma non ha funzionato.

codice Differenza

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

Si può fornire il proprio codice in cui si ottiene la distanza tra due coppie di latitudine/longitudine come 'distanza funzione ($ LAT1, $ long1, $ lat2, $ long2) {... '? – hakre

+0

Non ha senso, è semplice matematica? 55 - 49 = 6, 55-100 = 45 6 è più piccolo di 45. – Steven

+0

Sai davvero come calcolare la distanza tra due punti sul globo? – hakre

risposta

20

È necessario mappare la prima la distanza di ogni oggetto dal punto di riferimento.

Poi si ordina la mappa e quindi si può dire che ha il più basso (o più alto se si inverte la ricerca) distanza:

$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)]); 

uscita:

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

Fare attenzione si ha la giusto ordine di lat e long.

La funzione di distanza (solo l'intestazione leggermente cambiati e le unità sono state eliminate):

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

Fantastico! Bella risposta! – nickspiel

1

Non c'è modo facile e veloce per farlo. Devi scorrere tutti gli elementi e calcolare la distanza tra loro e il punto di partenza, salvare il risultato e ripetere, salvando il risultato solo se è inferiore a quello precedente.

0

Iterate attraverso l'array, confrontando i valori con quello che avete. Se il valore è inferiore al valore attualmente memorizzato (o se non si dispone di un valore attualmente memorizzato), archiviare tale valore, altrimenti gettarlo via.

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

Naturalmente, questo sarà reso più difficile dal fatto che la latitudine e longitudine sono su una sfera, e longitudini 179 e -179 sono più vicini di 90 e 179.

+0

Ho aggiornato la tua risposta in modo significativo, aggiungendo 'null' come valore predefinito invece della stringa vuota, il controllo rigoroso esplicito per essere' null', ha dichiarato chiaramente che '179' e' -179' riguardano longitudini. – Tadeck

+0

Ed è per questo che sono uno sviluppatore front-end e non un guru PHP. Grazie. :) –

4

Piuttosto utilizzando il teorema del coseno per la distanza, è possibile utilizzare piatta approssimazione terra. Le equazioni di terra piatta riducono il numero di funzioni trigonometriche nel calcolo. Il Δlat, Δlon è la differenza tra il tuo punto di riferimento e il punto di test.

Questa formula non sarebbe accurata per la navigazione a lunga distanza (migliaia di miglia) ma per questo particolare problema, non sei veramente interessato alla distanza precisa, ma chi è il punto più vicino a me. Questa è una formulazione più semplice che dovrebbe darti questo.

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 

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

codice Distanza

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, ho appena letto il nome della tua funzione è distanceMeters ... Ignora me. – Steven

+0

Se non si è interessati alla distanza effettiva (cioè solo ordinamento), è anche possibile rilasciare 'R *' dall'ultimo passo in quanto è una moltiplicazione costante per tutte le voci – MatsLindh

Problemi correlati