Autor: grudzień 2007 r.
Aktualizacja: grudzień 2013 r.
Cel
Ten samouczek jest przeznaczony dla programistów, którzy znają języki programowania i chcą dowiedzieć się, jak korzystać z interfejsu API Google Geocoding do geokodowania adresów i umieszczania ich w pliku KML. Chociaż przykłady kodu są dostępne w języku Python, można je łatwo dostosować do większości języków programowania.
Geokodowanie to proces konwertowania adresu na zestaw długości i szerokości geograficznej, co umożliwia wskazanie adresów na mapie. Warto geokodować adresy i umieszczać je bezpośrednio w pliku KML. Takie sytuacje są częste, na przykład gdy dane są wprowadzane w formularzu i generujesz pliki KML w odpowiedzi na żądania. Pliki KML mogą być przechowywane w bazie danych, systemie plików lub zwrócone do NetworkLink, który łączy się z Twoim plikiem. Podczas korzystania z tej metody musisz przestrzegać Warunków korzystania z usługi interfejsu Geocode API, ponieważ obowiązują pewne ograniczenia dotyczące czasu przechowywania wyników oraz liczby elementów, które możesz przetworzyć na dane geograficzne każdego dnia.
W tym samouczku pokazujemy, jak użyć Pythona, aby pobrać ciąg „1600 Amphitheatre Pkwy, Mountain View, CA 94043
” i przekształcić go w ten:
<?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>
Tworzenie dokumentu KML
KML to język znaczników XML, dzięki czemu do utworzenia dokumentu KML możemy używać języka Python z wbudowanymi funkcjami xml.dom.minidom. Minimalem Pythona jest implementacja DOM. Jest on obsługiwany w większości języków programowania, więc przeniesienie go do innego języka programowania powinno być łatwe. Aby to zrobić:
- Utwórz dokument za pomocą
xml.dom.minidom.Document()
w Pythonie. - Utwórz element główny
<kml>
za pomocącreateElementNS.
- Dołącz go do dokumentu za pomocą polecenia
appendChild
. - Utwórz element w dokumencie za pomocą
createElement
. - Dołącz go do elementu
<kml>
za pomocąappendChild
. - Dla każdego adresu utwórz element
<Placemark>
za pomocą atrybutucreateElement
i dołącz go do elementuDocument
. Następnie utwórz element<description>
, przypisz mu wartość adresu i dołącz go do elementu<Placemark>
. - Utwórz element
<Point>
, dodaj podrzędny element<coordinates>
i dołącz go do elementu<Placemark>
. - Wyślij adres do Geokodera interfejsu API Map Google, który wyśle odpowiedź w formacie JSON lub XML.
Użyj
urllib.urlopen()
, aby pobrać plik i odczytać go w ciągu znaków. - Przeanalizuj odpowiedź i wyodrębnij elementy długości i szerokości geograficznej.
- Utwórz węzeł tekstowy w elemencie
<coordinates>
i przypisz jego długość i szerokość geograficzną jako jego wartość. - Zapisz dokument KML w pliku tekstowym.
Przykładowy kod w Pythonie
Przykładowy kod poniżej zawiera fikcyjną zmienną mapsKey – musisz zastąpić ten klucz własnym kluczem.
Poniżej znajduje się przykładowy kod do geokodowania w języku Python 2.7 i pliku JSON:
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')
Inne kwestie do rozważenia
Czas wykonywania żądań danych geograficznych
Żądania geokodowania będą podlegać maksymalnym dziennym limitom liczby zapytań geokodera. Więcej informacji na temat tych ograniczeń znajdziesz w dokumentacji interfejsu Google Geocoding API. Aby mieć pewność, że zapytania nie będą wysyłane zbyt szybko do geokodera, możesz określić opóźnienie między poszczególnymi żądaniami geokodowania. Możesz zwiększyć to opóźnienie za każdym razem, gdy otrzymasz stan OVER_QUERY_LIMIT
, i użyć pętli while
, aby mieć pewność, że kod został przetworzony prawidłowo, zanim przejdziesz do następnego.
Zmiana kraju podstawowego
Geokoder zaprogramuje wyniki odpowiednio do domeny źródłowej.
Na przykład wpisanie „syracuse” w polu wyszukiwania na maps.google.com spowoduje wysłanie danych geograficznych do „Syracuse w Nowym Jorku”, a to samo zapytanie na maps.google.it (domenie włoskiej) znajdzie na Sycylii miasto „Siracusa”. Aby uzyskać te same wyniki, wysyłaj zapytanie przez geokodowanie HTTP do maps.google.it zamiast maps.google.com. Możesz to zrobić, zmieniając zmienną mapsUrl
w przykładowym kodzie powyżej.
Aby dowiedzieć się więcej o Promowanie ze względu na region, zapoznaj się z dokumentacją interfejsu Geocoding API.
Uwaga: nie możesz wysłać żądania do nieistniejącego serwera map.google.*, dlatego zanim przekierujesz na to zapytanie geokodowania, sprawdź, czy istnieje domena krajowa. Pomoc dotyczącą geokodowania według krajów znajdziesz w tym poście.
Podsumowanie
Powyższy kod pozwala teraz przetworzyć dane geograficzne za pomocą Pythona, utworzyć z niego plik KML (<Placemark>
) i zapisać go na dysku. Jeśli okaże się, że musisz przetworzyć geograficznie więcej adresów dziennie, niż pozwala na to limit lub geokoder Google nie uwzględnia interesujących Cię regionów, rozważ skorzystanie z dodatkowych usług geokodowania.
Teraz już wiesz, jak geokodować adresy, więc zapoznaj się z artykułami o używaniu plików KML w Edytorze Google Mashup oraz o tworzeniu plików KML przy użyciu języka PHP i MySQL. Jeśli masz pytania lub problemy dotyczące tego samouczka, zadaj je na forum Stack Overflow.