Archivio

Archivio dell'autore

Open Pronto Soccorsi: rendere disponibili, ed accessibili, i dati, di numeri e tempi di attesa per tipologia, dei pronto soccorsi italiani

24 luglio 2018 2 commenti

Immaginate una sera d’estate, un gruppo di ex-pallavolisti non più proprio giovanissimi, una pizza e qualche birra (magari anche qualcuna di troppo ), …. si trova uno spiazzo, compare un pallone (un vecchio Mikasa bianco … per chi ci ha giocato …. il famoso “mattone” …), e questi eterni ragazzini che iniziano a palleggiare come se non fosse passato il tempo …. solo che il tempo è passato e alla fine chiede il prezzo da pagare …. un palla un pò più alta del solito, un palleggio “fantasioso” e … crack!! un rumore bruttissimo di dita …. partono gli sfottò …. “cosa fai che non sei capace!!” … “non sei MAI stato capace …. !! ” ecc … ma poi le dita iniziano ad assumere un colore rossiccio, si gonfiano … e alè … si deve andare a concludere la serata al pronto soccorso e parte la discussione sul dove andare … “andiamo al pronto soccorso del ….. !!” … “Nooo lì non ci passa più, andiamo al pronto soccorso del ….., è un pò più lontano ma si fà prima!! Tanto mica è rotto … forse …” … ecc …

La scena poteva essere del tutto analoga se si fosse parlato della solita partita a calcetto tra colleghi di ufficio o della ancor più classica “scapoli e ammogliati”, e al posto delle dita ci fosse stata una caviglia, o anche una più semplice e classica indisposizione nel corso di una trasferta di lavoro in giro per l’Italia in posti non conosciuti.

Su quali basi prendiamo decisioni come quelle di cui sopra? Quali informazioni abbiamo a disposizione? Tendenzialmente sulla “sensazione”, se siamo in zone in cui conosciamo dove sono le strutture ospedaliere dotate di pronto soccorso (ci “fidiamo” dell’ospedale che conosciamo meglio, siamo sempre andati in quello, ecc … ), se no, nemmeno su quella se siamo in zone che non sono quelle solite che frequentiamo, e ci affidiamo ….. al “caso”.
Open Pronto Soccorsi parte da queste considerazioni e ha come obiettivo quello di provare a rendere disponibili, e accessibili, le informazioni sulle attese (numeri e tempi), dei pronto soccorsi italiani.

Non è una cosa del tutto innovativa: in rete ci sono diverse applicazioni (dai siti web alle app per smartphone), che offrono queste informazioni, ma per lo più per zone territoriali limitate o per specifiche Aziende Sanitarie Locali.

La novità proposta da Open Pronto Soccorsi è che prova a farlo sull’intero territorio nazionale usando i dati disponibili, siano essi open data (o open services …), o sfruttando i siti web che pubblicano queste informazioni andandoli a “leggere” in tempo reale, in modo del tutto analogo a come farebbe un utente che acceda al sito stesso (variando in tempo reale questi dati non potrebbero essere memorizzati su database …).

Open Pronto Soccorsi, per quanto funzionante in tutte le sue parti, è comunque da considerarsi una sorta di “proof of concept” ed esperienza prototipale e, al tempo stesso, anche un esempio di come non si fanno alcune cose (mi spiegherò più avanti …).

Abbiamo detto che Open Pronto Soccorsi usa i dati disponibili sull’intero territorio nazionale, siano essi open data o sfruttando i dati pubblicati tramite i siti web:

  • questi dati ci sono?
  • quanti sono?
  • sono uniformemente distribuiti?

