[PHP,MySQL] Orte aus Datenbank geokodieren

Für ein Projekt war es nötig, eine Geokodierung vorhandener Daten von Orten inkl. Adresse durchzuführen.
Die erste Idee für mich war es, Google Maps dafür einzusetzen. Hier braucht man nur für die Geokodierung sogar kein Javascript einzusetzen, sondern
man kann dies direkt mit PHP und natürlich MySQL erledigen.

Ich setze an dieser Stelle eine erfolgreiche Verbindung per mysql_connect() zur MySQL-Datenbank voraus. Außerdem benötigt ihr einen Google Maps-API Key, den ihr hier erhaltet.
Wie ich feststellen musste, ist dieser IP- bzw. Domainabhängig, d.h. er funktioniert nur unter der IP/Domain, die ihr bei der Anmeldung des Keys angegeben hat.

Um schön modular und nicht reduntant zu arbeiten habe ich 2 Funktionen geschrieben.
Eine dient für die Geokodierung eines Ortes geocodeOrt($adresse, $orts_id) , die andere itteriert durch alle in der Datenbank vorhandenen Orte namens alleOrte() und übergibt an geocodeOrt($adresse, $orts_id) die Parameter $adresse bestehend aus Straße, Hausnummer, PLZ , Ort und die $orts_id, was die ID des geokodiertem Ort ist.

Funktion alleOrte():

function alleOrte() {
 $query_alleOrte = "SELECT orts_id as id, concat(strasse,',',plz,' ',ort) as adresse FROM orte";
 $query_alleOrte_result = mysql_query($query_alleOrte);

 while ($row = mysql_fetch_array($query_alleOrte_result)) {
  geocodeOrt($row['adresse'], $row['id']);
 }
}

Und nun die spannendere Funktion geocodeOrt($adresse, $orts_id):

function geocodeOrt($adresse, $id) {
 define("MAPS_HOST", "maps.google.com");
 define("KEY", KEY); // hier euren Key als String eintragen

 $delay = 0;
 $base_url = "http://" . MAPS_HOST . "/maps/geo?output=xml" . "&key=" . KEY;
 $geocode_pending = true;
 while ($geocode_pending) {
  $request_url = $base_url . "&q=" . urlencode($adresse);
  $xml = simplexml_load_file($request_url) or die("url not loading");

  $status = $xml->Response->Status->code;
  if (strcmp($status, "200") == 0) {
   // Successful geocode
   $geocode_pending = false;
   $coordinates = $xml->Response->Placemark->Point->coordinates;
   $coordinatesSplit = split(",", $coordinates);
   // Format: Laenge, Breite, Hoehe
   $breite = $coordinatesSplit[1];
   $laenge = $coordinatesSplit[0];

   $query_update = "UPDATE orte
   SET laengengrad = '$laenge',
   breitengrad = '$breite'
   WHERE orts_id = '$id'";

   $update_result = mysql_query($query_update);
   if (!$update_result) {
    die("Invalid query: " . mysql_error());
   }
 } else if (strcmp($status, "620") == 0) {
  // sent geocodes too fast
  $delay += 100000;
 } else {
   // failure to geocode
   $geocode_pending = false;
   echo "Address " . $adresse . " failed to geocoded. ";
   echo "Received status " . $status . "\n";
  }
  usleep($delay);
 }
}

Da die Funktion geocodeOrt($adresse, $id) seperat ist, könnt ihr nun auch praktisch diese Funktion aufrufen, wenn in eurem z.B. CMS einen neuen Ort anlegt und direkt dann die Geokodierung durchführen möchtet.
So braucht ihr nicht wieder komplett alle Orte neu geokodieren zu lassen.

Ich hoffe, euch ist nun einiges klarer damit geworden und ich konnte euch helfen.

Advertisements
Veröffentlicht in PHP. Schlagwörter: , , , , , , . Leave a Comment »

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit Deinem WordPress.com-Konto. Abmelden / Ändern )

Twitter-Bild

Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )

Facebook-Foto

Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: