Sei sulla pagina 1di 82

I

Università IUAV di Venezia


---
FACOLTA’ DI PIANIFICAZIONE DEL
U
TERRITORIO
---
A
 
---
Corso di Laurea in
V
SISTEMI INFORMATIVI TERRITORIALI

PROGETTAZIONE E
REALIZZAZIONE PROTOTIPALE
DI UN SISTEMA PER LA GESTIONE
DEGLI EVENTI DI TRAFFICO

Laureando:
Andrea Maschio

Relatore:
Chiar. mo Prof. Massimo Rumor

Anno Accademico (2006/2007)

andrea.maschio@gmail.com
andrea.maschio@gmail.com
PROGETTAZIONE E
REALIZZAZIONE PROTOTIPALE
DI UN SISTEMA PER LA GESTIONE
DEGLI EVENTI DI TRAFFICO

andrea.maschio@gmail.com
2
Ringraziamenti:

Ad Alvise e Silvia, senza i quali nulla di tutto ciò sarebbe stato possibile.
A Nicola, che ha tentato di dare un rigore scientifico a questo progetto.
A Grazia e Giacomo, senza i quali LiTRoMS girerebbe solo a Kanagawa.
Ad Andrea e Justin che mi hanno fatto scoprire il supporto della comunità di
Geoserver.
Ai miei cari amici, che in questi tre anni hanno sopportato le mie assenze.
A chi non perde le speranze nei sogni.

3
4
 Indice 

Premessa 7

Descrizione del problema, stato attuale e requisiti 11

Situazione attuale degli strumenti informativi del traffico 11

Navigatori e traffico 15

Requisiti 15

Use cases 16

Perché un sistema web 17

Progetto di massima 19

Scelta del software 19

Dati 20

Ajax (Asynchronous Javascript And Xml) 22

La “Same Origin Policy” 24

Il design pattern 24

GeoDBMS 25

SRID e EPSG 27

Application server 28

Lo strato di presentazione 30

uDig (User friendly Desktop Internet GIS) 30

Sviluppo del prototipo 33

Creazione dell’ambiente di test 33

Postgis e pgrouting 33

Predisposizione del grafo 34

Algoritmi di routing 38

5
Visualizzare i dati del percorso in uDig 38

Comunicazione asincrona con Geoserver 41

Due variabili in più: il livello di traffico e i lavori in corso sulla tratta 41

Ricalcolo con algoritmi di routing ottimizzati in funzione del traffico 44

Progettazione prototipale dell’interfaccia del software LiTRoMS 48

Richiedere il percorso più breve da A a B 51

Lo strato di presentazione dell’applicazione e gli strumenti di interazione con l’utente 53

Selezionare una tratta 55

La gestione degli eventi di traffico 58

Progettazione interfaccia 58

Una variabile in più: il kilometro all’interno del quale si verifica l’evento 62

Impostare il livello di traffico e di disservizio 64

Individuare il kilometro di un determinato punto 66

Conclusioni 71

Risultati 71

Sviluppi futuri 71

Problematiche riscontrate 72

Bibliografia 74

Siti Web 75

Note 79

6
Premessa
La comunità Open Source, che ha avuto le sue origini dal progetto GNU datato 1983
e dalla Free Software Foundation fondata da Richard Stallman nel 1985, è nata con
l’intento di eliminare le restrizioni sulla copia, sulla distribuzione e l’estensione del
software. Apparentemente questa politica, questo obiettivo, sono idealisti. Si legano
spesso al concetto opposto a quello commerciale e certamente per molti aspetti non
condividono di questo aspetto la gran parte dei paradigmi.
Progettare e scrivere un software Open Source può sembrare semplice. Non è
diverso dal progettare e scrivere un software proprietario. Come per qualsiasi buon
software, è richiesto un lavoro di analisi funzionale e tecnica, per capire come mettere
d’accordo le esigenze del committente (anche se il committente e il software writer
sono la stessa persona), e le difficoltà e i vincoli tecnici ai quali è necessario
sottostare.
Più difficile è portare avanti lo sviluppo di un buon software. Molti hanno scritto un
software che potesse coprire l’esigenza del momento, la commissione del momento,
il lavoro o il progetto del momento. Quando però si tratta di portare avanti il lavoro è
difficile, se non si ha la motivazione data dalla necessità del software, creare una
condizione di sviluppo continuo in cui il software si evolve e diventa qualcosa di più di
una semplice ‘risoluzione di una necessità temporanea’. Ancora più difficile, è
scrivere un software che utilizza prodotti Open Source. La difficoltà di reperire
documentazione in alcuni casi, la mancanza di un referente a cui rivolgersi per
ottenere informazioni su un prodotto, l’assenza di informazioni su come fare
interagire tra di loro diversi prodotti Open Source, rende talvolta arduo il progettare e
sviluppare un’applicazione che si basa su questi prodotti.
Tuttavia la cosa più degna di nota del software Open Source, è che è in evoluzione.
Rispetta tutti i dettami dell’evoluzionismo Darwiniano, scartando le idee più deboli, le
righe di codice ‘sbagliate’ o meno efficienti. Questo è reso possibile dal susseguirsi di
miglioramenti apportati da persone in momenti successivi, dall’aggiornamento
continuo sulla base delle nuove tecnologie disponibili.

