Side Projects:

Facedetection
Source Magic
Intrusion Detection System
Issue Tracker
Searchengine
RemindMe
Open API

Impressum
Andreas Beder 2012


PLZ Umkreissuche in PHP

Hallo,

nachdem ich die letzten Tage wenig neues veröffentlicht habe, heute mal etwas interessantes für den ambitionierten PHP Programmierer.

Eine PLZ Umkreissuche in PHP, dazu benötigen wir:

  1. Eine Geo DB mit Long und LAT sowie PLZ (am besten von opengeodb auf sourceforge)
  2. Einen brauchbaren Umkreissuchen-Script
  3. Etwas Zeit

Bei meinen Versuchen hat sich herausgestellt, dass ich die meiste Zeit damit verbracht habe, eine brauchbare Datenbank zu finden und zu formatieren. Hilfe dazu weiter unten, jetzt erstmal etwas Code:

Code

<?
// Zuerst eine Verbindung zur Datenbank aufbauen!
 
$connect=@mysql_connect("localhost""user""pass")
or die(
"Cant connect to Database");
 @
mysql_select_db("geo_plz"$connect)or die("Cant select Database");

// die PLZ nach der wir suchen
$plz '9220';

// der Umkreis in Km
$umkreis 5;

// Erdradius (geozentrischer Mittelwert) in Km
$radius 6368;

/* -------------------------- */

$sql_rad mysql_query("SELECT lon, lat FROM `plz_at` WHERE `plz` = '$plz' ");
$erg_rad mysql_fetch_object($sql_rad);

// Umrechnung von GRAD IN RAD

$lon $erg_rad->lon 180 M_PI;
$lat $erg_rad->lat 180 M_PI;

// jetzt erfolgt die eigentliche Abfrage

$query "SELECT ort, plz, (
 "
