Da der erste Artikel ja gut ankam gibt es heute einen weiteren 
Das Firmenprojekt welches ich ja schon im ersten Artikel erwähnte ist eine aufgebohrte Zeiterfassung für die ich (für ein paar Auswertungen) auch (automatisch) die geographischen Koordinaten unserer Kunden ermitteln wollte. Die Lösung, die ich gefunden habe, nutzt (der Einfachheit halber) die Google-Maps API die neben ihren vielen anderen Features auch einen Geo-Coder beinhaltet.
Praktischerweise lässt dieser sich bequem über einen HTTP-Aufruf ansprechen und liefert seine Ergebnisse im XML, JSON oder CSV Format zurück.
Wie bei allen Google Maps Projekten braucht man zuerst einen kostenlosen API-Key (den bekommt man hier).
Danach wird die Sache eigentlich ganz einfach. Google stellt den GeoCoder unter der URL http://maps.google.com/maps/geo zur Verfügung. Um eine Adresse aufzulösen muss man also eigentlich nur die URL mit ein paar Parametern aufrufen. Angenommen der API-Key für Google Maps wäre “AAAAAZZZZZ” dann würde der Aufruf der URL
http://maps.google.com/maps/geo?q=Auhofstrasse+9%2C+63741+Aschaffenburg%2C+Deutschland&output=json&key=AAAAAZZZZZ
alle relevanten Daten zu der Adresse “Auhofstrasse 9, 63741 Aschaffenburg, Deutschland” zurückliefern.
Abhängig davon, welches Format man auswählt und je nach Informationslage liefert der Aufruf übrigens unterschiedlich umfangreiche Daten zurück. CSV liefert immer nur 4 Werte zurück: Status, Qualität, Breitengrad, Längengrad während XML/JSON je nach Informationslage noch wesentlich mehr Daten zurückliefern (gibt man als Adresse z.B. nur “Deutschland” an, liefert Google den Landesnamen auf Englisch, den Ländercode (DE) und ein paar Koordinaten zurück. Für die Beispieladresse liefert es aber auch noch einige Verwaltungsinformationen mit (z.B. das Aschaffenburg zu Bayern gehört, etc.)).
Da uns nur die Koordinaten interessieren, verwenden wir das CSV-Format.
Eine einfache Funktion könnte dann z.B. so aussehen:
function holeKoordinatenCSV($adresse) {
$google_maps_api = 'HIER BITTE EUREN API-KEY EINTRAGEN!';
// URL erzeugen
$url = 'http://maps.google.com/maps/geo?q='.urlencode($adresse).'&output=csv&key='.$google_maps_api;
// Ergebnis laden
$data = @file_get_contents($url);
if ($data !== false) {
$elements = explode(',',$data);
if ((int)$elements[0]==200) {
return array( 'accuracy' => (int)$elements[1],
'latitude' => $elements[2],
'longitude' => $elements[3]);
}
}
return false;
}Die Funktion liefert entweder ein Array mit Koordinaten oder FALSE zurück:
$koord = holeKoordinatenCSV('Auhofstrasse 9, 63741 Aschaffenburg, Deutschland');
if ($koord !== false) {
print_r($koord);
} else {
echo 'Es konnten keine Koordinaten ermittelt werden.';
}Die Funktion ist so zwar schon nutzbar, berücksichtigt aber kaum Fehler. Es ist also definitiv Spielraum für Verbesserungen wenn ihr mit dem Code arbeiten wollt.
Interessant ist neben den Koordinaten übrigens auch der Accuracy-Wert den ihr von der Funktion bekommt. Je höher der Wert ist (max. 9), desto genauer konnte die Adresse aufgelöst werden. Werte kleiner als 6 sind allerdings kaum noch brauchbar da 5 schon nur noch für das Postleitzahlengebiet steht (mehr Informationen dazu gibt es hier).
Wie man sieht ist es dank Google wirklich einfach die Koordinaten zu einer Adresse abzufragen. Zu guter Letzt noch zwei Sachen: wenn ihr die Funktion nutzen wollt dürft ihr das gerne tun (sie steht unter keiner besonderen Lizenz und darf von jedem frei genutzt werden – alles andere wäre bei den paar Zeilen auch eher “amüsant”
) und noch zu guter Letzt ein paar Hinweise zu Fallstricken:
- nutzt ihr JSON als Format müsst ihr beachten das json_decode() kein UTF8 verarbeiten kann
- nutzt ihr SimpleXML müsst ihr beachten das Encoding stimmt (ebenfalls UTF8 beachten!)
- die Adresse in der URL muss mit urlencode() in die richtige Form gebracht werden
Die ersten zwei Punkte spielen insofern eine Rolle, dass Google ggf. das Ergebnis nicht in der richtigen Kodierung zurückliefert (was davon abhängt welche Methode ihr zum Holen der Daten nutzt – Snoopy-Klasse, file_get_contents, CURL, usw.). Wenn also der Aufruf der URL einen scheinbar gültigen JSON-String liefert und json_decode() nichts zurückgibt versucht es mal mit utf8_decode() und dann erst json_decode(). Entsprechend könnt ihr utf8_encode() nutzen wenn SimpleXML beim Parsen der XML-Antwort rumzickt (“Input is not proper UTF-8, indicate encoding !”).
Der einzige Punkt den ich noch prüfen muss sind die Lizenzbedingungen von Google Maps und in wieweit die Nutzung erlaubt ist so wie ich das vorhabe (ich habe irgendwo gelesen, dass man die API nur nutzen darf wenn man auch Karten anzeigt und die auch öffentlich zugänglich sind!?!?)