7
Al software proprietario (che dal punto di vista dell’utilizzatore presenta diversi
vantaggi, ad esempio il supporto della casa produttrice del software quando
disponibile), tutto questo risulta semplicemente impossibile. I tempi stretti di sviluppo,
il sottostare a esigenze di marketing e ancora le esigenze di produttività delle aziende
produttrici, spesso producono codice poco affidabile e in casi estremi ancora più
costoso per le aziende in termini di danni causati dal suo uso.
Ecco che vediamo uscire patch, service pack, continui rilasci di correzioni che
introducono altri bugs e mettono a repentaglio talvolta la stessa stabilità del sistema
operativo sul quale viene eseguito il software.
Certo, il software Open Source ha tanti difetti, ma l’intenzione qui non è di aprire un
confronto tra le due modalità di sviluppo del software. Si vuole mettere un accento su
questa caratteristica ‘viva’ del software Open Source, sul fatto che il software Open è
destinato a sopravvivere, proprio per la sua natura di software condiviso.
Sempre più spesso le grandi compagnie rilasciano il loro software sotto licenza GPL
o similari (si veda ad esempio il progetto Eclipse rilasciato da IBM, o la stessa virtual
machine di Java rilasciata recentemente alla comunità Open Source da Sun. E’
difficile capire se è una questione di immagine o la volontà di mantenere la
ricchissima comunità Open Source vicino ai propri prodotti, resta il fatto che quel
software continuerà a crescere, e diverrà sempre migliore grazie alla stessa
comunità.

Nel preparare questo progetto ho avuto modo di interagire con varie comunità Open
Source, tra le quali prevalentemente la comunità di sviluppo di Geoserver, quella di
Openlayers, e quella di Postgis. Dire che mi hanno aiutato sarebbe limitante, e non
renderebbe onore alla grandissima disponibilità offerta. Attraverso la mailing list e i
canali IRC su freenode programmatori a tempo pieno ma anche persone che
lavorano e sviluppano per la comunità nel tempo libero, mi hanno aiutato a
conoscere il ‘loro’ software, mi hanno evidenziato i bug, e in cambio mi hanno
chiesto implicitamente di contribuire alla scoperta di nuovi bugs, alla condivisione
con la mailing list delle soluzioni trovate, alla richiesta di nuove features.

8
Credo che questo sia ciò che rende la comunità del software Open Source così
lungimirante e destinata al successo a lunga scadenza. Credo che sia per questo
che il sistema operativo Linux non solo non ha ceduto alla pressione della Microsoft
e alla sua guerra pubblicitaria dei primi anni di questo secolo nella quale cercava di
dimostrare che il software Open costava più dei suoi prodotti; ma addirittura ha
conquistato fette di mercato sempre più grandi in particolare con la distribuzione
Ubuntu, che finalmente è riuscita a conquistare anche le case dopo l’utenza
enterprise.

E’ per questo che lo stesso Firefox, nato dalle ceneri di Mozilla e ancora prima di
Netscape è arrivato a piazzarsi al 37.2 % nelle classifiche di uso del browser nel
mese di gennaio 2008 guadagnando i 4 punti persi da Internet Explorer 6 e 7 e
arrivando a un piazzamento impensabile nel 2002 quando Netscape 3 4 e 5
totalizzavano 8 punti mentre il browser Microsoft era all’85% (dati forniti dal consorzio
w3c).
Un risultato importante per tutto il software Open Source, perché ha convinto
l’opinione pubblica che il software per essere ‘buono’ non deve essere per forza
prodotto dalla Microsoft o dalla Norton; l’utente comune ha capito che il software
Open Source non cerca di ingannare, perché il codice sorgente è lì, a disposizione di
chiunque voglia capire cosa e soprattutto come lo fa.

Mi auguro che, nel suo piccolo, questo progetto possa contribuire se non alla
diffusione di buon software, almeno alla diffusione di questa idea.

9
10
Descrizione del problema, stato a5uale e requisi8
Situazione a5uale degli strumen8 informa8vi del traffico
Per analizzare lo stato dell’arte dei sistemi informativi per il traffico in Italia, sono stati
studiati e comparati tra loro alcuni esempi di implementazioni software di largo
consumo, facilmente reperibili in rete:
1. www.quattroruote.it
2. www.autostrade.it
3. http://traffico.kataweb.it

Lo scopo dell’analisi è stato quello di individuare peculiarità positive ed eventuali limiti


dei software in esame per poter definire nel migliore dei modi le caratteristiche del
prototipo in oggetto.

Qua5roruote
Il sito presenta una lista di tratte in cui è possibile visualizzare la situazione del traffico

1. Il traffico secondo Quattroruote

Nella vista di dettaglio si possono vedere informazioni specifiche legate alle condizioni
del singolo tratto stradale. L’informazione non è georeferenziata se non parzialmente,

11
e non c’è una visione su mappa. Ogni singolo disservizio viene trattato come
un’informazione testuale e non geografica.

2. Dettaglio delle tratte

Sito autostrade
Il sito delle autostrade presenta una mappa che offre una visualizzazione del traffico
basata su telecamere piazzate lungo il corso dell’autostrada. Come si può notare, la
visualizzazione è efficace, in quanto da l’idea della quantità di traffico, ma certamente
non consente una valutazione quantitativa né in termini di tempo né in termini di
percorsi alternativi.

12
3. Il traffico secondo il sito autostrade.it

Attraverso una legenda più specifica è possibile ottenere informazioni di dettaglio


nonché collegarsi alla visualizzazione tramite camere localizzate nelle zone di maggior
traffico.

4. Dettaglio sulla telecamera

13
Kataweb
Questo sito non si discosta di molto dai precedenti per quanto riguarda la
visualizzazione:
 

5. Il traffico secondo Kataweb

Si possono notare a fondo pagina le informazioni di dettaglio o gli eventi particolari


riportati in calce, ma fuori dalla mappa.
 
Quanto emerge relativamente a questa breve analisi è che la situazione del traffico è
solo parzialmente gestita in modo geografico. Quello che manca in ogni caso, è la
possibilità di ricercare il percorso più breve anche in funzione della situazione di

14
traffico. Lo scopo primario di questo studio è infatti quello di analizzarne la fattibilità e
la progettazione.

 Navigatori e traffico
E’ opportuno ricordare che questa funzionalità è già esistente in alcuni navigatori
commerciali. Le implementazioni di riferimento sono due, tra i grandi produttori di
software per la navigazione: TOM TOM e Route 66.
 
Entrambi i navigatori hanno l’opzione per il calcolo del percorso più breve e del
percorso più rapido che tiene conto anche delle velocità medie percorribili in ogni
singolo tratto come funzionalità core (comune a tutti i navigatori).
 
Essi però offrono anche un servizio aggiuntivo, il primo a pagamento e il secondo
gratuitamente (fatta salvo la tariffa telefonica per il collegamento GPRS necessario)
che offre informazioni sulla presenza di blocchi dovuti a traffico, incidenti, lavori.

Requisi8
I requisiti alla base dell’applicazione della quale si vuole sviluppare il prototipo sono i
seguenti:
1. Software Open Source. L’intera applicazione deve basarsi su prodotti per i quali la
licenza consenta di utilizzare, modificare e redistribuire il software o componenti
dello stesso.
2. Multipiattaforma e multibrowser. L’applicazione deve poter funzionare su più
piattaforme e su un ragionevole set di moderni browser. Come riferimento si
prenderanno Mozilla 1.0+, Firefox 1.0+, Microsoft Internet Explorer 6+, Opera 7+,
Safari 2+.
3. Portabilità del software. Con portabilità si intende l’indipendenza non solo dalla
piattaforma hardware ma dal sistema operativo che la controlla.
4. Funzionalità di base. Sono state definite due tipologie di utenti per le quali sono di
seguito elencate le funzionalità messe a disposizione dall’applicazione:

15
Use cases
Nei diagrammi delle figure 5 e 6, sono illustrati i principali use cases (casi d’uso)
dell’applicazione.
a. Utente amministratore:
• Visualizzazione della mappa e del tematismo legato al traffico e navigabilità della
stessa;
• Selezione di una o più tratte e impostazione del relativo livello di traffico.
• Selezione di una o più tratte e impostazione del relativo livello di disservizio
• Impostazione di un blocco per disservizio a un determinato kilometro di una strada
di percorrenza principale
Gestione dei dati di traffico

(Si logga
all'applicazione)

Visualizza la
mappa

Admin
Seleziona
una tratta

Imposta un
livello di
traffico

6. Use case lato amministratore

b. Utente fruitore:
• Visualizzazione della mappa e del tematismo legato al traffico e navigabilità della
stessa;
• Selezione di due punti di partenza e arrivo sulla mappa;
• Calcolo del percorso più breve;
• Calcolo del percorso più veloce in base alla situazione del traffico.

16
Utente visualizza i dati di traffico e ricerca un percorso alternativo

Visualizza la
mappa

Seleziona
un punto di
partenza
Utente
Seleziona
un punto di
arrivo

Chiede il calcolo
del percorso
ottimizzato

7. Use case lato fruitore

La componente legata all’autenticazione degli utenti e la personalizzazione dei profili,


sarà lasciata ad un eventuale secondo momento dello sviluppo.

Pertanto l’autenticazione sarà solo simulata, essa non fa pertanto parte dei requisiti
di funzionamento del prototipo.

Perché un sistema web
Un’applicazione come quella che si vuole progettare deve avere tra i requisiti
preliminari il fatto di essere portabile. Il grande vantaggio delle architetture web, oltre
alla scalabilità e al fatto di essere multipiattaforma, è quello di non richiedere
l’installazione di software sul client sul quale l’applicazione è in esecuzione.
 
Lo spostamento del carico di calcolo sulla componente server inoltre, se da un lato
comporta l’esigenza di un hardware prestante, implica lo sgravio del carico di calcolo
dal client. Quest’ultimo deve solo fornire l’interfaccia per le scelte operate dall’utente,
organizzando sostanzialmente solo i dati che servono per l’elaborazione in maniera
gradevole e semplice.
 
La web application, la cui implementazione ha assunto varie diciture tra le quali “Web
2.0”, risulta particolarmente efficiente nonostante l’alto contenuto di interazione

17
richiesto all’utente; tale software può essere eseguito su tutti i browser che oramai
rappresentano lo standard “de facto” per le applicazioni business.

18
Proge5o di massima

Scelta del soFware
La scelta del software è maturata da una precedente dissertazione sulle possibilità
offerte dai prodotti Open Source per un’applicazione web di tipo GIS, ed è il risultato
di un’ analisi tecnica che considera da un lato il miglior software disponibile, dall’altro
un’adeguata forma di licensing e supporto documentale.

I prodotti scelti per lo sviluppo dell’applicazione web LiTRoMS (Light Traffic Routing
Management System) sono:

1. PostgreSQL, il DBRMS Open Source rilasciato con licenza GPL che rappresenta
l’alternativa low cost a soluzioni enterprise basate su Oracle
2. Postgis, l’estensione di Postgres sviluppata dalla Refractions Research che non
solo rappresenta strutture tabellari spaziali ma anche gestisce relazioni
topologiche e spaziali tra i loro elementi.
3. Pgrouting, estensione di Postgis che implementa gli algoritmi di routing
4. PGadmin come strumento di amministrazione del database.
5. Geoserver, server Open Source che interconnette le features contenute nel
database, dandone una rappresentazione geospaziale visibile attraverso un
browser.
6. Tomcat, application server JEE che permette il deploy dell’applicativo LiTRoMS e
l’interazione LiTRoMS-Geoserver.
7. Openlayers, un framework interamente scritto in javascript che consente lo
sviluppo dello strato di presentazione di LiTRoMS secondo lo standard MVC.

Tutte le componenti sopra descritte, con le rispettive interazioni, sono rappresentate


in figura 7. Il front end utente è rappresentato da OpenLayers. Le richieste effettuate
attraverso l’interfaccia vengono trasmesse (1 e 2) a Postgis. Queste richieste talvolta
vengono trasmesse a Pgrouting (3) che restituisce i dati calcolati (3). LiTRoMS chiede
a OpenLayers il ricaricamento delle features (4) il quale trasmette la richiesta a

19
Geoserver (5). Geoserver chiede e ottiene le features (6 e 7) e le trasmette a
Openlayers (8). Un’ulteriore interazione è quella tra LiTRoMS e Postgres (9) per
quanto riguarda i dati funzionali all’applicazione, e tra uDig e Postgis (11) e Pgadmin
e Postgres/Postgis(10) in fase di sviluppo dell’applicazione.

Tomcat
8
OpenLayers Geoserver
5

1 4

LiTRoMS

2
9

Postgis 7

10 Pgadmin
Postgres

3 Pgrouting

11 uDig

8. Diagramma che illustra le interazioni tra le componenti dellʼapplicazione

Da8
La base di dati di questo applicativo è stata progettata utilizzando il database
Postgres, che rappresenta uno standard per le applicazioni enterprise Open Source.
 
Postgres fu sviluppato inizialmente dal Prof. Michael Stonebreaker come successore di Ingres, da
cui il nome che sta per “Dopo Ingres”. Fu sviluppato ulteriormente da laureandi di Stonebreaker
per diventare successivamente un prodotto open source nel 1996 con il nome di Postgres95. Oggi
PostgreSQL è un prodotto molto maturo, a cui hanno contribuito anche aziende del calibro di
Fujitsu, e continua a crescere in nuove features e performances. La versione 8 usata nella presente

20
applicazione supporta molte delle caratteristiche enterprise presenti ad esempio in Oracle, come i
Tablespaces, la possibilità di lanciare stored procedures da Java e le transazioni annidate.
 
La componente spaziale di Postgres, chiamata Postgis, e costituita da una serie di
librerie e di script SQL di creazione delle funzioni principali, è stata implementata
recentemente da Refractions Research e rilasciata con licenza GPL. L’azienda
canadese è ideatrice e principale realizzatrice anche di uDig (User friendly Desktop
Internet Gis) che si è rivelato prezioso in una fase iniziale del progetto in quanto ha
reso possibile la visualizzazione dei primi risultati per valutarne la consistenza.

La GNU General Public License è una licenza per software libero. Il testo ufficiale della licenza è
disponibile all'URL http://www.gnu.org/licenses/gpl.html, mentre all'URL http://
www.softwarelibero.it/gnudoc/gpl.it.txt è disponibile la traduzione non ufficiale in italiano.
 
La componente legata al routing, ossia al calcolo del percorso più rapido di
percorrenza di un grafo, è basata sull’algoritmo A* (Alpha star) ed è svolta
direttamente all’interno del DBRMS mediante stored procedures scritte in linguaggio
plpgsql e linguaggio C.
View Risultati
Ottimizzato View Risultati Shortest
Georeferenziati Georeferenziati Legenda
(resultsgeo_retepd_tra (resultsgeo_traffic)
ffic) Tabella

View

Calcolo

Risultati Ottimizzato Grafo principale Risultati Shortest


(results_traffic_retepd) (padova) (results_retepd)

Alterazione grafo
Livelli Traffico Traffico in base a dati di Disservizi Livelli disservizio
(trafficlevels) (retepd_traffic) traffico e (disruptions) (dirsuptionslevels)
disservizio

View Padova alterata


da livello di traffico e
disservizio
(v_rete_pd_traffic)

9. Diagramma che illustra il modello dei dati

21
Il modello dei dati per l’alimentazione delle features di geoserver è rappresentato in
figura 8. Le frecce indicano l’alimentazione delle view da parte delle tabelle. La tabella
padova contiene il grafo principale. Le tabelle contenenti i risultati alimentano le view
dei risultati georeferenziati insieme alla loro join (unione) con il grafo principale. Si
otterrà così un set di tratte selezionato, la cui struttura è del tutto uguale a quella
della tabella padova. Il grafo principale alimenta anche la vista del grafo distorta da
un calcolo che ne altererà la metrica preservandone gli aspetti topologici, come si
vedrà successivamente in dettaglio.

Ajax (Asynchronous Javascript And Xml)
Negli ultimi anni si è reso disponibile un nuovo pattern architetturale nelle
comunicazioni delle applicazioni web. La comunicazione web è svolta tipicamente
attraverso una serie di richieste definite in base al protocollo HTTP (attualmente alla
versione 1.1) e di risposte del server al client che effettua le richieste. La connessione
tra le due entità è finalizzata allo scambio delle informazioni, e viene chiusa quando è
terminata la transazione. Pertanto il flusso è tipicamente quello di un client (spesso un
browser) che chiede una risorsa attraverso una richiesta GET o POST e di un server
che risponde alla richiesta inviando un buffer corrispondente alla risorsa richiesta.
Poichè il buffer contiene spesso dei tag html che a loro volta indicano la necessità di
ulteriori risorse (immagini, script o fogli di stile), il client effettua una nuova richiesta
per ottenere la risorsa specificata, e così via fino a che la risorsa originaria e tutte le
risorse richieste da questa sono state scaricate in locale e possono essere
interpretate e formattate nel browser, o eseguite nello scripting runtime del browser
nel caso degli script.

Con l’introduzione da parte della Microsoft dell’oggetto XMLHttpRequest in Internet


Explorer 5, e nelle successive implementazioni nel browser Microsoft e in quelli della
famiglia Mozilla, si è creato un nuovo pattern di comunicazione tra client e server.

In dettaglio, questa è l’architettura di quella che è stata definita come la versione 2


del web:

22
10. Lʼarchitettura Ajax confrontata con il modello tradizionale

La grossa differenza con il sistema web tradizionale, è che lo scambio di dati riguarda
solo i dati essenziali e non l’insieme di files e di pagine che costituiscono l’interfaccia
utente. Generalmente questi dati vengono incorporati in strutture quali XML (da cui il
nome Asynchronous Javascript and Xml) o JSON (Javascript Object Notation) che
consentono essenzialmente di recuperare le informazioni sotto forma di stringa di
testo per trasformarle in oggetti di pronto utilizzo all’interno dell’ambiente di
esecuzione del browser. Una stringa JSON, contenente dati strutturati, può essere
trasformata in un oggetto del DOM del browser, che lo scripting runtime può leggere
e modificare. I vantaggi sono notevoli, soprattutto nel caso di interfacce molto ricche
e scambi di dati ridotti a poche informazioni, poichè limita la quantità di dati scambiati
tra il client e il server e può ad esempio consentire una validazione server o la
richiesta di liste di dati senza che il browser sia costretto a richiedere l’intera pagina
corredata di risorse non utili alla transazione in oggetto.
 
Questo generalmente comporta di contro la scrittura di un layer intermedio che
gestisca le chiamate effettuate dal client Ajax (tipicamente un oggetto DTHML
chiamato xmlHttpRequest).

23
La “Same Origin Policy”
La possibilità da parte dello scripting runtime di poter comunicare in maniera
indipendente con internet ha datro origine a delle problematiche di sicurezza non
indifferenti. La possibilità che codice ‘maligno’ possa effettuare chiamate a risorse
esterne all’insaputa dell’utente, detta ‘Cross scripting’, è stata pertanto limitata.

Tipicamente e con rare eccezioni costituite da alcune versioni del browser Microsoft
Internet Explorer, queste chiamate http possono essere eseguite sottostando ad
alcune regole fondamentali rivolte più alla sicurezza delle applicazioni che non alla
loro semplicità di sviluppo. Una di queste è la cosiddetta “SameOrigin Policy” che
consente al browser di effetturare chiamate http sincrone e asincrone tramite
javascript solamente verso il server da cui si è scaricata la pagina html contenente lo
script che desidera effettuare la connessione. Questo significa che non potrò in
nessun modo collegarmi direttamente al server B per ottenere un servizio web
tramite XmlHttpRequest dal server A. Per ottenere lo stesso effetto, sarò costretto a
utilizzare il server A (il mio server) come un server proxy, che riceve le richieste http
javascript, le processa effettuando le chiamate al servizio B di riferimento e restituisce
al client il risultato delle elaborazioni come se avesse effettuato esso stesso le
operazioni.
 
Come vedremo, questo creerà delle difficoltà nel momento in cui si vorrà interagire
con i dati direttamente dal browser in maniera visuale. Questa limitazione infatti
spinge fortemente verso la creazione di un unico server nel quale sono deployati tutti
i layers applicativi che forniscono servizi al prototipo.

Il design pa5ern
In generale, nello sviluppo di software, è assolutamente consigliabile seguire quelle
che sono le best practices di disegno architetturale e i design pattern più comuni ed
utilizzati, per l’evidente motivo che essi sono collaudati e rodati. L’obiettivo
architetturale di questo prototipo è di mantenere il più possibile la presentazione
separata dallo strato dei dati, in particolare modo per consentire l’eventuale sviluppo

24
dello stesso prototipo cambiando in maniera modulare i componenti dello stesso. In
questo particolare caso di sviluppo, il modello dei dati è rappresentato più da funzioni
di interazione con essi che non con l’interazione con i loro modelli. Si è tuttavia
cercato di rispettare per quanto possibile il pattern MVC soprattutto nell’ottica di
poter rendere intercambiabili in uno sviluppo futuro i componenti del software. E’
chiaro che in questo prototipo si è data la precedenza alle caratteristiche salienti dal
punto di vista geografico e agli obiettivi primari dell’applicazione, pertanto la
separazione tra i livelli è stata spesso simulata più che propriamente implementata.
Tuttavia si sono sfruttate le potenzialità di java e in generale della programmazione ad
oggetti per incapsulare oggetti in maniera modulare in modo da consentire un
eventuale sviluppo futuro. Di conseguenza la separazione tra il modello dati e la view
è effettuato da alcune servlet coadiuvate da alcune classi java, come vedremo in
seguito.

GeoDBMS
Nel prototipo, l’accesso ai dati servirà per consentire la memorizzazione di
informazioni spaziali, la memorizzazione di informazioni testuali, e il calcolo del
percorso attraverso funzioni di routing. Il GeoDBMS scelto per rappresentare il
modello dei dati è il relativamente recente ma già affermato Postgis, basato su
Postgres.
 
Un GeoDBMS, oltre alle caratteristiche comuni ai database tradizionali, ha la
possibilità di gestire informazioni con un grado di complessità più elevato. Le
informazioni bidimensionali o tridimensionali (che oltre alle posizioni inglobano nel loro
complesso anche informazioni ad esempio sul sistema di riferimento in uso, ossia del
DATUM cui le coordinate si riferiscono), sono memorizzate in campi detti
‘geospaziali’ che incapsulano al loro interno la complessità dell’informazione.
 
PostGis gestisce i dati spaziali memorizzando in una colonna di una tabella spaziale
(una tabella che contiene dati spaziali e geometrici) le coordinate e il sistema di
riferimento dell’oggetto memorizzato. Così, ad esempio, eseguendo la funzione

25
asText(field) sul campo the_geom della tabella padova, si ottiene una riga simile alla
seguente:

routing=# select asText(the_geom) from padova limit 1;


astext
------------------------------------------------------------------
MULTILINESTRING((1723355.75000933 5034276.00000291,1723375.37500135
5034263.4999709))
(1 row)

11. Come sono organizzati i dati spaziali in un GeoDBMS

Postgis gestisce i campi spaziali, oltre che con l’informazione spaziale vera e propria,
con la memorizzazione di un informazione sul sistema di riferimento in uso nella
tabella geometry_columns di sistema attraverso le varie funzioni a supporto della
memorizzazione di informazioni geografiche. Ad esempio, per aggiungere un campo
spaziale a una tabella di punti, si potrà operare in questo modo:

26
postgis=# select AddGeometryColumn('punti','geometry_id',-1,'POINT',

2);

addgeometrycolumn

----------------------------------------------------

public.punti.geometry_id SRID:-1 TYPE:POINT DIMS:2

In questo modo si sarà creato un punto nella tabella punti con sistema di riferimento
(SRID) -1, ossia nessuno.
 
I dati di partenza dell’applicazione sviluppata sono stati forniti nel sistema di
riferimento, ossia Gauss-Boaga fuso Ovest. Questo comporta che le coordinate
sono riferite a una falsa origine, ma come vedremo di questo si occuperà
l’application server, effettuando una proiezione sul sistema di riferimento di
destinazione.
I dati forniti sono stati recuperati in formato Shape (il formato ‘ufficiale’ di molte
cartografie, tra cui quella della regione Veneto).
 
Poiché si è scelto di lavorare con formati aperti e pertanto si è scelto il relativamente
giovane PostGis per lavorare con i dati spaziali, la prima esigenza che si è trovato
necessario affrontare è stata l’importazione dei dati in in tabelle spaziali. A questo
scopo è venuto in aiuto un tool fornito con l’installazione di postgis, shp2pgsql.
Con una semplice istruzione, il programma converte il file shape (che deve essere
copiato in una cartella insieme al file di indice .shx e al file di dati .dbf) in una tabella e
inserisce nella tabella geometry_columns le informazioni appropriate sul SRID di
riferimento.

SRID e EPSG
L' European Petroleum Survey Group o EPSG (1986 – 2005) era un'organizzazione
scientifica legata alla ricerca e all'esplorazione sul petrolio. EPSG compilò e diffuse
l'EPSG Geodetic Parameter Set, una base dati di ellissoidi terrestri, Datum, sistemi di
coordinate, proiezioni e unità di misura. Il ruolo dell'EPSG  fu superato nel 2005 dal
più recente OGP (Comitato per la Supervisione e il Posizionamento).

27
Il set di parametri geodetici  continua a essere noto come  EPSG Geodetic
Parameter Data Set ed è accessibile attraverso un'interfaccia web e pubblicato da
OGP.
Ognuno di questi set di informazioni relativi a un diverso sistema di riferimento è
memorizzato in una riga della tabella spatial_ref_sys di postgis, la quale viene creata
dagli script di Postgis in fase di installazione.

routing=# select * from spatial_ref_sys where srid=3003;


srid | auth_name | auth_srid | srtext | proj4text
-----+--------------+-----------+-------+---------------------
3003 | EPSG | 3003 | PROJCS["Monte Mario / Italy zone
1",GEOGCS["Monte Mario",DATUM["Monte_Mario", SPHEROID["International
1924",
6378388,297,AUTHORITY["EPSG","7022"]],AUTHORITY["EPSG","6265"]],PRIMEM
["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",
0.01745329251994328,AUTHORITY["EPSG","9122"]],AUTHORITY["EPSG","4265"]
],PROJECTION["Transverse_Mercator"],PARAMETER["latitude_of_origin",
0],PARAMETER["central_meridian",9],PARAMETER["scale_factor",
0.9996],PARAMETER["false_easting",1500000],PARAMETER["false_northing",
0],UNIT["metre",1,AUTHORITY["EPSG","9001"]],AUTHORITY["EPSG","3003"]]
| +proj=tmerc +lat_0=0 +lon_0=9 +k=0.999600 +x_0=1500000 +y_0=0
+ellps=intl +units=m +no_defs
(1 row)

