Seee, vabbè, buonanotte. Giovà, me so perso… concettualizzazione, modellizzazione, linguaggio??? Ma che vor dì???
Ok, cominciamo dall’inizio e con una storia.
Lucy accompagna la madre dal dottore che, dopo averla visitata, le prescrive delle sedute di fisioterapia. Lucy chiede al suo smartphone di trovare la lista dei dottori coperti dall’assicurazione della madre col più alto numero di feedback positivi secondo il servizio sanitario nazionale e che non siano lontani più di 20 chilometri dalla casa della madre. Lo smartphone di Lucy recupera l’agenda dei dottori più vicini e crea dei potenziali appuntamenti compatibili sia con l’agenda personale di Lucy sia con l’agenda del fratello Pete, con cui Lucy dovrà organizzarsi per accompagnare la madre alle sedute. Immediatamente Pete riceve sul suo smartphone l’elenco dei potenziali appuntamenti ma su alcune date non è d’accordo; Pete modifica quindi alcune date e riduce la distanza massima dei dottori da cercare a 15 chilometri. Queste restrizioni portano alla generazione di un nuovo calendario di potenziali appuntamenti. Lucy riceve le nuove date generate e le vanno bene. In questo modo le sedute di fisioterapia vengono automaticamente prenotate nell’agenda del dottore selezionato.
Questo racconto è tratto dal famoso articolo del Scientific American del 2001, in cui Tim Berners-Lee, creatore del Web e del Semantic Web, descrive la sua idea di Web, un ambiente in cui i programmi sono in grado di comprendere il significato delle parole e di prendere decisioni in modo autonomo.
Il Web così come lo conosciamo è costituito da pagine esplorabili all’interno di applicazioni chiamate browser, utilizzate dagli utenti per navigare la rete. I browser hanno il compito di rappresentare le pagine favorendo lo scambio di informazioni tra umani. Gli stessi browser, però, non sanno nulla degli argomenti trattati nella pagine, non sono in grado di comprendere il significato delle informazioni rappresentate né sono dotati di intelligenza per improvvisare ragionamenti logici in piena autonomia. Possiamo dire quindi che le informazioni rappresentate nelle pagine Web non favoriscono lo scambio tra programmi.
Ma come possono diventare intelligenti le macchine? Come possono capire il significato delle informazioni presenti nel Web?
Per rendere il Web intelligente è necessario creare un ambiente in cui a tutte le “cose” esistenti vengono associate informazioni e dati (metadati) in grado di specificarne il contesto semantico in un formato adatto all’interpretazione e all’elaborazione automatica. Le macchine non hanno l’abilità di capire il significato delle parole, a meno che non si creino le condizioni affinché possano comprendere e questo deve essere fatto in un linguaggio a loro comprensibile. Questo nuovo tipo di ambiente prende il nome di Web Semantico e, non solo consente lo scambio di informazioni tra programmi ma aumenta indirettamente ed esponenzialmente anche la quantità di informazioni che possono utilizzare gli esseri umani.
Uno specifico ambito di conoscenza può essere rappresentato in modo comprensibile dalle macchine utilizzando gli strumenti del Web Semantico, codificando cioè le informazioni tramite i concetti del dominio (classi, proprietà, e restrizioni). Il risultato di queste concettualizzazioni viene definito comunemente ontologia.
Non è scopo di questo post entrare nel dettaglio sugli strumenti tecnici del Web Semantico. Per maggiori informazioni potete fare riferimento alla serie di post presenti in questo blog: [1,2,3,4,5,6,7,8,9,10]
Per spiegare le motivazioni che hanno dato origine al progetto Ontopia prendiamo ad esempio il dominio dei servizi pubblici delle PA.
Alcuni di essi, anche se non tantissimi, sono disponibili online. Nonostante questo, però, i servizi pubblici potrebbero essere più efficienti se non esistessero barriere tra i servizi stessi, i sistemi IT e i dati. Uno dei più grandi problemi delle PA avviene quando i dati dei sistemi IT non possono essere scambiati tra sistemi diversi perché descritti in modo incompatibile; ciò avviene quando abbiamo problemi di semantica. Per superare questo ostacolo è necessario creare delle connessioni significative tra dati e per fare questo è necessario seguire standard aperti e condivisi. Questo limite non deve riguardare però solo il territorio nazionale; il patrimonio informativo delle PA dovrebbe essere riutilizzato e condiviso tra i tutti gli stati d’Europa e collegato insieme ad altre pubbliche amministrazioni, aziende e cittadini in un unico mercato digitale europeo.
Anche la Commissione Europea, nel documento quadro European Interoperability Framework, che mira a potenziare l’interoperabilità dei servizi pubblici nell’Unione Europea, afferma infatti che “l’agenda digitale può decollare solo se è garantita un’interoperabilità basata su standard e piattaforme aperte”.
Purtroppo, però, nelle PA italiane si riscontrano ancora le seguenti criticità:
In realtà sull’ultimo punto è necessario aggiungere qualcosa, ma procediamo per passi.
Dal punto di vista normativo l’Italia da anni insiste e incentiva l’adozione di standard condivisi come dimostrano i seguenti riferimenti:
Con queste premesse normative, da diversi anni l’AGID, Agenzia per l’Italia Digitale, in collaborazione con il Team per la Trasformazione Digitale, ha quindi intrapreso l’ardua sfida di standardizzare il patrimonio informativo della pubblica amministrazione, creando una famiglia di modelli di dati, cioè ontologie, con lo scopo di identificare e definire schemi condivisi per dati trasversali e non, ai diversi domini applicativi delle PA. Contemporaneamente l’AGID ha sviluppato dei vocabolari controllati, ottenuti armonizzando e standardizzando tassonomie, codici e nomenclature, da utilizzare come categorizzazioni nelle ontologie e nelle basi di dati pubbliche.
Questa iniziativa dell’AGID prende il nome di Ontopia e rappresenta, a mio avviso, uno dei più interessanti e ambiziosi progetti di AGID, perché costituisce la base e le fondamenta su cui, in maniera imprescindibile, dovrà essere fondata la pubblica amministrazione del futuro e da cui si dovrà partire per riuscire a dare una nuova immagine alle PA. Una PA che sia moderna e innovativa, trasparente e aperta, i cui dati siano semanticamente interoperabili, per facilitare lo sviluppo di nuovi sistemi informativi, per agevolare lo scambio di dati, per abilitare l’integrazione tra dati provenienti da fonti diverse.
Standardizzare l’architettura del patrimonio informativo delle pubbliche amministrazioni significa definire un linguaggio comune per l’interscambio dei dati, significa creare un ambiente in cui poter interrogare quello che viene chiamato il grafo della conoscenza della pubblica amministrazione italiana o Knowledge Graph. E tutto questo, in Ontopia, viene fatto sfruttando le potenzialità del Web Semantico.
Il progetto Ontopia è sviluppato con il supporto del laboratorio di tecnologie semantiche dell’Istituto di Scienze e Tecnologie della Cognizione (ISTC) del CNR e in collaborazione con diversi enti centrali e locali; è rilasciato con licenza aperta ed è allineata ai cosiddetti Core Vocabulary del programma ISA2 della Commissione Europea.
I principi cardine su cui si basa Ontopia sono:
L’approccio tecnico di modellazione di Ontopia è rappresentato nella seguente figura:
Tipicamente, nel creare un’ontologia, i componenti più importanti sono le classi e le proprietà. Le ontologie del progetto Ontopia fanno riferimento a profili applicativi nazionali, cioè sono state sviluppate tenendo in considerazione, da un lato l’esistenza di eventuali modelli di dati europei e/o internazionali, in modo da non dover reinventare la ruota, dall’altro declinando le ontologie su profili di conformità alla realtà italiana, cioè inserendo vincoli restrittivi in grado di descrivere un dettaglio più rispondente al mondo delle PA nazionali grazie ai quali è possibile migliorare e mantenere una più alta qualità dei dati descritti.
Inoltre, i concetti delle ontologie sono collegati esternamente ad un vocabolario controllato.
Un esempio fra tutti. Nell’ontologia delle Strutture Ricettive (ACCO), la classe Accomodation
, che è la classe principale che definisce la struttura ricettiva, ha la proprietà hasAccommodationTypology
il cui oggetto deve essere un concetto di tipo AccommodationTypology
. Le istanze di questa classe sono concetti del vocabolario controllato https://w3id.org/italia/controlled-vocabulary/classifications-for-accommodation-facilities/accommodation-typology
definito esternamente all’ontologia. Tra queste istanze, che sono concetti definiti formalmente e univocamente tramite URI, troviamo ad esempio Motel, Agriturismo, Ostello per la gioventù, etc.
Le ontologie di Ontopia non sono autoreferenziali e chiuse a se stesse ma riutilizzano ontologie e vocabolari controllati esistenti, e definiscono, in un file esterno, tutti gli allineamenti del caso. Ad esempio, il concetto di Organization viene definito nell’ ontologia Core Organization Vocabulary di Ontopia ma viene anche allineato al concetto Organization dell’ontologia Organization del consorzio W3C. Nel file esterno di allinamento troviamo infatti la definizione covapit:Organization
di Ontopia sottoclasse di org:Organization
dell’ontologia W3C.
La possibilità di estendere e riusare i concetti delle ontologie ha un impatto molto forte in termini di integrazione dei dati di Ontopia con altri dati esterni, modellati con ontologie direttamente o indirettamente allineate con Ontopia. Allineare ontologie significa costruire ponti tra grafi di conoscenza diversi, supportare e favorire lo scambio di informazioni, abbattere e superare l’approccio a silos solitamente adottato nelle PA italiane.
La seguente figura illustra invece lo stack ontologico del progetto Ontopia.
In Ontopia possiamo distinguere diversi livelli di ontologie organizzate a stack, dove le ontologie dei livelli più bassi sono riutilizzate dalle ontologie di livello più alto e mai il contrario. L’appartenenza ad uno specifico livello dipende dalle caratteristiche dell’ontologia stessa e dallo scopo per cui è stata sviluppata.
I livelli di Ontopia sono:
Ontopia è un progetto aperto, fortemente collaborativo e partecipativo. Tutte le risorse disponibili sono su un repository GitHub in cui è possibile partecipare, sia aprendo o rispondendo a issues, per consigli, suggerimenti, feedback sulle ontologie e i vocabolari controllati, sia inviando, tramite PR, eventuali estensioni, modifiche e/o correzioni degli attuali schemi caricati.
In questo post ho voluto raccontare, seppur in maniera introduttiva, il progetto Ontopia, una delle iniziative istituzionali più sfidanti degli ultimi anni. Una piattaforma di modelli di dati istituzionale, aperta e creata in modo collaborativo con centri di ricerca (CNR Roma), con pubbliche amministrazioni (ISTAT, MIBAC, Regione Piemonte, ANAC, Comune Palermo e Udine, Provincia Autonoma di Trento) e soprattutto con tutte le persone che vogliono contribuire al progetto, interagendo con GitHub.
Una piccola nota personale.
Circa 10 anni fa, durante il mio dottorato di ricerca, mi appassionai di Semantic Web e creai delle ontologie per la rappresentazione sia del mondo universitario italiano (SWIUP) sia delle statistiche dell’anagrafe studenti (LOIUS). In quella attività di ricerca descrissi in modo formale un pezzetto di pubblica amministrazione, nello specifico quella del Ministero dell’Istruzione, Università e Ricerca (MIUR). Quell’esperienza mi insegnò molte cose sul mondo del Semantic Web e dei Linked Data; appresi come definire modelli per la rappresentazione della conoscenza e come favorire l’interoperabilità semantica in contesti molto particolari come il mondo delle PA. Tuttavia quel lavoro morì subito dopo la consegna della tesi e da allora sono trascorsi quasi 10 anni.
In Ontopia, in quest’ambizioso progetto istituzionale che si impone in maniera così massiccia e trasversale sui domini applicativi delle PA, rivedo la concretizzazione reale e consistente di ciò che in una piccolissima parte avevo cercato di fare anch’io 10 anni fa, cercare cioè di rendere la PA più moderna; sono fortemente convinto che Ontopia sia la rotta giusta da seguire, supportare e incoraggiare, motivo per cui mi sento stimolato, nel mio piccolo, a contribuire al progetto.
Da Ontopia sto imparando molto, sto studiando l’approccio utilizzato per la creazione delle ontologie e dei vocabolari controllati e ho scoperto nuove tecniche di modellazione basate sui design pattern che non conoscevo.
Sto studiando, ho ancora tanto da imparare e sto cercando di dare il mio contributo nei seguenti modi:
Da diversi mesi avevo intenzione di scrivere un post sul progetto Ontopia e, complice il lungo ponte di Pasqua, finalmente ho trovato il tempo per farlo. Spero di essere riuscito a trasmettere un po’ di interesse e di entusiasmo a tutte quelle persone che hanno a che fare con il mondo delle PA a vario titolo (amministratori, dirigenti, dipendenti) e che sono chiamate a fare scelte importanti nei propri enti in materia di innovazione e modernizzazione.
Molto di ciò che ho scritto l’ho potuto apprendere da Giorgia Lodi, esperta di tecnologie semantiche, professionista di altissima competenza, che ringrazio.
Per maggiori approfondimenti sul progetto Ontopia sono disponibili le seguenti risorse online, da cui sono stato fortemente ispirato.
]]>From the technological point of view, Tim Berners–Lee invented nothing new but simply defined some rules for publication and interlinking RDF data on the Web, thus stirring up a very high interest by the scientific and business community around the world.
The Linked Data principles recommend to:
The basic principle of Linked Data is that data value increases if it is interlinked with other data. Structured data should be published using semantic languages and data would be linked with external sources through typed RDF links. The current Web is similar to a large filesystem where documents are scattered without information on the content meaning, and connected using untyped meaningless links. Instead, the Web of Data can be considered as a huge global database published on the Web, available to all interested people that may query, integrate, reuse, export data to develop applications on top of it. Increasing RDF links between resources belonging to different datasources means allowing search engines to carry out flexible queries similar to those provided by a relational database. Before talking about the four Linked Data principles, we define some terms that will help us go forward in this post.
As known, each URL
is a particular type of URI
, starting from http:
string, defining the path to find a specific resource on the Web. The http:
scheme of each URL also specifies the protocol used to access on the net through browsers; each URL address is then called deferencable
because it is relative to a resource on the Web retrievable through a well–known mechanism. Instead, putting in our browser URIs with tag:
or urn:
schemes, we are not able to find any resources because the relative protocols do not specify how to find items. In this case we know the URIs as not deferencable
.
The first Linked Data rule states to use URIs as names for things but not only things related to Web such as images, documents, video and so forth, but also for real–world objects like people, hotels, cars and even abstract ideas and non–existing things.
The second rule proposes to use HTTP URIs so that people can look up those names. The reason of this is very simple. The http://
scheme is the only URI scheme that is widely supported in today’s tools and infrastructure. All others require extra effort for passing proxies and firewall layers, for resolver Web services and so on; then, the HTTP protocol can be seen as a universal door to access all resources URIs.
The third Linked Data rule states that when someone looks up a URI, the server would always provide useful information, using the standards. But, given a specific URI, how can we find out what it identifies? Before answering this question we have to classify the resources in two types:
Information resources are identified by directly deferencable URI, and the result of the request is sent to the browser immediately. When a user requires information resources, the server Web generates a new representation of that resource returning an HTTP response code 200 OK
.
We can imagine an information resource as all that can be trasmitted electronically and can be viewed in a browser.
All URIs not directly deferencable are called instead non–information resources. Browsers can only display information resources; therefore, to provide a representation of non–information resources you perform a double step trick. When a user wants to find a non–information resource the Web server redirects to an information resource URI through the HTTP response code 303 See Other
. Then, the client performs a new request deferencing the just arrived information resource, finally obtaining a representation of the non–information resource.
So far we have explained how all information resources types can be deferenced using URIs. But, how does the Web server know which information resource has to be returned for a non–information URI request?
The answer is very simple and is related to the HTTP protocol;
in fact, in the HTTP Accept header
of the HTTP client request, we can specify the MIME type
of the representation type we want.
The Web server reads the requests and starts the content negotiation mechanism to give back the right information resource URI related with the specified representation. Then, if a user requires a non–information resource URI and wants to display it in a normal browser, the client will send in the HTTP Header the attribute Accept: text/html
, while for example, if we want to see the resource in an RDF browser, the attribute will be Accept: application/rdf+xml
. Therefore, the server will return the related information resource URI that the client will be able to deference displaying the information needed. The following figure shows the content negotiation mechanism.
Dereferenceable URIs can be constructed using two approaches preserving the implicit identity function.
Hash approach. In this case the URI is splitted into two parts separated by a hash symbol #
. This type of URI cannot be directly deferencable so we can use it to identify non–informative
resources without creating ambiguity because the HTTP protocol, before sending the request to the server, strips off the string after the hash symbol, to retrieve the information resource representation
containing the non–resource information description. For example, using this approach to identify the poet Dante Alighieri, the URI could be: http://example.org/poets.rdf#dalighieri
.
In the content negotiation mechanism, the part after the hash symbol will be removed and the server will return the http://example.org/poets.rdf
URL within which we will find information about the dalighieri
resource in RDF format.
Slash approach. In this case the non information resource is identified by the string following the last slash symbol /
, and to deference this type of URI, as seen above, the 303 - See Other
negotiation mechanism is adopted in order to find the right resource representation. For example, using this approach to identify the person Dante Alighieri, the URI could be:
http://example.org/dalighieri
. This resource does not exist in the server, then it sends a 303
redirect to client saying that information about that resource can be found in the http://example.org/poets.rdf
file within which we will find information about the dalighieri
resource in RDF format.
The semantic languages allow to exposes on the Web a large amount of data, and choosing the right URI approach can be fundamental to ensure a good performance of the system. Imagine a large single RDF file published on the Web containing millions of URIs, and let us use the hash approach. When a client wants to retrieve a single resource inside the file, although the resource would be at the top of the file, the server has to return the whole heavy file to find the related URI resource. This can be a bottleneck for the functioning of the system; so, depending on dataset size, we can adopt different strategies combining slash or hash approaches for deferencing URIs, to ensure the better performance to client requests.
The fourth and last Linked Data rule states to include links to other URIs in order to discover more things. This principle represents one of the most important rules because by adding RDF links to resources especially belonging to different datasets, we increase the amount of information available on the Web for those resources. Publishing data on the Web using the RDF data model following linked data rules means that clients can look up every URI in a huge graph to retrieve additional external information coming from different sources, merging and exploring datasets, querying and developing applications thus increasing the resource original value.
In 2007, the W3C SWEO group proposed the Linking Open Data (LOD) community project whose goal is to extend the Web with a data commons by publishing various open data sets as RDF on the Web and by setting RDF links between data items from different data sources (link)
In this project, some people embraced the Tim Berners–Lee rules and started to publish open data on the Web making interlinked datasets available.
The open data ideals state that data must be freely reusable by everyone without paying royalties. The LOD community aims to convert all open datasets available on the Web in RDF format to expose them in a structured way, in order to finally allow the free reuse by all, especially by machines that use the potentiality of semantic technologies. The first LOD interlinked datasets were:
From 2007, many projects, communities and developers contributed to increase the number of interlinked dataset inside the LOD cloud diagram. Currently, the LOD project is composed by 1224 data sets encoding more than 31 billion RDF triples, which are interlinked by around 504 million RDF links (2014). The Linking Open Data diagram can be seen in the following figure:
Starting from LOD RDF structured data, we can develop very interesting semantic applications such as browsers, user interfaces, search engine crawlers and reasoning engines. Everybody can contribute to increase the LOD diagram, converting open data to RDF and making it available as linked data and/or SPARQL endpoint on the Web. Thus, linked data paradigm is a way of publishing data on the Web; furthermore, due to semantic Web languages, it encourages reuse, reduces redundancy, and at the same time, maximizes the semantic interoperability between applications.
That’s all folks! Stay tuned!
]]>Già in un mio precedente post ho raccontato come aprire i dati della Protezione Civile della Regione Siciliana a partire dai bollettini PDF che pubblicavano ogni giorno sul loro sito.
Con la pubblicazione in opendata dei dati della protezione civile su scala nazionale il cambio di passo è davvero notevole e diventa realistico progettare importanti servizi digitali che siano sostenibili e a beneficio dei cittadini.
Stimolato anche dall’amico Andrea Borruso, che già aveva scritto un post sulla pubblicazione di questi dati,
vediamo come ottenere una maggiore flessibilità e facilità di accesso.
Sin da subito, tuttavia, noto alcune criticità.
I dati dovrebbero invece essere esposti in modo da garantire il massimo livello di flessibilità, secondo un formato standard e strutturato, in grado di filtrare i dati da consumare secondo le proprie specifiche necessità.
Uno dei modi più semplici e facili per accedere a dati su Webva è tramite API dedicate in formato JSON.
JSON (JavaScript Object Notation) è un formato aperto, semplice e adatto alla memorizzazione di informazioni e ai trasferimenti di dati dal client al server o viceversa.
Per la varietà di ambiti di applicazione, oltre al formato JSON, scelgo di esporre anche i dati in formato RSS.
RSS è uno dei più popolari formati per la distribuzione di contenuti Web; è basato su XML, da cui ha ereditato la semplicità, l’estensibilità e la flessibilità. Attraverso particolare software chiamati feedreader è possibile convogliare tutti i feed di interesse in un’unica applicazione (Web, standalone o mobile) in modo da avere in un unico punto le informazioni di tutti i siti di interesse senza doverli visitare manualmente ad uno ad uno.
Inoltre gli RSS si integrano in modo naturale con una serie di applicazioni, servizi e tool online con i quali è possibile creare nuovi servizi. Il servizio IFTTT, ad esempio, è in grado di agganciare un feed RSS a tantissimi altri servizi: social newtork, app di instant messaging, email, applicazioni di domotica in grado di accendere lampade, aprire finestre, avviare elettrodomestici e tanto altro.
Immaginate una lampada che cambia colore a seconda del colore dell’allerta meteo del giorno successivo ricordandovi ad esempio di lavare e stendere i panni oggi perchè domani sono previsti forti temporali. E che automaticamente disattiva l’irrigazione del giardino per il giorno successivo riattivandosi successivamente in assenza di allerta. Questi sono solo alcuni esempi di applicazioni potenzialmente realizzabili grazie al riutilizzo dei dati della Protezione Civile, riusabili perchè opendata.
Una volta deciso il formato da esporre voglio poter accedere ai dati in modo da personalizzare la mia richiesta in base all’uso che ne devo fare, secondo le seguenti caratteristiche:
Iniziamo dal primo punto.
Il Bollettino di criticità nazionale/allerta della Protezione Civile segnala la valutazione dei livelli di criticità/allerta idraulica, per temporali e idrogeologica mediamente attesi fino alle 24.00 del giorno di emissione e nelle 24 ore del giorno successive sulle 156 zone di allerta (vedi figura) in cui è suddiviso il territorio italiano. Il documento viene pubblicato ogni giorno, di norma, alle 16.00.
Le zone definite dalla Protezione Civile non combaciano con le province italiane per cui il primo problema da risolvere è individuare la zona di appartenenza di ciascuna città italiana. Per fare questo utilizzo il seguente script python.
import shapefile
from shapely.geometry import Point
from shapely.geometry import shape
import csv
# Apro il formato shape dei dati
shp = shapefile.Reader('data/20180502_1615_today')
# leggo tutti i poligoni
all_shapes = shp.shapes()
# e tutte le informazioni associate ai poligoni
all_records = shp.records()
# ottengo il numero dei poligoni
len_shapes = len(all_shapes)
# inizializzo un file CSV in scrittura
ofile = open('comuni-con-zone.csv', "w")
writer = csv.writer(ofile, delimiter=',', quotechar='"', quoting=csv.QUOTE_NONNUMERIC)
rownum = 0
# il file comuni.csv contiene tutte le città italiane con le relative latitudini e longitudini
with open("comuni.csv", "r") as f:
reader = csv.reader(f)
for row in reader:
# la prima riga la salto perchè è l'header
if rownum == 0:
header = row
header.append('zona_protezione_civile')
writer.writerow(header)
rownum+=1
else:
# per ogni città mi creo un oggetto Point a cui passo
# nel costruttore la latitudine e la longitudine
point = Point(float(row[4]), float(row[3]))
# devo capire dentro quale shape si trova il punto
# per cui ciclo su tutti i poligoni della protezione civile
for i in range(len_shapes):
# leggo il poligono i-esimo
boundary = all_shapes[i]
# se il punto, cioè la città, si trova dentro il poligono
if point.within(shape(boundary)):
# aggiungo la zona alla riga
row.append(all_records[i][0])
# e la salvo in un nuovo file CSV
writer.writerow(row)
break
Alla fine dello script verrà creato un nuovo file CSV chiamato comuni-con-zone.csv identico al file di partenza comuni.csv con in più la colonna zona della Protezione Civile per ogni città.
Questa è la parte più difficile di tutta l’applicazione. Una volta estratte le zone di ogni città il passo è breve. Nello stesso zip che contiene il formato SHP dei dati sono presenti due file CSV contenenti le previsioni della protezione civile del giorno stesso e del giorno successivo, le tipologie di rischio e il livello di allerta. Sempre con uno script python leggo questi dati, li organizzo secondo le mie necessità e li salvo banalmente su un db mysql. Quest’ultimo script lo collego ad un job cron che quotidianamente mi aggiornerà i dati del db.
La parte dell’applicazione relativa alla data integration è conclusa. Vediamo adesso come implementare la web-application.
Per generare la richiesta API e il feed RSS viene sviluppata un’interfaccia Web in grado di configurare le opzioni in modo da massimizzarne la flessibilità.
Secondo i seguenti parametri API:
Di seguito come appare l’interfaccia Web.
La web-application, di fatto un configuratore delle API, è di utilizzo immediato.
Basta scegliere la città di interesse, il rischio, la soglia minima di allerta, il giorno di interesse, il formato e il gioco è fatto!
N.B. Con la scelta della soglia minima di allerta il flusso verrà generato solo se l’allerta è maggiore o uguale a quella scelta. Per cui, se l’allerta scelta è quella arancione, il flusso conterrà eventuali allerte arancioni e rosse ma non bianche e gialle.
L’applicazione si trova al seguente indirizzo:
Nei prossimi post vedremo come agganciare i feed RSS ad altri servizi esterni, come ad esempio Facebook, Twitter e Telegram.
Se questo progetto ti è piaciuto, mi aiuti a farlo conoscere con un tweet?
Per consigli, feedback, suggerimenti, bug potete inserire una issue su questo repository.
Grazie!
That’s all folks! Stay tuned!
]]>Ed è proprio da quest’idea di merging documentale che sono partito per riflettere sulla possibilità di considerare i testi normativi alla stregua di codici sorgente e di poter utilizzare i tool a disposizione per il versionamento del software, ad esempio Git ma anche Subversion o Mercurial, per tenere traccia di tutte le modifiche che avvengono fra le versioni delle leggi.
Quest’idea in realtà non è nuova. Da diversi anni esistono dei progetti che supportano l’utilizzo di strumenti che, anche se nati per il mondo software, consentono sia di versionare i documenti normativi sia di far interagire i cittadini con i proponenti la legge, mettendoli in condizione di fornire feedback, consigli, critiche e/o spunti di miglioramento. E’ un esempio il progetto Bundes-Git che raccoglie in un repository git le leggi e i regolamenti federali tedeschi in markdown, cioè usando un formato in grado di migliorare la leggibilità e la fruibilità per gli utenti finali.
Anche in Italia, in occasione del referendum costituzionale del 2016, c’è stato chi ha pensato bene di versionare la costituzione corrente con quella che sarebbe stata se fosse passato il referendum confermativo.
Ritornando al CAD, a fine gennaio avevo quindi intenzione di creare un repository git e caricare tutte le versioni del CAD, naturalmente con commit diversi, per consentire sia la lettura del decreto legislativo su piattaforme online di versionamento, come ad esempio github, sia per tenere traccia delle modifiche di capi, titoli, articoli e commi e poter fare confronti tra le varie versioni. Successivamente avevo intenzione di creare una mappa dell’intero decreto, in grado di fornire all’utente il quadro generale non solo della versione corrente del CAD ma anche di tutte le precedenti.
Per reperire il testo delle varie versioni ho riciclato e fixato in alcune parti un vecchissimo scraper, sviluppato più di 4 anni fa per un progettino didattico, in grado di estrarre dati da normattiva.it e di creare un file JSON con capi, sezioni, articoli, versioni, testi, aggiornamenti, vigenze, riferimenti normativi del CAD.
Il file estratto lo potete trovare qui.
Era fine gennaio dicevo (cioè due settimane fa), avevo generato il file e accantonato il progetto per qualche settimana intendendo ritornarvi appena avessi avuto un pò più di tempo libero quando, ad un tratto…un fulmine a ciel sereno.
Il team digitale di Diego Piacentini carica su github tutte le versioni del CAD andando a realizzare esattamente quello che avevo in mente io. Non solo. Rilasciano il CAD in formato reStrucredText, collegano il repository al servizio di documentazione online readthedocs migliorando di molto l’esperienza di leggibilità, con in più la possibilità di confrontare le versioni, articolo per articolo, direttamente su github.
Questa la mia reazione
M’avete fregato sul tempo…A Piacentì, A Team Digitale…‘ve possino!!! se scherza eh ;-)
Raccolgo quatto quatto i cocci del mio progetto originale, accuso il colpo ma non demordo. Naufragata la parte relativa alla pubblicazione delle leggi su github mi concentro sulla seconda parte, cioè la realizzazione di una mappa in grado di visualizzare e interagire interattivamente con tutte le versioni del CAD.
Giro un pò in rete per prendere ispirazione su progetti di mappe e mi innamoro di quello realizzato nel 2012 da Gregor Aisch (CTO di datawrapper) per le leggi tedesche.
Decido quindi di riusarlo, estenderlo ed adattarlo al CAD.
Invece di partire però dal file JSON estratto con lo scraper, i cui dati non sono opendata ma sono licenziati in modo da non consentirne il riuso per fini commerciali, decido di riutilizzare invece i dati del team-digitale, che sono invece opendata licenziati dalla bellissima CC0.
Nasce quindi il progetto VisualCAD, la mappa interattiva della storia del CAD. Per la prima volta (che io sappia) è possibile fotografare tutta la storia del Codice dell’Amministrazione Digitale in un’unica infografica.
Dalla prima versione del 2005 si sono succeduti ben 29 aggiornamenti e in VisualCAD vengono rappresentati su colonne diverse. I quadratini corrispondono ai singoli articoli e il colore, come mostrato in legenda, ne evidenzia l’eventuale modifica, aggiunta, abrogazione effettuata dalla normativa specificata in alto alla colonna.
Dalla tendina è possibile selezionare ciascun articolo per ricostruire tutto l’iter di modifiche subito dallo stesso dalla prima versione sino all’ultima.
E’ inoltre possibile effettuare ricerche testuali nel titolo degli articoli inserendo del testo libero nel form relativo.
Passando col mouse sopra gli articoli viene visualizzato un breve estratto del testo e, nel caso di articolo modificato, viene mostrato il nuovo testo in verde e il testo rimosso in rosso.
Cliccando su ciascun quadratino è possibile infine visualizzare l’intero corpo dell’articolo e, cliccando sull’apposito pulsantino, evidenziare il testo modificato.
L’obiettivo è stato raggiunto.
In un’unica schermata è possibile navigare tutto il CAD con tutti i suoi aggiornamenti, in modo semplice, interattivo e fruibile da qualsiasi cittadino.
L’evoluzione di questo progetto potrebbe essere la creazione di nuove mappe per altre leggi partendo ad esempio dal file JSON scrapato, in attesa che normattiva licenzi i dati in opendata e rilasci delle API per interrogare l’archivio delle leggi in modo flessibile. Sogno o utopia?
Ritornando al progetto, questo è il sito di riferimento di VisualCAD. All’apertura potreste attendere un pò di secondi perchè i dati da caricare sono tanti.
Se questo progetto vi è piaciuto, mi aiutate a farlo conoscere con un tweet? Grazie!
E comunque, a parte gli scherzi, grazie mille a tutta la squadra del Team Digitale!
Commenti, critiche e suggerimenti sono i benvenuti!
That’s all folks! Stay tuned!
]]>Questa è la storia di Ioan Pairot, squattrinato maniscalco siciliano, che ebbe la cattiva sorte di vivere secoli or sono alla corte di un potente signorotto palermitano.
Il primo dei racconti iniziava così:
Galeotta fu la telefonata col conte Andreas de los Bash, nobile discendente della casata dei Borrusi, di origine borbonica, insediatasi a Palermo all’inizio del XIX secolo lamentante di non trovare sul situs Webus della Protezione Civilis dell’isola Trinacria notitia circa lo tempo previstus del giorno appresso in forma tal da essere riusata in posti altri da quel situs poco apertus. Maniscalco scapestrato qual ero, nulla potei replicare all’illustre conte, ma il pensier turbò quella mia notte insonne e mi accompagnò fin al mattino. E infin cedetti per lo sfinimento, per appagar del conte il desiderio e ritornar a dormir la notte, quieto e libero da pensier molesti a oltranza.
Per una migliore comprensione del racconto d’ora in avanti tradurrò la storia in lingua moderna.
[…] Il conte Andreas mi informò che la Protezione Civile siciliana pubblicava quotidinamente, sul proprio situs ipertestuales (oggi lo chiameremmo sito o pagina Web), il dispaccio delle allerte dei rischi idrogeologici (oggi lo chiameremmo report o bollettino) dell’intera regione in un formato file chiamato OCD (oggi lo chiameremmo PDF). Tale formato, purtroppo, impediva la possibilità di riusare le preziose informazioni del bollettino in contesti diversi da quello originale e il conte, desideroso di manipolare quei dati, mi intimò di trovare una soluzione al problema.
Conoscendo la sua ira funesta la notte non chiusi occhio ma, alle prime luci dell’alba, un lampo di luce mi guizzò in mente ed…Eureka… trovai la soluzione.
In questo diario descriverò il dettaglio tecnico.
Ogni giorno la Protezione Civile siciliana pubblicava su questa pagina Web il bollettino giornaliero dei rischi idrogeologici della regione, relativi ad un periodo che andava dalle 16 del giorno di pubblicazione fino alle 24 del giorno successivo.
Nel bollettino apparivano diverse mappe della Sicilia suddivise per zone e per ciascuna di esse era riportato il livello del rischio in base alla seguente scala di colori:
Il bollettino veniva pubblicato in PDF per cui le informazioni rimanevano confinate nel file precludendo la possibilità di riutilizzare gli stessi dati in contesti differenti da quello originale.
Per poter individuare il tipo di approccio da attuare ho analizzato attentamente il report della Protezione Civile ponendo particolare attenzione ai colori delle prime due mappe, relative ai livelli di allerta regionali del giorno di pubblicazione e del successivo. Per poter aprire e riusare i dati ingabbiati nel PDF avevo bisogno di grattare i colori di ogni zona al di fuori del file. Dovevo stabilire un insieme di passi (oggi lo chiameremmo algoritmo) in grado di riconoscere i colori delle mappe, in modo automatico e puntuale, al fine di risalire al colore di ogni singolo elemento grafico (oggi lo chiameremmo pixel) presente in ciascuna zona della mappa.
Vediamo i singoli passi
Sul sito della Protezione Civile era presente una pagina con l’elenco di tutti i bollettini meteo e disponibile al seguente URL
http://www.regione.sicilia.it/presidenza/protezionecivile/pp/archivio_idro.asp
Il primo link dell’elenco rappresentava l’ultimo bollettino pubblicato dalla Protezione Civile. Per estrarre tale link ho utilizzato la libreria BeautifulSoup, ormai lo standard de-facto per lo scraping Web in Angus (oggi lo chiameremmo Python). Di seguito la prima parte del fons (oggi lo chiameremo codice sorgente):
url = 'http://www.regione.sicilia.it/presidenza/protezionecivile/pp/archivio_idro.asp'
r = requests.get(url)
html = r.text
soup = BeautifulSoup(html, 'lxml')
pattern = 'Avviso rischio idrogeologico per il (.*)'
first_row = soup.find('td',{'class':'testo_tabelle_cent'})
text = first_row.text
m = re.match(pattern,text)
if m:
primo_giorno_text = (m.group(1))
primo_giorno = datetime.datetime.strptime(primo_giorno_text, '%d/%m/%Y')
secondo_giorno = primo_giorno + datetime.timedelta(days=+1)
secondo_giorno_text = secondo_giorno.strftime("%d/%m/%Y")
if first_row.a:
link = first_row.a.get('href')
if link:
href = link[3:]
A questo punto href conterrà il link (relativo) del bollettino della Protezione Civile.
WEB_ROOT_URL = 'http://www.regione.sicilia.it/presidenza/protezionecivile/'
full_url = WEB_ROOT_URL + href
file_pdf = 'protezione-civile.pdf'
wget_cmd = 'wget -O ' + file_pdf + ' "' +full_url + '"'
os.system(wget_cmd)
L’algoritmo prosegue con lo scaricamento del file (oggi lo chiameremmo download), attraverso il comando shell wget, invocato da python, grazie al quale otteniamo il trasferimento del PDF in locale sul mio calculator (oggi lo chiameremmo server).
Considerando che le mappe della Sicilia presenti nel report si trovavano sempre in prima pagina e sempre nella stessa posizione, ho iniziato a pensare a come esportare i dati al di fuori del file.
Volendo analizzare i colori delle mappe siciliane, ed essendo queste essenzialmente delle immagini incastonate nel PDF, la prima cosa che mi è venuta in mente è stata quella di convertire la prima pagina del PDF in un’immagine e utilizzare le librerie grafiche disponibili in Python per poter ottenere informazioni sui colori delle specifiche zone.
Attraverso il tool convert di ImageMagick ho convertito quindi la prima pagina del bollettino PDF in formato immagine PNG nel seguente modo:
file_png = 'protezione-civile.png'
file_pdf = 'protezione-civile.pdf'
cmd = 'convert '+ file_pdf + '[0] ' + file_png
os.system(cmd)
Con l’immagine generata ho individuato, in ciascuna delle prime due mappe, la posizione dei pixel ricadenti in ogni zona, in modo da potermi dedicare all’individuazione dei colori delle zone stesse.
pixel_sicilia_zone_primo_giorno = {}
pixel_sicilia_zone_primo_giorno['A'] = [262,174]
pixel_sicilia_zone_primo_giorno['B'] = [182, 188]
pixel_sicilia_zone_primo_giorno['C'] = [105, 186]
pixel_sicilia_zone_primo_giorno['D'] = [106, 208]
pixel_sicilia_zone_primo_giorno['E'] = [170, 230]
pixel_sicilia_zone_primo_giorno['F'] = [219, 269]
pixel_sicilia_zone_primo_giorno['G'] = [248, 266]
pixel_sicilia_zone_primo_giorno['H'] = [222, 216]
pixel_sicilia_zone_primo_giorno['I'] = [246, 202]
pixel_sicilia_zone_secondo_giorno = {}
pixel_sicilia_zone_secondo_giorno['A'] = [520,174]
pixel_sicilia_zone_secondo_giorno['B'] = [438, 188]
pixel_sicilia_zone_secondo_giorno['C'] = [364, 186]
pixel_sicilia_zone_secondo_giorno['D'] = [364, 209]
pixel_sicilia_zone_secondo_giorno['E'] = [431, 230]
pixel_sicilia_zone_secondo_giorno['F'] = [477, 268]
pixel_sicilia_zone_secondo_giorno['G'] = [506, 265]
pixel_sicilia_zone_secondo_giorno['H'] = [480, 216]
pixel_sicilia_zone_secondo_giorno['I'] = [504, 202]
Utilizzando le librerie Pillow è possibile ottenere informazioni sui singoli pixel delle immagini.
image = Image.open(file_png)
pixel = image.getpixel(i, j)
La funzione getPixel(), passando in input la posizione di un pixel, restituisce un vettore contenente la triade delle componenti dei colori primari nella forma RGB (red, green, blue), grazie alla quale è possibile risalire al colore del pixel desiderato.
In base ai valori delle componenti di ciascun colore è possibile adesso ottenere il livello di allerta della zona interessata.
def get_allerta(r,g,b):
if r == 0 and g == 255 and b == 0:
return 'ALLERTA VERDE - GENERICA VIGILANZA'
elif r == 255 and g == 255 and b == 0:
return 'ALLERTA GIALLA - ATTENZIONE'
elif r == 255 and g == 204 and b == 0:
return 'ALLERTA ARANCIONE - PREALLARME'
elif r == 255 and g ==0 and b==0:
return 'ALLERTA ROSSA - ALLARME'
else:
return ''
Ad esempio, la triade (0,255,0), corrisponde al colore VERDE, la triade (255,0,0) corrisponde al colore ROSSO e così via.
Infine è stata definita una struttura adatta a contenere le informazioni estratte dal bollettino PDF; successivamente è stata salvata in un file JSON e pubblicata su un server raggiungibile via Web.
previsioni = {}
previsioni['fonte'] = 'Regione Siciliana - Dipartimento della Protezione Civile'
previsioni['allerta_meteo'] = {}
previsioni['allerta_meteo']['date'] = []
previsioni['allerta_meteo']['url'] = full_url.replace(' ', '%20')
prev = collections.OrderedDict()
prev[primo_giorno_text] = collections.OrderedDict()
prev[secondo_giorno_text] = collections.OrderedDict()
for zona in ['A','B','C','D','E','F','G','H','I']:
rgb = get_pixel(picture, pixel_sicilia_zone_primo_giorno[zona][0], pixel_sicilia_zone_primo_giorno[zona][1])
allerta = get_allerta(rgb[0], rgb[1], rgb[2])
prev[primo_giorno_text]['ZONA ' + zona]= allerta
for zona in ['A','B','C','D','E','F','G','H','I']:
rgb = get_pixel(picture, pixel_sicilia_zone_secondo_giorno[zona][0], pixel_sicilia_zone_secondo_giorno[zona][1])
allerta = get_allerta(rgb[0], rgb[1], rgb[2])
prev[secondo_giorno_text]['ZONA ' + zona]= allerta
previsioni['allerta_meteo']['date'] = prev
with open('allerta.json', 'w') as f:
json.dump(previsioni, f, ensure_ascii=False)
move_cmd = 'mv allerta.json ../../gpirrotta.tk/regione-siciliana/protezione-civile/allerta.json'
os.system(move_cmd)
Tale codice sorgente è stato quindi fatto eseguire una volta al giorno dai vigilantes del conte (che oggi chiameremmo cron) al fine di produrre il seguente output:
[…] E fu così che ritornar potei, a notti placide e soavi sogni, pensate un pò al signorotto piacque, questa mia idea di agir così com’io ho testè scritto…
E c’è chi dice di aver sentito il conte, adesso lui in preda ad incubi notturni, accennar sibilante insolite parole… xml…RSS…POP.
Nessuno seppe però mai cosa intendesse dire, tra veglie, convulsioni e tormenti, con quegli strani e indecifrabili farfugliamenti…
Ioan Pairot
P.S. Non so se in futuro il servizio rimarrà sempre attivo, ma se così sarà i posteri lo potranno trovare al seguente URL. E il codice sorgente qui.
]]>Subito dopo il raduno di Opendata Sicilia 2016, svoltosi a settembre a Messina, avevo voglia di smanettare con gli opendata dei contratti pubblici - i cui URL dei file XML sono disponibili sul sito ANAC - e con gli opendata relativi agli incassi e ai pagamenti di tutte le pubbliche amministrazioni, disponibili sul sito SIOPE. Questi dati contengono informazioni molto utili sullo stato di salute delle pubbliche amministrazioni italiane e il loro riuso, in termini di analisi, esplorazione e mashup, è carburante prezioso per modelli di economie data-based.
Lo sanno bene alcune startup come Synapta che, applicando le potenzialità del linguaggio semantico ai contratti pubblici, rendono più sostenibili la gestione dei dati aziendali, risolvendo problemi quotidiani di aziende, pubbliche amministrazioni e cittadini.
Nel settore pubblico, invece, è da menzionare il progetto soldipubblici che, a partire dagli opendata relativi alle spese delle pubbliche amministrazioni, disponibili su SIOPE, promuovono e migliorano l’accesso e la comprensione dei cittadini sui dati della spesa della Pubblica Amministrazione, in un’ottica di maggiore trasparenza e partecipazione. A causa del cambio di codifica SIOPE, purtroppo, il servizio è momentaneamente non disponibile.
Come dicevo prima, avevo intenzione di sperimentare qualcosa con gli opendata SIOPE e ANAC ma, anche se avevo qualche piccola idea da cui partire, non ero molto convinto su dove sarei andato a parare :-) .
Sentivo forte l’esigenza di confrontarmi con chi, prima di me, si era cimentato nell’analisi di questi dati, ci aveva sbattuto la testa e sicuramente possedeva una visione più completa del dominio di riferimento.
Avevo bisogno di parlare con Giuseppe Ragusa
Quasi due anni fa, Giuseppe, confrontando i dati IPA, cioè le anagrafiche delle pubbliche amministrazioni, con i dati dei contratti pubblici ANAC, aveva scoperto delle anomalie e aveva raccontato la sua ricerca e i suoi risultati in questo post, che vi invito a leggere.
Era l’uomo che cercavo!
Ci siamo dati appuntamento un giorno di gennaio e via hangout abbiamo trascorso quasi l’intero pomeriggio cercando di immaginare, intuire, intercettare un qualche bisogno di cui il cittadino poteva avvertire l’esigenza, cercando di captare e percepire una qualche sua necessità, per farlo diventare, dal punto di vista della partecipazione civica, più attivo, più consapevole, più moderno. Dopo aver partorito due/tre idee da cui partire (che non ricordo neanche più) e dopo un paio di ore di brainstorming, piano piano, in modo silente, nella discussione stava emergendo con sempre più insistenza la parolina magica che sarebbe diventata l’architrave dell’intero progetto finale: sto parlando della parola FOIA.
Disclaimer
Non sono un giurista per cui mi scuso in anticipo per ogni imprecisione giuridica riscontrata nel proseguio del post
Il FOIA, acronimo di Freedom of Information Act è una legge sulla libertà di informazione, emanata negli Stati Uniti il 4 luglio 1966 (Wikipedia).
L’Italia ha recentemente introdotto uno strumento giuridico, chiamato accesso civico generalizzato, che riprende a grandi linee il FOIA americano, motivo per cui anche in Italia si parla ultimamente così tanto di FOIA. Con questo strumento il cittadino può richiedere alla pubblica amministrazione, tramite specifica istanza, dati, documenti, informazioni prodotti e posseduti dalle P.A., con alcune e delimitate esclusioni.
A dire il vero, mediante altre modalità di accesso, il cittadino poteva già ottenere informazioni dalle P.A., come ad esempio attraverso la richiesta di accesso civico semplice. Il cittadino, con questo strumento giuridico, ha il diritto di accesso a documenti, dati e informazioni su cui sussiste l’obbligo di pubblicazione ai sensi del D.Lgs 33/2013. Ogni pubblica amministrazione deve pubblicare sul proprio sito istituzionale, nella sezione Amministrazione Trasparente, un insieme di informazioni. Qualora il cittadino non trovi pubblicata una (o più) di queste informazioni può esercitare il diritto di accesso civico semplice, chiedendo alla P.A. la pubblicazione dei documenti mancanti.
Da segnalare lo strumento online Bussola della Trasparenza, realizzato dal Ministero per la Semplificazione e la Pubblica Amministrazione, con il quale è possibile monitorare l’adempimento, da parte dei siti Web delle pubbliche amministrazioni, degli obblighi di trasparenza imposti dalla legge italiana. Uno degli aspetti più interessanti di questo progetto è che i dati sul monitoraggio degli obblighi sono disponibili in opendata.
Ritornando al brainstorming con Giuseppe, alla fine del confronto sono emerse le seguenti osservazioni/preoccupazioni:
E’ emerso un vuoto da colmare e, sulla scia del nome del progetto albopop, propongo di chiamare questo vuoto FOIAPOP.
FoiaPop ha come obiettivo quello di supportare l’utente nella compilazione online di richieste di accesso civico semplice e generalizzato. Rispetto ad altre soluzioni simili, però, la compilazione della richiesta di accesso civico è guidata dai dati (data-driven). FoiaPop èin grado di ricostruire, in modo preciso e puntuale, i flussi monetari specifici di ogni pubblica amministrazione italiana, su cui il cittadino può facilmente maturare delle domande specifiche di accesso.
Grazie al riutilizzo degli opendata relativi alle basi informative IPA, SIOPE, e AVCP/ANAC, l’utente può formulare le richieste di accesso civico generalizzato semplicemente cliccando sulle voci di spese, incassi o contratti pubblici.
Allo stesso modo, sfruttando gli opendata relativi ai dati IPA, Obblighi ANAC e Bussola della Trasparenza, l’utente può compilare online la richiesta di accesso civico semplice per richiedere la pubblicazione di documenti obbligatori non presenti in Amministrazione Trasparente della Pubblica Amministrazione.
Vediamo adesso nel dettaglio il funzionamento della piattaforma descrivendo il workflow utilizzato da FoiaPop per il suo funzionamento.
Con FoiaPop è possibile selezionare una qualsiasi pubblica amministrazione italiana (più di 20.000), compilare una richiesta di accesso civico in modo semplice e, in pochi click, generare il modulo compilato in PDF da trasmettere alla pubblica amministrazione.
FoiaPop è ente-centrico, tutte le funzionalità ruotano attorno a ciascuna pubblica amministrazione e la base informativa di riferimento, elemento centrale su cui si basa la piattaforma, è l’indice della pubblica amministrazione IPA.
Inseriamo il nome della pubblica amministrazione di nostro interesse nell’apposito modulo di ricerca. Cerchiamo il termine Caltanissetta e scegliamo, tra i vari enti possibili, il comune di Caltanissetta.
FOIAPop ci consentirà, quindi, di creare le seguenti richieste di accesso civico:
Descriviamo adesso le diverse tipologie di richieste disponibili in FoiaPop.
E’ il caso più semplice di richiesta di accesso civico generalizzato (FOIA). Cliccando su Nuovo Accesso Civico Generalizzato verremo rendirizzati nel modulo di inserimento dei dati anagrafici del richiedente e del testo della richiesta.
Clicchiamo su AVANTI. FoiaPop visualizzerà un’anteprima della richiesta di accesso civico generalizzato, utile per effettuare gli ultimi controlli. L’anteprima riflette il modello di domanda PDF che sarà generato e presenta quindi tutte le informazioni di contesto specifico della richiesta di accesso civico generalizzato: l’intestatario Ufficio Relazioni con il Pubblico, l’indirizzo e l’email/PEC della pubblica amministrazione, l’oggetto, i dati anagrafici del richiedente, la richiesta stessa e, in calce, lo spazio dedicato alla firma. Seguono quindi le istruzioni relative alla modalità di trasmissione della richiesta che si sta per generare, con possibilità di download.
Dopo aver controllato la correttezza delle informazioni visualizzate in anteprima e dopo aver ricordato le modalità operative di trasmissione del modello, si può procedere alla generazione in PDF della richiesta di accesso civico generalizzato.
A questo punto l’utente può trasmettere la richiesta secondo le modalità di trasmissione che preferisce.
Nonostante il diritto di accesso generalizzato sia uno strumento a disposizione di tutti, spesso i cittadini non sanno cosa chiedere, non conoscono i dati sui quali possono chiedere informazioni, spiegazioni, chiarimenti. Per supportare il cittadino FoiaPop consente la compilazione di richieste di accesso civico generalizzato a partire dai dati SIOPE, cioè a partire da dati relativi gli incassi e i pagamenti delle pubbliche amministrazioni. Queste informazioni sono disponibili in opendata sul sito SIOPE da cui è possibile effettuare anche il download massivo per anno. Il livello di dettaglio è per singolo mese, la frequenza di aggiornamento è circa settimanale e tutti gli importi sono organizzati per codici gestionali SIOPE.
Per iniziare una nuova richiesta a partire dai dati SIOPE, dopo aver selezionato la pubblica amministrazione di nostro interesse, clicchiamo su Parti dai dati SIOPE - Incassi e Pagamenti Enti Pubblici e FoiaPop ci mostretà il seguente elenco
Per ogni voce SIOPE viene mostrata la tipologia (Entrate o Uscite), l’anno e il mese di riferimento, il codice gestionale SIOPE, la descrizione e l’importo relativo. Il più delle volte l’elenco è composto da diverse centinaia di righe ed è possibile filtrare i dati per parola chiave attraverso il modulo, posto ad inizio pagina.
Scorrendo verso il basso immaginiamo di volere chiedere maggiori informazioni sulla seguente spesa:
Non ci resta che cliccare su CREA FOIA ed iniziare la nostra richiesta. FoiaPop ci ripresenterà lo stesso form di compilazione dei dati anagrafici che abbiamo visto in precedenza con un’interessante differenza:
Subito prima del campo richiesta è presente un riquadro con il dettaglio della voce SIOPE che abbiamo selezionato in precedenza e su cui intendiamo esercitare il diritto di accesso civico generalizzato.
Clicchiamo su AVANTI. Anche in questo caso FoiaPop visualizzerà l’anteprima del modulo di richiesta ed inserirà automaticamente il riferimento ai dati SIOPE di nostro interesse, come si può vedere dalla seguente figura.
Dopo aver controllato l’esattezza di tutti i dati dell’anteprima non ci resta che cliccare sul tasto CREA RICHIESTA FOIA per generare il modulo in PDF da trasmettere alla P.A.
Oltre ai dati SIOPE, FoiaPop consente anche di creare richieste di accesso civico generalizzato a partire dai contratti pubblici delle P.A. La base informativa di riferimento è il sito ANAC dove è possibile effettuare il download di tutti gli URL dei file XML contenenti le informazioni sui contratti pubblici delle P.A., secondo lo standard AVCP.
Per iniziare una nuova richiesta dai dati ANAC, dopo aver selezionato la pubblica amministrazione di nostro interesse, clicchiamo su Parti dai dati ANAC - Contratti Pubblici -. FoiaPop ci mostrerà il seguente elenco
Per ogni contratto viene visualizzato la descrizione dell’appalto, i partecipanti alla gara, l’aggiudicatario, i tempi di completamento, l’importo di aggiudicazione e l’importo delle somme liquidate. Come già visto in precedenza, anche qui è disponibile un filtro di ricerca per parola chiave.
Prendiamo per esempio il seguente appalto:
Come per i casi precedenti dobbiamo inserire tutte le informazioni anagrafiche del richiedente e, in questo caso, nel campo relativo alla richiesta troviamo i dati sull’appalto ANAC su cui intendiamo esercitare il diritto di accesso.
Clicchiamo su AVANTI e l’anteprima ci mostrerà il riferimento ai dati ANAC incorporati nel testo della richiesta, con in più il riferimento dell’URL, fonte dei dati ANAC e il CIG di riferimento dell’appalto.
Dopo aver controllato l’esattezza di tutte le informazioni inserite procediamo alla generazione del modulo di richiesta in PDF cliccando su CREA RICHIESTA FOIA. Il modulo generato potrà quindi essere trasmesso alla pubblica amministrazione.
Attraverso apposite API FoiaPop consente l’integrazione delle sue funzionalità con siti esterni, come, ad esempio, i siti istituzionali degli enti pubblici.
L’URL da invocare è il seguente:
dove il parametro cf (obbligatorio) rappresenta il codice fiscale della pubblica amministrazione e il parametro dati (opzionale) rappresenta il dato da inserire nella richiesta di accesso civico generalizzato.
Un tipico scenario d’uso è, ad esempio, l’inserimento di un link (o di un bottone) nel sito istituzionale del comune utilizzando il parametro dati per veicolare gli oggetti degli atti amministrativi degli albi pretori come dati di partenza. L’utente che visita l’albo pretorio del comune vedrà, per ogni atto amministrativo pubblicato, un bottone Accesso Civico che lo rendirizzerà su FoiaPop per la compilazione automatica della richiesta di accesso civico generalizzato, a partire dai dati relativi all’oggetto specifico di quell’atto amministrativo.
Se non si vuole scendere a questo livello di dettaglio e per facilitare i webmaster dei siti delle pubbliche amministrazioni (ma anche di siti esterni) FoiaPop mette a disposizione dei widget pronti all’uso, da posizionare nelle pagine dei siti Web istituzionali, il cui codice HTML può essere copiato e incollato all’interno dei propri portali.
Cliccando su uno dei bottoni si verrà reindirizzati su FoiaPop e si potrà iniziare il processo di compilazione della richiesta online, esattamente come già visto in precedenza. L’ente di partenza è sempre il Comune di Caltanissetta.
Come già detto all’inizio di questo post, esistono diverse tipologie di accesso civico a disposizione del cittadino per richiedere informazioni e, tra queste, una delle più importanti è la richiesta di accesso civico semplice. Con questa richiesta si ha il diritto di accesso ai documenti, dati e informazioni su cui sussite l’obbligo di pubblicazione ai sensi del D.Lgs.33/2013. Tali obblighi sono resi di più agevole comprensione da ANAC (Autorità nazionale anticorruzione) che ne ha elaborato un elenco specifico. Tali informazioni devono essere pubblicate all’interno di ogni sito istituzionale delle P.A. nella sezione Amministrazione Trasparente. Se il cittadino non trova pubblicate una o più di queste informazioni può esercitare il diritto di accesso civico semplice, chiedendo alla P.A. la pubblicazione dei documenti mancanti.
Anche per questa tipologia di richiesta FoiaPop consente di creare passo passo il modulo da trasmettere alla P.A. Vediamo come.
Il punto di partenza è sempre la pubblica amministrazione di nostro interesse. Anche in questo caso scegliamo il comune di Caltanissetta.
Clicchiamo quindi su Nuovo Accesso Civico Semplice - Pubblicazioni Online Obbligatorie.
FoiaPop ci mostrerà l’elenco dei documenti che tutte le P.A. devono pubblicare all’interno della sezione Amministrazione Trasparente dei loro siti istituzionali. Tali obblighi, così come previsti dall’ANAC, sono strutturati in sezioni (macrofamiglie) e in sottosezioni (tipologie di dati).
Per ciascun obbligo, passando il mouse sopra l’icona punto interrogativo, FoiaPop visualizzerà il contenuto con un dettaglio maggiore.
FoiaPop, inoltre, verificherà l’esito del monitoraggio effettuato dalla Bussola della Trasparenza per ciascun obbligo e, in caso di esito positivo, mostrerà l’icona di una bussola con il collegamento alla pagina del sito istituzionale al cui interno si trova (o si dovrebbe trovare) il documento relativo all’obbligo monitorato.
L’utente procederà quindi a inserire uno o più obblighi nella richiesta di accesso civico semplice, a mò di carrello della spesa, e per ciascuna selezione potrà indicare la motivazione della richiesta, così come di seguito riportato.
Dopo aver selezionato il/i documento/i su cui richiedere l’accesso, premendo il tasto AVANTI l’utente potrà inserire le informazioni anagrafiche così come visto in precedenza.
Alla fine del modulo viene visualizzato il dettaglio degli obblighi non rispettati che si vogliono aggiungere alla richiesta. FoiaPop consente anche di inserire, in un campo libero, eventuali precisazioni a corredo della richiesta stessa.
Cliccando su AVANTI FoiaPop visualizzerà l’anteprima della richiesta di accesso civico semplice, completa di tutte le informazioni inserite.
Nella stessa pagina, in basso, si troveranno sempre le indicazioni operative per la trasmissione della richiesta alla P.A. (con possibilità di download). Dopo aver controllato l’esattezza di tutte le informazioni inserite nella richiesta possiamo cliccare su CREA RICHIESTA ACCESSO CIVICO SEMPLICE e FoiaPop genererà per noi il documento in PDF da trasmettere alla pubblica amministrazione.
Attraverso l’accesso tramite API è possibile generare richieste di accesso civico semplice a partire da siti esterni. L’URL da invocare è il seguente:
doce il parametro cf (obbligatorio) rappresenta il codice fiscale della pubblica amministrazione.
Un tipico scenario d’uso è, ad esempio, l’inserimento di un link (o di un bottone) all’interno del sito istituzionale di un comune, nella sezione Amministrazione Trasparente. L’utente che non riesce a trovare il documento desiderato, cliccando sul link/bottone, viene quindi reindirizzato su FoiaPop per la compilazione passo passo della richiesta di accesso civico semplice del documento non trovato.
Per facilitare il lavoro ai webmaster, FoiaPop mette a disposizione dei widget pronti all’uso, da posizionare direttamente nelle pagine del sito Web istituzionale, copiando e incollando il codice HTML generato dalla piattaforma. L’ente è sempre il Comune di Caltanissetta.
Cliccando su uno di questi bottoni si verrà reindirizzati su FoiaPop e si potrà iniziare il processo di compilazione della richiesta online, esattamente come già visto in precedenza.
FoiaPop è una piattaforma online per la compilazione di richieste di accesso civico semplice e generalizzato.
E’ online la versione beta.
FoiaPop è uno strumento rivolto ai cittadini per facilitare loro la compilazione delle richieste di accesso civico. Ma non è solo questo.
FoiaPop vuole essere uno strumento in grado aumentare la consapevolezza civica del cittadino comune affinchè possa diventare sempre più partecipe e determinante nella vita amministrativa della propria città, possa comprendere sempre meglio i processi interni della burocrazia del palazzo, possa farsi domande che suscitino in lui dubbi, critiche e osservazioni, che stimolino anche proposte, consigli e suggerimenti, possa svolgere attività di controllo dei processi decisionali all’interno delle istituzioni.
Se questo progetto ti è piaciuto, mi aiuti a farlo conoscere con un tweet? Grazie!
Per feedback, suggerimenti e critiche non esitate a lasciarmi un commento.
]]>Qualche mese più tardi Andrea Borruso creava l’ Albo Pop del comune di Bagheria, uno strumento in grado di collegare l’albo pretorio del comune a più canali online (RSS, Twitter, BOT Telegram), replicato successivamente anche da altri comuni sparsi in tutta Italia e da altre pubbliche amministrazioni.
In rete esistono tantissimi progetti che riusano dati cittadini e creano valore per l’utente finale. Cito ad esempio i BOT sviluppati da Pierfrancesco Paolicelli.
In passato anch’io ho presentato soluzioni applicative, a partire da dati aperti e non, in grado di creare servizi per la cittadinanza: OpenAlboPretorio, Parking in Messina, BOT Telegram per i trasporti (Amat Palermo) e per la Protezione Civile.
Tutti questi progetti erogano servizi per i cittadini, ne migliorano la vivibilità, incentivano la trasparenza della macchina pubblica, forniscono nuove modalità di interazione sfruttando le potenzialità della tecnologia, forniscono nuovi servizi al cittadino creando di fatto valore all’utente finale.
I dati cittadini sono più o meno sempre gli stessi, solitamente riguardano settori come ambiente, macchina amministrativa, cultura, turismo, istruzione, mobilità, sicurezza, sanità, sociale, sport, urbanistica, etc. Queste tematiche sono trasversali per città di qualsiasi dimensione, a partire da essi si potrebbero sviluppare effettivamente un’infinità di applicazioni per migliorare efficacemente la vita al cittadino.
Spesso mi arrivano email di richieste di aiuto, per l’implementazione di servizi che ho realizzato in passato in alcune città. Richieste di amministratori, associazioni o privati che vorrebbero vedere lo stesso identico servizio digitale anche nella loro città.
A questo punto mi faccio delle domande.
Perchè non far funzionare il tutto su un’unica piattaforma, sviluppare l’applicazione una volta sola e renderla disponibile a tutte le città? E ancora, perchè non dare ad ogni cittadino, ed ad ogni città, la possibilità di crearsi uno strumento in grado di creare valore a partire dai dati posseduti senza essere esperti di programmazione?
E’ da qui che sono partito, dalla consapevolezza che, individuata un’applicazione per soddisfare un’esigenza, tale soluzione possa essere replicata a tutte le città, in modo semplice e intuitivo. Piuttosto che avere tante app da installare sul proprio smartphone ho immaginato un’applicazione HUB, un aggregatore configurabile di flussi informativi, scalabile ed estendibile, che possa contenere più servizi, per lo smistamento centralizzato di informazioni generati a partire soprattutto da opendata.
Queste domande sono state il deterrente per la nascita di CityBot.
Disclaimer - CityBot è un prototipo sviluppato dal sottoscritto nei ritagli di tempo extralavorativi e non è ancora in versione stabile. Tuttavia è possibile sperimentarne già alcune funzionalità ma non è prevista ancora una data di rilascio pubblica ufficiale
Qualche giorno fa Skype (leggi Microsoft) ha annunciato il rilascio di un framework di sviluppo di BOT che consentirà agli sviluppatori di creare BOT dentro Skype. Anche Slack, da tempo, consente di programmare BOT per erogare servizi all’interno della sua chat. Inoltre Facebook, tramite il suo Messenger, ha iniziato a fornire servizi per gli utenti, sotto forma di BOT, anche se per adesso non ha aperto al mondo degli sviluppatori.
Con ciò cosa voglio dire? Voglio dire che l’attenzione da parte di importanti player IT verso i BOT si sta facendo molto seria! Proprio per questo credo fermamente che il mondo dei BOT sia una strada su cui investire tempo e risorse perchè potrebbe rivelarsi un canale su cui sviluppare modelli di business sostenibili.
CityBot è un configuratore di BOT Telegram in grado di creare servizi informativi per le città, rapidamente e senza essere esperti di programmazione.
CityBot fornisce attualmente le seguenti funzionalità:
Vediamo adesso come creare da zero un nuovo BOT e come arricchirlo di nuove funzionalità. Decidiamo, ad esempio, di creare il CityBot per la città di Palermo. Prima di operare su CityBot dobbiamo entrare in Telegram e creare un nuovo BOT. E’ un’operazione molto semplice, trovate tutte le informazioni sulla documentazione ufficiale di Telegram. Con quest’operazione otterrete il codice identificativo segreto del BOT, chiamato TOKEN, che ci servirà per la creazione del CityBot.
Andando quindi su Telegram creiamo il BOT PalermoCity_Bot.
Ritornando a CityBot, dopo una prima fase di registrazione, effettuiamo il login e ci ritroviamo nella pagina di benvenuto:
A questo punto clicchiamo su Crea il cityBot per la tua città e davanti a noi apparirà la seguente schermata che ci chiederà di inserire il nome della città del BOT e il TOKEN di Telegram, ottenuto in fase di creazione del BOT.
Inseriti nome della città e TOKEN (fittizio nell’esempio),
possiamo creare il BOT. Automaticamente la piattaforma riconoscerà il nome del BOT e ci consentirà di configurarlo in base alle nostre necessità. Cliccando su Configura,
entreremo nel pannello di configurazione del BOT:
![Image](/images/citybot-5.jpg?a %}
Dal pannello superiore si potrà accendere il BOT, spegnerlo, eliminarlo o modificare la città. La parte più interessante, però, è quella dei servizi disponibili, in elenco nel pannello inferiore. Nella sezione Plugin disponibili sono presenti i seguenti servizi:
Entriamo nel dettaglio in ciascuno dei servizi.
##Flusso RSS Feed L’RSS è uno dei più popolari formati per la distribuzione di contenuti Web, un flusso di testo aggiornato automaticamente sui nuovi articoli del sito a cui si riferisce. Al plugin di CityBot è possibile agganciare uno o più feed RSS, inerenti qualsiasi tipo di news: municipio, università, cronaca, politica, attualità, sport, eventi, etc.
Nel nostro esempio decidiamo di collegare in CityBot le notizie del comune. Sul sito del comune di Palermo i feed RSS sono disponibili alla seguente pagina.
Decidiamo di agganciare al nostro CityBot i seguenti feed:
Spostiamoci adesso su CityBot e iniziamo ad aggiungere il primo plugin al nostro CityBot scegliendo quindi flusso RSS Feed.
Clicchiamo su Aggiungi e vedremo comparire il plugin nella sezione Plugin Aggiunti.
A questo punto configuriamo il plugin cliccando su Configura e definiamo un nome per il servizio RSS. Tale nome comparirà nel menù del BOT, per cui cerchiamo di sceglierne uno il più appropriato possibile al contenuto informativo da agganciare. In questo caso, ad esempio, scegliamo il nome “Comune di Palermo”.
![Image](/images/citybot-9.jpg?a %}
Andiamo avanti e iniziamo la configurazione dei feed RSS.
![Image](/images/citybot-10.jpg?p %}
Nella sezione Feed collegati clicchiamo sul bottone Aggiungi (segno più)
e inseriamo il primo feed RSS
Anche in questo caso il nome del feed corrisponderà al nome del sottocomando del BOT. Per il nostro esempio inseriamo il nome News. Il numero max di elementi del feed è configurabile ma nel nostro esempio lasciamo il valore di default 10.
Ripetiamo la stessa operazione per il secondo feed inserendo come nome Bandi e Gare
Per ogni feed possiamo verificarne il contenuto o procedere alla rimozione.
![Image](/images/citybot-14.jpg?o %}
Ritorniamo nel pannello di amministrazione del plugin e accendiamo il servizio.
Dopodichè accendiamo anche il BOT,
ci spostiamo sul nostro smartphone e cerchiamo il Canale PalermoCity_BOT.
Nella schermata compare il messaggio di benvenuto e in basso il menù dei comandi disponibili. A sinistra compare il comando Comune di Palermo, definito nella configurazione del flusso RSS, mentre a destra il comando, sempre presente nel menù principale, relativo alle informazioni di CityBot. Cliccando su quest’ultimo vedremo la seguente schermata:
Nella schermata sono presente informazioni relative a CityBot, tra cui la città di riferimento e il nome dell’utente che ha creato il BOT. Cliccando invece sul primo comando, cioè Comune di Palermo, apparirà il seguente menù:
Il bottone di sinistra, così come configurato precedentemente, è collegato al feed RSS relativo alle informazioni sul comune di Palermo:
Il bottone di destra è collegato invece al feed RSS relativo alle informazioni su Bandi e gare.
##Flusso Comun Web ComunWeb nasce come riuso di una piattaforma realizzata per il comune di Trento, sviluppata da OpenContent e usata oggi da 178 enti locali, 2.123 amministratori locali e 5.000 dipendenti comunali. L’infrastruttura fornita da ComunWeb consente di strutturare e organizzare in modo intelligente le informazioni trattate mediante l’utilizzo di un modello di dati condiviso e di esporre tali dati con licenza opendata attraverso delle API REST.
E’ possibile collegare CityBot ad un flusso dati ComunWeb proveniente da qualsiasi comune aderente. Anche se non ha molto senso agganciare un flusso ComunWeb al nostro CityBot, dato che Palermo non è fra gli enti aderenti, immaginiamo di configurare il nostro CityBot per una città aderente, ad esempio per la città di Ala (TN).
Interrogando le API disponibili risaliamo ai link relativi al catalogo dei dataset, alla lista delle classi globali e a quelle utilizzate. Da quest’ultimo link decidiamo di agganciare CityBot con l’Albo Pretorio e l’elenco delle associazioni presenti in città.
Individuate le fonti dati spostiamoci sul pannello di configurazione di CityBot e aggiungiamo il plugin Flusso ComunWeb.
Entriamo in configurazione e, come per il Flusso RSS, inseriamo il nome che apparirà nel comando del menù principale del BOT; decidiamo di mettere come nome Comune di Ala (TN).
Inseriamo i due link di interrogazione per le informazioni da collegare. Decidiamo di chiamarli Albo Pretorio e Associazioni.
Anche in questo caso accendiamo il servizio, accendiamo il BOT e ci spostiamo sullo smartphone.
Come possiamo vedere dalla schermata, il bottone relativo al Comune di Ala è stato aggiunto a fianco a quello del Comune di Palermo.
Al nuovo bottone è associato il seguente sottomenù:
Al bottone Albo Pretorio corrisponderà il seguente flusso ComunWeb:
Al bottone Associazioni è agganciato invece quest’altro flusso:
Dal sito della Protezione Civile leggiamo:
Le aree di attesa sono i luoghi di prima accoglienza per la popolazione; possono essere utilizzate piazze, slarghi, parcheggi, spazi pubblici o privati non soggetti a rischio (frane, alluvioni, crollo di strutture attigue, etc.), raggiungibili attraverso un percorso sicuro. Il numero delle aree da scegliere è funzione della capacità ricettiva degli spazi disponibili e del numero degli abitanti. In tali aree la popolazione riceve le prime informazioni sull’evento e i primi generi di conforto. Le Aree di Attesa della popolazione saranno utilizzate per un periodo di tempo compreso tra poche ore e qualche giorno.
Il plugin Area di Attesa - Protezione Civile si pone come obiettivo quello di individuare in caso di emergenza, l’area di accoglienza più vicina prevista dalla Protezione Civile, fornendoci indicazioni relative alla distanza, percorso e tempo di percorrenza a partire dalla nostra posizione attuale.
Dal pannello di CityBot aggiungiamo il plugin Area di Attesa - Protezione Civile ed entriamo in configurazione. Visualizzeremo la seguente schermata:
A questo punto dovremo disegnare i poligoni corrispondenti alle aree di attesa della Protezione Civile. Possiamo farlo in due modi:
Nel primo caso bisognerà individuare l’area di attesa sulla mappa, cliccare sullo strumento Poligono in alto a destra,
e iniziare a disegnare il poligono lato per lato.-
Alla chiusura del poligono sarà necessario inserire informazioni relative all’area di attesa disegnata:
Inserite le informazioni dell’area di attesa, per aggiornare la mappa bisognerà cliccare su Aggiorna Dati. Dopo aver disegnato tutte le aree manualmente, per salvare la mappa in CityBot bisognerà cliccare su Salva mappa.
Nel secondo caso basterà invece uplodare la mappa da file GEOJSON, con l’unica accortezza di inserire le informazioni delle aree di attesa in proprietà chiamate name e description, dentro properties.
Esempio di caricamento delle aree di attesa da file GEOJSON:
Usciamo e ritorniamo nel pannello di amministrazione del BOT; accendiamo il servizio e spostiamoci sullo smartphone.
Il nuovo menù principale apparirà nel seguente modo:
Cliccando su Protezione Civile saremo invitati a cliccare sull’icona graffetta e ad inserire la nostra posizione geografica.
CityBot automaticamente calcolerà l’area di accoglienza più vicina, indicando sia la distanza per raggiungerla che il tempo di percorrenza a piedi. Verrà fornita anche la mappa e il link del percorso da seguire, passo passo.
Il problema dei parcheggi fuori e dentro le ZTL è più o meno trasversale a tutte le città. Vediamo adesso come sfruttare CityBot per calcolare automaticamente la tariffa oraria dei parcheggi, in base alla posizione GPS dello smartphone.
Aggiungiamo quindi l’ultimo dei servizi disponibili in CityBot e procediamo alla sua configurazione.
Anche per questo plugin, come per quello precedente, è possibile disegnare le mappe delle zone di parcheggio manualmente o da file GEOJSON. Nel primo caso indicheremo quindi nel campo Nome il nome dell’area di pagamento (ad es. P1, P2, ZTL1, ZTL2, etc.) e nel campo Descrizione, il dettaglio del pedaggio da pagare (Tariffa oraria, Fascia Oraria, Validità, etc.). Per il nostro esempio, su umap troviamo la mappa dei parcheggi su strada a pagamento di Palermo; decidiamo quindi di caricare su CityBot il file GEOJSON, adattando opportunamente il campo properties (name e description).
Ritorniamo nel pannello del BOT,accendiamo quest’ultimo servizio e il BOT. Spostandoci adesso sullo smartphone il menù sarà adesso:
Cliccando su Pedaggio in ZTL, ci verrà chiesto di inserire la propria posizione, sempre tramite l’icona graffetta, e CityBot ci fornirà le informazioni relative al pedaggio da pagare in base alla nostra posizione.
In questo post ho voluto raccontare la mia visione di città digitale. Tutto nasce dalla convinzione che l’utilità di un servizio digitale presente in una città può e deve essere esportata con facilità in qualsiasi altra città in modo che tutti i cittadini possano beneficiare degli stessi vantaggi digitali.
Da diversi mesi sto investendo tempo e risorse nello sviluppo di servizi digitali con i BOT Telegram e CityBot è un pò la summa delle esperienze maturate.
In futuro ho in mente di estendere CityBot con le seguenti funzionalità:
La piattaforma di CityBot si trova qui. Se volete provare il CityBot creato come esempio per la città di Palermo, cliccate qui.
Se CityBot vi è piaciuto, aiutatemi a farlo conoscere con un tweet, grazie!
Per feedback, suggerimenti e critiche non esitate a lasciarmi un commento.
That’s all folks! Stay tuned!
]]>Succede, però, che un lunedì mattina ricevo una email di Andrea Borruso, il quale mi propone, su un’idea di Ciro Spataro, di sviluppare un BOT che consenta ai cittadini palermitani, in caso di emergenza, di essere informati tempestivamente sulla posizione delle aree di accoglienza da raggiungere, predisposte dalla Protezione Civile di Palermo.
Dal sito della protezione civile si legge:
Le aree di accoglienza sono luoghi, individuati in aree sicure rispetto alle diverse tipologie di rischio e poste nelle vicinanze di risorse idriche, elettriche e fognarie, in cui vengono installati i primi insediamenti abitativi per alloggiare la popolazione colpita. Dovranno essere facilmente raggiungibili anche da mezzi di grandi dimensioni per consentirne l’allestimento e la gestione. Rientrano nella definizione di aree di accoglienza o di ricovero anche le strutture ricettive (hotel, residence, camping, etc.).
Negli ultimi quaranta anni, in molte zone d’Italia e specialmente in Sicilia, si sono verificati eventi di dissesto idrogeologico che hanno avuto conseguenze spesso catastrofiche. Senza andare troppo lontano negli anni, lucido è in me il ricordo del violento nubifragio di Messina del 2009, in cui hanno perso la vita 35 persone. Di conseguenza, la possibilità di diffondere informazioni ufficiali e prioritarie da parte delle istituzioni competenti, anche attraverso nuovi media che sfruttino la componente digitale come chiavistello per aprire canali mai raggiunti prima e arrivare, in caso di emergenza, a quanta più gente possibile nel più breve tempo possibile, assume un’importanza sempre più decisiva e strategica per la salvaguardia di vite umane.
In questo contesto, la disponibilità di dati aperti, gratuiti e accessibili riguardanti informazioni strategiche e di raccordo, soprattutto nei settori in cui la tempestività e il veicolo di informazioni giocano un ruolo cruciale, costituisce un elemento determinante e necessario per lo sviluppo di servizi vitali per il cittadino.
Chi sicuramente ha già capito questo è Ciro Spataro che, in veste di civic-hacker, ha mappato le aree di accoglienza persone della Protezione Civile di Palermo usando umap e openstreetmap.
Poniamoci adesso questa domanda: come possiamo riutilizzare i dati della mappa in altri contesti e creare servizi di valore e gratuiti per i cittadini palermitani?
Ciro suggerisce di prendere come esempio il lavoro fatto a Prato da Matteo Tempestini, cioè un BOT Telegram in grado di fornire varie informazioni utili per il cittadino, tra cui la possibilità di individuare, in caso di emergenza, l’area di accoglienza più vicina prevista dalla Protezione Civile.
Ho già avuto a che fare sia con progetti legati alla georeferenziazione di posizioni geografiche e alla loro appartenenza rispetto ad un’area geografica (ne parlo in questo post) sia con progetti legati allo sviluppo di BOT su dati relativi ai trasporti urbani (ne parlo in quest’altro post).
Tecnicamente si tratta di risolvere il seguente problema: data una posizione geografica, leggi latitudine e longitudine, individuare l’area di accoglienza o di ricovero della popolazione più vicine, secondo quanto previsto dalla Protezione Civile.
Dalla mappa mi esporto quindi tutte le aree in formato geoJSON, recuperando le coordinate dei vertici di ogni poligono. Dopodichè l’applicazione mi dovrà restituire l’area che ha il vertice più vicino alla posizione dell’utente.
La logica del programma è molto semplice:
In un mio precedente post ho affrontato il problema della distanza di un punto da una lista di punti utilizzando in modo diretto formule trigonometriche e una chiamata SQL.
Questa volta invece utilizzerò la libreria GeoTools, sviluppata da Antoine Corcy. La libreria fornisce molteplici funzionalità legate al mondo della georeferenziazione tra cui geocodifiche dirette e inverse, conversioni tra coordinate, distanze tra punti geografici in metri, chilometri, miglia o piedi, etc.
Siano, ad esempio, $coordA e $coordB i due punti di cui si vuole conoscere la distanza; per creare l’oggetto distance è necessario digitare quanto segue:
Per avere la distanza in metri (default) con il più performante tra gli algoritmi in libreria, digitiamo invece:
Se volessimo utilizzare invece l’algoritmo great-circle:
Per avere la distanza in chilometri utilizzando l’algoritmo haversine, l’invocazione sarà la seguente:
L’algoritmo vincenty, il più accurato fra tutti quelli presenti, è invocato nel seguente modo, con distanza in miglia:
Per maggiori informazioni consultate la documentazione ufficiale della libreria.
Risolto il problema di come calcolare la distanza, trovare l’area di accoglienza più vicina diventa un’operazione banale.
La funzionalità è affidata alla classe GeoToolsDistance che implementa il metodo distance come da contratto con l’interfaccia DistanceInterface.
In input vengono presi due oggetti del dominio di classe Vertex. Il codice è autoesplicativo.
Per confrontare le distanze di tutte le aree di accoglienza partiamo dall’oggetto Map che, dopo aver caricato in memoria la struttura dati del file GeoJSON, contenente le coordinate geografiche delle aree di accoglienza della protezione civile di Palermo, calcola la distanza minima all’interno del metodo getNearestArea. Il metodo prende in input la posizione dell’utente e restituisce in output l’area di accoglienza più vicina.
Per calcolare il tempo necessario per raggiungere l’area di accoglienza a piedi (feature consigliata da Andrea) ho usato l’API distancematrix messa a disposizione da Google.
L’output della chiamata restituisce informazioni relative alla distanza del viaggio e al tempo necessario per, partendo dal primo punto, raggiungere il secondo punto a piedi.
Per il percorso da seguire ho semplicemente inviato al BOT il seguente link, sostituendo opportunamente le variabili delle coordinate geografiche:
Mettiamo tutto in funzione e vediamo cosa apparirà su Telegram.
Il BOT da cercare si chiama @protezioneCivilePAbot
La prima cosa da fare è inviare la propria posizione cliccando sulla graffetta.
A questo punto il BOT risponderà nel seguente modo:
informando l’utente su quale area di accoglienza raggiungere, visualizzandola su mappa, su come raggiungerla e su quanto tempo ci vorrà a piedi per raggiungerla.
Il codice della demo, lo trovate nel mio repository si github.
Il progetto è scalabile per ogni città, basta avere un file GeoJSON, prodotto con Umap o con qualsiasi altro tool, con le aree di accoglienza della Protezione Civile.
Un ringraziamento particolare per il progetto va a Ciro Spataro, da cui è nata l’idea e ad Andrea Borruso, per i suoi preziosi feedback e consigli.
Se questo progetto vi è piaciuto un pò, mi aiutate a farlo conoscere in giro? Grazie
Twittami
That’s all folks! Stay tuned!
]]>In the literature we can find many other definitions to explain and define what ontology represents and means.
The term ontology is used in artificial intelligence, in the Semantic Web, in systems engineering, in software engineering, in biomedical informatics, in library science, in enterprise bookmarking and information architecture as a form of knowledge representation about the world or some part of it.
Ontologies have become common on the World Wide Web. The W3C Consortium developed the RDF Model, a language for encoding knowledge on Web pages to make it understandable to electronic agents. An ontology is the final result of a knowledge engineering process, a well–defined schema allows us to unambiguously define concepts and relationships over a specific knowledge domain.
As an ontology is an explicit description qualitatively advanced of domain concepts, it can be published and reused for different purposes, even if they were not included when it was created. Starting from standardized ontologies, it becomes much easier to develop their more specific ontology reusing and extending the existing ones.
Now we will see briefly the steps to follow in the knowledge engineering process.
The starting point is the domain to model.
One of the ways to understand the domain of the ontology is to sketch a list of questions that a knowledge base relying on the ontology should be able to answer. This task is called competency questions (Gruninger and Fox) and is useful to understand if the ontology includes sufficient information or needs further details. The ontology development is an iterative process and there are many correct ways to model a domain, so the question list should not necessarily be exhaustive.
Rather than reinvent the wheel, a very important aspect in the ontology development process is to consider reusing existing ontologies. As someone might have already defined an ontology about the same topic, it should be better to reuse and extend it for a specific purpose, thus saving a lot of hard work, instead of rewriting a new one. We can find hundreds of ontologies for any field of application.
Some of the most famous ontologies in the Semantic Web area are:
At this point, the goal is to extract and list all terms relative to the model. After collecting the most important words, we have to identify terms representing concepts, preferring to use nouns, and terms representing relations. Moreover, we have to define the hierarchical relation between concepts and we can use three approaches:
Starting from the above same term list we have to identify relationships between concepts identified in the previous step. Depending on property type, we can identify intrinsic properties which are those relating to the concept content, independently of other things, including its context and extrinsic properties which are those depending on a thing’s relationship with other things. To correctly model a specific domain, we need to define some ontology constraints to ensure instance consistency and validity. The most commonly used constraints are:
Il motivo di tutto questo proliferare di BOT è dovuto principalmente all’apertura di Telegram, nella sua versione 3, al mondo degli sviluppatori. Attraverso l’utilizzo di API ufficiali, infatti, è ora possibile creare, gestire e interagire con programmi BOT, personalizzandoli secondo le proprie esigenze.
Ho sempre visto un alto potenziale nell’uso di questo tipo di applicazioni e la scelta di Telegram potrebbe rivelarsi particolarmente azzeccata in questo senso.
Esattamente due anni fa anch’io ho iniziato a interessarmi di BOT, ad immaginarmi il mio smartphone come un telecomando da pigiare per ottenere specifici servizi: informazioni sui programmi televisivi, previsioni meteo, eventi serali della mia città, orari di apertura degli uffici pubblici, etc. Ho sviluppato quindi un BOT su Twitter grazie al quale, con un semplice tweet e una microgrammatica, riuscivo ad inviare richieste ad un’applicazione per ottenere informazioni sui programmi televisivi della serata. Descrivo nel dettaglio l’implementazione del progetto, che si chiama per l’appunto cosaceintv, in questo post; il sito del progetto è cosaceintv.it.
Tuttavia Twitter non consente di creare BOT in modo nativo per cui, per raggiungere lo scopo, sono dovuto scendere a compromessi, chiamateli workaround.
Ma con Telegram la situazione cambia
Vero è che l’app non è diffusa come WhatsApp, l’attuale killer application nel settore dell’instant messaging, (molti si aspettavano dei segnali di apertura API da WhatsApp in occasione dell’ultima conferenza F8 di Facebook, ma invece nisba) ma è anche vero che Telegram sta guadagnando sempre più terreno grazie soprattutto a scelte aziendali che si stanno rivelando strategicamente vincenti, come ad esempio
Più che una semplice app di messaggistica Telegram è di fatto una vera e propria piattaforma e in rete si trovano già applicazioni BOT di qualsiasi tipo; le più popolari si possono trovare al seguente link.
Ma anche in Italia cominciano a vedersi progetti interessanti.
A Prato Matteo Tempestini ha sviluppato il BOT Emergenze Prato per essere aggiornati in tempo reale su condizioni meteo, possibili allerte e segnalazioni. A Lecce, utilizzando gli opendata del comune e non solo, Pier Paolo Paolicelli (piersoft) ha sviluppato [OpenDataLecceBot]((https://telegram.me/opendataleccebot) con il quale è possibile ottenere informazioni su meteo, temperatura, qualità dell’aria, orari delle scuole, tariffe aree ZTL, eventi culturali, etc. Il servizio trasporti bus TPER fornisce informazioni aggiornate sui bus di Bologna usando i servizi informativi e gli opendata. (tperbot.)
Incuriosito quindi da tutto questo fermento mi è venuta voglia di rimettermi in gioco anch’io con i BOT e smanettare un pò con questa piattaforma. Ho accolto, quindi, il suggerimento di piersoft che consigliava di replicare il servizio offerto dalla TPER di Bologna sui trasporti anche per la città di Palermo, dato che i dati sui trasporti palermitani sono rilasciati dall’ azienda AMAT in formato GTFS con licenza OpenData.
La specifica GTFS (General Transit Feed Specification) è stata sviluppata da Google e definisce un formato comune per rappresentare informazioni orarie di un sistema di trasporti (bus, metro, treno, etc) associandole ad informazioni geografiche.
La specifica struttura i dati organizzandoli in un insieme di file CSV.
I più importanti sono i seguenti:
Per la specifica completa si rimanda alla pagina ufficiale GTFS
Quindi mettiamoci al lavoro e scarichiamo i dati dal sito AMAT di Palermo.
###Ma cosa vedono i miei occhi???
~~ Dalla pagina AMAT Palermo, sezione OpenData, i dati GTFS risultano aggiornati al 2014 purtroppo!~~
~~ In un settore come quello dei trasporti, il rilascio continuo di dati aggiornati aperti e riutilizzabili rappresenta una condizione necessaria per lo sviluppo di qualsiasi applicazione che voglia essere realmente utile ed efficace per cittadini.~~
** Ho preso una cantonata, dopo aver pubblicato il post il buon Andrea Borruso mi ha fatto notare che in rete ci sono i dati GTFS dell’azienda AMAT relativi all’anno 2015 e la pagina di riferimento è quella del Comune di Palermo, non quella dell’Azienda AMAT. Grazie Andrea! **
Ad agosto ho sviluppato una demo per spiegare come riutilizzare i dati relativi alle tariffe orarie delle ZTL a Messina, aumentandone di fatto il valore, se questi fossero stati rilasciati in modalità OpenData dall’azienda ATM. Ne parlo in questo post.
Allo stesso modo spiegherò in questo post come realizzare un BOT su Telegram in grado di fornire informazioni sui trasporti AMAT di Palermo, un modo intelligente di riuso dei dati aperti ~~ che possa servire per punzolare l’azienda AMAT al rilascio dei dati aggiornati.~~
Mettiamoci al lavoro!
~~ Per prima cosa scarico il file zippato GTFS dalla pagina OpenData AMAT Palermo.~~
Per prima cosa scarico il file zippato GTFS dalla pagina OpenData del Comune di Palermo.
Decido di caricare tutti i file CSV all’interno di un dabatase Mysql, per cui inizio a cercare in rete degli statement DDL in modo da risparmiarmi il creare tutto a manina. Uno potrebbe pensare che, essendo GTFS un formato ben definito, uno schema DDL vale l’altro.
###Errore!!!
Quelli che seguono sono alcuni consigli che vi potrebbero farvi risparmiare tempo e mal di testa quando decidete di creare uno schema GTFS trovato in rete.
####REGOLE D’ORO
La maggior parte dei campi id degli schemi che ho trovano in rete è in formato intero mentre nella maggior parte dei record dei dati GTFS AMAT il campo id contiene anche valori alfanumerici, ergo trasformate tutti gli id da int a varchar.
Per importare i dati automaticamente ho usato uno script in python scaricato da github. Trovate un fork sul mio repository github in quanto lo script conteneva un bug relativo al caricamento di codici alfanumerici contenenti il carattere E. Lo script erroneamente parsava i codici contenenti il carattere E come formato esadecimale considerandoli interi invece di stringa. Trovate la versione fixata nel mio repo.
A questo punto iniziamo a scrivere un pò di codice. La documentazione di riferimento per creare BOT con Telegram è fatta benissimo e la trovate al seguente link. Per lo sviluppo del codice ho usato questa libreria PHP a sua volta descritta in modo molto chiaro qui. La libreria è stata sviluppata per il framework PHP Laravel ma può essere utilizzata anche in modalità standalone.
La prima cosa da fare è creare il bot. Per fare questo bisogna aggiungere sul proprio client Telegram l’utente @BotFather e inviargli il seguente comando /newbot. Dopo aver risposto ad alcune domande, ad esempio nome ed username del BOT, viene generato un TOKEN che rappresenta il ponte di collegamento tra il nostro software e Telegram. Per maggiori dettagli sulla creazione dei bot fate riferimento alla documentazione ufficiale.
Per poter interagire con Telegram scriviamo quindi:
$telegram = new Api('BOT TOKEN');
$response = $telegram->getMe();
Nella response troveremo informazioni sul bot creato.
Per poter inviare messaggi all’utente bisognerà indicare, oltre al messaggio, anche l’ID della chat in modo che solo l’utente che ha fatto la richiesta possa ricevere il messaggio di ritorno.
Oltre a messaggi di testo il nostro BOT può rispondere anche con immagini, audio, video, allegati, etc.:
$response = $telegram->sendPhoto('CHAT_ID', 'path/to/photo.jpg', 'Some caption');
Ma come fa l’utente a chiedere le informazioni al BOT? Inviando dei comandi.
Per creare un comando, usando la libreria PHP, è necessario estendere la classe Command e implementare il metodo handle. Creare un comando è un’operazione veramente banale, è infatti necessario inizializzare semplicemente la variabile name con il nome del comando che si vuole creare. Nell’esempio si sta creando il comando /start.
Nell’esempio che segue, digitando da Telegram il comando /start il BOT risponderà con Hello World!;
<?php
use Telegram\Bot\Commands\Command;
class StartCommand extends Command
{
protected $name = "start";
protected $description = "Start Command to get you started";
public function handle($arguments)
$this->replyWithMessage('Hello World!');
}
}
Non mi soffermerò oltre su questa libreria perchè, come già detto, è presente una documentazione completa ed esaustiva.
Vediamo adesso le feature più importanti che dovrà avere il nostro BOT. Verranno descritte le più importanti scelte adottate per la logica applicativa. Si tratta essenzialmente di recuperare informazioni dal database e di formattare l’output, ci soffermeremo quindi solo sulle query SQL più importanti.
La prima versione di amatPABot, questo il nome del BOT, implementa due funzionalità:
###Orario Linee
Le informazioni sono tutte presenti nel db per cui all’interno del metodo handle viene gestita la logica per estrarre le informazioni relative alle linee AMAT di Palermo.
La query SQL utilizzata per mostrare le linee:
A questo punto viene mostrato l’elenco delle linee AMAT. L’utente può scegliere la linea di cui vuole sapere gli orari. Una volta scelta la linea un nuovo comando recupererà il nome delle fermate della linea (Andata e ritorno) e gli orari relativi.
Per recuperare gli orari delle corse uso la seguente query SQL, passandogli l’id della linea e l’id del servizio, cioè del periodo di riferimento nel calendario.
A questo punto l’output ottenuto è il seguente:
Passiamo adesso all’altra funzionalità.
###Fermata più vicina
Per ottenere informazioni sulla fermata più vicina dobbiamo per prima cosa cliccare sulla graffetta e inviare la nostra posizione geografica.
Fatto ciò un comando calcolerà le 5 fermate più vicine recuperandole dalla tabella stops eseguendo la seguente query:
Il valore 6371 è la lunghezza del raggio della terra. La formula utilizzata calcola la distanza in KM tra due punti espressi in latitudine e longitudine. Si tratta di una variante dell’Haversine Formula, per maggiori informazioni fate riferimento qui e qui.
Per ogni fermata recupero anche il nome delle linee passanti.
Vengono mostrate a video le 5 fermate più vicine con le relative linee passanti. La prima fermata viene visualizzata su una mappa (si lo so, è Google Maps e non OpenStreetMap; nativamente Telegram usa le mappe di Google per inviare al client le posizioni geografiche; per usare OSM si potrebbero, ad esempio, creare al volo immagini statiche e inviarle all’utente per la posizione delle fermate)
Per il deploy del BOT ho usato Cloudflare per avere una connessione SSL, condizione necessaria per poter utilizzare il WebHook in Telegram, invece del metodo manuale getUpdates.
###Ricapitolando
Per interagire con il bot dovete aggiungere al vostro client Telegram il contatto: @amatPABot.
Il codice sorgente lo trovate qui.
Attenzione, è’ una versione ancora poco stabile, non pronta per andare in produzione.
~~ I dati non sono aggiornati quindi, in questo momento, il BOT non è molto utile; però,~~ Se questo lavoro vi è
piaciuto un pò, potreste contribuire alla causa aiutandomi a fare un pò di tam-tam mediatico sui social network.
a farlo conoscere in giro sui social, grazie.
Twittami
Idee, critiche e suggerimenti sono benvenuti.
That’s all folks! Stay tuned!
]]>Ma partiamo dall’inizio, a circa un mese fa.
Lo scorso 10-11-12 luglio si è svolta a Patti (ME) l’Open Data Summer School, organizzata dallo Stretto Digitale nei locali del caffè Galante. Ovviamente non potevo lasciarmi scappare un’occasione del genere e nei tre giorni ho avuto l’opportunità di conoscere pilastri del movimento Open Data italiani come Pier Francesco Paolicelli (Piersoft), Andrea Borruso e Andrea Nelson Mauro. Sono stati giorni intensissimi nei quali ciascuno dei relatori ha condiviso la propria esperienza e la propria passione, mostrando esempi concreti di come sia possibile riusare i dati aperti in altri contesti, per accrescerne il valore originale, scoprendo ad esempio relazioni nuove dei dati con altre informazioni apparentemente sconnesse. Tutto questo servendosi di mappe, tool per estrarre e/o convertire pdf, per creare grafici, diagrammi e infografiche. Per un resoconto dettagliato dell’evento invito a leggere l’ottimo post di Nino Galante.
In passato ho avuto modo di lavorare con gli Open Data sia per motivi di ricerca in ambito Semantic Web (LOIUS Platform), sia per progetti personali ( OpenAlboPretorio, OpenGazzettaUfficiale - offline -, OpenSanita). Secondo i principi Open Data i dati andrebbero trattati come beni comuni, in quanto appartenenti al genere umano. Per definirsi Open Data i dati
Durante la summer school i relatori hanno presentato svariati esempi di mashup di dati, utilizzando diversi tool, script e programmi, integrandoli maggiormente con le mappe di OpenStreetMap (OSM), progetto collaborativo finalizzato a creare mappe a contenuto libero del mondo. Il progetto rappresenta una raccolta mondiale di dati geografici avente come scopo principale la creazione di mappe e cartografie.
Sono rimasto particolarmente colpito quando Piersoft, a proposito di Smart Cities e Open Data, ha fatto cenno ad una APP per smartphone, sviluppata non ricordo per quale città, in grado di calcolare la tariffa oraria per i parcheggi in zona ZTL, in base alla posizione GPS dello smartphone. Mi sono portato a casa quell’idea e il desiderio di sperimentare qualcosa del genere anche per la città in cui lavoro, ovvero Messina.
Andando sul sito dell’ATM Messina le uniche informazioni relative alle tariffe orarie dei parcheggi in ZTL sono presenti in questa pagina. Nella stessa pagina è presente anche la piantina dei lotti ZTL di seguito mostrata.
Primi guai all’orizzonte. In calce alla pagina del sito è riportato il seguente disclaimer:
Copyright C 2015 - ATM MESSINA - E' vietata la riproduzione anche parziale.
I dati quindi non possono essere usati neanche in modo parziale. In realtà l’ATM, essendo un ente strumentale del comune, dovrebbe rilasciare i dati con licenza aperta considerato che si tratta di dati pubblici di un ente legato ad una pubblica amministrazione, cioè il comune di Messina.
L’ATM dovrebbe seguire l’esempio di altre municipalizzate italiane (come ad esempio del comune di Roma), che hanno iniziato ad aprire agli sviluppatori i propri dati su traffico e mobilità, per incentivare lo sviluppo di app in grado di trasformare le città e renderle più Smart.
Tuttavia, immaginiamo per un attimo che non esista nessun copyright su questi dati, anzi immaginiamo che i dati siano rilasciati in modalità Open Data. Cosa potremmo farci? In che senso i dati aperti possono essere riusati in contesti diversi da quello di origine aumentandone il valore originale? In che senso i dati aperti possono fare da volano allo sviluppo di attività imprenditoriali private?
Per rispondere a tutte queste domande vedremo in questo post come implementare un ipotetico scenario attraverso lo sviluppo di un’applicazione reale. Scopo di questo esperimento è rafforzare la tesi secondo cui la pubblica amministrazione, nel rilasciare dati in modalità Open Data promuove l’innovazione permanente favorendo lo sviluppo economico del terzo millennio.
Disclaimer L’intero progetto, chiamato “PARKING IN MESSINA”, è da intendersi volutamente a carattere DIDATTICO, SPERIMENTALE e assolutamente NON A SCOPO DI LUCRO.
Cominciamo allora!
La prima cosa che decido di fare è disegnare su openstreetmap i lotti ZTL della città di Messina. Per fare questo scelgo di usare il tool UMAP, un software libero in grado di creare mappe che fanno uso di OpenStreetMap come sfondo. Con UMAP è possibile aggiungere alla mappa punti di interesse, marcatori, linee, poligoni, colori, icone. E’ possibile inoltre sia importare che esportare i dati nei formati più conosciuti (geojson, gpx, kml, osm, etc).
La cosa più disarmante di UMAP è la facilità di utilizzo, praticamente a portata di bambino. Per raggiungere il mio obiettivo ho disegnato i poligoni così come appaiono nella piantina ZTL, specificando per ciascun poligono le informazioni relative alla tariffa oraria del lotto. Prova a cliccare su uno dei lotti colorati.
A questo punto posso entrare in ZTL a Messina, aprire la mappa appena creata con il mio smartphone, selezionare il lotto nel quale si trova la mia autovettura e magicamente apparirà la tariffa oraria da pagare.
Tutti felici, tutti contenti, arrivederci e grazie?
Quando parcheggio la mia autovettura in un’area dove non conosco la tariffa ZTL, la mappa appena creata mi evita di dover andare per strada alla ricerca del cartello stradale indicante la tariffa vigente in quella via, ma mi costringe a selezionare manualmente la regione colorata nella mappa. Per alcuni potrebbe bastare questo, ma dato che sono una persona moooolto pigra, come del resto tanti informatici, il dover pensare a dove mi trovo e selezionare l’area colorata nella mappa rappresenta uno spreco di tempo imperdonabile. Deleghiamo all’applicazione il lavoro sporco!
Per eliminare questo spreco è necessario quindi:
Procediamo per gradi.
Nei dispositivi con GPS, grazie alle API HTML5 di geolocalizzazione, è possibile ottenere la posizione di un utente, previo consenso dello stesso. La funzionalità è supportata a partire dalle seguenti versioni di browser:
Il metodo da invocare per ottenere la posizione dell’utente è getCurrentPosition()
var x = document.getElementById("demo");
function getLocation() {
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
} else {
x.innerHTML = "Geolocation is not supported by this browser.";
}
}
function showPosition(position) {
x.innerHTML = "Latitude: " + position.coords.latitude +
"<br>Longitude: " + position.coords.longitude;
}
In questo modo otteniamo la latitudine e la longitudine della posizione in cui si trova il dispositivo.
Qui risiede il core dell’applicazione. Anche qui procediamo per gradi.
Prima di addentrarci nel caso specifico della ZTL di Messina dobbiamo astrarre l’obiettivo generalizzando il problema. L’obiettivo è quindi adesso: dato un punto geografico qualsiasi, espresso tramite una latitudine e una longitudine, stabilire se si trova all’interno di un poligono chiuso, espresso come insieme di punti geografici.
Per la risoluzione di questo problema esistono in letteratura diversi algoritmi geometrici. In questo contesto ho scelto di implementare in PHP la soluzione presentata da Philippe Reverdy. Sinteticamente, l’algoritmo calcola la somma degli angoli esistenti tra il punto da valutare e ogni coppia di punti costituenti il poligono. Se la somma è 2*pigreco il punto è interno al poligono, se la somma è 0 il punto è esterno al poligono. Per maggiori informazioni fate riferimento alla pagina sopra menzionata.
Ho rilasciato la libreria GPSPolygon
sul mio repository github.
Ho preparato anche una API Demo da invocare nel seguente modo:
**Parameters**
latitude (ex: latitude=38.19396)
longitude (ex: longitude=15.55599)
polygon (ex: polygon=38.197344511074,15.556431412697;38.197129504006,15.557370185852;38.192909334811,15.55691421032;38.193706168703,15.554140806198;)
Facciamo un esempio, consideriamo il poligono avente come vertici i seguenti punti geografici:
38.197344511074,15.556431412697;
38.197129504006,15.557370185852;
38.192909334811,15.55691421032;
38.193706168703,15.554140806198;
38.197344511074,15.556431412697
La mappa di riferimento è la città di Messina e il poligono identificato è delimitato dalle seguenti vie:
**viale Boccetta - Corso Cavour - Via Consolato del Mare - Via Garibaldi**.
![Image](/images/messina-polygon.jpg){: .center-image }
Vogliamo sapere se piazza Unione Europea, identificata con ```latitudine=38.19396``` e ```longitudine=15.55599``` si trova
all'interno del sopramenzionato poligono.
Questa l'<a href="http://www.pirrotta.it/gps-polygon-api/isPointInsidePolygon.php?latitude=38.19396&longitude=15.55599&polygon=38.197344511074,15.556431412697;38.197129504006,15.557370185852;38.192909334811,15.55691421032;38.193706168703,15.554140806198;38.197344511074,15.556431412697" target="blank">URL DEMO</a>
da invocare e questo il risultato:
{ info: { name: “GPSPolygon tool”, source: “https://github.com/gpirrotta/gpspolygon”, license: “MIT License - http://opensource.org/licenses/MIT”, author: { name: “Giovanni Pirrotta”, email: “giovanni.pirrotta@gmail.com” } }, service: { point: “38.19396,15.55599”, polygon: [ [ “38.197344511074”, “15.556431412697” ], [ “38.197129504006”, “15.557370185852” ], [ “38.192909334811”, “15.55691421032” ], [ “38.193706168703”, “15.554140806198” ], [ “38.197344511074”, “15.556431412697” ] ], answer: “YES” } }
La risposta **YES** del file JSON ci indica che piazza Unione Europea si trova dentro il poligono, così come possiamo
vedere anche nella figura sottostante.
![Image](/images/inside-polygon.jpg){: .center-image }
Per maggiori informazioni e altri esempi relativi alle **GPSPolygon DEMO API** potete fare riferimento alla
<a href="http://www.pirrotta.it/gps-polygon-api/" target="blank">pagina</a> del progetto.
Ritorniamo adesso al nostro problema originale.
Da una parte abbiamo l'algoritmo che fa al caso nostro. Il punto geografico da valutare ci viene fornito dal servizio API
di geolocalizzazione HTML5, tramite Javascript.
Da dove prendiamo invece l'insieme delle coordinate geografiche dei poligoni della ZTL di Messina?
La risposta è, ovviamente, dalla mappa creata in precedenza con il tool UMAP. (Ricordate quando ho detto che era
possibile importare/esportare i dati di UMAP nei formati più comuni?).
![Image](/images/umap-export-json.jpg){: .center-image }
A questo punto abbiamo il file <a href="/ext/ztl.json" target="blank">GEOJSON</a>
con tutte le coordinate geografiche delle aree ZTL disegnate con UMAP, quindi abbiamo i dati per costruirci i poligoni.
Andiamo avanti!
Dell'utente abbiamo detto di avere la posizione espressa sotto forma di coordinate geografiche, nulla però sappiamo sul nome
della via in cui si trova l'utente stesso. Per ottenere questa informazione decido di usare la libreria in
PHP <a href="http://geocoder-php.org/Geocoder/" target="blank">**Geocoder**</a>
sviluppata da <a href="http://williamdurand.fr/" target="blank">William Durand </a>.
A partire da una località qualsiasi la libreria restituisce le rispettive coordinate geografiche e viceversa,
consentendo di scegliere <a href="http://geocoder-php.org/Geocoder/#providers" target="blank">uno o più provider geografici </a>;
ovviamente tra i provider non poteva mancare ```OpenStreetMap```.
Il codice da usare è veramente minimo:
<? use Geocoder\HttpAdapter\CurlHttpAdapter; use Geocoder\Provider\OpenStreetMapProvider;
$curl = new CurlHttpAdapter();
$geocoder = new OpenStreetMapProvider($curl);
$results = $geocoder->getReversedData(array(38.19245, 15.55608));
$street = $results[0]['streetName'];
print $street; // via San Giacomo
A questo punto abbiamo tutti i dati:
* la latitudine e la longitudine della posizione dell'utente;
* il nome della via in cui si trova l'utente;
* le coordinate di tutti i poligoni della ZTL Messina.
La logica per decidere se un punto appartiene o no ad un poligono, come già detto in precedenza, verrà
implementata utilizzando la libreria ```GPSPolygon```.
Possiamo quindi passare all'ultimo punto.
#### L'applicazione deve restituirmi le tariffe vigenti per quella via.
Vediamo adesso come dovranno essere presentate le informazioni calcolate all'utente.
Il flusso di funzionamento dell'applicazione è il seguente:
* L'utente avvia l'APP;
* Il GPS del dispositivo comunica la latitudine e la longitudine della posizione in cui si trova;
* L'APP, ricevute le coordinate dell'utente, recupera la via;
* L'APP controlla se la posizione dell'utente si trova all'interno della ZTL di Messina;
* In caso positivo recupera il piano tariffario per quella via;
* L'utente visualizza sul proprio dispositivo la mappa in cui si trova, all'interno della quale un marker indicherà la sua posizione;
* L'utente visualizza sul proprio dispositivo il nome della via in cui si trova;
* Se la posizione dell'utente è all'interno della ZTL di Messina, esso riceve le informazioni sul piano tariffario relativo alla sua posizione;
* Se la posizione dell'utente è all'esterno della ZTL di Messina, esso riceve l'avviso di trovarsi fuori ZTL e che il pagamento è quindi gratuito;
* Se l'utente cambia parcheggio deve avere la possibilità di ricalcolare la tariffa senza spegnere l'APP.
Per lo sviluppo della Web-App ho deciso di usare <a href="http://goratchet.com/" target="blank">**Ratchet**</a>, framework
particolarmente indicato per lo sviluppo rapido di prototipi di applicazioni su dispositivi mobili.
Per la visualizzazione della mappa geografica ho usato la libreria <a href="http://openlayers.org/" target="blank">OpenLayer</a> grazie alla quale, in maniera semplice e immediata,
ho inserito la mappa e il marker della posizione dell'utente in questo modo:
``` javascript
<html>
<body>
<div id="mapdiv"></div>
<script src="http://www.openlayers.org/api/OpenLayers.js"></script>
<script>
map = new OpenLayers.Map("mapdiv");
map.addLayer(new OpenLayers.Layer.OSM());
var lonLat = new OpenLayers.LonLat( -0.1279688 ,51.5077286 )
.transform(
new OpenLayers.Projection("EPSG:4326"),
map.getProjectionObject()
);
var zoom=16;
var markers = new OpenLayers.Layer.Markers( "Markers" );
map.addLayer(markers);
markers.addMarker(new OpenLayers.Marker(lonLat));
map.setCenter (lonLat, zoom);
</script>
</body>
</html>
L’obiettivo è stato raggiunto e la sfida è stata vinta! :-) L’applicazione è solo una demo ma è già di grande utilità, a dimostrazione di come sia possibile, partendo da semplici dati della pubblica amministrazione, aumentarne il valore e creare un servizio utile per la cittadinanza, attraverso software opensource a costo zero.
Sicuramente possono essere aggiunte altre funzionalità, come ad esempio le posizioni sulla mappa degli edicolanti per l’acquisto dei gratta e sosta, la possibilità di inserire un orario di arrivo e un orario di partenza lasciando che l’APP stessa calcoli l’ammontare totale da pagare, informazioni di contatto dell’ATM, etc…
Purtroppo però, come dette sopra, i dati di partenza non sono Open Data quindi l’applicazione non potrebbe esistere.
Pertanto, mi auguro che questo esempio (che ribadisco essere a scopo DIDATTICO e NON A SCOPO DI LUCRO) possa servire da sprono alla governance amministrativa del comune di Messina e all’ATM, ad innescare processi e modelli organizzativi ispirati sempre più a principi di apertura e di rilascio dei dati in modalità Open Data.
La web-app PARKING IN MESSINA è disponibile al seguente link: DEMO
Feedback, bug, consigli, pareri e critiche costruttive sono i benvenuti!
That’s all folks! Stay tuned!
]]>Behat tests a feature by executing its scenarios’ steps in a context. It allows you to write your user stories in the natural language taking advantage of Gherkin language syntax.
Afterwords I chose to write user stories in my native language and Behat helped me by providing Italian gherkin keyword translations. At this time it supports 62 native languages.
In order to know the Gherkin keyword translation for the Italian language you must digit in console:
behat --story-syntax --lang=it
# language: it
Funzionalità: Internal operations
In order to stay secret
As a secret organization
We need to be able to erase past agents' memory
Contesto:
[Date|Dati|Data|Dato] there is agent A
E there is agent B
Scenario: Erasing agent memory
[Date|Dati|Data|Dato] there is agent J
E there is agent K
Quando I erase agent K's memory
Allora there should be agent J
Ma there should not be agent K
Schema dello scenario: Erasing other agents' memory
[Date|Dati|Data|Dato] there is agent <agent1>
E there is agent <agent2>
Quando I erase agent <agent2>'s memory
Allora there should be agent <agent1>
Ma there should not be agent <agent2>
Esempi:
| agent1 | agent2 |
| D | M |
Using behat in Web applications I like the Behat extension for Mink, a browser emulator abstraction layer. It hides emulator differences behind a single consistent API and represents a bridge towards real browser emulators such as
Mink extension supports 17 different languages so I found the Italian XLIFF file, in the source code, (see github) containing the patterns of Italian sentences recognized by the library.
Apart some English PDF cheatsheets I have not found much readable native language syntax documentation about Behat and Mink. (Let me know if you know).
So, to fill the gap, I developed the Behat-Gherkin/Mink Translator in order to generate on the fly the native language syntax documentation that PHP developers can use for their job.
Thas’all folks! Stay tuned!
]]>The SPARQL language is a W3C Recommendation defining a standard way to retrieve data from RDF graphs distributed on the Web. SPARQL performs complex joins
exploring data by querying unknown relationships. The querying criterion is based on pattern matching mechanisms, and, in particular, on triple pattern
constructs, that reflect the RDF triple assertion model and provide a flexible model for finding matches.
Triple patterns are just like triples, except that any of the parts of a triple can be replaced with a variable. For example, in the following pattern ?book ex:title ?title
, in place of the subject and of the object, two variables are involed, marked with ?
, that act as unknown variables while the ex:title
property acts as a constant. SPARQL variables can match any resources or literals in the RDF dataset.
The SPARQL skeleton is:
# prefix declarations
PREFIX ex: <http://example.org/>
...
# dataset definition
FROM ...
# result clause
SELECT ...
# query pattern
WHERE {
...
}
# query modifiers
ORDER BY ...
In the graph http://example.org/books.rdf
we want to find all book resources (?book
) and all person resources (?person
) linked with the ex:hasAuthor
predicate. So, book titles (?book_title
) associated with relative authors’ name and surname (?person_name
,person_surname
) are returned.
PREFIX ex: <http://example.org/>
SELECT ?book_title ?person_name ?person_surname
FROM <http://example.org/books.rdf>
WHERE {
?book a ex:Book;
ex:title ?book_title;
ex:hasAuthor ?person.
?person ex:name ?person_name;
ex:surname ?person_surname.
}
This is the result:
------------------------------------------------------------------------
| book_title | person_name | person_surname |
========================================================================
|"UML Distilled" | "Martin" | "Fowler" |
------------------------------------------------------------------------
|"Test-Driven Development: By Example" | "Kent" | "Beck" |
------------------------------------------------------------------------
SPARQL language is similar to SQL language. SPARQL selects data from the dataset by using a SELECT statement to determine which subset of selected data is returned. Also, SPARQL uses a WHERE clause to define graph patterns to find a match for in the query data set. Also the binding between variables and instances will generally return in table format but we can also specify other formats, such as JSON, RDF/XML, etc.
That’s all for now. In the next posts I will introduce how to develop a new ontology using the Semantic Web ingredients learned in the previous posts of this series. So, stay tuned!
]]>#}
L’attesa fu breve, il mistero fu presto svelato.
Symfony ha finalmente deciso di rilasciare le linee guida ufficiali per lo sviluppo di applicazioni con il proprio framework.
La notizia del rilascio ha subito riscosso grandi entusiasmi da parte della comunità, che aspettava da tempo le best practices ufficiali da adottare per sfruttare appieno le funzionalità di Symfony, pur mantenendo alta la qualità di codice prodotto.
Nonostante la caratura ufficiale delle best-practices, ad onor del vero, da anni la comunità Symfony, fra le migliori al mondo in campo PHP e OOP, contribuisce con articoli, post, presentazioni e libri alla diffusione di tecniche, strategie e casi d’uso per riuscire a sfruttare al meglio le funzionalità del framework.
Consigliando come migliorare l’esperienza dello sviluppatore nell’utilizzare Symfony, di fatto, la comunità ha giocato un ruolo fondamentale per la diffusione del framework stesso contribuendo sia a migliorarlo che a renderlo più flessibile e sicuro.
Molte di queste risorse, disponibili sul Web, possono essere considerate dei veri e propri tesori da custodire e proteggere gelosamente. Confesso che alcune di queste intuizioni avrei voluto scoprirle tanti anni fa quando ho iniziato a cimentarmi con la filosofia OOP. (Per i più curiosi consiglio di seguire planet-php.net )
E’ possibile scaricare le best practices ufficiali di Symfony direttamente dal sito Symfony. Anche se si tratta di una prima versione non definitiva, ho pensato di tradurla in italiano. Sotto trovate l’indice oppure andate sul mio repo github.
La traduzione è in fase di revisione. Consigli e contributi (leggasi PR) per migliorare la comprensione e leggibilità sono i benvenuti.
We know the HTML Web languages do not explicitly encode information, then, to create the new Web (also called by someone Web 3.0) we must proceed as follows:
In both cases some problems immediately arise. Web pages may frequently change without warning and for each update a human intervention is necessary to align data. Publishing a relative RDF document for each Web page significantly increases data redundancy; this violates the “Don’t Repeat Yourself” principle (DRY) and this should be avoided.
To circumvent these limits, the Resource Description Framework in attributes W3C Recommendation (RDFa) provided a solution to embed machine readable data on the same Web page. The concept is very simple; the RDFa technology allows to bring the RDF model into Web pages coding RDF statements inside XHTML tags as attributes. The RDFa defines a syntax for embedding an RDF graph in XHTML document using attributes for expressing RDF properties about concepts inside the page. So doing, the DRY principle is not violated, and data result to be written and published only once, either for humans or machines. Data inside pages would be easier to maintain since each update will require to modify only one source. In addition, structured information would allow a better indexing by search engines that will experience benefits in terms of efficiency.
Now I will show an example:
<HTML>
<head><title>An RDFa sample</title></head>
<body>
<p>The author of <b>UML Distilled</b>
is <i>Martin Fowler</i></html>
</p>
</body>
</html>
We need to unlock the metadata already in Web-pages, and RDFa provides a generic way to do this by building on features already in HTML. In the following code we can see how to enrich the previous HTML code using RDFa technology
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ex="http://example.org/" version="XHTML+RDFa 1.0" xml:lang="en">
<head><title>An RDFa sample</title></head>
<body>
<p><div typeof="ex:Book" about="http://example.org/umld">
The author of <b><span property="ex:title">UML Distilled</span></b>
is <div typeof="ex:Person" about="http://example.org/mfowler">
<i><span property="ex:name">Martin</span>
<span property="ex:surname">Fowler</span></div></i>
</div></p>
</body>
</html>
When a Web page is a valid RDFa document generally it is present the following icon…
…and here you can find the W3C Validator tool.
Obviously, this is just an overview. For detail I invite you to refer to the official documentation.
That’s all folks. Stay tuned!
]]>#}
Although RDFS represents a very useful language to model domains, it suffers the following limitations:
rdfs:range
property defines the range of a certain property for all classes,
but in RDF Schema we cannot declare a constraint only for a single class;Male
class is disjoint from the Female
class;hasMother
property;Because of these limitations, the W3C Consortium defined a new knowledge representation language called OWL that provides a well defined syntax and semantics with a sufficiently expressive mechanism to ensure automate processing using a reasoner engine. Depending on the level of expressiveness, OWL specification includes the definition of three variants:
The OWL Full language uses all primitives provided by the OWL Definition Language with the possibility of changing the meaning of OWL/RDF pre-defined primitives. It is either syntactically or semantically compatible with RDF, namely, each valid document in RDF is also valid in OWL Full, and each inference obtained in RDFS is a valid inference in OWL Full. Unfortunately, the OWL Full language is undecidable, so it cannot work on a reasoner engine.
The OWL DL is a sublanguage of OWL Full and, limiting the way to use OWL and RDF constructors, it allows to map the OWL language on a description logic, in order to gain computational efficiency. In fact, it allows the reasoning support not permitted by OWL Full, but we lose the full compatibility with RDF; an RDF document cannot be considered an OWL DL document. Vice versa, each valid OWL DL document is also a valid RDF document.
The OWL Lite is an OWL DL sublanguage and provides a limited set of constructors. For example, it excludes enumerated classes, the disjunction operator and some cardinality features. The OWL Lite is very simple to use but allows less expressiveness.
In the following Figure we can see the relationships between OWL dialects.
In the OWL language we can model our domain with the concept of class, that
represents one of the most important aspect of the language. To do this we use the owl:Class
;
Also exist two pre-defined classes:
owl:Thing
is the superclass of all classes and a default class of all individuals. Thus,
every individual in OWL world is member of owl:Thing
;owl:Nothing
is a class that has no instances and is a subclass of all classes.Thanks to the expressiveness of the OWL language, we can define more characteristics of classes we need
to design. The language provides the owl:EquivalentClass
construct to declare the equivalence
between two classes or the owl:disjointWith
construct to define the classes that do not
share any individuals.
An owl:Property
is instead a binary relation defining relationships between individuals, or between
individuals and data value. There are two pre-defined property classes:
owl:ObjectTypeProperty
resource defines the relation between instances of two classes;owl:DataTypeProperty
resource defines the relation between instances of classes and literal values,
such as string, date, float, etc.Also, the OWL language provides some owl:ObjectTypeProperty
subclasses specifying some interesting
class characteristics.
owl:TransitiveProperty
construct defines a transitive property: if a relation between the
class A and the class B exists, and a relation between the class B and the class C
exists, the also a relation between the class A and the class C does exist.owl:SymmetricProperty
construct defines a symmetric property: if a relation between
the class A and the class B exists, then also a relation between the class B and the
class A does exist.owl:FunctionalProperty
construct defines a property with at most one value for each instance.Also, we can set the cardinality of properties using the following OWL resources: owl:Restriction
,
owl:onProperty
, owl:minCardinality
, owl:maxCardinality
, so we can create new classes using
boolean operators through the owl:unionOf
, owl:complementOf
and owl:intersectionClass
constructs.
Obviously, there are many other constructs and language features provided by OWL language.
For more details you can refer to the official documentation.
Let us come back to our old statement (in the previous post), and let us try to draw the relative ontology using the OWL language.
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix owl: <http://www.w3.org/2002/07/owl#>.
@prefix ex: <http://example.org/>.
ex:Person rdf:type owl:Class.
ex:name rdf:type owl:DatatypeProperty.
ex:surname rdf:type owl:DatatypeProperty.
ex:title rdf:type owl:DatatypeProperty.
ex:isbn rdf:type owl:DatatypeProperty.
ex:hasAuthor rdf:type owl:ObjectProperty.
rdfs:domain ex:Book;
rdfs:range ex:Person.
ex:hasUniqueAuthor rdf:type owl:ObjectProperty ;
rdfs:subPropertyOf ex:hasAuthor.
ex:Book rdf:type owl:Class;
rdfs:subClassOf
[ rdf:type owl:Restriction ;
owl:onProperty ex:hasUniqueAuthor ;
owl:maxCardinality "1"^^<http://www.w3.org/2001/XMLSchema#int>
] .
ex:umld rdf:type ex:Book;
ex:hasUniqueAuthor ex:mfowler;
ex:title "UML Distilled";
ex:isbn "0201325632".
ex:mfowler rdf:type ex:Person;
ex:name "Martin";
ex:surname "Fowler".
As can be seen in the code, the rdfs:Class
resources were replaced by the relative owl:Class
constructs.
Depending on the type of object, we can identify owl:DatatypeProperty
and owl:ObjectProperty
property instances.
In our example only ex:hasAuthor
is an owl:ObjectProperty
instance,
whereas the remaining ones are owl:DatatypeProperty
property instances.
Now let us imagine we want to specialize the ex:hasAuthor
property.
We want to define a particular property modeling books with a single
author. To do this, we define the ex:hasUniqueAuthor
property as subproperty
(rdfs:subPropertyOf
) of ex:hasAuthor
property. To define this
constraint we must create an anonymous owl:Restriction
class, specifying
as properties the attributes that have to be constrained.
In this case we indicate the resource ex:hasUniqueAuthor
through the owl:onProperty
property and we indicate the maximum number of relations the ex:hasUniqueAuthor
property can join between classes, in this case only
one, through the owl:maxCardinality
property.
That’s all folks! Stay tuned!
]]>The RDF Model provides only a mechanism to describe data as statements, but it can say nothing about the content of the assertion and the properties used in triples. It is clear that something is missing, and here is where the RDF Schema (RDFs) comes into play.
The RDF Schema (RDFs) is the way to describe the meaning of classes and properties to help machines process data efficiently. RDFs Vocabulary extends RDF model to provide primitives to write light schemas for RDF triples allowing describing taxonomies of classes and properties to create and define what is called the ontology of the domain of interest. RDFS provides some constructs to organize classes in a hierarchy providing mechanisms to extend them in subclasses and to create new schemas through incremental changes. The meaning of each resource is expressed through the reference to a specific vocabulary.
Using the RDFS Vocabulary, we can define for example the class Person
and the class Book to define the http://example.org/mfowler
resource
as an instance of the class Person, and the http://example.org/umld
resource as an instance of the class Book.
So, we can define the http://example.org/hasAuthor
resource as a
new property stating that it relates an instance of Book to an instance
of Person.
One of the interesting features of RDF Schema is the simplicity with
which it can be extended by the namespace mechanism. Not only can
we use different RDF Schema vocabularies, but we can also extend a
standard version without the need of redefining all concepts.
The most important RDFS items to define metadata schemas or ontologies are:
rdf:type
property, the rdfs:Class instances obtained
are themselves class objects, then again classes to instantiate.rdfs:Class
resource or an rdfs:Class
instance. In the first case
the subject resource will be a new class type, otherwise it will be
a generic typed class instance.rdfs:subClassOf: the property rdfs:subClassOf is an instance of rdf:Property and it is used to state that all the instances of one class are instances of another. A triple of the form:
C1 rdfs:subClassOf C2
states that C1 is an instance of rdfs:Class
, C2 is an instance of
rdfs:Class
and C1 is a subclass of C2. The resource specifies the
inheritance relationship between classes and can be a subclass of
one or more classes (multiple inheritance).
rdfs:Property
has domain instances of a certain class. For example, the property
identified by the http://example.org/hasAuthor
URI, instance
of rdfs:Property
, has to have as subject type the Book class.rdfs:Property
,
has as range instances of a certain class. For example, the property
identified by the http://example.org/hasAuthor
URI, instance
of rdfs:Property
, has to have as object type the Person class.The following figure represents the relationship graph of the most important RDFS classes:
Let us now see how to apply what we have just described in our previous
statement. At the beginning we define two new classes: ex:Book
and ex:Person
instances of the rdfs:Class
resource. Then, we can typify
the ex:umld
and the ex:mfowler
resources, through the
rdf:type
property. As done with classes, we instanciate the property
resources (ex:authorOf
, ex:firstname
, ex:lastname
, ex:title
, ex:isbn
) as
rdfs:Property
instances, using again the rdf:type
property. Also, we
can describe some relations between properties, for example, establishing
the domain and the range for the authorOf property. For example,
we can explicit the authorOf property that must join instances of Book
with instances of Person, and so forth.
Let us show now RDFS Schema serialization. For semplicity I will adopt the N3 notation
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix ex: <http://example.org/>.
ex:Book rdf:type rdfs:Class.
ex:Person rdf:type rdfs:Class.
ex:fistname rdf:type rdfs:Property.
ex:lastname rdf:type rdfs:Property.
ex:title rdf:type rdfs:Property.
ex:isbn rdf:type rdfs:Property.
ex:hasAuthor rdf:type rdfs:Property;
rdfs:domain ex:Book;
rdfs:range ex:Person.
ex:umld rdf:type ex:Book;
ex:hasAuthor ex:mfowler;
ex:title "UML Distilled";
ex:isbn "0201325632".
ex:mfowler rdf:type ex:Person;
ex:firstname "Martin";
ex:lastname "Fowler".
#}
To solve the problem the W3C Consortium has formalized a conceptual layer called Resource Description Framework (RDF), which aims to provide an abstract formalism to describe resources. The RDF is a neutral domain/application metadata model which can be viewed as a directed labeled graph and provides a valid solution to the metadata representation problems on the Web. The RDF model ensures interoperability between applications exchanging machine–understandable information on the Web.
The first letter of RDF acronym stands for Resource but, what is a resource? A resource is every concrete or abstract thing identified by a URI and can be really anything: an image, a document, a person, a book, etc.
The URI, acronym of Uniform Resource Identifier
, is instead a simple
string identifying uniquely a generic resource that can be an image,
a video, a service, anything, even not available online. If the resource
is located on the Web we call it Uniform Resource Locator
(URL) where
the http protocol identifies the mechanism to access the resource. For
instance, the address Web http://giovanni.pirrotta.it
represents the URL
of my blog. If the resource is identified
by a name belonging to a namespace we call it Uniform Resource
Name (URN). The URN is used when we have to identify a resource
without specifying a particular location but simply a membership in
a specific domain. For example, urn:isbn:12238789879 identifies a specific
resource within ISBN codes.
The URI syntax may change, but in general absolute URIs are written as follows:
<scheme>:<scheme-specific-part>
If a URI ends with the hash character (#), followed by a name, it is called qualified URI and it used to identify many resources in the same document.
Moreover we define as a property each attribute, characteristic or relation useful to describe a resource. To describe the domain of interest, a very important role is played by properties describing attributes and relations among resources. With properties we can specify everything about everything, and, since a property is also a resource, it is identified by a URI.
Now we can define the statement as the basic knowledge unit in RDF. It is composed by a subject, that is a resource, a predicate, which is the property, and is again a resource, and by an object, that can be a resource or a literal. A literal is simply a typed primitive value, such as string, integer, float, etc.
RDF only proposes an abstract model to represent the knowledge on the Web without specifying any technical mechanism to realize it. The best way to evidentiate this formalism is to represent the defined statement through the use of a directed labeled graph.
As we can see in the figure the subject is represented by an oval node, the predicate is represented by an arrow, and, if the object is a resource, it is represented by an oval node, whereas if the object is literal, by a rectangle.
Now I will explain how the RDF model works through an example.
Let us assume we want to define the following statement:
Martin Fowler is the author of the book "UML Distilled"
First of all we have to transform the statement in an RDF triple according to the following mapping:
UML Distilled
book with the http://example.org/umld URI;is the author of
property with the
http://example.org/hasAuthor URI;Martin Fowler
person with the
“Martin Fowler string Literal.We compose the following triple:
-> (http://example.org/umld, http://example.org/hasAuthor, “Martin Fowler”) <-
Note that RDF Model does not specify the way to represent the statements. We can use triples, graphs or whatever we retain useful for our purposes. For example, we can also think of the assertion as a simple relation
-> P(S) = O or P(S,O) <-
where P represents the property, S represents the subject and O represents the object.
Applying the above relation, we have
-> http://example.org/hasAuthor(http://example.org/umld) = “Martin Fowler” <-
The same statement can be represented as the graph shown in the next figure
The statement is formalized using the RDF model, but still nothing has been said about the type of resource defined. Now, all we know is that there is a resource with a property and a literal as a property value.
We know that the subject resource has a title and an ISBN code, and that also the object resource has a name and a surname. To correctly represent this extra information, the literal “Martin Fowler” must be transformed into a resource with a specific URI. In a similar way, as we have seen, it is possible to indefinitely extend the knowledge graph, thanks to the RDF model flexibility, simply adding nodes and arcs. As we can see in the figure, we replaced the literal with a new URI resource and we added new properties and relative literals values, better specifying the original statement.
RDF ensures a conceptual abstract model to define and use metadata; but to create and exchange them, a concrete syntax is necessary, and now XML comes into play.
Although, from a logical point of view, XML is not sufficiently powerful to describe Web resources, from a physical point of view, it proves to be an appropriate technology to serialize resources thanks to its rigorous syntax.
The following document represents the RDF/XML
version of the previous statement
example:
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ex="http://example.org/">
<rdf:Description about="http://example.org/umld">
<ex:hasAuthor>Martin Fowler</ex:hasAuthor>
</rdf:Description>
</rdf:RDF>
Inside an RDF/XML document, the rdf:RDF root node delimits the context within which all RDF statements are defined. In the rdf:RDF node, the text after the colon and before the equal, represents the namespace, namely an abbreviation we can use as a reference to uniquely identify the set of metadata we are using. The namespace mechanism does not only help us not to entirely rewrite the full URI when we refer to a resource, but also allows us to specify a set of names belonging to a specific domain, that defines an ontology.
Imagine we have to define the title
property for a person and the
title
property for a book. As we know, the property must be identified
by a URI and we cannot specify, within the same document, the title
property for both resources, since they have different meanings. To
overcome the problem, we can use namespaces to disambiguate meaning
differences between title properties, applying the right property
URI according to the context. Also, we can reuse namespaces defined
outside the RDF/XML document and accepted by the community as a
standard. That is the beauty of the RDF interoperability.
To describe an RDF statement
, we must represent the triple subject,
predicate and object in the RDF/XML document. To define the subject,
we assign the subject URI to the rdf:about
attribute of the rdf:Description
tag. Inside the rdf:Description
tag we must specify all properties related
to the subject.
Considering Martin Fowler as a resource, we will have
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ex="http://example.org/">
<rdf:Description about="http://example.org/umld">
<ex:title>UML Distilled</ex:title>
<ex:isbn>0201325632</ex:isbn>
<ex:hasAuthor rdf:resource="http://example.org/mfowler"/>
</rdf:Description>
<rdf:Description about="http://example.org/mfowler">
<ex:firstname>Martin</ex:firstname>
<ex:lastname>Fowler</ex:lastname>
</rdf:Description>
</rdf:RDF>
As we can see from previous examples, we defined a new namespace,
called ex, within the rdf:RDF
tag, in order to refer to RDF/XML
document resources in abbreviated form. With the same simplicity we
can import other namespaces in the same document to increase the
vocabularies available to describe resources.
In addition to the RDF/XML syntax, other triple-oriented RDF serializations exist, such as the N–Triples and Notation 3 (N3) formats.
N–Triples format is simply the assertion sequence where each statement is in the form
<subject><predicate><object>.
If we wanted to describe our previous resources in N–Triples format this would be the result:
<http://example.org/umld><http://example.org/hasAuthor><http://example/mfowler>.
<http://example.org/umld><http://example.org/title> "UML Distilled".
<http://example.org/umld><http://example.org/isbn> "0201325632".
<http://example.org/mfowler><http://example.org/firstname> "Martin".
<http://example.org/mfowler><http://example.org/lastname> "Fowler".
Also N3 format allows to describe resources using RDF model but, unlike the XML syntax, ensures a better human readibility. The same example in N3 format reads:
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.
@prefix ex: <http://example.org/>.
ex:umld ex:hasAuthor ex:mfowler;
ex:title "UML Distilled";
ex:isbn "0201325632".
ex:mfowler ex:firstname "Martin";
ex:lastname "Fowler".
That’s all for now.
In the next post I will focus the discussion on the RDF Schema Model (RDFs).
I will explain the way to create the vocabulary of resources in order to describe the meaning of classes and properties to help machines process data efficiently.
So stay tuned!
]]>XML
alone is not sufficiently powerful in the Semantic Web context.
XML is the acronym of Extensible Markup Language and represents a meta-language for the syntactic definition
of markup languages allowing to add metadata
to local
data and separate contents from presentations with a
neutral textual format.
Imagine we have the following XML code:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<mailbox>
<mail id="01">
<to>Giovanni</to>
<from>Francesco</from>
<title>Enjoy Christmas</title>
<body>Merry Christmas and a Happy New Year</body>
</mail>
</mailbox>
In the above example the tags <mailbox>
, <mail>
,<to>
,<from>
,<title>
and <body>
have been created specifically for our document and the name of each tag has been implemented to describe in the best possible way the content data.
The big problem is that XML
is unsuitable to the global
semantic interpretation because there is no
way to explain to the machine that for example, the string Giovanni
, enclosed withing the tag <to>
,
represents the name of a person.
With XML it is possible to adequately describe the content of a document, bux XML syntax does not define any explicit mechanism to semantically describe relationships between resources inside and outside the document. In fact, XML alone is not sufficiently powerful to explain the semantics in an independent and autonomous way from the context.
Also it is not able to generate new knowledge starting from the original data infering new statements.
For example, if we have the fact The dog is a mammal
, the XML does not allow to define
the sentence in terms of relationship. Also if we consider the fact Fido is a dog
, it should be
possible to infer the new fact Fido is a mammal
. But XML does not allow to explicit this rule between
resources because of it is unsuitable to represent semantically the resource on the Web.
To overcome the XML semantic markup limitations, the W3C Consortium has formalized some models which aim to provide an abstract formalism to describe resources and their relationships (RDF, RDFs, OWL).
The RDF model will be described in the next post, so, stay tuned!
]]>Proprio per la sua diffusione capillare e globale, secondo me però, twitter potrebbe essere utilizzato per fare anche altro.
Mi piacerebbe infatti utilizzare il mio client twitter come un telecomando da pigiare per ottenere specifici servizi: informazioni sui programmi televisi attualmente in onda, previsioni meteo, eventi serali della mia città, orari di apertura degli uffici pubblici, etc.
Mi piacerebbe avere la possibilità di interagire in modo semplice e immediato, tramite un banale tweet, ed ottenere queste informazioni, in modo centralizzato, direttamente sul mio smartphone.
Sono state queste motivazioni che mi hanno portato a ideare e sviluppare cosaceintv
, un servizio quindi tweet-driven
.
#}
Tecnicamente parlando ho implementato un BOT in grado di intercettare il testo del tweet, di validarlo e di eseguire la richiesta inviando all’utente una risposta, tramite un tweet. Esistono già interessanti Twitter Bot in grado di rispondere automaticamente a tweet con menzioni particolari o contenenti un testo predefinito. Nonostante ciò ritengo siano ancora troppo pochi e sottoconsiderati.
cosaceintv
mette a disposizione un servizio interrogabile tramite tweet in grado di fornire informazioni sui programmi televisivi del giorno, sperimentando ed esplorando così un nuovo modo di interagire con twitter.
Per ottenere ciò ho definito un linguaggio specifico per il dominio, cioè un DLS, dei principali canali TV italiani.
Il software sviluppato si compone di due parti (vedere Figura):
pull
di tutti i tweet che menzionano l’utente @cosaceintv
. Se il comando è valido il software esegue la richiesta interrogando il repository dei programmi TV, precedentemente popolato dallo scraper. Ottenuti i programmi TV, l’engine si occuperà infine di inviare uno o più tweets, tramite messaggi diretti, all’utente richiedente.Per utilizzare il servizio:
Diventate follower di @cosaceintv:
Inviare un tweet menzionando @cosaceintv in questo modo:
@cosaceintv #1
dopo la menzione e’ obbligatorio specificare l’hash anti-duplicazione (#1), che deve essere un numero sempre diverso per ogni richiesta uguale. In questo modo twitter non considerera’ le richieste uguali come tweet duplicati e non blocchera’ di fatto l’invio del tweet.
Quindi se gia’ ho richiesto @cosaceintv #1
, la seconda volta, per la stessa identica richiesta, inviero’ un tweet con l’hash anti-duplicazione diverso da 1,
ad es. @cosaceintv #2
o qualsiasi altro numero diverso da quelli gia’ usati.
L’hash anti-duplicazione si applica anche alle successive tipologie di richieste.
@cosaceintv alle 16:50 #1
(l’orario e’ accettato nella forma hh:mm, hh, h, ad es. 16:40, 16, 9)
@cosaceintv dalle 16:00 alle 19:00 #1
@cosaceintv su RAI1 #1
(canali disponibili: RAI1, RAI2, RAI3, CANALE5, ITALIA1, RETE4, LA7)
@cosaceintv su RAI1, RAI2, RAI3 #1
@cosaceintv su RAI1,RAI2 alle 19:00 #1
@cosaceintv su RAI1,RAI2 dalle 19:00 alle 21:00 #1
Dopo aver inviato il tweet, aspettate circa 3 minuti e… enjoy tweets :)
p.s. l’attesa dipende anche dal tempo di sincronizzazione del vostro client twitter.
Il progetto è ancora in uno stato alpha, tuttavia è già disponibile online per effettuare prove:
That’s all folks! Stay tuned!
]]>#}
Si evidenzia che ogni iniziativa volta alla diffusione della Gazzetta Ufficiale della Repubblica Italiana in formato digitale, potrà essere effettuata unicamente previa espressa autorizzazione dell’Istituto Poligrafico e Zecca dello Stato.
Se non ricordo male, dal sito si poteva accedere alle gazzette ufficiali degli ultimi 60 giorni, mentre i numeri precedenti erano visionabili solo in sommario. Per ottenere la visualizzazione completa bisognava pagare.
Sì, avete capito bene, la visione della legge italiana, pagata con i nostri soldi, che per natura non ha nessun copyright, era a pagamento. Sono rimasto basito e le mie speranze di poter fare un pò di sano scraping senza scontrarmi con autorizzazioni e permessi vari sono andate in fumo.
Tutto questo fino alla fine dell’anno scorso perchè, con mia stragrande meraviglia le cose sono cambiate.
Dal 1° gennaio 2013 infatti sul sito ufficiale della Gazzetta Ufficiale è apparso il seguente disclaimer:
L’Istituto Poligrafico e Zecca dello Stato S.p.A. promuove la più ampia fruibilità della Gazzetta Ufficiale della Repubblica Italiana in formato digitale. […] La riproduzione dei testi forniti nel formato elettronico è consentita purché venga menzionata la fonte, il carattere non autentico e gratuito.
Sebbene non sia specificata con quale tipo di licenza siano disponibili i dati, adesso è possibile quindi riutilizzare i dati delle gazzette ufficiali in altri contesti senza scontrarsi con autorizzazioni e limiti di prima. Proprio quello che volevo.
Partendo da questo, complici le ferie estive e il mio pallino per gli Open Data, ho
immaginato quindi un meccanismo di accesso alle gazzette ufficiali in modo strutturato, in grado di automatizzare il processo di elaborazione e di riuso dei dati in contesti differenti da quello di partenza, per accrescere il valore originale dei dati: è nato così il progetto OpenGazzettaUfficiale
.
Il servizio, ancora in beta, mette a disposizione API di accesso alle gazzette ufficiali e rilascia i dati, restituiti attualmente in formato JSON, con licenza IODL v2.
Il dataset di riferimento comprende le gazzette ufficiali suddivise nelle seguenti serie:
Vediamo un pò di numeri.
Sul sito ufficiale la serie generale (la più grande e completa), comprende tutti i numeri delle gazzette ufficiali dal 1945, quindi ad oggi sono quasi 68 anni. Ciascun anno (ad eccezione del primo) include circa 300 numeri di gazzette. Ogni numero raccoglie anche fino a 60 atti. Ciascun atto è formato poi da un certo numero di articoli (anche fino a 30) e da allegati sia testuali che esterni in pdf. Il contenuto di ciascuna serie, anno, gazzetta, atto, articolo o allegato è raggiungibile con un URL univoco. E questo solo la serie generale.
Facendo una stima molto provvisoria, solo per la serie generale, si arrivano a contare più di 7 milioni di link da scrapare. Poi ci sono tutte le altre serie. Dal punto di vista tecnico utilizzo componenti Symfony per lo scraping e un sistema di caching eterno per limitare le chiamate esterne. Il tutto in un hosting condiviso da poche decine di euro l’anno.
Per informazioni sulle API guardare la documentazione presente nella homepage del progetto.
Vediamo adesso come realizzare facilmente quel servizio Web accennato sopra, per il controllo automatico dei concorsi pubblici in riferimento a particolari topic. Immaginiamo di voler ottenere informazioni sui concorsi pubblici in aeronautica. E’ necessario quindi attivare un servizio cron, limitatamente nei giorni di martedì e venerdì, che sono i giorni in cui viene pubblicata la Gazzetta Ufficiale serie Concorsi, per il seguente script:
<?php
$topic = 'aeronautica';
$json = file_get_contents('http://www.opengazzettaufficiale.it/serie/concorsi');
$serie = json_decode($json, true);
$ultimoAnnoSerie = array_reverse($serie['anni'])[0];
$json = file_get_contents($ultimoAnnoSerie['url']);
$numeriGazzetta = json_decode($json, true);
$ultimaGazzetta = array_reverse($numeriGazzetta['gazzette'])[0];
$json = file_get_contents($ultimaGazzetta['url']);
$sommario = json_decode($json, true);
$atti = $sommario['atti-gazzetta-ufficiale'];
foreach($atti as $atto) {
if (preg_match("/.*$topic.*/", $atto['breve'])) {
$to = 'giovanni.pirrotta@gmail.com';
$subject = $atto['oggetto'];
$message = $atto['breve'] ;
mail($to, $subject, $message); // mail, tweet, facebook, etc...
}
}
Il codice è autoesplicativo.
Il servizio è ancora un prototipo e molto deve essere ancora fatto, ad esempio la ricerca centralizzata delle gazzette. Il codice è attualmente soggetto a modifiche e ottimizzazioni.
Feedback, commenti e critiche sono i benvenuti.
]]>Così è stato anche quando nel novembre del 2012 ho letto che l’utente eccoilmoro
aveva realizzato, come esperimento di civic-hacking, lo scraping dell’albo pretorio online dei comuni della Bassa Romagna, reindirizzando il tutto su una pagina
FB prima e su un profilo Twitter dopo.
Il tutto è stato poi riportato in questo blog.
Stimolato anch’io dallo stesso desiderio di aprire l’albo pretorio online del mio piccolo paese ho sviluppato degli script di scraping in PHP per la generazione di feed RSS dati poi in pasto ad uno dei più famosi servizi di pubblicazione automatica nei Facebook, cioè RSSGraffiti. Successivamente ho reindirizzato il tutto sulla pagina FB dell’Albo Pretorio del mio comune (creata ad-hoc), vale a dire Terme Vigliatore (ME). Lo stesso script l’ho poi adattato per l’Albo Pretorio del più grande comune limitrofo, cioè Barcellona Pozzo di Gotto (ME).
Come già scritto in un precedente post, credo fermamente che ogni pubblica amministrazione debba innescare meccanismi e processi interni ispirati a principi di trasparenza ed apertura in modo da poter fornire una misura al cittadino per la valutazione oggettiva dell’attività amministrativa, con strumenti che siano semplici e alla portata di tutti, leggi open-gov.
Volendo contribuire anch’io nel mio piccolo, a distanza di mesi, sono ritornato su quegli script di scraping con l’intenzione di rilasciarli e metterli a disposizione di tutti: è nato così il progetto OpenAlboPretorio, disponibile su github.
Per l’installazione
$ git clone https://github.com/gpirrotta/OpenAlboPretorio.git
$ cd OpenAlboPretorio
e digitiamo i seguenti comandi:
$ wget http://getcomposer.org/composer.phar
$ php composer.phar install
A questo punto aggiungiamo l’autoloader al nostro script e avremo accesso alla libreria
<?php
require 'vendor/autoload.php';
La class OpenAlboPretorio
rappresenta l’entry point della libreria.
Attualmente sono implementati i seguenti scraper:
TermeVigliatoreScraper
effettua lo scraping dall’Albo Pretorio online di Terme Vigliatore (ME)BarcellonaPGScraper
effettua lo scraping dall’Albo Pretorio online di Barcellona Pozzo di Gotto (ME)e i seguenti formati di output:
Vediamo adesso come utilizzare la libreria.
E’ possibile utilizzare il metodo city
per selezionare lo scraper con le impostazioni di default (max 10 risultati)
<?php
$albo = new OpenAlboPretorio();
$results = $albo->city(AlboPretorioScraperFactory::TERME_VIGLIATORE);
->open();
print $results
Oppure è possibile personalizzare lo scraper manualmente:
<?php
$scraper = new BarcellonaPGScraper(new BarcellonaPGMasterPageScraper(), new BarcellonaPGDetailPageScraper());
$scraper->setItemType(BarcellonaPGScraper::TIPOLOGIA_DETERMINAZIONE_DEL_SINDACO);
$formatter = new FeedFormatter(FeedFormatter::ATOM_FEED_TYPE); // RSS2 default
$albo = new OpenAlboPretorio();
$results = $albo->scrapeUsing($scraper)
->formatUsing($formatter)
->maxNumberItems(10)
->open();
print $results;
Per creare lo scraper della tua città è necessario implementare l’interfaccia AlboPretorioScraperInterface
.
Estrarre i dati dal sito Web dell’albo pretorio di una qualsiasi città significa, generalmente, estrarre i dati da due pagine:
1) una pagina Master - la pagina Web che contiene l’elenco di tutti gli atti amministrativi (items) dove su ciascun atto troviamo una breve descrizione e il link relativo (in figura il link è sulla descrizione in grassetto);
2) una pagina Detail - la singola pagina Web dell’atto amministrativo contenente il dettaglio (numero, mittente, oggetto, stato, validità di pubblicazione, allegati, etc.)
Per gestire questo tipo di logica di estrazione dei dati la libreria fornisce una classe astratta
chiamata AbstractMasterDetailTemplateScraper
che implementa l’interfaccia AlboPretorioScraperInterface
.
La classe dipende dalle seguenti interfacce:
MasterPageScraperInterface
usata per estrarre l’elenco degli URL degli atti amministrativi dalla pagina master;DetailPageScraperInterface
usata per estrarre i dati di ciascun atto amministrativo ritornando un oggetto AlboPretorioItem
Ovviamente, se il template della pagina Web dell’albo pretorio segue una logica di estrazione diversa da quella Master-Detail, è possibile implementarne di nuove in base alle proprie esigenze.
La libreria si trova su github, rilasciata con licenza opensource MIT.
N.B. In merito alla liceità sull’attività di scraping di dati della pubblica amministrazione voglio condividere con voi alcune osservazioni:
da un lato è risaputo che i comuni possono rimuovere gli atti amministrativi dall’albo pretorio online dopo un certo numero di giorni. Quello che accade spesso, invece, è che gli atti rimangono nell’archivio online consultabile, mentre solo l’allegato, copia dell’atto cartaceo, viene effettivamente rimosso;
dall’altro, dal 19 marzo 2013, tutti i dati e documenti che le pubbliche amministrazioni pubblicano con qualsiasi modalità, senza l’espressa adozione di una licenza d’uso, si intendono rilasciati come dati aperti secondo il principio open data by default (art. 52 e art.68 del Codice Amministrazione Digitale), anche se non è stato ancora deciso il tipo di licenza.
L’albo pretorio online dei comuni finora presenti su OpenAlboPretorio non riportano nessun tipo di licenza di rilascio dei dati in fondo alla pagina, motivo per cui rientrerei (spero) nel secondo punto. E’ un aspetto sicuramente da approfondire, motivo per cui consiglio a chiunque voglia utilizzare OpenAlboPretorio di stare vigili sull’argomento.
Se vuoi contribuire al progetto aggiungendo lo scraper dell’Albo Pretorio della tua città, o semplicemente migliorando il codice rilasciato, le PR sono le benvenute.
That’s all folks!
Importante aggiornamento
Dopo la pubblicazione del progetto OpenAlboPretorio è nata un’interessante discussione sulla lista SOA, dove dei giuristi esperti del settore mi hanno fatto notare come la questione sulla tutela della privacy e la pubblicità delle delibere dell’albo pretorio sia un argomento molto controverso del panorama giuridico italiano.
In estrema sintesi gli atti dell’albo pretorio possono essere suddivisi in due categorie (ringrazio Giovanni Battista Gallus per il chiarimento):
Per non incorrere in violazioni della privacy invito quindi, a chiunque volesse utilizzare e/o estendere la libreria, di effettuare solo lo scraping degli atti amministrativi del primo punto.
]]>Imagine we encounter the sentence
In 2013, the minimum required height for male candidate is 1.65
Obviously, a human being would have no trouble understanding in reading time the semantics of the sentence, because he is a being endowed with intelligence. For a man there are no problems to understand the difference between numbers 2013 and 1.65, the first indicating the year and the second the height.
But, how can you say this to the computer? Is the computer able to understand unambiguously the sentence, grasping all nuances? Of course, our software agent cannot automatically extract semantics from text since the only text itself is meaningless for machines. Then, how can we help our software to understand the text; what can we do to make it more intelligent?
The only way to help the computer to understand something is to rewrite the sentence in a structured way, using markers to define the meaning of parts.
For example, we can rewrite the previous sentence using the following markers:
[Start of requirements]
[A date] {In 2013}
[closely] {the minimum}
[it is not accessible without] {required}
[a measure] {height}
[a genre] {for male}
[those who want to access] {candidate}
[semantic link {height}] {is}
[limitation for access] {1.65}
[end of sentence] {.}
In this way, we specify each concept with a marker indicating the semantics and allowing a software agent to interpret the meaning of terms enclosed in braces automatically. Although our goal is to fill the request application for the police selection, we can easily see that the simple understanding of a sentence can be a difficult task for a non-human user. You can already guess now that the understanding of the text above mentioned in the labeled sentences depends on the ability of a software to know the meaning of the markers. Thus, the idea is to create markers, as terms of a vocabulary formally defined, powerful enough to set and share meaning by machines.
The future of the Web, according to Tim Berners-Lee vision, is to extend the actual Web into an environment where we can publish not only data, but also information describing the data, called metadata, which are essential to determine their meaning. We have to decorate pages with extra information to explain the meaning contained. To achieve this target we have to use a knowledge representation common model, shared by all people and sufficiently expressive.
All information will be expressed by formal descriptive statements saying the relationship existing between two resources (i.e. Michael is a student, the sky is blue, etc.) and data can be represented as a giant global graph, highly interconnected and finally machine-understandable.
The Semantic Web goal is to extend the actual Web, transforming it into the Web of Data. The semantic technologies provide necessary tools to reuse information implementing systems for typifying content and links between pages. The Semantic Web research area includes a set of evolving technologies, standards and tools forming a technological stack; each level represents the basis for the levels defined at higher levels as we can see in the Figure.
But, how do we represent the information written in HTML in a structured way? And how do we specify the meaning of each single abstract or concrete concept? The reply in next posts!
Stay tuned!
]]>Da qualche tempo però, appassionato di data mining, è nato in me il desiderio di effettuare ricerche statistiche sulla storia delle amministrazioni passate, per ricavarne qualcosa di interessante e curioso.
Primo passo, la ricerca di fonti attendibili dalle quali prelevare i dati per iniziare le elaborazioni.
Dopo una prima ricerca infruttuosa sul sito del comune ho trovato nel sito del Ministero dell’Interno e nello specifico in questa pagina informazioni davvero interessanti. La pagina consente infatti di scaricare tutti gli archivi in formato standard CSV relativi agli amministratori comunali, provinciali e regionali di tutti i comuni d’Italia con rilevazioni annuali dal 1985 al 2012.
Possiamo partire!
Per ogni amministratore, sia esso sindaco, assessore o consigliere, l’archivio riporta, tra i tanti codici identificativi, anche alcune informazioni di carattere personale come ad esempio i seguenti dati:
- cognome
- nome
- sesso
- data di nascita
- comune italiano o stato estero di nascita
- descrizione carica
- descrizione partito
- descrizione titolo di studio
- descrizione professione
- anno di elezione
Dopo un’oretta passata tra script bash di estrazione, conversione e riconciliazione dei dati vediamo cosa ne è uscito fuori.
Innanzitutto ho trovato dati relativi al comune di Terme Vigliatore solo dal 1988 fino al 2012. Inoltre,
inspiegabilmente, il Ministero degli Interni non fornisce alcun dato del nostro paese nel 2002.
Che sarà mai successo nel 2002?
Non verranno presi infine in considerazione gli anni relativi all’ultimo commissariamento (2005-2007) in quanto
mancanti.
Bene, cominciamo a farci qualche domanda e a rispondere mostrando le statistiche elaborate!
** 1) Quante donne hanno amministrato Terme Vigliatore negli ultimi 24 anni? **
Poche; aggiungo io, purtroppo. Su un totale di 79 amministratori tra sindaci, consiglieri e assessori, solo l’ 11% di donne sono salite sullo scranno comunale.
** 2) Qual è stato il livello di istruzione dei nostri amministratori? **
** 3) Che lavoro facevano i nostri amministratori? **
** 4) Dove sono nati i nostri amministratori? **
Fino al 28 giugno 1966 Terme Vigliatore faceva parte del comune di Castroreale, motivo per cui molti amministratori, pur essendo nati a Terme Vigliatore, risultano all’anagrafe nati a Castroreale.
** 5) Qual era l’età media degli amministratori? **
** 6) Chi sono stati i nostri amministratori e per quanto tempo? **
(Il totale anni è dato dalla somma di ciascun amministratore considerando tutte le cariche ricoperte nel periodo di riferimento - es. 5 = 3 (da consigliere) + 2 (da assessore))
That’s all folks!
Prima di chiudere volevo esprimere un augurio al sindaco e ai neo-consiglieri (soprattutto ai più giovani) affinchè la loro attività amministrativa possa innescare compiti, processi e modelli organizzativi ispirati sempre più a principi di:
trasparenza: perchè noi cittadini dobbiamo poter misurare e valutare l’attività amministrativa, dobbiamo essere messi in condizione di monitorare e giudicare i processi decisionali adottati, con strumenti semplici e alla portata di tutti;
apertura: i dati prodotti dal comune, in quanto finanziati da denaro pubblico, appartengono al cittadino e a quest’ultimo devono ritornare; l’analisi dei dati prodotti dall’attività amministrativa rappresenta la chiave oggettiva per giudicare la virtuosità di un comune, per confrontarlo con realtà simili o del comprensorio, per mettere in evidenza eventuali sprechi, per individuare ambiti da migliorare, etc;
partecipazione: perchè noi cittadini dobbiamo poter essere coinvolti e resi partecipi alla gestione amministrativa mediante anche strumenti tecnologici, piattaforme online di ascolto, forum di partecipazione democratica che possano stimolare proposte e interventi effettivamente legati alle esigenze e necessità dei cittadini. Nell’era del Web, esistono decine di applicazioni informatiche, anche a costo 0, che consentirebbero di appiattire il gap esistente tra i cittadini e il palazzo comunale, tra elettori ed eletti;
collaborazione: perchè non si consideri il comune come un’istituzione disconnessa a se stante, modello isola, ma invece come cellula viva all’interno di una rete collaborativa composta anche da altri enti, organizzazioni, associazioni e movimenti con i quali instaurare rapporti di crescita e benessere sociale, artistico e culturale.
In una sola parola: open government!
]]>The World Wide Web is mainly based on documents written in HTML language but, infortunately, the language defines only how to show data without specifying anything about the meaning of data showed.
All data, such as local sport events, weather information, plane times, major baseball statistics, television guides, and so on are presented by numerous sites, but all in HTML. So it is difficult to reuse these data in different contexts, it is difficult for machines to perform automatic tasks in order to carry out specific activities.
We imagine for example the difficulty for a search engine to find the information desired by a user. When we perform a search, we expect the search engine is able to understand the nuance of meaning that we want to express without problems of interpretation. For example, if we search the Italian word espresso, how does the search engine understand if we are searching for information about:
The word espresso has many meanings depending on the context in which it appears. Unlike, in a semantic-based system each word is related to a series of semantic networks, which are not simply lists of words, but dense data links allowing to process complex information. A software agent should understand if different propositions identify the same concept, individuate all relationships between a word and their properties, unlike current search engines that index all contents by words and not by semantic networks.
The documents published on the Web can be considered as belonging to a huge global file system; since HTML pages are written by humans for humans, the semantics is implicit inside the pages and links, and it is made explicit in the human-interaction. The data contained in Web pages are not organized and structured to be processed, queried and interpreted unambiguously in a model that can explain the implicit semantics in a manner understandable to machines, because in this context everything revolves around documents and their links, and not around data, i.e., the resources contained into documents.
For example, with HTML languages we can list items for sale but there is no capability within the HTML itself to assert unambisuously that, item number “ABC” is a DVD recorder with a price of euro 100,00. Rather HTML can only say that the portion of text “super” is something that should be placed near the text “DVD recorder” and so forth. There is no way to say “This is an e-commerce site” or event to establish that DVD recorder is a kind of product or that euro 100,00 is a price.
Summarizing, the problem of the actual Web is that the content is not structured and the links are untyped and meaningless. We can see each Web server as a disconnected data silos and in each silos the data cannot be reused in external contexts from the original one. We cannot ask expressive queries on data, we cannot process content within applications of mashup data with information coming from different data sources.
We have problems in terms of interpretation, integration and automatic processing.
That’s all for now. In the next post I will talk about how machines can think. Stay tuned!
]]>A very famous example used by founder explains his original idea. In a utopian world Lucy is at the doctor’s, and she calls her brother Pete to tell him that the doctor has prescribed some physiotherapy sessions to their mother. Lucy immediately instructs her agent semantics software, through her PDA, to retrieve information about her mother’s treatment such as the list of doctors covered by her mother’s insurance with a high level confidence provided by the confidence ranking service and no more than 20 miles distance from her mother’s house. For each doctor found, the software agent retrieves information from the doctor’s homepage and creates the potential appointments compatible with the Lucy and Pete’s schedules. When Pete sees the plan of appointments provided by Lucy’s agent, he decides to add other constraints, such as less distance and different times, until Lucy and Pete find a compatible solution to the needs of both.
With this example, Tim Berners-Lee explains how the Web should evolve in the future, because currently the Web is not able to process the content of each Web page, extract information and make decisions. Instead, the Semantic Web intends to add meaning to pages, creating an environment where the programs themselves can also perform complex tasks for users in a completely automatic way.
In the Web of the future, every doctor’s homepage should provide the ability to understand and interrogate its content; each software should be able to process the page and, for example, automatically retrieves the doctor’s schedules, and from these responses make decisions autonomously and efficiently.
In the next posts I will explain Semantic Web ingredients able to transform the current Web into a structured environment machine-processable. To do this I will start pointing out the current Web limitations, and next I will show how it is possible to overcome these obstacles applying semantic technologies. Finally I will describe the Linked Data principles which have brought a breath of fresh air to Semantic Web applications.
]]>