2010-11-16 14 views
9

Ho una posizione (latitudine & longitudine). Come posso ottenere un elenco di codici postali che sono parzialmente o completamente entro il raggio di 10 miglia dalla mia posizione?Dato coordinate, come ottengo tutti i codici postali entro un raggio di 10 miglia?

La soluzione potrebbe essere una chiamata a un noto servizio Web (google maps, bing maps, ecc.) O una soluzione di database locale (il client ha SQL Server 2005) o un algoritmo.

Ho visto un po 'di similar question, ma tutte le risposte lì riguardano quasi l'utilizzo della funzionalità di geografia di SQL Server 2008 che non è disponibile per me.

+2

In quale paese stai cercando di trovare i codici di avviamento postale? – Pedery

+0

@Pedery. US di A – AngryHacker

risposta

5

In primo luogo, avrete bisogno di un database di tutti i codici di avviamento postale e le loro latitudini e longitudini corrispondenti. In Australia ci sono solo poche migliaia di queste (e le informazioni sono facilmente disponibili), tuttavia presumo che sia probabilmente un compito più difficile negli Stati Uniti.

In secondo luogo, dato che si sa dove si trova e si conosce il raggio che si sta cercando, è possibile cercare tutti i codici di avviamento postale che rientrano in tale raggio. Qualcosa di semplice scritto in PHP potrebbe essere il seguente: (scuse che non è in C#)

function distanceFromTo($latitude1,$longitude1,$latitude2,$longitude2,$km){ 
    $latitude1 = deg2rad($latitude1); 
    $longitude1 = deg2rad($longitude1); 
    $latitude2 = deg2rad($latitude2); 
    $longitude2 = deg2rad($longitude2); 
    $delta_latitude = $latitude2 - $latitude1; 
    $delta_longitude = $longitude2 - $longitude1; 
    $temp = pow(sin($delta_latitude/2.0),2) + cos($latitude1) * cos($latitude2) * pow(sin($delta_longitude/2.0),2); 
    $earth_radius = 3956; 
    $distance = $earth_radius * 2 * atan2(sqrt($temp),sqrt(1-$temp)); 
    if ($km) 
    $distance = $distance * 1.609344; 
    return $distance; 
} 
+0

AngryHacker: Luke ha pubblicato una implementazione PHP della formula di Haversine che ho menzionato. – winwaed

5

La maggior parte delle ricerche funziona con centroidi. Per poter lavorare con i codici zip parziali entro le 10 miglia, dovrai acquistare un database di poligoni zipcode (*). Quindi implementare un algoritmo che controlla i codici di avviamento postale con i vertici entro il raggio di 10 miglia. Per essere fatto correttamente, è necessario utilizzare la formula di Haversine per la misurazione della distanza. Con alcune strutture dati intelligenti, è possibile ridurre significativamente lo spazio di ricerca. Allo stesso modo, le ricerche possono essere notevolmente accelerate memorizzando e confrontando inizialmente con estensioni zipcoe (Nord, Ovest, Est, Sud).

(*) Nota: tecnicamente i codici di avviamento postale NON sono poligoni! So che tutti noi pensiamo a loro in questo modo, ma in realtà sono raccolte di punti dati (indirizzi stradali) e questo è il modo in cui l'USPS li usa davvero. Ciò significa che i codici di avviamento postale possono includere altri codici di avviamento postale; i codici di avviamento postale possono essere costituiti da più "poligoni"; e i codici postali possono sovrapporsi ad altri codici di avviamento postale. La maggior parte di queste situazioni non dovrebbe essere un problema, ma dovrai gestire i CAP che possono essere definiti come più poligoni.

9

Inizia con un database dei codici di avviamento postale che contiene zipcodes e la loro latitudine e longitudine corrispondenti coordinate

http://www.zipcodedownload.com/Products/Product/Z5Commercial/Standard/Overview/

Per ottenere la distanza tra latitudine e longitudine, avrai bisogno di una buona formula a distanza. Questo sito ha un paio di varianti:

http://www.meridianworlddata.com/distance-calculation/

La formula "Great Circle distanza" è un po 'estrema. Questo funziona abbastanza bene dalla mia esperienza:

sqrt(x * x + y * y) 

where x = 69.1 * (lat2 - lat1) 
and y = 69.1 * (lon2 - lon1) * cos(lat1/57.3) 

la query SQL sarà quindi simile a questa:

select zd.ZipCode 
from ZipData zd 
where 
    sqrt(
     square(69.1 * (zd.Latitude - @Latitude)) + 
     square(69.1 * (zd.Longitude - @Longitude) * cos(@Latitude/57.3)) 
    ) < @Distance 

Buona fortuna!

+2

Questa è stata davvero un'ottima risposta ... tutte le distanze sono nel raggio di un quarto di miglio che ho immaginato ...+1 –

+0

ottima risposta +1 - puoi dirmi da dove viene la matematica? Cosa rappresentano i numeri decimali? –

+0

Il collegamento a meridianworld.com non è più valido, quindi l'ho aggiornato ad una versione memorizzata nella cache. Credo che i numeri magici derivino da una approssimazione a distanza che calcola le distanze sulla superficie di una sfera. Ci sono formule più accurate là fuori, ma per il tuo scenario base di "store locator", questo ha funzionato bene per me. – dana