Giovanni Pirrotta

Just a curious person

Quando Un BOT Può Salvarti La Vita!

Ok, lo confesso, mi sto facendo prendere un pò troppo la mano da Telegram e il suo BOT, ma non è colpa mia se hanno reso così semplice e disarmante creare servizi di valore con la loro chat. :–)

Succede, però, che un lunedì mattina ricevo una email di Andrea Borruso, il quale mi propone, su un’idea di Ciro Spataro, di sviluppare un BOT che consenta ai cittadini palermitani, in caso di emergenza, di essere informati tempestivamente sulla posizione delle aree di accoglienza da raggiungere, predisposte dalla Protezione Civile di Palermo.

Dal sito della protezione civile si legge:

Le aree di accoglienza sono luoghi, individuati in aree sicure rispetto alle diverse tipologie di rischio e poste nelle vicinanze di risorse idriche, elettriche e fognarie, in cui vengono installati i primi insediamenti abitativi per alloggiare la popolazione colpita. Dovranno essere facilmente raggiungibili anche da mezzi di grandi dimensioni per consentirne l’allestimento e la gestione. Rientrano nella definizione di aree di accoglienza o di ricovero anche le strutture ricettive (hotel, residence, camping, etc.).

Negli ultimi quaranta anni, in molte zone d’Italia e specialmente in Sicilia, si sono verificati eventi di dissesto idrogeologico che hanno avuto conseguenze spesso catastrofiche. Senza andare troppo lontano negli anni, lucido è in me il ricordo del violento nubifragio di Messina del 2009, in cui hanno perso la vita 35 persone. Di conseguenza, la possibilità di diffondere informazioni ufficiali e prioritarie da parte delle istituzioni competenti, anche attraverso nuovi media che sfruttino la componente digitale come chiavistello per aprire canali mai raggiunti prima e arrivare, in caso di emergenza, a quanta più gente possibile nel più breve tempo possibile, assume un’importanza sempre più decisiva e strategica per la salvaguardia di vite umane.

In questo contesto, la disponibilità di dati aperti, gratuiti e accessibili riguardanti informazioni strategiche e di raccordo, soprattutto nei settori in cui la tempestività e il veicolo di informazioni giocano un ruolo cruciale, costituisce un elemento determinante e necessario per lo sviluppo di servizi vitali per il cittadino.

Chi sicuramente ha già capito questo è Ciro Spataro che, in veste di civic-hacker, ha mappato le aree di accoglienza persone della Protezione Civile di Palermo usando umap e openstreetmap.

Visualliza schermo intero

Poniamoci adesso questa domanda: come possiamo riutilizzare i dati della mappa in altri contesti e creare servizi di valore e gratuiti per i cittadini palermitani?

Ciro suggerisce di prendere come esempio il lavoro fatto a Prato da Matteo Tempestini, cioè un BOT Telegram in grado di fornire varie informazioni utili per il cittadino, tra cui la possibilità di individuare, in caso di emergenza, l’area di accoglienza più vicina prevista dalla Protezione Civile.

Ho già avuto a che fare sia con progetti legati alla georeferenziazione di posizioni geografiche e alla loro appartenenza rispetto ad un’area geografica (ne parlo in questo post) sia con progetti legati allo sviluppo di BOT su dati relativi ai trasporti urbani (ne parlo in quest’altro post).

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

Dalla mappa mi esporto quindi tutte le aree in formato geoJSON, recuperando le coordinate dei vertici di ogni poligono. Dopodichè l’applicazione mi dovrà restituire l’area che ha il vertice più vicino alla posizione dell’utente.

La logica del programma è molto semplice:

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

In un mio precedente post ho affrontato il problema della distanza di un punto da una lista di punti utilizzando in modo diretto formule trigonometriche e una chiamata SQL.

Questa volta invece utilizzerò la libreria GeoTools, sviluppata da Antoine Corcy. La libreria fornisce molteplici funzionalità legate al mondo della georeferenziazione tra cui geocodifiche dirette e inverse, conversioni tra coordinate, distanze tra punti geografici in metri, chilometri, miglia o piedi, etc.

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

  Telegram
1
2
3
4
5
6
7
    <?php

    $geotools = new \League\Geotools\Geotools();
    $coordA   = new \League\Geotools\Coordinate\Coordinate([48.8234055, 2.3072664]);
    $coordB   = new \League\Geotools\Coordinate\Coordinate([43.296482, 5.36978]);

    $distance = $geotools->distance()->setFrom($coordA)->setTo($coordB);

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

  Algoritmo flat
