Ops …. io e la mia vecchia bici siamo finiti sul sito di Mapillary

11 settembre 2015 2 commenti

Oggi il mio post su come farsi il proprio StreetView con Mapillary è stato ripreso nella sezione Community di Mapillary ….

MapillaryCommunityMember

Un minimo di soddisfazione ed orgoglio non lo nego … 🙂

 

Categorie:Open Data, Progetti Tag:

GFOSS DAY 2015 a Lecco il 28-29 Settembre 2015


Il GFOSS DAY 2015 si terrà a Lecco il 28-29 Settembre 2015

Il GFOSS DAY è un evento promosso dall’Associazione Italiana per l’Informazione Geografica Libera (GFOSS.it) della durata di due giorni, durante il quale vengono presentati i migliori lavori sull’utilizzo, lo sviluppo e la diffusione delle applicazioni libere e a codice aperto (Free and Open Source Software) in ambito GIS.

Vengono inoltre trattati argomenti sui dati aperti (Open Data) geografici. Durante la conferenza ci sarà anche la possibilità di conoscere nuovi software attraverso workshop, tenuti dai più importanti contributori italiani al software libero geografico. Lo scopo principale della manifestazione, giunta quest’anno alla settima edizione, è quello di coinvolgere imprese, enti pubblici, scuole, università, centri di ricerca, sviluppatori, cittadini, operatori del settore ed appassionati ai temi del software libero geografico e degli open data.

Il 25 Settembre si sarà la chiusura delle registrazioni!!

Per i contatti info@gfoss.it

Categorie:Conferenze Tag:

Una vecchia bici (da donna …), un tablet (in prestito …), un pò di tempo ed ecco come farsi lo StreetView del proprio Comune

30 agosto 2015 7 commenti

Quanti di voi già conoscono Mapillary? Quanti lo hanno già usato? Quanti vi hanno già contribuito? Se le risposte sono, “no”, “no” e “no” allora vi suggerisco di fare prima un giro informativo sul sito ufficiale del progetto, poi di tornare qui per capire come potete realizzare lo street view del vostro comune, quartiere, zona di interesse, ecc …

Citando Wikipedia riporto …. “… Mapillary (mapillary.com) è un servizio per condividere foto georeferenziate sviluppato da una startup, con sede a Malmö, Svezia. I suoi ideatori vogliono rappresentare il mondo intero (non solo le strade) con delle foto. Ritengono che per coprire tutti i posti interessanti nel mondo siano necessari un progetto crowd-sourced indipendente e un approccio sistematico alla copertura di aree interessanti. I servizi come Google, che utilizzano auto equipaggiate con speciali fotocamere, non riusciranno a coprire il mondo con dettaglio sufficiente. Secondo loro, la conoscenza locale è quasi imbattibile, e solo gli abitanti sanno cosa veramente sia importante quando si scatta una foto. Sono interessati alla copertura di qualunque posto all’aperto, e possono contribuiere a un sistema che rappresenta il mondo con un alto livello di dettaglio. La maggior parte della elaborazione di immagine è fatta lato server usando tecnologie Big data e di visione artificiale, rendendo la raccolta dei dati estremamente semplice per l’utente. Pertanto, Mapillary migliora con ciascuna nuova foto, perchè ogni nuova foto è messa in relazione con tutte le foto esistenti nel suo intorno. ……. I contributori possono installare la app Mapillary su smartphone Android o iPhone, sono noti casi di successo persino su dispositivi Kindle App Store, Jolla e Blackberry che possono eseguire app Android. Dopo la registrazione, l’utente può cominciare a scattare foto ….

Quindi in sostanza Mapillary è:

  • un sistema crowd-sourced per raccogliere fotografie georiferite nel mondo e realizzare un’alternativa al prodotto Street View di Google
  • un’app di semplice utilizzo con cui fare fotografie, o serie di fotografie, delle zone di interesse

Le immagini su Mapillary possono essere usate secondo la licenza internazionale Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA). Un permesso speciale è concesso per derivare dati dalle foto per contribuire ad OpenStreetMap. Le tracce GPX possono essere usate senza restrizioni. La licenza è stata cambiata il 29 aprile 2014 da CC-BY-NC a CC-BY-SA.

Il sistema di stà rapidamente diffondendo in giro per il mondo …

Mapillary-world

…. sicuramente in evidenza l’Europa, in particolare dalla Germania andando verso nord ….


mapillary-europe

mentre in Italia è ancora poco presente ed in modo non strutturato.

mapillary-italy

Tuttavia è un sistema che, con davvero poco sforzo e praticamente senza necessità di nessun background tecnico (ad esempio è molto più semplice che non mappare su OpenStreetMap con ID o con JOSM ….), permette di produrre risultati interessanti ed immediatamente visibili, anche perchè i tools che Mapillary stà pian piano mettendo a disposizione (o ha in sviluppo ….), stanno migliorando ed aumentando così come pure la disponibilità di API ne permette un uso anche a terzi (canale ancora poco utilizzato a dire la verità, forse legato al fatto che deve aumentare la disponibilità di zone completamente e ben mappate).

Nella sostanza è sufficiente saper fare delle foto usando uno smartphone / tablet ed usare qualche piccola accortezza: la app di Mapillary permette di fare foto “singole” o “sequenze” (queste si possono catturare ogni 2 secondi camminando, andando in bicicletta, andando in auto, ovviamente in questi ultimi due casi è necessario fissare in un qualche modo il dispositivo ….).

Terminata la sessione di mapping, è possibile rivedere le fotografie, elminare quelle venute male e provvedere all’upload sul server: dopo qualche ora le vostre fotografie sono già disponibili ….. a chiunque!!

