2010-11-16 7 views
9

Ich habe einen Standort (Breitengrad & Länge). Wie kann ich eine Liste von Postleitzahlen erhalten, die teilweise oder vollständig innerhalb des 10-Meilen-Radius von meinem Standort liegen?Gegebene Koordinaten, wie bekomme ich alle Postleitzahlen innerhalb eines Radius von 10 Meilen?

Die Lösung könnte ein Aufruf an einen bekannten Webservice (Google Maps, Bing Maps, etc ...) oder eine lokale Datenbanklösung (der Client hat SQL Server 2005) oder einen Algorithmus sein.

Ich habe die etwas similar question gesehen, aber alle Antworten dort beziehen sich ziemlich weitgehend auf SQL Server 2008 Geographie-Funktionalität, die für mich nicht verfügbar ist.

+2

In welchem ​​Land möchten Sie Postleitzahlen finden? – Pedery

+0

@Pedery. US von A – AngryHacker

Antwort

5

Zunächst benötigen Sie eine Datenbank aller Postleitzahlen und ihrer entsprechenden Breiten- und Längengrade. In Australien gibt es nur ein paar tausend davon (und die Informationen sind leicht verfügbar), aber ich nehme an, dass es wahrscheinlich eine schwierigere Aufgabe in den USA ist.

Zweitens, wenn Sie wissen, wo Sie sind, und Sie wissen, den Radius, den Sie suchen, können Sie alle Postleitzahlen, die innerhalb dieses Radius fallen. Etwas einfach in PHP geschrieben würde wie folgt aussehen: (Entschuldigung, es ist nicht 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 hat eine PHP-Implementierung der Haversine-Formel gepostet, die ich erwähnte. – winwaed

5

Die meisten Suchen arbeiten mit Schwerpunkten. Um mit Teil-Postleitzahlen zu arbeiten, die innerhalb der 10 Meilen liegen, müssen Sie eine Datenbank mit Postleitzahl-Polygonen (*) kaufen. Implementieren Sie dann einen Algorithmus, der im Umkreis von 10 Meilen nach Postleitzahlen mit Scheitelpunkten sucht. Um richtig gemacht zu werden, müssen Sie die Haversine-Formel für die Entfernungsmessung verwenden. Mit einigen cleveren Datenstrukturen können Sie den Suchraum erheblich reduzieren. In ähnlicher Weise können Suchvorgänge erheblich beschleunigt werden, indem gespeichert und anfänglich mit Zipcoe-Extents verglichen wird (Norden, Westen, Osten, Süden).

(*) Hinweis: Technisch sind Postleitzahlen keine Polygone! Ich weiß, dass wir alle so an sie denken, aber in Wirklichkeit sind sie Sammlungen von Datenpunkten (Straßenadressen) und so benutzt der USPS sie wirklich. Dies bedeutet, dass Postleitzahlen andere Postleitzahlen enthalten können. Postleitzahlen können aus mehreren "Polygonen" bestehen; und Postleitzahlen können andere Postleitzahlen überlappen. Die meisten dieser Situationen sollten kein Problem sein, aber Sie müssen mit Postleitzahlen umgehen, die als mehrere Polygone definiert werden können.

9

Beginnen Sie mit einer Postleitzahl-Datenbank, die zipcodes und ihre entsprechenden Breiten- und Längenkoordinaten enthält:

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

Um den Abstand zwischen Längen- und Breitengrad zu erhalten, benötigen Sie eine gute Entfernungsformel. Diese Seite hat ein paar Variationen:

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

Die "Great Circle Distance" Formel ein wenig extrem. Dies funktioniert gut genug, um aus meiner Erfahrung:

sqrt(x * x + y * y) 

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

Ihre SQL-Abfrage wird dann wie folgt aussehen:

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 

Viel Glück!

+2

Das war eigentlich eine gute Antwort ... alle Entfernungen sind innerhalb einer Viertelmeile, die ich mir vorgestellt habe ...+1 –

+0

große Antwort +1 - können Sie mir sagen, wo die Mathematik herkommt? Was bedeuten die Dezimalzahlen? –

+0

Der Link zu meridianworld.com ist nicht mehr gültig, also habe ich ihn auf eine zwischengespeicherte Version aktualisiert. Ich glaube, dass die magischen Zahlen aus einer Abstandsannäherung stammen, die Abstände auf der Oberfläche einer Kugel berechnet. Es gibt genauere Formeln da draußen, aber für Ihr grundlegendes "Filialfinder" -Szenario hat dieses für mich gut funktioniert. – dana