Iniziamo con il dire che:

  • i dati sono distribuiti a macchia di leopardo sul territorio nazionale, quindi NON in modo uniforme. Ma, seppur in parte, ci sono. La loro disponibilità mi fà venire in mente due considerazioni:
  • dati disponibili come opendata, nel senso di esposti tramite un portale open data in un formato machine readable, documentati e dotati di opportuna licenza vi sono solo nel Lazio (rif. http://dati.lazio.it/catalog/it/dataset/pronto-soccorso-accessi-in-tempo-reale ), o almeno io ho trovato solo questi … vi prego di segnalarmi casi che posso non aver raccolto e sarà mia cura aggiungerli al sistema. Nella realtà, volendo, anche il Friuli Venezia Giulia esporrebbe questi dati in un formato machine readable, ma non lo fa in modo ufficiale attraverso un portale open data. Lo si scopre solo analizzando, con la console del browser, il traffico di rete che intercorre quando viene consultato il sito del portale regionale dei servizi della Sanità (rif. https://servizionline.sanita.fvg.it/psonline/#/index ) (e se vogliamo questo è il secondo esempio di come “non” si dovrebbero fare le cose, nel senso che il dato, o meglio il servizio, è disponibile ma non pubblicato in modo ufficiale, e quindi per usarlo si deve fare di necessità virtù ….)
  • la maggior parte dei dati è “contenuta” all’interno di pagine web dei diversi siti delle aziende ospedaliere locali o degli ospedali
    Si, ma quanti sono e quali sono? Alla data della pubblicazione di questo post sono riuscito a recuperare (ricerca fatta “a mano” sul web …), i dati per i pronto soccorsi di 172 comuni (per quelli con più di un pronto soccorso potrebbero non esserci tutti …), che sono i seguenti:
Abano Terme Cavalese Lucera Rovigo
Acquapendente Cerignola Luino San Bonifacio
Adria Chioggia Malcesine San Daniele del Friuli
Agordo Cittadella Manduria San Dona’ di Piave
Alatri Cittiglio Manfredonia San Gavino Monreale
Albano Laziale Cividale del Friuli Mantova San Giovanni in Persiceto
Alghero Civita Castellana Martina Franca San Marcello Pistoiese
Altamura Civitavecchia Mestre San Pietro Vernotico
Ancona Cles Mirano San Severo di Puglia
Andria Colleferro Molfetta San Vito al Tagliamento
Anzio Conegliano Monfalcone Sanremo
Arco Copertino Monopoli Santorso
Arzignano Corato Monselice Sassari
Asiago Dolo Monserrato Scorrano
Bagno a Ripoli Feltre Montagnana Sora
Bari Figline Valdarno Montebelluna Sorgono
Barletta Firenze Monterotondo Subiaco
Bassano del Grappa Foggia Muravera Taranto
Bazzano Fondi Negrar Tarquinia
Belluno Formia Noventa Vicentina Tempio Pausania
Bentivoglio Francavilla Fontana Nuoro Terlizzi
Bibione Frascati Oderzo Terracina
Bisceglie Frosinone Olbia Tione di Trento
Bologna Galatina Oristano Tivoli
Bordighera Gallipoli Ostuni Tolmezzo
Borgo San Lorenzo Gemona del Friuli Ozieri Torino
Borgo Valsugana Genova Padova Trani
Bosa Ghilarza Palermo Trecenta
Bovolone Gorizia Palestrina Trento
Bracciano Grado Palmanova Treviso
Brindisi Iglesias Peschiera del Garda Trieste
Budrio Imperia Pescia Triggiano
Bussolengo Isili Pieve di Cadore Udine
Cagliari Isola della Scala Piove di Sacco Valdagno
Camposampiero Jesolo Pistoia Varese
Canosa di Puglia La Maddalena Pordenone Velletri
Caorle Lanusei Poretta Terme Venezia
Carbonia Latina Portogruaro Vergato
Casarano Latisana Prato Verona
Caserta Lavagna Putignano Vicenza
Cassino Lecce Rieti Villafranca di Verona
Castelfranco Veneto Legnago Roma Viterbo
Castellaneta Lonigo Rovereto Vittorio Veneto

Ovviamente questa lista potrebbe non essere esaustiva (e non sono riuscito a recuperare informazioni relative a quanti sono i comuni che hanno almeno un pronto soccorso e nemmeno quanti sono in totale di pronto soccorsi in Italia se non questo articolo di La Repubblica, http://inchieste.repubblica.it/it/repubblica/rep-it/2015/04/13/news/emergenza_pronto_soccorso-110835510/, che riferisce che in totale sono 844, ma non viene citata la fonte … ), per cui se siete a conoscenza di casi non riportati vi prego di segnalarmeli e sarà mia cura aggiungerli al sistema.

Dove sono sul territorio nazionale di dati che sono riuscito a recuperare?
Eccovi una immagine della loro distribuzione:

Regione Lazio e Regione Friuli Venezia Giulia, pur esponendo questi dati in un formato machine readable lo fanno usando una “struttura dati” propria e non omogenea (sebbene largamente sovrapponibile).

Anche questo è un esempio di come “non” si dovrebbero fare le cose: l’avere una struttura dati omogenea e condivisa facilita, e di molto, il riuso e l’integrazione.

Volendo scendere nel dettaglio a tale proposito posso ancora dire che:

Partendo quindi da questi due casi, ognuno virtuoso per alcuni aspetti, la prima cosa che ho cercato di fare e provare a rendere omogenea la struttura dati con la quale distribuire questa informazione.

La struttura, in formato JSON, valorizzata per un caso reale, che OpenProntoSoccorsi propone è la seguente:

{
"Comune": "Torino",
"prontoSoccorsi": [{
"osm_id": "3451061182",
"x": "395558.38897202",
"y": "4987631.1389556",
"Lon": "7.6740615999994",
"Lat": "45.034437800007",
"ps_name": "Pronto Soccorso Pediatrico Ospedale Infantile Regina Margherita",
"city": "Torino",
"address": "Via Gianfranco Zuretti 23",
"tel": "N.D.",
"email": "N.D.",
"url_website": "http://www.cittadellasalute.to.it/index.php?option=com_content&view=article&id=6786:situazione-pazienti-in-pronto-soccorso&catid=165:pronto-soccorso&Itemid=372",
"numeri_bianco_attesa": "2",
"tempi_bianco_attesa": "N.D.",
"numeri_bianco_in_visita": "0",
"tempi_bianco_in_visita": "N.D.",
"numeri_verde_attesa": "2",
"tempi_verde_attesa": "N.D.",
"numeri_verde_in_visita": "9",
"tempi_verde_in_visita": "N.D.",
"numeri_giallo_attesa": "1",
"tempi_giallo_attesa": "N.D.",
"numeri_giallo_in_visita": "8",
"tempi_giallo_in_visita": "N.D.",
"numeri_rosso_attesa": "0",
"tempi_rosso_attesa": "N.D.",
"numeri_rosso_in_visita": "1",
"tempi_rosso_in_visita": "N.D."
}, {
"osm_id": "3538127651",
"x": "395564.61951198",
"y": "4988418.0292382",
"Lon": "7.6739770999994",
"Lat": "45.041520300007",
"ps_name": "Pronto Soccorso Presidio Molinette",
"city": "Torino",
"address": "Corso Bramante",
"tel": "N.D.",
"email": "N.D.",
"url_website": "http://www.cittadellasalute.to.it/index.php?option=com_content&view=article&id=6786:situazione-pazienti-in-pronto-soccorso&catid=165:pronto-soccorso&Itemid=372",
"numeri_bianco_attesa": "0",
"tempi_bianco_attesa": "N.D.",
"numeri_bianco_in_visita": "1",
"tempi_bianco_in_visita": "N.D.",
"numeri_verde_attesa": "9",
"tempi_verde_attesa": "N.D.",
"numeri_verde_in_visita": "34",
"tempi_verde_in_visita": "N.D.",
"numeri_giallo_attesa": "1",
"tempi_giallo_attesa": "N.D.",
"numeri_giallo_in_visita": "12",
"tempi_giallo_in_visita": "N.D.",
"numeri_rosso_attesa": "0",
"tempi_rosso_attesa": "N.D.",
"numeri_rosso_in_visita": "2",
"tempi_rosso_in_visita": "N.D."
}, {
"osm_id": "3538149967",
"x": "394879.62564376",
"y": "4989442.452764",
"Lon": "7.6650675999993",
"Lat": "45.050638200007",
"ps_name": "Pronto Soccorso Ospedale Mauriziano",
"city": "Torino",
"address": "Corso Carlo e Nello Rosselli",
"tel": "N.D.",
"email": "N.D.",
"url_website": "https://www.mauriziano.it/flex/cm/pages/ServeBLOB.php/L/IT/IDPagina/669",
"numeri_bianco_attesa": "3",
"tempi_bianco_attesa": "N.D.",
"numeri_bianco_in_visita": "2",
"tempi_bianco_in_visita": "N.D.",
"numeri_verde_attesa": "10",
"tempi_verde_attesa": "N.D.",
"numeri_verde_in_visita": "40",
"tempi_verde_in_visita": "N.D.",
"numeri_giallo_attesa": "0",
"tempi_giallo_attesa": "N.D.",
"numeri_giallo_in_visita": "20",
"tempi_giallo_in_visita": "N.D.",
"numeri_rosso_attesa": "0",
"tempi_rosso_attesa": "N.D.",
"numeri_rosso_in_visita": "1",
"tempi_rosso_in_visita": "N.D."
}]
}

quindi un array di risorse corrispondenti ai singoli pronto soccorsi attinenti ad un determinato comune italiano, ognuno con i suoi dati di dettaglio (indirizzo, coordinate, ecc .. ), e l’informazione del numero e dei tempi di attesa per ogni singolo livello di urgenza classico dei pronto soccorsi (bianco, verde, giallo e rosso).

Il grosso del lavoro è stato quindi quello di convertire le diverse fonti dato disomogenee (in formato e contenuto ..), in una struttura dati omogenea, esponendola come servizio “machine readable” così da renderla consultabile ed utilizzabile per poi costruire applicazioni fruitrici che rendessero tali informazioni direttamente utilizzabili dagli utenti finali attraverso diversi canali e modalità.

Un esempio, utilizzabile, di quanto illustrato sopra è consultabile “live” al seguente indirizzo web: http://www.cesaregerbino.it/OpenProntoSoccorsi/API/getProntoSoccorsoDetailsByMunicipality.php?municipality=Torino&distance=0
dove è possibile modificare il nome del comune e in cui il parametro distance indica, se valorizzato a zero, che la ricerca viene svolta per i pronto soccorsi che si trovano all’interno del territorio comunale del comune indicato, altrimenti permette di fare una ricerca nell’intorno del comune stesso, ad esempio distance=10000 indica una ricerca nell’intorno di 10 km dal comune indicato.

Ma non sono tutte rose e anche per questa parte, che è il vero valore aggiunto di questo lavoro, ci sono degli aspetti che evidenziano come “non” andrebbero fatte le cose, e questa volta a carico mio.

Come detto precedentemente, a parte i casi di Regione Lazio e Regione Fiuli venezia Giulia, la maggior parte dei pronto soccorsi che pubblicano i loro dati lo fanno attraverso pagine web.

In questi casi non era possibile convertire le informazioni nella struttura JSON di cui sopra, ma era necessario fare dell’ulteriore lavoro.

La strada adottata (e unica adottabile …), è stata quella di fare dello “scraping” delle pagine web, andando a “leggere” i dati in esse contenuti e convertendoli nel formato di cui sopra per rendere il tutto omogeneo e trasparente.

Perchè questo, seppur per un buon fine, non è il modo con cui fare correttamente le cose:

  • perchè lo scraping delle pagine web è un’operazione un pò “borderline”, anche dal punto di vista delle licenze d’uso. E’ pur vero che, nel caso specifico, la soluzione adottata NON preleva dati dalle pagine per memorizzarle nel sistema (non avrebbe senso perchè è un dato che cambia continuamente …..), ma effettua, “live” una lettura del contenuto delle pagine web in quel preciso istante e lo ripresenta, in formato diverso (e solo per i dati di interesse … ), all’utente. Potremmo dire che, per certi versi, si sostituisce all’occhio dell’utente che altrimenti leggerebbe la pagina del sito web (ma dovrebbe conoscerne la url .. ), dal suo dispositivo di consultazione. In tale contesto OpenProntoSoccorsi NON crea o genera nemmeno ulteriore traffico di rete o carico sui sistemi finali
  • lo scraping è una soluzione “debole” e che dipende fortemente dal mantenimento della struttura della pagina web di origine. Se questa cambia, anche minimanente, questa modifica può impattare sul risultato dello scraping, e quindi impedire di recuperare le informazioni generando errori sul sistema.

Al netto delle cose di cui sopra e delle possibili contromisure (mi sono “protetto” da eventuali errori dello scraping legate al cambio di struttura delle pagine implementando un meccanismo di notifica che però non mi solleva dal dover, di volta in volta, andare a modificare l’algoritmo di scraping “riconcorrendo” le modifiche dei siti ….), il sistema, pur restando una proof of concepts, risulta essere funzionante in tutte le sue parti ed anche con prestazioni accettabili.

Seppur non oggetto principale delle attività, a partire dei servizi di OpenProntoSoccorsi, e per rendere fruibili queste informazioni, ho provato ad implementare alcune applicazioni di esempio e precisamente:

  • un bot telegram (OpenProntoSoccorsiBot), in cui è possibile indicare il nome del comune di interesse ed un raggio di ricerca nel suo intorno e che restituisce l’elenco dei pronto soccorsi con relative info sui numeri e tempi di attese per tipologia. E’ anche possibile indicare la posizione, ed un raggio di ricerca nel suo intorno, ed ottenere il medesimo risultato: in questo caso il bot permette anche di avere l’informazione del percorso per raggiungere il pronto soccorso di interesse tra quelli proposti.

Questi sono solo alcuni esempi di applicazioni realizzabili sulla base dei servizi offerti, non gli unici possibili.

Alcune proposte / evoluzioni:

  • app native (android o IOS)
  • app che, sfruttando l’output del servizio in JSON, traducano questo in un formato audio così da permettere di fornire le medesime informazioni anche ad una utenza con limiti visivi

E questo è tutto … nella speranza che nessuno ne debba mai usufruire sul serio (e comunque per i casi di necessità “serie” dei pronto soccorsi i canali ufficiali del 112 e/o del 118 restano i riferimenti principali e raccomandati … ), per chi avesse necessità di info o chiarimenti mi può contattare.

Per ulteriori dettagli tecnici si rimanda al post relativo.

P.S
Ritornando all’episodio di apertura … il dito non era rotto, ghiaccio per qualche giorno e pomate … 🙂

Annunci
Categorie:Uncategorized

Open Pronto Soccorsi: come è fatto “dentro”


In questo post vedo di fornire qualche dettaglio su quelle che sono le caratteristiche e soluzioni tecniche che stanno alla base di Open Pronto Soccorsi.

ARCHITETTURA

Schematicamente l’architettura della soluzione è la seguente:

 

 

Nel diagramma sono citati i vari componenti del sistema che:

  • è ospitato su una macchina Ubuntu 14.0.4 LTS
  • utilizza come database SQLite3 + Spatialite 4.4.0
  • implementa la logica di business in PHP 5
  • si avvale di servizi di OpenStreetMap, OSM Buildings, Mapquest e Google ShortLink

Si tratta di una soluzione che utilizza tutti software open source e attinge da servizi disponibili in rete.

Per una soluzione più scalabile è possibile passare ad utilizzare POSTGRESQL con la sua estensione POSTGIS, non cambiando la logica di funzionamento.

Nel diagramma sono anche illustrati i passi delle diverse operazioni coinvolte e precisamente:

Se la consultazione avviene via web application da browser:

  • l’utente invia una richiesta dal proprio client (a)
  • il sistema interroga la propria base dato per recuperare il nome del comune indicato e le infomazioni di quali Pronto Soccorsi sono necessarie per la ricerca (b)
  • il sistema richiama le API di OpenProntoSoccorsi per ottenere le informazioni di dettaglio sui singoli Pronto soccorsi (c)
  • la parte di implementazione delle API recupera i dati di dettaglio per le interrogazioni di ogni singolo Pronto Soccorso (d)
  • la parte di implementazione delle API interroga le fonti dati (Servizi open data siti web via scraping) (e)

Se la consultazione avviene via bot Telegram:

  • l’utente invia una richiesta dal proprio client (1)
  • il sistema recupera le richieste con un’operazione di getUpdates (2)
  • effettua le ricerche su DB (3)
  • il sistema richiama le API di OpenProntoSoccorsi per ottenere le informazioni di dettaglio sui singolo Pronto soccorsi (4)
  • la parte di implementazione delle API interroga le fonti dati (Servizi open data siti web via scraping) (e)
  • nell’elaborazione della risposta invoca i servizi di Google Shortlink per abbreviare le url (5)
  • con un’operazione di sendMessage risponde (6)
  • Telegram inoltra la risposta al client (7)
  • l’utente può fruire dei diversi link contenuti nella risposta (8, 8a, 8b e 8c)

L’intero sistema, come indicato in figura può essere ospitato su un unico nodo Apache + PHP5.

Nella configurazione attuale del sistema questo è stato diviso su due nodi:

 

DATI
I dati principali utilizzati sono:

  • i dati geografici dei comuni italiani
  • i dati della localizzazione dei pronto soccorsi italiani (o meglio del loro ingresso ….)

COMUNI
Per i dati geografici dei comuni italiani la fonte dati è ISTAT:

https://www.istat.it/it/archivio/124086 (e precisamente lo scarico dei dati in WGS84 UTM32N quindi http://www.istat.it/storage/cartografia/confini_amministrativi/non_generalizzati/2016/Limiti_2016_WGS84.zip ).
tale dato lo si può scaricare con una wget e precisamente nel seguente modo

wget http://www.istat.it/storage/cartografia/confini_amministrativi/non_generalizzati/2016/Limiti_2016_WGS84.zip

Occorre ricordarsi che, se si è dietro ad un proxy occorre indicarlo, quindi l’istruzione diventa

wget -e use_proxy=yes -e http_proxy=<proxy>:<porta> http://www.istat.it/storage/cartografia/confini_amministrativi/non_generalizzati/2016/Limiti_2016_WGS84.zip

oppure con il comando curl nel seguente modo

curl -o Limiti_2016_WGS84.zip http://www.istat.it/storage/cartografia/confini_amministrativi/non_generalizzati/2016/Limiti_2016_WGS84.zip

Anche qui occorre ricordarsi che, se si è dietro ad un proxy occorre indicarlo, quindi l’istruzione diventa

curl --proxy <proxy>:<porta> -o Limiti_2016_WGS84.zip http://www.istat.it/storage/cartografia/confini_amministrativi/non_generalizzati/2016/Limiti_2016_WGS84.zip

A livello di struttura dati si mantiene quella standard dell’ISTAT: i campi che interessano principalmente sono:

  • COMUNE: toponimo del Comune
  • PRO_COM: codice ISTAT del Comune

Occorre trasformare i dati da EPSG4326 in EPSG32632 e quindi:

unzip Limiti_2016_WGS84.zip
ogr2ogr -t_srs EPSG:32632 comuni_From_ISTAT_32632.shp Limiti_2016_WGS84/Com2016_WGS84/Com2016_WGS84.shp

E’ quindi possibile eliminare files e directories temporanee:

rm Limiti_2016_WGS84.zip
rm -R Limiti_2016_WGS84

 

PRONTO SOCCORSI
Per i dati dei pronto soccorsi italiani questo dato non esiste in modalità “open”: alcuni dati sono su OSM ma non tutti quelli che servono.

Una fase preliminare delle attività è quindi stata quella di verificare, puntualmente, se sulla base dati OSM fosse presente il dato di interesse relativi ai singoli Pronto Soccorsi e, se non presente, provvedere ad inserire la localizzazione dell’ingresso dei pronto soccorsi.

Sul “come” mappare i Pronti Soccorsi non esiste una univocità di approccio (rif. https://lists.openstreetmap.org/pipermail/talk-it/2017-March/thread.html#57635 e, più recente, https://lists.openstreetmap.org/pipermail/talk-it/2018-July/thread.html#63667)
per cui se si ricontrassero errori o imprecisioni nei miei dati vi prego di segnalarmelo e sarà mia cura correggere eventuali errori.

Per recuperare i dati dei pronto soccorsi italiani è possibile utilizzare una query Overpass Turbo (rif. https://overpass-turbo.eu/), che è la seguente:

[out:json][timeout:250];
{{geocodeArea:Italia}}->.searchArea;
(
node["amenity"="hospital"]["emergency"="yes"](area.searchArea);
);
/out body;
>;
out skel qt;

Per eseguire la query da linea di comando è necessario, sempre da Overpass Turbo (rif. https://overpass-turbo.eu/), esportare la query come Overpass XML.

Si ottiene questo:

<osm-script output="json" output-config="" timeout="250">
<id-query into="searchArea" ref="3600365331" type="area"/>
<union into="_">
<query into="_" type="node">
<has-kv k="amenity" modv="" v="hospital"/>
<has-kv k="emergency" modv="" v="yes"/>
<area-query from="searchArea" into="_" ref=""/>
</query>
</union>
<print e="" from="_" geometry="skeleton" limit="" mode="body" n="" order="id" s="" w=""/>
<recurse from="_" into="_" type="down"/>
<print e="" from="_" geometry="skeleton" limit="" mode="skeleton" n="" order="quadtile" s="" w=""/>
</osm-script>

E’ necessario modificare il formato di output da `json` a `xml` in quanto risulterà più facile la successiva conversione automatica in ESRI shapefile e quindi il file è da trasformare in

<osm-script output="xml" output-config="" timeout="250">
<id-query into="searchArea" ref="3600365331" type="area"/>
<union into="_">
<query into="_" type="node">
<has-kv k="amenity" modv="" v="hospital"/>
<has-kv k="emergency" modv="" v="yes"/>
<area-query from="searchArea" into="_" ref=""/>
</query>
</union>
<print e="" from="_" geometry="skeleton" limit="" mode="body" n="" order="id" s="" w=""/>
<recurse from="_" into="_" type="down"/>
<print e="" from="_" geometry="skeleton" limit="" mode="skeleton" n="" order="quadtile" s="" w=""/>
</osm-script>

L’esecuzione della query da linea di comando è la seguente:

wget --post-file=ps_From_OSM.txt http://overpass-api.de/api/interpreter --output-document=ps_From_OSM.osm

Anche qui occorre ricordarsi che, se si è dietro ad un proxy occorre indicarlo e quindi l’istruzione diventa

wget -e use_proxy=yes -e http_proxy=<proxy>:porta> --post-file=ps_from_OSM.txt http://overpass-api.de/api/interpreter --output-document=ps_From_OSM.osm

A livello di struttura dati si mantiene quella di OSM.

Per convertire il file .osm in ESRI shapefile

ogr2ogr -nlt POINT -skipfailures TMP_DIR ps_From_OSM.osm

Occorre trasformare i dati da EPSG4326 in EPSG32632 e quindi:

ogr2ogr -t_srs EPSG:32632 ps_From_OSM_32632.shp TMP_DIR/points.shp

E’ quindi possibile eliminare files e directories temporanee:

rm ps_From_OSM.osm
rm -R TMP_DIR

A questo punto è possibile caricare i dati in Spatialite: il caricamento avviene manualmente usando Spatialite GUI

Una volta caricati i dati dei pronto soccorsi in Spatialite per calcolare le coordinate X e Y dei Pronto Soccorsi è possibile usare Spatialite nel seguente modo.

ALTER TABLE 'ps_From_OSM_32632' ADD COLUMN X REAL;
ALTER TABLE 'ps_From_OSM_32632' ADD COLUMN Y REAL;
UPDATE 'ps_From_OSM_32632' SET X=ST_X("Geometry") , Y=ST_Y("Geometry");

Per calcolare le coordinate Lat e Lon dei Pronto Soccorsi è possibile usare Spatialite nel seguente modo.

ALTER TABLE 'ps_From_OSM_32632' ADD COLUMN LON double;
ALTER TABLE 'ps_From_OSM_32632' ADD COLUMN LAT double;
UPDATE 'ps_From_OSM_32632' SET LON=ST_X(ST_Transform(geometry,4326));
UPDATE 'ps_From_OSM_32632' SET LAT=ST_Y(ST_Transform(geometry,4326));

 

QUALI PRONTO SOCCORSI PER COMUNE?
Poichè non tutti i comuni italiani hanno all’interno del loro territorio comunale un pronto soccorso è necessario capire come individuare i pronto soccorsi più vicini al comune in esame.

Considerando che:

  • calcolarlo dinamicamente ad ogni richiesta è onerso, anche in termini di tempi di risposta
  • le informazioni relative a comuni italiani e pronto soccorsi non sono informazioni che mutano così dinamicamente

si è deciso di preventivamente di ricavare queste informazioni di “vicinanza”.

Per “vicini” si intende i pronto soccorsi che ricadono “dentro” il comune e anche quelli più “vicini” all’area del comune.

La query spaziale da applicare in Spatialite è stata fornita da Alessandro Furieri sulla lista pubblica di Spatialite (rif. https://groups.google.com/forum/#!topic/spatialite-users/Hnpe_GdA6Pg ).

Ovviamente occorre prima di tutto caricare in Spatialite i layer dei comuni (comuni-From-ISTAT-32632) e dei pronto soccorso (ps-From-OSM-32632) creati in precedenza: questa operazione si può effettuare manualmente usando Spatialite GUI di dev fornita (quando si importano i dati dagli shapefiles ricordarsi di impostare esplicitamente il sistema di riferimento EPSG 32632, quindi indicare “32632” come numero)

Successivamente occorre dare i seguenti comandi:

#### Step 1 ####
CREATE TABLE dist_com_ps_1 AS
SELECT pg.ROWID AS pg_rowid,
pg.COMUNE AS pg_COMUNE,
pt.ROWID AS pt_rowid,
pt.OSM_ID as pt_osm_id,
pt.NAME AS pt_NAME,
pt.X AS pt_X,
pt.Y AS pt_Y,
pt.LON AS pt_LON,
pt.LAT AS pt_LAT,
ST_Distance(pg.geometry, pt.geometry) AS dist
FROM comuni_From_ISTAT_32632 AS pg, ps_From_OSM_32632 AS pt
ORDER BY pg_rowid, dist;

#### Step 2 ####
#### Creazione dell'indice per velocizzare la query ####
create index idx_dist_com_ps_1_pg_COMUNE_dist on dist_com_ps_1(pg_COMUNE, dist);

Esistono potenziali alternative che sono state suggerite per POSTGRESQL, in seguito ad una richiesta su
StackExchange (lista GIS – http://gis.stackexchange.com/questions/229505/the-first-n-points-near-a-polygon-spatialite-or-postgis-query), ma tali possibilità non sono state provate.

 

COME RECUPERARE LE INFO VIA SCRAPING
Per gestire i metadati necessari allo scraping delle pagine web da cui si traggono i dati di numeri e tempi di attesa la struttura della tabella di appoggio è la seguente:

osm_id: id del Pronto Soccorso come in OSM
ps_name: da mettere a mano (al più verificare corrispondenza con OSM ...)
city: da mettere a mano
address: da mettere a mano
tel: da mettere a mano
email: da mettere a mano
url_website: url del sito web dove sell'Ospedale ( Pronto Soccorso)
url_data: url del sito web dove ci sono i dati dei tempi e dei numeri dei pazienti in attesa
specific_function: da usare se serve una funzione specifica di parsing (altrimenti il valore è NO)
data_type: (HTML / JSON)
xpath_numeri_bianco: xpath dell'elemento della pagina HTML che contiene il numero di pazienti in attesa con codice bianco
xpath_tempi_bianco: xpath dell'elemento della pagina HTML che contiene il temp odi attesa per i pazienti in attesa con codice bianco
xpath_numeri_verde: xpath dell'elemento della pagina HTML che contiene il numero di pazienti in attesa con codice verde
xpath_tempi_verde: xpath dell'elemento della pagina HTML che contiene il temp odi attesa per i pazienti in attesa con codice verde
xpath_numeri_giallo: xpath dell'elemento della pagina HTML che contiene il numero di pazienti in attesa con codice giallo
xpath_tempi_giallo: xpath dell'elemento della pagina HTML che contiene il temp odi attesa per i pazienti in attesa con codice giallo
xpath_numeri_rosso: xpath dell'elemento della pagina HTML che contiene il numero di pazienti in attesa con codice rosso
xpath_tempi_rosso: xpath dell'elemento della pagina HTML che contiene il temp odi attesa per i pazienti in attesa con codice rosso

 

RIPORTARE SU MAPPA I PRONTO SOCCORSI
Per la parte di web mapping è necessario avere un layer dei pronto soccorsi da aggiungere sulla mappa.

Si può utilizzare un GeoJSON.

Da Spatialite è possibile creare una tabella che contiene le info che servono con questo comando:

CREATE TABLE ps_layer
AS SELECT
t2.osm_id as osm_id,
t2.ps_name as Nome,
t2.city as Citta,
t2.address as Indirizzo,
t2.url_website as Url,
t1.X as X,
t1.Y as Y,
t1.LON as LON,
t1.LAT as LAT
FROM ps_From_OSM_32632 AS t1, ps_details AS t2
WHERE t1.osm_id = t2.osm_id;

Questa tabella è poi caricabile come layer in QGIS, esportarla come file CSV e reimportarla come nuovo layer usando come coordinate i valori dei campi X e Y (attenzione che le coordinate sono espresse in EPSG:32632).

Infine è possibile salvare il tutto come GeoJSON avendo cura di indicare come sistema di riferimento EPSG:4326

Categorie:Uncategorized

Street Image Compare: how to compare Google Street View and Mapillary in the same web page

7 agosto 2017 6 commenti

If you ask to a crowd of people if they use Google Street View, probably you’ll have a positive answer.

If you ask, to the same crowd of people if they use Mapillary, probably the positive answers will be much less.

Despite the fact Mapillary, with lower means and possibilities, is proposed as a “crowd” alternative to the BigG service, its diffusion is not yet widespread, although there are places on the Earth whose geo referred images are available on Mapillary platform and are not available on Google Street platform.

The question is: is it possible to know, for a specific place, if geo referred images are available in one of these platforms or in both and, in that case, compare them?

I became aware about this problem after seeing an email in an Italian forum on Geographic Free and Open Source software (Gfoss.it); I’ve searched on the web but not successful.

So, starting from the OSM Map Compare idea, I’ve decide to build something by myself and in this way Street Image Compare was created.

The application is very simple to use: for the same place you can compare Google Street View and Mapillary images (if they are both available) and “surf” on the streets having Google Maps and OpenStreetMap as reference.

The user can select the place in three different ways:

  • typing the place name
  • typing an address
  • typing the coordinates couple

The application use Google Maps geocoder as geocoding engine.

When you open the app on the web page with the two maps, Google Street View and Mapillary, you can navigate on the images using the little arrows that are shown on the images: on the maps you’ll see a marker that show your current position.

On the both maps, and using the right buttons, is also possible to click on a specific point where you want to positionate yourself.

It’s quite easy to show the availability of Google Street View images (you can move the pegman on the map and immediately are shown some blue lines that show where the Google Street View images are present or not …) ….

…. for Mapillary is available a button “ON/OFF Mapillary sequences” on OpenStreetMap that draws some blue lines which show where the Mapillary images are present or not.

So, now with Street Image Compare you can compare Google Street View and Mapillary for every place in the world !!!

Here you’re a user session little video

 

On a technical point of view these are the data / services used:

Beyond the mere comparison between two similar services (or, in any case with strong analogies …), that could be a coding exercise the application has some pratical use.

The pictures above are about Amatrice in Italy where last year, on August 24, 2016, there was a great earthquake: in this case you can compare places before and after the earthquake because after this event someone has captured and published the images on Mapillary platform.

You can move along Amatrice streets and the effect in really shocking !!

Starting from this example you can understand as, in case of natural events with big impacts, Mapillary, for its “crowd” nature, can be useful to capture images after the events and with Street Image Compare, you can immediately compare places before and after event. Very useful!

The application code is open source, available on GitHub, with MIT license.

Here you have some examples:

Note: thanks to Mariana Cristina Da Silva for the help on this post! 🙂

Street Image Compare: confrontare Google Street View e Mapillary nella stessa pagina web

6 agosto 2017 4 commenti

Se ad una platea di persone si chiedesse di alzare la mano a chi conosce Google Street View, e lo abbia usato almeno una volta, sicuramente si noterebbero moltissime mani alzate.

Se, alla stessa platea, si chiedesse di alzare la mano a chi conosce Mapillary, e lo abbia usato almeno una volta, le mani alzate sarebbero sicuramente molte di meno.

Nonostante Mapillary si ponga, pur con mezzi e possibilità inferiori, come alternativa “crowd” al servizio di BigG, la sua diffusione non è ancora infatti così ampia e capillare sebbene vi siano
zone della Terra le cui immmagini georiferite risultano essere state catturate e disponibili sulla piattaforma offerta da Mapillary e non su quella offerta da Google Street View.

Ma …… esiste la possibilità di sapere se, per una determinata zona, entrambe le piattaforme, o una sola di loro, dispone di immagini e, nel caso, di poterle confrontare ?

Mi sono posto questa domanda dopo aver visto una mail, sulla lista di GFOSS.it: ho cercato sulla rete e non ho trovato nulla adatto allo scopo (sebbene se la cosa mi paresse strana … ).

Sfruttando l’idea di OSM Map Compare, ho deciso di provare a farlo io e da questa idea è nato Street Image Compare.

L’applicazione dovrebbe piuttosto semplice ed intuitiva: permette di confrontare, per la medesima zona, le immagini (se disponibili …), sia di Google Street View sia di Mapillary e, di navigare i percorsi avendo come riferimenti territoriali sia la mappa di Google Maps sia la mappa di OpenStreetMap.

L’utente può selezionare, a partire da una semplice pagina web, l’area di interesse in tre diverse modalità:

  • scrivendo il nome di una località
  • scrivendo un indirizzo
  • scrivendo una coppia di coordinate

Per la geocodifica è utilizzato il geocoder di Google Maps.

Una volta ottenuta la pagina web con le due mappe, Google Street View e Mapillary, l’utente può navigare le immagini usando le frecce che trova disponibili sulle immagini stesse: sulle mappe saranno riportati i marker che indicano la corrispondente posizione corrente sul territorio.

E’ anche possibile, su entrambe le mappe e con appositi bottoni, cliccare in un punto per posizionarsi direttamente in una zone ben precisa.

Mentre è piuttosto facile individuare la disponibilità su mappa di Google Street View (basta spostare l'”omino” sulla mappa e appaiono delle righe blu che evidenziano dove è presente o meno Google Street View … ), ….

…. per Mapillary è disponibile un apposito bottone “ON/OFF Mapillary sequences” che permette di evidenziare sulla mappa Open Street Map dove Mapillary sia presente o meno.

Quindi ora con Street Image Compare, per ogni posto del mondo, è possibile confrontare Google Street View e Mapillary!!

E’ comunque disponibile un filmato di una sessione si utilizzo

 

Da un punto di vista tecnico i dati e servizi utilizzati sono:

Dalla mail citata in precedenza, che ha dato origine all’idea, e come evidenziato dalle immagini sopra riportate, emerge un utilizzo pratico dello strumento che và al di là del mero confronto tra due servizi analoghi o comunque con forti analogie (che di per sè potrebbe essere un esercizio informatico più o meno interessante ….): sfruttando il fatto che in aree quali quelle colpite dell’evento del terremoto del 24/08/2017 in centro Italia, a ridosso dell’evento, sono state catturate delle immagini con Mapillary, è quindi possibile utilizzare Street Image Compare per un confronto che illustra con “crudezza” la potenza distruttiva dell’evento naturale.

E’ possibile spostarsi lungo le strade e poter vedere le medesime zone prima e dopo l’evento e l’effetto è di sicuro impattante.

Partendo da questo esempio già in essere si comprende come, in caso di eventi naturali che abbiano grossi impatti sul territorio, Mapillary, proprio per la sua natura “crowd”, possa essere utilizzato da attori diversi sia “istituzionali” sia abitanti gli stessi dei luoghi interessati per raccogliere le immagini post evento per poi, con uno strumento come Street Image Compare, avere immediatamente disponibile un confronto delle zone pre e post evento.

Mapillary, tra l’altro, permette anche di poter “filtrare” le immagini per data di rilevamento: questa funzionalità NON è presente nell’attuale versione di Street Image Compare ma, una volta implementata, potrebbe permettere, eseguendo opportune campagne di “rilevamento” di avere un monitoraggio attivo e pubblico dell’evolversi delle attività di ricostruzione.

Il codice dell’applicazione è liberamente disponibile con licenza MIT.

Ecco alcuni riferimenti di interesse:

 

Spaghetti Open Data 2017 … o meglio OpenDataFest – Caltanisetta, 2-4 Giugno 2017 !!

2 aprile 2017 3 commenti

Il quinto raduno di Spaghetti Open Data si terrà a Caltanissetta, 2-4 giugno 2017, in concomitanza con il raduno 2017 di Open Data Sicilia e cambia anche nome, si chiamerà  OpenDataFest !!

Tre giorni per conoscere il mondo dei dati e della conoscenza aperti, incontrare persone che se ne interessano, condividere esperienze e costruire prototipi.

Se hai a cuore il tema dei dati aperti, e se ti senti almeno un po’ civic hacker è il posto giusto per te, chiunque tu sia e qualunque cosa tu sappia o non sappia fare.

E se hai soltanto sentito parlare di Open Data e di dati aperti e ne vuoi capire di più, sei più che benvenuto: anche se vuoi approfondire uno qualsiasi dei temi collegati all’openness.

Per tutti i dettagli questo è il link da monitorare … http://www.spaghettiopendata.org/page/opendatafest-il-raduno-del-2017-benvenuto

Realizzare automaticamente storytelling usando Mapillary? Ci si può provare …

2 ottobre 2016 4 commenti

Mapillary è un servizio per condividere foto georeferenziate sviluppato da una startup, con sede a Malmö, Svezia. I suoi ideatori vogliono rappresentare il mondo intero (non solo le strade) con delle foto. Ritengono che per coprire tutti i posti interessanti nel mondo siano necessari un progetto crowd-sourced indipendente e un approccio sistematico alla copertura di aree interessanti.

Si pongono quindi, fatte le debite proporzioni, in alternativa a Google Street View.

Contribuire è facilissimo: chiunque può scaricare l’app di Mapillary sul proprio smartphone / tablet ed iniziare a scattare foto muovendosi a piedi, in bici o in auto, effettuare poi l’upload sulla piattaforma, e dopo pochissimo tempo rendere disponibile il frutto del proprio “lavoro” al resto della community di Mapillary.

Tempo fa ho usato questo approccio per mappare l’intero mio comune.

Di chi sono le immagini caricate sul sistema e come si possono usare? Le immagini su Mapillary possono essere usate da chiunque secondo la licenza internazionale Creative Commons Attribution-ShareAlike 4.0 (CC-BY-SA).

Un permesso speciale è concesso per derivare dati dalle foto per contribuire ad OpenStreetMap.

Le tracce GPX possono essere usate senza restrizioni.

Sino a non molti mesi fà queste immagini erano consultabili solo attraverso il sito di Mapillary: interessante ma un po’ “chiusa” come possibilità.

A Febbraio 2016 però Mapillary se n’è uscita con Mapillary JS,  che è quanto segue (citando esattamente quanto pubblicato … )

“…MapillaryJS is a tool used for displaying street level photos anywhere on the internet. Today we are putting it into your hands. It enables you to add street level photos to your blog, website or even into your professional mapping applications. …”

E’ quindi ora possibile utilizzare le immagini di Mapillary all’interno di una qualunque applicazione web usando un’interfaccia Javascript che ne facilità la fruizione.

Tra gli esempi forniti con Mapillary JS, ha colpito la mia curiosità quello relativo allo storytelling.

Da qui ho iniziato a pensare se fosse possibile, per produrre il codice della pagina di esempio, automatizzare le scelta delle immagini e delle relative sequenze partendo da un percorso che l’utente poteva disegnare su una mappa.

Il risultato ora c’è ed è … SAMBA !!!  (il nome deriva dall’influenza del periodo olimpico che ha coinciso con lo sviluppo dell’applicativo??? 🙂 ….  comunque l’acronimo stà per Storytelling Author Mapillary BAsed).

samba

L’applicativo permette di scegliere una qualunque area del mondo, per nome o indirizzo, visualizzare su una mappa quelle che sono le tracce delle sequenze di immagini di Mapillary che sono disponibili per quell’area e, sulla base di queste, interattivamente, di impostare quelli che sono i punti di interesse per cui si vuole che il nostro percorso passi (sino ad un massimo di 25 punti …. ).

L’applicativo calcolerà il percorso ed individuerà quelle che sono le immagini di Mapillary più vicine ai punti del percorso stesso (nel verso della percorrenza … ), e proverà a proporre una prima versione dello storytelling di cui l’utente può fare il preview in una sorta di “filmato”.

Se il preview è giudicato soddisfacente l’utente può scaricare il codice sorgente HTML / Javascript per una sua esecuzione autonoma o per poter essere incluso nella pagina web del proprio sito.

Qualora nel preview vi siano immagini non corrette o che generano problemi nell’esecuzione del “filmato” stesso (situazione piuttosto comune …), o qualora l’utente desideri inserire dei piccoli commenti testuali in corrispondenza di alcune delle immagini, è possibile effettuare un raffinamento, deselezionando le immagini da escludere dalla restituzione e/o editando il testo.

Nuovamente sarà possibile effettuare un preview e/o scaricare il codice sorgente HTML / Javascript: il processo di raffinamento può essere eseguito più volte sino ad arrivare alla configurazione di gradimento.

Ogni passo è corredato da un help ed un filmato di esempio di utilizzo.

Riporto qui i filmati per completezza di informazione (nel loro insieme rappresentano una sessione di utilizzo completa).

Step 1

Step 2

Step 3

Step 4

Step 5

I vincoli per l’utilizzo sono i seguenti:

  • utilizzo di un browser di recente generazione e che supporti WebGL: l’applicazione è stata testata su Chrome e Firefox
  • numero massimo punti per il calcolo percorso: 25
  • non si possono usare lettere o caratteri speciali nel testo descrittivo che viene aggiunto all’immagine. Non è possibile usare tag HTML (es. per mettere link)

L’applicazione non è fruibile da smartphone / tablet in quanto risulta comunque difficoltosa l’interazione sulla mappa nel momento in cui si disegnano i punti di interesse o, peggio ancora quando li si desidera riposizionare / trascinare sulla mappa stessa.

Sono comunque fruibili da smartphone / tablet gli storytelling generati.

Esistono problemi noti, che sono:

  • il servizio di routing di MapBox ha un piccolo bug per cui, a volte, non riporta nel percorso l’ultimo punto (destinazione). Ho cercato di aprire una richiesta su StackExchange,  ma ad oggi non ho ancora avuto risposte, nemmeno da MapBox stessa. Il bug non è comunque bloccante anche se fastidioso

Ecco alcuni esempi di storytelling prodotti con SAMBA:

Il codice dell’applicazione e’ disponibile su GitHub con licenza Licenza MIT Copyright (c) [2014].

Ora non vi resta che provare … enjoy!

 

Storytelling Author Mapillary BAsed (SAMBA): come è fatto “dentro”


In questo post vedo di fornire qualche dettaglio su quelle che sono le caratteristiche e soluzioni tecniche che stanno alla base di SAMBA, Storytelling Author Mapillary BAsed.

Schematicamente l’architettura della soluzione è la seguente:

architecture

L’applicazione è una tipica web mapping application realizzata in HTML / Javascript avvalendosi di una componente PHP 5 ospitata su web server Apache.

Per implementare le sue funzionalità utilizza una serie di librerie Javascript e di alcuni servizi e precisamente:

  • mapbox-gl-draw.js: fornisce il supporto per disegnare ed editare features su mappe basate su MapBox GL JS
  • Mapillary API: le API di accesso alle immagini e sequenze di Mapillary
  • MapBox Directions API: le API MapBox per il calcolo dei percorsi
  • MapBox GL Geocoder: il Geocoder per mappe basate su MapBox GL JS
  • Turf.JS: libreria Javascript realizzata da MapBox per il calcolo di funzioni geospaziali direttamente sul browser
  • il servizio (vector tiles), delle sequenze di Mapillary  pubblkicato su http://d25uarhxywzl1j.cloudfront.net/v0.1/{z}/{x}/{y}.mvt

Il codice dell’applicazione e’ disponibile su GitHub con licenza Licenza MIT Copyright (c) [2014].