Erstellt: Dezember 2007
Aktualisiert: Dezember 2013
Ziel
Diese Anleitung richtet sich an Entwickler, die mit Skriptsprachen vertraut sind und wissen möchten, wie sie mit der Google Geocoding API Adressen geocodieren und in eine KML-Datei einbinden können. Die Codebeispiele werden in Python dargestellt, lassen sich jedoch problemlos an die meisten anderen Programmiersprachen anpassen.
Geocoding bezeichnet die Umwandlung einer Adresse in eine Gruppe von Breiten- und Längengradkoordinaten, damit Adressen auf einer Karte dargestellt werden können. Sie können Adressen geocodieren und direkt in eine KML-Datei einfügen. Das ist z. B. üblich, wenn Daten in ein Formular eingegeben werden und Sie KML-Dateien als Antwort auf Anfragen generieren. Diese KML-Dateien können in einer Datenbank oder in einem Dateisystem gespeichert oder an einen NetworkLink zurückgegeben werden, der eine Verbindung zu Ihrer Datei herstellt. Beachten Sie, dass Sie bei der Verwendung dieser Technik die Nutzungsbedingungen für die Geocoding API einhalten müssen, da es einige Zeitbeschränkungen gibt, für die die Ergebnisse gespeichert werden können, und wie viele Elemente Sie pro Tag 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-Markup-Sprache. Daher können wir mit den integrierten Python-Funktionen von xml.dom.minidom ein KML-Dokument erstellen. Die Miniaturversion von Python ist eine DOM-Implementierung. DOM wird in den meisten Programmiersprachen unterstützt. Daher sollte dieser Vorgang einfach in eine andere Programmiersprache portiert werden können. Und so gehts:
- Erstellen Sie das Dokument mit
xml.dom.minidom.Document()
von Python. - Erstellen Sie das Stammelement
<kml>
mitcreateElementNS.
- Hängen Sie es mithilfe von
appendChild
an das Dokument an. - Erstellen Sie ein Dokumentelement mit
createElement
. - Hängen Sie es mithilfe von
appendChild
an das Element<kml>
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, der eine Antwort im JSON- oder XML-Format sendet.
Verwenden Sie
urllib.urlopen()
, um die Datei abzurufen und in einen String zu lesen. - Parst die Antwort und extrahiert die Längen- und Breitengradelemente.
- Erstellen Sie einen Textknoten im Element
<coordinates>
und weisen Sie den String für Längen- und Breitengrad als Wert zu. - Schreiben Sie das KML-Dokument in eine Textdatei.
Python-Beispielcode
Im folgenden Beispielcode wird eine Dummy-MapsKey-Variable verwendet. Sie müssen diesen Schlüssel durch Ihren eigenen Schlüssel ersetzen.
Im Folgenden sehen Sie Beispielcode für das Geocoding mit Python 2.7 und der 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 maximalen Tageslimits für die Abfragerate. Weitere Informationen zu diesen Limits finden Sie in der Dokumentation zur Google Geocoding API. Damit Abfragen nicht zu schnell an den Geocoder gesendet werden, können Sie zwischen den einzelnen Geocode-Anfragen eine Verzögerung angeben. Sie können diese Verzögerung jedes Mal erhöhen, wenn Sie einen OVER_QUERY_LIMIT
-Status erhalten, und mit einer while
-Schleife prüfen, ob Sie eine Adresse erfolgreich geocodiert haben, bevor Sie zur nächsten gelangen.
Änderung des zugrunde liegenden Landes
Der Geocoder ist so programmiert, dass die Ergebnisse je nach Ursprungsdomain gewichtet werden.
Wenn Sie beispielsweise „syracuse“ in das Suchfeld auf maps.google.com eingeben, wird die Stadt „Syracuse, NY“ geocodiert, während dieselbe Abfrage auf maps.google.it (Domain von Italien) zurückgegeben wird, wird die Stadt „Siracusa“ auf Sizilien gefunden. Sie erhalten dieselben Ergebnisse, wenn Sie die Abfrage über die HTTP-Geocodierung an maps.google.it statt an maps.google.com senden. Dazu ändern Sie einfach die Variable mapsUrl
im Beispielcode oben.
Weitere Informationen finden Sie in der Geocoding API-Dokumentation.
Hinweis:Sie können keine Anfrage an einen nicht vorhandenen „maps.google.*“-Server senden. Achten Sie also darauf, dass eine länderspezifische Domain vorhanden ist, bevor Sie Ihre Geocoding-Abfragen an sie weiterleiten. Informationen zur Geocodierung nach Land findest du in diesem Beitrag.
Fazit
Mit dem obigen Code kannst du jetzt mit Python eine Adresse geocodieren, daraus eine KML-<Placemark>
erstellen und sie auf dem Laufwerk speichern. Wenn Sie feststellen, dass Sie mehr Adressen pro Tag geocodieren müssen, als die Limits zulassen, oder der Google-Geocoder die gewünschten Regionen nicht umfasst, können Sie zusätzliche Geocoding-Webdienste verwenden.
Nachdem Sie nun wissen, wie Sie Ihre Adressen geocodieren, lesen Sie die Artikel KML im Google Mashup Editor verwenden und PHP und MySQL zum Erstellen von KML verwenden. Wenn Sie Probleme mit oder Fragen zu dieser Anleitung haben, posten Sie sie im Stack Overflow-Forum.