Come si può notare la stringa in cui viene dichiarato il sistema di riferimento contiene
molte utili informazioni per la libreria che dovrà occuparsi di effettuare la proiezione
delle coordinate tra i vari sistemi di riferimento dell’applicazione. In questo caso le
librerie coninvolte sono le librerie Proj 4 all’interno dell’Application server.

Applica8on server
L’application server scelto per lo sviluppo del prototipo è Geoserver. Giunto alla
versione 1.6 o quasi all’atto della redazione della presente tesi (in effetti la versione in
uso è la 1.6 Release Candidate 3), Geoserver è un application server completamente
sviluppato in java utilizzando il framework JEE.

28
 
Geoserver è molto importante all’interno del consorzio OGC perché è preso come
implementazione di riferimento delle specifiche WFS (Web feature services) e WMS
(Web mapping services).
 
Esso è in grado di fornire quindi su base vettoriale (o raster) mappe georeferenziate a
partire da varie sorgenti dati (tra cui shape e postgis).
 
Geoserver è un’implementazione piuttosto fedele alle specifiche di WMS e WFS,
pertanto non offre la possibilità di condizionare i risultati all’elaborazione o ad un
calcolo per cui è previsto il protocollo WPS (Web Processing Service). Geoserver può
quindi alimentare le proprie FeatureType (insieme di features ossia nel GIS di
“elementi minimi dotati di un contenuto informativo”) attraverso la configurazione di
uno o più DataStores che rappresentano le sorgenti dei dati e possono essere file
shape o GeoDBMS di vario tipo.