Mapillary fà in realtà molto di più ma non mi dilungo sui dettagli e, come detto in precedenza, vi rimando al sito.

Partendo da questi presupposti ho provato a vedere cose riuscivo a fare nel mio piccolo comune cosa che, per chi interessato, può tranquillamente replicare per la propria area di interesse.

Ecco cosa ho utilizzato:

  • una vecchia bici da donna
  • un tablet (in prestito, nello specifico un IPAD Mini …)
  • un supporto per il tablet da montare sulla bici (per evitare che cadesse): unica spesa fatta (circa 30 Euro)
  • qualche ora libera per girare in bici per le strade del comune (si può anche ottenere lo stesso risultato andando a piedi o in automobile)

Ecco alcune immagini del miscuglio di tecnologie 1.0 e 2.0 …. 🙂

SAMSUNG

SAMSUNG

Il risultato finale è questo (cliccare sull’immagine per aprire Mapillary sulla zona …) ….

Mapillary-Carignano

Ed ecco qualche dettaglio ….

Carignano-1

Carignano-2

Carignano-3

Quindi posso dire (con un pò di orgoglio ?!), che ora il mio comune è praticamente uno dei pochi comuni Italiani  completamente mappato su Mapillary!

Ovviamente ora si può migliorare aggiungendo immagini di dettaglio dei punti di maggiore interesse e chiunque, oltre me, lo può e lo potrà fare ed il sistema migliorerà da solo.

Qualche dettaglio / suggerimento per chi volesse replicare:

  • cercate, nell’ambito del possibile, di evitare di fotografare persone, targhe automobilistiche, ecc … In ogni caso, una volta fatto l’upload delle immagini su Mapillary, è possibile controllare le proprie immagini ed intervenire, in post processing, editando le immagini “oscurando” (blur) parti di esse per rendere irriconoscibili volti, targhe automobilistiche, particolari, ecc … (Mapillary cerca di farlo per voi in modo automatico ma è comunque sempre consigliabile una verifica ed un intervento umano ….)
  • cercate, nell’ambito del possibile, di catturare immagini o sequenze in orari con poco affollamento
  • percorrete le vie in entrambi i sensi di marcia: se possibile anche catturando immagini lateralmente quindi l’optimum sarebbe percorrere una via in entrambi i sensi di di marcia catturando immagini frontalmente e poi, nuovamente percorrere la via catturando immagini letaralmente. Ecco un esempio di quello che si ottiene ruotando a 360° sullo stesso punto

DettaglioCarignano1

DettaglioCarignano2

DettaglioCarignano3

DettaglioCarignano4

