Indirizzi di geocodifica da utilizzare in KML

Mano Marks, team geografico di Google
Scritto: dicembre 2007
Ultimo aggiornamento: dicembre 2013

Obiettivo

Questo tutorial è destinato agli sviluppatori che hanno dimestichezza con i linguaggi di script e vogliono imparare a utilizzare l'API Google Geocoding per geocodificare gli indirizzi e incorporarli in un file KML. Anche se gli esempi di codice sono 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, consentendo di indicare gli indirizzi su una mappa. Ti consigliamo di geocodificare gli indirizzi e inserirli direttamente in un file KML. Ciò accade spesso, ad esempio, quando i dati vengono inseriti in un modulo e quando generi file KML in risposta alle richieste. Questi file KML potrebbero essere archiviati in un database, in un file system o restituiti a un NetworkLink che si connette al tuo file. Tieni presente che, quando utilizzi questa tecnica, devi rispettare i Termini di servizio dell'API Geocoding, poiché esistono alcune limitazioni relative al tempo di archiviazione dei risultati, nonché il numero di elementi che puoi geocodificare ogni giorno.

Questo tutorial mostra come utilizzare Python per prendere la stringa "1600 Amphitheatre Pkwy, Mountain View, CA 94043" e trasformarla in questo:

<?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>

Crea un documento KML

KML è un linguaggio di markup XML, per cui possiamo usare le funzioni Python incorporate in xml.dom.minidom per creare un documento KML. Il punto minimo di Python è l'implementazione del DOM, mentre il DOM è supportato nella maggior parte dei linguaggi di programmazione, quindi questo processo dovrebbe essere facile da trasferire in un altro linguaggio di programmazione. La procedura è la seguente:

  1. Crea il documento utilizzando l'xml.dom.minidom.Document() di Python.
  2. Crea l'elemento principale <kml> utilizzando createElementNS.
  3. Aggiungilo al documento utilizzando appendChild.
  4. Crea un elemento Documento utilizzando createElement.
  5. Aggiungilo all'elemento <kml> utilizzando appendChild.
  6. Per ogni indirizzo, crea un elemento <Placemark> utilizzando createElement e aggiungilo all'elemento Document. Quindi, crea un elemento <description>, assegnagli il valore dell'indirizzo e aggiungilo all'elemento <Placemark>.
  7. Crea un elemento <Point>, aggiungi un elemento <coordinates> secondario e aggiungilo all'elemento <Placemark>.
  8. Invia l'indirizzo al Geocoder dell'API di Google Maps, che invia una risposta in formato JSON o XML. Usa urllib.urlopen() per recuperare il file e leggerlo in una stringa.
  9. Analizza la risposta ed estrai gli elementi di longitudine e latitudine.
  10. Crea un nodo di testo nell'elemento <coordinates> e assegna la relativa stringa di longitudine/longitudine come valore.
  11. Scrivi il documento KML in un file di testo.

Codice Python di esempio

Tieni presente che il codice di esempio seguente utilizza una variabile fittizia fittizia: devi sostituire questa chiave con la tua chiave.

Il codice campione per la geocodifica con Python 2.7 e output JSON è mostrato di seguito:

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 a  element.
  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

Tempistiche delle richieste di geocodifica

Le richieste di geocodifica sono soggette ai limiti giornalieri massimi relativi alla frequenza di query del geocodificatore. 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 loop while per assicurarti che l'indirizzo sia stato geocodificato correttamente prima di passare a quello successivo.

Modifica del paese di base

Il geocodificatore è programmato per differenziare i risultati in base al dominio di origine. Ad esempio, se inserisci "siracusa" nella casella di ricerca di maps.google.com, verrà impostata la geocodifica di "Siracusa, NY", mentre se inserisci la stessa query su maps.google.it (il dominio italiano), troverai la città di "Siracusa" in Sicilia. Otterresti gli stessi risultati inviando la query tramite geocodifica HTTP a maps.google.it anziché a maps.google.it. Per farlo, modifica la variabile mapsUrl nel codice di esempio riportato sopra. Consulta la documentazione dell'API Geocoding per ulteriori informazioni sulla Differenziazione per regione.

Nota: non puoi inviare una richiesta a un server Maps.google.* inesistente, quindi assicurati che esista un dominio del paese prima di reindirizzare le query di geocodifica al suo interno. Per informazioni sul supporto geografico per paese, leggi questo post.

Conclusione

Utilizzando il codice sopra, ora puoi geocodificare un indirizzo utilizzando Python, creare un file KML <Placemark> e utilizzarlo su disco. Se hai bisogno di geocodificare più indirizzi al giorno rispetto a quanto consentito dai limiti o se il geocodificatore di Google non copre le regioni che ti interessano, valuta la possibilità di utilizzare servizi web di geocodifica aggiuntivi.

Ora che sai come geocodificare i tuoi indirizzi, consulta gli articoli su Utilizzo di KML in Google Mashup Editor e Utilizzo di PHP e MySQL per creare KML. In caso di problemi o domande su questo tutorial, pubblica un post sul forum di Stack Overflow.