12. Lʼediting di un Feature type in geoserver

In questo caso Geoserver viene eseguito come un war (web application archive)
deployato nell’application server Tomcat (in fase di sviluppo lanciato dall’ambiente di
sviluppo integrato Eclipse Europa) prevalentemente per avere un unico server con

29
due web applications e poter consentire l’interazione client-server senza incappare
nelle criticità indotte dalla policy della “Same Origin”.

Lo strato di presentazione
Lo strato di presentazione dell’applicazione è gestito dalle due principali views
dell’applicazione, ossia due jsp (Java Server Pages) che presentano rispettivamente
la possibilità di ‘amministrare’ la console e di usarla simulando un utente che deve
spostarsi nell’area interessata e ha la possibilità di cercare un percorso ottimizzato in
funzione del traffico e delle interruzioni programmate. Una buona parte del lavoro di
interazione con i dati è stato svolto pertanto in codice interpretato ed eseguito nel
browser come script “javascript”. Questo comporta, come si è potuto osservare, una
limitata gamma di browser supportati, tra i quali si annoverano comunque Internet
Explorer 6+ e Firefox 1.5+ nonché Safari 3+, che rappresentano la grande
maggioranza dei browser in circolazione.

Lo strato di visualizzazione delle mappe è costituito da un framework javascript,


OpenLayers. Esso si incarica di gestire l’interazione con le mappe fornite
dall’application server. In questo caso è attraverso questo componente che sarà
possibile fare una richiesta di tipo WFS o WMS e trasformare il risultato in una mappa
visualizzabile all’interno del browser. Rispetto all’utilizzo di un’applet o di un activex,
questo framework rende estremamente portabile l’applicazione, poiché richiede
solamente un browser con l’accesso a Internet (solo per la visualizzazione del layer
base il quale è servito da Google Maps.

uDig (User friendly Desktop Internet GIS)
Questo utilissimo software desktop si è rivelato davvero indispensabile in una fase
iniziale del lavoro in cui non conoscendo i componenti in gioco risulta difficile anche
solo visualizzare i dati a disposizione. E’ sviluppato dalla Refractions Research (la
canadese ‘madre’ di Postgis) come una Rich Client Platform basata su Eclipse.
 

30
Il software uDig è in grado di visualizzare una mappa fornita in modalità WMS o WFS
da un application server, oppure di visualizzare direttamente i dati memorizzati in vari
formati, tra i quali shape, Postgis, Oracle.

31
32
Sviluppo del proto8po
Creazione dell’ambiente di test
Per cominciare lo sviluppo del prototipo, si è reso necessario creare un ambiente che
consentisse l’esplorazione delle problematiche di carattere software ed
eventualmente hardware.

In un primo momento la problematica maggiore è stato il reperimento dei dati


necessari allo sviluppo dell’applicazione che avessero i seguenti requisiti:
 
1.  I dati dovevano essere in qualche modo portabili in Postgis (il database relazionale
Open Source era uno dei requisiti primari)
2. I dati dovevano costituire essenzialmente una cartografia percorribile, quindi con
gli attributi topologici corretti.
 
In un primo momento avendo avuto una certa difficoltà nel recupero dei dati con
queste caratteristiche si è presa in considerazione l’applicazione di esempio fornita
dall’estensione PGrouting che senza dubbio aveva tutte le caratteristiche necessarie.
 
I dati forniti con l’applicazione di esempio (della quale si sono presi solamente i file
shape) contiene un grafo già predisposto con i campi richiesti dall’algoritmo di
routing.

Postgis e pgrou8ng
Non ritenendo importante specificare in dettaglio le operazioni necessarie
all’installazione di Postgres e di Postgis, va comunque ricordato per sommi capi il
percorso necessario all’installazione del database in ambiente Apple OS X 10.5.2
Leopard.

William Kyngesburye nel suo sito http://www.kyngchaos.com/wiki/software:postgres mette a


disposizione i porting di tutti i pacchetti necessari a questa applicazione per chi desideri
predisporla in ambiente Os X. Eseguendo gli installer di Postgres, Postgis e delle librerie esterne

33
richieste come GDal e PROJ4 (Kyngesburye ha messo a disposizione addirittura un unico installer
per tutte le librerie esterne) nonché di PGrouting che sono scaricabili all’indirizzo sopra riportato
l’ambiente può essere predisposto in maniera relativamente semplice. Si vedano i rispettivi file di
licenza per quanto riguarda la possibilità di redistribuzione del software.

Dopo aver lanciato l’installazione di PGrouting, è stato necessario eseguire le


istruzioni SQL contenute nei file allegati alla distribuzione.

Per importare i dati recuperati in un secondo momento con la cartografia del comune
di Padova si sono svolte le seguenti operazioni:
 
1.    Creazione del database
2.    Importazione dei dati a partire da file shape in postgis
3.    Predisposizione dei dati per la percorribilità (grafo)
 
Vediamoli in dettaglio. Il database è stato creato con le seguenti istruzioni (eseguite
da terminale):
createdb -U postgres -E routing
createlang -U postgres plpgsql routing

Successivamente gli script di creazione delle funzioni di Postgis:


psql -U postgres -f postgis-1.2.1/lwpostgis.sql routing
psql -U postgres -f postgis-1.2.1/spatial_ref_sys.sql routing

E quelli di creazione delle funzioni di routing:


psql -U postgres -f routing_core.sql routing
psql -U postgres -f routing_wrappers.sql routing

Predisposizione  del grafo
I dati di Padova sono stati forniti in formato shape. Il comando utilizzato per importarli
è il seguente:
 

34
SuppaBookPro:retepd superandrew$ shp2pgsql -I -s 3003 retepd.shp

padova > padova.sql

Shapefile type: Arc

Postgis type: MULTILINESTRING[2]

 
Il tool shp2pgsql deve essere informato (con l’opzione –s) riguardo il sistema di
riferimento dei dati importati (in questo caso la cartografia è in Gauss-Boaga fuso
Ovest). L’opzione  -I invece crea un indice  di tipo GIST (Generalized Search Tree)
sulla tabella creata.
Ecco i dati:

13.  I dati ottenuti della tabella Padova

A questo punto i dati devono essere trasformati in qualcosa che gli algoritmi di
routing possono capire. Per ovvie ragioni gli algoritmi di routing implementati in
Postgis non possono sapere quali sono i campi che determinano le geometrie e i
rispettivi valori per determinare la lunghezza dei rami, ad esempio per poter calcolare
il loro costo in termini di percorribilità.
 

35
Di conseguenza, seguendo le specifiche riportate nella documentazione di Pgrouting
si è provveduto alla preparazione del grafo ‘percorribile’ nel modo seguente:

/* Aggiunta dei 4 campi x1,x2,y1,y2 */


ALTER TABLE padova ADD COLUMN x1 double precision;
ALTER TABLE padova ADD COLUMN y1 double precision;
ALTER TABLE padova ADD COLUMN x2 double precision;
ALTER TABLE padova ADD COLUMN y2 double precision;

/* Impostazione del valore dei campi in base alle coordinate dei due
nodi del ramo */
UPDATE padova SET x1 = x(startpoint(the_geom));
UPDATE padova SET y1 = y(startpoint(the_geom));
UPDATE padova SET x2 = x(endpoint(the_geom));
UPDATE padova SET y2 = y(endpoint(the_geom));

/* Aggiunta dei campi source e target che costituiranno il punto di


partenza e di arrivo dell’algoritmo */

ALTER TABLE padova ADD COLUMN source integer;


ALTER TABLE padova ADD COLUMN target integer;
ALTER TABLE padova ADD COLUMN length double precision;

/* Creazione della topologia di rete (questa istruzione serve per


l’algoritmo Dijkstra, che non è stato usato)*/
SELECT assign_vertex_id('padova', 0.1, 'the_geom', 'gid');
UPDATE padova SET length = length(the_geom);

/* Creazione degli indici GIST */


CREATE INDEX padova_source_idx ON padova(source);
CREATE INDEX padova_target_idx ON padova(target);
CREATE INDEX padova_geom_idx ON padova USING GIST(the_geom
GIST_GEOMETRY_OPS);

36
Un semplice metodo di verifica che tutto sia stato eseguito correttamente è quello di chiamare la
funzione di calcolo del percorso più breve “A*” passando un source e un target qualsiasi della tabella
importata ‘padova’:

routing=#SELECT * FROM shortest_path_astar('


SELECT gid as id,
source::integer,
target::integer,
length::double precision as cost,
x1, y1, x2, y2
FROM padova',
238, 1455, false, false);

Risultato:
routing=#
vertex_id | edge_id | cost
-----------+---------+------------------
238 | 3780 | 238.50773647297
3261 | 3785 | 210.849832324886
1493 | 3787 | 108.033161085457
3993 | 4130 | 59.9270694650945
4194 | 4131 | 61.611013803887
4346 | 6408 | 76.6270246976172
1513 | 6409 | 69.8270123457657
4192 | 4037 | 38.4084299014576
4277 | 4041 | 23.7226846720035
4281 | 4057 | 87.0225184292831
2710 | 3872 | 197.492441859573
4022 | 3646 | 20.4771262818944
4021 | 3652 | 113.808318383449
4027 | 3660 | 69.9506504358752
4036 | 3665 | 39.9002527459174
4040 | 6424 | 17.1927841774245
1454 | 842 | 65.857513091373
1455 | -1 | 0
(18 rows)

37
Come si può vedere, l’algoritmo elenca una serie di rami, nell’ordine in cui devono
essere percorsi, e il relativo costo.

Algoritmi di rou8ng
La scelta tra gli algoritmi disponibili per il calcolo del percorso più breve è piuttosto
ampia, considerato che il percorso più breve è necessariamente uno e uno soltanto,
pertanto quello che cambia è essenzialmente l’efficienza dell’algoritmo stesso.
L’algoritmo Dijkstra viene spesso utilizzato anche nel calcolo del percorso meno
costoso in un circuito elettrico. L’algoritmo A* (A star) tiene conto euristicamente
anche della distanza approssimativa del target, è quindi preferibile probabilmente in
un contesto geografico, e particolarmente con grandi datasets. L’algoritmo Shooting
Star tiene conto anche del senso di guida, e potrebbe certamente essere più
importante in una fase di implementazione reale dell’applicazione.

Da prove effettuate sulla applicazione di esempio contenente un grande dataset con i


dati della città giapponese Kanagawa, le prestazioni migliori sembrano essere quelle
dell’algoritmo A*, che alla fine è stato scelto come algoritmo di riferimento per
l’applicazione.

Esula dallo scopo del prototipo la valutazione dell’efficienza di un algoritmo di calcolo


rispetto ad un altro, ma è sembrato più logico sfruttare quello che sembrava dare
risultati migliori in termini di performance, e anche per il suo metodo euristico che
sembra appropriato in un contesto geografico.

Visualizzare i da8 del percorso in uDig
Come primo milestone del progetto, l’obiettivo è quello di ottenere il percorso più
breve tra due rami del grafo (ovvero tra due nodi): ci si preoccuperà in un secondo
momento di poterlo visualizzare all’interno del browser, e di applicare tutti gli ulteriori
calcoli necessari all’esclusione o penalizzazione di determinate tratte a seconda della
loro situazione di traffico o di blocco per lavori.
 

