Verfasst: Dezember 2007
Aktualisiert: Dezember 2013
Ziel
Dieses Tutorial richtet sich an Entwickler, die mit Skriptsprachen vertraut sind und lernen möchten, wie sie die Google Geocoding API verwenden, um Adressen zu geocodieren und in eine KML-Datei einzufügen. Die Codebeispiele sind zwar in Python, können aber relativ einfach an die meisten anderen Programmiersprachen angepasst werden.
Beim Geocoding wird eine Adresse in eine Reihe von Breiten- und Längengradkoordinaten umgewandelt, sodass Adressen auf einer Karte angegeben werden können. Möglicherweise möchten Sie Adressen geocodieren und direkt in eine KML-Datei einfügen. Das ist z. B. häufig der Fall, wenn Daten in ein Formular eingegeben werden und Sie als Reaktion auf Anfragen KML-Dateien generieren. Diese KML-Dateien können in einer Datenbank oder einem Dateisystem gespeichert oder an einen NetworkLink zurückgegeben werden, der mit Ihrer Datei verbunden ist. Beachten Sie, dass Sie bei dieser Methode die Nutzungsbedingungen für die Geocoding API einhalten müssen. Es gibt Einschränkungen hinsichtlich der Dauer, für die die Ergebnisse gespeichert werden dürfen, sowie der Anzahl der Elemente, die Sie täglich geocodieren können.
In dieser Anleitung erfahren Sie, wie Sie mit Python den String „1600 Amphitheatre Pkwy, Mountain View, CA 94043
“ in Folgendes umwandeln:
<?xml version='1.0' encoding='UTF-8'?>
<kml xmlns='http://earth.google.com/kml/2.2'>
<Document>
<Placemark>
<description>1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA</description>
<Point>
<coordinates>-122.081783,37.423111,0</coordinates>
</Point>
</Placemark>
</Document>
</kml>
KML-Dokument erstellen
KML ist eine XML-Auszeichnungssprache. Daher können wir die integrierten xml.dom.minidom-Funktionen von Python verwenden, um ein KML-Dokument zu erstellen. Das minidom-Modul von Python ist eine DOM-Implementierung. Da DOM in den meisten Programmiersprachen unterstützt wird, sollte sich dieser Prozess problemlos in eine andere Programmiersprache übertragen lassen. Und so gehts:
- Erstellen Sie das Dokument mit
xml.dom.minidom.Document()
von Python. - Erstellen Sie das
<kml>
-Stammelement mitcreateElementNS.
. - Hängen Sie es mit
appendChild
an das Dokument an. - Erstellen Sie ein Document-Element mit
createElement
. - Hängen Sie es mit
appendChild
an das<kml>
-Element an. - Erstellen Sie für jede Adresse ein
<Placemark>
-Element mitcreateElement
und hängen Sie es an dasDocument
-Element an. Erstellen Sie dann ein<description>
-Element, weisen Sie ihm den Wert der Adresse zu und hängen Sie es an das<Placemark>
-Element an. - Erstellen Sie ein
<Point>
-Element, fügen Sie ein untergeordnetes<coordinates>
-Element hinzu und hängen Sie es an das<Placemark>
-Element an. - Senden Sie die Adresse an den Geocoder der Maps API. Dieser sendet eine Antwort im JSON- oder XML-Format.
Verwenden Sie
urllib.urlopen()
, um die Datei abzurufen und in einen String einzulesen. - Die Antwort parsen und die Elemente für Längen- und Breitengrad extrahieren.
- Erstellen Sie einen Textknoten im
<coordinates>
-Element und weisen Sie ihm den String für Längen- und Breitengrad als Wert zu. - Schreiben Sie das KML-Dokument in eine Textdatei.
Python-Beispielcode
Im Beispielcode unten wird die Dummy-Variable „mapsKey“ verwendet. Sie müssen diesen Schlüssel durch Ihren eigenen Schlüssel ersetzen.
Unten sehen Sie Beispielcode für die Geocodierung mit Python 2.7 und JSON-Ausgabe:
import urllib import xml.dom.minidom import json def geocode(address, sensor=False): # This function queries the Google Maps API geocoder with an # address. It gets back a csv file, which it then parses and # returns a string with the longitude and latitude of the address. # This isn't an actual maps key, you'll have to get one yourself. # Sign up for one here: https://code.google.com/apis/console/ mapsKey = 'abcdefgh' mapsUrl = 'https://maps.googleapis.com/maps/api/geocode/json?address=' # This joins the parts of the URL together into one string. url = ''.join([mapsUrl,urllib.quote(address),'&sensor=',str(sensor).lower()]) #'&key=',mapsKey]) jsonOutput = str(urllib.urlopen(url).read ()) # get the response # fix the output so that the json.loads function will handle it correctly jsonOutput=jsonOutput.replace ("\\n", "") result = json.loads(jsonOutput) # converts jsonOutput into a dictionary # check status is ok i.e. we have results (don't want to get exceptions) if result['status'] != "OK": return "" coordinates=result['results'][0]['geometry']['location'] # extract the geometry return str(coordinates['lat'])+','+str(coordinates['lng']) def createKML(address, fileName): # This function creates an XML document and adds the necessary # KML elements. kmlDoc = xml.dom.minidom.Document() kmlElement = kmlDoc.createElementNS('http://earth.google.com/kml/2.2','kml') kmlElement = kmlDoc.appendChild(kmlElement) documentElement = kmlDoc.createElement('Document') documentElement = kmlElement.appendChild(documentElement) placemarkElement = kmlDoc.createElement('Placemark') descriptionElement = kmlDoc.createElement('description') descriptionText = kmlDoc.createTextNode(address) descriptionElement.appendChild(descriptionText) placemarkElement.appendChild(descriptionElement) pointElement = kmlDoc.createElement('Point') placemarkElement.appendChild(pointElement) coorElement = kmlDoc.createElement('coordinates') # This geocodes the address and adds it to aelement. coordinates = geocode(address) coorElement.appendChild(kmlDoc.createTextNode(coordinates)) pointElement.appendChild(coorElement) documentElement.appendChild(placemarkElement) # This writes the KML Document to a file. kmlFile = open(fileName, 'w') kmlFile.write(kmlDoc.toprettyxml(' ')) kmlFile.close() if __name__ == '__main__': createKML('1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA', 'google.kml')
Weitere wichtige Punkte
Zeitliche Abfolge der Geocodierungsanforderungen
Für Geocoding-Anfragen gelten die täglichen Limits für die maximale Abfragerate des Geocoders. Weitere Informationen zu diesen Beschränkungen finden Sie in der Dokumentation zur Google Geocoding API. Damit Sie nicht zu schnell Anfragen an den Geocoder senden, können Sie eine Verzögerung zwischen den einzelnen Geocode-Anfragen festlegen. Sie können diese Verzögerung jedes Mal erhöhen, wenn Sie den Status OVER_QUERY_LIMIT
erhalten, und eine while
-Schleife verwenden, um sicherzustellen, dass Sie eine Adresse erfolgreich geocodiert haben, bevor Sie zur nächsten Adresse wechseln.
Änderung des zugrunde liegenden Landes
Der Geocoder ist so programmiert, dass die Ergebnisse je nach Ursprungsdomain unterschiedlich gewichtet werden.
Wenn Sie beispielsweise „syracuse“ in das Suchfeld auf maps.google.com eingeben, wird die Stadt „Syracuse, NY“ geografisch codiert. Wenn Sie dieselbe Anfrage auf maps.google.it (der Domain für Italien) eingeben, wird die Stadt „Siracusa“ auf Sizilien gefunden. Sie erhalten dieselben Ergebnisse, wenn Sie diese Anfrage über HTTP-Geocoding an maps.google.it anstelle von maps.google.com senden. Dazu müssen Sie die Variable mapsUrl
im obigen Beispielcode ändern.
Weitere Informationen zur Regionsgewichtung finden Sie in der Dokumentation zur Geocoding API.
Hinweis:Sie können keine Anfrage an einen nicht vorhandenen maps.google.*-Server senden. Achten Sie also darauf, dass eine Länderdomain vorhanden ist, bevor Sie Ihre Geocoding-Anfragen dorthin weiterleiten. Informationen zur Geocodierung nach Land finden Sie in diesem Beitrag.
Fazit
Mit dem obigen Code können Sie jetzt eine Adresse mit Python geocodieren, daraus eine KML-Datei <Placemark>
erstellen und sie auf der Festplatte speichern. Wenn Sie mehr Adressen pro Tag geocodieren müssen, als die Grenzwerte zulassen, oder wenn der Google-Geocoder die gewünschten Regionen nicht abdeckt, sollten Sie zusätzliche Geocoding-Webdienste in Betracht ziehen.
Nachdem Sie nun wissen, wie Sie Ihre Adressen geocodieren, können Sie sich die Artikel KML im Google Mashup Editor verwenden und KML mit PHP und MySQL erstellen ansehen. Wenn Sie Probleme mit diesem Tutorial haben oder Fragen dazu haben, posten Sie bitte im Stack Overflow-Forum.