Particolare interessante presente da qualche mese, è che Mapillary prova a riconoscere i vari segnali stradali presenti sulle vostre fotografie, permettendo così di avere la georeferenziazione degli stessi (ovviamente è bene anche qui fare un post processing per verificare la bontà del riconoscimento automatico

CarignanoSegnali

Al netto di iniziative “singole” come la mia, fattibili su aree mediamente piccole, Mapillary si presta a “eventi” di mapping di gruppo, ad esempio quello recentemente svoltosi presso l’area archeologica di Pompei che ha permesso di portare sulla piattaforma le immagini georiferite di una parte significativa dell’area archeologica visitabile.

L’esperienza è quindi replicabile presso altre aree di particolare interesse.

Lo stesso principio di potrebbe applicare coinvolgendo le scuole, magari nei periodi delle loro gite scolatische o in aree di particolare interesse che si voglia valorizzare coinvogendo gli studenti, magari associandovi dei meccanismi di “gaming” per rendere la cosa più interessante.

Da provare ……. in fondo basta veramente poco!

We want also the National Catalogue for Spatial Data in the INSPIRE register!


A year and a half ago (precisely on February 11, 2014), based on the initiative of some Italian geomatics fans, a petition was launched to denounce the lack of presence of Italy in the INSPIRE register: italy4INSPIRE

rndt4inspire

This initiative, which has rapidly gathered more than 100 adhesions, not only by individuals but also by associations and communities of the geomatics sector, aimed to highlight the fact that it was enough just a grain of sand in the cumbersome and infernal bureaucratic machine (the failure to send an email by ghost responsible), to make yet another fool to our country in the international arena.

And the joke was that Italy had already fulfilled so far the sectoral legislation creating the “National Catalogue for Spatial Data” ( RNDT – Repertorio Nazionale dei Dati Territoriali) and therefore could even get us to the finish among the first in Europe. Among other things, the initiative was echoed in two parliamentary questions, submitted on 4 July and 12 November 2014 , remained unanswered.

What happened after so long?

That we took the usual “patch” Italian style, registering the only endpoint of the National Geoportal (which counts a few hundred metadata), continuing to ignore RNDT, despite European law allows each Member State to present more than one National access point.

Why?

Since the Decree 32/2010 (which transposed the INSPIRE Directive in Italy) refers explicitly to RNDT and that this, in consistency and continuity with the monitoring “envisaged by the Commission” 2014, signaled 6140 metadata and in 2015 more than 17940 metadata are reported, why it was not registered yet?

We wonder if someone with a name, a surname and a face, will never give an answer and, above all, will manage to achieve the goal of registering the RNDT endpoint in the INSPIRE register.

RNDT4INSPIRE_h

Categorie:Uncategorized Tag:,

Vogliamo anche RNDT nel registro INSPIRE! #RNDT4INSPIRE


Un anno e mezzo fa (per la precisione il giorno 11 febbraio 2014), su iniziativa di alcuni appassionati geomatici italiani, veniva lanciata una petizione per denunciare la mancata presenza dell’Italia nel registro INSPIRE: italy4INSPIRE

rndt4inspire
Questa iniziativa, che ha raccolto rapidamente oltre 100 adesioni, non solo di singole persone ma anche di associazioni e comunità del settore geomatico, puntava a mettere in risalto il fatto che bastava un granellino di sabbia nella farraginosa ed infernale macchina burocratica (il mancato invio di una mail da parte di fantomatici responsabili), per far fare al nostro Belpaese l’ennesima figuraccia in campo internazionale.

E la beffa era che l’Italia aveva adempiuto già da tempo alla normativa di settore realizzando il “Repertorio Nazionale dei Dati Territoriali” (RNDT) e quindi poteva addirittura farci arrivare al traguardo tra i primi in Europa.

Tra l’altro, l’iniziativa veniva ripresa anche in due interrogazioni parlamentari, presentate rispettivamente il 4 luglio e il 12 novembre 2014, rimaste tuttora senza risposta.

Cosa è successo a distanza di così tanto tempo?

Che ci abbiamo messo la solita “pezza” all’Italiana, registrando il solo endpoint del Geoportale Nazionale (che annovera poche centinaia di metadati), continuando a ignorare RNDT, nonostante la legge europea consenta ad ogni Stato Membro di esporre più di un punto di accesso nazionale.

Perché? Visto che il D.lgs. 32/2010 richiama esplicitamente RNDT e che questo in uniformità e continuità con il monitoraggio “previsto dalla Commissione” 2014 segnalava 6140 metadati e quello 2015 ne riporta oltre 17940, perché non è stato ancora registrato? Chissà se qualcuno, con un nome, un cognome ed una faccia, riuscirà mai a dare una risposta e, soprattutto, a raggiungere l’obiettivo di registrare l’endpoint RNDT nel registro INSPIRE.

RNDT4INSPIRE_h

Categorie:Progetti Tag:,

OpenStreetMap, GeoPortale Nazionale e OpenRefine: tutorial per come farsi del geocoding in casa partendo da un elenco di indirizzi


Partendo dal mio ultimo post “Come convertire indirizzi in coordinate geografiche (geocoding) usando i servizi WFS del GeoPortale Nazionale e Open Refine“, che ha tratto ispirazione da quest’altro post “Using OpenRefine to geocode your data with Google and OpenStreetMap API”, ho provato a mettere insieme le cose per cercare di ottenere una sorta di “guida” su come, partendo da un foglio elettronico in  cui vi siano dei dati da georiferire per indirizzo, ottenerne la georeferenziazione, con la migliore precisione possibile e al più approssimata  al Comune.

Ecco quali sono i criteri che ho provato a seguire:

  1. se il dato è possibile georiferirlo usando i dati di OpenStreetMap e quindi le  MapQuest Nominatim API, questa viene considerata la prima e migliore delle opzioni: occorre tuttavia appurare che la georeferenziazione avvenga per “osm_type=node”, e quindi per punto. Sostanzialmente se quello specifico numero civico esiste tra i dati di OpenStreetMap, questo viene considerato il dato migliore
  2. se il dato non è georiferibile usando i dati di OpenStreetMap e quindi le  MapQuest Nominatim API per “nodo”, si verifica se lo sia usando i servizi WFS del GeoPortale Nazionale: se lo è viene questa viene considerata come seconda opzione
  3. se il dato non è georiferibile usando i dati di OpenStreetMap e quindi le  MapQuest Nominatim API per “nodo”, e nemmeno usando i servizi WFS del GeoPortale Nazionale, si verifica se lo sia usando i dati di OpenStreetMap e quindi le API di Nominatim per “osm_type=way”, e quindi per interpolazione sulla strada: se lo è viene questa viene considerata come terza opzione
  4. se il bene non è georiferibile nè usando i dati di OpenStreetMap e quindi le  MapQuest Nominatim API per “nodo”, nè usando i servizi WFS del GeoPortale Nazionale, e nemmeno usando i dati di OpenStreetMap e quindi le  MapQuest Nominatim API per “osm_type=way”, si verifica se lo sia usando e API di Nominatim georeferendo per Comune: se lo è (e lo dovrebbe essere sempre …..), viene questa viene considerata come quarta opzione ovviamente con un grado di approssimazione molto elevato e grossolano.

In questo modo, classificando la tipologia di metodo di georeferenziazione, possiamo differenziare per  la “qualità” della precisione con cui quel dato è stato georiferito per indirizzo.

Come detto in precedenza si ipotizza di partire da un foglio elettronico che contenga i dati da georiferire. La sua struttura dati può essere libera: nel seguito si indicheranno quali sono i nuovi campi da creare che, al termine delle operazioni potranno essere eliminati, lasciando i soli campi contenenti le coordinate degli indirizzi e la tipologia di modalità di geocodifica.

  1. aprire il foglio elettronico in Google Refine / Open Refine e generare un progetto
  2. creare una colonna con nome “Comune-work-1” contenente il nome del comune
  3. creare una colonna con nome “Comune-work-2” partendo dalla colonna “Comune-work-1” applicando la formula replace(value,' ','%20')
  4. modificare il contenuto della colonna “Comune-work-2” applicando la formula replace(value,'\'','%27'). NOTA: se nel nome del comune compaiono altro caratteri particolari, replicare sostituendo le rispettive sequenze di escape.
  5. creare una colonna con nome “Ubicazione-work-1” contenente la ubicazione (es. Via Roma), SENZA civico
  6. creare una colonna “Ubicazione-work-2” partendo dalla colonna “Ubicazione-work-1” eliminando gli spazi sostituendoli con il carattere di escape %20, eliminando gli apostrofi sotituendoli con il carattere di escape %27, ecc … Occorre lavorare un pò direttamente in Refine: se non ci sono info o se ci sono info non corrette mettere come valore “xxx”
  7. creare una colonna con nome “Civico-work-1” contenente il SOLO numero civico. Occorre lavorare un pò in Excel o Refine: se non ci sono info o se ci sono info non corrette mettere “xxx”
  8. creare una colonna “ResponsePCN” il cui contenuto è il risultato delle query WFS al PCN, fatte ogni 1500 millisecondi (o superiore …) ottenute da 'http://wms.pcn.minambiente.it/ogc?map=/ms_ogc/wfs/Numeri_Civici_2012.map&VERSION=1.1.0&service=wfs&request=GetFeature&TYPENAME=IN.NUMERICIVICI.2012&Filter=%3Cogc:Filter%20xmlns:ogc=%22http://www.opengis.net/ogc%22%3E%3CAND%3E%3Cogc:PropertyIsEqualTo%20matchCase=%22false%22%3E%3Cogc:PropertyName%3Ecomune%3C/ogc:PropertyName%3E%3Cogc:Literal%3E' + cells["Comune-work-2"].value + '%3C/ogc:Literal%3E%3C/ogc:PropertyIsEqualTo%3E%3Cogc:PropertyIsEqualTo%20matchCase=%22false%22%3E%3Cogc:PropertyName%3Enome%3C/ogc:PropertyName%3E%3Cogc:Literal%3E' + cells["Ubicazione-work-2"].value + '%3C/ogc:Literal%3E%3C/ogc:PropertyIsEqualTo%3E%3Cogc:PropertyIsLike%20matchCase=%22false%22%20wildCard=%22*%22%20singleChar=%22.%22%20escapeChar=%22!%22%3E%3Cogc:PropertyName%3Ecivico%3C/ogc:PropertyName%3E%3Cogc:Literal%3E*' + cells["Civico-work-1"].value + '*%3C/ogc:Literal%3E%3C/ogc:PropertyIsLike%3E%3C/AND%3E%3C/ogc:Filter%3E'
  9. creare una colonna “Lat-PCN” partendo dalla colonna “ResponsePCN” ed applicare la seguente regola: toNumber(split(trim(substring(value.parseHtml().select("gml|Point gml|pos")[0].toString(),10, -10)), " ")[0])
  10. creare una colonna “Lon-PCN” partendo dalla colonna “ResponsePCN” ed applicare la seguente regola: toNumber(split(trim(substring(value.parseHtml().select("gml|Point gml|pos")[0].toString(),10, -10)), " ")[1])
  11. usare le facets “Text” sulla colonna “Lat-PCN“: selezionare le righe “blank” e valorizzare a 0
  12. usare le facets “Text” sulla colonna “Lon-PCN“: selezionare le righe “blank” e valorizzare a 0
  13. creare una colonna “AddressForOsmNominatim” da valorizzare con la seguente regola: cells["Ubicazione-work-2"].value + "%20" + cells["Civico-work-1"].value + "," + cells["Comune-work-2"].value + ",Italia"
  14. creare una colonna “ResponseNominatimForAddress” il cui contenuto è il risultato della query a Nominatim con la seguente chiamata: 'http://open.mapquestapi.com/nominatim/v1/search.php?format=json&q=' + cells["AddressForOsmNominatim"].value
  15. creare una colonna “Lat-OSM-Address-Node” partendo dalla colonna “ResponseNominatimForAddress” ed applicare la seguente regola: if(value.parseJson()[0].osm_type=="node",value.parseJson()[0].lat,"")
  16. usare le facets “Text” sulla colonna “Lat-OSM-Address-Node“: selezionare le righe “blank” e valorizzare a 0
  17. creare una colonna “Lon-OSM-Address-Node” partendo dalla colonna “ResponseNominatimForAddress” ed applicare la seguente regola: if(value.parseJson()[0].osm_type=="node",value.parseJson()[0].lon,"")
  18. usare le facets “Text” sulla colonna “Lon-OSM-Address-Node“: selezionare le righe “blank” e valorizzare a 0
  19. creare una colonna “Lat-OSM-Address-Way” partendo dalla colonna “ResponseNominatimForAddress” ed applicare la seguente regola: if(value.parseJson()[0].osm_type=="way",value.parseJson()[0].lat,"")
  20. usare le facets “Text” sulla colonna “Lat-OSM-Address-Way“: selezionare le righe “blank” e valorizzare a 0
  21. creare una colonna “Lon-OSM-Address-Way” partendo dalla colonna “ResponseNominatimForAddress” ed applicare la seguente regola: if(value.parseJson()[0].osm_type=="way",value.parseJson()[0].lon,"")
  22. usare le facets “Text” sulla colonna “Lon-OSM-Address-Way“: selezionare le righe “blank” e valorizzare a 0
  23. creare una colonna “CityForOsmNominatim” e valorizzare con la seguente regola: cells["Comune-work-2"].value + ",Italia&limit=1"
  24. creare una colonna “ResponseNominatimForCity” il cui contenuto è il risultato della query a Nominatim con la seguente chiamata: 'http://open.mapquestapi.com/nominatim/v1/search.php?format=json&q=' + cells["CityForOsmNominatim"].value
  25. creare una colonna “Lat-OSM-City” partendo dalla colonna “ResponseNominatimForCity” ed applicare la seguente regola: value.parseJson()[0].lat
  26. usare le facets “Text” sulla colonna “Lat-OSM-City“: selezionare le righe “blank” e valorizzare a 0
  27. creare una colonna “Lon-OSM-City” partendo dalla colonna “ResponseNominatimForCity” ed applicare la seguente regola: value.parseJson()[0].lon
  28. usare le facets “Text” sulla colonna “Lon-OSM-City“: selezionare le righe “blank” e valorizzare a 0
  29. creare una colonna “GeoRefType” e valorizzare cona la seguente regola: if(cells["Lon-OSM-Address-Node"].value!="0","OSM_NODE",(if(cells["Lon-PCN"].value!="0","GN",(if(cells["Lon-OSM-Address-Way"].value!="0","OSM-WAY","OSM-CITY")))))
  30. creare una colonna “Lat” e valorizzare cona la seguente regola: if(cells["Lat-OSM-Address-Node"].value!="0",cells["Lat-OSM-Address-Node"].value,(if(cells["Lat-PCN"].value!="0",cells["Lat-PCN"].value,(if(cells["Lat-OSM-Address-Way"].value!="0",cells["Lat-OSM-Address-Way"].value,cells["Lat-OSM-City"].value)))))
  31. creare una colonna “Lon” e valorizzare cona la seguente regola: if(cells["Lon-OSM-Address-Node"].value!="0",cells["Lon-OSM-Address-Node"].value,(if(cells["Lon-PCN"].value!="0",cells["Lon-PCN"].value,(if(cells["Lon-OSM-Address-Way"].value!="0",cells["Lon-OSM-Address-Way"].value,cells["Lon-OSM-City"].value)))))
  32. applicare la trasformazione “To number” alle celle della colonna “Lat
  33. applicare la trasformazione “To number” alle celle della colonna “Lon
  34. cancellare, se desiderato, tutte le colonne di lavoro mantenendo solo le colonne “GeoRefType“, “Lat” e “Lon

Quanto descritto sopra ha valenza generale e può essere modificato a piacere, sia alterando i criteri utilizzati per dare le priorità di georeferenziazione tra le diverse alternative, sia, qualora si individuassero altri servizi WFS di esposizione dei numeri civici georiferiti in aggiunta a quelli del GeoPortale Nazionale, per estendere le fonti utilizzate.

A questo punto non vi resta che provare con dei vostri dati (se ci sono errori o cose non chiare segnalate e chiedete …. proviamo a risolvere insieme), e mettere così le vostre informazioni, delle quali al momento avete solo un indirizzo, su una qualunque mappa desideriate.

Enjoy!

 

Come convertire indirizzi in coordinate geografiche (geocoding) usando i servizi WFS del GeoPortale Nazionale e Open Refine

29 maggio 2015 4 commenti

Quante volte si ha la necessità di convertire un indirizzo nella corrispondente coppia di cooordinate e quindi,  in un dato spaziale riutilizzabile?

E quante volte si avrebbe la necessità di  farlo su un insieme di indirizzi?

E quanti dati si potrebbero georiferire per indirizzo, portandoli inizialmente su una mappa, per poi usarli ed analizzarli con funzionalità “spaziali” incrociandoli con altri dati georiferiti?

Certo, a queste domande si potrebbe rispondere (e spesso si opera in tal modo ….), dicendo ” …. ma ci sono i servizi di geocoding di Google (o similari)!!“.

Vero, cosa buona e giusta, non si fà peccato, e chissà quante volte questi sono stati (e saranno …), utilizzati anche da coloro che abitualmente lavorano con i dati spaziali, compreso chi sta scrivendo questo post.

Però è altrettanto vero che esistono modalità alternative le quali possono fare uso di open data o open services pubblicamente disponibili.

Semplicemente ……. è meno noto e quindi non le si utilizza, sprecando piccole o grandi miniere che sono state faticosamente messe pubblicamente disponibili a tutti, e che quindi sono a tutti gli effetti ……”roba” nostra!

Con queste modalità è inoltre possibile evitare i limiti di licenza che si devono, professionalmemte, rispettare qualora si utilizzino le modalità di geocoding che si avvalgono, ad esempio, delle Google Geocoding API che riporto, per sintesi e chiarezza, in modo integrale (qui il link per il riferimento ufficiale completo) :

==================================================================================================

The Google Geocoding API has the following limits in place:

Users of the free API:
  • 2500 requests per 24 hour period.
  • 5 requests per second.
Google Maps API for Work customers:
  • 100 000 requests per 24 hour period.
  • 10 requests per second.

Note: These limits apply to the Google Geocoding web service which is primarily intended for server-side geocoding. If you are geocoding data in response to user input on the web, or on a mobile device, consider using client side geocoding.

These limits are enforced to prevent abuse and/or repurposing of the Geocoding API, and may be changed in the future without notice. Additionally, we enforce a request rate limit to prevent abuse of the service. If you exceed the 24-hour limit or otherwise abuse the service, the Geocoding API may stop working for you temporarily. If you continue to exceed this limit, your access to the Geocoding API may be blocked.

For guidance on strategies for optimizing quota usage, please refer to Usage Limits for Google Maps API Web Services and Geocoding Strategies.

The Geocoding API may only be used in conjunction with a Google map; geocoding results without displaying them on a map is prohibited. For complete details on allowed usage, consult the Maps API Terms of Service License Restrictions.

==================================================================================================

La frase The Geocoding API may only be used in conjunction with a Google map è fortemente vincolante e, sinceramente, non so quanto sia nota e rispettata.

Questo non vuol dire che gli open data, o gli open services, sui civici georiferiti siano liberamente utilizzabili e siano privi di licenza, tutt’altro: hanno anch’essi le loro, spesso e volentieri non sono le licenze più “permissive” come potrebbe essere una Creative Commons — CC0 1.0 Universal, ma al tempo stesso spesso permettono, nei rispetto delle stesse, un utilizzo più ampio dei dati georiferiti rispetto ad esempio a quelle di BigG .

Partendo da questi presupposti e avendo ad esempio ipotetico una serie di informazioni, magari su un documento testuale o un foglio elettronico, per le quali si abbiano gli indirizzi comprensivi di nome comune, via e numero civico, cosa serve quindi per poter essere operativi ?

Direi che servono potenzialmente due cose (oltre ad un pò di pazienza e la voglia di sporcarsi un pò le mani ….):

  • degli open data relativi ai civici georiferiti
  • degli open services relativi ai civici che permettano di essere interrogati per indirizzo restituendo, possibilmente in un formato standard,  le rispettive coordinate in un qualche sistema di riferimento

Sul primo punto direi che mi sono già espresso e trovate riferimenti in proposito in altri post in questo stesso blog: la P.A si stà pian piano muovendo (un pò in ordine sparso a dire il vero ….), sulla base di questo stò, faticosamente, cercando di mantenere una raccolta di quelli che sono gli open data sui civici ad oggi disponibili sul territorio  nazionale ed esisterebbe anche la teorica disponibilità dei civici georiferiti open data prevista nell’elenco dei dataset dell’Agenda Digitale 2014, purtroppo al momento ampiamente disattesa.

Sul secondo, che è quello di maggior interesse per gli obiettivi di questo post, non esistono molti open services che permettano di fare un geocoding, ma, fortunamente, in questo caso viene in aiuto il GeoPortale Nazionale e, per la precisione, il servizio WFS dei civici, nello specifico denominato Numeri civici – Aggiornamento 2012. 

Per tale servizio sono resi disponibili:

NOTA: ovviamente dello stesso dataset esiste anche il servizio WMS che trovate, con lo stesso nome, in questo elenco http://www.pcn.minambiente.it/PCNDYN/catalogowms.jsp?lan=it

Le opportunità che tale servizio offre sono:

  • implementazione secondo protocolli di interoperabilità standard (WFS)
  • intera copertura nazionale

E’ quindi possibile, potenzialmente, inviare una richiesta WFS al servizio facendosi restituire le features che soddisfano alle condizioni di richiesta: sono restitituiti tutti i dati relativi alle features stesse, comprese le geometrie e quindi si possono ottenere le coordinate di un qualunque indirizzo sul territorio nazionale.

Nella pratica, andando poi a vedere nel dettaglio, non è detto che ci siano tutti tutti gli indirizzi, ma ci si augura che la copertura, come anche la qualità dell’informazione, sia in continua crescita.

La disponibilità di un tale servizio è comunque, e sicuramente, elemento prezioso e tanto vale provare ad usarlo.

La prima cosa da fare è sapere quelle che sono le caratteristiche (metadati), del servizio e queste le si possono ottenere con la seguente chiamata al servizio wfs:

http://wms.pcn.minambiente.it/ogc?map=/ms_ogc/wfs/Numeri_Civici_2012.map&service=wfs&request=getCapabilities

Il secondo passo è sapere come è strutturata l’informazione associata, questo per individuare i campi su cui elaborare la richiesta: questo lo si può ottenere con la seguente chiamata al servizio wfs:

http://wms.pcn.minambiente.it/ogc?map=/ms_ogc/wfs/Numeri_Civici_2012.map&service=wfs&request=DescribeFeatureType

A questo punto è possibile elaborare la query: un esempio è il seguente (l’indirizzo ricercato è Berbenno, Via Milano 55):

http://wms.pcn.minambiente.it/ogc?map=/ms_ogc/wfs/Numeri_Civici_2012.map&VERSION=1.1.0&service=wfs&request=GetFeature&TYPENAME=IN.NUMERICIVICI.2012&Filter=<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc"><AND><ogc:PropertyIsEqualTo matchCase="false"><ogc:PropertyName>comune</ogc:PropertyName><ogc:Literal>Berbenno</ogc:Literal></ogc:PropertyIsEqualTo><ogc:PropertyIsEqualTo matchCase="false"><ogc:PropertyName>nome</ogc:PropertyName><ogc:Literal>Via Milano</ogc:Literal></ogc:PropertyIsEqualTo><ogc:PropertyIsLike matchCase="false" wildCard="*" singleChar="." escapeChar="!"><ogc:PropertyName>civico</ogc:PropertyName><ogc:Literal>*55*</ogc:Literal></ogc:PropertyIsLike></AND></ogc:Filter>

la quale produce il seguente risultato (in evidenza la porzione di XML in cui vi sono le coordinate del punto)

<?xml version='1.0' encoding="ISO-8859-1" ?>
 <wfs:FeatureCollection
 xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
 xmlns:gml="http://www.opengis.net/gml"
 xmlns:wfs="http://www.opengis.net/wfs"
 xmlns:ogc="http://www.opengis.net/ogc"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://wms.pcn.minambiente.it/ogc?map=/ms_ogc/wfs/Numeri_Civici_2012.map&amp;SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=IN.NUMERICIVICI.2012&amp;OUTPUTFORMAT=text/xml;%20subtype=gml/3.1.1 http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
 <gml:boundedBy>
 <gml:Envelope srsName="EPSG:4326">
 <gml:lowerCorner>45.808287 9.575815</gml:lowerCorner>
 <gml:upperCorner>45.808287 9.575815</gml:upperCorner>
 </gml:Envelope>
 </gml:boundedBy>
 <gml:featureMember>
 <ms:IN.NUMERICIVICI.2012 gml:id="IN.NUMERICIVICI.2012.1225789">
 <gml:boundedBy>
 <gml:Envelope srsName="EPSG:4326">
 <gml:lowerCorner>45.808287 9.575815</gml:lowerCorner>
 <gml:upperCorner>45.808287 9.575815</gml:upperCorner>
 </gml:Envelope>
 </gml:boundedBy>
 <ms:boundary>
 <gml:Point srsName="EPSG:4326">
 <gml:pos>45.808287 9.575815</gml:pos>
 </gml:Point>
 </ms:boundary>
 <ms:id>13800026062251</ms:id>
 <ms:nome>Via Milano</ms:nome>
 <ms:civico>55</ms:civico>
 <ms:istat>03016023</ms:istat>
 <ms:cap>24030</ms:cap>
 <ms:comune>BERBENNO</ms:comune>
 <ms:nome_ted> </ms:nome_ted>
 <ms:provincia>BERGAMO</ms:provincia>
 <ms:regione>LOMBARDIA</ms:regione>
 </ms:IN.NUMERICIVICI.2012>
 </gml:featureMember>
 </wfs:FeatureCollection>

Nota tecnica solo per chi interessato: analizzando il contenuto del filtro WFS della richiesta si può notare che abbiamo tre condizioni in AND: in due casi si usa l’operatore ogc:PropertyIsEqualTo mentre in uno si usa invece l’operatore ogc:PropertyIsLike.

<AND>
 <ogc:PropertyIsEqualTo matchCase="false">
 <ogc:PropertyName>comune</ogc:PropertyName>
 <ogc:Literal>Berbenno</ogc:Literal>
 </ogc:PropertyIsEqualTo>
 <ogc:PropertyIsEqualTo matchCase="false">
 <ogc:PropertyName>nome</ogc:PropertyName>
 <ogc:Literal>Via Milano</ogc:Literal>
 </ogc:PropertyIsEqualTo>
 <ogc:PropertyIsLike matchCase="false" wildCard="*" singleChar="." escapeChar="!">
 <ogc:PropertyName>civico</ogc:PropertyName>
 <ogc:Literal>*55*</ogc:Literal>
 </ogc:PropertyIsLike>
</AND>

La ragione è legata al fatto che MapServer (che è l’application server GIS utilizzato dal GeoPortale Nazionale per esporre i servizi di interoperabilità OGC compliant), ha delle difficoltà a trattare numeri espressi come stringhe e quindi occorre necessariamente usare questo workaround: il dettaglio è trattato qui: http://osgeo-org.1560.x6.nabble.com/How-to-use-filter-encoding-in-MapServer-in-a-WFS-query-td5205424.html

 A questo punto quello che resta da fare sono due ulteriori passi:

  • automatizzare le richieste nel caso, tipico, di un elenco / insieme di dati geroriferiti per indirizzo
  • estrarre le coordinate dei civici così georiferiti dall’XML di risposta

Per entrambi può tornare utile come tool Open Refine da un lato, e le preziose indicazioni di questo post “Using OpenRefine to geocode your data with Google and OpenStreetMap API” da cui ho preso spunto ed ispirazione dopo aver assistito al mini-corso della sezione di  “da UglyData a Mappa in un pomeriggio: passando per OpenRefine, R e Turf.JS” (tenuto da Simone Cortesi, Andrea Zedda, Michele Ferretti e con la partecipazione di Fabrizio Tambussa e Stefano Sabatini che ringrazio in blocco…..), svoltosi nella giornata di chiusura del raduno Spaghetti Open Data 2015 (SOD15) a Bologna.

Il post di cui sopra illustra come fare geocoding usando i servizi di geocoding  Google Maps e OpenStreetMap, nello specifico MapQuest Nominatim API: ho pensato di provare ad estenderlo usando come servizio di geocoding il servizio WFS dei civici del GeoPortale Nazionale.

Premessa: non descrivo qui nel dettaglio come usare OpenRefine, è out-of-scope di questo post. Sulla rete è disponibile ampio materiale illustrativo e tutorial per muovere i primi passi.

Immaginiamo di partire da un foglio elettronico in cui vi siano i dati da georiferire con le informazioni di Comune, Via e Numero Civico, sommate ovviamente ad altre informazioni descrittive.

La prima cosa da fare, dopo aver ovviamente caricato il foglio elettronico in OpenRefine, è preparare i dati in modo che Comune, Via e Numero Civico siano rispettivamente su tre colonne separate che chiameremo “Comune“, “Ubicazione” e “Civico“, e che, qualora vi siano degli spazi, questi siano sostituiti dalla corrispondente sequenza di escape %20, se compaiono apostrofi questi siano sostituiti dalla corrispondente sequenza di escape %27, ecc … (questa operazione può essere fatta a mano o usando le funzionalità di OpenRefine).

A questo punto è necessario aggiungere una nuova colonna selezionando una colonna esistente e cliccando il tasto destro del mouse selezionando Edit column –>Add column by fetching URLs.

Nella nuova colonna che ad esempio chiameremo “PCN”, copiare la seguente chiamata http in GET parametrizzata:

'http://wms.pcn.minambiente.it/ogc?map=/ms_ogc/wfs/Numeri_Civici_2012.map&VERSION=1.1.0&service=wfs&request=GetFeature&TYPENAME=IN.NUMERICIVICI.2012&Filter=%3Cogc:Filter%20xmlns:ogc=%22http://www.opengis.net/ogc%22%3E%3CAND%3E%3Cogc:PropertyIsEqualTo%20matchCase=%22false%22%3E%3Cogc:PropertyName%3Ecomune%3C/ogc:PropertyName%3E%3Cogc:Literal%3E' + cells["Comune"].value + '%3C/ogc:Literal%3E%3C/ogc:PropertyIsEqualTo%3E%3Cogc:PropertyIsEqualTo%20matchCase=%22false%22%3E%3Cogc:PropertyName%3Enome%3C/ogc:PropertyName%3E%3Cogc:Literal%3E' + cells["Ubicazione"].value + '%3C/ogc:Literal%3E%3C/ogc:PropertyIsEqualTo%3E%3Cogc:PropertyIsLike%20matchCase=%22false%22%20wildCard=%22*%22%20singleChar=%22.%22%20escapeChar=%22!%22%3E%3Cogc:PropertyName%3Ecivico%3C/ogc:PropertyName%3E%3Cogc:Literal%3E*' + cells["Civico"].value + '*%3C/ogc:Literal%3E%3C/ogc:PropertyIsLike%3E%3C/AND%3E%3C/ogc:Filter%3E'

Quando si procederà, confermando, saranno inviate tante chiamate in GET quante sono le righe del foglio elettronico e per ognuna verrà mantenuto l’XML di risposta: per l’indirizzo in esame ecco l’XML risultato della chiamata con evidenziati i campi che contengono le coordinate dell’indirizzo

<?xml version='1.0' encoding="ISO-8859-1" ?>
 <wfs:FeatureCollection
 xmlns:ms="http://mapserver.gis.umn.edu/mapserver"
 xmlns:gml="http://www.opengis.net/gml"
 xmlns:wfs="http://www.opengis.net/wfs"
 xmlns:ogc="http://www.opengis.net/ogc"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://mapserver.gis.umn.edu/mapserver http://wms.pcn.minambiente.it/ogc?map=/ms_ogc/wfs/Numeri_Civici_2012.map&amp;SERVICE=WFS&amp;VERSION=1.1.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=IN.NUMERICIVICI.2012&amp;OUTPUTFORMAT=text/xml;%20subtype=gml/3.1.1 http://www.opengis.net/wfs http://schemas.opengis.net/wfs/1.1.0/wfs.xsd">
 <gml:boundedBy>
 <gml:Envelope srsName="EPSG:4326">
 <gml:lowerCorner>45.808287 9.575815</gml:lowerCorner>
 <gml:upperCorner>45.808287 9.575815</gml:upperCorner>
 </gml:Envelope>
 </gml:boundedBy>
 <gml:featureMember>
 <ms:IN.NUMERICIVICI.2012 gml:id="IN.NUMERICIVICI.2012.1225789">
 <gml:boundedBy>
 <gml:Envelope srsName="EPSG:4326">
 <gml:lowerCorner>45.808287 9.575815</gml:lowerCorner>
 <gml:upperCorner>45.808287 9.575815</gml:upperCorner>
 </gml:Envelope>
 </gml:boundedBy>
 <ms:boundary>
 <gml:Point srsName="EPSG:4326">
 <gml:pos>45.808287 9.575815</gml:pos>
 </gml:Point>
 </ms:boundary>
 <ms:id>13800026062251</ms:id>
 <ms:nome>Via Milano</ms:nome>
 <ms:civico>55</ms:civico>
 <ms:istat>03016023</ms:istat>
 <ms:cap>24030</ms:cap>
 <ms:comune>BERBENNO</ms:comune>
 <ms:nome_ted> </ms:nome_ted>
 <ms:provincia>BERGAMO</ms:provincia>
 <ms:regione>LOMBARDIA</ms:regione>
 </ms:IN.NUMERICIVICI.2012>
 </gml:featureMember>
 </wfs:FeatureCollection>

Per evitare di sovraccaricare il server di chiamate (ed essere magari “bannati” dal GeoPortale …..), occorre essere professionali: la disponibilità di un servizio non ne implica un abuso e quindi è doveroso, ed opportuno, schedulare le chiamate verso il server in modo che siano sufficientemente distanziate nel tempo.

Open Refine lo permette di fare impostando un parametro “Throttle delay” quando si crea una colonna Add column by fetching URLs.

ThrottleDelay

Di default tale parametro è valorizzato a 5000 millisecondi ed è quindi opportuno aumentarlo così da ridurre il carico di richieste verso il server

Una volta ottenute le  diverse risposte, una per ogni riga del nostro foglio elettronico, quello che resta da fare è estrarre dall’XML le coordinate e riportarle in campi della tabella creati appositamente.

E’ quindi possibile creare due nuove colonne partendo dalla colonna “PCN”, rispettivamente “Lat” e “Lon”, per ognuna delle quali si dovranno applicare le seguenti regole espresse in linguaggio GREL:

  • toNumber(split(trim(substring(value.parseHtml().select(“gml|Point gml|pos”)[0].toString(),10, -10)), ” “)[0])
  • toNumber(split(trim(substring(value.parseHtml().select(“gml|Point gml|pos”)[0].toString(),10, -10)), ” “)[1])

Terminate queste attività è quindi possibile eliminare, se ritenute non più utili, tutte le colonne di servizio: quello che si otterrà è lo stesso foglio elettronico iniziale con due nuove colonne “Lat” e “Lon” in cui saranno valorizzate le coordinate dell’indirizzo (questo se la chiamata al servizio del GeoPortale ha dato esito positivo, quindi per un indirizzo presente nella base dati, altrimenti ovviamente non avremmo alcun valore).

Tutto sommmato piuttosto semplice rispetto al grosso valore aggiunto che si ottiene: buon divertimento!