38
Eseguendo la query specificata tra due rami a caso, è senza dubbio possibile
immaginare quello che sta succedendo: infatti i dati restituiti rappresentano a loro
volta il ramo (edge_id), il nodo (vertex_id) e il costo della percorrenza della tratta.
Tuttavia la possibilità di poterli visualizzare in maniera grafica costituisce a questo
punto un importante punto intermedio per poter valutare che quanto svolto sinora sia
corretto dal punto di vista topologico e anche dal punto di vista dell’efficacia del
calcolo effettuato dall’algoritmo nella determinazione del percorso più breve.
 
A questo punto sorge un problema che si porrà anche in una fase successiva: il
bisogno di rendere persistenti i risultati dell’elaborazione in modo che sia possibile
visualizzarli come un dataset, nel caso di uDig, come un layer WFS o WMS nel caso
di geoserver. Udig da una parte, e i due protocolli dell’OGC infatti non consentono di
basare i dataset che alimentano le features sull’output di funzioni, procedure o query
SQL ma solo di legarli a views e tabelle.
 
L’idea è quindi di basare la visualizzazione in udig su una view. Si metteranno
pertanto in join i risultati (salvati in una tabella) con la tabella dei dati geografici,
ottenendo il set dei rami risultanti, insieme alle loro informazioni geografiche.
 
Creiamo quindi la tabella results_retepd, che conterrà i risultati dell’elaborazione
dell’algoritmo di calcolo del percorso più breve:

CREATE TABLE public.results_retepd (


vertex_id int4 NOT NULL,
edge_id int4 NULL,
cost float8 NULL,
sessionid varchar(100) NOT NULL,
PRIMARY KEY(vertex_id,sessionid)
)
CREATE INDEX ix_vertex_id_retepd_traffic
ON public.results_retepd(vertex_id)
CREATE INDEX ix_vertex_id_retepd
ON public.results_retepd(vertex_id)

39
Alla tabella creata è stato aggiunto un campo sessionid di tipo testuale per la possibilità di poter
selezionare i risultati delle elaborazioni in base all’utente che le ha generate attraverso un filtro
WMS (che vedremo in seguito).

CREATE OR REPLACE VIEW public.resultsgeo_retepd


AS
SELECT k.gid, k.length, k.x1, k.y1, k.x2, k.y2, k.source, k.target,
k.the_geom, r.sessionid FROM padova k, results_retepd r WHERE
(r.edge_id = k.gid);

A questo punto, eseguendo


--delete from results_retepd ;
INSERT into results_retepd
select * FROM shortest_path_astar
('SELECT gid AS id, source::int4, target::int4, length::double
precision AS cost, length::double precision AS
reverse_cost,x1,x2,y1,y2 FROM a_getpadova(true)',p_start, p_end,
false, false);

Ci troveremo nella situazione di poter finalmente visualizzare il layer in uDig previa


creazione di una nuova mappa e aggiunta del layer direttamente come un dataset da
postgis attraverso un wizard:

14. Il percorso più breve dal nodo A al nodo B visualizzato mediante uDig

40
Comunicazione asincrona con Geoserver
Raggiunto il primo obiettivo, si registra un dato di fatto: la comunicazione all’interno
dell’applicazione dovrà essere svolta in maniera prevalentemente asincrona per la
caratteristica stessa dei dataset geografici supportati da udig e come si vedrà anche
da geoserver di non poter essere frutto dell’elaborazione di una funzione o di una
procedura ma solo del binding a una tabella o a una view.

Questa non è un’affermazione assoluta, sicuramente ci sono modi diversi per


interagire con un application server di tipo geografico come Geoserver che
supportino un’interattività diversa. Ad esempio, il portocollo WFS-T (dove la T sta per
transational) che è supportato da geoserver, consente di bloccare alcune features
una volta aperte in modifica da un client, e consentono di effettuare modifiche che
poi possono essere salvate nella base dati. Tuttavia questo non è sufficiente per
l’applicazione, in quanto la necessità qui non è di modificare i dati ma di avere un
layer che deriva dall’elaborazione di una richiesta a cui sono stati passati dei
parametri. Questo protocollo esiste, si chiama WPS, ma non è supportato da
geoserver allo stato attuale, anche se è in via di sviluppo e probabilmente sarà
implementato nella versione 2. Si userà pertanto un particolare modello di dialogo
asincrono che consisterà nell’aggiornamento di dati e nel successivo caricamento
della features dei dati modificati in un momento immediatamente successivo.
 

Due variabili in più: il livello di traffico e i lavori in corso sulla tra5a
Si è visto come fornire all’algoritmo A*  gli elementi utili al calcolo del percorso più
breve, ma uno degli obiettivi del presente prototipo è quello di fornire un elemento in
più all’algoritmo per renderlo capace di evitare tratte che sono penalizzate per la
presenza di traffico o di un blocco che impedisce di fatto l’attraversamento della
tratta.
 
Il grafo a disposizione non può essere alterato in maniera topologica, ma le
trasformazioni dovute al traffico possono essere viste come deformazioni che non
modificano la topologia ma agiscono modificando virtualmente la metrica. Per

41
virtualmente si intende che immaginando una velocità di percorrenza costante, la

lunghezza apparente
la tot  è :

€ la tot = t tot v tot = ∑ k t j kw j la j


j=1

Dove
t tot  è il tempo totale, v tot  la velocità totale, kw j  è il coefficiente dovuto alla

€ kt j
presenza di lavori nella j-esima tratta, è il coefficiente dovuto alla presenza di
la j
traffico nella j-esima tratta e  la lunghezza
€ effettiva, reale, della singola tratta.
€ €

Poichè la lunghezza apparente delle tratte è il prodotto della loro lunghezza reale per

un coefficiente positivo, che ne rappresenta il costo, l’effettivo tempo di percorrenza,
immaginando una velocità costante, cresce in maniera lineare.
Sottoponendo all’algoritmo A* un grafo con differenti coefficienti di costo, si farà in
modo di preservare la topologia ma di alterare la metrica ai fini della valutazione delle
tratte più convenienti.

kw j kt j
Ai due coefficienti  e  sono attribuiti dei valori convenzionali che simulano il
reale impatto sul tempo di percorrenza della tratta e quindi della sua lunghezza

la j
apparente .
€ €
kw j kt j
I valori di  e :


Valore kw Descrizione
€ €
1 Scorrevole

1000000 Lavori in corso
15.  Impostazione dei livelli di disservizio

42
Valore kt Descrizione

1 Scorrevole

2 Poco trafficato

5 Mediamente trafficato

10 Abbastanza trafficato

20 Molto trafficato

1000000 Viabilità bloccata

16. Impostazioni dei valori di traffico

È chiaro che la scelta di applicare un valore estremamente alto in caso di blocco del
traffico o per lavori è una scelta dovuta al mezzo: infatti è una convenzione per
indicare un tempo infinito di percorrenza (o una distanza apparente infinita) su una
tratta che costringerà l’algoritmo ad evitarla a causa del costo troppo elevato. Questo
è dovuto alla scelta di immagazzinare questi valori in un database. Tuttavia un valore
fino a 20 può rappresentare in effetti un coefficiente reale di attraversamento di una
via in base alla condizione di traffico. Immaginando infatti di percorrere un certo tratto
in un minuto se le sue condizioni di traffico sono scorrevoli, è perfettamente
verosimile che se ne possano impiegare 20 per percorrerlo se il traffico è elevato.

Postgres supporta i numeri interi fino a 9223372036854775807. In particolare il formato bigint


supporta valori da -9223372036854775808 a 9223372036854775807. I tipi float4 e float 8 tuttavia
supportano 3 valori speciali: +infinity, -infinity e NaN.

Si è ritenuto suffficiente e corretto applicare il valore arbitrario di 1000000 poichè tale


cifra moltiplicata per la distanza genera una distanza apparente che l'algoritmo A*
deve necessariamente escludere, pur non essendo la distanza apparente realmente
infinita. Probabilmente anche un valore molto più piccolo sarebbe stato sufficiente,
ma il fine tuning dei coefficienti esula dallo scopo del prototipo in fase di
progettazione e sviluppo.

43
Ricalcolo con algoritmi di rou8ng o]mizza8 in funzione del traffico
Si sono create due tabelle atte a contenere la codifica e i valori dei livelli di disservizio
e di traffico,
--codifica dei livelli di disservizio
CREATE TABLE public.disruptionlevels (
id int4 NOT NULL,
DisruptionLevDescr text NULL,
PRIMARY KEY(id));

--codifica dei livelli di traffico


CREATE TABLE public.trafficlevels (
id int4 NOT NULL,
TrafficoLevDescr text NULL,
PRIMARY KEY(id));

e due tabelle che contengono i livelli di disservizio e di traffico per ramo

--rami con livello di traffico e chiave esterna su padova


CREATE TABLE public.retepd_traffic (
retepd_gid int4 NULL,
trafficoliv_id int4 NULL,
id int4 NOT NULL,
PRIMARY KEY(id)
)
GO
ALTER TABLE public.retepd_traffic
ADD CONSTRAINT ek_traffic_padova_gid
FOREIGN KEY(retepd_gid)
REFERENCES public.padova(gid);

-rami con livello di disservizio e chiave esterna su padova


CREATE TABLE public.disruptions (
disruption_id numeric NOT NULL,
gid int4 NULL,
data_da date NULL,
data_a date NULL,

44
note text NULL,
disruption_liv_id int4 NULL,
PRIMARY KEY(disruption_id)
);

ALTER TABLE public.disruptions


ADD CONSTRAINT gid_padova
FOREIGN KEY(gid)
REFERENCES public.padova(gid);

A questo punto dovremo fare in modo di presentare la tabella padova, data in input
alla funzione shortest_path_astar, come una tabella identica a padova per quanto
riguarda le geometrie, ma con un campo calcolato che tiene conto dei coefficienti di
lavori in corso e in assenza di questi (sono mutuamente esclusivi per scelta
architetturale) del livello di traffico. E’ chiaro che un livello 1 di lavori in corso e di
traffico genera una lunghezza apparente esattamente identica alla lunghezza
topologica del ramo.
 
Si creano allo scopo i seguenti oggetti: la view v_retepd_traffic
 
CREATE OR REPLACE VIEW public.v_retepd_traffic
AS

SELECT
--tutti i campi di padova
k.the_geom, k.gid, k.source, k.target, k.length, k.x1, k.y1, k.x2,
k.y2,
--il coefficiente di traffico se non è nullo altrimenti 1
CASE WHEN (t.trafficoliv_id IS NOT NULL) THEN t.trafficoliv_id
ELSE 1 END AS trafficoliv_id,
--se il livello di disservizio non è nullo allora 1000000
CASE WHEN (d.disruption_liv_id IS NOT NULL) THEN (1000000)::double
precision

--altrimenti se è nullo ma il livello di traffico non è nullo allora


il coefficiente di traffico moltiplicato per la lunghezza

45
WHEN ((d.disruption_liv_id IS NULL) AND (t.trafficoliv_id IS NOT
NULL)) THEN
(k.length * ((t.trafficoliv_id)::numeric)::double precision) ELSE
k.length END AS traffic_length

