Autore: dicembre 2007
Aggiornamento: dicembre 2013
Obiettivo
Questo tutorial è rivolto agli sviluppatori che hanno familiarità con i linguaggi di scripting e vogliono imparare a utilizzare l'API Google Geocoding per geocodificare gli indirizzi e incorporarli in un file KML. Sebbene gli esempi di codice siano presentati in Python, possono essere adattati abbastanza facilmente alla maggior parte degli altri linguaggi di programmazione.
La geocodifica è il processo di conversione di un indirizzo in un insieme di coordinate di latitudine/longitudine, che consente di indicare gli indirizzi su una mappa. Potresti voler geocodificare gli indirizzi e inserirli direttamente in un file KML. Questo è comune, ad esempio, quando i dati vengono inseriti in un modulo e vengono generati file KML in risposta alle richieste. Questi file KML potrebbero essere memorizzati in un database, in un file system o restituiti a un NetworkLink che si connette al file. Tieni presente che quando utilizzi questa tecnica, devi rispettare i Termini di servizio dell'API Geocoding, in quanto esistono alcune limitazioni relative al periodo di tempo per cui i risultati possono essere archiviati, nonché al numero di elementi che puoi geocodificare ogni giorno.
Questo tutorial mostra come utilizzare Python per trasformare la stringa
"1600 Amphitheatre Pkwy, Mountain View, CA 94043
" in questo modo:
<?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>
Creare un documento KML
KML è un linguaggio di markup XML, quindi possiamo utilizzare le funzioni xml.dom.minidom integrate di Python per creare un documento KML. minidom di Python è un'implementazione DOM e DOM è supportato nella maggior parte dei linguaggi di programmazione, quindi questo processo dovrebbe essere facile da trasferire in un altro linguaggio di programmazione. Procedi nel seguente modo:
- Crea il documento utilizzando
xml.dom.minidom.Document()
di Python. - Crea l'elemento radice
<kml>
utilizzandocreateElementNS.
- Aggiungilo al documento utilizzando
appendChild
. - Crea un elemento Documento utilizzando
createElement
. - Aggiungilo all'elemento
<kml>
utilizzandoappendChild
. - Per ogni indirizzo, crea un elemento
<Placemark>
utilizzandocreateElement
e aggiungilo all'elementoDocument
. Poi, crea un elemento<description>
, assegnagli il valore dell'indirizzo e aggiungilo all'elemento<Placemark>
. - Crea un elemento
<Point>
, aggiungi un elemento secondario<coordinates>
e aggiungilo all'elemento<Placemark>
. - Invia l'indirizzo al geocodificatore dell'API Maps, che invia una risposta in formato JSON o XML.
Utilizza
urllib.urlopen()
per recuperare il file e leggerlo in una stringa. - Analizza la risposta ed estrai gli elementi di longitudine e latitudine.
- Crea un nodo di testo nell'elemento
<coordinates>
e assegna la stringa di longitudine/latitudine come valore. - Scrivi il documento KML in un file di testo.
Codice Python di esempio
Tieni presente che il codice di esempio riportato di seguito utilizza una variabile mapsKey fittizia. Dovrai sostituire questa chiave con la tua chiave.
Di seguito è mostrato un codice campione per il geocoding con Python 2.7 e output 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')
Altri aspetti da considerare
Tempistica delle richieste di geocodifica
Le richieste di geocodifica saranno soggette ai limiti giornalieri della frequenza massima di query del geocoder. Per ulteriori informazioni su questi limiti, consulta la documentazione dell'API Google Geocoding. Per assicurarti di non inviare query troppo rapidamente al geocodificatore, puoi specificare un ritardo tra ogni richiesta di geocodifica. Puoi aumentare questo ritardo ogni volta che ricevi
uno stato OVER_QUERY_LIMIT
e utilizzare un ciclo while
per assicurarti di aver
geocodificato correttamente un indirizzo prima di passare al successivo.
Modificare il paese di base
Il geocoder è programmato per distorcere i risultati a seconda del dominio di origine.
Ad esempio, se inserisci "Siracusa" nella casella di ricerca su maps.google.com, verrà geocodificata la città di
"Syracuse, NY", mentre se inserisci la stessa query su maps.google.it (il dominio italiano),
verrà trovata la città di "Siracusa" in Sicilia. Otterresti gli stessi risultati inviando la query
tramite geocodifica HTTP a maps.google.it anziché a maps.google.com,
cosa che puoi fare modificando la variabile mapsUrl
nel codice di esempio riportato sopra.
Per ulteriori informazioni sul region biasing, consulta la documentazione dell'API Geocoding.
Nota:non puoi inviare una richiesta a un server maps.google.* inesistente, quindi assicurati che esista un dominio nazionale prima di reindirizzare le query di geocodifica. Per informazioni sul supporto del geocodice per paese, consulta questo post.
Conclusione
Utilizzando il codice riportato sopra, ora puoi geocodificare un indirizzo utilizzando Python, creare un file KML
<Placemark>
e salvarlo su disco. Se ti accorgi di dover
geocodificare più indirizzi al giorno rispetto a quanto consentito dai limiti o che il geocoder di Google non copre le
regioni che ti interessano, valuta la possibilità di utilizzare servizi web di geocodifica aggiuntivi.
Ora che sai come geocodificare gli indirizzi, consulta gli articoli su Utilizzo di KML in Google Mashup Editor e Utilizzo di PHP e MySQL per creare KML. Se hai problemi o domande su questo tutorial, pubblicale nel forum di Stack Overflow.