1
2
    <?php
    $distance->flat(); // 659166.50038742 (meters)

Se volessimo utilizzare invece l’algoritmo great-circle:

  Telegram API
1
2
    <?php
    $distance->greatCircle(); // 659021.90812846

Per avere la distanza in chilometri utilizzando l’algoritmo haversine, l’invocazione sarà la seguente:

  Algoritmo haversine
1
2
    <?php
    $distance->in('km')->haversine(); // 659.02190812846

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

  Algoritmo vincenty
1
2
    <?php
    $distance->in('mi')->vincenty(); // 409.05330679648

Per maggiori informazioni consultate la documentazione ufficiale della libreria.

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

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

  Metodo “distance”
1
2
3
4
5
6
7
8
9
    <?php
    public function distance(Vertex $from, Vertex $to)
    {
        $coordFrom = new Coordinate([$from->getLatitude(), $from->getLongitude()]);
        $coordTo = new Coordinate([$to->getLatitude(), $to->getLongitude()]);
        $distanceCalculator = $this->geotools->distance()->setFrom($coordFrom)->setTo($coordTo);

        return $distanceCalculator->in('km')->haversine();
    }

In input vengono presi due oggetti del dominio di classe Vertex. Il codice è autoesplicativo.

Per confrontare le distanze di tutte le aree di accoglienza partiamo dall’oggetto Map che, dopo aver caricato in memoria la struttura dati del file GeoJSON, contenente le coordinate geografiche delle aree di accoglienza della protezione civile di Palermo, calcola la distanza minima all’interno del metodo getNearestArea. Il metodo prende in input la posizione dell’utente e restituisce in output l’area di accoglienza più vicina.

  Metodo “getNearestArea”
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?php
    public function getNearestArea(Vertex $vertex)
    {
        $areaNearest = null;
        $distanceNearest = PHP_INT_MAX;
        foreach($this->aree as $areaAccoglienza) {
            $areaAccoglienza->calculateVertexNearest($vertex);
            $v = $areaAccoglienza->getVertexNearest();
            if ($v->getDistance() < $distanceNearest) {
                $distanceNearest = $v->getDistance();
                $areaNearest = $areaAccoglienza;
            }
        }

        return $areaNearest;
    }

Per calcolare il tempo necessario per raggiungere l’area di accoglienza a piedi (feature consigliata da Andrea) ho usato l’API distancematrix messa a disposizione da Google.

  API distancematrix
1
https://maps.googleapis.com/maps/api/distancematrix/json?origins=LATITUDINE-ORIGINE,LONGITUDINE-ORIGINEs&destinations=LATITUDINE-DESTINAZIONE,LONGITUDINE-DESTINAZIONE&mode=walking&language=it-IT"

L’output della chiamata restituisce informazioni relative alla distanza del viaggio e al tempo necessario per, partendo dal primo punto, raggiungere il secondo punto a piedi.

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

  API percorso viaggio
1
http://maps.google.com/maps?f=d&hl=en&saddr=LATITUDINE-ORIGINE,LONGITUDINE-ORIGINE&daddr=LATITUDINE-DESTINAZIONE,LONGITUDINE-DESTINAZIONE&ie=UTF8&0&om=0&output=kml

Mettiamo tutto in funzione e vediamo cosa apparirà su Telegram.

Il BOT da cercare si chiama @protezioneCivilePAbot

La prima cosa da fare è inviare la propria posizione cliccando sulla graffetta.

A questo punto il BOT risponderà nel seguente modo:

informando l’utente su quale area di accoglienza raggiungere, visualizzandola su mappa, su come raggiungerla e su quanto tempo ci vorrà a piedi per raggiungerla.

Il codice della demo, lo trovate nel mio repository si github.

Il progetto è scalabile per ogni città, basta avere un file GeoJSON, prodotto con Umap o con qualsiasi altro tool, con le aree di accoglienza della Protezione Civile.

Un ringraziamento particolare per il progetto va a Ciro Spataro, da cui è nata l’idea e ad Andrea Borruso, per i suoi preziosi feedback e consigli.

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

Twittami

That’s all folks! Stay tuned!

Comments