file_get_contents läuft meines Erachtens nach nicht zwangsläufig mit remote Adressen.
Code Schnipsel unter eine Lizenz zu stellen, ist übrigens ein äußerst merkwürdiger Gedankengang. Gehört der nicht eigentlich Deinem Arbeitgeber, wenn Du ihn für den entwickelt hast?
Abseits des Artikels: Womit werden Deine Code Beispiele gerendert? Sieht gut aus und die Verlinkung zu php.net finde ich witzig.
Du würdest Dich wundern wo Leute überall seltsame Lizenzen dranpappen…
Bezüglich meines Arbeitgebers: einerseits unterstützt er dieses Blog (die Firmen-Homepage verlinkt sogar in einer News-Meldung nach hier) und andererseits ist der Code den ich hier veröffentliche nicht der, den ich in der Firma nutze. Die Codebeispiele hier sind immer stark vereinfacht. Zum Beispiel nutzt mein richtiger Code wahlweise CURL oder die Snoopy-Klasse zur Kommunikation.
Alle Code-Beispiele werden mit dem CodeColorer PlugIn angezeigt. Das unterstützt alle möglichen Sprachen (PHP, C, Bash, JavaScript, usw.).
“Der einzige Punkt den ich noch prüfen muss sind die Lizenzbedingungen von Google Maps und in wieweit die Nutzung erlaubt ist so wie ich das vorhabe (ich habe irgendwo gelesen, dass man die API nur nutzen darf wenn man auch Karten anzeigt und die auch öffentlich zugänglich sind!?!?)”
Ja – siehe bitte http://code.google.com/apis/maps/signup.html
(9.1)Unless you have entered into a separate written agreement with Google or obtained Google’s written permission, your Maps API Implementation must not:
(a) require a fee-based subscription or other fee-based restricted access; or
(b) operate only behind a firewall or only on an internal network (except during the development and testing phase).
10. License Restrictions. Except as expressly permitted under the Terms, or unless you have received prior written authorization from Google (or, as applicable, from the provider of particular Content), Google’s licenses above are subject to your adherence to all of the restrictions below. Except as explicitly permitted in Section 7 or the Maps APIs Documentation, you must not (nor may you permit anyone else to):
10.8 use the Static Maps API other than in an implementation in a web browser;
Hallo Christian.
Sehr interessanter Artikel. Kann ich für mein gerade Angefangenes Projekt brauchen
Schönen Sonntag noch.