.$radius." * SQRT(2*(1-cos(RADIANS(lat)) * 
 cos("
.$lat.") * (sin(RADIANS(lon)) *
 sin("
.$lon.") + cos(RADIANS(lon)) * 
 cos("
.$lon.")) - sin(RADIANS(lat)) * sin(".$lat.")))) AS Distance 
 FROM plz_at WHERE 
 "
.$radius." * SQRT(2*(1-cos(RADIANS(lat)) * 
 cos("
.$lat.") * (sin(RADIANS(lon)) * 
 sin("
.$lon.") + cos(RADIANS(lon)) * 
 cos("
.$lon.")) - sin(RADIANS(lat)) * sin(".$lat."))) <= ".$umkreis.
 ORDER BY Distance
"
;

// die Ausgabe (vereinfacht)

$sql mysql_query($query);
while( 
$erg mysql_fetch_object($sql) ) {

 echo 
'
<pre>'
print_r($erg), '</pre>
'
;
}
?>


Natürlich wäre es jetzt denkbar für jede gefundene PLZ im Umkreis eine Abfrage der Mitglieder oder Filialen zu machen, diesen Spass überlasse ich aber lieber euch :)

Wer die formatierte Datenbank für Deutschland, Österreich und Schweiz braucht oder eine Frage hat, einfach kurz melden.

LG

Andreas

Eine wichtige Adresse die beim Erstellen der Datenbank sowie der Gestaltung der Abfrage hilfreich ist lautet:

http://opengeodb.giswiki.org/wiki/OpenGeoDB_-_Umkreissuche

[UPDATE]

Ich habe die Datenbank online gestellt, übernehme aber keine Garantie für Vollständigkeit und Richtigkeit.

http://www.codejungle.org/code/zip.sql.gz



Name
Johannes
Hey Andreas!

Bei mir berechnet das Script scheinbar die Differenzen in einem anderen Maßstab. z.B.:

Koblenz - Stuttgart : 5759 (wirklich : 209 KM)
Koblenz - Hamburg : 6007 (wirklich : 391 KM)
Koblenz - Paris : 6135 (wirklich : 413 KM)
Koblenz - New York : 10416 ( wirklich : 6128 KM)

Ich habe das Script leicht abgeändert aber die Lng und Lat Eingaben sind gleich. Kannst du dir da einen Reim drauf machen?

Vielen Dank
Jo

Name
Andreas
Hi Tom,

also der Artikel ist vom 2008-08-03,
daher schon etwas älter ...
Der DB Dump ist vom 2010-07-07, evtl werd ich mal ein script bastelen, das die daten regelmässig aktualisiert..

lg
andreas

Name
tom
Ich vermisse hier eine Datumsangabe von diesem HowTo bzw. Artikel. Wie alt ist dieser ca ?

Ich habe probleme damit eine aktuelle plz_de SQL DUMP zu bekommen.

Name
Andreas
Hi Ben,
ich nehm mal an du meinst diese Zeile:
// die PLZ nach der wir suchen
$plz = '9220';

falls ja, diese dient nur zur Demonstrationszwecken, hier könnte genauso gut der Inhalt von einem Eingabefeld stehen...

lg
Andreas

Name
Ben
Hi,
danke erstmal für das Script und die sql!
aber mal ne blöde frage:
warum legen wir fest nach was wir suchen???
oder kapier ich irgendwas ned?

danke schonmal für die antwort!
cheers,
ben

Name
Andreas
Hi Sam,
Also alles was im Umkreis von 1km der Postleitzahl 80634 zu finden ist findet er,
einschließlich die PLZ von anderen Bezirken. Willst du das nicht, könnte man die Ausgabe noch filtern, bzw schon in der abfrage ein distinct auf den ort machen ..
wenn du noch fragen hast, kannst dich auch gerne per mail an mich wenden.

lg
andreas

Name
Sam
Sorry für den Doppelpost, bitte einen löschen.
Oder ist das so gemeint, dass die PLZ 80634 zu München gehört, hier weitere 74 PLZs ausgegeben werden weil diese auch zu München gehören und er dann ausserhalb von München 1km mit dazu sucht?
Ich dachte er geht von der PLZ aus 1 km? Also alles was im Umkreis von der Postleitzahl 80634 zu finden ist?

Name
Sam
Also irgendwie kann das doch nicht stimmen, nehme ich folgenden Link:

http://codejungle.org/api/plz.php?plz=80634&umkreis=1&land=de

Dann schmeisst er mir zig Ergebnisse raus was alles im Umkreis von 1km hier entfernt sein soll.

Schau ich hier: http://www.plz-umkreis.com/?zipcode=80637&radius=1&country=de

Dann kommt genau 1 Ergebnis raus bei 1km Umkreis und so stimmt es auch.

Wo hängts also?!

Name
Markus
Hilfe! Egal welche parameter ich für $plz und $umkreis eingebe ich bekomme immer(!) dieselben 8 städte als ergebnis angezeigt

Name
Marcus
Schönes Script! Einfach und unkompliziert!
Allerdings habe ich den Eindruck, dass die Berechnung nicht ganz richtig arbeitet.

Dein Script gibt mir
von 51.3333, 6.56833333 nach 51.2601699, 6.5142186
8,9 km aus. Bei Google Maps ist allerdings die kürzeste Strecke 15,4 km, wenn ich genau nach diesen Koordinaten suche.

Name
Florian
Super Sache, klappt wunderbar für deutsche PLZ!

Ich habe mir die aktuelle DB/CSV von OpenGeoDB geholt: http://fa-technik.adfc.de/code/opengeodb/PLZ.tab
Datenbank anlegen, CSV importieren. In deinem Code noch "plz_at" durch "plz_de" (Name der Datenbanktabelle) ersetzt, Datenbankverbindung angepasst und schon läuft es!

Danke das du den Code mit der Community teilst!

Name
Andreas
mhm wundert mich etwas,
ich verwende die datenbank selber auch bei meiner api, siehe http://codejungle.org/api/plz.php?plz=23747&umkreis=5&land=de

kann es sein das du in den beiden (bzw einer von beiden) abfragen noch plz_at drin stehen hast ?

lg
andreas

Name
hmmm
also irgendwas stimmt mit der datenbank plz_de nicht. egal welche parameter ich für $plz und $umkreis eingebe ich bekomme immer(!) dieselben 8 städte als ergebnis angezeigt

Name
Alex
Hallo, tolle Seite.
Auch ich suche für unseren kleinen Onlineshop eine Funktion, in der Interessenten Ihre PLZ eingeben können und dann die nächste Abholstelle von uns erfahren.

Beispiel: Kunde kommt aus 70190 und dann wird ihm die Abholstelle in 70200 angezeigt...

Wenn du mir da weiter helfen könntest, wäre ich dir sehr dankbar, da ich schon ganz verzweifelt so etwas suche.

Insgesamt hab ich 9 Abholstellen - meisst Verwandschaft - ich bin gespannt ob das technisch möglich ist!

Gruss aus Stuttgart

Name
martin
Danke für solch ein klasse Script!

vg
martin

Name
Andreas
hallo jean,
der rückgabewert ist in km,
der grund wieso die formatierung teilweise so seltsam ausschaut, ist das es soviele nachkomma stellen gibt, das es in ein integar berreich nicht mehr reinpasst...
auf einem 64 bit system hättest im übrigen ein dopellt so großen integar berreich...
um die ausgabe jetzt schön zu formatieren, würde ich mit round den wert einfach auf die 2 komma stelle runden.
hoffe ich konnte damit deine frage beantworten.

lg
andreas

Name
Jean
Hi,
super Script! Endlich mal was brauchbares :)
Was mich noch interessieren würde:
In welcher Einheit kommt die Distance zurück? KM?
Ich habe zb die Angabe
Distance: 8.8364875934259e-05
Distance: 2.3394734447394
Beide PLZ sind 57572 (gesucht nach 57572).
Wie kann ich die Distance in KM formatieren?

Danke schonmal im Voraus! :)

Grüße
Jean

Name
sandex
ja super...
also es funktioniert jetzt alles.

habe einfach nur den DB-Verweis in der eigendlichen Abfrage übersehen.
(...AS Distance FROM plz_at WHERE...)

also alle Panik umsonst...
Danke für den Script, die DB und die rasche Antwort...

Gruß
Sandex

Name
Andreas
hallo sandex,
vermutlich ist das error reporting bei dir abgeschaltet und deswegen bekommst du eine weiße seite. schau mal ob du irgendeine php error logs findest, ich kann dir dann vermutlich weiterhelfen.

lg
andreas

Name
sandex
Hallo,
ich habe die Datenbank angelegt und die Inhalte importiert, den Script auf den Server geladen und getestet. Alles Super.

Jetzt habe ich versucht auf die Tabelle "plz_de" zuzugreifen und bekomme nur eine weisse Seite.

Die Tabellen "plz_at" und "plz_ch" funtionieren dagegen einwandfrei.

Nun möchte ich gern wissen warum das so ist und wie ich das Problem lösen kann.

Kannst du mir da weiterhelfen?

Name
Patrick
Hi,

klasse Script.

Danke und Grüße aus Karlsruhe

Name
Andreas
Hi,
du kannst die Datenbank hier herunterladen:
http://www.codejungle.org/code/zip.sql.gz

best regards
andreas

Name
Stephan
Hallo Andreas,

erstmal Danke für Deine Mühe.

Ich bin auf der Suche nach einer formatierten Datenbank für die deutschen Städte auf Deine Seite gestoßen und habe Deinen Kommentar unter Deinem PLZ-Umkreissuche Skript gelesen.

Wäre es möglich, dass Du mir das SQL file mit den deutschen Geodaten zuschickst?

Vielen Dank und lieben Gruß aus Köln,
Stephan

Name
Andreas
Hallo Oliver,

sorry das ich dir erst jetzt schreibe,
wenn du noch intresse hast, schicke ich dir gerne die datenbank.

lg
andreas

Name
Oliver
Hi.. wäre klasse wenn ich die Geo-Datenbank für Deutschland, Österreich und Schweiz von dir bekommen könnte.

Danke und Gruss
Oliver