FROM ((padova k LEFT JOIN retepd_traffic t ON ((k.gid =


t.retepd_gid)))
LEFT JOIN v_disruptions_now d ON ((d.gid = k.gid)));

Dopo aver impostato in maniera casuale una serie di nodi con il valore di traffico
desiderato o con livello di disservizio diverso da 1, è possibile osservare
immediatamente in uDig come la funzione di calcolo del percorso più breve in
funzione del grafo ‘apparente’ che carichiamo con un tematismo in uDig metta in
evidenza il livello di ‘impraticabilità’ delle tratte.

17.  Il percorso ottenuto in verde evita le zone maggiormente trafficate

Come si può notare, la serie di tratte evidenziate con colore verde, ‘evita’ le zone
colorate di rosso più intenso, ma ‘accetta’ di percorrere alcune tratte trafficate ma
non così costose da percorrere quanto il costo necessario ad evitarle.

46
Ora che abbiamo ottenuto le funzionalità core dal punto di vista del calcolo del
percorso ottimale, è opportuno creare delle funzioni che possano incapsulare la
logica dell’applicazione ed accentrare il codice necessario allo svolgimento delle
operazioni comuni.

La funzione di calcolo del percorso, oltre ai nodi di partenza e fine, sarà


parametrizzata aggiuntivamente con le seguenti variabili (introdotte in un secondo
momento della progettazione):

1. Evita la Zona a Traffico Limitato


2. Percorri solo la viabilità principale
3. Id della sessione (utile per poter differenziare i risultati in base all’utente)

Si sono create pertanto allo scopo le due funzioni a_calculateshortestpath_retepd e


a_calculateshortestpath_retepd_traffic che differiscono essenzialmente perché la
prima trae la sua sorgente dati dalla tabella del grafo originario mentre la seconda
effettua il calcolo basandosi sulla view creata in precedenza che alterando il grafo
propone all’algoritmo la lunghezza apparente.

Le caratteristiche salienti della funzione a_calculateshortestpath_retepd_traffic:


CREATE OR REPLACE FUNCTION

public.a_calculateshortestpath_retepd_traffic

( in startpoint int4,

in endpoint int4,

in avoid_ztl bool,

in main_routing bool,

in session_id text)

RETURNS SETOF

resultsgeo_retepd_traffic AS

--restituisce un set di dati equivalente a un subset della


vista resultsgeo_rete_pd_traffic

47
[...]

--svuoto il set dei risultati precedenti (per sessionid)


delete from results_traffic_retepd where sessionid = session_id ;

--inserisco nella tabella dei risultati l’output della funzione


INSERT into results_traffic_retepd

select a.*, session_id as sessionid FROM shortest_path_astar

