<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Giovanni Pirrotta]]></title>
  <link href="http://giovanni.pirrotta.it/atom.xml" rel="self"/>
  <link href="http://giovanni.pirrotta.it/"/>
  <updated>2019-05-06T16:54:24+00:00</updated>
  <id>http://giovanni.pirrotta.it/</id>
  <author>
    <name><![CDATA[Giovanni Pirrotta]]></name>
    
  </author>
  <generator uri="https://jekyllrb.com">Jekyll</generator>

  
  <entry>
    <title type="html"><![CDATA[Alla scoperta di Ontopia, il Knowledge Graph della PA Italiana]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2019/05/04/alla-scoperta-di-ontopia-il-knowledge-graph-della-pa-italiana/"/>
    <updated>2019-05-04T01:40:08+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2019/05/04/alla-scoperta-di-ontopia-il-knowledge-graph-della-pa-italiana</id>
    <content type="html"><![CDATA[<p>Cos’è <strong>Ontopia</strong>? E’ una famiglia di ontologie e di vocabolari controllati pensata per il mondo della pubbliche amministrazioni. Sì, ma cos’è un’<strong>ontologia</strong>?
Un’ontologia è la concettualizzazione di una realtà di interesse ottenuta mediante la definizione formale di un dominio specifico attraverso un linguaggio di modellizzazione.</p>

<p>Seee, vabbè, buonanotte. Giovà, me so perso… concettualizzazione, modellizzazione, linguaggio??? Ma che vor dì???</p>

<!--More-->

<p><img class="center-image" src="/images/ontopia/arya-meme.jpg" width="80%" /></p>

<p>Ok, cominciamo dall’inizio e con una storia.</p>

<p><strong>Lucy</strong> accompagna la madre dal dottore che, dopo averla visitata, le prescrive delle sedute di fisioterapia. 
Lucy chiede al suo <strong>smartphone</strong> 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 <strong>Pete</strong>, 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.</p>

<p>Questo racconto è tratto dal famoso articolo del <a href="http://www-sop.inria.fr/acacia/cours/essi2006/Scientific%20American_%20Feature%20Article_%20The%20Semantic%20Web_%20May%202001.pdf">Scientific American del 2001</a>, in cui <strong>Tim Berners-Lee</strong>, creatore del <strong>Web</strong> e del <strong>Semantic Web</strong>, 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.</p>

<p>Il Web così come lo conosciamo è costituito da pagine esplorabili all’interno di applicazioni chiamate <strong>browser</strong>, utilizzate dagli utenti per navigare la rete. I browser hanno il compito di rappresentare le pagine favorendo lo <strong>scambio</strong> di informazioni tra umani. Gli stessi browser, però, non sanno nulla degli argomenti trattati nella pagine, non sono in grado di <strong>comprendere</strong> il significato delle informazioni rappresentate né sono dotati di intelligenza per improvvisare <strong>ragionamenti</strong> logici in piena autonomia. Possiamo dire quindi che le informazioni rappresentate nelle pagine Web non favoriscono lo scambio tra programmi.</p>

<p>Ma come possono diventare <strong>intelligenti</strong> le macchine? Come possono capire il <strong>significato</strong> delle informazioni presenti nel Web?</p>

<p>Per rendere il Web intelligente è necessario creare un <strong>ambiente</strong> in cui a tutte le “cose” esistenti vengono associate informazioni e dati (<strong>metadati</strong>) 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 <strong>condizioni</strong> affinché  possano comprendere e questo deve essere fatto in un <strong>linguaggio</strong> a loro comprensibile. Questo nuovo tipo di ambiente prende il nome di <strong>Web Semantico</strong> 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.</p>

<p>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 (<em>classi</em>, <em>proprietà</em>, e <em>restrizioni</em>). Il risultato di queste concettualizzazioni viene definito comunemente <strong>ontologia</strong>.</p>

<p>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: [<a href="http://giovanni.pirrotta.it/blog/2013/05/24/semantic-web-what/" target="blank">1</a>,<a href="http://giovanni.pirrotta.it/blog/2013/06/03/limits-of-the-web-today/" target="blank">2</a>,<a href="http://giovanni.pirrotta.it/blog/2013/07/04/can-machines-think/" target="blank">3</a>,<a href="http://giovanni.pirrotta.it/blog/2013/11/20/xml-limits/" target="blank">4</a>,<a href="http://giovanni.pirrotta.it/blog/2013/12/23/the-rdf-model/" target="blank">5</a>,<a href="http://giovanni.pirrotta.it/blog/2014/01/06/semantic-web-ingredients-the-rdf-schema-model/" target="blank">6</a>,<a href="http://giovanni.pirrotta.it/blog/2014/07/22/semantic-web-ingredients-the-web-ontology-language/" target="blank">7</a>,<a href="http://giovanni.pirrotta.it/blog/2014/07/30/semantic-web-ingredients-rdfa/" target="blank">8</a>,<a href="http://giovanni.pirrotta.it/blog/2014/10/27/semantic-web-ingredients-the-sparql-language/" target="blank">9</a>,<a href="http://giovanni.pirrotta.it/blog/2015/10/18/developing-an-ontology/" target="blank">10</a>]</p>

<h3 id="perchè-ontopia">Perchè Ontopia</h3>

<p>Per spiegare le motivazioni che hanno dato origine al progetto Ontopia prendiamo ad esempio il dominio dei <strong>servizi pubblici</strong> delle PA.</p>

<p>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 <em>non possono essere scambiati</em> tra sistemi diversi perché descritti in modo <strong>incompatibile</strong>; ciò avviene quando abbiamo <strong>problemi di semantica</strong>. Per superare questo ostacolo è necessario creare delle <em>connessioni significative</em> tra dati e per fare questo è necessario seguire <strong>standard aperti</strong> e <strong>condivisi</strong>.
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.</p>

<p>Anche la <strong>Commissione Europea</strong>, nel documento quadro <em>European Interoperability Framework</em>, che mira a potenziare l’interoperabilità dei servizi pubblici nell’Unione Europea, afferma infatti che “<em>l’agenda digitale può decollare solo se è garantita un’interoperabilità basata su standard e piattaforme aperte</em>”.</p>

<p>Purtroppo, però, nelle PA italiane si riscontrano ancora le seguenti criticità:</p>

<ul>
  <li><strong>mancanza di standard condivisi</strong> in uso alle applicazioni software che gestiscono l’attività amministrativa;</li>
  <li>ogni applicativo, il più delle volte proprietario, gestisce i dati della PA secondo logiche che <strong>non supportano nativamente l’interoperabilità semantica</strong>, cioè lo stesso concetto di un dominio condiviso tra diverse PA viene rappresentato in modo diverso a seconda dell’applicativo che lo gestisce.  A questo costo si aggiunge spesso anche quello causato dal <strong>lock-in</strong> del fornitore, cioè quando le PA, per la difficoltà a migrare verso sistemi IT più moderni offerti da aziende terze, rimangono imprigionate allo stesso fornitore ICT;</li>
  <li><strong>mancanza di una regia unica nazionale</strong> che proponga e imponga dall’alto l’utilizzo di una solida e stabile architettura dell’informazione dei dati pubblici e che obblighi i fornitori ICT a rilasciare i propri applicativi secondo tali standard.</li>
</ul>

<p>In realtà sull’ultimo punto è necessario aggiungere qualcosa, ma procediamo per passi.</p>

<p>Dal punto di vista normativo l’Italia da anni insiste e incentiva l’adozione di standard condivisi come dimostrano i seguenti riferimenti:</p>

<ul>
  <li><strong>Art. 20 - Comunità intelligenti</strong> - della legge n. 221 del 17 dicembre 2012, recante misure urgenti per la crescita del Paese:
    <ul>
      <li>L’Agenzia per l’Italia Digitale (AGID) definisce strategie e obiettivi, coordina il processo di attuazione e predispone gli strumenti tecnologici ed economici per il progresso delle comunità intelligenti. A tal fine l’Agenzia: […]
c) emana le linee guida recanti definizione di standard tecnici, compresa la determinazione delle ontologie dei servizi e dei dati delle comunità intelligenti;</li>
    </ul>
  </li>
  <li><strong>Linee guida per la valorizzazione del patrimonio informativo della Pubblica Amministrazione</strong> - AGID:
    <ul>
      <li>Il documento,[…], approfondisce l’uso di un insieme di standard di base e di ontologie e vocabolari specifici per categorie trasversali e verticali di dati delle pubbliche amministrazioni, al fine di guidare nell’effettiva implementazione dei modelli proposti, i.e., dei dati e dei metadati, e operativo.</li>
    </ul>
  </li>
  <li><strong>Vocabolari controllati e modelli di dati</strong> - Capitolo 4 del Piano Triennale ICT 2017/19</li>
</ul>

<p>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 <strong>standardizzare il patrimonio informativo della pubblica amministrazione</strong>, creando  una famiglia di modelli di dati, cioè <strong>ontologie</strong>, 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 <strong>vocabolari controllati</strong>, ottenuti armonizzando e standardizzando tassonomie, codici e nomenclature, da utilizzare come categorizzazioni nelle ontologie e nelle basi di dati pubbliche.</p>

<p>Questa iniziativa dell’AGID prende il nome di <strong>Ontopia</strong> 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 <strong>moderna</strong> e <strong>innovativa</strong>, <strong>trasparente</strong> e <strong>aperta</strong>, i cui dati siano <strong>semanticamente interoperabili</strong>, per facilitare lo sviluppo di nuovi sistemi informativi, per agevolare lo scambio di dati, per abilitare l’integrazione tra dati provenienti da fonti diverse.</p>

<p>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 <strong>grafo della conoscenza della pubblica amministrazione italiana</strong> o <strong>Knowledge Graph</strong>. E tutto questo, in Ontopia, viene fatto sfruttando le potenzialità del <strong>Web Semantico</strong>.</p>

<p>Il progetto Ontopia è sviluppato con il supporto del laboratorio di tecnologie semantiche dell’<a href="https://www.istc.cnr.it/">Istituto di Scienze e Tecnologie della Cognizione (ISTC) del CNR</a> e in collaborazione con diversi enti centrali e locali; è rilasciato con licenza aperta ed è allineata ai cosiddetti Core Vocabulary del programma <a href="https://ec.europa.eu/isa2/home_en">ISA2 della Commissione Europea</a>.</p>

<p>I <strong>principi</strong> cardine su cui si basa Ontopia sono:</p>

<ul>
  <li>il processo di creazione del progetto Ontopia si è avvalso di una metodologia iterativa, incrementale e collaborativa di modellazione delle ontologie basata su pattern, cioè su soluzioni di modellazione per problemi che ricorrono con frequenza. Questa pratica metodologica prende il nome di <strong>Agile eXtreme Design</strong> ed è stata associata all’uso dei <a href="http://ontologydesignpatterns.org/wiki/Main_Page">design pattern per le ontologie</a>;</li>
  <li>il progetto ha respiro europeo e la lingua di riferimento è l’inglese; le etichette degli elementi dell’ontologia e dei vocabolari controllati sono in inglese, in italiano e a volte in tedesco;</li>
  <li>ogni elemento dell’ontologia è identificato univocamente da una <strong>URI</strong>, resa persistente dal servizio <a href="https://w3id.org/" target="_blank">w3id.org</a>;</li>
  <li>le ontologie e i vocabolari controllati sono disponibili in varie serializzazioni: <strong>rdf/xml</strong>, <strong>rdf/turtle</strong>, <strong>json-ld</strong>;</li>
  <li>è possibile navigare tra le ontologie e i vocabolari controllati tramite <strong>interfaccia Web</strong>;</li>
  <li>è possibile fare interrogazioni tramite un <strong>endpoint SPARQL</strong> disponibile al seguente <a href="https://ontopia.daf.teamdigitale.it/sparql" target="_blank">link</a>;</li>
  <li>il progetto Ontopia <strong>riusa</strong> ontologie in modo indiretto ed effettua gli <strong>allineamenti</strong> in file separati.</li>
</ul>

<p>L’approccio tecnico di modellazione di Ontopia è rappresentato nella seguente figura:</p>

<p><img class="center-image" src="/images/ontopia/ontopia-tecnico.png" width="80%" /></p>

<p>Tipicamente, nel creare un’ontologia, i componenti più importanti sono le <strong>classi</strong> e le <strong>proprietà</strong>. Le ontologie del progetto Ontopia fanno riferimento a <strong>profili applicativi nazionali</strong>, 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 <strong>profili di conformità</strong> 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.</p>

<p>Inoltre, i concetti delle ontologie sono collegati esternamente ad un vocabolario controllato. 
Un esempio fra tutti. Nell’ontologia delle <strong>Strutture Ricettive</strong> (<a href="https://github.com/italia/daf-ontologie-vocabolari-controllati/tree/master/Ontologie/ACCO">ACCO</a>), la classe <code class="highlighter-rouge">Accomodation</code>, che è la classe principale che definisce la struttura ricettiva, ha la proprietà  <code class="highlighter-rouge">hasAccommodationTypology</code> il cui oggetto deve essere un concetto di tipo <code class="highlighter-rouge">AccommodationTypology</code>. Le istanze di questa classe sono concetti del vocabolario controllato <code class="highlighter-rouge">https://w3id.org/italia/controlled-vocabulary/classifications-for-accommodation-facilities/accommodation-typology</code>
definito esternamente all’ontologia. Tra queste istanze, che sono concetti definiti formalmente e univocamente tramite URI, troviamo ad esempio <strong>Motel</strong>, <strong>Agriturismo</strong>, <strong>Ostello per la gioventù</strong>, etc.</p>

<p>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 <strong>Organization</strong> viene definito nell’ ontologia <a href="https://github.com/italia/daf-ontologie-vocabolari-controllati/tree/master/Ontologie/COV">Core Organization Vocabulary</a> di Ontopia ma viene anche allineato al concetto <strong>Organization</strong> dell’ontologia <a href="https://www.w3.org/TR/vocab-org/">Organization</a> del consorzio <strong>W3C</strong>. Nel file esterno di allinamento troviamo infatti la definizione <code class="highlighter-rouge">covapit:Organization</code> di Ontopia <em>sottoclasse</em> di <code class="highlighter-rouge">org:Organization</code> dell’ontologia <strong>W3C</strong>.</p>

<p>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.</p>

<p>La seguente figura illustra invece lo <strong>stack ontologico</strong> del progetto Ontopia.</p>

<p><img class="center-image" src="/images/ontopia/ontopia-stack.png" width="80%" /></p>

<p>In Ontopia possiamo distinguere diversi <strong>livelli</strong> 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.</p>

<p>I livelli di Ontopia sono:</p>

<ul>
  <li><strong>Livello fondazionale L0</strong> - l’ontologia <strong>L0</strong> rappresenta un’ontologia di tipo <strong>top level</strong>; sono definiti termini molto generali utilizzati in tutte le altre ontologie di Ontopia, ad esempio concetti come <em>Evento</em>, <em>Sistema</em>, <em>Caratteristica</em>, <em>Entità</em>, <em>Location</em>. L’ontologia L0 rappresenta il fulcro del progetto Ontopia e consente a tutte le altre ontologie del progetto di essere collegate tra loro.</li>
  <li><strong>Livello core</strong> - le ontologie del livello <strong>core</strong> sono indipendenti dai concetti dei domini verticali e possono essere usati per descrivere in maniera trasversale concetti di più dataset. Fanno parte di questo livello le ontologie:
    <ul>
      <li>sulle <em>persone</em>, sviluppata in collaborazione con ISTAT;</li>
      <li>sulle <em>organizzazioni</em>, sviluppata a partire dall’indice delle pubbliche amministrazioni <strong>IPA</strong>;</li>
      <li>sui <em>luoghi</em>, sviluppato con ISTAT e l’agenzia delle Entrate.</li>
    </ul>
  </li>
  <li><strong>Livello di supporto</strong> - le ontologie di questo livello modellano concetti di supporto alle altre ontologie; troviamo concetti relativi al <em>tempo</em>, ai <em>ruoli</em>, alle <em>unità di misura</em>, ai <em>prezzi</em>, ai <em>social media</em>, ai <em>punti di interesse</em>, alle <em>lingue</em>, alle <em>condizioni di accesso</em>, etc.</li>
  <li><strong>Livello di dominio</strong> - le ontologie di questo livello modellano concetti relativi a domini specifici. Sono presenti le ontologie relative:
    <ul>
      <li>alle <em>Strutture Ricettive</em>;</li>
      <li>agli <em>Eventi IOT</em>, utilizzata per modellare il traffico in tempo reale;</li>
      <li>agli <em>Eventi pubblici</em>;</li>
      <li>al <em>Mondo della Cultura</em>;</li>
      <li>ai <em>Servizi Pubblici</em>, utilizzata nella piattaforma <em>servizi.gov.it</em>;</li>
      <li>ai <em>Contratti Pubblici</em>, sviluppata insieme ad ANAC, Regione Piemonte e Synapta.</li>
    </ul>
  </li>
  <li><strong>Vocabolari controllati</strong> - tassonomie di termini ricorrenti da utilizzare come istanze di dati per le ontologie di Ontopia e nelle basi di dati pubbliche;</li>
  <li><strong>Ontologie per i metadati</strong>: in questa categoria fanno parte le ontologie <strong>DCAT-APIT</strong>, per la metadatazione dei cataloghi dati e l’ontologia <strong>ADMC-APIT</strong>, per metadatare le ontologie stesse.</li>
</ul>

<h3 id="dove-si-trova-ontopia">Dove si trova Ontopia?</h3>
<p>Ontopia è un progetto aperto, fortemente collaborativo e partecipativo. Tutte le risorse disponibili sono su un repository <a href="https://github.com/italia/daf-ontologie-vocabolari-controllati">GitHub</a> 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.</p>

<p><img class="center-image" src="/images/ontopia/ontopia-github.png" width="80%" /></p>

<h3 id="conclusioni">Conclusioni</h3>

<p>In questo post ho voluto raccontare, seppur in maniera introduttiva, il progetto <strong>Ontopia</strong>, una delle iniziative istituzionali più sfidanti degli ultimi anni. Una piattaforma di modelli di dati <strong>istituzionale</strong>, <strong>aperta</strong> e creata in modo <strong>collaborativo</strong> 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.</p>

<p><em>Una piccola nota personale</em>.</p>

<p>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 (<a href="http://www.gpirrotta.tk/sw/swiup/">SWIUP</a>) sia delle statistiche dell’anagrafe studenti (<a href="http://www.gpirrotta.tk/sw/loius/">LOIUS</a>). In quella attività di ricerca descrissi in modo formale un pezzetto di pubblica amministrazione, nello specifico quella del Ministero dell’Istruzione, Università e Ricerca (<strong>MIUR</strong>). 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.</p>

<p>In <strong>Ontopia</strong>, 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.</p>

<p>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.</p>

<p>Sto studiando, ho ancora tanto da imparare e sto cercando di dare il mio contributo nei seguenti modi:</p>

<ul>
  <li>ho suggerito dei vocabolari controllati per il mondo universitario confrontandomi principalmente con <a href="https://twitter.com/GiorgiaLodi">Giorgia Lodi</a>, consulente AGID, coordinatrice del progetto Ontopia, nonché esperta di Semantic Web. Sono nati <a href="https://github.com/italia/daf-ontologie-vocabolari-controllati/tree/master/VocabolariControllati/classifications-for-universities">due vocabolari</a> controllati che ho proposto tramite PR su GitHub e che adesso fanno parte di Ontopia;</li>
  <li>con <a href="https://twitter.com/dataibi">Davide Taibi</a> stiamo cercando di <strong>“ontopizzare”</strong> l’ontologia <a href="http://www.openars.org">OpenARS</a>, modello di dati sviluppato per la rappresentazione dei dati sull’attività parlamentare dell’<a href="http://www.ars.sicilia.it">Assemblea Regionale Siciliana</a> (ARS), che abbiamo presentato l’anno scorso a Palermo in occasione del <a href="http://ods2018.opendatasicilia.it/">raduno annuale</a> della comunità Open Data Sicilia;</li>
  <li>ho rispolverato il mio vecchio progetto di modellazione del dominio delle università italiane e ho intenzione di creare una nuova ontologia - integrata con Ontopia - in grado di rappresentare concetti, relazioni e proprietà delle offerte formative e dei manifesti degli studi delle Università italiane;</li>
  <li>infine, non per importanza, sto cercando di portare Ontopia anche all’interno della PA in cui lavoro: ho progettato e implementato una piattaforma prototipo per la gestione della carta dei servizi, rendendola compliant allo standard europeo CPSV-AP nella sua declinazione italiana <a href="https://github.com/italia/daf-ontologie-vocabolari-controllati/tree/master/Ontologie/CPSV">CPSV-AP_IT</a> (<em>Core Public Service Vocabolary -  Application Profile Italy</em>) di Ontopia. Il prototipo è in grado di generare <em>al volo</em> lo schema RDF della carta dei servizi e di renderlo disponibile online per poter consentire in futuro l’<strong>harvesting</strong> dal portale <em>servizi.gov.it</em>. 
 La piattaforma è inoltre in grado di creare automaticamente i <strong>file .RST</strong> (<a href="https://it.wikipedia.org/wiki/ReStructuredText">reStructuredText</a>) necessari per generare automaticamente la documentazione tramite <a href="http://www.sphinx-doc.org/en/master/">SPHINX</a>, secondo le linee guida del progetto <a href="https://docs.italia.it/">Docs Italia</a> del Team per la Trasformazione Digitale. Ciò consentirà la pubblicazione automatica della carta dei servizi sul portale nazionale dei documenti pubblici digitali.
 Infine, la piattaforma è in grado di dialogare con un chatbot <a href="https://www.telegram.org/">Telegram</a> sia per ottenere le informazioni dei servizi pubblici sia per fruire di servizi di geolocalizzazione e indicazioni stradali dei servizi pubblici offline. 
 In futuro spero di poter condividere quest’esperienza di progetto attraverso i canali ufficiali della mia PA.</li>
</ul>

<p>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.</p>

<p>Molto di ciò che ho scritto l’ho potuto apprendere da Giorgia Lodi, esperta di tecnologie semantiche, professionista di altissima competenza, che ringrazio.</p>

<p>Per maggiori approfondimenti sul progetto Ontopia sono disponibili le seguenti risorse online, da cui sono stato fortemente ispirato.</p>

<ul>
  <li>[<strong>Homepage</strong>] - <a href="https://github.com/italia/daf-ontologie-vocabolari-controllati">Progetto Ontopia</a></li>
  <li>[<strong>Slide</strong>] - <a href="http://ods2018.opendatasicilia.it/presentazioni/Lodi-OntoPiA.pdf">G.Lodi - OntoPiA – la rete di ontologie e vocabolari controllati per la pubblica amministrazione</a></li>
  <li>[<strong>Webinar</strong>] - <a href="https://vimeo.com/282521928">G.Lodi OntoPiA - la rete di ontologie e vocabolari</a></li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Linked Data for a Better Web]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2018/07/27/linked-data-the-four-rules/"/>
    <updated>2018-07-27T01:40:08+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2018/07/27/linked-data-the-four-rules</id>
    <content type="html"><![CDATA[<p>In the previous Semantic Web posts [<a href="http://giovanni.pirrotta.it/blog/2013/05/24/semantic-web-what/" target="blank">1</a>,<a href="http://giovanni.pirrotta.it/blog/2013/06/03/limits-of-the-web-today/" target="blank">2</a>,<a href="http://giovanni.pirrotta.it/blog/2013/07/04/can-machines-think/" target="blank">3</a>,<a href="http://giovanni.pirrotta.it/blog/2013/11/20/xml-limits/" target="blank">4</a>,<a href="http://giovanni.pirrotta.it/blog/2013/12/23/the-rdf-model/" target="blank">5</a>,<a href="http://giovanni.pirrotta.it/blog/2014/01/06/semantic-web-ingredients-the-rdf-schema-model/" target="blank">6</a>,<a href="http://giovanni.pirrotta.it/blog/2014/07/22/semantic-web-ingredients-the-web-ontology-language/" target="blank">7</a>,<a href="http://giovanni.pirrotta.it/blog/2014/07/30/semantic-web-ingredients-rdfa/" target="blank">8</a>,<a href="http://giovanni.pirrotta.it/blog/2014/10/27/semantic-web-ingredients-the-sparql-language/" target="blank">9</a>,<a href="http://giovanni.pirrotta.it/blog/2015/10/18/developing-an-ontology/" target="blank">10</a>] I introduced tools, standards and languages to try to overcome the problem to integrate and reuse information between different applications. In this post I am going to describe a different way to present and share data on the Web, that, in recent years, played an important role in the development of Semantic Web applications concretely showing the benefits of semantic technologies.
In 2006, the  father of the HTML language and of the Semantic Web, <strong>Tim Berners–Lee</strong>, proposed a very simple way to publish structured data on the Web. The <strong>Linked Data</strong> era began!
<!--More--></p>

<p><img class="center-image" src="/images/linkeddata/linked_data.png" width="80%" /></p>

<p>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.</p>

<h3 id="linked-data-rules">Linked Data Rules</h3>

<p>The <a href="https://www.w3.org/DesignIssues/LinkedData.html" target="blank">Linked Data principles</a> recommend to:</p>

<ol>
  <li><em>Use URIs as names for things</em>;</li>
  <li><em>Use HTTP URIs so that people can look up those names</em>;</li>
  <li><em>When someone looks up a URI, provide useful information, using the standards</em>;</li>
  <li><em>Include links to other URIs, so that they can discover more things</em>.</li>
</ol>

<p>The basic principle of <strong>Linked Data</strong> 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 <strong>untyped</strong> meaningless links. Instead, the <a href="http://linkeddata.org" target="blank">Web of Data</a> 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 <strong>Linked Data principles</strong>, we define some terms that will help us go forward in this post.</p>

<p>As known, each <code class="highlighter-rouge">URL</code> is a particular type of <code class="highlighter-rouge">URI</code>, starting from <code class="highlighter-rouge">http:</code> string, defining the path to find a specific resource on the Web. The <code class="highlighter-rouge">http:</code> scheme of each URL also specifies the protocol used to access on the net through browsers; each URL address is then called <code class="highlighter-rouge">deferencable</code>  because it is relative to a resource on the Web retrievable through a well–known mechanism. Instead, putting in our browser URIs with <code class="highlighter-rouge">tag:</code> or <code class="highlighter-rouge">urn:</code> 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 <code class="highlighter-rouge">not deferencable</code>.</p>

<p>The <strong>first Linked Data rule</strong> 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.</p>

<p>The <strong>second rule</strong> proposes to use HTTP URIs so that people can look up those names. The reason of this is very simple. The <code class="highlighter-rouge">http://</code> 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.</p>

<p>The <strong>third Linked Data rule</strong> 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:</p>

<ul>
  <li><em>Information Resources</em>;</li>
  <li><em>Non-Information Resources</em>.</li>
</ul>

<p><em>Information resources</em> 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 <code class="highlighter-rouge">200 OK</code>.
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 <em>non–information resources.</em> 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 <code class="highlighter-rouge">303 See Other</code>. 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 <code class="highlighter-rouge">HTTP Accept header</code> of the HTTP client request, we can specify the <code class="highlighter-rouge">MIME type</code> 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 <code class="highlighter-rouge">Accept: text/html</code>, while for example, if we want to see the resource in an RDF browser, the attribute will be <code class="highlighter-rouge">Accept: application/rdf+xml</code>. 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.</p>

<p><img class="center-image" src="/images/linkeddata/rdf-content-negotiation.png" width="90%" /></p>

<p>Dereferenceable URIs can be constructed using two approaches preserving the implicit identity function.</p>

<ul>
  <li>
    <p><em>Hash approach</em>. In this case the URI is splitted into two parts separated by a hash symbol <code class="highlighter-rouge">#</code>. 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 <em>Dante Alighieri</em>, the URI could be: <code class="highlighter-rouge">http://example.org/poets.rdf#dalighieri</code>.
In the content negotiation mechanism, the part after the hash symbol will be removed and the server will return the <code class="highlighter-rouge">http://example.org/poets.rdf</code> URL within which we will find information about the <code class="highlighter-rouge">dalighieri</code> resource in RDF format.</p>
  </li>
  <li>
    <p><em>Slash approach</em>. In this case the non information resource is identified by the string following the last slash symbol <code class="highlighter-rouge">/</code>, and to deference this type of URI, as seen above, the <code class="highlighter-rouge">303 - See Other</code> negotiation mechanism is adopted in order to find the right resource representation. For example, using this approach to identify the person <em>Dante Alighieri</em>, the URI could be:
<code class="highlighter-rouge">http://example.org/dalighieri</code>. This resource does not exist in the server, then it sends a <code class="highlighter-rouge">303</code> redirect to client saying that information about that resource can be found in the <code class="highlighter-rouge">http://example.org/poets.rdf</code> file within which we will find information about the <code class="highlighter-rouge">dalighieri</code> resource in RDF format.</p>
  </li>
</ul>

<p>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.</p>

<h3 id="linked-open-data">Linked Open Data</h3>

<p>The <strong>fourth and last Linked Data rule</strong> 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.</p>

<p>In 2007, the W3C SWEO group proposed the <a href="http://linkeddata.org/" target="blank">Linking Open Data (LOD)</a> community project whose goal is to <em>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</em> (<a href="https://www.w3.org/DesignIssues/LinkedData.html" target="blank">link</a>)</p>

<p>In this project, some people embraced the Tim Berners–Lee rules and started to publish open data on the Web making interlinked datasets available.</p>

<p>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:</p>

<ul>
  <li><a href="https://wiki.dbpedia.org/" target="blank">DBpedia</a>: a dataset containing extracted data from Wikipedia; the DBpedia data set currently provides information about 4.58 million things (English version), including 1,445,000 persons, 735,000   places, 411,000 creative works (including 123,000 music albums, 87,000 films and 19,000 videogames), 241,000 organizations (including 58,000 companies and 49,000 educational institutions), 251,000 species and 6,000 diseases.
 It provides localized versions in 125 languages. Altogether, the DBpedia data set consists of (more than) 3 billion RDF triples (2014 statistics);</li>
  <li><a href="http://www.informatik.uni-trier.de/ ley/db/" target="blank">DBLP Bibliography</a>: provides bibliographic information about scientific papers; it contains about 800,000 articles, 400,000 authors, and approximately 15 million triples;</li>
  <li><a href="http://www.geonames.org/" target="blank">GeoNames</a>: provides RDF descriptions of geographical features worldwide.</li>
  <li><a href="http://revyu.com/" target="blank">Revyu</a>: a Review service that consumes and publishes Linked  Data, primarily from DBpedia.</li>
  <li><a href="http://www.foaf-project.org/" target="blank">FOAF</a>: a dataset describing persons, their properties and relationships.</li>
</ul>

<p>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:</p>

<p><img class="center-image" src="/images/linkeddata/lod_big2.png" width="80%" /></p>

<p>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.</p>

<p>That’s all folks! Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Protezione Civile POP: crea gli avvisi di allerta della tua città]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2018/05/17/protezione-civile-pop/"/>
    <updated>2018-05-17T01:40:08+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2018/05/17/protezione-civile-pop</id>
    <content type="html"><![CDATA[<p>Dal 5 marzo di quest’anno il <a href="http://www.protezionecivile.gov.it/" target="blank">Dipartimento della Protezione Civile</a> 
pubblica sul proprio <a href="http://www.protezionecivile.gov.it/jcms/it/bollettini_di_criticita.wp" target="blank">sito</a> i bollettini di criticità 
nazionale e di allerta in formato xml, shape, csv e pdf. <strong>C’è di più!</strong> Dopo circa un mese gli stessi dati sono stati rilasciati con licenza aperta, cioè riutilizzabili liberamente in altri contesti.
<!--More--></p>

<p>Già in un mio precedente <a href="http://giovanni.pirrotta.it/blog/2017/12/20/del-riutilizzo-dei-dati-meteo-ai-tempi-dei-borboni/" target="blank">post</a>
ho raccontato come aprire i dati della <a target="blank" href="http://www.regione.sicilia.it/presidenza/protezionecivile/">Protezione Civile</a> della Regione Siciliana 
a partire dai bollettini PDF che pubblicavano ogni giorno sul loro sito.</p>

<p><img class="center-image" src="/images/protezionecivilerss/bollettino.png" width="60%" /></p>

<p>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.</p>

<p>Stimolato anche dall’amico <a target="blank" href="https://twitter.com/aborruso">Andrea Borruso</a>, che già aveva scritto 
un <a href="http://blog.ondata.it/i-nuovi-bollettini-di-allerta-della-protezione-civile-sono-opendata/" target="blank">post</a> 
sulla pubblicazione di questi dati,</p>

<p><img class="center-image" src="/images/protezionecivilerss/borruso.png" width="60%" /></p>

<p>vediamo come ottenere una maggiore flessibilità e facilità di accesso.</p>

<p>Sin da subito, tuttavia, noto alcune criticità.</p>

<ul>
  <li>I link ai dati non sono univoci; una parte del link è costituita dal giorno di rilascio a cui vengono aggiunti 4 numeri random. Sarà l’orario di rilascio??? Non è dato sapere. 
Ne segue che per estrarre il link dovrò ricorrere allo <em>scraping</em>, purtroppo :-(</li>
  <li>I link ai vari formati disponibili (xml, pdf, shp) in realtà rimandano a un file <strong>zip</strong>, all’interno del quale si trovano i dati della protezione civile, che non è proprio
il massimo per accedere programmaticamente al dato.</li>
</ul>

<p>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à.</p>

<p>Uno dei modi più semplici e facili per accedere a dati su Webva è tramite <strong>API</strong> dedicate in formato <strong>JSON</strong>.</p>

<p>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.</p>

<p><img class="center-image" src="/images/protezionecivilerss/json.png" width="60%" /></p>

<p>Per la varietà di ambiti di applicazione, oltre al formato JSON, scelgo di esporre anche i dati in formato <strong>RSS</strong>.</p>

<p>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 <strong>feedreader</strong> è 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.</p>

<p>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 <a href="https://ifttt.com" target="blank">IFTTT</a>, 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.</p>

<p>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 <em>potenzialmente</em> realizzabili grazie al riutilizzo dei dati della Protezione Civile, riusabili perchè <strong>opendata</strong>.</p>

<p><img class="center-image" src="/images/protezionecivilerss/rss-to-social.png" width="80%" /></p>

<p>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:</p>

<ul>
  <li>le informazioni devono riferirsi alla città in cui vivo o di cui mi interessa sapere le previsioni;</li>
  <li>devo poter scegliere la tipologia di rischio (idraulico, idrogeologico e temporali) di cui mi interessano le informazioni;</li>
  <li>devo poter scegliere il livello minimo di allerta, tra verde, gialla, arancione e rossa (vedi figura);</li>
  <li>devo poter scegliere se mi interessano le previsioni del giorno corrente o del giorno successivo.</li>
</ul>

<p><img class="center-image" src="/images/protezionecivilerss/legenda.jpg" width="35%" /></p>

<p>Iniziamo dal primo punto.</p>

<p>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 <strong>156 zone di allerta</strong> (vedi figura) in cui è suddiviso il territorio italiano. Il documento viene pubblicato ogni giorno, di norma, alle 16.00.</p>

<p><img class="center-image" src="/images/protezionecivilerss/zone-italia.png" width="60%" /></p>

<p>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 <strong>python</strong>.</p>

<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="kn">import</span> <span class="nn">shapefile</span>
<span class="kn">from</span> <span class="nn">shapely.geometry</span> <span class="kn">import</span> <span class="n">Point</span> 
<span class="kn">from</span> <span class="nn">shapely.geometry</span> <span class="kn">import</span> <span class="n">shape</span> 
<span class="kn">import</span> <span class="nn">csv</span>

<span class="c"># Apro il formato shape dei dati</span>
<span class="n">shp</span> <span class="o">=</span> <span class="n">shapefile</span><span class="o">.</span><span class="n">Reader</span><span class="p">(</span><span class="s">'data/20180502_1615_today'</span><span class="p">)</span> 

<span class="c"># leggo tutti i poligoni</span>
<span class="n">all_shapes</span> <span class="o">=</span> <span class="n">shp</span><span class="o">.</span><span class="n">shapes</span><span class="p">()</span> 

<span class="c"># e tutte le informazioni associate ai poligoni</span>
<span class="n">all_records</span> <span class="o">=</span> <span class="n">shp</span><span class="o">.</span><span class="n">records</span><span class="p">()</span>

<span class="c"># ottengo il numero dei poligoni</span>
<span class="n">len_shapes</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">all_shapes</span><span class="p">)</span>

<span class="c"># inizializzo un file CSV in scrittura</span>
<span class="n">ofile</span>  <span class="o">=</span> <span class="nb">open</span><span class="p">(</span><span class="s">'comuni-con-zone.csv'</span><span class="p">,</span> <span class="s">"w"</span><span class="p">)</span>
<span class="n">writer</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">writer</span><span class="p">(</span><span class="n">ofile</span><span class="p">,</span> <span class="n">delimiter</span><span class="o">=</span><span class="s">','</span><span class="p">,</span> <span class="n">quotechar</span><span class="o">=</span><span class="s">'"'</span><span class="p">,</span> <span class="n">quoting</span><span class="o">=</span><span class="n">csv</span><span class="o">.</span><span class="n">QUOTE_NONNUMERIC</span><span class="p">)</span>

<span class="n">rownum</span> <span class="o">=</span> <span class="mi">0</span>

<span class="c"># il file comuni.csv contiene tutte le città italiane con le relative latitudini e longitudini</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">"comuni.csv"</span><span class="p">,</span> <span class="s">"r"</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
    <span class="n">reader</span> <span class="o">=</span> <span class="n">csv</span><span class="o">.</span><span class="n">reader</span><span class="p">(</span><span class="n">f</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">row</span> <span class="ow">in</span> <span class="n">reader</span><span class="p">:</span>
        
        <span class="c"># la prima riga la salto perchè è l'header</span>
        <span class="k">if</span> <span class="n">rownum</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
            <span class="n">header</span> <span class="o">=</span> <span class="n">row</span>
            <span class="n">header</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s">'zona_protezione_civile'</span><span class="p">)</span>
            <span class="n">writer</span><span class="o">.</span><span class="n">writerow</span><span class="p">(</span><span class="n">header</span><span class="p">)</span>
            <span class="n">rownum</span><span class="o">+=</span><span class="mi">1</span>
        <span class="k">else</span><span class="p">:</span>
            <span class="c"># per ogni città mi creo un oggetto Point a cui passo</span>
            <span class="c"># nel costruttore la latitudine e la longitudine</span>
            <span class="n">point</span> <span class="o">=</span> <span class="n">Point</span><span class="p">(</span><span class="nb">float</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">4</span><span class="p">]),</span> <span class="nb">float</span><span class="p">(</span><span class="n">row</span><span class="p">[</span><span class="mi">3</span><span class="p">]))</span>
            
            <span class="c"># devo capire dentro quale shape si trova il punto </span>
            <span class="c"># per cui ciclo su tutti i poligoni della protezione civile    </span>
            <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="n">len_shapes</span><span class="p">):</span>
                <span class="c"># leggo il poligono i-esimo</span>
                <span class="n">boundary</span> <span class="o">=</span> <span class="n">all_shapes</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> 
                
                <span class="c"># se il punto, cioè la città, si trova dentro il poligono</span>
                <span class="k">if</span> <span class="n">point</span><span class="o">.</span><span class="n">within</span><span class="p">(</span><span class="n">shape</span><span class="p">(</span><span class="n">boundary</span><span class="p">)):</span>  
                    <span class="c"># aggiungo la zona alla riga</span>
                    <span class="n">row</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">all_records</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="mi">0</span><span class="p">])</span>
                    <span class="c"># e la salvo in un nuovo file CSV</span>
                    <span class="n">writer</span><span class="o">.</span><span class="n">writerow</span><span class="p">(</span><span class="n">row</span><span class="p">)</span>
                    <span class="k">break</span>

</code></pre>
</div>
<p>Alla fine dello script verrà creato un nuovo file CSV chiamato <em>comuni-con-zone.csv</em> identico al file di partenza <em>comuni.csv</em> con in più la colonna <strong>zona</strong> della Protezione Civile per ogni città.</p>

<p><img class="center-image" src="/images/protezionecivilerss/csv-zone.png" width="80%" /></p>

<p>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 <em>job cron</em> che quotidianamente mi aggiornerà i dati del db.</p>

<p>La parte dell’applicazione relativa alla <em>data integration</em> è conclusa. Vediamo adesso come implementare la <strong>web-application</strong>.</p>

<p>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à.</p>

<p>Secondo i seguenti parametri API:</p>

<p><img class="center-image" src="/images/protezionecivilerss/parametri-api.png" /></p>

<p>Di seguito come appare l’interfaccia Web.</p>

<p><img class="center-image" src="/images/protezionecivilerss/protezionecivilepop2.png" /></p>

<p>La <strong>web-application</strong>, di fatto un configuratore delle API, è di utilizzo immediato.<br />
 Basta scegliere la città di interesse, il rischio, la soglia minima di allerta, il giorno di interesse, il formato e il gioco è fatto!</p>

<h3 id="flusso-json">Flusso JSON</h3>

<p><img class="center-image" src="/images/protezionecivilerss/json-output.png" /></p>

<p><img class="center-image" src="/images/protezionecivilerss/json-terme.png" /></p>

<h3 id="feed-rss">Feed RSS</h3>

<p><img class="center-image" src="/images/protezionecivilerss/rss-output.png" /></p>

<p><img class="center-image" src="/images/protezionecivilerss/rss-terme.png" /></p>

<p><strong>N.B.</strong> 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 <strong>arancione</strong>, il flusso conterrà eventuali allerte arancioni e rosse ma  non bianche e gialle.</p>

<p>L’applicazione si trova al seguente indirizzo:</p>

<p><a href="http://www.protezionecivilepop.tk" target="blank">Protezione Civile POP</a></p>

<p>Nei prossimi post vedremo come agganciare i feed RSS ad altri servizi esterni, come ad esempio Facebook, Twitter e Telegram.</p>

<p>Se questo progetto ti è piaciuto, mi aiuti a farlo conoscere con un 
<a href="http://twitter.com/share?url=http://www.protezionecivilepop.tk&amp;text=Protezione+Civile+POP+:+crea+gli+avvisi+di+allerta+della+tua+città+@gpirrotta">tweet</a>?</p>

<p>Per consigli, feedback, suggerimenti, bug potete inserire una <strong>issue</strong> su <a target="_blank" href="https://github.com/gpirrotta/protezionecivilepop/issues">questo repository</a>.</p>

<p>Grazie!</p>

<p>That’s all folks! Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[VisualCAD: la mappa interattiva della storia del CAD]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2018/02/09/visualcad-la-mappa-interattiva-della-storia-del-cad/"/>
    <updated>2018-02-09T01:40:08+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2018/02/09/visualcad-la-mappa-interattiva-della-storia-del-cad</id>
    <content type="html"><![CDATA[<p>Il Codice dell’Amministrazione Digitale (<strong>CAD</strong>) è il testo normativo di riferimento 
della pubblica amministrazione che disciplina il processo di digitalizzazione
dell’attività amministrativa.
Da più di un decennio il CAD, cioè il <a href="http://www.normattiva.it/uri-res/N2Ls?urn:nir:stato:decreto.legislativo:2005-03-07;82" target="blank">decreto legislativo n.82 del 7/3/2005</a>, viene sistematicamente
<em>bistrattato</em> a colpi di leggi, decreti legislativi e decreti legge, come un vestito continuamente rattoppato
 a suon di taglia e cuci, a discapito delle povere pubbliche amministrazioni che hanno il compito di attuare 
 le disposizioni normative.
Dal testo originario del 2005, tra piccole e grandi modifiche,
si sono succeduti ben 29 aggiornamenti.
Ad ogni aggiornamento, per poter leggere il testo coordinato, è necessario apportare all’ultima versione del CAD
tutte le modifiche previste dall’aggiornamento normativo.
Paragonando quest’operazione al mondo informatico, potremmo dire che l’operazione effettuata è un
 <strong>merge</strong> di un <em>fix</em> o di una nuova <em>feature</em> nella <strong>codebase</strong> di un software.</p>

<!--More-->
<p><img class="center-image" src="/images/visualcad/cad.jpg" width="60%" /></p>

<p>Ed è proprio da quest’idea di <em>merging</em> 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 <strong>Git</strong> ma anche <strong>Subversion</strong> o <strong>Mercurial</strong>, per tenere traccia di tutte le modifiche
che avvengono fra le versioni delle leggi.</p>

<p>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 <a href="https://github.com/bundestag/gesetze" target="blank">Bundes-Git</a> che
raccoglie in un repository <strong>git</strong> le leggi e i regolamenti federali tedeschi in <a href="https://it.wikipedia.org/wiki/Markdown" target="blank">markdown</a>,
cioè usando un formato in grado di migliorare la leggibilità e la fruibilità per gli utenti finali.</p>

<p>Anche in Italia, in occasione del referendum costituzionale del 2016, c’è stato chi
ha pensato bene di <a href="https://github.com/pmontrasio/costituzione" target="blank">versionare</a> 
la costituzione corrente con quella che sarebbe stata se fosse passato il referendum confermativo.</p>

<p>Ritornando al CAD, a fine gennaio avevo quindi intenzione di creare un repository <strong>git</strong> e caricare
tutte le versioni del CAD, naturalmente con <strong>commit</strong> diversi, per consentire sia la lettura 
del decreto legislativo  su piattaforme online di versionamento, come ad esempio
<a target="blank" href="https://www.github.com">github</a>,
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.</p>

<p>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 <strong>normattiva.it</strong> e di creare
un file JSON con <em>capi</em>, <em>sezioni</em>, <em>articoli</em>, <em>versioni</em>, <em>testi</em>, <em>aggiornamenti</em>, <em>vigenze</em>,
<em>riferimenti normativi</em> del CAD.</p>

<p>Il file estratto lo potete trovare <a target="blank" href="http://giovanni.pirrotta.it/images/cad_scraped.json">qui</a>.</p>

<p>Era fine gennaio dicevo (<em>cioè due settimane fa</em>), 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.</p>

<p><img class="center-image" src="/images/visualcad/tweet.png" width="60%" /></p>

<p>Il <a href="https://twitter.com/teamdigitaleIT" target="blank">team digitale</a> di <a href="https://twitter.com/diegopia" target="blank">Diego Piacentini</a> 
carica su <a href="" target="blank">github</a> tutte le versioni del CAD andando
a realizzare <strong>esattamente</strong> quello che avevo in mente io. Non solo. Rilasciano il CAD
in formato <a href="https://it.wikipedia.org/wiki/ReStructuredText" target="blank">reStrucredText</a>, 
collegano il repository al servizio di documentazione online 
<a href="https://readthedocs.org/" target="blank">readthedocs</a>
migliorando  di molto l’esperienza di leggibilità, con in più la possibilità
 di confrontare le versioni, articolo per articolo, direttamente su 
 <a href="https://github.com/italia/cad-docs/compare/v2016-08-26...v2017-12-13" target="blank">github</a>.</p>

<p><em>Questa la mia reazione</em></p>

<p><img class="center-image" src="/images/visualcad/cereal.png" width="40%" /></p>

<p><em>M’avete fregato sul tempo…A Piacentì, A Team Digitale…‘ve possino!!!</em>  <strong>se scherza eh ;-)</strong></p>

<p>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.</p>

<p>Giro un pò in rete per prendere ispirazione su progetti di mappe e mi innamoro di quello realizzato nel 2012  da
<a href="http://driven-by-data.net/" target="blank">Gregor Aisch</a> (CTO di datawrapper) per le 
<a href="http://visualisiert.net/parteiengesetz/" target="blank"> leggi tedesche</a>.</p>

<p>Decido quindi di riusarlo, estenderlo ed adattarlo al CAD.</p>

<p>Invece di partire però dal file JSON estratto con lo scraper, i cui dati non sono opendata ma
sono <a href="http://www.normattiva.it/static/legal.html" target="blank">licenziati</a> in modo da non consentirne il riuso per fini commerciali, 
decido di riutilizzare invece i dati del <strong>team-digitale</strong>, che sono invece opendata licenziati dalla bellissima <a href="https://creativecommons.org/publicdomain/zero/1.0/" target="blank">CC0</a>.</p>

<p>Nasce quindi il progetto <strong>VisualCAD</strong>, 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.</p>

<p><img class="center-image" src="/images/visualcad/visualcad-big.png" width="100%" /></p>

<p>Dalla prima versione del 2005 si sono succeduti ben <strong>29 aggiornamenti</strong> e in 
 <strong>VisualCAD</strong> 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.</p>

<p><img class="center-image" src="/images/visualcad/legenda.png" width="80%" /></p>

<p>Dalla tendina è possibile selezionare ciascun articolo per ricostruire tutto l’iter di modifiche subito dallo
stesso dalla prima versione sino all’ultima.</p>

<p><img class="center-image" src="/images/visualcad/singoloiter.png" width="100%" /></p>

<p>E’ inoltre possibile effettuare ricerche testuali nel titolo degli articoli inserendo del testo libero nel form relativo.</p>

<p>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.</p>

<p><img class="center-image" src="/images/visualcad/articolomodificato.png" width="50%" /></p>

<p>Cliccando su ciascun quadratino è possibile infine visualizzare l’intero corpo dell’articolo e, cliccando sull’apposito pulsantino, evidenziare
 il testo modificato.</p>

<p><img class="center-image" src="/images/visualcad/modal.png" width="60%" /></p>

<p>L’obiettivo è stato raggiunto.</p>

<p>In un’unica schermata è possibile navigare tutto il CAD con tutti i suoi aggiornamenti, in modo semplice, interattivo
e fruibile da qualsiasi cittadino.</p>

<p>L’evoluzione di questo progetto potrebbe essere la creazione di nuove mappe per altre leggi partendo ad esempio dal file JSON <em>scrapato</em>,
in attesa che <em>normattiva</em> licenzi i dati in <strong>opendata</strong> e rilasci delle API per interrogare l’archivio delle leggi in modo flessibile.
Sogno o utopia?</p>

<p>Ritornando al progetto, questo è il <a href="http://www.visualcad.it" target="blank">sito</a> di riferimento di VisualCAD.
All’apertura potreste attendere un pò di secondi perchè i dati da caricare sono tanti.</p>

<p>Se questo progetto vi è piaciuto, mi aiutate a farlo conoscere con un 
<a href="http://twitter.com/share?url=http://www.visualcad.it&amp;text=VisualCAD+-+la+mappa+online+e+interattiva+della+storia+del+CAD.+Perchè+anche+l'occhio+vuole+la+sua+parte!+@gpirrotta">tweet</a>? 
Grazie!</p>

<p>E comunque, a parte gli scherzi,  <strong>grazie</strong> mille a tutta la squadra del Team Digitale!</p>

<p>Commenti, critiche e suggerimenti sono i benvenuti!</p>

<p>That’s all folks! Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Del riutilizzo dei dati meteo ai tempi dei Borboni]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2017/12/20/del-riutilizzo-dei-dati-meteo-ai-tempi-dei-borboni/"/>
    <updated>2017-12-20T01:40:08+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2017/12/20/del-riutilizzo-dei-dati-meteo-ai-tempi-dei-borboni</id>
    <content type="html"><![CDATA[<p>Tutto ebbe inizio un giorno quando, di buon mattino, in un vecchio baule antico della mia soffitta, ritrovai un vecchio manoscritto
di racconti intitolato “<em>Digital Fabulas</em>”, la cui prima pagina recitava:</p>

<blockquote>
  <p><em>Questa è la storia di <strong>Ioan Pairot</strong>, squattrinato maniscalco siciliano, che ebbe la cattiva sorte
di vivere secoli or sono alla corte di un potente signorotto palermitano.</em></p>
</blockquote>

<p>Il primo dei racconti iniziava così:</p>

<p><em>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.</em>
  <em>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.</em></p>

<!--More-->

<p><img class="center-image" src="/images/protezionecivile/sicilia-storica.jpg" width="60%" /></p>

<p><strong>Per una migliore comprensione del racconto d’ora in avanti tradurrò la storia in lingua moderna.</strong></p>

<hr />

<h4 id="dal-diario-di-ioan-pairot">Dal diario di Ioan Pairot</h4>

<p>[…] Il conte Andreas mi informò che la Protezione Civile siciliana pubblicava quotidinamente, sul proprio situs ipertestuales (<em>oggi lo chiameremmo sito o pagina Web</em>),
il dispaccio delle allerte dei rischi idrogeologici (<em>oggi lo chiameremmo report o bollettino</em>) dell’intera regione in un formato file chiamato <strong>OCD</strong> (<em>oggi lo chiameremmo PDF</em>).
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.</p>

<p>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…<strong>Eureka</strong>…  trovai la soluzione.</p>

<p>In questo diario descriverò il dettaglio tecnico.</p>

<p>Ogni giorno la Protezione Civile siciliana pubblicava su questa <a target="_blank" href="http://www.regione.sicilia.it/presidenza/protezionecivile/pp/archivio_idro.asp">pagina Web</a>
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.</p>

<p><img class="center-image" src="/images/protezionecivile/bollettino.png" width="90%" /></p>

<p>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:</p>

<p><img class="center-image" src="/images/protezionecivile/livelli-allerta.png" width="70%" /></p>

<p>Il bollettino veniva pubblicato in <strong>PDF</strong> per cui le informazioni rimanevano confinate nel file precludendo la possibilità di
riutilizzare gli stessi dati in contesti differenti da quello originale.</p>

<p>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 <strong>aprire</strong> e <strong>riusare</strong> i dati <em>ingabbiati</em> nel PDF avevo bisogno di <em>grattare</em> i colori di ogni zona al di fuori del file. 
Dovevo stabilire un insieme di passi (<em>oggi lo chiameremmo algoritmo</em>) in grado di riconoscere i colori delle mappe, in modo automatico e puntuale,
al fine di risalire al colore di ogni singolo elemento grafico (<em>oggi lo chiameremmo pixel</em>) presente in ciascuna zona della mappa.</p>

<p>Vediamo i singoli passi</p>

<p>Sul sito della Protezione Civile era presente una pagina con l’elenco di tutti i bollettini meteo e disponibile al seguente URL</p>

<p><a target="_blank" href="http://www.regione.sicilia.it/presidenza/protezionecivile/pp/archivio_idro.asp">http://www.regione.sicilia.it/presidenza/protezionecivile/pp/archivio_idro.asp</a></p>

<p><img class="center-image" src="/images/protezionecivile/elenco-report.png" width="90%" /></p>

<p>Il primo link dell’elenco rappresentava l’ultimo bollettino pubblicato dalla Protezione Civile.
Per estrarre tale link ho utilizzato la libreria <a href="https://www.crummy.com/software/BeautifulSoup/"><em>BeautifulSoup</em></a>, ormai lo standard de-facto per lo scraping Web in <strong>Angus</strong> (<em>oggi lo chiameremmo Python</em>).
Di seguito la prima parte del <strong>fons</strong> (<em>oggi lo chiameremo codice sorgente</em>):</p>

<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="n">url</span> <span class="o">=</span> <span class="s">'http://www.regione.sicilia.it/presidenza/protezionecivile/pp/archivio_idro.asp'</span>

<span class="n">r</span> <span class="o">=</span> <span class="n">requests</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">url</span><span class="p">)</span>

<span class="n">html</span> <span class="o">=</span> <span class="n">r</span><span class="o">.</span><span class="n">text</span>
<span class="n">soup</span> <span class="o">=</span> <span class="n">BeautifulSoup</span><span class="p">(</span><span class="n">html</span><span class="p">,</span> <span class="s">'lxml'</span><span class="p">)</span>
 
<span class="n">pattern</span> <span class="o">=</span> <span class="s">'Avviso rischio idrogeologico per il (.*)'</span>
<span class="n">first_row</span> <span class="o">=</span> <span class="n">soup</span><span class="o">.</span><span class="n">find</span><span class="p">(</span><span class="s">'td'</span><span class="p">,{</span><span class="s">'class'</span><span class="p">:</span><span class="s">'testo_tabelle_cent'</span><span class="p">})</span>
<span class="n">text</span> <span class="o">=</span> <span class="n">first_row</span><span class="o">.</span><span class="n">text</span>
<span class="n">m</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">match</span><span class="p">(</span><span class="n">pattern</span><span class="p">,</span><span class="n">text</span><span class="p">)</span>
<span class="k">if</span> <span class="n">m</span><span class="p">:</span>
    <span class="n">primo_giorno_text</span> <span class="o">=</span> <span class="p">(</span><span class="n">m</span><span class="o">.</span><span class="n">group</span><span class="p">(</span><span class="mi">1</span><span class="p">))</span>
    <span class="n">primo_giorno</span> <span class="o">=</span> <span class="n">datetime</span><span class="o">.</span><span class="n">datetime</span><span class="o">.</span><span class="n">strptime</span><span class="p">(</span><span class="n">primo_giorno_text</span><span class="p">,</span> <span class="s">'</span><span class="si">%</span><span class="s">d/</span><span class="si">%</span><span class="s">m/</span><span class="si">%</span><span class="s">Y'</span><span class="p">)</span>
    <span class="n">secondo_giorno</span> <span class="o">=</span> <span class="n">primo_giorno</span> <span class="o">+</span> <span class="n">datetime</span><span class="o">.</span><span class="n">timedelta</span><span class="p">(</span><span class="n">days</span><span class="o">=+</span><span class="mi">1</span><span class="p">)</span>
    <span class="n">secondo_giorno_text</span> <span class="o">=</span> <span class="n">secondo_giorno</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s">"</span><span class="si">%</span><span class="s">d/</span><span class="si">%</span><span class="s">m/</span><span class="si">%</span><span class="s">Y"</span><span class="p">)</span>
    
<span class="k">if</span> <span class="n">first_row</span><span class="o">.</span><span class="n">a</span><span class="p">:</span>
    <span class="n">link</span> <span class="o">=</span> <span class="n">first_row</span><span class="o">.</span><span class="n">a</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'href'</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">link</span><span class="p">:</span>
        <span class="n">href</span> <span class="o">=</span> <span class="n">link</span><span class="p">[</span><span class="mi">3</span><span class="p">:]</span>
</code></pre>
</div>

<p>A questo punto <strong>href</strong> conterrà il link (<em>relativo</em>) del bollettino della Protezione Civile.</p>

<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="n">WEB_ROOT_URL</span> <span class="o">=</span> <span class="s">'http://www.regione.sicilia.it/presidenza/protezionecivile/'</span>
<span class="n">full_url</span> <span class="o">=</span>  <span class="n">WEB_ROOT_URL</span> <span class="o">+</span> <span class="n">href</span>
<span class="n">file_pdf</span> <span class="o">=</span> <span class="s">'protezione-civile.pdf'</span>
<span class="n">wget_cmd</span> <span class="o">=</span> <span class="s">'wget -O '</span> <span class="o">+</span> <span class="n">file_pdf</span> <span class="o">+</span> <span class="s">' "'</span> <span class="o">+</span><span class="n">full_url</span> <span class="o">+</span> <span class="s">'"'</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">wget_cmd</span><span class="p">)</span>
</code></pre>
</div>

<p>L’algoritmo prosegue con lo <strong>scaricamento</strong> del file (oggi lo chiameremmo <em>download</em>), attraverso il comando shell  <strong>wget</strong>, invocato 
da python, grazie al quale otteniamo il trasferimento del PDF in locale sul mio <strong>calculator</strong> (<em>oggi lo chiameremmo server</em>).</p>

<p>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.</p>

<p><img class="center-image" src="/images/protezionecivile/mumble-meme.jpg" width="30%" /></p>

<p>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 <strong>convertire</strong> 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.</p>

<p>Attraverso il tool <strong>convert</strong> di <a href="http://www.imagemagick.org/script/index.php"><strong>ImageMagick</strong></a> ho convertito quindi 
la prima pagina del bollettino PDF in formato immagine <strong>PNG</strong>  nel seguente modo:</p>

<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="n">file_png</span> <span class="o">=</span> <span class="s">'protezione-civile.png'</span>
<span class="n">file_pdf</span> <span class="o">=</span> <span class="s">'protezione-civile.pdf'</span>
<span class="n">cmd</span> <span class="o">=</span> <span class="s">'convert '</span><span class="o">+</span> <span class="n">file_pdf</span> <span class="o">+</span> <span class="s">'[0] '</span> <span class="o">+</span> <span class="n">file_png</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">cmd</span><span class="p">)</span>    
</code></pre>
</div>

<p>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.</p>

<p><img class="center-image" src="/images/protezionecivile/mappe-frecce.png" width="90%" /></p>

<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="n">pixel_sicilia_zone_primo_giorno</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="s">'A'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">262</span><span class="p">,</span><span class="mi">174</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="s">'B'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">182</span><span class="p">,</span> <span class="mi">188</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="s">'C'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">105</span><span class="p">,</span> <span class="mi">186</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="s">'D'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">106</span><span class="p">,</span> <span class="mi">208</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="s">'E'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">170</span><span class="p">,</span> <span class="mi">230</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="s">'F'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">219</span><span class="p">,</span> <span class="mi">269</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="s">'G'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">248</span><span class="p">,</span> <span class="mi">266</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="s">'H'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">222</span><span class="p">,</span> <span class="mi">216</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="s">'I'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">246</span><span class="p">,</span> <span class="mi">202</span><span class="p">]</span>

<span class="n">pixel_sicilia_zone_secondo_giorno</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="s">'A'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">520</span><span class="p">,</span><span class="mi">174</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="s">'B'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">438</span><span class="p">,</span> <span class="mi">188</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="s">'C'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">364</span><span class="p">,</span> <span class="mi">186</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="s">'D'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">364</span><span class="p">,</span> <span class="mi">209</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="s">'E'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">431</span><span class="p">,</span> <span class="mi">230</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="s">'F'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">477</span><span class="p">,</span> <span class="mi">268</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="s">'G'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">506</span><span class="p">,</span> <span class="mi">265</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="s">'H'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">480</span><span class="p">,</span> <span class="mi">216</span><span class="p">]</span>
<span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="s">'I'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[</span><span class="mi">504</span><span class="p">,</span> <span class="mi">202</span><span class="p">]</span>
</code></pre>
</div>

<p>Utilizzando le librerie <a target="_blank" href="https://python-pillow.org/">Pillow</a> è possibile ottenere informazioni sui singoli pixel delle immagini.</p>

<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="n">image</span> <span class="o">=</span>  <span class="n">Image</span><span class="o">.</span><span class="nb">open</span><span class="p">(</span><span class="n">file_png</span><span class="p">)</span>
<span class="n">pixel</span> <span class="o">=</span> <span class="n">image</span><span class="o">.</span><span class="n">getpixel</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">j</span><span class="p">)</span>
</code></pre>
</div>

<p>La funzione <em>getPixel()</em>, passando in input la posizione di un pixel, restituisce un vettore contenente la triade delle componenti
dei colori primari nella forma <a target="blank" href="https://it.wikipedia.org/wiki/RGB"><strong>RGB</strong></a> (red, green, blue), grazie alla quale è possibile risalire al colore del pixel desiderato.</p>

<p><img class="center-image" src="/images/protezionecivile/rgb.png" width="30%" /></p>

<p>In base ai valori delle componenti di ciascun colore è possibile adesso ottenere il livello di allerta della zona interessata.</p>

<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="k">def</span> <span class="nf">get_allerta</span><span class="p">(</span><span class="n">r</span><span class="p">,</span><span class="n">g</span><span class="p">,</span><span class="n">b</span><span class="p">):</span>
    <span class="k">if</span> <span class="n">r</span> <span class="o">==</span> <span class="mi">0</span> <span class="ow">and</span> <span class="n">g</span> <span class="o">==</span> <span class="mi">255</span> <span class="ow">and</span> <span class="n">b</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="s">'ALLERTA VERDE - GENERICA VIGILANZA'</span>
    <span class="k">elif</span> <span class="n">r</span> <span class="o">==</span> <span class="mi">255</span> <span class="ow">and</span> <span class="n">g</span> <span class="o">==</span> <span class="mi">255</span> <span class="ow">and</span> <span class="n">b</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="s">'ALLERTA GIALLA - ATTENZIONE'</span>
    <span class="k">elif</span> <span class="n">r</span> <span class="o">==</span> <span class="mi">255</span> <span class="ow">and</span> <span class="n">g</span> <span class="o">==</span> <span class="mi">204</span> <span class="ow">and</span> <span class="n">b</span> <span class="o">==</span> <span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="s">'ALLERTA ARANCIONE - PREALLARME'</span>
    <span class="k">elif</span> <span class="n">r</span> <span class="o">==</span> <span class="mi">255</span> <span class="ow">and</span> <span class="n">g</span> <span class="o">==</span><span class="mi">0</span> <span class="ow">and</span> <span class="n">b</span><span class="o">==</span><span class="mi">0</span><span class="p">:</span>
        <span class="k">return</span> <span class="s">'ALLERTA ROSSA - ALLARME'</span>
    <span class="k">else</span><span class="p">:</span>
        <span class="k">return</span> <span class="s">''</span>
</code></pre>
</div>

<p>Ad esempio, la triade (0,255,0), corrisponde al colore <strong>VERDE</strong>, la triade (255,0,0) corrisponde al colore <strong>ROSSO</strong>
e così via.</p>

<p>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.</p>

<div class="language-python highlighter-rouge"><pre class="highlight"><code><span class="n">previsioni</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">previsioni</span><span class="p">[</span><span class="s">'fonte'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'Regione Siciliana - Dipartimento della Protezione Civile'</span>
<span class="n">previsioni</span><span class="p">[</span><span class="s">'allerta_meteo'</span><span class="p">]</span> <span class="o">=</span> <span class="p">{}</span>
<span class="n">previsioni</span><span class="p">[</span><span class="s">'allerta_meteo'</span><span class="p">][</span><span class="s">'date'</span><span class="p">]</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">previsioni</span><span class="p">[</span><span class="s">'allerta_meteo'</span><span class="p">][</span><span class="s">'url'</span><span class="p">]</span> <span class="o">=</span> <span class="n">full_url</span><span class="o">.</span><span class="n">replace</span><span class="p">(</span><span class="s">' '</span><span class="p">,</span> <span class="s">'</span><span class="si">%20</span><span class="s">'</span><span class="p">)</span>

<span class="n">prev</span> <span class="o">=</span> <span class="n">collections</span><span class="o">.</span><span class="n">OrderedDict</span><span class="p">()</span>
<span class="n">prev</span><span class="p">[</span><span class="n">primo_giorno_text</span><span class="p">]</span> <span class="o">=</span> <span class="n">collections</span><span class="o">.</span><span class="n">OrderedDict</span><span class="p">()</span>
<span class="n">prev</span><span class="p">[</span><span class="n">secondo_giorno_text</span><span class="p">]</span> <span class="o">=</span> <span class="n">collections</span><span class="o">.</span><span class="n">OrderedDict</span><span class="p">()</span>

<span class="k">for</span> <span class="n">zona</span> <span class="ow">in</span> <span class="p">[</span><span class="s">'A'</span><span class="p">,</span><span class="s">'B'</span><span class="p">,</span><span class="s">'C'</span><span class="p">,</span><span class="s">'D'</span><span class="p">,</span><span class="s">'E'</span><span class="p">,</span><span class="s">'F'</span><span class="p">,</span><span class="s">'G'</span><span class="p">,</span><span class="s">'H'</span><span class="p">,</span><span class="s">'I'</span><span class="p">]:</span>
  <span class="n">rgb</span> <span class="o">=</span> <span class="n">get_pixel</span><span class="p">(</span><span class="n">picture</span><span class="p">,</span> <span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="n">zona</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">pixel_sicilia_zone_primo_giorno</span><span class="p">[</span><span class="n">zona</span><span class="p">][</span><span class="mi">1</span><span class="p">])</span>
  <span class="n">allerta</span> <span class="o">=</span> <span class="n">get_allerta</span><span class="p">(</span><span class="n">rgb</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">rgb</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">rgb</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
  <span class="n">prev</span><span class="p">[</span><span class="n">primo_giorno_text</span><span class="p">][</span><span class="s">'ZONA '</span> <span class="o">+</span> <span class="n">zona</span><span class="p">]</span><span class="o">=</span> <span class="n">allerta</span>

<span class="k">for</span> <span class="n">zona</span> <span class="ow">in</span> <span class="p">[</span><span class="s">'A'</span><span class="p">,</span><span class="s">'B'</span><span class="p">,</span><span class="s">'C'</span><span class="p">,</span><span class="s">'D'</span><span class="p">,</span><span class="s">'E'</span><span class="p">,</span><span class="s">'F'</span><span class="p">,</span><span class="s">'G'</span><span class="p">,</span><span class="s">'H'</span><span class="p">,</span><span class="s">'I'</span><span class="p">]:</span>
  <span class="n">rgb</span> <span class="o">=</span> <span class="n">get_pixel</span><span class="p">(</span><span class="n">picture</span><span class="p">,</span> <span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="n">zona</span><span class="p">][</span><span class="mi">0</span><span class="p">],</span> <span class="n">pixel_sicilia_zone_secondo_giorno</span><span class="p">[</span><span class="n">zona</span><span class="p">][</span><span class="mi">1</span><span class="p">])</span>
  <span class="n">allerta</span> <span class="o">=</span> <span class="n">get_allerta</span><span class="p">(</span><span class="n">rgb</span><span class="p">[</span><span class="mi">0</span><span class="p">],</span> <span class="n">rgb</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">rgb</span><span class="p">[</span><span class="mi">2</span><span class="p">])</span>
  <span class="n">prev</span><span class="p">[</span><span class="n">secondo_giorno_text</span><span class="p">][</span><span class="s">'ZONA '</span> <span class="o">+</span> <span class="n">zona</span><span class="p">]</span><span class="o">=</span> <span class="n">allerta</span>

<span class="n">previsioni</span><span class="p">[</span><span class="s">'allerta_meteo'</span><span class="p">][</span><span class="s">'date'</span><span class="p">]</span> <span class="o">=</span> <span class="n">prev</span>

<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s">'allerta.json'</span><span class="p">,</span> <span class="s">'w'</span><span class="p">)</span> <span class="k">as</span> <span class="n">f</span><span class="p">:</span>
  <span class="n">json</span><span class="o">.</span><span class="n">dump</span><span class="p">(</span><span class="n">previsioni</span><span class="p">,</span> <span class="n">f</span><span class="p">,</span> <span class="n">ensure_ascii</span><span class="o">=</span><span class="bp">False</span><span class="p">)</span>

<span class="n">move_cmd</span> <span class="o">=</span> <span class="s">'mv allerta.json ../../gpirrotta.tk/regione-siciliana/protezione-civile/allerta.json'</span>
<span class="n">os</span><span class="o">.</span><span class="n">system</span><span class="p">(</span><span class="n">move_cmd</span><span class="p">)</span>    
</code></pre>
</div>

<p>Tale codice sorgente è stato quindi fatto eseguire una volta al giorno dai <strong>vigilantes</strong> del conte (che oggi chiameremmo <em>cron</em>)
al fine di produrre il seguente output:</p>

<p><img class="center-image" src="/images/protezionecivile/json.png" width="90%" /></p>

<blockquote>
  <p>[…] 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…</p>
</blockquote>

<blockquote>
  <p>E c’è chi dice di aver sentito il conte, adesso lui in preda ad incubi notturni, accennar sibilante insolite parole… <strong>xml</strong>…<strong>RSS</strong>…<strong>POP</strong>.</p>
</blockquote>

<blockquote>
  <p><em>Nessuno seppe però mai cosa intendesse dire, tra veglie, convulsioni e tormenti, con quegli strani e indecifrabili farfugliamenti…</em></p>
</blockquote>

<blockquote>
  <p><strong>Ioan Pairot</strong></p>
</blockquote>

<p><strong>P.S.</strong> <em>Non so se in futuro il servizio rimarrà sempre attivo, ma se così sarà i posteri lo potranno trovare al seguente <a target="blank" href="http://www.gpirrotta.tk/regione-siciliana/protezione-civile/allerta.json">URL</a></em>.
E il codice sorgente  <a target="_blank" href="https://gist.github.com/gpirrotta/43697a050dfc1e5807a43f72aa1ae32d">qui</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[FoiaPop: accesso civico data-driven]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2017/07/04/foiapop-accesso-civico-data-driven/"/>
    <updated>2017-07-04T01:40:08+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2017/07/04/foiapop-accesso-civico-data-driven</id>
    <content type="html"><![CDATA[<p>Ritorno a scrivere in questo blog, dopo molto tempo, su un tema a me molto caro e cioè l’utilizzo degli opendata come <strong>strumento</strong> per facilitare 
processi inerenti la trasparenza e la diffusione di informazioni da parte delle pubbliche amministrazioni.</p>

<p>Subito dopo il raduno di <a target="_blank" href="http://ods16.opendatasicilia.it">Opendata Sicilia 2016</a>, 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,
 è <strong>carburante</strong> prezioso per modelli di economie <em>data-based.</em></p>

<!--More-->

<p>Lo sanno bene alcune startup come <a target="_blank" href="https://synapta.it/">Synapta</a> 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.</p>

<p>Nel settore pubblico, invece, è da menzionare il progetto <a target="_blank" href="http://soldipubblici.gov.it/it/home">soldipubblici</a> che, a partire dagli opendata relativi alle spese delle pubbliche amministrazioni,
disponibili su <a target="_blank" href="http://www.siope.it">SIOPE</a>, 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. <em>A causa del cambio di codifica SIOPE, purtroppo, il servizio è momentaneamente non disponibile</em>.</p>

<p>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 <em>parare</em> :-) .</p>

<p><img class="center-image" src="/images/foiapop/mumble-meme.jpg" width="30%" /></p>

<p>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.</p>

<p>Avevo bisogno di parlare con <a target="_blank" href="https://www.twitter.com/giuragu">Giuseppe Ragusa</a></p>

<p>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 <a target="_blank" href="http://opendatasicilia.it/2015/07/27/anac-e-indice-pa-i-dati-sugli-enti-non-tornano/">post</a>, che vi invito a leggere.</p>

<p>Era l’uomo che cercavo!</p>

<p>Ci siamo dati appuntamento un giorno di gennaio e via <em>hangout</em> 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 <strong>FOIA</strong>.</p>

<p><em>Disclaimer</em><br />
<em>Non sono un giurista per cui mi scuso in anticipo per ogni imprecisione giuridica riscontrata nel proseguio del post</em></p>

<p>Il <strong>FOIA</strong>, acronimo di <em>Freedom of Information Act è una legge sulla libertà di informazione, emanata negli Stati Uniti il 4 luglio 1966</em>
 (<a href="https://it.wikipedia.org/wiki/Freedom_of_Information_Act">Wikipedia</a>).</p>

<p>L’Italia ha recentemente introdotto uno strumento giuridico, chiamato <em>accesso civico generalizzato</em>, 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.</p>

<p>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 <em>accesso civico semplice</em>.
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 
<a target="blank" href="http://www.normattiva.it/uri-res/N2Ls?urn:nir:stato:decreto.legislativo:2013-03-14;33!vig=">D.Lgs 33/2013</a>.
Ogni pubblica amministrazione deve pubblicare sul proprio sito istituzionale, nella sezione <strong>Amministrazione Trasparente</strong>, 
un insieme di <a href="http://www.anticorruzione.it/portal/public/classic/AttivitaAutorita/AttiDellAutorita/_Atto?ca=6667">informazioni</a>.
Qualora il cittadino non trovi pubblicata una (o più) di queste informazioni può esercitare il diritto di 
<em>accesso civico semplice</em>, chiedendo alla P.A. la pubblicazione dei documenti mancanti.</p>

<p>Da segnalare lo strumento online <a href="http://bussola.magellanopa.it/il-progetto.html">Bussola della Trasparenza</a>, 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 <a href="http://bussola.magellanopa.it/open-data.html">opendata</a>.</p>

<p>Ritornando al brainstorming con Giuseppe, alla fine del confronto sono emerse le seguenti osservazioni/preoccupazioni:</p>

<ul>
  <li>i cittadini <strong>non conoscono</strong> il diritto di accesso civico, nè quello semplice nè quello generalizzato (FOIA);</li>
  <li>i cittadini più informati (pochi) spesso non sanno da dove partire, <strong>non hanno</strong> quindi gli strumenti per poter definire e portare a termine
una richiesta di accesso ai dati, documenti e informazioni;</li>
  <li>le manifestazioni più importanti all’interno di una PA sono quelle su cui <strong>ruotano i flussi monetari</strong> e cioè i pagamenti, gli incassi, gli appalti, etc.</li>
</ul>

<p>E’ emerso un vuoto da colmare e, sulla scia del nome del progetto <a target="blank" href="http://albopop.it/">albopop</a>, propongo di chiamare questo vuoto <strong>FOIAPOP</strong>.</p>

<h2 id="foiapop">FOIAPOP</h2>

<p><img class="center-image" src="/images/foiapop/homepage.png" width="60%" /></p>

<p><strong>FoiaPop</strong> 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.</p>

<p>Grazie al riutilizzo degli opendata relativi alle basi informative IPA, SIOPE, e AVCP/ANAC, l’utente può formulare le <em>richieste di accesso civico generalizzato</em>
semplicemente cliccando sulle voci di spese, incassi o contratti pubblici.</p>

<p>Allo stesso modo, sfruttando gli opendata relativi ai dati IPA, Obblighi ANAC e Bussola della Trasparenza, l’utente può compilare online la richiesta
di <em>accesso civico semplice</em> per richiedere la pubblicazione di documenti obbligatori non presenti in Amministrazione Trasparente della Pubblica Amministrazione.</p>

<p>Vediamo adesso nel dettaglio il funzionamento della piattaforma descrivendo il workflow utilizzato da FoiaPop per il suo funzionamento.</p>

<p><img class="center-image" src="/images/foiapop/workflow.png?t=dfdf" width="80%" /></p>

<p>Con FoiaPop è possibile <strong>selezionare</strong> una qualsiasi pubblica amministrazione italiana (più di 20.000), <strong>compilare</strong>
una richiesta di accesso civico in modo semplice e, in pochi click, <strong>generare</strong> il modulo compilato in PDF da trasmettere 
alla pubblica amministrazione.</p>

<p><strong>FoiaPop</strong> è <em>ente-centrico</em>, 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 <a href="http://www.indicepa.gov.it/documentale/n-opendata.php">IPA</a>.</p>

<p>Inseriamo il nome della pubblica amministrazione di nostro interesse nell’apposito modulo di ricerca. 
Cerchiamo il termine <strong>Caltanissetta</strong> e scegliamo, tra i vari enti possibili, il <strong>comune di Caltanissetta</strong>.</p>

<p><img class="center-image" src="/images/foiapop/caltanissetta.png" width="60%" /></p>

<p><strong>FOIAPop</strong> ci consentirà, quindi, di creare le seguenti richieste di accesso civico:</p>

<p><img class="center-image" src="/images/foiapop/sceltarichiesta.png" width="90%" /></p>

<p>Descriviamo adesso le diverse tipologie di richieste disponibili in <strong>FoiaPop.</strong></p>

<h2 id="nuovo-accesso-civico-generalizzato">Nuovo Accesso Civico Generalizzato</h2>

<p>E’ il caso più semplice di richiesta di accesso civico generalizzato (FOIA). Cliccando su <strong>Nuovo Accesso Civico Generalizzato</strong>
 verremo rendirizzati nel modulo di inserimento dei dati anagrafici del richiedente e del testo della richiesta.</p>

<p><img class="center-image" src="/images/foiapop/form-foia.png" width="60%" /></p>

<p>Clicchiamo su <strong>AVANTI</strong>.  <strong>FoiaPop</strong> visualizzerà un’<strong>anteprima</strong> della richiesta di <em>accesso civico generalizzato</em>, 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 <em>Ufficio Relazioni con il Pubblico</em>, 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.</p>

<p><img class="center-image" src="/images/foiapop/preview-foia.png" width="60%" /></p>

<p>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.</p>

<p><img class="center-image" src="/images/foiapop/foia.png" width="60%" /></p>

<p>A questo punto l’utente può trasmettere la richiesta secondo le modalità di trasmissione che preferisce.</p>

<h2 id="nuovo-accesso-civico-generalizzato-dai-dati-siope">Nuovo Accesso Civico Generalizzato dai dati SIOPE</h2>

<p>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 <strong>FoiaPop</strong> 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 <a target="blank" href="https://www.siope.it/Siope2Web/jsp/dispatchHome.do">download</a> 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.</p>

<p>Per iniziare una nuova richiesta a partire dai dati SIOPE, dopo aver selezionato la pubblica amministrazione di nostro interesse,
clicchiamo su <strong>Parti dai dati SIOPE - Incassi e Pagamenti Enti Pubblici</strong>  e FoiaPop ci mostretà il seguente elenco</p>

<p><img class="center-image" src="/images/foiapop/siope-list.png" width="80%" /></p>

<p>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 <strong>parola chiave</strong> attraverso il modulo, posto ad inizio pagina.</p>

<p>Scorrendo verso il basso immaginiamo di volere chiedere maggiori informazioni sulla seguente spesa:</p>

<p><img class="center-image" src="/images/foiapop/dispositivi-medici.png" width="80%" /></p>

<p>Non ci resta che cliccare su <strong>CREA FOIA</strong> 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:</p>

<p><img class="center-image" src="/images/foiapop/siope-form.png" width="80%" /></p>

<p>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.</p>

<p>Clicchiamo su <em>AVANTI</em>. 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.</p>

<p><img class="center-image" src="/images/foiapop/siope-preview.png" width="80%" /></p>

<p>Dopo aver controllato l’esattezza di tutti i dati dell’anteprima non ci resta che cliccare sul
tasto <em>CREA RICHIESTA FOIA</em> per generare il modulo in PDF da trasmettere alla P.A.</p>

<h2 id="nuovo-accesso-civico-generalizzato-dai-dati-anac">Nuovo Accesso Civico Generalizzato dai dati ANAC</h2>
<p>Oltre ai dati SIOPE, <strong>FoiaPop</strong> consente anche di creare richieste di accesso civico generalizzato a partire dai contratti pubblici delle P.A.
La base informativa di riferimento è il sito <a href="http://dati.anticorruzione.it/#/l190">ANAC</a> 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.</p>

<p>Per iniziare una nuova richiesta dai dati ANAC, dopo aver selezionato la pubblica amministrazione di nostro interesse,
clicchiamo su <strong>Parti dai dati ANAC - Contratti Pubblici -</strong>. FoiaPop ci mostrerà il seguente elenco</p>

<p><img class="center-image" src="/images/foiapop/anac-list.png" width="90%" /></p>

<p>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.</p>

<p>Prendiamo per esempio il seguente appalto:</p>

<p><img class="center-image" src="/images/foiapop/anac-list3.png" width="80%" /></p>

<p>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.</p>

<p><img class="center-image" src="/images/foiapop/anac-form2.png" width="80%" /></p>

<p>Clicchiamo su <strong>AVANTI</strong> 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.</p>

<p><img class="center-image" src="/images/foiapop/anac-preview2.png" width="90%" /></p>

<p>Dopo aver controllato l’esattezza di tutte le informazioni inserite procediamo alla generazione del modulo di richiesta in PDF
cliccando su <strong>CREA RICHIESTA FOIA</strong>. Il modulo generato potrà quindi essere trasmesso alla pubblica amministrazione.</p>

<h2 id="accesso-civico-generalizzato-api">Accesso Civico Generalizzato API</h2>

<p>Attraverso apposite <strong>API</strong> FoiaPop consente l’integrazione delle sue funzionalità con siti esterni, come, ad esempio,
i siti istituzionali degli enti pubblici.</p>

<p>L’URL da invocare è il seguente:</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title"> </span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line">http://www.foiapop.it/api/accesso-civico-generalizzato?cf=CODICE-FISCALE-DELLA-PA&amp;dati=DATI-DA-INSERIRE-NELLA-RICHIESTA</div></div></pre></div></figure>

<p>dove il parametro <strong>cf</strong> (obbligatorio) rappresenta il codice fiscale della pubblica amministrazione e il parametro <strong>dati</strong> (opzionale) 
rappresenta il <em>dato</em> da inserire nella richiesta di accesso civico generalizzato.</p>

<p>Un tipico scenario d’uso è, ad esempio, l’inserimento di un link (o di un bottone) nel sito istituzionale del comune 
utilizzando il parametro <em>dati</em> per veicolare gli <em>oggetti</em>  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 <em>Accesso Civico</em>
che lo rendirizzerà su <em>FoiaPop</em> per la compilazione automatica della richiesta di <em>accesso civico generalizzato</em>, a partire dai dati
relativi all’oggetto specifico di quell’atto amministrativo.</p>

<p>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)
<strong>FoiaPop</strong> 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.</p>

<p><img class="center-image" src="/images/foiapop/foia-api.png" width="80%" /></p>

<h3 id="demo">Demo</h3>
<iframe style="width:123px;height:35px" marginwidth="0" marginheight="0" align="top" scrolling="No" frameborder="0" hspace="0" vspace="0" src="http://www.foiapop.it/ente/dbece4af-e46b-47cf-9e0f-26db9b9c9365/accesso-civico-generalizzato/widget"></iframe>
<iframe style="width:123px;height:35px" marginwidth="0" marginheight="0" align="top" scrolling="No" frameborder="0" hspace="0" vspace="0" src="http://www.foiapop.it/ente/dbece4af-e46b-47cf-9e0f-26db9b9c9365/accesso-civico-generalizzato/widget?style=btn-success"></iframe>
<iframe style="width:123px;height:35px" marginwidth="0" marginheight="0" align="top" scrolling="No" frameborder="0" hspace="0" vspace="0" src="http://www.foiapop.it/ente/dbece4af-e46b-47cf-9e0f-26db9b9c9365/accesso-civico-generalizzato/widget?style=btn-info"></iframe>
<iframe style="width:123px;height:35px" marginwidth="0" marginheight="0" align="top" scrolling="No" frameborder="0" hspace="0" vspace="0" src="http://www.foiapop.it/ente/dbece4af-e46b-47cf-9e0f-26db9b9c9365/accesso-civico-generalizzato/widget?style=btn-warning"></iframe>
<iframe style="width:123px;height:35px" marginwidth="0" marginheight="0" align="top" scrolling="No" frameborder="0" hspace="0" vspace="0" src="http://www.foiapop.it/ente/dbece4af-e46b-47cf-9e0f-26db9b9c9365/accesso-civico-generalizzato/widget?style=btn-danger"></iframe>

<p>Cliccando su uno dei bottoni si verrà reindirizzati su <strong>FoiaPop</strong> e si potrà iniziare il processo di compilazione della richiesta online, esattamente come già visto in precedenza. L’ente di partenza
è sempre il <em>Comune di Caltanissetta</em>.</p>

<h2 id="nuovo-accesso-civico-semplice">Nuovo Accesso Civico Semplice</h2>

<p>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 <em>richiesta di accesso civico semplice</em>. 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
 <a href="http://www.anticorruzione.it/portal/rest/jcr/repository/collaboration/Digital%20Assets/anacdocs/Attivita/Atti/determinazioni/2016/1310/Del.1310.2016.All_new.xls">elenco</a> 
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 <em>accesso civico semplice</em>, chiedendo alla P.A.
la pubblicazione dei documenti mancanti.</p>

<p>Anche per questa tipologia di richiesta FoiaPop consente di creare passo passo il modulo da trasmettere alla P.A. Vediamo come.</p>

<p>Il punto di partenza è sempre la pubblica amministrazione di nostro interesse. Anche in questo caso scegliamo il <em>comune di Caltanissetta</em>.</p>

<p>Clicchiamo quindi su <strong>Nuovo Accesso Civico Semplice - Pubblicazioni Online Obbligatorie</strong>.</p>

<p><img class="center-image" src="/images/foiapop/bottone-acs.png" width="80%" /></p>

<p>FoiaPop ci mostrerà l’elenco dei documenti che tutte le P.A. devono pubblicare all’interno della sezione <strong>Amministrazione Trasparente</strong> dei loro siti istituzionali.
Tali obblighi, così come previsti dall’ANAC, sono strutturati in sezioni (macrofamiglie) e in sottosezioni (tipologie di dati).</p>

<p><img class="center-image" src="/images/foiapop/at-list.png" width="90%" /></p>

<p>Per ciascun obbligo, passando il mouse sopra l’icona <strong>punto interrogativo</strong>, FoiaPop visualizzerà il contenuto con un dettaglio maggiore.</p>

<p><img class="center-image" src="/images/foiapop/at-tooltip.png" width="80%" /></p>

<p><strong>FoiaPop</strong>, inoltre, verificherà l’esito del monitoraggio effettuato dalla <a href="http://bussola.magellanopa.it/home.html">Bussola della Trasparenza</a> 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 (<em>o si dovrebbe trovare</em>) il documento relativo
all’obbligo monitorato.</p>

<p><img class="center-image" src="/images/foiapop/at-bussola.png" width="80%" /></p>

<p>L’utente procederà quindi a inserire uno o più obblighi nella <em>richiesta di accesso civico semplice</em>, a mò di carrello della spesa, e per ciascuna selezione potrà indicare la
motivazione della richiesta, così come di seguito riportato.</p>

<p><img class="center-image" src="/images/foiapop/at-carrello.png" width="50%" /></p>

<p>Dopo aver selezionato il/i documento/i su cui richiedere l’accesso, premendo il tasto <strong>AVANTI</strong> l’utente potrà inserire le informazioni anagrafiche 
così come visto in precedenza.</p>

<p>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.</p>

<p><img class="center-image" src="/images/foiapop/at-form.png" width="80%" /></p>

<p>Cliccando su <em>AVANTI</em>  FoiaPop visualizzerà l’anteprima della <em>richiesta di accesso civico semplice</em>, completa di tutte le informazioni inserite.</p>

<p><img class="center-image" src="/images/foiapop/at-preview.png" width="80%" /></p>

<p>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 <strong>CREA RICHIESTA ACCESSO CIVICO SEMPLICE</strong>
e FoiaPop genererà per noi il documento in PDF da trasmettere alla pubblica amministrazione.</p>

<p><img class="center-image" src="/images/foiapop/accesso-civico-semplice.png" width="100%" /></p>

<h2 id="accesso-civico-semplice-api">Accesso Civico Semplice API</h2>
<p>Attraverso l’accesso tramite <strong>API</strong> è possibile generare richieste di <em>accesso civico semplice</em> a partire da siti esterni.
L’<strong>URL</strong> da invocare è il seguente:</p>
<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title"> </span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line">http://www.foiapop.it/api/accesso-civico-semplice?cf=CODICE-FISCALE-DELLA-PA</div></div></pre></div></figure>

<p>doce il parametro <strong>cf</strong> (obbligatorio) rappresenta il codice fiscale della pubblica amministrazione.</p>

<p>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 <strong>Amministrazione Trasparente</strong>. L’utente che non riesce a trovare il documento desiderato, cliccando sul link/bottone,
viene quindi reindirizzato su <strong>FoiaPop</strong> per la compilazione passo passo della richiesta di <em>accesso civico semplice</em> del documento non trovato.</p>

<p>Per facilitare il lavoro ai webmaster, <strong>FoiaPop</strong> 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 <em>Comune di Caltanissetta</em>.</p>

<h3 id="demo-1">Demo</h3>
<iframe style="width:123px;height:35px" marginwidth="0" marginheight="0" align="top" scrolling="No" frameborder="0" hspace="0" vspace="0" src="http://www.foiapop.it/ente/dbece4af-e46b-47cf-9e0f-26db9b9c9365/accesso-civico-semplice/widget"></iframe>
<iframe style="width:123px;height:35px" marginwidth="0" marginheight="0" align="top" scrolling="No" frameborder="0" hspace="0" vspace="0" src="http://www.foiapop.it/ente/dbece4af-e46b-47cf-9e0f-26db9b9c9365/accesso-civico-semplice/widget?style=btn-success"></iframe>
<iframe style="width:123px;height:35px" marginwidth="0" marginheight="0" align="top" scrolling="No" frameborder="0" hspace="0" vspace="0" src="http://www.foiapop.it/ente/dbece4af-e46b-47cf-9e0f-26db9b9c9365/accesso-civico-semplice/widget?style=btn-info"></iframe>
<iframe style="width:123px;height:35px" marginwidth="0" marginheight="0" align="top" scrolling="No" frameborder="0" hspace="0" vspace="0" src="http://www.foiapop.it/ente/dbece4af-e46b-47cf-9e0f-26db9b9c9365/accesso-civico-semplice/widget?style=btn-warning"></iframe>
<iframe style="width:123px;height:35px" marginwidth="0" marginheight="0" align="top" scrolling="No" frameborder="0" hspace="0" vspace="0" src="http://www.foiapop.it/ente/dbece4af-e46b-47cf-9e0f-26db9b9c9365/accesso-civico-semplice/widget?style=btn-danger"></iframe>

<p>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.</p>

<h2 id="conclusioni">Conclusioni</h2>
<p>FoiaPop è una piattaforma online per la compilazione di richieste di <em>accesso civico semplice e generalizzato</em>.</p>

<p>E’ online la versione <a href="http://www.foiapop.it">beta</a>.</p>

<p>FoiaPop è uno strumento rivolto ai cittadini per facilitare loro la compilazione delle richieste di accesso civico.
<strong>Ma non è solo questo.</strong></p>

<p>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.</p>

<hr />

<p><br />
Se questo progetto ti è piaciuto, mi aiuti a farlo conoscere con un tweet? Grazie!</p>

<p><a href="http://twitter.com/share?url=http://www.foiapop.it&amp;text=FoiaPop+-+Accesso+civico+data-driven!+@foiapop+@gpirrotta">Twittami</a></p>

<p><a href="http://twitter.com/share?url=http://www.foiapop.it&amp;text=FoiaPop+-+Accesso+civico+data-driven!+@foiapop+@gpirrotta"><img src="/images/twitter.png" alt="Image" /></a></p>

<p>Per feedback, suggerimenti e critiche non esitate a lasciarmi un commento.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Citybot: la tua città, smart, in pochi click]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2016/04/09/citybot-la-tua-citta-smart-in-pochi-click/"/>
    <updated>2016-04-09T11:11:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2016/04/09/citybot-la-tua-citta-smart-in-pochi-click</id>
    <content type="html"><![CDATA[<p>A settembre 2015 ho partecipato al raduno Open Data Sicilia, svoltosi a Palermo.
In quell’occasione sono venuto a conoscenza del progetto <a href="http://www.comunweb.it/">ComunWeb</a>, cioè una soluzione informatica omogenea per tutti i comuni e le comunità di Valle interessate a un portale di comunicazione su piattaforma condivisa.
<!--More-->
La parte di ComunWeb che ha destato in me maggior attenzione è stata quella relativa all’utilizzo di un <a href="http://www.comunweb.it/openpa/classes">modello di dati condiviso</a> fra tutti gli enti locali aderenti (attualmente 178), grazie al quale i
 flussi di dati tipici di un ente, risultati interni di processi decisionali, vengono rappresentati mediante uno schema standard unico.
 Questo passaggio, a mio avviso, è la chiave di volta dell’intero progetto perchè è propedeutico a qualsiasi discorso inerente riuso e interoperabilità, temi molto cari a un
 <em>opendataro</em> come me. Qui non parliamo del classico <em>civic-hacker</em> che passa le notti ad aprire dataset che la pubblica amministrazione quando va bene rilascia in modalità chiusa.
 No no, qui è la pubblica amministrazione stessa, fonte e sorgente autorevole di dati pubblici che, nell’espletamento dei compiti amministrativi quotidiani,
 produce ed espone automaticamente i dati verso l’esterno. L’infrastruttura di ComunWeb  consente
 di interrogare i dati dell’ente tramite <a href="http://www.comunweb.it/Supporto/Manuale-d-uso/Funzionalita-per-gli-Open-Data/Risorse-Rest-API-v1">API REST</a>
  e con licenza Opendata. I dati ritornano di fatto al cittadino. Chapeau!</p>

<p>Qualche mese più tardi  <a href="https://twitter.com/aborruso">Andrea Borruso</a> creava l’ <a href="http://albopop.it/about/">Albo Pop</a> 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  <a href="http://albopop.it/comune/">altri comuni</a>
sparsi in tutta Italia e da altre <a href="http://albopop.it/altrepa/">pubbliche amministrazioni</a>.</p>

<p>In rete esistono tantissimi progetti che riusano dati <em>cittadini</em> e creano valore per l’utente finale. Cito ad esempio i BOT sviluppati da <a href="http://www.piersoft.it/?p=626">Pierfrancesco Paolicelli</a>.</p>

<p>In passato anch’io ho presentato soluzioni applicative, a partire da dati aperti e non, in grado di creare servizi per la cittadinanza: <a href="http://giovanni.pirrotta.it/blog/2013/07/22/openalbopretorio-apriti-sesamo/">OpenAlboPretorio</a>,
<a href="http://giovanni.pirrotta.it/blog/2015/08/12/parking-messina-quando-la-ztl-incontra-gli-open-data/">Parking in Messina</a>, BOT Telegram per i
trasporti (<a href="http://giovanni.pirrotta.it/blog/2015/10/09/stazione-amat-di-palermo-ce-un-telegram-per-te/">Amat Palermo</a>) e per la <a href="http://giovanni.pirrotta.it/blog/2015/10/28/protezione-civile-palermo-telegram-bot/">Protezione Civile</a>.</p>

<p>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.</p>

<p>I dati <em>cittadini</em> 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 <em>effettivamente</em> un’infinità di applicazioni per migliorare <em>efficacemente</em> la vita al cittadino.</p>

<p>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 <strong>stesso identico</strong> servizio digitale anche nella loro città.</p>

<p>A questo punto mi faccio delle domande.</p>

<p>Perchè non far funzionare il tutto su un’<strong>unica</strong> piattaforma, sviluppare l’applicazione <strong>una</strong> volta sola e renderla disponibile a <strong>tutte</strong> 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?</p>

<p>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 <em>app</em> da installare sul proprio <em>smartphone</em> ho immaginato un’applicazione  <strong>HUB</strong>, 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.</p>

<p>Queste domande sono state il deterrente per la nascita di <a href="http://www.citybot.it">CityBot</a>.</p>

<p><strong>Disclaimer</strong> - <em>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</em></p>

<p><img src="/images/citybot.jpg" alt="Image" class="center-image" /></p>

<h2 id="perchè-un-bot">Perchè un BOT?</h2>
<p>Qualche giorno fa Skype (leggi Microsoft) ha <a href="http://blogs.skype.com/2016/03/30/skype-bots-preview-comes-to-consumers-and-developers/">annunciato</a>
 il rilascio di un framework di sviluppo di BOT che consentirà agli sviluppatori di creare BOT dentro Skype.
Anche <a href="https://get.slack.help/hc/en-us/articles/202026038-Slackbot-your-assistant-notepad-programmable-bot">Slack</a>, da tempo, consente
di programmare BOT per erogare servizi all’interno della sua chat.
Inoltre Facebook, tramite il suo <strong>Messenger</strong>, ha iniziato a fornire servizi per gli utenti, sotto forma di BOT, anche se per adesso non ha aperto
al mondo degli sviluppatori.</p>

<p>Con ciò cosa voglio dire? Voglio dire che l’attenzione da parte di importanti <em>player</em> IT verso i BOT si sta facendo <strong>molto seria</strong>!
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.</p>

<h2 id="citybot">CITYBOT</h2>

<p><a href="http://www.citybot.it">CityBot</a> è un configuratore di BOT Telegram in grado di creare servizi informativi per le città,
rapidamente e senza essere esperti di programmazione.</p>

<p>CityBot fornisce attualmente le seguenti funzionalità:</p>

<ul>
  <li><strong>Flusso RSS Feed</strong> - per collegare uno o più <strong>feed RSS</strong> e tenerti aggiornato sulle informazioni istituzionali e non della tua città: albo pretorio, news dall’università, eventi, notizie in genere, etc.</li>
  <li><strong>Flusso ComunWeb</strong> - se la città aderisce al progetto <strong>ComunWeb</strong>, a partire dai dati che il comune mette a disposizione tramite le API online,
              è possibile creare nuovi flussi informativi in CityBot e rendere il cittadino consapevole di ciò che accade nel comune.</li>
  <li><strong>Area di Attesa - Protezione Civile</strong> - servizio che aiuta i cittadini a raggiungere le aree di attesa predisposte dalla Protezione Civile in caso di calamità naturale ed aumentare, in maniera facile e immediata, la sicurezza della città e dei suoi abitanti.</li>
  <li>** Pagamento parcheggi in ZTL ** - per far conoscere ai cittadini, data la loro posizione, le tariffe dei parcheggi in ZTL e nelle aree circostanti.</li>
</ul>

<p><img src="/images/citybot-44.jpg" alt="Image" class="center-image" /></p>

<h2 id="creazione-di-un-nuovo-bot">Creazione di un nuovo BOT</h2>
<p>Vediamo adesso come creare da zero un nuovo BOT e come arricchirlo di nuove funzionalità.
Decidiamo, ad esempio, di creare il <strong>CityBot</strong> per la città di Palermo. Prima di operare su CityBot
dobbiamo entrare in <strong>Telegram</strong> e creare un nuovo BOT. E’ un’operazione molto semplice, trovate
tutte le informazioni sulla <a href="https://core.telegram.org/bots#botfather">documentazione ufficiale</a> di Telegram.
Con quest’operazione otterrete il codice identificativo segreto del BOT, chiamato <strong>TOKEN</strong>, che ci servirà
per la creazione del CityBot.</p>

<p>Andando quindi su Telegram creiamo il BOT <a href="https://telegram.me/PalermoCity_Bot">PalermoCity_Bot</a>.</p>

<p>Ritornando a CityBot, dopo una prima fase di registrazione, effettuiamo il login e ci ritroviamo nella pagina di benvenuto:</p>

<p><img src="/images/citybot-1.jpg" alt="Image" class="center-image" /></p>

<p>A questo punto clicchiamo su <strong>Crea il cityBot per la tua città</strong> e davanti a noi apparirà la seguente schermata
che ci chiederà di inserire il nome della città del BOT e il <strong>TOKEN</strong> di Telegram, ottenuto in fase di creazione del BOT.</p>

<p><img src="/images/citybot-2.jpg" alt="Image" class="center-image" /></p>

<p>Inseriti <strong>nome</strong> della città e <strong>TOKEN</strong> (<em>fittizio nell’esempio</em>),</p>

<p><img src="/images/citybot-3.jpg" alt="Image" class="center-image" /></p>

<p>possiamo creare il BOT.
Automaticamente la piattaforma riconoscerà il nome del BOT e ci consentirà di configurarlo in base alle nostre necessità.
Cliccando su <strong>Configura</strong>,
<img src="/images/citybot-4.jpg" alt="Image" class="center-image" /></p>

<p>entreremo nel pannello di configurazione del BOT:</p>

<p>![Image](/images/citybot-5.jpg?a %}</p>

<p>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 <strong>Plugin disponibili</strong> sono presenti i seguenti servizi:</p>

<ul>
  <li>**Flusso RSS Feed **</li>
  <li>**Flusso ComunWeb **</li>
  <li>**Area di Attesa - Protezione Civile **</li>
  <li><strong>Parcheggio Zone a Traffico Limitato (ZTL)</strong></li>
</ul>

<p>Entriamo nel dettaglio in ciascuno dei servizi.</p>

<p>##Flusso RSS Feed
L’<strong>RSS</strong> è 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.</p>

<p>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 <a href="http://www.comune.palermo.it/lista_rss.php">pagina</a>.</p>

<p><img src="/images/citybot-8.jpg" alt="Image" class="center-image" /></p>

<p>Decidiamo di agganciare al nostro CityBot i seguenti feed:</p>

<ul>
  <li><strong>Informazione</strong>: Comunicati stampa, scadenze, avvisi, accade a Palermo <a href="http://www.comune.palermo.it/feed/rss.xml">feed</a></li>
  <li><strong>Bandi e Gare</strong>: <a href="http://www.comune.palermo.it/feed/rss_bandi.xml">feed</a></li>
</ul>

<p>Spostiamoci adesso su CityBot e iniziamo ad aggiungere il primo plugin al nostro CityBot scegliendo quindi <strong>flusso RSS Feed</strong>.</p>

<p>Clicchiamo su <strong>Aggiungi</strong> e vedremo comparire il plugin nella sezione <strong>Plugin Aggiunti</strong>.</p>

<p><img src="/images/citybot-6.jpg" alt="Image" class="center-image" /></p>

<p>A questo punto configuriamo il plugin cliccando su <strong>Configura</strong> 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 <strong>“Comune di Palermo”</strong>.</p>

<p>![Image](/images/citybot-9.jpg?a %}</p>

<p>Andiamo avanti e iniziamo la configurazione dei feed RSS.</p>

<p>![Image](/images/citybot-10.jpg?p %}</p>

<p>Nella sezione <strong>Feed collegati</strong> clicchiamo sul bottone <strong>Aggiungi</strong> (segno più)</p>

<p><img src="/images/citybot-11.jpg" alt="Image" class="center-image" /></p>

<p>e inseriamo il primo feed RSS</p>

<p><img src="/images/citybot-12.jpg" alt="Image" class="center-image" /></p>

<p>Anche in questo caso il nome del feed corrisponderà al nome del sottocomando del BOT.
Per il nostro esempio inseriamo il nome <strong>News</strong>.
Il numero max di elementi del feed è configurabile ma nel nostro esempio lasciamo il valore di default 10.</p>

<p>Ripetiamo la stessa operazione per il secondo feed inserendo come nome <strong>Bandi e Gare</strong></p>

<p><img src="/images/citybot-13.jpg" alt="Image" class="center-image" /></p>

<p>Per ogni feed possiamo verificarne il contenuto o procedere alla rimozione.</p>

<p>![Image](/images/citybot-14.jpg?o %}</p>

<p>Ritorniamo nel pannello di amministrazione del plugin e accendiamo il servizio.</p>

<p><img src="/images/citybot-16.jpg" alt="Image" class="center-image" /></p>

<p>Dopodichè accendiamo anche il BOT,</p>

<p><img src="/images/citybot-17.jpg" alt="Image" class="center-image" /></p>

<p>ci spostiamo sul nostro smartphone e cerchiamo il <strong>Canale</strong> <a href="https://telegram.me/PalermoCity_Bot">PalermoCity_BOT</a>.</p>

<p><img src="/images/citybot-29.jpg" alt="Image" class="center-image" /></p>

<p>Nella schermata compare il messaggio di benvenuto e in basso il menù dei comandi disponibili.
A sinistra compare il comando <strong>Comune di Palermo</strong>, 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:</p>

<p><img src="/images/citybot-30.jpg" alt="Image" class="center-image" /></p>

<p>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è <strong>Comune di Palermo</strong>, apparirà il seguente menù:</p>

<p><img src="/images/citybot-31.jpg" alt="Image" class="center-image" /></p>

<p>Il bottone di sinistra, così come configurato precedentemente, è collegato al feed RSS relativo alle informazioni sul <strong>comune di Palermo</strong>:</p>

<p><img src="/images/citybot-32.jpg" alt="Image" class="center-image" /></p>

<p>Il bottone di destra è collegato invece  al feed RSS relativo alle informazioni su <strong>Bandi e gare</strong>.</p>

<p><img src="/images/citybot-33.jpg" alt="Image" class="center-image" /></p>

<p>##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 <a href="http://www.comunweb.it/openpa/classes">modello di dati condiviso</a> e di esporre tali dati con licenza opendata attraverso delle API REST.</p>

<p>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 <a href="http://www.comune.ala.tn.it/">Ala</a> (TN).</p>

<p>Interrogando le <a href="http://www.comune.ala.tn.it/api/opendata/v1/help">API</a> 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’<a href="http://www.comune.ala.tn.it/api/opendata/v1/content/class/albo_elenco">Albo Pretorio</a> e l’elenco
delle <a href="http://www.comune.ala.tn.it/api/opendata/v1/content/class/associazione">associazioni</a> presenti in città.</p>

<p>Individuate le fonti dati spostiamoci sul pannello di configurazione di CityBot e aggiungiamo il plugin <strong>Flusso ComunWeb</strong>.</p>

<p><img src="/images/citybot-18.jpg" alt="Image" class="center-image" /></p>

<p>Entriamo in configurazione e, come per il <strong>Flusso RSS</strong>, inseriamo il nome che apparirà nel comando del menù principale del BOT;
decidiamo di mettere come nome <strong>Comune di Ala (TN)</strong>.</p>

<p><img src="/images/citybot-19.jpg" alt="Image" class="center-image" /></p>

<p>Inseriamo i due link di interrogazione per le informazioni da collegare. Decidiamo di chiamarli <strong>Albo Pretorio</strong> e <strong>Associazioni</strong>.</p>

<p><img src="/images/citybot-20.jpg" alt="Image" class="center-image" /></p>

<p>Anche in questo caso accendiamo il servizio, accendiamo il BOT e ci spostiamo sullo smartphone.</p>

<p>Come possiamo vedere dalla schermata, il bottone relativo al <strong>Comune di Ala</strong> è stato aggiunto a fianco a quello del <strong>Comune di Palermo</strong>.</p>

<p><img src="/images/citybot-34.jpg" alt="Image" class="center-image" /></p>

<p>Al nuovo bottone è associato il seguente sottomenù:</p>

<p><img src="/images/citybot-35.jpg" alt="Image" class="center-image" /></p>

<p>Al bottone <strong>Albo Pretorio</strong> corrisponderà il seguente flusso ComunWeb:</p>

<p><img src="/images/citybot-36.jpg" alt="Image" class="center-image" /></p>

<p>Al bottone <strong>Associazioni</strong> è agganciato invece quest’altro flusso:</p>

<p><img src="/images/citybot-37.jpg" alt="Image" class="center-image" /></p>

<h2 id="protezione-civile">Protezione Civile</h2>
<p>Dal <a href="http://www.protezionecivile.gov.it/jcms/it/glossario.wp?contentId=GLO13370">sito</a>
della Protezione Civile leggiamo:</p>

<p><em>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.</em></p>

<p>Il plugin <strong>Area di Attesa - Protezione Civile</strong> 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.</p>

<p>Dal pannello di CityBot aggiungiamo il plugin <strong>Area di Attesa - Protezione Civile</strong> ed entriamo
in configurazione. Visualizzeremo la seguente schermata:</p>

<p><img src="/images/citybot-21.jpg" alt="Image" class="center-image" /></p>

<p>A questo punto dovremo disegnare i poligoni corrispondenti alle aree di attesa della Protezione Civile.
Possiamo farlo in due modi:</p>

<ul>
  <li>disegnando le aree attraverso lo strumento <strong>Poligono</strong></li>
  <li>importando la mappa da file GEOJSON</li>
</ul>

<p>Nel <strong>primo caso</strong> bisognerà individuare l’area di attesa sulla mappa,  cliccare sullo strumento <strong>Poligono</strong> in alto a destra,</p>

<p><img src="/images/citybot-22.jpg" alt="Image" class="center-image" /></p>

<p>e iniziare a disegnare il poligono lato per lato.-</p>

<p><img src="/images/citybot-23.jpg" alt="Image" class="center-image" /></p>

<p>Alla chiusura del poligono sarà necessario inserire informazioni relative all’area di attesa disegnata:</p>

<p><img src="/images/citybot-24.jpg" alt="Image" class="center-image" /></p>

<p>Inserite le informazioni dell’area di attesa, per aggiornare la mappa bisognerà cliccare su <strong>Aggiorna Dati</strong>.
Dopo aver disegnato tutte le aree manualmente, per salvare la mappa in CityBot bisognerà cliccare su <strong>Salva mappa</strong>.</p>

<p>Nel <strong>secondo caso</strong> basterà invece uplodare la mappa da file <a href="http://geojson.org/">GEOJSON</a>, con l’unica accortezza
di inserire le informazioni delle aree di attesa in proprietà chiamate <strong>name</strong> e <strong>description</strong>, dentro <strong>properties</strong>.</p>

<p>Esempio di caricamento delle aree di attesa da file GEOJSON:</p>

<p><img src="/images/citybot-25.jpg" alt="Image" class="center-image" /></p>

<p>Usciamo e ritorniamo nel pannello di amministrazione del BOT; accendiamo il servizio e spostiamoci sullo smartphone.</p>

<p>Il nuovo menù principale apparirà nel seguente modo:</p>

<p><img src="/images/citybot-38.jpg" alt="Image" class="center-image" /></p>

<p>Cliccando su <strong>Protezione Civile</strong> saremo invitati a cliccare sull’icona graffetta e ad inserire la nostra posizione geografica.</p>

<p><img src="/images/citybot-39.jpg" alt="Image" class="center-image" /></p>

<p>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.</p>

<p><img src="/images/citybot-40.jpg" alt="Image" class="center-image" /></p>

<h2 id="parcheggio-zone-a-traffico-limitato-ztl">Parcheggio Zone a Traffico Limitato (ZTL)</h2>
<p>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.</p>

<p>Aggiungiamo quindi l’ultimo dei servizi disponibili in CityBot e procediamo alla sua configurazione.</p>

<p><img src="/images/citybot-26.jpg" alt="Image" class="center-image" /></p>

<p>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 <strong>Nome</strong> il nome dell’area di pagamento (ad es. P1, P2, ZTL1, ZTL2, etc.)
e nel campo <strong>Descrizione</strong>, il dettaglio del pedaggio da pagare (Tariffa oraria, Fascia Oraria, Validità, etc.).
Per il nostro esempio, su <a href="https://umap.openstreetmap.fr">umap</a> troviamo la <a href="https://umap.openstreetmap.fr/it/map/mappa-parcheggi-su-strada-a-pagamento-e-ztl-palerm_58038#12/38.1269/13.3717">mappa dei parcheggi</a>
 su strada a pagamento di Palermo; decidiamo quindi di caricare su CityBot il file GEOJSON, <em>adattando</em> opportunamente il campo <strong>properties</strong> (<em>name</em> e <em>description</em>).</p>

<p><img src="/images/citybot-27.jpg" alt="Image" class="center-image" /></p>

<p>Ritorniamo nel pannello del BOT,accendiamo quest’ultimo servizio e il BOT. Spostandoci adesso sullo smartphone il menù sarà adesso:</p>

<p><img src="/images/citybot-41.jpg" alt="Image" class="center-image" /></p>

<p>Cliccando su <strong>Pedaggio in ZTL</strong>, 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.</p>

<p><img src="/images/citybot-42.jpg" alt="Image" class="center-image" /></p>

<h2 id="conclusioni">Conclusioni</h2>
<p>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.</p>

<p>Da diversi mesi sto investendo tempo e risorse nello sviluppo di servizi digitali con i BOT Telegram
e <em>CityBot</em> è un pò la <em>summa</em> delle esperienze maturate.</p>

<p>In futuro ho in mente di estendere <em>CityBot</em> con le seguenti funzionalità:</p>

<ul>
  <li>plugin su altri <strong>Punti di Interesse</strong> (farmacie, ospedali, parchi, attività commerciali);</li>
  <li>plugin <strong>Raccolta Differenziata</strong>;</li>
  <li>plugin <strong>Meteo</strong>;</li>
  <li>plugin <strong>Trasporti</strong> (agganciato a <a href="http://transit.land">Transit.land</a>);</li>
  <li>attivazione <strong>Canali</strong> per notifiche push.</li>
</ul>

<p>La piattaforma di <em>CityBot</em> si trova <a href="http://www.citybot.it">qui</a>.
Se volete provare il CityBot creato come esempio per la città di Palermo, cliccate <a href="https://telegram.me/PalermoCity_Bot">qui</a>.</p>

<p>Se <em>CityBot</em> vi è piaciuto, aiutatemi a farlo conoscere con un tweet, grazie!</p>

<p><a href="http://twitter.com/share?url=http://www.citybot.it&amp;text=@gpirrotta+CityBot+-+Crea+il+BOT+della+Tua+Città+in+Pochi+Click!">Twittami</a></p>

<p><a href="http://twitter.com/share?url=http://www.citybot.it&amp;text=@gpirrotta+CityBot+-+Crea+il+BOT+della+Tua+Città+in+Pochi+Click!"><img src="/images/twitter.png" alt="Image" class="center-image" /></a></p>

<p>Per feedback, suggerimenti e critiche non esitate a lasciarmi un commento.</p>

<p>That’s all folks! Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Quando un BOT può salvarti la vita!]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2015/10/28/protezione-civile-palermo-telegram-bot/"/>
    <updated>2015-10-28T14:21:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2015/10/28/protezione-civile-palermo-telegram-bot</id>
    <content type="html"><![CDATA[<p>Ok, lo confesso, mi sto facendo prendere un pò troppo la mano
da <a href="https://telegram.org/">Telegram</a> e il suo <a href="https://core.telegram.org/bots">BOT</a>,
ma non è colpa mia se hanno reso così semplice e disarmante creare servizi di valore con la loro chat. :-)</p>

<p>Succede, però, che un lunedì mattina ricevo una email di <a href="https://twitter.com/aborruso">Andrea Borruso</a>,
il quale mi propone, su un’idea di <a href="https://twitter.com/cirospat">Ciro Spataro</a>, 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.</p>

<!--More-->

<p>Dal <a href="http://www.protezionecivile.gov.it/jcms/it/glossario.wp?contentId=GLO13371">sito</a>
della protezione civile si legge:</p>

<p><em>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.).</em></p>

<p><img src="/images/protezione-civile.png" alt="Image" class="center-image" /></p>

<p>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 <a href="https://it.wikipedia.org/wiki/Alluvione_di_Messina_del_2009">violento nubifragio di Messina del 2009</a>,
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.</p>

<p>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.</p>

<p>Chi sicuramente ha già capito questo  è <a href="https://twitter.com/cirospat">Ciro Spataro</a> che, in veste di civic-hacker,
ha mappato le <a href="http://umap.openstreetmap.fr/it/map/mappa-piano-protezione-civile-palermo-2014_16328#12/38.1190/13.3422">aree di accoglienza persone della Protezione Civile di Palermo</a>
usando <a href="http://umap.openstreetmap.fr/it/">umap</a> e <a href="https://www.openstreetmap.org/">openstreetmap</a>.</p>

<iframe width="100%" height="300px" frameborder="0" src="http://umap.openstreetmap.fr/it/map/mappa-piano-protezione-civile-palermo-2014_16328?scaleControl=false&amp;miniMap=false&amp;scrollWheelZoom=false&amp;zoomControl=true&amp;allowEdit=false&amp;moreControl=true&amp;datalayersControl=true&amp;onLoadPanel=undefined&amp;captionBar=false&amp;datalayers=29962"></iframe>
<p><a href="http://umap.openstreetmap.fr/it/map/mappa-piano-protezione-civile-palermo-2014_16328">Visualliza schermo intero</a></p>

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

<p>Ciro suggerisce di prendere come esempio il lavoro fatto a <a href="https://iltempe.github.io/Emergenzeprato/">Prato</a> da
 <a href="http://pratosmart.teo-soft.com/emergenzeprato/">Matteo Tempestini</a>, 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.</p>

<p>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 <a href="http://giovanni.pirrotta.it/blog/2015/08/12/parking-messina-quando-la-ztl-incontra-gli-open-data/">post</a>) sia con
progetti legati allo sviluppo di BOT su dati relativi ai trasporti urbani
(ne parlo in quest’altro <a href="http://giovanni.pirrotta.it/blog/2015/10/09/stazione-amat-di-palermo-ce-un-telegram-per-te/">post</a>).</p>

<p>Tecnicamente si tratta di risolvere il seguente problema: data una posizione geografica, leggi
<em>latitudine</em> e <em>longitudine</em>, individuare l’area di accoglienza o di ricovero della popolazione
più vicine, secondo quanto previsto dalla Protezione Civile.</p>

<p>Dalla mappa mi esporto quindi tutte le aree in formato <em>geoJSON</em>, 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.</p>

<p>La logica del programma è molto semplice:</p>

<ol>
  <li>L’utente invia la propria posizione tramite il BOT</li>
  <li>L’applicazione seleziona l’area di accoglienza più vicina
confrontando le distanze tra la posizione dell’utente e i vertici di tutte le aree</li>
  <li>L’applicazione restituisce:
    <ul>
      <li>il nome dell’area di accoglienza più vicina</li>
      <li>la mappa geografica dell’area</li>
      <li>la distanza in km</li>
      <li>il tempo necessario per raggiungere l’area a piedi</li>
      <li>il link con il percorso da seguire.</li>
    </ul>
  </li>
</ol>

<p>In un mio precedente <a href="http://giovanni.pirrotta.it/blog/2015/10/09/stazione-amat-di-palermo-ce-un-telegram-per-te/">post</a>
ho affrontato il problema della distanza di un punto da una lista di punti utilizzando in modo
diretto formule trigonometriche e una chiamata SQL.</p>

<p>Questa volta invece utilizzerò la libreria <a href="https://github.com/thephpleague/geotools#geotools">GeoTools</a>, 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.</p>

<p>Siano, ad esempio, <em>$coordA</em> e <em>$coordB</em> i due punti di cui si vuole conoscere la distanza;
 per creare l’oggetto <em>distance</em> è necessario digitare quanto segue:</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  Telegram</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="cp">&lt;?php</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line"> </div></div><div data-line="3" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="nv">$geotools</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">\League\Geotools\Geotools</span><span class="p">();</span>
</div></div><div data-line="4" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="nv">$coordA</span>   <span class="o">=</span> <span class="k">new</span> <span class="nx">\League\Geotools\Coordinate\Coordinate</span><span class="p">([</span><span class="mf">48.8234055</span><span class="p">,</span> <span class="mf">2.3072664</span><span class="p">]);</span>
</div></div><div data-line="5" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="nv">$coordB</span>   <span class="o">=</span> <span class="k">new</span> <span class="nx">\League\Geotools\Coordinate\Coordinate</span><span class="p">([</span><span class="mf">43.296482</span><span class="p">,</span> <span class="mf">5.36978</span><span class="p">]);</span>
</div></div><div data-line="6" class="code-highlight-row numbered"><div class="code-highlight-line"> </div></div><div data-line="7" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="nv">$distance</span> <span class="o">=</span> <span class="nv">$geotools</span><span class="o">-&gt;</span><span class="na">distance</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">setFrom</span><span class="p">(</span><span class="nv">$coordA</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">setTo</span><span class="p">(</span><span class="nv">$coordB</span><span class="p">);</span></div></div></pre></div></figure>

<p>Per avere la distanza in metri (default) con il più performante tra gli algoritmi in libreria, digitiamo invece:</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  Algoritmo flat</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="cp">&lt;?php</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="nv">$distance</span><span class="o">-&gt;</span><span class="na">flat</span><span class="p">();</span> <span class="o">//</span> <span class="mf">659166.50038742</span> <span class="p">(</span><span class="nx">meters</span><span class="p">)</span></div></div></pre></div></figure>

<p>Se volessimo utilizzare invece l’algoritmo <strong>great-circle</strong>:</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  Telegram API</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="cp">&lt;?php</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="nv">$distance</span><span class="o">-&gt;</span><span class="na">greatCircle</span><span class="p">();</span> <span class="o">//</span> <span class="mf">659021.90812846</span></div></div></pre></div></figure>

<p>Per avere la distanza in chilometri utilizzando l’algoritmo <strong>haversine</strong>, l’invocazione sarà la seguente:</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  Algoritmo haversine</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="cp">&lt;?php</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="nv">$distance</span><span class="o">-&gt;</span><span class="na">in</span><span class="p">(</span><span class="s1">'km'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">haversine</span><span class="p">();</span> <span class="o">//</span> <span class="mf">659.02190812846</span></div></div></pre></div></figure>

<p>L’algoritmo <strong>vincenty</strong>, il più accurato fra tutti quelli presenti, è invocato nel
seguente modo, con distanza in miglia:</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  Algoritmo vincenty</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="cp">&lt;?php</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="nv">$distance</span><span class="o">-&gt;</span><span class="na">in</span><span class="p">(</span><span class="s1">'mi'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">vincenty</span><span class="p">();</span> <span class="o">//</span> <span class="mf">409.05330679648</span></div></div></pre></div></figure>

<p>Per maggiori informazioni consultate la
<a href="https://github.com/thephpleague/geotools#geotools">documentazione ufficiale</a>
 della libreria.</p>

<p>Risolto il problema di <em>come</em> calcolare la distanza, trovare l’area di accoglienza più vicina
 diventa un’operazione banale.</p>

<p>La funzionalità è affidata alla classe <em>GeoToolsDistance</em> che implementa il metodo <em>distance</em>
come da contratto con l’interfaccia <em>DistanceInterface</em>.</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  Metodo "distance"</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="cp">&lt;?php</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="k">public</span> <span class="k">function</span> <span class="nf">distance</span><span class="p">(</span><span class="nx">Vertex</span> <span class="nv">$from</span><span class="p">,</span> <span class="nx">Vertex</span> <span class="nv">$to</span><span class="p">)</span>
</div></div><div data-line="3" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="p">&#x7b;</span>
</div></div><div data-line="4" class="code-highlight-row numbered"><div class="code-highlight-line">        <span class="nv">$coordFrom</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Coordinate</span><span class="p">([</span><span class="nv">$from</span><span class="o">-&gt;</span><span class="na">getLatitude</span><span class="p">(),</span> <span class="nv">$from</span><span class="o">-&gt;</span><span class="na">getLongitude</span><span class="p">()]);</span>
</div></div><div data-line="5" class="code-highlight-row numbered"><div class="code-highlight-line">        <span class="nv">$coordTo</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Coordinate</span><span class="p">([</span><span class="nv">$to</span><span class="o">-&gt;</span><span class="na">getLatitude</span><span class="p">(),</span> <span class="nv">$to</span><span class="o">-&gt;</span><span class="na">getLongitude</span><span class="p">()]);</span>
</div></div><div data-line="6" class="code-highlight-row numbered"><div class="code-highlight-line">        <span class="nv">$distanceCalculator</span> <span class="o">=</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">geotools</span><span class="o">-&gt;</span><span class="na">distance</span><span class="p">()</span><span class="o">-&gt;</span><span class="na">setFrom</span><span class="p">(</span><span class="nv">$coordFrom</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">setTo</span><span class="p">(</span><span class="nv">$coordTo</span><span class="p">);</span>
</div></div><div data-line="7" class="code-highlight-row numbered"><div class="code-highlight-line"> </div></div><div data-line="8" class="code-highlight-row numbered"><div class="code-highlight-line">        <span class="k">return</span> <span class="nv">$distanceCalculator</span><span class="o">-&gt;</span><span class="na">in</span><span class="p">(</span><span class="s1">'km'</span><span class="p">)</span><span class="o">-&gt;</span><span class="na">haversine</span><span class="p">();</span>
</div></div><div data-line="9" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="p">&#x7d;</span></div></div></pre></div></figure>

<p>In input vengono presi due oggetti del dominio di classe <a href="https://github.com/gpirrotta/protezione-civile-bot/blob/master/src/GP/ProtezioneCivileBot/Model/Vertex.php">Vertex</a>. Il codice è autoesplicativo.</p>

<p>Per confrontare le distanze di tutte le aree di accoglienza partiamo dall’oggetto <a href="https://github.com/gpirrotta/protezione-civile-bot/blob/master/src/GP/ProtezioneCivileBot/Model/Map.php">Map</a>
che, dopo aver caricato in memoria la struttura dati del file <strong>GeoJSON</strong>, contenente le coordinate
geografiche delle aree di accoglienza della protezione civile di Palermo, calcola la distanza minima all’interno del metodo
<em>getNearestArea</em>. Il metodo prende in input la posizione dell’utente e restituisce in output l’area di accoglienza più vicina.</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  Metodo "getNearestArea"</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="cp">&lt;?php</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="k">public</span> <span class="k">function</span> <span class="nf">getNearestArea</span><span class="p">(</span><span class="nx">Vertex</span> <span class="nv">$vertex</span><span class="p">)</span>
</div></div><div data-line="3" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="p">&#x7b;</span>
</div></div><div data-line="4" class="code-highlight-row numbered"><div class="code-highlight-line">        <span class="nv">$areaNearest</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
</div></div><div data-line="5" class="code-highlight-row numbered"><div class="code-highlight-line">        <span class="nv">$distanceNearest</span> <span class="o">=</span> <span class="nx">PHP_INT_MAX</span><span class="p">;</span>
</div></div><div data-line="6" class="code-highlight-row numbered"><div class="code-highlight-line">        <span class="k">foreach</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="na">aree</span> <span class="k">as</span> <span class="nv">$areaAccoglienza</span><span class="p">)</span> <span class="p">&#x7b;</span>
</div></div><div data-line="7" class="code-highlight-row numbered"><div class="code-highlight-line">            <span class="nv">$areaAccoglienza</span><span class="o">-&gt;</span><span class="na">calculateVertexNearest</span><span class="p">(</span><span class="nv">$vertex</span><span class="p">);</span>
</div></div><div data-line="8" class="code-highlight-row numbered"><div class="code-highlight-line">            <span class="nv">$v</span> <span class="o">=</span> <span class="nv">$areaAccoglienza</span><span class="o">-&gt;</span><span class="na">getVertexNearest</span><span class="p">();</span>
</div></div><div data-line="9" class="code-highlight-row numbered"><div class="code-highlight-line">            <span class="k">if</span> <span class="p">(</span><span class="nv">$v</span><span class="o">-&gt;</span><span class="na">getDistance</span><span class="p">()</span> <span class="o">&lt;</span> <span class="nv">$distanceNearest</span><span class="p">)</span> <span class="p">&#x7b;</span>
</div></div><div data-line="10" class="code-highlight-row numbered"><div class="code-highlight-line">                <span class="nv">$distanceNearest</span> <span class="o">=</span> <span class="nv">$v</span><span class="o">-&gt;</span><span class="na">getDistance</span><span class="p">();</span>
</div></div><div data-line="11" class="code-highlight-row numbered"><div class="code-highlight-line">                <span class="nv">$areaNearest</span> <span class="o">=</span> <span class="nv">$areaAccoglienza</span><span class="p">;</span>
</div></div><div data-line="12" class="code-highlight-row numbered"><div class="code-highlight-line">            <span class="p">&#x7d;</span>
</div></div><div data-line="13" class="code-highlight-row numbered"><div class="code-highlight-line">        <span class="p">&#x7d;</span>
</div></div><div data-line="14" class="code-highlight-row numbered"><div class="code-highlight-line"> </div></div><div data-line="15" class="code-highlight-row numbered"><div class="code-highlight-line">        <span class="k">return</span> <span class="nv">$areaNearest</span><span class="p">;</span>
</div></div><div data-line="16" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="p">&#x7d;</span></div></div></pre></div></figure>

<p>Per calcolare il tempo necessario per raggiungere l’area di accoglienza a piedi
 (<em>feature consigliata da Andrea</em>) ho usato l’API <a href="https://developers.google.com/maps/documentation/distance-matrix/intro">distancematrix</a> messa a disposizione
 da Google.</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  API distancematrix</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line">https://maps.googleapis.com/maps/api/distancematrix/json?origins=LATITUDINE-ORIGINE,LONGITUDINE-ORIGINEs<span class="err">&amp;</span>destinations=LATITUDINE-DESTINAZIONE,LONGITUDINE-DESTINAZIONE<span class="err">&amp;</span>mode=walking<span class="err">&amp;</span>language=it-IT"</div></div></pre></div></figure>

<p>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.</p>

<p>Per il percorso da seguire ho semplicemente inviato al BOT il seguente link, sostituendo opportunamente le variabili delle coordinate geografiche:</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  API percorso viaggio</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line">http://maps.google.com/maps?f=d<span class="err">&amp;</span>hl=en<span class="err">&amp;</span>saddr=LATITUDINE-ORIGINE,LONGITUDINE-ORIGINE<span class="err">&amp;</span>daddr=LATITUDINE-DESTINAZIONE,LONGITUDINE-DESTINAZIONE<span class="err">&amp;</span>ie=UTF8<span class="err">&amp;</span>0<span class="err">&amp;</span>om=0<span class="err">&amp;</span>output=kml</div></div></pre></div></figure>

<p>Mettiamo tutto in funzione e vediamo cosa apparirà su Telegram.</p>

<p>Il BOT da cercare si chiama <a href="http://telegram.me/protezioneCivilePAbot">@protezioneCivilePAbot</a></p>

<p>La prima cosa da fare è inviare la propria posizione cliccando sulla graffetta.</p>

<p><img src="/images/protezione-civile-screenshot1.jpg" alt="Image" class="center-image" /></p>

<p>A questo punto il BOT risponderà nel seguente modo:</p>

<p><img src="/images/protezione-civile-screenshot2.jpg" alt="Image" class="center-image" /></p>

<p>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.</p>

<p>Il codice della demo, lo trovate nel mio repository si <a href="https://github.com/gpirrotta/protezione-civile-bot">github</a>.</p>

<p>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.</p>

<p>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.</p>

<p>Se questo progetto vi è piaciuto un pò, mi aiutate a farlo conoscere in giro? Grazie</p>

<p><em>Twittami</em></p>

<p><a href="http://twitter.com/share?url=https://telegram.me/protezioneCivilePABot&amp;text=@gpirrotta+ProtezioneCivilePABot+-+Il+BOT+che+può+salvarti+la+vita+in+caso+di+emergenze"><img src="/images/twitter.png" alt="Image" class="center-image" /></a></p>

<p>That’s all folks! Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Developing an Ontology]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2015/10/18/developing-an-ontology/"/>
    <updated>2015-10-18T15:23:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2015/10/18/developing-an-ontology</id>
    <content type="html"><![CDATA[<p>The term ontology has its origin in philosophy; in the framework of
computer science, it represents a formal representation of knowledge
as a set of concepts within a domain, and the relationships between
these concepts.</p>

<!--More-->

<p><img src="/images/ontology.jpg" alt="Image" class="center-image" /></p>

<p>In the literature we can find many other definitions to explain and define what ontology
represents and means.</p>

<ul>
  <li>Defines the concepts and relationships used to describe and represent
an area of knowledge (<em>Ivan Herman, W3C</em>)</li>
  <li>A taxonomy combined with inference rules (<em>T. Berners–Lee, J.Hendler, O. Lassila, W3C</em>)</li>
  <li>The theory or study of being as such; i.e., of the basic characteristics
of all reality (<em>Encyclopedia Britannica</em>)</li>
  <li>The science of something and of nothing, of being and not–being,
of the thing and the mode of the thing, of substance and accident
(<em>Gottfried Wilhelm Leibniz - Sämtliche schriften und briefe.</em>)</li>
  <li>A formal definition of concepts (entities, relationships) of a given
area of knowledge, described in a standardized form (<em>Carugo &amp;
Pongor, 2002</em>)</li>
  <li>A systematic arrangement of all of the important categories of objects
or concepts which exist in some field of discourse, showing
the relations between them. (<em>Collaborative International Dictionary
of English</em>)</li>
  <li>An ontology can be defined as a structured and limited concept
catalog not unambiguously defined (<em>Uitermark</em>)</li>
</ul>

<p>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.</p>

<p>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.</p>

<p>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.</p>

<p>Now we will see briefly the steps to follow in the knowledge engineering
process.</p>

<h2 id="domain-definition">Domain Definition</h2>
<p>The starting point is the domain to model.</p>

<ul>
  <li>We have to specifically define the ontology domain.</li>
  <li>We have to define what use you intend to do with the ontology.</li>
  <li>For what types of questions the information in the ontology should
provide answers?</li>
  <li>Who will use and maintain the ontology?</li>
</ul>

<p>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 <em>competency questions</em>
(<em>Gruninger and Fox</em>) 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.</p>

<h2 id="reusing-existing-ontology">Reusing Existing Ontology</h2>
<p>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.</p>

<p>Some of the most famous ontologies in the Semantic Web area are:</p>

<ul>
  <li><a href="http://www.dublincore.org/documents/dces/"><em>Dublin Core</em></a>.
Dublin core ontology provides a simple and standardized
set of conventions for describing things online in ways
that make them easier to find. Dublin Core is widely used to
describe digital materials such as video, sound, image, text, and
composite media like Web pages.</li>
  <li><a href="http://xmlns.com/foaf/spec/"><em>FOAF</em></a>. The Friend of a Friend (FOAF) Ontology, defined using
OWL language, is an RDF extension created to define people,
their activity and their relationships with other people and other
objects. The FOAF project is creating a Web of machine–readable
pages describing people, the links between them and the things
they create and do.</li>
  <li><a href="http://www.w3.org/TR/skos-primer/">SKOS</a>. Simple Knowledge Organization System Ontology
is a common data model for sharing and linking knowledge organization
systems, such as thesauri, taxonomies, classification schemes and subject heading systems,
share a similar structure, via the Web.</li>
</ul>

<h2 id="identifying-concepts">Identifying Concepts</h2>

<p>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:</p>

<ul>
  <li><strong>Top-down:</strong> we start from the more general concepts to more
specific ones, up to the desired level of detail;</li>
  <li><strong>Bottom-up:</strong> we start from the more specific concepts and go up
the hierarchy to the more general concepts;</li>
  <li><strong>Hybrid:</strong> we start from the concepts of more immediate detection,
to specify or abstract them where necessary.</li>
</ul>

<h2 id="identifying-properties">Identifying Properties</h2>
<p>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 <em>intrinsic</em> properties which are those relating
to the concept content, independently of other things, including
its context and <em>extrinsic</em> 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:</p>

<ul>
  <li><strong>cardinality constraints</strong>: to specify the minimun and/or maximum
relationship cardinality between concepts. For example, each son
has exactly one mother and one father, and so forth;</li>
  <li><strong>value type constraints</strong>: to specify the literal value types. For example
string, number, boolean, date, etc;</li>
  <li><strong>domain constraints</strong>: to specify what instance types the properties
accept as subject;</li>
  <li><strong>range constraints</strong>: to specify what instance types the properties
accept as object.</li>
</ul>

<h2 id="reference">Reference</h2>

<ul>
  <li><em>Natalya F. Noy and Deborah L. McGuinness</em> -  Ontology
 development 101: A guide to creating your first ontology.</li>
  <li><em>Dean Allemang and Jim Hendler</em> -  SemanticWeb for the Working Ontologist:
 Effective Modeling in RDFS and OWL. Morgan Kaufmann,
 2008</li>
  <li><em>M. Gruninger and Fox</em> -  Methodology for the design and evaluation
 of ontologies. In In: Proceedings of the Workshop on Basic
 Ontological Issues in Knowledge Sharing IJCAI, Montreal, 1995.</li>
  <li><em>John Davies, Dieter Fensel, and Frank van Harmelen</em> -  Towards the
Semantic Web, Ontology-driven Knowledge Management. Wiley, 2002</li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Trasporti Amat di Palermo? C'è un Telegram per te! (aggiornato)]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2015/10/09/stazione-amat-di-palermo-ce-un-telegram-per-te/"/>
    <updated>2015-10-09T17:00:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2015/10/09/stazione-amat-di-palermo-ce-un-telegram-per-te</id>
    <content type="html"><![CDATA[<p>In questi ultimi tempi in rete si fa un gran parlare di <strong>BOT</strong> (abbreviazione di robot), ovvero quei programmi che fanno credere
all’utente di parlare con una persona reale ma che di fatto sono risponditori automatici utili per fornire servizi vari
come ad esempio il meteo, news, quiz, sondaggi, giochi, etc.</p>

<p>Il motivo di tutto questo proliferare di BOT è dovuto principalmente all’apertura di <a href="https://telegram.org/">Telegram</a>,
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.</p>

<!--More-->

<p>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.</p>

<p>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 <a href="http://www.twitter.com">Twitter</a> 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 <strong>cosaceintv</strong>,
in questo <a href="http://giovanni.pirrotta.it/blog/2013/10/04/cosaceintv-la-guida-tv-a-portata-di-tweet/">post</a>;
il sito del progetto è <a href="http://www.cosaceintv.it">cosaceintv.it</a>.</p>

<p>Tuttavia Twitter non consente di creare  BOT in modo nativo per cui, per raggiungere
 lo scopo, sono dovuto scendere a compromessi, chiamateli <em>workaround</em>.</p>

<p><em>Ma con Telegram la situazione cambia</em></p>

<p>Vero è che l’app non è diffusa come <a href="https://www.whatsapp.com/">WhatsApp</a>, l’attuale <em>killer application</em> nel settore
dell’instant messaging, (molti si aspettavano dei segnali di apertura API da WhatsApp in occasione
dell’ultima conferenza <a href="https://fbf8.com/">F8</a> di Facebook, ma invece <strong>nisba</strong>) ma è anche vero che Telegram sta guadagnando sempre più terreno grazie soprattutto a
scelte aziendali che si stanno rivelando strategicamente vincenti, come ad esempio</p>

<ul>
  <li>il rilascio del sorgente in opensource,</li>
  <li>l’alta attenzione nei confronti della sicurezza e della privacy degli utenti,</li>
  <li>la possibilità di creare chat segrete e autodistruggenti dopo un tempo prestabilito,</li>
  <li>un design pulito e gradevole,</li>
  <li>la totale gratuita,</li>
  <li>l’assenza di pubblicità</li>
  <li>ed infine, non meno importante, l’ultima feature aggiunta cioè la possibilità di creare BOT per la gestione di servizi personalizzati e l’interazione in modo programmatico attraverso API.</li>
</ul>

<p>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 <a href="http://storebot.me/top/">link</a>.</p>

<p><em>Ma anche in Italia cominciano a vedersi progetti interessanti.</em></p>

<p>A Prato <a href="https://twitter.com/il_tempe">Matteo Tempestini</a> ha sviluppato il <a href="https://telegram.me/emergenzeprato_bot">BOT Emergenze Prato</a>
per essere aggiornati in tempo reale su condizioni meteo, possibili allerte e segnalazioni.
A Lecce, utilizzando gli opendata del comune e non solo, <a href="https://twitter.com/piersoft">Pier Paolo Paolicelli (piersoft)</a> 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 <a href="http://www.tper.it/">TPER</a> fornisce informazioni aggiornate sui bus di
Bologna usando i servizi informativi e gli opendata. (<a href="https://telegram.me/tperbot">tperbot</a>.)</p>

<p>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 <strong>piersoft</strong> 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 <a href="http://www.amat.pa.it/index.php?option=com_content&amp;view=article&amp;id=1090&amp;Itemid=287">rilasciati</a>
dall’ azienda AMAT in formato GTFS con licenza OpenData.</p>

<p>La specifica <a href="https://developers.google.com/transit/gtfs/reference">GTFS</a> (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.</p>

<p>La specifica struttura i dati organizzandoli in un insieme di file CSV.</p>

<p>I più importanti sono i seguenti:</p>

<ul>
  <li><strong>agency</strong> - informazioni inerenti l’azienda che gestisce i trasporti;</li>
  <li><strong>routes</strong> - informazioni sulle linee dei trasporti;</li>
  <li><strong>trips</strong> - informazioni inerenti le corse per ciascuna linea;</li>
  <li><strong>stops</strong> - le fermate geolocalizzate;</li>
  <li><strong>stop_times</strong> - l’orario di arrivo e partenza e la sequenza per ogni corsa in ciascuna fermata;</li>
  <li><strong>calendar</strong> - periodo del servizio trasporti su base settimanale;</li>
  <li><strong>calendar_dates</strong> - date in cui vi sono delle eccezioni rispetto a quanto descritto
in <em>calendar</em> (ad. es. feste)</li>
</ul>

<p>Per la specifica completa si rimanda alla <a href="https://developers.google.com/transit/gtfs/reference">pagina ufficiale GTFS</a></p>

<p>Quindi mettiamoci al lavoro e scarichiamo i dati dal sito AMAT di Palermo.</p>

<p>###Ma cosa vedono i miei occhi???</p>

<p><img src="/images/crying-meme.png" alt="Image" class="center-image" /></p>

<p>~~ Dalla pagina AMAT Palermo, sezione OpenData, i dati GTFS risultano <strong>aggiornati al 2014</strong>
purtroppo!~~</p>

<p>~~ 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.~~</p>

<p>** Ho preso una cantonata, dopo aver pubblicato il post il buon <a href="http://twitter.com/aborruso">Andrea Borruso</a> 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! **</p>

<p>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 <a href="http://giovanni.pirrotta.it/blog/2015/08/12/parking-messina-quando-la-ztl-incontra-gli-open-data/">post</a>.</p>

<p>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 <em>punzolare</em>
l’azienda AMAT al rilascio dei dati aggiornati.~~</p>

<p><em>Mettiamoci al lavoro!</em></p>

<p>~~ Per prima cosa scarico il file zippato GTFS dalla <a href="http://www.amat.pa.it/index.php?option=com_content&amp;view=article&amp;id=1090&amp;Itemid=287">pagina</a> OpenData AMAT Palermo.~~</p>

<p>Per prima cosa scarico il file zippato GTFS dalla <a href="http://www.comune.palermo.it/opendata_dld.php?id=349">pagina</a> OpenData del Comune di  Palermo.</p>

<p>Decido di caricare tutti i file CSV all’interno di un dabatase Mysql, per cui inizio a cercare in rete degli
<a href="https://en.wikipedia.org/wiki/Data_definition_language">statement DDL</a> 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.</p>

<p>###Errore!!!</p>

<p><em>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.</em></p>

<p>####REGOLE D’ORO</p>

<ol>
  <li>Analizzare <strong>sempre</strong> e <strong>bene</strong> la qualità dei dati da importare <strong>prima</strong> di importarli</li>
  <li>GOTO 1 ;-)</li>
</ol>

<p>La maggior parte dei campi <strong>id</strong> degli schemi che ho trovano in rete è in formato intero
mentre nella maggior parte dei record dei dati GTFS AMAT il campo <strong>id</strong> contiene anche valori
alfanumerici, ergo trasformate tutti gli id da <strong>int</strong> a <strong>varchar</strong>.</p>

<p>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 <strong>E</strong>. Lo script erroneamente parsava i codici contenenti
il carattere <strong>E</strong> come formato esadecimale considerandoli interi invece di stringa.
Trovate la versione fixata nel mio <a href="https://github.com/gpirrotta/py-gtfs-mysql">repo</a>.</p>

<p>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
<a href="https://core.telegram.org/bots/api">link</a>.
Per lo sviluppo del codice ho usato questa <a href="https://github.com/irazasyed/telegram-bot-sdk">libreria PHP</a>
 a sua volta descritta in modo molto chiaro <a href="https://irazasyed.github.io/telegram-bot-sdk/">qui</a>. La libreria è stata sviluppata per il framework PHP
<a href="http://laravel.com/">Laravel</a>
ma può essere utilizzata anche in modalità standalone.</p>

<p>La prima cosa da fare è creare il bot. Per fare questo bisogna aggiungere sul proprio
client Telegram l’utente <strong>@BotFather</strong> e inviargli il seguente comando <strong>/newbot</strong>.
Dopo aver risposto ad alcune domande, ad esempio nome ed username del BOT, viene generato
un <strong>TOKEN</strong> che rappresenta il ponte di collegamento tra il nostro software e Telegram.
Per maggiori dettagli sulla creazione dei bot fate riferimento alla documentazione ufficiale.</p>

<p>Per poter interagire con Telegram scriviamo quindi:</p>

<div class="language-php highlighter-rouge"><pre class="highlight"><code>    $telegram = new Api('BOT TOKEN');
    $response = $telegram-&gt;getMe();
</code></pre>
</div>

<p>Nella <em>response</em> troveremo informazioni sul bot creato.</p>

<p>Per poter inviare messaggi all’utente bisognerà indicare, oltre al messaggio, anche l’<strong>ID</strong> della chat in modo che
solo l’utente che ha fatto la richiesta possa ricevere il messaggio di ritorno.</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  Telegram</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line">$response = $telegram-&gt;sendMessage('CHAT_ID', 'Hello World');</div></div></pre></div></figure>

<p>Oltre a messaggi di testo il nostro BOT può rispondere anche con immagini, audio, video, allegati, etc.:</p>

<div class="language-php highlighter-rouge"><pre class="highlight"><code>$response = $telegram-&gt;sendPhoto('CHAT_ID', 'path/to/photo.jpg', 'Some caption');
</code></pre>
</div>

<p>Ma come fa l’utente a chiedere le informazioni al BOT? Inviando dei <strong>comandi</strong>.</p>

<p>Per creare un comando, usando la libreria PHP, è necessario estendere la classe <strong>Command</strong> e implementare il metodo
 <strong>handle</strong>.
Creare un comando è un’operazione veramente banale, è infatti necessario inizializzare semplicemente la variabile <em>name</em>
con il nome del comando che si vuole creare. Nell’esempio si sta creando il comando <em>/start</em>.</p>

<p>Nell’esempio che segue, digitando da Telegram il comando <em>/start</em> il BOT risponderà con <strong>Hello World!</strong>;</p>

<div class="language-php highlighter-rouge"><pre class="highlight"><code>    <span class="cp">&lt;?php</span>

    <span class="k">use</span> <span class="nx">Telegram\Bot\Commands\Command</span><span class="p">;</span>

    <span class="k">class</span> <span class="nc">StartCommand</span> <span class="k">extends</span> <span class="nx">Command</span>
    <span class="p">{</span>

        <span class="k">protected</span> <span class="nv">$name</span> <span class="o">=</span> <span class="s2">"start"</span><span class="p">;</span>
        <span class="k">protected</span> <span class="nv">$description</span> <span class="o">=</span> <span class="s2">"Start Command to get you started"</span><span class="p">;</span>

        <span class="k">public</span> <span class="k">function</span> <span class="nf">handle</span><span class="p">(</span><span class="nv">$arguments</span><span class="p">)</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="na">replyWithMessage</span><span class="p">(</span><span class="s1">'Hello World!'</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
</code></pre>
</div>

<p>Non mi soffermerò oltre su questa libreria perchè, come già detto, è presente una documentazione completa ed esaustiva.</p>

<p>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 <em>SQL</em> più importanti.</p>

<p>La prima versione di <strong>amatPABot</strong>, questo il nome del BOT, implementa due funzionalità:</p>

<ul>
  <li><strong>Orario Linee</strong></li>
  <li><strong>Fermata più vicina</strong></li>
</ul>

<p><img src="/images/amat-bot-2.jpg" alt="Image" class="center-image" /></p>

<p>###Orario Linee</p>

<p>Le informazioni sono tutte presenti nel db per cui all’interno del metodo <em>handle</em> viene
gestita la logica per estrarre le informazioni relative alle linee AMAT di Palermo.</p>

<p>La query SQL utilizzata per mostrare le linee:</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  SQL</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">SELECT</span> <span class="n">route_id</span><span class="p">,</span> <span class="n">route_long_name</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">FROM</span> <span class="n">routes</span>
</div></div><div data-line="3" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">ORDER</span> <span class="k">BY</span> <span class="n">route_id</span> <span class="k">asc</span></div></div></pre></div></figure>

<p><img src="/images/amat-bot-3.jpg" alt="Image" class="center-image" /></p>

<p>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.</p>

<p>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.</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  SQL</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">SELECT</span> <span class="o">*</span> <span class="k">from</span> <span class="n">stop_times</span><span class="p">,</span> <span class="n">trips</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">WHERE</span> <span class="n">stop_times</span><span class="p">.</span><span class="n">trip_id</span> <span class="o">=</span> <span class="n">trips</span><span class="p">.</span><span class="n">trip_id</span> <span class="k">and</span>
</div></div><div data-line="3" class="code-highlight-row numbered"><div class="code-highlight-line">       <span class="n">trips</span><span class="p">.</span><span class="n">route_id</span> <span class="o">=</span> <span class="p">:</span><span class="n">route_id</span> <span class="k">and</span> <span class="n">service_id</span> <span class="o">=</span> <span class="p">:</span><span class="n">service_id</span>
</div></div><div data-line="4" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">GROUP</span> <span class="k">BY</span> <span class="n">stop_times</span><span class="p">.</span><span class="n">trip_id</span></div></div></pre></div></figure>

<p>A questo punto l’output ottenuto è il seguente:</p>

<p><img src="/images/amat-bot-4.jpg" alt="Image" class="center-image" /></p>

<p>Passiamo adesso all’altra funzionalità.</p>

<p>###Fermata più vicina</p>

<p>Per ottenere informazioni sulla fermata più vicina  dobbiamo per prima cosa cliccare sulla graffetta e inviare la
nostra posizione geografica.</p>

<p><img src="/images/graffetta-amat.jpg" alt="Image" class="center-image" /></p>

<p><img src="/images/posizione-amat.jpg" alt="Image" class="center-image" /></p>

<p>Fatto ciò un comando calcolerà le 5 fermate più vicine recuperandole dalla tabella <em>stops</em> eseguendo la seguente query:</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  SQL</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">SELECT</span> <span class="n">stop_id</span><span class="p">,</span> <span class="n">stop_name</span><span class="p">,</span> <span class="n">stop_lat</span><span class="p">,</span> <span class="n">stop_lon</span><span class="p">,</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="p">(</span><span class="mi">6371</span> <span class="o">*</span> <span class="n">acos</span><span class="p">(</span> <span class="n">cos</span><span class="p">(</span> <span class="n">radians</span><span class="p">(:</span><span class="n">latitude</span><span class="p">))</span> <span class="o">*</span>
</div></div><div data-line="3" class="code-highlight-row numbered"><div class="code-highlight-line">              <span class="n">cos</span><span class="p">(</span> <span class="n">radians</span><span class="p">(</span> <span class="n">stop_lat</span> <span class="p">))</span> <span class="o">*</span>
</div></div><div data-line="4" class="code-highlight-row numbered"><div class="code-highlight-line">              <span class="n">cos</span><span class="p">(</span> <span class="n">radians</span><span class="p">(</span> <span class="p">:</span><span class="n">longitude</span> <span class="p">)</span> <span class="o">-</span>
</div></div><div data-line="5" class="code-highlight-row numbered"><div class="code-highlight-line">              <span class="n">radians</span><span class="p">(</span><span class="n">stop_lon</span><span class="p">))</span> <span class="o">+</span>
</div></div><div data-line="6" class="code-highlight-row numbered"><div class="code-highlight-line">              <span class="n">sin</span><span class="p">(</span> <span class="n">radians</span><span class="p">(:</span><span class="n">latitude</span><span class="p">))</span>
</div></div><div data-line="7" class="code-highlight-row numbered"><div class="code-highlight-line">              <span class="o">*</span> <span class="n">sin</span><span class="p">(</span><span class="n">radians</span><span class="p">(</span><span class="n">stop_lat</span><span class="p">))))</span> <span class="k">AS</span> <span class="n">distance</span>
</div></div><div data-line="8" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">FROM</span> <span class="n">stops</span>
</div></div><div data-line="9" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">HAVING</span> <span class="n">distance</span> <span class="o">&lt;</span> <span class="mi">250000</span>
</div></div><div data-line="10" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">ORDER</span> <span class="k">BY</span> <span class="n">distance</span> <span class="k">limit</span> <span class="mi">5</span><span class="nv">"</span></div></div></pre></div></figure>

<p>Il valore <em>6371</em> è la lunghezza del raggio della terra. La formula utilizzata calcola la distanza in <strong>KM</strong>
tra due punti espressi in latitudine e longitudine. Si tratta di una variante dell’<em>Haversine Formula</em>,
per maggiori informazioni fate riferimento <a href="https://en.wikipedia.org/wiki/Haversine_formula">qui</a> e
<a href="http://www.codecodex.com/wiki/Calculate_distance_between_two_points_on_a_globe#Haversine_Formula">qui</a>.</p>

<p>Per ogni fermata recupero anche il nome delle linee passanti.</p>

<figure class="code-highlight-figure"><figcaption class="code-highlight-caption"><span class="code-highlight-caption-title">  SQL</span></figcaption><div class="code-highlight"><pre class="code-highlight-pre"><div data-line="1" class="code-highlight-row numbered"><div class="code-highlight-line"><span class="k">SELECT</span> <span class="n">route_id</span>
</div></div><div data-line="2" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="k">FROM</span> <span class="n">stops</span><span class="p">,</span> <span class="n">stop_times</span><span class="p">,</span> <span class="n">trips</span>
</div></div><div data-line="3" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="k">WHERE</span> <span class="n">stops</span><span class="p">.</span><span class="n">stop_id</span><span class="o">=</span><span class="n">stop_times</span><span class="p">.</span><span class="n">stop_id</span>
</div></div><div data-line="4" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="k">AND</span> <span class="n">stop_times</span><span class="p">.</span><span class="n">trip_id</span> <span class="o">=</span> <span class="n">trips</span><span class="p">.</span><span class="n">trip_id</span>
</div></div><div data-line="5" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="k">AND</span> <span class="n">stops</span><span class="p">.</span><span class="n">stop_id</span> <span class="o">=</span> <span class="p">:</span><span class="n">stop_id</span>
</div></div><div data-line="6" class="code-highlight-row numbered"><div class="code-highlight-line">    <span class="k">GROUP</span> <span class="k">BY</span> <span class="n">route_id</span></div></div></pre></div></figure>

<p>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)</p>

<p><img src="/images/risposta-fermate.jpg" alt="Image" class="center-image" /></p>

<p>Per il <em>deploy</em> del BOT ho usato <a href="w.cloudflare.com/ssl">Cloudflare</a> per avere una
connessione SSL, condizione necessaria per poter utilizzare il <a href="https://core.telegram.org/bots/api#setwebhook">WebHook</a>
in Telegram, invece del metodo manuale <a href="https://core.telegram.org/bots/api#getting-updates">getUpdates</a>.</p>

<p>###Ricapitolando</p>

<ul>
  <li><del>I dati mostrati dal BOT non sono aggiornati al 2015 ma all’ultimo trimestre 2014;</del></li>
  <li>Il BOT è funzionante con i dati aggiornati al 2015;</li>
  <li>Sulla correttezza e consistenza dei dati non garantisco. Non prendetevela con me
per eventuali inesattezze e/o sbagli :-)</li>
  <li><del>E’ possibile aggiungere tante altre funzionalità ma la vera <strong>mission</strong> di questa prima versione è costringere
l’AMAT di Palermo al rilascio dei dati aggiornati al 2015.</del></li>
  <li>Il BOT sviluppato è <em>ancora</em> una demo. E’ possibile aggiungere altre funzionalità, il limite è la fantasia.</li>
</ul>

<p>Per interagire con il bot dovete aggiungere al vostro client Telegram il contatto: <a href="https://telegram.me/amatpabot">@amatPABot</a>.</p>

<p><a href="https://telegram.me/amatpabot"><img src="/images/AMATBOTlogo.jpg" alt="Image" class="center-image" /></a></p>

<p>Il codice sorgente lo trovate <a href="https://github.com/gpirrotta/amat-pa-bot">qui</a>.</p>

<p><strong>Attenzione, è’ una versione ancora poco stabile, non pronta per andare in produzione.</strong></p>

<p>~~ I dati non sono aggiornati quindi, <em>in questo momento</em>, il BOT non è molto utile; però,~~ Se questo lavoro vi è
piaciuto un pò, potreste contribuire <del>alla causa aiutandomi a fare un pò di tam-tam mediatico sui social network.</del>
a farlo conoscere in giro sui social, grazie.</p>

<p><em>Twittami</em></p>

<p><a href="http://twitter.com/share?url=https://telegram.me/amatpabot&amp;text=@gpirrotta+AmatPABot+-+AMAT+Palermo+BOT+Informazioni+trasporti+pubblici"><img src="/images/twitter.png" alt="Image" class="center-image" /></a></p>

<p>Idee, critiche e suggerimenti sono benvenuti.</p>

<p>That’s all folks! Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Parking In Messina. quando la ZTL incontra gli Open Data]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2015/08/12/parking-messina-quando-la-ztl-incontra-gli-open-data/"/>
    <updated>2015-08-12T06:00:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2015/08/12/parking-messina-quando-la-ztl-incontra-gli-open-data</id>
    <content type="html"><![CDATA[<p>Metti che è da una vita che non aggiorno questo blog, metti che sono sostenitore da
tanti anni degli <a href="https://it.wikipedia.org/wiki/Dati_aperti" target="blank">Open Data</a> e di tutto ciò che gli gira attorno, metti che finalmente sono in ferie e ho
qualche giorno libero da dedicare a qualche idea che mi porto dietro da qualche mese, bene, metti insieme tutto questo :-)</p>

<p>Ma partiamo dall’inizio, a circa un mese fa.</p>

<!--More-->

<p>Lo scorso <strong>10-11-12 luglio</strong> si è svolta a Patti (ME) l’<a href="http://www.lostrettodigitale.org/summer-school-su-opendata-il-programma/" target="blank">Open Data Summer School</a>,
organizzata dallo <a href="http://www.lostrettodigitale.org/" target="blank">Stretto Digitale </a>
nei locali del <a href="https://caffegalante.wordpress.com/" target="blank">caffè Galante</a>.
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 <a href="https://twitter.com/piersoft" target="blank">Pier Francesco Paolicelli (Piersoft)</a>,
<a href="https://twitter.com/aborruso" target="blank">Andrea Borruso</a> e
<a href="https://twitter.com/nelsonmau" target="blank">Andrea Nelson Mauro</a>.
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
<a href="https://caffegalante.wordpress.com/2015/08/10/la-summer-school-sugli-open-data-de-lo-stretto-digitale/" target="blank">post</a> di
<a href="https://twitter.com/picomiles" target="blank">Nino Galante</a>.</p>

<p>In passato ho avuto modo di lavorare con gli Open Data sia per motivi di ricerca in ambito Semantic Web
(<a target="blank" href="http://www.linkedopendata.it/datasets/loius-linking-italian-university-statistics-project">LOIUS Platform</a>),
sia per progetti personali (<a target="blank" href="http://giovanni.pirrotta.it/blog/2013/07/22/openalbopretorio-apriti-sesamo/"> OpenAlboPretorio</a>,
<a target="blank" href="http://giovanni.pirrotta.it/blog/2013/08/28/opengazzettaufficiale-la-legge-e-open-per-tutti/">OpenGazzettaUfficiale</a> - offline -,
<a target="blank" href="https://github.com/gpirrotta/opensanita">OpenSanita</a>).
Secondo i principi <strong>Open Data</strong> i dati andrebbero trattati come <strong>beni comuni</strong>, in quanto appartenenti al genere umano.
Per definirsi <strong>Open Data</strong> i dati</p>

<ul>
  <li>devono essere disponibili secondo i termini di una licenza che ne permetta l’utilizzo da parte di chiunque, anche
 per finalità commerciali, in formato disaggregato;</li>
  <li>devono essere accessibili attraverso le tecnologie dell’informazione in formati aperti e in modo automatico da parte di programmi;</li>
  <li>devono essere resi disponibili gratuitamente.</li>
</ul>

<p>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 <a target="blank" href="http://www.openstreetmap.org/">OpenStreetMap </a>
(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.</p>

<p>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.</p>

<p><img src="/images/challenge_accepted.jpg" alt="Image" class="center-image" /></p>

<p>Andando sul sito dell’<a href="http://www.atmmessina.it" target="blank">ATM Messina</a> le uniche informazioni relative
 alle tariffe orarie dei parcheggi in ZTL sono presenti in questa <a href="http://www.atmmessina.it/altri.asp?id=5" target="blank">pagina</a>.
Nella stessa pagina è presente anche la piantina dei lotti ZTL di seguito mostrata.</p>

<p><img src="/images/piantinaZTL.jpg" alt="Image" class="center-image" /></p>

<p><strong>Primi guai all’orizzonte.</strong> In calce alla <a href="http://www.atmmessina.it/altri.asp?id=5" target="blank">pagina del sito </a>
è riportato il seguente disclaimer:</p>

<div class="highlighter-rouge"><pre class="highlight"><code>Copyright C 2015 - ATM MESSINA -   E' vietata la riproduzione anche parziale.
</code></pre>
</div>

<p><img src="/images/meme-why.jpg" alt="Image" class="center-image" /></p>

<p>I dati quindi non possono essere usati neanche in modo parziale. In realtà l’ATM, essendo un <strong>ente strumentale</strong> del comune,
<em>dovrebbe</em>  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.</p>

<p>L’ATM dovrebbe seguire l’esempio di altre municipalizzate italiane  (come ad esempio del comune di <a href="http://www.agenziamobilita.roma.it/it/progetti/open-data/" target="blank">Roma</a>),
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ù <strong>Smart</strong>.</p>

<p>Tuttavia, immaginiamo per un attimo che non esista nessun copyright su questi dati, anzi immaginiamo che i dati siano rilasciati
in modalità <strong>Open Data</strong>.  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?</p>

<p>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à <strong>Open Data</strong>
promuove l’innovazione permanente favorendo lo sviluppo economico del terzo millennio.</p>

<p><strong>Disclaimer</strong>
<em>L’intero progetto, chiamato “PARKING IN MESSINA”, è da intendersi volutamente a carattere DIDATTICO, SPERIMENTALE e
assolutamente NON A SCOPO DI LUCRO.</em></p>

<p>Cominciamo allora!</p>

<p>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 <a href="http://umap.openstreetmap.fr/it/" target="blank">UMAP</a>,
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).</p>

<p>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.</p>

<h2 id="messina-piano-tariffario-ztl">Messina Piano Tariffario ZTL</h2>
<p><a href="http://umap.openstreetmap.fr/it/map/messina-piano-tariffario-aree-ztl_49528">Visualliza schermo intero</a>&lt;/p&gt;</p>

<iframe width="100%" height="700px" frameborder="0" src="http://umap.openstreetmap.fr/it/map/messina-piano-tariffario-aree-ztl_49528?scaleControl=false&amp;miniMap=false&amp;scrollWheelZoom=false&amp;zoomControl=true&amp;allowEdit=false&amp;moreControl=true&amp;datalayersControl=true&amp;onLoadPanel=undefined&amp;captionBar=false"></iframe>

<p>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.</p>

<p>Tutti felici, tutti contenti, arrivederci e grazie?</p>

<p><img src="/images/lol.jpg" alt="Image" class="center-image" /></p>

<h2 id="ma-anche-no">Ma anche no!</h2>

<p>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 <strong>pigra</strong>, 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!</p>

<p>Per eliminare questo spreco è necessario quindi:</p>

<ul>
  <li>far capire all’applicazione la posizione del mio dispositivo mobile e</li>
  <li>se sono all’interno della ZTL di Messina,</li>
  <li>l’applicazione deve restituirmi le tariffe vigenti per quella via.</li>
</ul>

<p>Procediamo per gradi.</p>
<h4 id="far-capire-allapplicazione-la-posizione-del-mio-dispositivo">Far capire all’applicazione la posizione del mio dispositivo</h4>

<p>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:</p>

<p><img src="/images/geolocation-html5-browser-support.jpg" alt="Image" class="center-image" /></p>

<p>Il metodo da invocare per ottenere la posizione dell’utente è <code class="highlighter-rouge">getCurrentPosition()</code></p>

<div class="highlighter-rouge"><pre class="highlight"><code>    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 +
        "&lt;br&gt;Longitude: " + position.coords.longitude;
    }
</code></pre>
</div>
<p>In questo modo otteniamo la latitudine e la longitudine della posizione in cui si trova il dispositivo.</p>

<h4 id="se-sono-allinterno-della-ztl-di-messina">Se sono all’interno della ZTL di Messina</h4>
<p>Qui risiede il <strong>core</strong> dell’applicazione. Anche qui procediamo per gradi.</p>

<p>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.</p>

<p>Per la risoluzione di questo problema esistono in letteratura diversi <a target="blank" href="http://paulbourke.net/geometry/polygonmesh/">algoritmi geometrici</a>.
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 è <strong>interno</strong> al poligono, se la somma è 0 il punto è <strong>esterno</strong> al poligono.
Per maggiori informazioni fate riferimento alla pagina sopra menzionata.</p>

<p>Ho rilasciato la libreria <code class="highlighter-rouge">GPSPolygon</code> sul mio repository <a href="https://github.com/gpirrotta/gpspolygon" target="blank">github</a>.</p>

<p>Ho preparato anche una API Demo da invocare nel seguente modo:</p>

<pre><code class="language-http://www.pirrotta.it/gps-polygon-api/isPointInsidePolygon.php">
**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'&lt;a href="http://www.pirrotta.it/gps-polygon-api/isPointInsidePolygon.php?latitude=38.19396&amp;longitude=15.55599&amp;polygon=38.197344511074,15.556431412697;38.197129504006,15.557370185852;38.192909334811,15.55691421032;38.193706168703,15.554140806198;38.197344511074,15.556431412697" target="blank"&gt;URL DEMO&lt;/a&gt;
da invocare e questo il risultato:

</code></pre>
<p>{
    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”
    }
}</p>

<div class="highlighter-rouge"><pre class="highlight"><code>
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
&lt;a href="http://www.pirrotta.it/gps-polygon-api/" target="blank"&gt;pagina&lt;/a&gt; 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 &lt;a  href="/ext/ztl.json" target="blank"&gt;GEOJSON&lt;/a&gt;
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 &lt;a href="http://geocoder-php.org/Geocoder/" target="blank"&gt;**Geocoder**&lt;/a&gt;
sviluppata da &lt;a href="http://williamdurand.fr/" target="blank"&gt;William Durand &lt;/a&gt;.
A partire da una località qualsiasi la libreria restituisce le rispettive coordinate geografiche e viceversa,
consentendo  di scegliere &lt;a href="http://geocoder-php.org/Geocoder/#providers" target="blank"&gt;uno o più provider geografici &lt;/a&gt;;
 ovviamente tra i provider non poteva mancare ```OpenStreetMap```.

Il codice da usare è veramente minimo:

</code></pre>
</div>
<p>&lt;?
    use Geocoder\HttpAdapter\CurlHttpAdapter;
    use Geocoder\Provider\OpenStreetMapProvider;</p>

<div class="highlighter-rouge"><pre class="highlight"><code>$curl     = new CurlHttpAdapter();
$geocoder = new OpenStreetMapProvider($curl);

$results = $geocoder-&gt;getReversedData(array(38.19245, 15.55608));

$street = $results[0]['streetName'];

print $street; // via San Giacomo
</code></pre>
</div>

<div class="highlighter-rouge"><pre class="highlight"><code>
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 <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://goratchet.com/"</span> <span class="na">target=</span><span class="s">"blank"</span><span class="nt">&gt;</span>**Ratchet**<span class="nt">&lt;/a&gt;</span>, framework
particolarmente indicato per lo sviluppo rapido di prototipi di applicazioni su dispositivi mobili.

Per la visualizzazione della mappa geografica ho usato la libreria <span class="nt">&lt;a</span> <span class="na">href=</span><span class="s">"http://openlayers.org/"</span> <span class="na">target=</span><span class="s">"blank"</span><span class="nt">&gt;</span>OpenLayer<span class="nt">&lt;/a&gt;</span> grazie alla quale, in maniera  semplice e immediata,
ho inserito la mappa e il marker della posizione dell'utente in questo modo:


``` javascript
<span class="nt">&lt;html&gt;</span>
    <span class="nt">&lt;body&gt;</span>
      <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"mapdiv"</span><span class="nt">&gt;&lt;/div&gt;</span>
      <span class="nt">&lt;script </span><span class="na">src=</span><span class="s">"http://www.openlayers.org/api/OpenLayers.js"</span><span class="nt">&gt;&lt;/script&gt;</span>
      <span class="nt">&lt;script&gt;</span>
        <span class="nx">map</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">OpenLayers</span><span class="p">.</span><span class="nx">Map</span><span class="p">(</span><span class="s2">"mapdiv"</span><span class="p">);</span>
        <span class="nx">map</span><span class="p">.</span><span class="nx">addLayer</span><span class="p">(</span><span class="k">new</span> <span class="nx">OpenLayers</span><span class="p">.</span><span class="nx">Layer</span><span class="p">.</span><span class="nx">OSM</span><span class="p">());</span>

        <span class="kd">var</span> <span class="nx">lonLat</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">OpenLayers</span><span class="p">.</span><span class="nx">LonLat</span><span class="p">(</span> <span class="o">-</span><span class="mf">0.1279688</span> <span class="p">,</span><span class="mf">51.5077286</span> <span class="p">)</span>
              <span class="p">.</span><span class="nx">transform</span><span class="p">(</span>
                <span class="k">new</span> <span class="nx">OpenLayers</span><span class="p">.</span><span class="nx">Projection</span><span class="p">(</span><span class="s2">"EPSG:4326"</span><span class="p">),</span>
                <span class="nx">map</span><span class="p">.</span><span class="nx">getProjectionObject</span><span class="p">()</span>
              <span class="p">);</span>

        <span class="kd">var</span> <span class="nx">zoom</span><span class="o">=</span><span class="mi">16</span><span class="p">;</span>

        <span class="kd">var</span> <span class="nx">markers</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">OpenLayers</span><span class="p">.</span><span class="nx">Layer</span><span class="p">.</span><span class="nx">Markers</span><span class="p">(</span> <span class="s2">"Markers"</span> <span class="p">);</span>
        <span class="nx">map</span><span class="p">.</span><span class="nx">addLayer</span><span class="p">(</span><span class="nx">markers</span><span class="p">);</span>

        <span class="nx">markers</span><span class="p">.</span><span class="nx">addMarker</span><span class="p">(</span><span class="k">new</span> <span class="nx">OpenLayers</span><span class="p">.</span><span class="nx">Marker</span><span class="p">(</span><span class="nx">lonLat</span><span class="p">));</span>

        <span class="nx">map</span><span class="p">.</span><span class="nx">setCenter</span> <span class="p">(</span><span class="nx">lonLat</span><span class="p">,</span> <span class="nx">zoom</span><span class="p">);</span>
      <span class="nt">&lt;/script&gt;</span>
    <span class="nt">&lt;/body&gt;</span>
<span class="nt">&lt;/html&gt;</span>
</code></pre>
</div>

<h2 id="simulazioni">Simulazioni</h2>

<h3 id="nexus-5-dentro-ztl">Nexus 5 (dentro ZTL)</h3>
<p><img src="/images/nexus5-parking.jpg" alt="Image" class="center-image" /></p>

<h3 id="nokia-lumia-520-dentro-ztl">Nokia Lumia 520 (dentro ZTL)</h3>
<p><img src="/images/nokia-parking.jpg" alt="Image" class="center-image" /></p>

<h3 id="iphone-5-fuori-ztl">Iphone 5 (fuori ZTL)</h3>
<p><img src="/images/iphone5-parking.jpg" alt="Image" class="center-image" /></p>

<h3 id="blackberry-playbook-fuori-ztl">Blackberry Playbook (fuori ZTL)</h3>
<p><img src="/images/blackberry-playbook-parking.jpg" alt="Image" class="center-image" /></p>

<h2 id="considerazioni-finali">Considerazioni finali</h2>
<p>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.</p>

<p>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…</p>

<p>Purtroppo però, come dette sopra, i dati di partenza non sono <strong>Open Data</strong> quindi l’applicazione non potrebbe esistere.</p>

<p>Pertanto, mi auguro che questo esempio (che ribadisco essere a scopo <em>DIDATTICO</em> e <em>NON A SCOPO DI LUCRO</em>) 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à
<strong>Open Data</strong>.</p>

<h3 id="demo">DEMO</h3>
<p>La web-app <strong>PARKING IN MESSINA</strong> è disponibile al seguente link: <a href="http://www.pirrotta.it/parking-in-messina/" target="blank">DEMO</a></p>

<p>Feedback, bug, consigli, pareri e critiche costruttive sono i benvenuti!</p>

<p>That’s all folks! Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Behat-Gherkin/Mink: one translator to rule them all]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2015/02/17/behat-gherkin-mink-one-translator-to-rule-them-all/"/>
    <updated>2015-02-17T08:12:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2015/02/17/behat-gherkin-mink-one-translator-to-rule-them-all</id>
    <content type="html"><![CDATA[<p>Recently I started to develop my software using <a href="http://it.wikipedia.org/wiki/Behavior-driven_development">Behaviour-Driven Development</a> approach and, since my
 preferred programming language is PHP, I chose one of the most popular existing acceptance
 testing tool, namely <a href="http://behat.org/">Behat</a>.</p>

<!--More-->

<p><img src="/images/behat.png" alt="Image" class="center-image" /></p>

<p>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.</p>

<p>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.</p>

<p>In order to know the Gherkin keyword translation for the Italian language you must digit in console:</p>

<div class="highlighter-rouge"><pre class="highlight"><code>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 &lt;agent1&gt;
    E there is agent &lt;agent2&gt;
    Quando I erase agent &lt;agent2&gt;'s memory
    Allora there should be agent &lt;agent1&gt;
    Ma there should not be agent &lt;agent2&gt;

    Esempi:
      | agent1 | agent2 |
      | D      | M      |
</code></pre>
</div>

<p>Using behat in Web applications I like the <a href="https://github.com/Behat/MinkExtension">Behat extension for Mink</a>,
a browser emulator abstraction layer. It hides emulator differences behind a single consistent
API and represents a bridge towards real browser emulators such as</p>

<ul>
  <li><a href="http://mink.behat.org/en/latest/drivers/goutte.html">Goutte</a></li>
  <li><a href="http://mink.behat.org/en/latest/drivers/browserkit.html">BrowserKit</a></li>
  <li><a href="http://mink.behat.org/en/latest/drivers/selenium2.html">Selenium2</a></li>
  <li><a href="http://mink.behat.org/en/latest/drivers/zombie.html">Zombie</a></li>
  <li><a href="http://mink.behat.org/en/latest/drivers/sahi.html">Sahi</a></li>
  <li><a href="http://mink.behat.org/en/latest/drivers/selenium.html">Selenium</a></li>
</ul>

<p>Mink extension supports 17 different languages so I found the Italian XLIFF file, in the source code,
 (<a href="https://github.com/Behat/MinkExtension/blob/master/i18n/it.xliff">see github</a>) containing the patterns of Italian
 sentences recognized by the library.</p>

<p>Apart some <a href="http://blog.lepine.pro/wp-content/uploads/2012/03/behat-cheat-sheet-en.pdf">English PDF cheatsheets</a>
I have not found much readable native language syntax documentation about
Behat and Mink. (Let me know if you know).</p>

<p>So, to fill the gap, I developed the <a href="http://www.pirrotta.it/behat-mink-translator">Behat-Gherkin/Mink Translator</a>
in order to generate on the fly the native language syntax documentation that PHP developers can use for their job.</p>

<p>Thas’all folks! Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Semantic Web Ingredients: the SPARQL language]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2014/10/27/semantic-web-ingredients-the-sparql-language/"/>
    <updated>2014-10-27T18:15:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2014/10/27/semantic-web-ingredients-the-sparql-language</id>
    <content type="html"><![CDATA[<p>In the previous <a href="http://giovanni.pirrotta.it/blog/2014/07/30/semantic-web-ingredients-rdfa/">post</a> of this series I described the RDFa language specifying the most important advantages in using it. 
Now it’s the turn of the SPARQL, a sort of SQL language for the Semantic Web world. 
<!--More-->#}</p>

<p><img src="/images/semantic-web/sparql.png" alt="Image" class="center-image" /></p>

<p>The <a href="http://www.w3.org/TR/rdf-sparql-query/">SPARQL language</a> is a W3C Recommendation defining a standard way to retrieve data from RDF graphs distributed on the Web. SPARQL performs complex <code class="highlighter-rouge">joins</code> exploring data by querying unknown relationships. The querying criterion is based on pattern matching mechanisms, and, in particular, on <code class="highlighter-rouge">triple pattern</code> constructs, that reflect the RDF triple assertion model and provide a flexible model for finding matches.</p>

<p>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 <code class="highlighter-rouge">?book ex:title ?title</code>, in place of the subject and of the object, two variables are involed, marked with <code class="highlighter-rouge">?</code>, that act as unknown variables while the <code class="highlighter-rouge">ex:title</code> property acts as a constant. SPARQL variables can match any resources or literals in the RDF dataset.</p>

<p>The SPARQL skeleton is:</p>

<div class="highlighter-rouge"><pre class="highlight"><code># prefix declarations
PREFIX ex: &lt;http://example.org/&gt;
...
# dataset definition
FROM ...

# result clause
SELECT ...

# query pattern
WHERE {
...
}

# query modifiers
ORDER BY ...
</code></pre>
</div>

<p>In the graph <code class="highlighter-rouge">http://example.org/books.rdf</code> we want to find all book resources (<code class="highlighter-rouge">?book</code>) and all person resources (<code class="highlighter-rouge">?person</code>) linked with the <code class="highlighter-rouge">ex:hasAuthor</code> predicate. So, book titles (<code class="highlighter-rouge">?book_title</code>) associated with relative authors’ name and surname (<code class="highlighter-rouge">?person_name</code>,<code class="highlighter-rouge">person_surname</code>) are returned.</p>

<div class="highlighter-rouge"><pre class="highlight"><code>PREFIX ex: &lt;http://example.org/&gt;
SELECT ?book_title ?person_name ?person_surname
FROM &lt;http://example.org/books.rdf&gt;
WHERE {
       ?book a ex:Book;
             ex:title ?book_title;
             ex:hasAuthor ?person.
       ?person ex:name ?person_name;
               ex:surname ?person_surname.
}
</code></pre>
</div>

<h2 id="the-sparql-structure">The SPARQL structure</h2>

<ul>
  <li><strong>PREFIX</strong> clause defines prefixes and namespaces, for abbreviating URIs;</li>
  <li><strong>SELECT</strong> clause defines the information we want to retrieve from the statement repository;</li>
  <li><strong>FROM</strong> clause defines the RDF graph(s) to explore. It can be a local or remote source; we can also set the <strong>FROM NAMED</strong> and <strong>GRAPH</strong> clauses to specify multiple data sources;</li>
  <li><strong>WHERE</strong> clause defines the graph pattern to find a match in the dataset; it represents the most important SPARQL clause in the query;</li>
  <li><strong>ORDER BY</strong> ordering, slicing and other rearranging query results.</li>
</ul>

<p>This is the result:</p>

<div class="highlighter-rouge"><pre class="highlight"><code>------------------------------------------------------------------------
| book_title                             | person_name | person_surname |
========================================================================
|"UML Distilled"                         | "Martin"    | "Fowler"       |
------------------------------------------------------------------------
|"Test-Driven Development: By Example"   | "Kent"      | "Beck"         |
------------------------------------------------------------------------
</code></pre>
</div>
<p>SPARQL language is similar to <a href="http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt">SQL language</a>. 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.</p>

<p>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!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Symfony Best Practices Italian Translation]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2014/10/17/symfony-best-practices-italian-translation/"/>
    <updated>2014-10-17T17:00:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2014/10/17/symfony-best-practices-italian-translation</id>
    <content type="html"><![CDATA[<p>Tutto ebbe inizio con un misterioso tweet di <a href="https://twitter.com/sensiolabs">@sensiolabs</a>, la casa madre del framework <a href="http://www.symfony.com">Symfony</a>.</p>

<p><img src="/images/tweet-sensio.png" alt="Image" class="center-image" /></p>

<!--More-->
<p>#}</p>

<p>L’attesa fu breve, il mistero fu presto svelato.
<img src="/images/tweet-symfony.png" alt="Image" class="center-image" /></p>

<p>Symfony ha finalmente deciso di <a href="http://symfony.com/blog/introducing-the-official-symfony-best-practices">rilasciare</a> le linee guida ufficiali per lo sviluppo di applicazioni con il proprio framework.</p>

<p>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.</p>

<p>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.</p>

<p>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.</p>

<p>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.
<em>(Per i più curiosi consiglio di seguire <a href="http://www.planet-php.net/">planet-php.net</a> )</em></p>

<p>E’ possibile scaricare le best practices ufficiali di Symfony direttamente dal <a href="http://symfony.com/doc/current/best_practices/index.html">sito Symfony</a>.
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 <a href="https://github.com/gpirrotta/symfony-best-practices-it">github</a>.</p>

<p>La traduzione è in fase di revisione. Consigli e contributi (leggasi PR) per migliorare la comprensione e leggibilità sono i benvenuti.</p>

<h2 id="symfony-best-practices"><a href="https://github.com/gpirrotta/symfony-best-practices-it">Symfony Best Practices</a></h2>

<ol>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-01.md"><strong>Best Practices del Framework Symfony</strong></a></li>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-02.md"><strong>La creazione del progetto</strong></a></li>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-03.md"><strong>La configurazione</strong></a></li>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-04.md"><strong>Organizzare la logica di business</strong></a></li>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-05.md"><strong>I Controller</strong></a></li>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-06.md"><strong>I Template</strong></a></li>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-07.md"><strong>I Form</strong></a></li>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-08.md"><strong>L’Internazionalizzazione</strong></a></li>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-09.md"><strong>La Sicurezza</strong></a></li>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-10.md"><strong>I Web Assets</strong></a></li>
  <li><a href="https://github.com/gpirrotta/symfony-best-practices-it/blob/master/it/capitolo-11.md"><strong>I Test</strong></a></li>
</ol>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Semantic Web Ingredients: RDFa, RDF in attributes]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2014/07/30/semantic-web-ingredients-rdfa/"/>
    <updated>2014-07-30T16:52:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2014/07/30/semantic-web-ingredients-rdfa</id>
    <content type="html"><![CDATA[<p>In previous posts I introduced the <strong>RDF model</strong> as the key ingredient of the Semantic Web and other
standard languages, such as <strong>RDF Schema</strong> and <strong>OWL</strong>, to describe concepts and relationships more
expressively. These semantic technologies allow to extend the actual Web providing a <em>globally coherent
notion of meaning</em>, transforming the text in concepts and relations to increase the data integration
with external applications.
<!--More-->#}</p>

<p>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:</p>

<ul>
  <li>for each new Web page we have to describe the information therein contained in a new parallel
document where we have to apply one or more specific ontologies defining the Web page data into
resources. The result will be a machine-understandable document;</li>
  <li>for pages currently on the Web (the majority) a solution could be that of adding a triplifier
tool or scraping Web pages to automatically generate the relative
semantified version of Web documents, allowing machines to process data.</li>
</ul>

<p>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 <em>“Don’t Repeat Yourself”</em>
principle (<a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>) and this should be avoided.</p>

<p>To circumvent these limits, the <em>Resource Description Framework in attributes</em> 
W3C Recommendation (<a href="http://www.w3.org/TR/rdfa-syntax/">RDFa</a>) 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.</p>

<p>Now I will show an example:</p>

<div class="language-c++ highlighter-rouge"><pre class="highlight"><code><span class="o">&lt;</span><span class="n">HTML</span><span class="o">&gt;</span>
  <span class="o">&lt;</span><span class="n">head</span><span class="o">&gt;&lt;</span><span class="n">title</span><span class="o">&gt;</span><span class="n">An</span> <span class="n">RDFa</span> <span class="n">sample</span><span class="o">&lt;/</span><span class="n">title</span><span class="o">&gt;&lt;/</span><span class="n">head</span><span class="o">&gt;</span>
  <span class="o">&lt;</span><span class="n">body</span><span class="o">&gt;</span>
    <span class="o">&lt;</span><span class="n">p</span><span class="o">&gt;</span><span class="n">The</span> <span class="n">author</span> <span class="n">of</span> <span class="o">&lt;</span><span class="n">b</span><span class="o">&gt;</span><span class="n">UML</span> <span class="n">Distilled</span><span class="o">&lt;/</span><span class="n">b</span><span class="o">&gt;</span>
    <span class="n">is</span> <span class="o">&lt;</span><span class="n">i</span><span class="o">&gt;</span><span class="n">Martin</span> <span class="n">Fowler</span><span class="o">&lt;/</span><span class="n">i</span><span class="o">&gt;&lt;/</span><span class="n">html</span><span class="o">&gt;</span>
    <span class="o">&lt;/</span><span class="n">p</span><span class="o">&gt;</span>
  <span class="o">&lt;/</span><span class="n">body</span><span class="o">&gt;</span>
  <span class="o">&lt;/</span><span class="n">html</span><span class="o">&gt;</span>
</code></pre>
</div>

<p>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</p>

<div class="language-html highlighter-rouge"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
  <span class="cp">&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
  "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd"&gt;</span>
  <span class="nt">&lt;html</span> <span class="na">xmlns=</span><span class="s">"http://www.w3.org/1999/xhtml"</span>
    <span class="na">xmlns:ex=</span><span class="s">"http://example.org/"</span> <span class="na">version=</span><span class="s">"XHTML+RDFa 1.0"</span> <span class="na">xml:lang=</span><span class="s">"en"</span><span class="nt">&gt;</span>
     <span class="nt">&lt;head&gt;&lt;title&gt;</span>An RDFa sample<span class="nt">&lt;/title&gt;&lt;/head&gt;</span>
     <span class="nt">&lt;body&gt;</span>
     <span class="nt">&lt;p&gt;&lt;div</span> <span class="na">typeof=</span><span class="s">"ex:Book"</span> <span class="na">about=</span><span class="s">"http://example.org/umld"</span><span class="nt">&gt;</span>
      The author of <span class="nt">&lt;b&gt;&lt;span</span> <span class="na">property=</span><span class="s">"ex:title"</span><span class="nt">&gt;</span>UML Distilled<span class="nt">&lt;/span&gt;&lt;/b&gt;</span>
      is <span class="nt">&lt;div</span> <span class="na">typeof=</span><span class="s">"ex:Person"</span> <span class="na">about=</span><span class="s">"http://example.org/mfowler"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;i&gt;&lt;span</span> <span class="na">property=</span><span class="s">"ex:name"</span><span class="nt">&gt;</span>Martin<span class="nt">&lt;/span&gt;</span>
      <span class="nt">&lt;span</span> <span class="na">property=</span><span class="s">"ex:surname"</span><span class="nt">&gt;</span>Fowler<span class="nt">&lt;/span&gt;&lt;/div&gt;&lt;/i&gt;</span>
      <span class="nt">&lt;/div&gt;&lt;/p&gt;</span>
   <span class="nt">&lt;/body&gt;</span>
   <span class="nt">&lt;/html&gt;</span>
</code></pre>
</div>

<ul>
  <li><strong>about</strong> attribute determines what we are talking about;</li>
  <li><strong>property</strong> attribute defines the type of relation between resources;</li>
  <li><strong>typeof</strong> attribute defines the class to instantiate.</li>
</ul>

<p>When a Web page is a valid RDFa document generally it is present the following icon…</p>

<p><img src="/images/semantic-web/rdfa.png" alt="Image" class="center-image" /></p>

<p>…and <a href="http://www.w3.org/2012/pyRdfa/Validator.html">here</a> you can find the W3C Validator tool.</p>

<p>Obviously, this is just an overview. For detail I invite you to refer to
the <a href="http://www.w3.org/TR/rdfa-syntax/">official documentation</a>.</p>

<p>That’s all folks. Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Semantic Web Ingredients: the Web Ontology Language]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2014/07/22/semantic-web-ingredients-the-web-ontology-language/"/>
    <updated>2014-07-22T16:00:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2014/07/22/semantic-web-ingredients-the-web-ontology-language</id>
    <content type="html"><![CDATA[<p>In this post, after nearly six months, I continue my Semantic Web series speaking
about the <strong>OWL</strong> language, acronym of <a href="http://www.w3.org">Web Ontology Language</a>,
that provides a rich set of concepts for defining classes and properties.</p>

<!--More-->
<p>#}</p>

<p>Although <strong>RDFS</strong> represents a very useful language to model domains, it suffers the following limitations:</p>

<ul>
  <li>the <code class="highlighter-rouge">rdfs:range</code> 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;</li>
  <li>we cannot say that two classes are disjoint, for example you cannot declare that the <code class="highlighter-rouge">Male</code>
class is disjoint from the <code class="highlighter-rouge">Female</code> class;</li>
  <li>we cannot define new classes using boolean operators. In fact, to create a new class, we could use
the union, the intersection and the complement operators, but the <strong>RDFS</strong> does not provide tools
powerful enough to express it;</li>
  <li>we cannot define cardinality constraints on properties. For example, we cannot declare that a
<strong>Person</strong> instance can have only one <code class="highlighter-rouge">hasMother</code> property;</li>
  <li>we cannot specify particular features on properties such as transitivity, symmetry or inverse
properties.</li>
</ul>

<p>Because of these limitations, the <a href="http://www.w3.org">W3C Consortium</a> 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:</p>

<ul>
  <li>
    <p>The <strong>OWL Full</strong> 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.</p>
  </li>
  <li>
    <p>The <strong>OWL DL</strong> 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.</p>
  </li>
  <li>
    <p>The <strong>OWL Lite</strong> 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.</p>
  </li>
</ul>

<p>In the following Figure we can see the relationships between OWL dialects.</p>

<p><img src="/images/semantic-web/owl-variants.png" alt="Image" class="center-image" /></p>

<p>In the OWL language we can model our domain with the concept of <strong>class</strong>, that
represents one of the most important aspect of the language. To do this we use the <code class="highlighter-rouge">owl:Class</code>;
Also exist two pre-defined classes:</p>

<ul>
  <li><code class="highlighter-rouge">owl:Thing</code> is the superclass of all classes and a default class of all individuals. Thus,
every individual in OWL world is member of <code class="highlighter-rouge">owl:Thing</code>;</li>
  <li><code class="highlighter-rouge">owl:Nothing</code> is a class that has no instances and is a subclass of all classes.</li>
</ul>

<p>Thanks to the expressiveness of the OWL language, we can define more characteristics of classes we need
to design. The language provides the <code class="highlighter-rouge">owl:EquivalentClass</code> construct to declare the equivalence
between two classes or the <code class="highlighter-rouge">owl:disjointWith</code> construct to define the classes that do not
share any individuals.</p>

<p>An <code class="highlighter-rouge">owl:Property</code> is instead a binary relation defining relationships between individuals, or between
individuals and data value. There are two pre-defined property classes:</p>

<ul>
  <li>the <code class="highlighter-rouge">owl:ObjectTypeProperty</code> resource defines the relation between instances of two classes;</li>
  <li>the <code class="highlighter-rouge">owl:DataTypeProperty</code> resource defines the relation between instances of classes and literal values,
such as string, date, float, etc.</li>
</ul>

<p>Also, the OWL language provides some <code class="highlighter-rouge">owl:ObjectTypeProperty</code> subclasses specifying some interesting
class characteristics.</p>

<ul>
  <li>The <code class="highlighter-rouge">owl:TransitiveProperty</code> construct defines a transitive property: if a relation between the
class <strong>A</strong> and the class <strong>B</strong> exists, and a relation between the class <strong>B</strong> and the class <strong>C</strong>
exists, the also a relation between the class <strong>A</strong> and the class <strong>C</strong> does exist.</li>
  <li>The <code class="highlighter-rouge">owl:SymmetricProperty</code> construct defines a symmetric property: if a relation between
the class <strong>A</strong> and the class <strong>B</strong> exists, then also a relation between the class <strong>B</strong> and the
class <strong>A</strong> does exist.</li>
  <li>The <code class="highlighter-rouge">owl:FunctionalProperty</code> construct defines a property with at most one value for each instance.</li>
</ul>

<p>Also, we can set the cardinality of properties using the following OWL resources: <code class="highlighter-rouge">owl:Restriction</code>,
   <code class="highlighter-rouge">owl:onProperty</code>, <code class="highlighter-rouge">owl:minCardinality</code>, <code class="highlighter-rouge">owl:maxCardinality</code>, so we can create new classes using
boolean operators through the <code class="highlighter-rouge">owl:unionOf</code>, <code class="highlighter-rouge">owl:complementOf</code> and <code class="highlighter-rouge">owl:intersectionClass</code> constructs.
Obviously, there are many other constructs and language features provided by OWL language.
For more details you can refer to the <a href="http://www.w3.org/TR/owl-features/">official documentation</a>.</p>

<p>Let us come back to our old statement (in the previous <a href="http://giovanni.pirrotta.it/blog/2014/01/06/semantic-web-ingredients-the-rdf-schema-model/">post</a>),
and let us try to draw the relative ontology using the OWL language.</p>

<div class="language-c++ highlighter-rouge"><pre class="highlight"><code><span class="err">@</span><span class="n">prefix</span> <span class="n">rdf</span><span class="o">:</span> <span class="o">&lt;</span><span class="n">http</span><span class="o">:</span><span class="c1">//www.w3.org/1999/02/22-rdf-syntax-ns#&gt;.
</span><span class="err">@</span><span class="n">prefix</span> <span class="n">rdfs</span><span class="o">:</span> <span class="o">&lt;</span><span class="n">http</span><span class="o">:</span><span class="c1">//www.w3.org/2000/01/rdf-schema#&gt;.
</span><span class="err">@</span><span class="n">prefix</span> <span class="n">owl</span><span class="o">:</span> <span class="o">&lt;</span><span class="n">http</span><span class="o">:</span><span class="c1">//www.w3.org/2002/07/owl#&gt;.
</span><span class="err">@</span><span class="n">prefix</span> <span class="n">ex</span><span class="o">:</span> <span class="o">&lt;</span><span class="n">http</span><span class="o">:</span><span class="c1">//example.org/&gt;.
</span>
<span class="n">ex</span><span class="o">:</span><span class="n">Person</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">owl</span><span class="o">:</span><span class="n">Class</span><span class="p">.</span>
<span class="n">ex</span><span class="o">:</span><span class="n">name</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">owl</span><span class="o">:</span><span class="n">DatatypeProperty</span><span class="p">.</span>
<span class="n">ex</span><span class="o">:</span><span class="n">surname</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">owl</span><span class="o">:</span><span class="n">DatatypeProperty</span><span class="p">.</span>
<span class="n">ex</span><span class="o">:</span><span class="n">title</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">owl</span><span class="o">:</span><span class="n">DatatypeProperty</span><span class="p">.</span>
<span class="n">ex</span><span class="o">:</span><span class="n">isbn</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">owl</span><span class="o">:</span><span class="n">DatatypeProperty</span><span class="p">.</span>

<span class="n">ex</span><span class="o">:</span><span class="n">hasAuthor</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">owl</span><span class="o">:</span><span class="n">ObjectProperty</span><span class="p">.</span>
             <span class="n">rdfs</span><span class="o">:</span><span class="n">domain</span> <span class="n">ex</span><span class="o">:</span><span class="n">Book</span><span class="p">;</span>
             <span class="n">rdfs</span><span class="o">:</span><span class="n">range</span> <span class="n">ex</span><span class="o">:</span><span class="n">Person</span><span class="p">.</span>

<span class="n">ex</span><span class="o">:</span><span class="n">hasUniqueAuthor</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">owl</span><span class="o">:</span><span class="n">ObjectProperty</span> <span class="p">;</span>
                   <span class="n">rdfs</span><span class="o">:</span><span class="n">subPropertyOf</span> <span class="n">ex</span><span class="o">:</span><span class="n">hasAuthor</span><span class="p">.</span>


<span class="n">ex</span><span class="o">:</span><span class="n">Book</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">owl</span><span class="o">:</span><span class="n">Class</span><span class="p">;</span>
        <span class="n">rdfs</span><span class="o">:</span><span class="n">subClassOf</span>
         <span class="p">[</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">owl</span><span class="o">:</span><span class="n">Restriction</span> <span class="p">;</span>
           <span class="n">owl</span><span class="o">:</span><span class="n">onProperty</span> <span class="n">ex</span><span class="o">:</span><span class="n">hasUniqueAuthor</span> <span class="p">;</span>
           <span class="n">owl</span><span class="o">:</span><span class="n">maxCardinality</span> <span class="s">"1"</span><span class="o">^^&lt;</span><span class="n">http</span><span class="o">:</span><span class="c1">//www.w3.org/2001/XMLSchema#int&gt;
</span>         <span class="p">]</span> <span class="p">.</span>

<span class="n">ex</span><span class="o">:</span><span class="n">umld</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">ex</span><span class="o">:</span><span class="n">Book</span><span class="p">;</span>
               <span class="n">ex</span><span class="o">:</span><span class="n">hasUniqueAuthor</span> <span class="n">ex</span><span class="o">:</span><span class="n">mfowler</span><span class="p">;</span>
               <span class="n">ex</span><span class="o">:</span><span class="n">title</span> <span class="s">"UML Distilled"</span><span class="p">;</span>
               <span class="n">ex</span><span class="o">:</span><span class="n">isbn</span> <span class="s">"0201325632"</span><span class="p">.</span>

<span class="n">ex</span><span class="o">:</span><span class="n">mfowler</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">ex</span><span class="o">:</span><span class="n">Person</span><span class="p">;</span>
            <span class="n">ex</span><span class="o">:</span><span class="n">name</span> <span class="s">"Martin"</span><span class="p">;</span>
            <span class="n">ex</span><span class="o">:</span><span class="n">surname</span> <span class="s">"Fowler"</span><span class="p">.</span>
</code></pre>
</div>

<p>As can be seen in the code, the <code class="highlighter-rouge">rdfs:Class</code>
resources were replaced by the relative <code class="highlighter-rouge">owl:Class</code> constructs.</p>

<p>Depending on the type of object, we can identify <code class="highlighter-rouge">owl:DatatypeProperty</code>
and <code class="highlighter-rouge">owl:ObjectProperty</code> property instances.
In our example only <code class="highlighter-rouge">ex:hasAuthor</code> is an <code class="highlighter-rouge">owl:ObjectProperty</code> instance,
whereas the remaining ones are <code class="highlighter-rouge">owl:DatatypeProperty</code> property instances.</p>

<p>Now let us imagine we want to specialize the <code class="highlighter-rouge">ex:hasAuthor</code> property.
We want to define a particular property modeling books with a single
author. To do this, we define the <code class="highlighter-rouge">ex:hasUniqueAuthor</code> property as subproperty
(<code class="highlighter-rouge">rdfs:subPropertyOf</code> ) of <code class="highlighter-rouge">ex:hasAuthor</code> property. To define this
constraint we must create an anonymous <code class="highlighter-rouge">owl:Restriction</code> class, specifying
as properties the attributes that have to be constrained.
In this case we indicate the resource <code class="highlighter-rouge">ex:hasUniqueAuthor</code> through the <code class="highlighter-rouge">owl:onProperty</code>
property and we indicate the maximum number of relations the <code class="highlighter-rouge">ex:hasUniqueAuthor</code>
property can join between classes, in this case only
one, through the <code class="highlighter-rouge">owl:maxCardinality</code> property.</p>

<p>That’s all folks! Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Semantic Web Ingredients: the RDF Schema Model]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2014/01/06/semantic-web-ingredients-the-rdf-schema-model/"/>
    <updated>2014-01-06T08:07:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2014/01/06/semantic-web-ingredients-the-rdf-schema-model</id>
    <content type="html"><![CDATA[<p>In the <a href="http://giovanni.pirrotta.it/blog/2013/12/23/the-rdf-model/">last post</a> 
I introduced the RDF Model to define assertions as triple statements. 
But how does a stupid machine understand what a certain
property describing a certain resource means?</p>

<!--More-->

<p>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 <strong>RDF Schema (RDFs)</strong> comes into
play.</p>

<p>The <a href="http://www.w3.org/TR/rdf-schema">RDF Schema (RDFs)</a>  is the way to describe the meaning of
classes and properties to help machines process data efficiently. <strong>RDFs
Vocabulary</strong> 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.</p>

<p>Using the RDFS Vocabulary, we can define for example the class <strong>Person</strong>
and the class <strong>Book</strong> to define the <code class="highlighter-rouge">http://example.org/mfowler</code> resource
as an instance of the class <strong>Person</strong>, and the <code class="highlighter-rouge">http://example.org/umld</code>
resource as an instance of the class <strong>Book</strong>.</p>

<p>So, we can define the <code class="highlighter-rouge">http://example.org/hasAuthor</code> resource as a
new property stating that it relates an instance of <strong>Book</strong> to an instance
of <strong>Person</strong>.
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.</p>

<p>The most important RDFS items to define metadata schemas or ontologies are:</p>

<ul>
  <li><strong>rdfs:Resource</strong>: it is the class of everything. All things described by
RDF are resources, instance of rdfs:Resource.</li>
  <li><strong>rdfs:Class</strong>: the Class resource is one of the most important RDFS
vocabulary constructs because it allows to create new classes, as a
category or a model, of anything concrete or abstract. It is importan
to note the reflexive nature of this resource; instancing a new
class using the <code class="highlighter-rouge">rdf:type</code> property, the rdfs:Class instances obtained
are themselves class objects, then again classes to instantiate.</li>
  <li><strong>rdfs:Property</strong>: this resource is used to instantiate a new property
or a new property subclass. Again, also this one, is a rdfs:Resource
subclass.</li>
  <li><strong>rdfs:Literal</strong>: an rdfs:Literal is an rdfs:Resource subclass and represents
a typed primitive value borrow from XML Schema Datatypes (string, date, float, etc.)</li>
  <li><strong>rdf:type</strong>: the property is used to say that a certain resource, instance
of rdfs:Resource is an instance of a certain class. If it is
present in the statement predicate, the object resource must be
an <code class="highlighter-rouge">rdfs:Class</code> resource or an <code class="highlighter-rouge">rdfs:Class</code> instance. In the first case
the subject resource will be a new class type, otherwise it will be
a generic typed class instance.</li>
  <li>
    <p><strong>rdfs:subClassOf</strong>: 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:</p>

    <p><strong>C1 rdfs:subClassOf C2</strong></p>

    <p>states that <strong>C1</strong> is an instance of <code class="highlighter-rouge">rdfs:Class</code>, <strong>C2</strong> is an instance of
<code class="highlighter-rouge">rdfs:Class</code> and <strong>C1</strong> is a subclass of <strong>C2</strong>. The resource specifies the
inheritance relationship between classes and can be a subclass of
one or more classes (multiple inheritance).</p>
  </li>
  <li><strong>rdfs:domain</strong>: used to say that a certain resource, instance of <code class="highlighter-rouge">rdfs:Property</code>
has domain instances of a certain class. For example, the property
identified by the <code class="highlighter-rouge">http://example.org/hasAuthor</code> URI, instance
of <code class="highlighter-rouge">rdfs:Property</code>, has to have as subject type the Book class.</li>
  <li><strong>rdfs:range</strong>: used to say that a certain resource, instance of <code class="highlighter-rouge">rdfs:Property</code>,
has as range instances of a certain class. For example, the property
identified by the <code class="highlighter-rouge">http://example.org/hasAuthor</code> URI, instance
of <code class="highlighter-rouge">rdfs:Property</code>, has to have as object type the <strong>Person</strong> class.</li>
</ul>

<p>The following figure represents the relationship graph of the most important
RDFS classes:</p>

<p><img src="/images/semantic-web/rdfs-model.gif" alt="Image" class="center-image" /></p>

<p>Let us now see how to apply what we have just described in our previous
statement. At the beginning we define two new classes: <code class="highlighter-rouge">ex:Book</code>
and <code class="highlighter-rouge">ex:Person</code> instances of the <code class="highlighter-rouge">rdfs:Class</code> resource. Then, we can typify
the <code class="highlighter-rouge">ex:umld</code> and the <code class="highlighter-rouge">ex:mfowler</code> resources, through the
<code class="highlighter-rouge">rdf:type</code> property. As done with classes, we instanciate the property
resources (<code class="highlighter-rouge">ex:authorOf</code>, <code class="highlighter-rouge">ex:firstname</code>, <code class="highlighter-rouge">ex:lastname</code>, <code class="highlighter-rouge">ex:title</code>, <code class="highlighter-rouge">ex:isbn</code>) as
<code class="highlighter-rouge">rdfs:Property</code> instances, using again the <code class="highlighter-rouge">rdf:type</code> 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.</p>

<p>Let us show now RDFS Schema serialization. For semplicity I will
adopt the N3 notation</p>

<div class="language-c++ highlighter-rouge"><pre class="highlight"><code><span class="err">@</span><span class="n">prefix</span> <span class="n">rdf</span><span class="o">:</span> <span class="o">&lt;</span><span class="n">http</span><span class="o">:</span><span class="c1">//www.w3.org/1999/02/22-rdf-syntax-ns#&gt;.
</span><span class="err">@</span><span class="n">prefix</span> <span class="n">rdfs</span><span class="o">:</span> <span class="o">&lt;</span><span class="n">http</span><span class="o">:</span><span class="c1">//www.w3.org/2000/01/rdf-schema#&gt;.
</span><span class="err">@</span><span class="n">prefix</span> <span class="n">ex</span><span class="o">:</span> <span class="o">&lt;</span><span class="n">http</span><span class="o">:</span><span class="c1">//example.org/&gt;.
</span>		
<span class="n">ex</span><span class="o">:</span><span class="n">Book</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">rdfs</span><span class="o">:</span><span class="n">Class</span><span class="p">.</span>
<span class="n">ex</span><span class="o">:</span><span class="n">Person</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">rdfs</span><span class="o">:</span><span class="n">Class</span><span class="p">.</span>
		
<span class="n">ex</span><span class="o">:</span><span class="n">fistname</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">rdfs</span><span class="o">:</span><span class="n">Property</span><span class="p">.</span>
<span class="n">ex</span><span class="o">:</span><span class="n">lastname</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">rdfs</span><span class="o">:</span><span class="n">Property</span><span class="p">.</span>
<span class="n">ex</span><span class="o">:</span><span class="n">title</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">rdfs</span><span class="o">:</span><span class="n">Property</span><span class="p">.</span>
<span class="n">ex</span><span class="o">:</span><span class="n">isbn</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">rdfs</span><span class="o">:</span><span class="n">Property</span><span class="p">.</span>
<span class="n">ex</span><span class="o">:</span><span class="n">hasAuthor</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">rdfs</span><span class="o">:</span><span class="n">Property</span><span class="p">;</span>
		     <span class="n">rdfs</span><span class="o">:</span><span class="n">domain</span> <span class="n">ex</span><span class="o">:</span><span class="n">Book</span><span class="p">;</span>
		     <span class="n">rdfs</span><span class="o">:</span><span class="n">range</span> <span class="n">ex</span><span class="o">:</span><span class="n">Person</span><span class="p">.</span>
		
<span class="n">ex</span><span class="o">:</span><span class="n">umld</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">ex</span><span class="o">:</span><span class="n">Book</span><span class="p">;</span>
		<span class="n">ex</span><span class="o">:</span><span class="n">hasAuthor</span> <span class="n">ex</span><span class="o">:</span><span class="n">mfowler</span><span class="p">;</span>
		<span class="n">ex</span><span class="o">:</span><span class="n">title</span> <span class="s">"UML Distilled"</span><span class="p">;</span>
		<span class="n">ex</span><span class="o">:</span><span class="n">isbn</span> <span class="s">"0201325632"</span><span class="p">.</span>
		
<span class="n">ex</span><span class="o">:</span><span class="n">mfowler</span> <span class="n">rdf</span><span class="o">:</span><span class="n">type</span> <span class="n">ex</span><span class="o">:</span><span class="n">Person</span><span class="p">;</span>
		   <span class="n">ex</span><span class="o">:</span><span class="n">firstname</span> <span class="s">"Martin"</span><span class="p">;</span>
		   <span class="n">ex</span><span class="o">:</span><span class="n">lastname</span> <span class="s">"Fowler"</span><span class="p">.</span>
</code></pre>
</div>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Semantic Web Ingredients: The RDF Model]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2013/12/23/the-rdf-model/"/>
    <updated>2013-12-23T08:03:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2013/12/23/the-rdf-model</id>
    <content type="html"><![CDATA[<p>While in the <a href="http://localhost:4000/blog/2013/12/20/the-rdf-model/">previous post</a> 
I explained why XML alone is not sufficiently powerful in the Semantic Web context in
this post I will explain how to overcome the XML semantic markup limitations.</p>

<!--More-->
<p>#}</p>

<p>To solve the problem the W3C Consortium has formalized a conceptual layer called <a href="http://www.w3.org/TR/rdf-primer.">Resource Description
Framework (RDF)</a>, 
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.</p>

<p>The first letter of <strong>RDF acronym</strong> stands for <strong>Resource</strong> but, what is a resource?
A resource is every concrete or abstract thing identified by a <strong>URI</strong> and 
can be really anything: an image, a document, a person,
a book, etc.</p>

<p>The <a href="http://www.w3.org/TR/
webarch"><strong>URI</strong></a>, acronym of <code class="highlighter-rouge">Uniform Resource Identifier</code>, 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 <code class="highlighter-rouge">Uniform Resource Locator</code> (<strong>URL</strong>) where
the http protocol identifies the mechanism to access the resource. For
instance, the address Web <code class="highlighter-rouge">http://giovanni.pirrotta.it</code> represents the URL
of my blog. If the resource is identified
by a name belonging to a <a href="http://www.w3.org/TR/
webarch">namespace</a> we call it Uniform Resource
Name (<strong>URN</strong>). 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, <strong>urn:isbn:12238789879</strong> identifies a specific
resource within ISBN codes.</p>

<p>The URI syntax may change, but in general absolute URIs are written as follows:</p>

<div class="highlighter-rouge"><pre class="highlight"><code>	&lt;scheme&gt;:&lt;scheme-specific-part&gt;

</code></pre>
</div>

<p>If a URI ends with the hash character (<strong>#</strong>), followed by a name, it is called <strong>qualified URI</strong> 
and it used to identify many resources in the same document.</p>

<p>Moreover we define as a <a href="http://www.w3.org/TR/rdf-primer">property</a> 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.</p>

<p>Now we can define the <a href="http://www.w3.org/TR/rdf-primer">statement</a> as the basic knowledge unit in RDF. 
It is composed by a <strong>subject</strong>, that is a resource, a <strong>predicate</strong>, which is the property, and is
again a resource, and by an <strong>object</strong>, that can be a resource or a literal. A
<strong>literal</strong> is simply a typed primitive value, such as string, integer, float,
etc.</p>

<p>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.</p>

<p><img src="/images/semantic-web/rdf-model.jpg" alt="Image" class="center-image" /></p>

<p>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.</p>

<p>Now I will explain how the RDF model works through an example.</p>

<p>Let us assume we want to define the following statement:</p>

<div class="highlighter-rouge"><pre class="highlight"><code>Martin Fowler is the author of the book "UML Distilled"
</code></pre>
</div>

<p>First of all we have to transform the statement in an RDF triple according
to the following mapping:</p>

<ul>
  <li><strong>subject:</strong> we decide to identify the <code class="highlighter-rouge">UML Distilled</code> book with the http://example.org/umld URI;</li>
  <li><strong>predicate:</strong> we decide to identify the <code class="highlighter-rouge">is the author of</code> property with the
http://example.org/hasAuthor URI;</li>
  <li><strong>object:</strong> we decide to identify the <code class="highlighter-rouge">Martin Fowler</code> person with the
“Martin Fowler string Literal.</li>
</ul>

<p>We compose the following triple:</p>

<p>-&gt; (http://example.org/umld, http://example.org/hasAuthor, “Martin Fowler”) &lt;-</p>

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

<p>-&gt; <strong>P(S) = O</strong> or <strong>P(S,O)</strong> &lt;-</p>

<p>where <strong>P</strong> represents the property, <strong>S</strong> represents the subject and <strong>O</strong> represents
the object.</p>

<p>Applying the above relation, we have</p>

<p>-&gt; http://example.org/hasAuthor(http://example.org/umld) = “Martin Fowler” &lt;-</p>

<p>The same statement can be represented as the graph shown in the next figure</p>

<p><img src="/images/semantic-web/rdf-model-literal.jpg" alt="Image" class="center-image" /></p>

<p>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.</p>

<p>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.</p>

<p><img src="/images/semantic-web/rdf-model-object.jpg" alt="Image" class="center-image" /></p>

<p>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.</p>

<p>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.</p>

<p>The following document represents the <code class="highlighter-rouge">RDF/XML</code> version of the previous statement
example:</p>

<div class="language-xml highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;rdf:RDF</span>
  <span class="na">xmlns:rdf=</span><span class="s">"http://www.w3.org/1999/02/22-rdf-syntax-ns#"</span>
  <span class="na">xmlns:ex=</span><span class="s">"http://example.org/"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;rdf:Description</span> <span class="na">about=</span><span class="s">"http://example.org/umld"</span><span class="nt">&gt;</span>
      <span class="nt">&lt;ex:hasAuthor&gt;</span>Martin Fowler<span class="nt">&lt;/ex:hasAuthor&gt;</span>
   <span class="nt">&lt;/rdf:Description&gt;</span>
<span class="nt">&lt;/rdf:RDF&gt;</span>
</code></pre>
</div>

<p>Inside an <strong>RDF/XML</strong>
document, the <strong>rdf:RDF root</strong> node delimits the context within which all
RDF statements are defined. In the <strong>rdf:RDF node</strong>, 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.</p>

<p>Imagine we have to define the <code class="highlighter-rouge">title</code> property for a person and the
<code class="highlighter-rouge">title</code> 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.</p>

<p>To describe an <code class="highlighter-rouge">RDF statement</code>, 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 <code class="highlighter-rouge">rdf:about</code> attribute of the <code class="highlighter-rouge">rdf:Description</code>
tag. Inside the <code class="highlighter-rouge">rdf:Description</code> tag we must specify all properties related
to the subject.</p>

<p>Considering Martin Fowler as a resource, we will have</p>

<div class="language-xml highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;rdf:RDF</span>
  <span class="na">xmlns:rdf=</span><span class="s">"http://www.w3.org/1999/02/22-rdf-syntax-ns#"</span>
  <span class="na">xmlns:ex=</span><span class="s">"http://example.org/"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;rdf:Description</span> <span class="na">about=</span><span class="s">"http://example.org/umld"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;ex:title&gt;</span>UML Distilled<span class="nt">&lt;/ex:title&gt;</span>
    <span class="nt">&lt;ex:isbn&gt;</span>0201325632<span class="nt">&lt;/ex:isbn&gt;</span>
    <span class="nt">&lt;ex:hasAuthor</span> <span class="na">rdf:resource=</span><span class="s">"http://example.org/mfowler"</span><span class="nt">/&gt;</span>
  <span class="nt">&lt;/rdf:Description&gt;</span>
  <span class="nt">&lt;rdf:Description</span> <span class="na">about=</span><span class="s">"http://example.org/mfowler"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;ex:firstname&gt;</span>Martin<span class="nt">&lt;/ex:firstname&gt;</span>
    <span class="nt">&lt;ex:lastname&gt;</span>Fowler<span class="nt">&lt;/ex:lastname&gt;</span>
  <span class="nt">&lt;/rdf:Description&gt;</span>
<span class="nt">&lt;/rdf:RDF&gt;</span>
</code></pre>
</div>

<p>As we can see from previous examples, we defined a new namespace,
called <strong>ex</strong>, within the <code class="highlighter-rouge">rdf:RDF</code> tag, in order to refer to <code class="highlighter-rouge">RDF/XML</code>
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.</p>

<p>In addition to the RDF/XML syntax, other triple-oriented RDF serializations
exist, such as the <strong>N–Triples</strong> and <strong>Notation 3</strong> (N3) formats.</p>

<p>N–Triples format is simply the assertion sequence where each statement
is in the form</p>

<div class="language-c highlighter-rouge"><pre class="highlight"><code><span class="o">&lt;</span><span class="n">subject</span><span class="o">&gt;&lt;</span><span class="n">predicate</span><span class="o">&gt;&lt;</span><span class="n">object</span><span class="o">&gt;</span><span class="p">.</span>
</code></pre>
</div>

<p>If we wanted to describe our previous resources in N–Triples format
this would be the result:</p>

<div class="language-php highlighter-rouge"><pre class="highlight"><code><span class="nt">&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">.</span><span class="na">org</span><span class="err">/</span><span class="na">umld</span><span class="nt">&gt;&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">.</span><span class="na">org</span><span class="err">/</span><span class="na">hasAuthor</span><span class="nt">&gt;&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">/</span><span class="na">mfowler</span><span class="nt">&gt;</span>.
<span class="nt">&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">.</span><span class="na">org</span><span class="err">/</span><span class="na">umld</span><span class="nt">&gt;&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">.</span><span class="na">org</span><span class="err">/</span><span class="na">title</span><span class="nt">&gt;</span> "UML Distilled".
<span class="nt">&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">.</span><span class="na">org</span><span class="err">/</span><span class="na">umld</span><span class="nt">&gt;&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">.</span><span class="na">org</span><span class="err">/</span><span class="na">isbn</span><span class="nt">&gt;</span> "0201325632".
<span class="nt">&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">.</span><span class="na">org</span><span class="err">/</span><span class="na">mfowler</span><span class="nt">&gt;&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">.</span><span class="na">org</span><span class="err">/</span><span class="na">firstname</span><span class="nt">&gt;</span> "Martin".
<span class="nt">&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">.</span><span class="na">org</span><span class="err">/</span><span class="na">mfowler</span><span class="nt">&gt;&lt;http:</span><span class="err">//</span><span class="na">example</span><span class="err">.</span><span class="na">org</span><span class="err">/</span><span class="na">lastname</span><span class="nt">&gt;</span> "Fowler".
</code></pre>
</div>

<p>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:</p>

<div class="language-c++ highlighter-rouge"><pre class="highlight"><code><span class="err">@</span><span class="n">prefix</span> <span class="n">rdf</span><span class="o">:</span> <span class="o">&lt;</span><span class="n">http</span><span class="o">:</span><span class="c1">//www.w3.org/1999/02/22-rdf-syntax-ns#&gt;.
</span><span class="err">@</span><span class="n">prefix</span> <span class="n">ex</span><span class="o">:</span> <span class="o">&lt;</span><span class="n">http</span><span class="o">:</span><span class="c1">//example.org/&gt;.
</span>
<span class="n">ex</span><span class="o">:</span><span class="n">umld</span> <span class="n">ex</span><span class="o">:</span><span class="n">hasAuthor</span> <span class="n">ex</span><span class="o">:</span><span class="n">mfowler</span><span class="p">;</span>
        <span class="n">ex</span><span class="o">:</span><span class="n">title</span> <span class="s">"UML Distilled"</span><span class="p">;</span>
        <span class="n">ex</span><span class="o">:</span><span class="n">isbn</span>  <span class="s">"0201325632"</span><span class="p">.</span>
<span class="n">ex</span><span class="o">:</span><span class="n">mfowler</span> <span class="n">ex</span><span class="o">:</span><span class="n">firstname</span> <span class="s">"Martin"</span><span class="p">;</span>
           <span class="n">ex</span><span class="o">:</span><span class="n">lastname</span>  <span class="s">"Fowler"</span><span class="p">.</span>
</code></pre>
</div>

<p>That’s all for now.</p>

<p>In the next post I will focus the discussion on the <a href="http://www.w3.org/TR/rdf-schema">RDF Schema Model</a> <strong>(RDFs)</strong>.<br />
I will explain the way to create the vocabulary of resources in order to describe the <strong>meaning</strong> of classes and properties to help machines process data efficiently.</p>

<p>So stay tuned!</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Semantic Web Ingredients: why the XML alone is not sufficiently powerful]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2013/11/20/xml-limits/"/>
    <updated>2013-11-20T08:33:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2013/11/20/xml-limits</id>
    <content type="html"><![CDATA[<p>In this post we continue the Semantic Web post series (the last published in July) and in particular I will explain 
why <code class="highlighter-rouge">XML</code> alone is not sufficiently powerful in the Semantic Web context.</p>

<!--More -->

<p><a href="http://www.w3.org/TR/xml">XML</a> is the acronym of <strong>Extensible Markup Language</strong> and represents a meta-language for the syntactic definition
of markup languages allowing to add <code class="highlighter-rouge">metadata</code> to <code class="highlighter-rouge">local</code> data and separate contents from presentations with a 
neutral textual format.</p>

<p>Imagine we have the following XML code:</p>

<div class="language-xml highlighter-rouge"><pre class="highlight"><code>
<span class="cp">&lt;?xml version="1.0" encoding="ISO-8859-1" ?&gt;</span>
<span class="nt">&lt;mailbox&gt;</span>
	<span class="nt">&lt;mail</span> <span class="na">id=</span><span class="s">"01"</span><span class="nt">&gt;</span>
		<span class="nt">&lt;to&gt;</span>Giovanni<span class="nt">&lt;/to&gt;</span>
		<span class="nt">&lt;from&gt;</span>Francesco<span class="nt">&lt;/from&gt;</span>
		<span class="nt">&lt;title&gt;</span>Enjoy Christmas<span class="nt">&lt;/title&gt;</span>
		<span class="nt">&lt;body&gt;</span>Merry Christmas and a Happy New Year<span class="nt">&lt;/body&gt;</span>
	<span class="nt">&lt;/mail&gt;</span>
<span class="nt">&lt;/mailbox&gt;</span>

</code></pre>
</div>

<p>In the above example the tags <code class="highlighter-rouge">&lt;mailbox&gt;</code>, <code class="highlighter-rouge">&lt;mail&gt;</code>,<code class="highlighter-rouge">&lt;to&gt;</code>,<code class="highlighter-rouge">&lt;from&gt;</code>,<code class="highlighter-rouge">&lt;title&gt;</code> and <code class="highlighter-rouge">&lt;body&gt;</code> 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 <code class="highlighter-rouge">XML</code> is unsuitable to the <code class="highlighter-rouge">global</code> semantic interpretation because there is no
way to explain to the machine that for example, the string <code class="highlighter-rouge">Giovanni</code>, enclosed withing the tag <code class="highlighter-rouge">&lt;to&gt;</code>,
represents the <strong>name</strong> of a <strong>person</strong>.</p>

<p>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 <strong>alone</strong> is not sufficiently powerful to explain the semantics in an independent and autonomous way from the context.</p>

<p>Also it is not able to generate new knowledge starting from the original data infering new statements. 
For example, if we have the fact <code class="highlighter-rouge">The dog is a mammal</code>, the XML does not allow to define 
the sentence in terms of relationship. Also if we consider the fact <code class="highlighter-rouge">Fido is a dog</code>, it should be
possible to infer the new fact <code class="highlighter-rouge">Fido is a mammal</code>. But XML does not allow to explicit this rule between
resources because of it is unsuitable to represent semantically the resource on the Web.</p>

<p>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).</p>

<p>The RDF model will be described in the next post, so, stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CosaCeInTV.it: guida TV a portata di tweet]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2013/10/04/cosaceintv-la-guida-tv-a-portata-di-tweet/"/>
    <updated>2013-10-04T10:25:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2013/10/04/cosaceintv-la-guida-tv-a-portata-di-tweet</id>
    <content type="html"><![CDATA[<p>Fra tutti i social network presenti online uno dei miei preferiti è <a href="https://www.twitter.com">Twitter</a>. 
La semplicità e immediatezza del servizio di invio, in soli 140 caratteri, di informazioni in tempo reale è diventato
negli anni un modello vincente di business.
Non sto qui ad elencare il numero di utenti in costante crescita, le centinaia di applicazioni sviluppate da terzi, la possibilità di interagire con i tweets tramite API, la quasi imminente entrata in borsa dell’azienda, etc.</p>

<p>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.<br />
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.</p>

<p>Sono state queste motivazioni che mi hanno portato a ideare e sviluppare <code class="highlighter-rouge">cosaceintv</code>, un servizio quindi <code class="highlighter-rouge">tweet-driven</code>.</p>

<!--More-->
<p>#}</p>

<p>Tecnicamente parlando ho implementato un <a href="http://it.wikipedia.org/wiki/Bot">BOT</a> 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 <a href="http://www.digitaltrends.com/social-media/the-10-best-twitter-bots-you-arent-following/">Twitter Bot</a> in grado di rispondere automaticamente a
tweet con menzioni particolari o contenenti un testo predefinito. Nonostante ciò ritengo siano ancora troppo pochi e sottoconsiderati.</p>

<p><code class="highlighter-rouge">cosaceintv</code> 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.</p>

<p>Per ottenere ciò ho definito un linguaggio specifico per il dominio, cioè un <a href="http://it.wikipedia.org/wiki/Domain_Specific_Language">DLS</a>, dei principali canali TV italiani.</p>

<p>Il software sviluppato si compone di due parti (vedere Figura):</p>

<p><img src="/images/cosaceintv-architecture.jpg" alt="Image" class="center-image" /></p>

<ul>
  <li><strong>TV Program Scraper</strong>: è il modulo che si occupa dello scraping dei programmi TV e, a cadenza continua, li salva in un repository interno;</li>
  <li><strong>CosaCeInTV Engine</strong>: è il cuore del progetto.<br />
Tutto parte dall’utente che invia semplicemente un tweet. L’engine effettua la <code class="highlighter-rouge">pull</code> di tutti i tweet che menzionano l’utente <code class="highlighter-rouge">@cosaceintv</code>. 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.</li>
</ul>

<p>Per utilizzare il servizio:</p>

<ul>
  <li>
    <p>Diventate follower di <a href="https://twitter.com/cosaceintv"><strong>@cosaceintv</strong></a>:</p>
  </li>
  <li>
    <p>Inviare un tweet menzionando @cosaceintv in questo modo:</p>

    <ul>
      <li><em>per conoscere i programmi TV della giornata a partire dall’ora corrente:</em>
        <div class="language-php highlighter-rouge"><pre class="highlight"><code>@cosaceintv #1
</code></pre>
        </div>
      </li>
    </ul>

    <p>dopo la menzione e’ <strong>obbligatorio</strong> specificare l’hash anti-duplicazione (<strong>#1</strong>), che deve essere un numero <strong>sempre diverso</strong> 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.<br />
Quindi se gia’ ho richiesto <code class="highlighter-rouge">@cosaceintv #1</code>, la seconda volta, per la stessa <strong>identica</strong> richiesta, inviero’ un tweet con l’hash anti-duplicazione diverso da 1,
ad es. <code class="highlighter-rouge">@cosaceintv #2</code> o qualsiasi altro numero diverso da quelli gia’ usati.<br />
L’hash anti-duplicazione si applica anche alle successive tipologie di richieste.</p>

    <ul>
      <li><em>per conoscere i programmi TV della giornata a partire da una certa ora:</em>
        <div class="language-php highlighter-rouge"><pre class="highlight"><code> @cosaceintv alle 16:50 #1
</code></pre>
        </div>
        <p>(l’orario e’ accettato nella forma hh:mm, hh, h, ad es. 16:40, 16, 9)</p>
      </li>
      <li><em>per conoscere i programmi TV della giornata entro un periodo limitato di tempo:</em>
        <div class="language-php highlighter-rouge"><pre class="highlight"><code> @cosaceintv dalle 16:00 alle 19:00 #1
</code></pre>
        </div>
      </li>
      <li><em>per conoscere i programmi TV su un determinato canale, a partire dall’ora corrente:</em>
        <div class="language-php highlighter-rouge"><pre class="highlight"><code> @cosaceintv su RAI1 #1
</code></pre>
        </div>
        <p>(canali disponibili: <strong>RAI1, RAI2, RAI3, CANALE5, ITALIA1, RETE4, LA7</strong>)</p>
      </li>
      <li><em>per conoscere i programmi TV su piu’ canali, a partire dall’ora corrente:</em>
        <div class="language-php highlighter-rouge"><pre class="highlight"><code> @cosaceintv su RAI1, RAI2, RAI3 #1
</code></pre>
        </div>
      </li>
      <li><em>per conoscere i programmi TV su un (o piu’) canale(i), a partire da una determinata ora:</em>
        <div class="language-php highlighter-rouge"><pre class="highlight"><code> @cosaceintv su RAI1,RAI2 alle 19:00 #1
</code></pre>
        </div>
      </li>
      <li><em>per conoscere i programmi TV su un (o piu’) canale(i), entro un periodo limitato di tempo:</em>
        <div class="language-php highlighter-rouge"><pre class="highlight"><code> @cosaceintv su RAI1,RAI2 dalle 19:00 alle 21:00 #1
</code></pre>
        </div>
      </li>
    </ul>
  </li>
  <li>
    <p>Dopo aver inviato il tweet, aspettate circa 3 minuti e… enjoy tweets :)</p>
  </li>
</ul>

<p>p.s. l’attesa dipende anche dal tempo di sincronizzazione del vostro client twitter.</p>

<p>Il progetto è ancora in uno stato alpha, tuttavia è già disponibile online per effettuare prove:</p>

<p><strong><a href="http://cosaceintv.it">cosaceintv.it</a></strong></p>

<p>That’s all folks! Stay tuned!</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[OpenGazzettaUfficiale: la legge e' Open per tutti]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2013/08/28/opengazzettaufficiale-la-legge-e-open-per-tutti/"/>
    <updated>2013-08-28T07:39:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2013/08/28/opengazzettaufficiale-la-legge-e-open-per-tutti</id>
    <content type="html"><![CDATA[<p>Circa un anno fa avevo intenzione di sviluppare un servizio che automaticamente mi inviasse via mail il bando dei concorsi
pubblici non scaduti, relativamente a dei settori di interesse da me specificati. In rete esistono già svariati siti Web
sui concorsi ma io volevo ottenere una maggiore flessibilità di interrogazione. Così, di primo acchito, sono andato sulla
fonte ufficiale e più importante dei concorsi pubblici in Italia, vale a dire la <strong>gazzetta ufficiale</strong>, dove, con mia grande
sorpresa, ho letto il seguente disclaimer:</p>

<!--More-->
<p>#}</p>

<blockquote>
  <p>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.</p>
</blockquote>

<p>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.</p>

<p>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 <em>scraping</em> senza scontrarmi con autorizzazioni e permessi vari
sono andate in fumo.</p>

<p>Tutto questo fino alla fine dell’anno scorso perchè, con mia stragrande meraviglia le cose sono cambiate.<br />
Dal 1° gennaio 2013 infatti sul sito ufficiale della <a href="http://www.gazzettaufficiale.it">Gazzetta Ufficiale</a> è apparso il seguente disclaimer:</p>

<blockquote>
  <p>L’Istituto Poligrafico e Zecca dello Stato S.p.A. <strong>promuove la più ampia fruibilità</strong> della Gazzetta Ufficiale della Repubblica Italiana in formato digitale. […] La riproduzione dei testi forniti nel formato elettronico <strong>è consentita</strong> purché venga menzionata la fonte, il carattere non autentico e gratuito.</p>
</blockquote>

<p>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.</p>

<p>Partendo da questo, complici le ferie estive e il mio pallino per gli <a href="http://it.wikipedia.org/wiki/Dati_aperti">Open Data</a>, 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 <code class="highlighter-rouge">OpenGazzettaUfficiale</code>.</p>

<p>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 <a href="http://www.dati.gov.it/iodl/2.0/">IODL v2</a>.</p>

<p>Il dataset di riferimento comprende le gazzette ufficiali suddivise nelle seguenti serie:</p>

<ul>
  <li><strong>Serie Generale:</strong>  Atti normativi ad amministrativi emanati dalle Amministrazioni centrali e periferiche	
  dello Stato (dal 1945);</li>
  <li><strong>1a Serie Speciale - Corte Costituzionale:</strong> decisioni della Corte Costituzionale ed Atti di promovimento
  rimessi al giudizio della Corte (dal 1956);</li>
  <li><strong>2a Serie Speciale - Unione Europea:</strong> atti comunitari (dal 1984);</li>
  <li><strong>3a Serie Speciale - Regioni:</strong> atti normativi ad amministrativi di interesse nazionale emanati
  dalle singole Regioni (dal 1988);</li>
  <li><strong>4a Serie Speciale - Concorsi ed Esami:</strong> concorsi banditi dalle Amministrazioni centrali e periferiche
  dello Stato (dal 1999);</li>
  <li><strong>5a Serie Speciale - Contratti Pubblici:</strong> bandi di gara banditi dalla Pubblica Amministrazione (dal 2007);</li>
  <li><strong>Parte II - Foglio delle inserzioni:</strong> inserzioni commerciali e giudiziarie di soggetti pubblici e privati  (dal 2007).</li>
</ul>

<p>Vediamo un pò di numeri.</p>

<p>Sul sito ufficiale la <strong>serie generale</strong> (la più grande e completa), comprende tutti i numeri delle gazzette ufficiali dal 1945, quindi ad oggi sono quasi <strong>68 anni</strong>. Ciascun anno (ad eccezione del primo) include circa <strong>300 numeri</strong> di gazzette. Ogni numero raccoglie anche fino a 
<strong>60 atti</strong>. Ciascun atto è formato poi da un certo numero di articoli (anche fino a 30) e da allegati sia testuali che esterni in <strong>pdf</strong>. Il contenuto di ciascuna serie, anno, gazzetta, atto, articolo o allegato è raggiungibile con un URL univoco. E questo solo la <strong>serie generale</strong>.</p>

<p>Facendo una stima molto provvisoria, solo per la serie generale, si arrivano a contare più di 7 milioni di link da <em>scrapare</em>. Poi ci sono tutte le altre serie.
Dal punto di vista tecnico utilizzo componenti <a href="http://www.symfony.com">Symfony</a> 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.</p>

<p>Per informazioni sulle API guardare la documentazione presente nella <a href="http://www.opengazzettaufficiale.it">homepage</a> del progetto.</p>

<p>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 <em>aeronautica</em>. E’
necessario quindi attivare un servizio <strong>cron</strong>, limitatamente nei giorni di martedì e venerdì, che sono i giorni in cui viene pubblicata la Gazzetta Ufficiale serie <strong>Concorsi</strong>, per il seguente script:</p>

<div class="language-php highlighter-rouge"><pre class="highlight"><code>
<span class="cp">&lt;?php</span>

	<span class="nv">$topic</span> <span class="o">=</span> <span class="s1">'aeronautica'</span><span class="p">;</span>
	<span class="nv">$json</span> <span class="o">=</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="s1">'http://www.opengazzettaufficiale.it/serie/concorsi'</span><span class="p">);</span>
	<span class="nv">$serie</span> <span class="o">=</span> <span class="nb">json_decode</span><span class="p">(</span><span class="nv">$json</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
	<span class="nv">$ultimoAnnoSerie</span> <span class="o">=</span> <span class="nb">array_reverse</span><span class="p">(</span><span class="nv">$serie</span><span class="p">[</span><span class="s1">'anni'</span><span class="p">])[</span><span class="mi">0</span><span class="p">];</span>
	<span class="nv">$json</span> <span class="o">=</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="nv">$ultimoAnnoSerie</span><span class="p">[</span><span class="s1">'url'</span><span class="p">]);</span>
	<span class="nv">$numeriGazzetta</span> <span class="o">=</span> <span class="nb">json_decode</span><span class="p">(</span><span class="nv">$json</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
	<span class="nv">$ultimaGazzetta</span> <span class="o">=</span> <span class="nb">array_reverse</span><span class="p">(</span><span class="nv">$numeriGazzetta</span><span class="p">[</span><span class="s1">'gazzette'</span><span class="p">])[</span><span class="mi">0</span><span class="p">];</span>
	<span class="nv">$json</span> <span class="o">=</span> <span class="nb">file_get_contents</span><span class="p">(</span><span class="nv">$ultimaGazzetta</span><span class="p">[</span><span class="s1">'url'</span><span class="p">]);</span>
	<span class="nv">$sommario</span> <span class="o">=</span> <span class="nb">json_decode</span><span class="p">(</span><span class="nv">$json</span><span class="p">,</span> <span class="kc">true</span><span class="p">);</span>
	<span class="nv">$atti</span> <span class="o">=</span> <span class="nv">$sommario</span><span class="p">[</span><span class="s1">'atti-gazzetta-ufficiale'</span><span class="p">];</span>

	<span class="k">foreach</span><span class="p">(</span><span class="nv">$atti</span> <span class="k">as</span> <span class="nv">$atto</span><span class="p">)</span> <span class="p">{</span>
	    <span class="k">if</span> <span class="p">(</span><span class="nb">preg_match</span><span class="p">(</span><span class="s2">"/.*</span><span class="nv">$topic</span><span class="s2">.*/"</span><span class="p">,</span> <span class="nv">$atto</span><span class="p">[</span><span class="s1">'breve'</span><span class="p">]))</span> <span class="p">{</span>
	        <span class="nv">$to</span>      <span class="o">=</span> <span class="s1">'giovanni.pirrotta@gmail.com'</span><span class="p">;</span>
		    <span class="nv">$subject</span> <span class="o">=</span> <span class="nv">$atto</span><span class="p">[</span><span class="s1">'oggetto'</span><span class="p">];</span>
			<span class="nv">$message</span> <span class="o">=</span> <span class="nv">$atto</span><span class="p">[</span><span class="s1">'breve'</span><span class="p">]</span> <span class="p">;</span>
			  
			<span class="nb">mail</span><span class="p">(</span><span class="nv">$to</span><span class="p">,</span> <span class="nv">$subject</span><span class="p">,</span> <span class="nv">$message</span><span class="p">);</span> <span class="c1">// mail, tweet, facebook, etc...
</span>	    <span class="p">}</span>
	<span class="p">}</span>
</code></pre>
</div>

<p>Il codice è autoesplicativo.</p>

<p>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.</p>

<p>Feedback, commenti e critiche sono i benvenuti.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[OpenAlboPretorio: apriti sesamo - aggiornato]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2013/07/22/openalbopretorio-apriti-sesamo/"/>
    <updated>2013-07-22T15:09:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2013/07/22/openalbopretorio-apriti-sesamo</id>
    <content type="html"><![CDATA[<p>Sono iscritto ormai da più di due anni alla mailing list <a href="https://groups.google.com/forum/#!forum/spaghettiopendata"><strong>Spaghetti Open Data</strong></a> (<strong>SOA</strong>), 
punto di incontro di un gruppo di persone, di professione tra loro eterogenea (programmatori, ricercatori, avvocati, esperti del settore, semplici curiosi, etc.), interessati al rilascio dei dati pubblici in formato aperto, leggi <a href="http://it.wikipedia.org/wiki/Dati_aperti">Open Data</a>. Anche se non partecipo attivamente alle attività della community, ogni volta che torno a leggere i post della lista trovo sempre qualcosa che mi arricchisce e ispira.</p>

<p>Così è stato anche quando nel novembre del 2012 ho letto che l’utente <code class="highlighter-rouge">eccoilmoro</code> aveva realizzato, come esperimento di civic-hacking, lo scraping dell’albo pretorio online dei comuni della Bassa Romagna, reindirizzando il tutto su una pagina 
<a href="https://www.facebook.com/AlboPretorioBassaRomagna">FB</a> prima e su un profilo <a href="https://twitter.com/BassaRomagna">Twitter</a> dopo.
Il tutto è stato poi riportato in questo <a href="http://opendatabassaromagna.blogspot.it/2013/06/lalbo-pretorio.html">blog</a>.</p>

<!--More-->

<p>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è <a href="http://www.rssgraffiti.com/">RSSGraffiti</a>.
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).</p>

<p>Come già scritto in un precedente <a href="http://giovanni.pirrotta.it/blog/2013/06/12/terme-vigliatore-e-la-sua-storia-amministrativa/">post</a>, credo
fermamente che ogni pubblica amministrazione debba innescare meccanismi e processi interni ispirati a principi di
<strong>trasparenza</strong> ed <strong>apertura</strong> 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 <a href="http://it.wikipedia.org/wiki/Open_government">open-gov</a>.</p>

<p>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 <strong>OpenAlboPretorio</strong>, disponibile su <a href="https://github.com/gpirrotta/OpenAlboPretorio">github</a>.</p>

<p>Per l’installazione</p>

<ul>
  <li>cloniamo la libreria sulla nostra macchina:</li>
</ul>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>git clone https://github.com/gpirrotta/OpenAlboPretorio.git
<span class="gp">$ </span><span class="nb">cd </span>OpenAlboPretorio
</code></pre>
</div>

<p>e digitiamo i seguenti comandi:</p>

<div class="language-bash highlighter-rouge"><pre class="highlight"><code><span class="gp">$ </span>wget http://getcomposer.org/composer.phar
<span class="gp">$ </span>php composer.phar install
</code></pre>
</div>

<p>A questo punto aggiungiamo l’autoloader al nostro script e avremo accesso alla libreria</p>

<div class="language-php highlighter-rouge"><pre class="highlight"><code>
<span class="cp">&lt;?php</span>

<span class="k">require</span> <span class="s1">'vendor/autoload.php'</span><span class="p">;</span>

</code></pre>
</div>

<p>La class <code class="highlighter-rouge">OpenAlboPretorio</code> rappresenta l’entry point della libreria.</p>

<p>Attualmente sono implementati i seguenti scraper:</p>

<ul>
  <li><code class="highlighter-rouge">TermeVigliatoreScraper</code> effettua lo scraping dall’<a href="http://85.33.208.78:82/albopretorio/ricerca_atti.asp">Albo Pretorio online</a> di Terme Vigliatore (ME)</li>
  <li><code class="highlighter-rouge">BarcellonaPGScraper</code> effettua lo scraping dall’<a href="http://88.41.51.242/gesdelidet/dadabik_4.2/program_files/index.php?table_name=atti&amp;function=search&amp;where_clause=&amp;page=0&amp;order=datapu&amp;order_type=DESC&amp;records_per_page=50">Albo Pretorio online</a> di Barcellona Pozzo di Gotto (ME)</li>
</ul>

<p>e i seguenti formati di output:</p>

<ul>
  <li>JSON</li>
  <li>RSS</li>
  <li>ATOM</li>
</ul>

<p>Vediamo adesso come utilizzare la libreria.<br />
E’ possibile utilizzare il metodo <code class="highlighter-rouge">city</code> per selezionare lo scraper con le impostazioni di default (max 10 risultati)</p>

<div class="language-php highlighter-rouge"><pre class="highlight"><code><span class="cp">&lt;?php</span>

    <span class="nv">$albo</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">OpenAlboPretorio</span><span class="p">();</span>
    <span class="nv">$results</span> <span class="o">=</span> <span class="nv">$albo</span><span class="o">-&gt;</span><span class="na">city</span><span class="p">(</span><span class="nx">AlboPretorioScraperFactory</span><span class="o">::</span><span class="na">TERME_VIGLIATORE</span><span class="p">);</span>
                    <span class="o">-&gt;</span><span class="na">open</span><span class="p">();</span>

    <span class="k">print</span> <span class="nv">$results</span>  
</code></pre>
</div>

<p>Oppure è possibile personalizzare lo scraper manualmente:</p>

<div class="language-php highlighter-rouge"><pre class="highlight"><code><span class="cp">&lt;?php</span>

    <span class="nv">$scraper</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">BarcellonaPGScraper</span><span class="p">(</span><span class="k">new</span> <span class="nx">BarcellonaPGMasterPageScraper</span><span class="p">(),</span> <span class="k">new</span> <span class="nx">BarcellonaPGDetailPageScraper</span><span class="p">());</span>
    <span class="nv">$scraper</span><span class="o">-&gt;</span><span class="na">setItemType</span><span class="p">(</span><span class="nx">BarcellonaPGScraper</span><span class="o">::</span><span class="na">TIPOLOGIA_DETERMINAZIONE_DEL_SINDACO</span><span class="p">);</span>

    <span class="nv">$formatter</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">FeedFormatter</span><span class="p">(</span><span class="nx">FeedFormatter</span><span class="o">::</span><span class="na">ATOM_FEED_TYPE</span><span class="p">);</span>  <span class="c1">// RSS2 default
</span>
    <span class="nv">$albo</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">OpenAlboPretorio</span><span class="p">();</span>
    <span class="nv">$results</span> <span class="o">=</span> <span class="nv">$albo</span><span class="o">-&gt;</span><span class="na">scrapeUsing</span><span class="p">(</span><span class="nv">$scraper</span><span class="p">)</span>
                    <span class="o">-&gt;</span><span class="na">formatUsing</span><span class="p">(</span><span class="nv">$formatter</span><span class="p">)</span>
                    <span class="o">-&gt;</span><span class="na">maxNumberItems</span><span class="p">(</span><span class="mi">10</span><span class="p">)</span>
                    <span class="o">-&gt;</span><span class="na">open</span><span class="p">();</span>
    <span class="k">print</span> <span class="nv">$results</span><span class="p">;</span>

</code></pre>
</div>

<p>Per creare lo scraper della tua città è necessario implementare l’interfaccia <code class="highlighter-rouge">AlboPretorioScraperInterface</code>.
Estrarre i dati dal sito Web dell’albo pretorio di una qualsiasi città significa, generalmente, estrarre i dati da due pagine:</p>

<p>1) una pagina <strong>Master</strong> -  la pagina Web che contiene l’elenco di tutti gli atti amministrativi (<strong>items</strong>) dove su ciascun atto troviamo una breve descrizione e il link relativo (in figura il link è sulla descrizione in grassetto);</p>

<p><img src="/images/master-terme-vigliatore.png" alt="Master Terme Vigliatore" /></p>

<p>2) una pagina <strong>Detail</strong> - la singola pagina Web dell’atto amministrativo contenente il dettaglio (numero, mittente, oggetto, stato, validità di pubblicazione, allegati, etc.)
<img src="/images/detail-terme-vigliatore.png" alt="Detail Terme Vigliatore" /></p>

<p>Per gestire questo tipo di logica di estrazione dei dati la libreria fornisce una classe astratta
chiamata <code class="highlighter-rouge">AbstractMasterDetailTemplateScraper</code> che implementa l’interfaccia <code class="highlighter-rouge">AlboPretorioScraperInterface</code>.</p>

<p>La classe dipende dalle seguenti interfacce:</p>

<ul>
  <li><code class="highlighter-rouge">MasterPageScraperInterface</code> usata per estrarre l’elenco degli URL degli atti amministrativi dalla pagina master;</li>
  <li><code class="highlighter-rouge">DetailPageScraperInterface</code> usata per estrarre i dati di ciascun atto amministrativo ritornando un oggetto <code class="highlighter-rouge">AlboPretorioItem</code></li>
</ul>

<p>Ovviamente, se il template della pagina Web dell’albo pretorio segue una logica di estrazione diversa da quella <strong>Master-Detail</strong>, è possibile implementarne di nuove in base alle proprie esigenze.</p>

<p>La libreria si trova su <a href="https://github.com/gpirrotta/OpenAlboPretorio">github</a>, rilasciata con licenza 
opensource <a href="http://opensource.org/licenses/MIT">MIT</a>.</p>

<p><strong>N.B.</strong> In merito alla liceità sull’attività di scraping di dati della pubblica amministrazione voglio condividere con voi alcune osservazioni:</p>

<ul>
  <li>
    <p>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;</p>
  </li>
  <li>
    <p>dall’altro, dal 19 marzo 2013, tutti i dati e documenti che le pubbliche amministrazioni pubblicano con qualsiasi modalità, <strong>senza l’espressa adozione di una licenza d’uso</strong>, si intendono rilasciati come dati aperti secondo il principio 
  <em>open data by default</em>  (art. 52 e art.68 del Codice Amministrazione Digitale), anche se non è stato ancora
  deciso il tipo di licenza.</p>
  </li>
</ul>

<p>L’albo pretorio online dei comuni finora presenti su <strong>OpenAlboPretorio</strong> non riportano nessun tipo di licenza di rilascio dei dati
in fondo alla pagina, motivo per cui <em>rientrerei</em> (spero) nel secondo punto. E’ un aspetto sicuramente da approfondire, motivo per cui consiglio a chiunque voglia utilizzare <strong>OpenAlboPretorio</strong> 
di stare vigili sull’argomento.</p>

<p>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.</p>

<p>That’s all folks!</p>

<p><strong>Importante aggiornamento</strong></p>

<p>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.</p>

<p>In estrema sintesi gli atti dell’albo pretorio possono essere suddivisi in due categorie (ringrazio Giovanni Battista Gallus per il chiarimento):</p>

<ul>
  <li>atti dell’albo pretorio online, oggetto anche di pubblicazione
obbligatoria ex d.lgs 33: questi dati dovrebbero essere “replicati” anche nella sezione “amministrazione trasparente” dei siti comunali e su di loro trova piena applicazione il decreto trasparenza - pubblicabili per 5 anni, riusabili, open by default;</li>
  <li>atti dell’albo pretorio online, <strong>NON</strong> oggetto di pubblicazione obbligatoria: occorre applicare le linee guida del Garante e laddove contengano dati personali, occorre fare molta attenzione ai trattamenti illeciti.</li>
</ul>

<p>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.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Can machines think?]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2013/07/04/can-machines-think/"/>
    <updated>2013-07-04T16:27:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2013/07/04/can-machines-think</id>
    <content type="html"><![CDATA[<p>Suppose we want to become a policeman and to participate in the selection we need to complete the online request application available in the police Website. To do this, we decide to rely this task to our software agent to achieve an independent interaction between the software agent and the police homepage. Simplifying a lot, our software agent could start from the police homepage and, through string-matching analysis and exploration of the links, it might be able to recognize a page containing the words <strong>selection</strong> and <strong>2013</strong> and it could “think” to have found the right page to start its interaction.</p>

<!--More-->

<p>Imagine we encounter the sentence</p>

<blockquote>
  <p>In 2013, the minimum required height for male candidate is 1.65</p>
</blockquote>

<p>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 <strong>2013</strong> and <strong>1.65</strong>, the first indicating the year and the second the height.</p>

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

<p>The only way to help the computer to understand <strong>something</strong> is to rewrite the sentence in a structured way, using markers to define the meaning of parts.</p>

<p>For example, we can rewrite the previous sentence using the following markers:</p>

<div class="highlighter-rouge"><pre class="highlight"><code>[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] {.}
</code></pre>
</div>

<p>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.</p>

<p>The future of the Web, according to Tim Berners-Lee <a href="http://www.xml.com/pub/a/2000/12/xml2000/timbl.html">vision</a>, 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.</p>

<p>All information will be expressed by formal descriptive statements saying the relationship existing between two resources (<em>i.e. Michael is a student, the sky is blue, etc.</em>) and data can be represented as a <strong>giant global graph</strong>, highly interconnected and finally <strong>machine-understandable</strong>.</p>

<p>The Semantic Web goal is to extend the actual Web, transforming it into the <a href="http://www.linkeddata.org/"><strong>Web of Data</strong></a>.
The semantic technologies provide necessary tools to reuse information implementing systems for <strong>typifying</strong> content and links between pages. The Semantic Web research area includes a <a href="http://www.w3.org/standards/semanticweb/">set</a> 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.</p>

<p><img src="/images/semantic_web_stack.jpg" alt="Image" class="center-image" /></p>

<p>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!</p>

<p>Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Terme Vigliatore Statistics]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2013/06/12/terme-vigliatore-e-la-sua-storia-amministrativa/"/>
    <updated>2013-06-12T09:43:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2013/06/12/terme-vigliatore-e-la-sua-storia-amministrativa</id>
    <content type="html"><![CDATA[<p>Il popolo sovrano ha deciso.<br />
<a href="http://it.wikipedia.org/wiki/Terme_Vigliatore">Terme Vigliatore</a> ha eletto il suo primo cittadino riconfermando il sindaco uscente.<br />
Personalmente non ne potevo più del fermento elettorale che si era innescato da mesi e
che vedeva i protagonisti delle varie liste, dei movimenti e degli schieramenti darsele (metaforicamente parlando) di santa ragione per accrescere il proprio bacino elettorale.<br />
Tutto questo è ormai (e per fortuna) acqua passata!</p>

<p>Da qualche tempo però, appassionato di <a href="http://it.wikipedia.org/wiki/Data_mining">data mining</a>,
è nato in me il desiderio di effettuare ricerche statistiche sulla storia delle amministrazioni passate, per ricavarne qualcosa di interessante e curioso.</p>

<!--More-->

<p>Primo passo, la ricerca di fonti attendibili dalle quali prelevare i dati per iniziare le elaborazioni.</p>

<p>Dopo una prima ricerca infruttuosa sul sito del <a href="http://www.comune.termevigliatore.me.it/public/">comune</a> ho trovato nel
sito del <strong>Ministero dell’Interno</strong> e nello specifico in questa <a href="http://amministratori.interno.it/amministratori/AmmIndex5.htm">pagina</a>
informazioni davvero interessanti.
La pagina consente infatti di scaricare tutti gli archivi in formato standard
<a href="http://it.wikipedia.org/wiki/Comma-separated_values">CSV</a> relativi agli amministratori comunali, provinciali e
regionali di tutti i comuni d’Italia con rilevazioni annuali dal 1985 al 2012.</p>

<p>Possiamo partire!</p>

<p>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:</p>

<div class="highlighter-rouge"><pre class="highlight"><code>- 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
</code></pre>
</div>

<p>Dopo un’oretta passata tra script bash di estrazione, conversione e riconciliazione dei dati vediamo cosa ne è uscito
fuori.</p>

<p>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?<br />
Non verranno presi infine in considerazione gli anni relativi all’ultimo commissariamento (2005-2007) in quanto
mancanti.</p>

<p>Bene, cominciamo a farci qualche domanda e a rispondere mostrando le statistiche elaborate!</p>

<p>** 1) Quante donne hanno amministrato Terme Vigliatore negli ultimi 24 anni? **</p>

<p>Poche; aggiungo io, purtroppo. Su un totale di <strong>79</strong> amministratori tra sindaci, consiglieri e assessori, solo
l’ <strong>11%</strong> di donne sono salite sullo <em>scranno</em> comunale.</p>

<p><img src="/images/elezioni/distribuzione-sessi.png" alt="Image" class="center-image" /></p>

<p>** 2) Qual è stato il livello di istruzione dei nostri amministratori? **</p>

<p><img src="/images/elezioni/livello-istruzione.png" alt="Image" class="center-image" /></p>

<p>** 3) Che lavoro facevano i nostri amministratori? **</p>

<p><img src="/images/elezioni/professioni-amministratori.png" alt="Image" class="center-image" /></p>

<p>** 4) Dove sono nati i nostri amministratori? **</p>

<p>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.</p>

<p><img src="/images/elezioni/luogo-nascita.png" alt="Image" class="center-image" /></p>

<p>** 5) Qual era l’età media degli amministratori? **</p>

<p><img src="/images/elezioni/eta-media-amministratori2.png" alt="Image" class="center-image" /></p>

<p>** 6) Chi sono stati i nostri amministratori e per quanto tempo? **<br />
(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))</p>

<p><img src="/images/elezioni/anni-in-carica-amministratori.png" alt="Image" class="center-image" /></p>

<p>That’s all folks!</p>

<p>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:</p>

<ul>
  <li>
    <p><strong>trasparenza</strong>: 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;</p>
  </li>
  <li>
    <p><strong>apertura</strong>: 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;</p>
  </li>
  <li>
    <p><strong>partecipazione</strong>: 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 <em>gap</em> esistente tra i cittadini e il palazzo comunale, tra elettori ed eletti;</p>
  </li>
  <li>
    <p><strong>collaborazione</strong>: perchè non si consideri il comune come un’istituzione disconnessa a se stante, modello <em>isola</em>, 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.</p>
  </li>
</ul>

<p>In una sola parola: <a href="http://it.wikipedia.org/wiki/Open_government"><strong>open government</strong></a>!</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Limits of the Web today]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2013/06/03/limits-of-the-web-today/"/>
    <updated>2013-06-03T10:39:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2013/06/03/limits-of-the-web-today</id>
    <content type="html"><![CDATA[<p>The Web was born in 1999 at the <a href="http://www.cern.ch">CERN</a> laboratory, when scientist need to share information and scientific researches in realtime. To accomplish this task, Tim Berners-Lee conceived a <a href="http://www.w3.org/History/1989/proposal.html">hypertextual system of communication</a> between documents that became, in few years, the keystone of the World Wide Web (WWW). He introduces a markup convention, called <em>HyperText Markup Language</em> (HTML), to visualize and format documents allowing the linking through <em>anchor</em> words. When HTML pages are loaded in Web server programs installed on computers and located in different places of the world, users can reach the Web documents using particular programs called browsers allowing them to navigate the Web of linked documents.
<!--More--></p>

<p>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.<br />
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.</p>

<p>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 <em>nuance</em> of meaning that we want to express without problems of interpretation. For example, if we search the Italian word <em>espresso</em>, how does the search engine understand if we are searching for information about:</p>

<ul>
  <li>espresso, the past participle of the Italian verb <strong>esprimere</strong>;</li>
  <li>espresso, a kind of Italian <strong>train</strong>;</li>
  <li>espresso, a kind of <strong>coffee</strong>;</li>
  <li>espresso, the famous Italian <strong>newspaper</strong>.</li>
</ul>

<p>The word <em>espresso</em> 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 <em>understand</em> 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.</p>

<p>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.</p>

<p>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 “<em>ABC</em>” is a <strong>DVD recorder</strong> with a price of <strong>euro 100,00</strong>. 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 <em>“This is an e-commerce site”</em> or event to establish that <em>DVD recorder</em> is a kind of product or that <em>euro 100,00</em> is a price.</p>

<p>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.<br />
We have problems in terms of interpretation, integration and automatic processing.</p>

<p>That’s all for now. In the next post I will talk about how machines can think. Stay tuned!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Semantic Web what?]]></title>
    <link href="http://giovanni.pirrotta.it/blog/2013/05/24/semantic-web-what/"/>
    <updated>2013-05-24T16:53:00+00:00</updated>
    <id>http://giovanni.pirrotta.it/blog/2013/05/24/semantic-web-what</id>
    <content type="html"><![CDATA[<p>The <strong>Semantic Web</strong> term was coined by the same founding father of the Web, <a href="http://www.w3.org/People/Berners-Lee/">Tim Berners-Lee</a>, with the aim of extending the current Web in a structured environment in which each resource can be semantically processed.</p>

<p>A very famous <a href="http://tinyurl.com/tbl-semweb">example</a> 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. 
<!--More-->
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.</p>

<p>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.</p>

<p>In the Web of the future, every doctor’s homepage should provide the ability to <strong>understand</strong> and <strong>interrogate</strong> 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.</p>

<p>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 <a href="http://www.w3.org/DesignIssues/LinkedData.html">Linked Data principles</a> which have brought a breath of fresh air to Semantic Web applications.</p>
]]></content>
  </entry>
  
</feed>
