Introduzione:
Dopo aver analizzato il geocoding vi HTTP in questo post
ora passiamo alle directions ossia alla generazione di percorsi (indicazioni stradali).
Il funzionamento è molto semplice: Si da in input un tragitto e si ottiene in ritorno una polyline.
Cos'è una polyline?Una polyline è una serie di cooridnate composte da coppie di numeri (latitudine, longitudine) che genera un percorso stradale.
Come ottenere una polyline via HTTP?
Per farlo lato server (ed immagazzinare direttamente i dati sul DB) ho trovato che è sufficiente fare una chiamata all'url http://maps.google.com/maps/nav
i seguito una lista dei parametri che è possibile passare (in GET) a questo url per ottenere diverse risposte.
q: Il percorso che si vuole cercare nella forma "from:place to:place to:place..... to:place". I "to:place" intermedi rappresentano tappe intermedie del viaggio mentre il "from:place" il punto di partenza e l'ultimo "to:place" la destinazione,
key: La tua API key (qui
il link per crearla)
output: Il formato di output.
Le opzioni sono xml, kml, csv, o json.
- oe: La codifica dlel'output come utf8 ecc. (non documentato da Google)
Detto ciò ecco il mio codice Python (utilizzato da una vista di django) per effettuare il geocoding:
from urllib import *
from django.utils import simplejson
def getDirections(path):
path=path.encode('utf-8')
mapsUrl = 'http://maps.google.com/maps/nav'
query={'q':path,'output':'json','oe':'utf8','key':'YOURKEYGOESHERE',}
url = '?'.join([mapsUrl,urlencode(query)])
directions = simplejson.loads(urlopen(url).read())
return directions
Il parametro in ingresso (path) è il percorso che si vuole ricercare nella forma specificata sopra
Il valore di ritorno è un array contenente, oltre ad una gran quantita di dati sul percorso e le indicazioni testuali, anche la polyline rappresentante il percorso desiderato.
La comodità (utilizzando python e django) è che, scegliendo il formato
di ritorno json ed utilizzando la funzione simplejson.loads per la
decodifica, ottengo direttamente un dizionario strutturato come segue.
Nell'esempio la ricerca del percorso da casa mia all'università (ottenibile richiamando questo URL
)
{ "name":"from:via eolo camporesi 5 forli to:via sacchi cesena",
"Status":
{ "code":200,
"request":"directions"
},
"Placemark":
[
{ "id":"",
"address":"Via Eolo Camporesi, 5, 47100 Forlì FC, Italia",
"AddressDetails":
{ "Country":
{ "CountryNameCode":"IT",
"AdministrativeArea":
{ "AdministrativeAreaName":"Emilia Romagna",
"SubAdministrativeArea":
{ "SubAdministrativeAreaName":"Forlì-Cesena",
"Locality":
{ "LocalityName":"Forlì",
"Thoroughfare":
{ "ThoroughfareName":"Via Eolo Camporesi, 5"},
"PostalCode":
{ "PostalCodeNumber":"47100"}
}
}
}
},
"Accuracy": 8
},
"Point":{"coordinates":[12.063465,44.210046,0]}
},
{ "id":"",
"address":"Via Sacchi, 47023 Cesena FC, Italia",
"AddressDetails":
{ "Country":
{ "CountryNameCode":"IT",
"AdministrativeArea":
{ "AdministrativeAreaName":"Emilia Romagna",
"SubAdministrativeArea":
{ "SubAdministrativeAreaName":"Forlì-Cesena",
"Locality":
{ "LocalityName":"Cesena",
"Thoroughfare":
{ "ThoroughfareName":"Via Sacchi"},
"PostalCode":{"PostalCodeNumber":"47023"}
}
}
}
},
"Accuracy": 6
},"Point":{"coordinates":[12.243441,44.140183,0]}
}
],
"Directions":
{ "copyrightsHtml":"Map data ©2008 Tele Atlas",
"summaryHtml":"19 km (circa 29 min)",
"Distance":{"meters":18836,"html":"19 km"},
"Duration":{"seconds":1753,"html":"29 min"},
"Routes":
[
{ "Distance":{"meters":18836,"html":"19 km"},
"Duration":{"seconds":1753,"html":"29 min"},
"summaryHtml":"19 km (circa 29 min)",
"Steps":
[
{ "descriptionHtml":"Procedi in direzione <b>nordovest<\/b> da <b>Via Eolo Camporesi<\/b> verso <b>Via Lamberto Valli<\/b>",
"Distance":{"meters":85,"html":"85 m"},
"Duration":{"seconds":16,"html":"16 sec"},
"Point":{"coordinates":[12.063460,44.210030,0]}
},
...
...
{ "descriptionHtml":"Svolta a <b>destra<\/b> a <b>Via Pier Paolo Pasolini<\/b>",
"Distance":{"meters":61,"html":"61 m"},
"Duration":{"seconds":12,"html":"12 sec"},
"Point":{"coordinates":[12.242520,44.139630,0]}
} ,
"End":{"coordinates":[12.243272,44.139530,0]}
}
]
}
}
La struttura comprende tutte le coordinate necessarie a creare la polyline organizzate in una lista di indicazioni step-by-step. Sarà quindi sufficiente accedere a data['Directions'] che conterrà un array con le indicazioni e le cooridnate dei vari punti della polyline.
Detto ciò è facile intuire per quale motivo con python e django
risulti così semplice immagazzinare nel DB o fare operazioni
server-side con i dati che google ci ritorna in formato json.
.
Quota questo articolo sul tuo sito
1. Nota Scritto da mmpiece , alle 15-07-2008 17:49 , IP: 93.149.107.104 ciao, ho fatto un po\' di test... la chiamata verso google ritorna una serie di punti che corrispondono ai \"punti di svolta\". Quindi se provi a riportare la polyline su google maps il risultato non è soddisfacente. Almeno io pensavo che graficasse il percorso sulla strada... invece non è così: se provi a fare un Roma Milano, la A1 diventa una retta. Non so se c\'è un parametro che mi manca nella chiamata. Un saluto e grazie comunque per il tuo lavoro. ciao |
2. Scritto da matteoparrucci , alle 16-07-2008 16:52 , IP: 81.208.83.217 Effettivamente anche io avevo notato questo tipo di comportamento. Se mi mandi un tuo indirizzo email dal form di contatto ti mando il codice per risolvere. |
3. Scritto da Daniele, alle 13-10-2009 17:33 , IP: 93.47.38.74 Ciao, grazie del tutorial. Anche io ho questo problema nel riportare sulla mappa la polyline ottenuta tramite i punti, potresti aiutarmi nel capire come correggere questo errore. Ciao, Daniele |
4. Ecco qua Scritto da Matteo Parrucci , alle 13-10-2009 17:40 , IP: 93.42.217.235 E' sufficiente che, al posto di json nell'output scegli kml e di seguito parsi l'xml risultante... Il codice python per farlo sarà il seguente: query={'hl':local,'gl':local,'saddr':saddr, 'daddr':daddr, 'output':'kml', 'oe':'utf8', 'key':'yourkeyhere',} url = '?'.join([mapsUrl,urlencode(query)]) cleanXML=re.sub('|', '', urlopen(url).read()); parser = etree.XMLParser() try: xmlDirections=etree.parse(StringIO(cleanXML), parser) polyline+=xmlDirections.xpath('/Document/Placemark/GeometryCollection/LineString/coordinates/text()') steps+=xmlDirections.xpath('/Document/Placemark/name/text()') except etree.XMLSyntaxError, e: return {'Status':{'code':400}} |
Solo gli utenti registrati possono lasciare commenti Loggati o registrati. |