('SELECT gid AS id, source::int4, target::int4, traffic_length::double

precision AS cost, traffic_length::double precision AS

reverse_cost,x1,x2,y1,y2 FROM a_getpadova_traffic('||

avoidztl_str||','||main_routing_str||')',p_start, p_end, false, false)

a; --a_getpadova è una funzione che mi restituisce un set di dati in

base ai parametri passati

[...]

--sebbene come vedremo la funzione verrà utilizzata in modo


asincrono, restituisco il set di risultati ottenuto come un cursore
per consentire ulteriori sviluppi in contesti WPS
for ret_row in select * from resultsgeo_retepd_traffic loop

return next ret_row;

end loop;

return;

Proge5azione proto8pale dell’interfaccia del soFware LiTRoMS
L'interfaccia utente lato pubblico è stata progettata secondo queste linee guida:
deve essere il più semplice possibil e adattarsi anche a risoluzioni basse. Inoltre verrà
costruita non basandosi su tabelle, ma su selettori CSS, in modo da avere la
possibilità di scorporarne la grafica e renderne più semplice la modifica. In figura 4 si
illustra l’aspetto e l’usabilità dell’interfaccia utente.
L’utente può selezionare la via cliccando sulla mappa per selezionare il punto di
partenza e di arrivo, o alternativamente inserendo i relativi nomi delle vie. Il prototipo
dell’interfaccia viene riportato in figura:

48
Ricerca
Mappa principale

Da via

A via

Evita ZTL Solo


viabilità
principale

Partenza
da

Arrivo a Messaggi

Comandi

reset Calcola percorso

Notizie sul traffico

• Etichetta Etichetta
Blocco in via rinaldi C
Incidente in via savelli notizie sul
Campo di testo
Viabilità bloccata per lavori in via Campo di testo

18. Prototipo interfaccia lato utente

Ecco come si presenta l’interfaccia utente di LiTRoMS per ottenere il percorso


ottimizzato all’interno del browser Safari 3:

49
19. Lʼinterfaccia utente di LiTRoMS

50
Deployment dell’applicazione web: la logica
Lo step successivo è quello di portare in web la visualizzazione e la selezione dei dati
ottenuti su richiesta dell’utente.

Dopo aver installato la versione 1.6 RC3 di geoserver mediante un archivio di tipo
war (web application archive), viene sviluppato l’applicativo LiTRoMS all’interno di
Tomcat Application Server. L’applicazione si serve di OpenLayers per la
visualizzazione delle mappe e per la comunicazione con Geoserver, e di alcune
procedure di controllo e di logica scritte in linguaggio Java (Java Servlet) per la
comunicazione con la base dati Postgres.
Un’immagine georeferenziata ottenuta attraverso le API (Application Program
Interfaces) fornite dalla SDK (Software Development Kit) di Google Maps,
contestualizza la mappa nell’area di interesse.

La classe Java che comunica a Postgis i parametri del percorso richiesto è


ShortestPath. Il metodo doPost( ) fa solo da dispatcher e chiama il metodo
appropriato del connettore PostgresConnector( ); quest’ultimo a sua volta chiama la
funzione e notifica al chiamante l’eventuale errore nel recupero di nodi attraverso la
classe VertexNotFoundException( ), in modo da notificare all’utente che ha scelto un
tipo di calcolo non congruente con il nodo selezionato (ad esempio ha scelto di
partire da “via Roma” evitando la ZTL, cosa evidentemente non possibile essendo la
via compresa nella zona a traffico limitato).

In aggiunta le classi ListProvider( ) e AjaxProvider( ) svolgono funzioni di utilità come


la popolazione degli elenchi dei possibili valori di traffico o disservizio presenti nella
modalità amministrativa del software.

Richiedere il percorso più breve da A a B
Il percorso che l’utente può calcolare è sempre il percorso più breve dal punto A al
punto B. Tuttavia, se il percorso calcolato sulle distanze reali tra A e B è in effetti
quello più breve da un punto di vista metrico, viene definito un percorso ottimizzato

51
come un percorso che viene considerato di percorrenza più conveniente sul grafo
alterato dai pesi dei coefficienti di traffico o di disservizio.
L’utente ha la possibilità di cliccare direttamente nella mappa per individuare le vie di
interesse, nel qual caso vengono inserite due puntine di colore verde e rosso per
segnalare rispettivamente il punto di partenza e di arrivo; contemporaneamente nella
sezione ricerca una guida all’utente segnala qual è il prossimo step da eseguire.
E’ inoltre possibile vedere i livelli di traffico evidenziati da un gradiente di rosso.

20. I livelli di traffico sono evidenziati dal livello crescente di rosso

Cliccando su “Calcola percorso”, l’utente può visualizzare il percorso più breve in


verde e in azzurro il percorso ottimizzato. Si può notare come entrambi i percorsi
evitino la Zona a Traffico limitato


21. Calcolo del percorso con esclusione delle tratte ZTL

52
Infatti, deselezionando l’opzione ‘Evita ZTL’ il percorso calcolato è leggermente
differente.

22. Calcolo del percorso con inclusione delle tratte ZTL

Lo  strato  di  presentazione  dell’applicazione  e  gli  strumen8  di  interazione 


con l’utente
Volendo analizzare il funzionamento del caricamento delle features è sufficiente
guardare il codice sorgente della pagina CalcoloPercorsoOttimizzato.jsp.
I layers di OpenLayers vengono caricati con una sintassi simile alla seguente:
var high_traffic = new OpenLayers.Layer.WMS(
"Situazione Traffico",
"/geoserver/wms",
{
width: '800',

layers: 'topp:v_retepd_traffic_high',
height: '585',
format: 'image/png',
transparent:true //è un overlay trasparente
}
);
Alla pressione del tasto “Calcola percorso” partono due chiamate asincrone alla
stessa servlet effettuate dalla funzione “calculate”
function calculate(p_start, p_end){

var avoid_ztl=false;
var main_routing = false;

avoid_ztl = $('avoid_ztl').checked;
main_routing = $('main_routing').checked;

53
new Ajax.Request("ShortestPath?
map=retepd&requestedpath=traffic&startPoint="+p_start+"&endPoint="+p_end
+"&avoid_ztl="+avoid_ztl+"&main_routing="+main_routing, {asynchronous:true,
evalScripts:true, onSuccess: function(transport){write("(ajax):<BR>" +
transport.responseText)}});

new Ajax.Request("ShortestPath?
map=retepd&requestedpath=normal&startPoint="+p_start+"&endPoint="+p_end+
"&avoid_ztl="+avoid_ztl+"&main_routing="+main_routing, {asynchronous:true,
evalScripts:true, onSuccess: function(transport){write("(ajax):<BR>" +
transport.responseText)}});


Viene chiesto alla pagina di chiamare dopo due secondi la funzione
‘reloadShortestPath()’
window.setTimeout('reloadShortestPath()',2000);

la quale attraverso il metodo redraw ricarica le features dei due layers del percorso
più breve e del percorso ottimizzato.
routing.redraw();
shortest_path.redraw();

Come si è visto in precedenza, la servlet richiede al connettore di chiamare le funzioni


a_calculateshortestpath_retepd e a_calculateshortestpath_retepd_traffic, le quali
insericono le tratte richieste in una tabella che è la sorgente dati delle features ,
l’insieme delle quali rappresenta il percorso dell’utente corrente e che
successivamente vengono ricaricate da Geoserver. Si noti che la richiesta del layer
del percorso più breve, così come quella del percorso ottimizzato, contengono un
parametro ‘filter’ all’interno del quale viene indicata la stringa che costituisce il filtro
vero e proprio: si richiede a geoserver di escludere le features che non hanno come
sessionid quello della sessione in corso. Il sessionid è un identificativo univoco che
viene assegnato a ogni diverso browser che si collega all’applicazione.

var shortest_path = new OpenLayers.Layer.WMS(


"Ottimizzato",
"/geoserver/wms",
{
filter:'<Filter><PropertyIsEqualTo>
<PropertyName>sessionid</PropertyName>
<Literal>
<%=request.getSession().getId()%>
</Literal>
</PropertyIsEqualTo></Filter>',
width: '800',
layers: 'topp:resultsgeo_retepd_traffic',

54
height: '585',
styles: '',
format: 'image/png',
transparent:true

}
);

Questa caratteristica del filtro, come vedremo in futuro, potrà essere utilizzata per
filtrare per data gli eventi di traffico.

Selezionare una tra5a
Sono due i modi in cui l’utente può scegliere la via e quindi i nodi desiderati:
1. Cliccando sulla mappa, come si è visto
2. Selezionando il nome della via dalla casella di testo

Nel primo caso, a partire dal click dell’utente, viene generato un url (Uniform
Resource Locator) contenente la trasposizione in coordinate geografiche delle
coordinate geometriche x, y del punto che si è cliccato.
Viene così generato un bbox , ossia un buffer a di forma rettangolare localizzato
all’interno della mappa attraverso le sue coordinate, con una tolleranza di 5 pixel;
viene effettuata una richiesta a geoserver delle features comprese nell’area del bbox.
Viene presa la prima feature restituita, se ne viene restituita una. Il formato di output
richiesto è JSON, in modo da poter avere un oggetto javascript al ritorno dalla
chiamata asincrona:
url = '/geoserver/wfs?
MAXFEATURES=20&SERVICE=WFS&VERSION=1.0.0&REQUEST=GetFeature&TYPENAME=topp:padova&
SRS=EPSG:3003&outputformat=json&BBOX='+min_ll.lon+','+min_ll.lat+','+max_ll.lon
+','+max_ll.lat+',EPSG:900913';

Si noti l’ultimo parametro della query string che costituisce il sistema di riferimento EPSG in uso:
infatti le coordinate che stiamo usando nella visualizzazione corrente sono proiettate nel sistema di
riferimento di Google, che è EPSG:900913, pertanto le nostre coordinate Gauss Boaga verrebbero
posizionate addirittura in Puglia, a causa della falsa origine del fuso ovest!

Viene impostato il ramo di partenza ed alternativamente il ramo di arrivo se quello di


partenza è già stato impostato, dalla funzione setSource, in cui la variabile json

55
contiene l’intero insieme di features restituito da geoserver secondo il formato JSON
di seguito riportato:
{"type":"FeatureCollection","features":

[{"type":"Feature","id":"padova.6532","geometry":

{"type":"MultiLineString"

,"coordinates":[[[1721056.5369831903,5031779.717952583],

[..]

"codice_via":83656,"nome_via":"tre ponti",

[...]

"source":5902,"target":214,

[]

:"EPSG","properties":{"code":"3003"}},"bbox":

[1721056.5,5031779.5,1721140.75,5033255]}

function setSource(response) {

var json = response.responseText.evalJSON();

if (!json.features[0]){warn("Attenzione: nessuna via
selezionata!");return;}
if ($('avoid_ztl').checked&&json.features[0].properties.ztl==1)
{warn();return;}

if ($('main_routing').checked &&
json.features[0].properties.tipo.indexOf('principale')==-1){warn();return;}


if(!sourceSet){
source=json.features[0].properties.source;
viaStart = json.features[0].properties.nome_via;
[...]
}else{
target = json.features[0].properties.target;
viaEnd = json.features[0].properties.nome_via;

$('viaEnd').value = viaEnd

Un altro sistema di selezione consiste nella digitazione di alcune lettere nel campo
‘partenza da via:’ e ‘arrivo a via:’; essa, alimentata da una richiesta asincrona che
restituisce via json il nome della via selezionata, consente di impostare, sempre
attraverso la funzione setSource, il punto di partenza e di arrivo.

56
23. Autocompletamento nel nome della via

57
La ges8one degli even8 di traffico
Proge5azione interfaccia
L’interfaccia di amministrazione, ossia il pannello che l’utente amministratore vede, è
stata progettata con queste caratteristiche:
Messaggi

Mappa principale

Comandi

Livello traffico
Livello Scorrevole

Imposta liv. traffico

Dal 08/02/2008

Al 15/02/2008

Nome Strada Corso Australia

Al KM 5600

Tipo diss. Lavori cavi elettrici

Diss. su tratte Diss. Kilometrico

Pannello di amministrazione Selezione

Istruzioni sull'uso del pannello

BBOX Poligono Click

24. Progettazione interfaccia utente amministrativa

L’interfaccia amministrativa di LiTRoMS si presenta così:

58
25. Interfaccia amministrativa di LiTRoMS

59
Le operazioni che l’amministratore dovrà compiere saranno incentrate sull’attribuire
ad una determinata tratta un valore di traffico oppure contrassegnare la tratta come
bloccata per lavori.
Per quanto riguarda l’impostazione dei dati di traffico, l’amministratore può scegliere
varie forme di selezione: ad esempio il quadrato o il poligono, o la selezione della
tratta attraverso un click, che avviene come nella modalità di selezione della tratta per
il calcolo del percorso da parte dell’utente.
Supponendo che l’amministratore sappia che c’è la Fiera di Padova, vorrà impostare
un livello di traffico elevato per quella zona, così da scoraggiare chi dovesse
richiedere di passare per quella zona seguendo il percorso più breve dal luogo di
partenza a quello di arrivo. L’amministratore, dopo aver zoomato adeguatamente la
mappa, può selezionare il poligono di interesse, ed impostare per esso un livello di
traffico elevato:

26. Selezione delle tratte attraverso il poligono

L’applicazione andrà a identificare le tratte comprese nella selezione effettuata con il


poligono (o meglio in una sua approssimazione geometrica) e imposterà il livello di
traffico desiderato

60
27. Impostazione di traffico effettuata, il layer è stato ricaricato

Come si può notare il calcolo del percorso, in seguito a questa impostazione,


restituisce un percorso ottimizzato che evita la zona trafficata:

28. Il calcolo del percorso cerca di evitare le zone trafficate

Analogo discorso per quanto riguarda l’aggiornamento di una tratta con


l’impostazione dei lavori in corso: se l’amministratore imposta un blocco per lavori al
centro di una via, ad esempio, l’algoritmo evita quella tratta.
Possiamo vedere un esempio impostando ad esempio un lavoro all’incrocio centrale
di via Venezia:

61
29. Un disservizio impostato in via Venezia

Si può osservare come la tratta viene eliminata dal calcolo del percorso ottimizzato:

30. Il calcolo del percorso ottimizzato evita la tratta interessata dai lavori

 Una variabile in più: il kilometro all’interno del quale si verifica l’evento
Una funzionalità che si ritiene utile impostare, anche se a livello di dati richiede
sostanzialmente un’organizzazione su base aggregata di alcune vie, è la funzione di
impostazione di un blocco per lavori a un determinato kilometro di una percorrenza
principale. E’ chiaro che questa funzionalità è più rivolta a un sistema provinciale che
urbano, ma senza dubbio la sua impostazione è di interesse accademico anche per
la presente tesi.

62
La funzione in oggetto è utilizzabile semplicemente inserendo una kilometrica (in
metri) nell’apposito campo e selezionando un livello di disservizio, e poi premendo il
pulsante “Imposta disservizio su tangenziali”. La funzione è specializzata sulle
tangenziali, in quanto le si immagina come strade di grande percorrenza in cui la
specifica kilometrica ha un valore aggiunto diverso rispetto a una tratta urbana.

31. Selezione del kilometro in cui si verifica il disservizio

Ecco dunque la tratta che assume il tematismo legato al disservizio (e ottenuto con la
stilizzazione SLD del layer WMS)

32. Il disservizio è stato impostato sul kilometro desiderato

63
Terminata questa panoramica sull’interfaccia amministrativa, possiamo fare una
carrellata su quali metodi sono stati usati per le impostazioni del livello di traffico.

Impostare il livello di traffico e di disservizio
Si è creata in Postgis la funzione a_settrafficlevel_retepd che accetta in input una
stringa contenente i nodi separati da virgola, e una funzione analoga che accetta un
array di interi rappresentanti i nodi da aggiornare, e il livello di traffico come secondo
parametro.
Nell’applicazione si è utilizzata la funzione che accetta la stringa e separa al suo
interno i nodi in un array a causa di un difetto documentato del driver JDBC Postgres
nella gestione degli array come parametro. Il procedimento è assolutamente analogo,
comunque, e consente semplicemente di impostare un valore di traffico sulla tabella
relativa, procedendo all’aggiornamento se il nodo è già presente, o all’inserimento se
il nodo è un nodo non registrato. Per completezza vediamo la funzione che imposta il
traffico con il parametro nodes che è un array di interi

CREATE OR REPLACE FUNCTION public.a_settrafficlevel_retepd (in nodes

_int4, in trafficlevel int4) RETURNS bool AS

[...]

BEGIN

counter = array_lower(nodes, 1);

WHILE (counter <= array_upper(nodes, 1)) LOOP

select trafficoliv_id into tr_id from retepd_traffic where

retepd_gid=nodes[counter];

if tr_id is null then

insert into retepd_traffic (id, retepd_gid,

trafficoliv_id)values(nextval('retepd_traffic_id_seq'),nodes[counter],

trafficlevel);

64
else

update retepd_traffic set trafficoliv_id = trafficlevel where

retepd_gid=nodes[counter];

end if;

counter = counter +1;

end LOOP;

[...]

e la funzione che imposta i disservizi con il parametro nodesstring che è una stringa:

CREATE OR REPLACE FUNCTION "public"."a_setdisruptionlevel_retepd" (in

nodesstring varchar, in disruptionlevel int4) RETURNS bool AS

$BODY$

DECLARE

tr_id integer;

counter int8;

nodes integer[];

BEGIN

select string_to_array(nodesstring,',') into nodes;

counter = array_lower(nodes, 1);

WHILE (counter <= array_upper(nodes, 1)) LOOP

select disruption_id into tr_id from disruptions where

gid=nodes[counter];

if tr_id is null then

65
insert into disruptions (disruption_id, gid,

disruption_liv_id)values(nextval('disruptions_id_seq'),nodes[counter],

disruptionlevel);

else

update disruptions set disruption_liv_id = disruptionlevel where

gid=nodes[counter];

end if;

counter = counter +1;

end LOOP;

Si noti che l’unica differenza sostanziale tra le due funzioni è la chiamata alla funzione
string_to_array( nodesstring, ',' ) che effettua la separazione dei valori passati e li
trasforma in un array di interi.

Individuare il kilometro di un determinato punto
La funzione a_setdisruptions_level_retepd viene chiamata anche dopo aver ricavato il
nodo corrispondente a un determinato kilometro di Corso Australia. La via è stata
scelta arbitrariamente, e ha richiesto di stabilire convenzionalmente il kilometro zero in
corrispondenza di una delle due estremità della strada.
Per poter ottenere l’insieme delle tratte corrispondenti a Corso Australia, si è reso
necessario un lavoro di aggregazione dati, consistito nel recuperare tutte le tratte che
effettivamente costituiscono la via di interesse.
Selezionando l’insieme delle tratte il cui attributo nome_via era uguale a “Corso
Australia”, si ottiene un elenco di tratte la cui lunghezza complessiva è circa 14
kilometri, di gran lunga superiore alla lunghezza effettiva di Corso Australia che si
aggira sugli 8.6 kilometri (misurata in maniera approssimativa utilizzando lo strumento
Google Earth).
Molte tratte in effetti costituiscono svincoli di accesso e uscite, per cui si è reso
necessario eliminare dalla selezione complessiva le tracce non corrispondenti alla
percorrenza principale della strada.
Per ottenere il vero insieme delle tratte costituenti Corso Australia, si è proceduto
come in un normale calcolo del percorso, ossia chiedendo di calcolare il percorso più

66
breve dalla tratta scelta come “kilometro zero” fino all’ultima tratta, e
successivamente andando ad eliminare manualmente dal set di tratte selezionate le
poche tratte sulle quali l’algoritmo aveva effettivamente scelto il percorso più breve,
optando per un’uscita e un rientro da Corso Australia perché metricamente più
“convenienti” in termini di percorrenza.

33. Misurazione della lunghezza di Corso Australia da Google Earth

Una volta isolate le tratte e aggregate in una view che a titolo di esempio è stata
creata per Corso Australia ma evidentemente può contenere strade come
aggregazioni di tratte, la funzione che recupera la tratta al kilometro di una
determinata via di percorrenza principale (il cui nome è un parametro della funzione),
percorre in ordine le tratte costituenti la via tenendo conto della somma delle
lunghezze delle tratte percorse. Una volta che la somma delle distanze è maggiore
del kilometro desiderato, quello è il nodo su cui si vuole fare l’aggiornamento. Va
notato che trattandosi di una funzione implementata a livello di prototipo, allo stato
attuale la funzione incorpora in maniera hard coded le tratte selezionate.

CREATE OR REPLACE FUNCTION "public"."a_getbranchatkm" (in streetname

text, in nodestart int4, in km float8) RETURNS int4 AS

[...]

67
open rows for

select s.*, p.length, p.gid FROM shortest_path_astar

('SELECT gid AS id, source::int4, target::int4, length::double

precision AS cost, length::double precision AS

reverse_cost,x1,x2,y1,y2 FROM padova',p_start, p_end, false, false) s

inner join padova p on p.gid = s.edge_id;

loop

fetch rows into row;

IF NOT FOUND THEN

EXIT; -- exit loop

END IF;

raise notice 'len=%', len;

len=len + row.length;

if len > km then

branch_gid=row.gid;

EXIT;

end if;

end loop;

close rows;

return branch_gid;

Sulla base di questo id, può essere effettuato l’aggiornamento del livello di
disservizio, che avviene con chiamate alle opportune servlet come nella modalità di
calcolo del percorso.

if ("atkm".equals(action)){

atKm = Double.parseDouble(request.getParameter("atkm"));
if (!"".equals(request.getParameter("street"))){
street = request.getParameter("street");
}
else
{
throw new ServletException("Parametro street mancante");
}

int nodo = PostgresConnector.getInstance().getBranchAtKm(atKm, street,
nodestart);
if(nodo!=-1){

68
nodi = nodi + nodo;
result = pg.SetDisruption(nodi, livellodisservizio, l, new
Date(System.currentTimeMillis()), new Date(System.currentTimeMillis()));
out.println("<span>" + (result?"Livello disservizio impostato
correttamente.":"Errore durante l'impostazione del livello di disservizio.")+"</
span>");
}else{
out.println("<span class=’error’>Nessun nodo al KM " +atKm+" di via " +
street+"</span>");
return;
}

69
 

70
Conclusioni

Risulta8
L’applicazione è stata creata utilizzando software Open Source. Essa consente di
inserire informazioni sul traffico e sui disservizi in corso e ad un utente di richiedere un
percorso che eviti le zone critiche.
Nell’applicazione creata, il valore aggiunto è nella gestione di queste informazioni;
una gestione che con l’inserimento di dati di traffico aumenta in maniera diretta la
qualità di vita di chi sta guidando, ma anche di chi risiede nella zona, grazie ad un
uso razionale delle tratte. Quelle del traffico o dei disservizi sono solo alcune delle
molteplici cause che possono bloccare una tratta, eppure ognuna di queste cause
genera esternalità di grande rilevanza.

Sviluppi futuri
Poter alimentare dati sul traffico grazie all’uso di sensori annegati nell’asfalto o di
telecamere come si sta sperimentando in alcune realtà italiane, quindi gestire in
maniera scalare anziché empirica l’informazione sul traffico, può consentire una
precisione quasi millimetrica nella gestione dei percorsi. Ad esempio, l’applicazione
potrebbe tenere conto del fatto di aver suggerito a un certo numero di richieste di
eseguire un percorso alternativo, e contrassegnare questo stesso percorso
alternativo per una certa frazione di tempo come trafficato e suggerire ulteriori
alternative alle nuove richieste.

Un’altra caratteristica non difficile da implementare ma preziosa nell’aumentare


“l’intelligenza” dell’applicazione potrebbe essere quella di tener conto di fenomeni
morfologici e adattare così i percorsi calcolati in funzione della pendenza e della
pesantezza del mezzo, e ancora più grandi opportunità di sviluppo potrebbero
giungere dalla bidirezionalità dei dati. Supponendo infatti che ogni veicolo fosse in
grado di fornire la propria posizione al sistema, questo certamente contribuirebbe
non solo ad avere in maniera puntuale i dati di traffico ma anche a suggerire in

71
modalità “transazionale” percorsi diversi non indicando lo stesso percorso a più
veicoli di quanto non possa gestire la portata delle tratte da percorrere.

Problema8che riscontrate
Costruire un GIS Open è possibile, ma contrariamente a quanto si possa pensare, il
problema non è nella scrittura del software, ma nel recupero dei dati. A differenza di
altri tipi di software in cui i dati vengono gestiti, manipolati e inseriti attraverso il
software stesso, solitamente il software GIS nasce con l’esigenza di consultare,
analizzare e sviscerare le informazioni presenti nel territorio, anche dove il dato puro e
semplice non parla un linguaggio facile da capire.
In effetti, un’applicazione come quella sviluppata è ben poca cosa se si pensa
all’importanza che hanno i dati al suo interno. O meglio, sono i dati a renderla
potente, perché se all’interno del database geografico fosse presente la cartografia
italiana, l’applicazione sarebbe in grado di calcolare il percorso ottimizzato non solo
da un punto all’altro di Padova, ma da un punto all’altro dell’Italia, dell’Europa, e così
via.
Ci sono esperimenti collettivi di raccolte di dati che in un certo senso rappresentano
una versione avanzata della condivisione del codice sorgente, e nel caso dei gis
potrebbero costituire la vera differenza per la crescita del software open.
Uno di questi esempi è Open Street Maps: una raccolta di dati da parte di volontari
che raccolgono e inseriscono dati riguardanti il territorio per mezzo di rilievi tramite
GPS. A titolo di esempio, la situazione dei dati di Padova è ancora molto incompleta,
tuttavia fa un certo effetto pensare che ognuna di queste strade esiste nella
cartografia di Open Maps per il semplice motivo che un volontario con un GPS
portatile ha inserito i dati sul nome della via, i numeri civici, il senso di percorrenza e
altri dati utili.
Quindi il valore dei Sistemi Informativi è nei dati più che nella loro elaborazione? No,
non è così. Perché la lettura dei dati è sempre stata a disposizione, ma è la loro
interpretazione “visuale” che cambia nei GIS. Basti pensare al primo storico esempio
di GIS, in cui fu identificata la causa di un’epidemia di colera da parte del Dottor John
Show grazie all’osservazione della mappatura delle localizzazioni di casi intorno a una

72
sorgente contaminata nell’area di Soho, Londra, nel 1854. Questa conclusione porto
il Dottor Show a capire che il colera si trasmetteva attraverso i liquidi e non, come si
pensava all’epoca, attraverso l’aria.
Il valore dei Gis è nella capacità di interpretare i dati, nel ricavare metainformazioni da
informazioni semplici, e nel riuscire a trasformare il territorio in informazioni di più
agevole comprensione anche per la persona comune.

73
Bibliografia
Aime, Andrea. “Geoserver, Protocollo WFS”. Diss. 2007. 01 Feb. 2008.

Aime, Andrea. "Parameter for WMS Feature Type." Geoserver Developers Mailing List. 15 Feb.
2008. 16 Feb. 2008 <geoserver-devel@lists.sourceforge.net>.

Aime, Andrea. "WMS Filter on Date Field." Geoserver Users Mailing List. 25 Feb. 2008. 25 Feb.
2008 <Geoserver-users@lists.sourceforge.net>.

Browser Stats. W3C Consortium. 2008. <http://www.w3schools.com/browsers/


browsers_stats.asp>.

De La Beaujardière, Jeff, ed. Web Map Service Implementation Specification. 16 Jan. 2002,
Open Gis Consortium Inc. 2002.

Deoliveira, Justin. The Platform Module. Ed. Justin Deoliveira. Open Plans. 14 Feb. 2008
<http://docs.codehaus.org/display/GEOSDOC/0+Platform#0Platform-ows>.

Deoliveira, Justin. "Troubles with Google Overlay." Geoserver Developers Mailing List. 10 Feb.
2008. 16 Feb. 2008 <geoserver-devel@lists.sourceforge.net>.

Ford, Neal. Art of Java Web Development. Greenwich, CT, US: Manning Publications Co., 2006.

Garrett, Jesse J. "Ajax: a New Approach to Web Applications." 18 Feb. 2005. 16 Feb. 2008
<http://www.adaptivepath.com/ideas/essays/archives/000385.php>.

Hocevar, Andreas. "Selecting Features Through Box." Openlayers Users Group. 08 Feb. 2008.
09 Feb. 2008 <www.openlayers.org>.

Jody Garnett, GeoServer WFS-T,< weblogs.java.net >, January 2006

Lemoine, Eric. "Coordinates System Transformations." Openlayers Users Group. 13 Feb. 2008.
13 Feb. 2008 <www.openlayers.org>.

Maschio, Andrea. "I Database Topografici." Diss. Università IUAV - Venezia, 2007.

Maschio, Andrea. "Scelta Del Software Per Un Webgis." Diss. Università IUAV - Venezia, 2007.

74
Metsker, Steven J. Design Patterns in Java. 1st ed. Milano: Pearson Education Italia S.R.L.,
2003. 81-83.

Parente, Claudio, Santamaria, Raffaele Sistemi Informativi Georiferiti, Estr. Giannini Napoli 2004

The Postgresql Global Dev. Postgres 8.3.0 Documentation. The PostgreSQL Global
Development Group. 2008.

The Postgresql Global Dev. PostgreSQL history. The PostgreSQL Global Development Group.
2008.< http://www.postgresql.org/about/history>

Ramsey, Paul. PostGIS Manual. Refractions Research. 2005.


Vretanos, Panagiotis A., ed. Web Feature Service Implementation Specification. 03 May 2005,
Open Geospatial Consortium Inc. 2005.

Zakas, Nicholas C., Jeremy Mc Peak, and Joe Fawcett. Professional Ajax. 1st ed. Indianapolis,
Indiana, US: Wiley, 2006.

Si8 Web

http://www.wikipedia.org
http://en.wikipedia.org
http://pgrouting.postlbs.org/
http://www.kyngchaos.com/
http://www.opengeospatial.org/

75
76
UNIVERSITÀ IUAV DI VENEZIA
FACOLTA’ DI PIANIFICAZIONE DEL TERRITORIO

DICHIARAZIONE DI CONSULTABILITA’ O NON CONSULTABILITA’


DELLA TESI

Il sottoscritto Maschio Andrea, matr. n. 252268

laureando in Sistemi Informativi Territoriali sessione straordinaria


dell’a.a. 2006/2007

DICHIARA
che la sua tesi dal titolo:
“Progettazione e realizzazione prototipale di un sistema di gestione
degli eventi di traffico” è consultabile da subito.

data 05/03/2008 firma ………………………

77
78
Note

79
80