Public Light Manager - Una GUI per la gestione remota di un impianto di illuminazione pubblica
-
Upload
gianluca-ritrovati -
Category
Technology
-
view
1.062 -
download
2
description
Transcript of Public Light Manager - Una GUI per la gestione remota di un impianto di illuminazione pubblica
Universita Politecnica delle Marche
Facolta di Ingegneria
Corso di
Microelettronica
Public Lighting Manager
Una GUI per la gestione di impianti diilluminazione pubblica
Relatore Studente
Prof. Claudio Turchetti Gianluca Ritrovati
Correlatore matr: 221143
Prof. Giorgio Biagetti
Anno Accademico 2011/2012
Universita Politecnica delle Marche
Facolta di Ingegneria
Corso di
Microelettronica
Public Lighting Manager
Una GUI per la gestione di impianti diilluminazione pubblica
Relatore Studente
Prof. Claudio Turchetti Gianluca Ritrovati
Correlatore matr: 221143
Prof. Giorgio Biagetti
Anno Accademico 2011/2012
Abstract
In questa tesina viene relazionato il lavoro di implementazione di una
interfaccia grafica (GUI) per la gestione di una rete di illuminazione pub-
blica. L’applicazione, legge da un database esterno i dati della rete di illu-
minazione e li presenta all’utente. Questi dati comprendono le coordinate
GPS, le caratteristiche tecniche e l’indirizzo seriale di ciascun lampione. Me-
diante questi dati la rete di illuminazione viene rappresentata su una mappa
topografica e sottoforma di lista ordinata.
L’operatore ha quindi a disposizione una serie di strumenti e di criteri
per la seleziare i lampioni e per inviare determinati comandi da remoto.
1
Indice
1 Introduzione 4
1.1 Scenario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.2 Obiettivi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.3 Scelte tecnologiche . . . . . . . . . . . . . . . . . . . . . . . . 6
1.4 Struttura della tesina . . . . . . . . . . . . . . . . . . . . . . . 7
2 Background 8
2.1 La libreria Qt . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.1 Il Meta-Object System . . . . . . . . . . . . . . . . . . 10
2.1.2 Meta-Object Compiler . . . . . . . . . . . . . . . . . . 11
2.1.3 Signals and Slots . . . . . . . . . . . . . . . . . . . . . 11
2.1.4 L’architettura Model/View . . . . . . . . . . . . . . . 14
2.2 Sistemi di coordinate . . . . . . . . . . . . . . . . . . . . . . . 17
2.2.1 Il sistema WGS84 . . . . . . . . . . . . . . . . . . . . 17
2.2.2 Il sistema cartesiano . . . . . . . . . . . . . . . . . . . 17
2.2.3 Conversione di coordinate . . . . . . . . . . . . . . . . 18
2.3 I servers WMS . . . . . . . . . . . . . . . . . . . . . . . . . . 20
2.3.1 Il progetto OpenStreetMap . . . . . . . . . . . . . . . 22
2.3.2 I tiles . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
2.3.3 Trasformazione di coordinate . . . . . . . . . . . . . . 23
3 Il Public Lighting Manager 25
3.1 L’interfaccia . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
3.1.1 Menu . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
3.1.2 Barra degli strumenti . . . . . . . . . . . . . . . . . . 27
3.1.3 Vista mappa . . . . . . . . . . . . . . . . . . . . . . . 28
3.1.4 Pannello filtri . . . . . . . . . . . . . . . . . . . . . . . 28
2
INDICE 3
3.1.5 Vista elenco . . . . . . . . . . . . . . . . . . . . . . . . 29
3.1.6 Barra di stato . . . . . . . . . . . . . . . . . . . . . . . 29
3.2 Gestione database . . . . . . . . . . . . . . . . . . . . . . . . 29
3.2.1 Avviare una nuova connessione . . . . . . . . . . . . . 29
3.2.2 Aprire un file di connessione . . . . . . . . . . . . . . . 31
3.2.3 Modifica database . . . . . . . . . . . . . . . . . . . . 31
3.2.4 Chiusura della connessione . . . . . . . . . . . . . . . 34
3.3 Selezione e filtraggio . . . . . . . . . . . . . . . . . . . . . . . 34
3.3.1 Selezione da mappa . . . . . . . . . . . . . . . . . . . 35
3.3.2 Selezione da tabella . . . . . . . . . . . . . . . . . . . 35
3.3.3 Selezione con filtro . . . . . . . . . . . . . . . . . . . . 36
3.4 Invio comandi . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4 Implementazione software 38
4.1 Gestione della mappa . . . . . . . . . . . . . . . . . . . . . . 38
4.1.1 Struttura di QMapControl . . . . . . . . . . . . . . . 39
4.1.2 Le geometrie . . . . . . . . . . . . . . . . . . . . . . . 39
4.1.3 I livelli . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
4.1.4 Richiesta dei Tiles . . . . . . . . . . . . . . . . . . . . 43
4.2 Struttura del progetto . . . . . . . . . . . . . . . . . . . . . . 44
4.3 Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
4.3.1 Connessione . . . . . . . . . . . . . . . . . . . . . . . . 46
4.3.2 Database Editor . . . . . . . . . . . . . . . . . . . . . 49
4.4 L’architettura Model/View . . . . . . . . . . . . . . . . . . . 53
4.4.1 Implementazione del model . . . . . . . . . . . . . . . 53
4.4.2 Implementazione del view . . . . . . . . . . . . . . . . 54
4.5 Selezione e filtraggio . . . . . . . . . . . . . . . . . . . . . . . 55
4.5.1 Selezione singola da mappa . . . . . . . . . . . . . . . 55
4.5.2 Selezione multipla da mappa . . . . . . . . . . . . . . 55
4.5.3 La funzione performMouseSelection() . . . . . . . . . . 55
4.5.4 Selezione e filtraggio da pannello . . . . . . . . . . . . 56
4.6 Operazioni di Input/Output . . . . . . . . . . . . . . . . . . . 56
4.6.1 Operazioni di input . . . . . . . . . . . . . . . . . . . 56
4.6.2 Operazioni di output . . . . . . . . . . . . . . . . . . . 57
5 Conclusioni e sviluppi futuri 58
Capitolo 1
Introduzione
In questo capitolo si descrive il contesto teconologico nel quale il progetto
e stato ideato. Vengono fissati gli obiettivi da raggiungere ed illustrate le
motivazioni che hanno portato alla scelta di determinate tecnologie.
Viene infine descritta la struttura della tesina.
1.1 Scenario
Nell’ambito di politiche di risparmio energetico sempre piu stringenti [5],
il settore dell’illuminazione sta vivendo un profondo moto di rinnovamento.
Sia in campo domestico, che in campo industriale infatti, le tecnologie ener-
geticamente meno efficienti, vengono progressivamente sostituite con nuovi
sistemi con alto rendimento e minor consumo.
Il settore pubblico non fa eccezione, basti pensare che la voce di spesa
maggiore per un bilancio comunale, e quella relativa alla pubblica illumi-
nazione, sia per quanto riguarda il consumo energetico e sia per i costi di
gestione e manutenzione.
Le soluzioni che permettono un risparmio economico, implicano quindi
sia l’uso di dispositivi di illuminazione piu efficienti, come ad esempio proiet-
tori a tecnologia LED e sia una gestione telecontrollata di questi dispositivi,
capace di regolare in tempo reale i flussi luminosi a seconda delle esigenze e
della variabilita delle condizioni di luce naturale.
Da un punto di vista tecnico quindi, e facile prevedere l’uso sempre mag-
giore di elettronica di controllo ed in particolare, l’uso di protocolli wireless
come lo ZigBee [1] [8]. Lo sviluppo futuro sara quello di creare una rete
4
1.2 Obiettivi 5
Fig. 1.1: Una rete di lampioni
intelligente di illuminazione, la cui gestione e affidata ad un computer cen-
trale, dal quale poter avviare opportuni programmi di illuminamento o su
cui ricevere tutte le informazioni sullo stato e sul consumo dei proiettori.
1.2 Obiettivi
Ipotizzando uno scenario come quello descritto precedentemente, il la-
voro svolto in questo progetto, e stato quello di sviluppare una interfac-
cia grafica (Graphical User Interface), per la gestione remota della rete di
illuminazione pubblica.
L’applicazione deve poter leggere da un database esterno i dati relativi
ai singoli lampioni della rete. Questi dati sono:
• l’identificativo (ID) dell’apparato illuminante;
• le coordinate geografiche del lampione, espresse come latitudine e lon-
gitudine;
• il nome della via dove il lampione e situato;
• il gruppo (circoscrizione, quartiere, ecc.) al quale il lampione appar-
tiene;
• il tipo di supporto (su palo, a sospensione, a muro ecc.) e la data
ultima di sostituzione;
1.3 Scelte tecnologiche 6
• il tipo di lampada (a LED, ai vapori di sodio, alogena ecc.) e la data
ultima di sostituzione;
• il nome dell’operatore che ha effettuato l’installazione o l’ultimo inter-
vento;
• l’indirizzo seriale per l’invio dei comandi.
L’applicazione deve prevedere la possibilita modificare e di integrare,
successivamente, tutte le voci del database a seconda delle necessita.
La rete di illuminazione deve essere rappresentata su una mappa, secondo
le coordinate di ciascun elemento.
Inoltre l’operatore deve poter selezionare sulla mappa i singoli lampioni,
sui quali poter effettuare le operazioni del caso.
L’applicazione deve prevedere anche una forma di rappresentazione tabel-
lare, con un pannello filtri che permetta la selezione per ubicazione, per
gruppo, per lampada montata e per operatore tecnico.
Al momento della stesura del progetto non e stato ancora definito nello
specifico l’hardware di comunicazione dei lampioni, pertanto le operazioni
effettuabili su questi dispositivi sono limitati ai comandi di accensione e
spegnimento. Per lo stesso motivo non sono implementati gli algoritmi per
il trattamento dei segnali di comunicazione con i dispositivi, ma i comandi
si riducono alla semplice scrittura su un file di log ( log file.txt).
1.3 Scelte tecnologiche
Il progetto, che d’ora in avanti chiameremo“Public Lighting Manager”(o
abbreviato P.L.M.), e stato scritto in linguaggio C++, utilizzando il frame-
work Qt versione 4.7 [2]. Si tratta di una libreria di proprieta della Nokia,
distribuita gratuitamente, appositamente studiata per la realizzazione in-
terfacce grafiche, con un approccio particolarmente orientato agli oggetti.
Questo framework e multipiatatforma, quindi permette il porting dell’appli-
cazione su diversi sistemi operativi (Linux, Windows e Mac) e su sistemi em-
beded, come PDA e smartphones. Inoltre, Qt ingloba una serie di API (Ap-
plication Programming Interface) di generica utilita, che ci hanno agevolato
nel creare le funzioni per l’accesso dell’applicazione al database SQL, nella
programmazione di rete e nella lettura/scrittura in formato XML.
1.4 Struttura della tesina 7
Per lo storage dei dati abbiamo utilizzato un database di tipo MySql [3].
Si tratta di un database open source, ormai diffusissimo grazie alle sue ottime
prestazioni, alla sua elevata affidabilita e alla facilita d’utilizzo. E’ anch’esso
multipiattaforma ed e ben supportato da Qt.
Per la visualizzazione della mappa e stato utilizzato il servizio Open-
StreetMap [6]. Si tratta di un sistema partecipativo, simile a Wikipedia,
per la condivisione di dati cartografici da apparati GPS. Rispetto al noto
servizio Google Maps le mappe OSM possono essere utilizzate liberamente (e
gratuitamente) all’interno delle applicazioni, a patto che se ne citi la fonte.
La natura collaborativa del progetto OSM fa si che il materiale mappale sia
sempre aggiornato e corretto. In presenza di nuove urbanizzazioni, ad es-
empio, e sufficiente aggiornare i dati caricando i nuovi tracciati con l’ausilio
di un normale dispositivo GPS.
1.4 Struttura della tesina
• Capitolo 2: Background. In questo capitolo viene presentata una
panoramica sulle tecnologie adottate che sono alla base del progetto e
sulle motivazioni che ne hanno determinato la scelta.
• Capitolo 3: Il Public Lighting Manager. In questo capitolo illustreremo
il funzionamento dell’applicazione dal punto di vista dell’utilizzatore
finale.
• Capitolo 4: Implementazione dell’applicazione. Viene presentata la
struttura del progetto, sotto l’aspetto dell’implementazione del codice.
Segue una panoramica sulle classi e le funzioni principali.
• Capitolo 5: Conclusioni e sviluppi futuri. Si presentano i risultati
dei test dell’interfaccia e le problematiche riscontrate. Si analizzano
inoltre i possibili sviluppi dell’interfaccia.
Capitolo 2
Background
2.1 La libreria Qt
Il framework Qt nasce da un progetto di Haavard Nord e Eirik Chambe-
Eng (fondatori della Trolltech) nell’ambito della realizzazione di un ambi-
ente per lo sviluppo di interfacce grafiche in C++ [10]. Mentre erano im-
pegnati in questo progetto, ai due venne l’idea di rendere quel framework
multipiattaforma, garantendo la presenza delle stesse API sotto ogni sistema
operativo. Nel 1995 venne pubblicata la prima versione del framework Qt.
Nella programmazione di interfacce grafiche si richiede una buona effi-
cienza a tempo di esecuzione ed un elevato grado di flessibilita. Per soddis-
fare questi requisiti che Qt combina alla velocita del C++ la flessibilita del
suo modello ad oggetti.
Nello specifico, Qt aggiunge le seguenti potenzialita al C++:
• un potente meccanismo di comunicazione tra oggetti chiamato Signals
and Slots;
• un potente sistema di eventi e filtraggio degli eventi;
• l’internazionalizzazione delle applicazioni;
• la possibilita di richiedere all’oggetto le sue proprieta dinamicamente;
• un sistema di timer;
• una gerarchia di oggetti, dove QObject ne e la radice;
• un sistema di puntatori;
8
2.1 La libreria Qt 9
• un cast dinamico che opera attraverso le librerie.
Molte di queste caratteristiche vengono implementate con le tecniche
standard del C++, mentre altre, come la comunicazione Signals and Slots
e il sistema dinamico delle proprieta, richiede il Meta-Object System imple-
mentato da Qt attraverso il Meta-Object Compiler (MOC).
Le classi che stanno alla base del modello ad oggetti di Qt sono:
• QMetaClassInfo: contiene le informazioni su una classe
• QMetaEnum: contiene i meta dati dei tipi enumerativi
• QMetaMethod: contiene i meta dati sulle funzioni membro
• QMetaObject: contiene meta informazioni sugli oggetti Qt
• QMetaProperty: contiene meta data che riguardano le proprieta
• QMetaType: gestisce i nomi dei tipi nel Meta-Object System
• QObject: la radice della gerarchia di oggetti Qt
• QObjectCleanupHandler: gestisce il ciclo di vita degli oggetti
• QPointer: classe che implementa i puntatori agli oggetti
• QSignalMapper: gestisce i segnali dai sender identificati
• QVariant: questa classe agisce come l’unione dei principali tipi degli
oggetti Qt
Un oggetto Qt valido deve avere:
• Un nome univoco;
• un posto nella gerarchia degli oggetti;
• puo essere connesso ad altri oggetti per inviare o ricevere segnali;
• deve avere un insieme di proprieta.
2.1 La libreria Qt 10
2.1.1 Il Meta-Object System
Il Meta-Object System e un estensione del C++ che rende il linguaggio
piu adatto alla programmazione di GUI mediante componenti che sfruttan-
do le elevate prestazioni del C++ e che non potrebbero essere raggiunte
altrimenti. Questo si base su tre aspetti:
1. la classe QObject fornisce una classe base per gli oggetti che possono
usufruire del Meta-Object System;
2. la macro Q OBJECT all’interno della sezione privata della dichiarazione
di classe viene utilizzata per abilitare alcune funzionalita del meta
oggetto come le proprieta dinamiche, ed il sistema di comunicazione
Signals and Slots;
3. il Meta-Object Compiler fornisce ad ogni QObject il codice necessario
per l’implementazione delle caratteristiche del meta oggetto.
Inoltre, per fornire i meccanismi di comunicazione tra oggetti mediante
Signals and Slots, il Meta-Object System mette a disposizione le seguenti
funzionalita:
• QObject::metaObject(): restituisce il meta oggetto associato alla classe
• QMetaObject::className(): restituisce il nome della classe a tempo di
esecuzione
• QObject::inherits(): permette di discriminare se l’oggetto e istanza di
una classe ereditata
• QObject::tr() e QObject::trUtf8(): permettono la traduzione di stringhe
per la proprieta di internazionalizzazione
• QObject::setProperty() e QObject::property(): permettono di leggere e
settare le proprieta dell’oggetto dinamicamente
• QMetaObject::newInstance(): costruisce una nuova istanza della classe
• qobject cast() utilizzato su un QObject da la possibilita di eseguire un
cast dinamico dell’oggetto.
2.1 La libreria Qt 11
2.1.2 Meta-Object Compiler
Il Meta-Object Compiler (MOC) e un applicazione di Qt per la gestione
delle estensioni C++. In particolare esso si occupa di creare un file sorgente,
contenente il codice del meta oggetto, per ogni file sorgente contenente la
macro Q OBJECT o altre macro come PROPERTY e Q ENUMS. Questo
sorgente verra poi incluso nel vecchio file o compilato e linkato all’implemen-
tazione della classe. La creazione del file contenente il codice per il meta
oggetto e necessaria per implementare meccanismi come la comunicazione
tra gli oggetti, la gestione delle proprieta dinamicamente e le informazioni
dei tipi a runtime (RTTI). Un tipico file sorgente dove il MOC agisce e
mostrato di seguito:
c l a s s MyClass : p u b l i c QObject
{
Q OBJECT
pu b l i c :
MyClass ( QObject ∗ pa r en t=0) ;
MyClass ( ) ;
s i g n a l s :
v o i d mySigna l ( ) ;
p u b l i c s l o t s :
v o i d mySlot ( ) ;
} ;
La creazione dei sorgenti che contengono i meta dati puo avvenire secon-
do due diverse modalita: una che prevede l’utilizzo diretto del MOC addeb-
itando al programmatore l’onere di inserire delle regole per la gestione del
MOC all’interno dei makefile, l’altra che prevede l’utilizzo del tool qmake
che crea automaticamente i makefile con le regole idonee per il corretto
funzionamento del MOC.
2.1.3 Signals and Slots
Il sistema Signals and Slots implementa la comunicazione tra gli ogget-
ti. Questa e una caratteristica peculiare di Qt che lo differenzia da altri
framework per GUI in circolazione.
Nell’ambito della programmazione di interfacce grafiche, ci si aspetta che
al variare di dati corrisponda la variazione di qualche elemento della GUI.
Nei vecchi framework per la programmazione di GUI, questo meccanismo
2.1 La libreria Qt 12
viene implementato utilizzando dei riferimenti a delle funzioni detti callback.
I problemi principali che affliggono questo sistema sono due: innanzitutto
non e type-safe, nel senso che non possiamo essere sicuri che la funzione
chiamante invochi una funzione callback con i parametri adeguati, in secondo
luogo, una funzione callback e strettamente legata alla funzione chiamante,
quindi quest’ultima deve conoscere con precisione la funzione da invocare.
Il sistema Signals and Slots di Qt, rappresenta una valida alternativa
al meccanismo del callback. Ogni oggetto Qt e caratterizzato dall’avere
una serie di segnali e di slot, alla quale il programmatore puo aggiungere
quelli creati autonomamente. Un segnale viene emesso da un oggetto al
verificarsi di un determinato evento, mediante il metodo emit(), mentre lo
slot rappresenta l’azione, o la sequenza di azioni, da intraprendere quando
questo viene attivato dal segnale al quale e collegato. in pratica uno slot
e l’equivalente di un metodo con degli opportuni argomenti in ingresso. A
differenza del meccanismo di callback, Signals and Slots e type-safe, nel senso
che la firma del segnale emesso deve coincidere con la firma dello slot che
deve essere eseguito. Inoltre, segnali e slot sono disaccoppiati, cio vuol dire
che un segnale non deve conoscere lo slot a cui e collegato. La connessione
tra un segnale ed uno slot avviene mediante il metodo:
connect ( Sender , SIGNAL( s i g n a l ( ) ) , Rece i v e r , SLOT( s l o t ( ) ) )
dove i parametri assumono il seguente significato:
→ Sender: l’oggetto (o il thread) che invia il segnale;
→ SIGNAL(signal()): il segnale che viene emesso dal Sender;
→ Receiver: l’oggetto (o un thread) che riceve il segnale;
→ SLOT(slot()): le funzioni che il receiver deve eseguire alla ricezione del
segnale.
La Fig. 2.1 mostra un esempio di connessione tra oggetti. Questo mec-
canismo prevede non solo la connessione tra segnale e slot, ma anche la
connessione tra due segnali, tra un segnale e piu slot e tra piu segnali ed uno
slot. Ovviamente non e contemplata la connessione tra due slot, in quanto
non e possibile emettere uno slot.
Quando un segnale viene emesso, l’esecuzione dello slot avviene istan-
taneamente e solo al termine della sua esecuzione, il chiamante riprende il
2.1 La libreria Qt 13
Fig. 2.1: Esempio di collegamento Signal/Solt.
controllo. Esiste anche la possibilita di creare una coda di connessioni, in
questo caso l’esecuzione dello slot associato all’emissione di un segnale non
avviene istantaneamente.
La connessione tra segnale e slot puo essere interrotta mediante la chia-
mata alla funzione disconnect().
L’unico punto a sfavore di questo sistema di comunicazione e che risulta
essere circa 10 volte piu lento, rispetto a chiamare direttamente la funzione
da eseguire. Questo tempo e dovuto all’overhead richiesto per localizzare
l’oggetto, creare la connessione ed effettuare il marshall dei parametri. Tut-
tavia questo rallentamento influisce in minima parte nel tempo complessivo
di esecuzione del programma e rimane comunque piu veloce dell’allocazione
di un nuovo oggetto mediante new.
Vediamo infine un esempio pratico dell’utilizzo del sistema Signal /
Slot. Si puo notare come la creazione di un segnale avviene all’atto del-
la creazione della classe che definisce l’oggetto, mentre, la creazione di uno
slot oltre a richiedere la dichiarazione, come avviene per il segnale, deve
essere implementato allo stessa maniera di un metodo.
p u b l i c s l o t s :
v o i d s e tVa l u e ( i n t v a l u e ) ;
s i g n a l s
va lueChanged ( i n t newValue ) ;
2.1 La libreria Qt 14
vo i d Counter : : Se tVa lue ( i n t e v a l u e )
{
i f ( v a l u e !=m value ) {
m value=va l u e ;
emit va lueChanged ( v a l u e ) ;
}
}
Couter a , b ;
QObject : : connect (&a , SIGNAL( va lueChanged ( i n t ) ) ,
&b ,SLOT( s e tVa l u e ( i n t ) ) ) ;
a . s e tVa l u e (12) ; //a . v a l u e ( )==12, b . v a l u e ( )==12
b . s e tVa l u e (48) ; //a . v a l u e ( )==12, b . v a l u e ( )==48
Siano a e b due oggetti di tipo Counter. L’invocazione del metodo set-
Value() sull’oggetto a (uno slot puo essere invocato anche come un normale
metodo) provoca la variazione dell’attuale valore dell’oggetto che emette il
segnale valueChanged(int), attivando di conseguenza lo slot dell’oggetto b
che provvedera ad assegnare il valore ricevuto come parametro.
2.1.4 L’architettura Model/View
Il framework Qt introduce lo schema di progettazione Model/View Con-
troller (MVC). Si tratta di un pattern architetturale molto usato nell’ingeg-
neria del software, che consiste nel separare nettamente il problema dei dati
dalla loro rappresentazione, con dei vantaggi enormi in termini di flessibilita.
Il pattern e cosı composto:
• il model: fornisce i metodi per accedere ai dati utili all’applicazione;
• il view: visualizza i dati contenuti nel model e si occupa dell’inter-
azione con utenti e agenti;
• il controller riceve i comandi dell’utente (in genere attraverso il view)
e li attua modificando lo stato degli altri due componenti.
Quando, come nel frmework Qt, il view ed il controller sono combi-
nati si ottiene l’architettura model/view. Questa ha anch’essa il fine ul-
timo di separare il modo il cui i dati sono memorizzati, dal modo in cui
sono presentati, ma con un’architettura piu semplice. Questa separazione
2.1 La libreria Qt 15
Fig. 2.2: Il pattern Model/View Controller.
permette di rappresentare gli stessi dati in modi differenti, e da la possi-
bilita di implementare nuove views, senza dover cambiare la struttura dati
sottostante.
Per permettere la gestione flessibile dei dati da parte dell’utente, viene
introdotto il concetto di delegate. Questo elemento gestisce la conversione
dei dati, nello scambio tra model e view.
Lo schema dell’archittettura model/view in Qt e presentato in Fig. 2.2.
Il model comunica con la sorgente dati, provvedendo ad interfacciarli
con gli altri componenti dell’architettura. La natura della comunicazione
dipende dal tipo di dati e dal modo il model e implementato.
Il view ottiene dal model un sistema di indici riferito ai dati. Questi
indici verranno utilizzati per recuperare i dati dalla sorgente.
Nelle view standard, un delegate converte i singoli dati. Quando un
dato e modificato, il delegate comunica direttamente con il model utilizzando
la sua indicizzazione.
La comunicazione tra queste componenti avviene mediante il sistema
Signals and Slots:
→ i segnali provenienti dal model informano il view del cambiamento nei
dati;
→ i segnali provenienti dal view contengono le informazioni nate dalle
iterazioni dell’utente con la visualizzazione;
→ i segnali provenienti dal delegate aggiornano model e view: nello speci-
fico informano il model se bisogna aggiornare o prelevare dei dati e il
2.1 La libreria Qt 16
view se bisogna aggiornare la vista.
Ognuna delle componenti descritte sono implementate in Qt da clas-
si astratte che definiscono una interfaccia comune e, in alcuni casi, im-
plementano alcune proprieta di defautl. Le classi astratte necessitano di
essere sottoclassate per ottenere un set completo di funzioni necessarie ai
componenti.
Model
Tutti gli oggetti model in Qt derivano dalla classe astratta QAbstrac-
tItemModel. Questa classe implementa i metodi comuni a tutti i tipi di
model. E’ flessibile a sufficienza da permettere al view di rappresentare i
dati come tabelle, liste o alberi. Strutture dati complesse possono essere
modellati creando delle sottoclassi di QAbstractItemModel. Per le strutture
dati piu comuni, Qt fornisce un’ampia scelta di sottoclassi. Per la gestione
del database MySql ad esempio, in questo progetto abbiamo utlizzato le
classi QSqlTableModel e QSqlRelationalTableModel.
View
Implementazioni complete sono fornite per diversi tipi di rappresen-
tazione: QListView visualizza i dati in formato lista, qtQTableView vi-
sualizza i dati di un modello in forma tabellare, mentre QTreeView mostra
i dati come lista gerarchica. Ognuna di queste classi deriva dalla classe as-
tratta QAbstractItemView. Tutte queste classi possono essere a loro volta
sottoclassate per ottenere visualizzazioni personalizzate.
Delegate
Diversamente dal pattern MVC, la progettazione Model/View non com-
prende una completa separazione delle componenti per la gestione delle iter-
azioni con l’utente. In generale il view e responsabile della presentazione dei
dati e della gestione degli input da parte dell’utente. Per consentire maggior
flessibilita nel modo in cui si ottengono questi input, le iterazioni con l’utente
vengono gestite dal delegate. Questo componente oltre a gestire gli input
dall’utente, include anche delle funzionalita di rendering per la modifica di
oggetti nelle viste. Le classi base dei delegate sono: QAbstractItemDelegate
e QItemDelegate.
2.2 Sistemi di coordinate 17
Questi aspetti del framework Qt verranno ripresi nei prossimi capitoli,
quando tratteremo l’implementazione del framework model/view all’interno
del nostro progetto.
2.2 Sistemi di coordinate
Verranno di seguito descritti due sistemi di coordinate, necessari per
poter lavorare con materiale mappale. Il World Geodatic System e uno dei
tanti sistemi di riferimento per mappe, ed uno dei piu usati.
2.2.1 Il sistema WGS84
Il World Geodatic System (WGS84) e un sistema di riferimento terrestre,
cartesiano e geocentrico. Il sistema tiene conto della non perfetta sfericita
della terra. Esso e realizzato con una precisione di ±1m. Le coordinate sono
espresse in gradi secondo due parametri: latitudine e longitudine.
La longitudine, chiamata anche meridiano, giace perpendicolarmente
all’equatore e corre da un polo all’altro. E’ suddiviso in 360◦, 180◦ nell’em-
isfero orientale e 180◦ nell’emisfero occidentale. Il meridiano nullo passa per
l’osservatorio di Greenwich, in Inghilterra.
La latitudine, chiamata anche parallelo, giace parallelamente all’equa-
tore. E’ suddivisa in 180◦, 90◦ a nord dell’equatore e 90◦ a sud. Tra queste
coordinate si puo indicare anche la quota sul livello del mare. Le coordinate
sono illustrate in Fig. 2.3.
Il WGS84 costituisce il sistema di coordinate utilizzato anche dai sistemi
Global Positioning System (GPS).
2.2.2 Il sistema cartesiano
Il sistema di coordinate cartesiano e quello piu diffuso in ambiti generali.
Gli assi delle coordinate sono disposti perpendicolarmente tra loro e si in-
contrano in corrispondenza dell’origine. A seconda delle necessita, l’origine
puo essere posta in corrispondenza di un qualsiasi punto di riferimento.
Sull’asse x (ascissa) i valori di coordinata crescono generalmente da
sinistra a destra.
Sull’asse y (ordinate) crescono in base all’applicazione: da sotto a sopra
o da sopra a sotto. Nella computer grafica ad esempio l’origine corrisponde
2.2 Sistemi di coordinate 18
Fig. 2.3: Il sistema di coordinate WGS84.
Fig. 2.4: Il sistema di coordinate cartesiano.
all’angolo visualizzato in alto a sinistra. In questo caso i valori negativi non
sono accettabili poiche non corrispondono alla posizione di pixel. Questo
sistema di coordinate e rappresentato in Fig. 2.4.
2.2.3 Conversione di coordinate
Nel rappresentare dati geografici su uno schermo, nasce la necessita di
operare una conversione di coordinate da un sistema sferico, come il WGS84,
in un sistema piano come quello cartesiano. Esistono diversi metodi di
proiezione di coordinate ma tutti questi comportano inevitabilmente anche
una distorsione. Non esiste una proiezione migliore, tutte si caratterizzano
per una determinata “semplicificazione“, occorre quindi solo scegliere quella
piu adatta ad una determinata applicazione.
Gli obiettivi di massima da osservare per una proiezione sono:
2.2 Sistemi di coordinate 19
Fig. 2.5: Esempi di proiezione su solidi
♦ l’equidistanza;
♦ isogonalita, cioe il mantenimento degli angoli;
♦ equivalenza delle aree.
Le proiezioni si distinguono per il solido che funge da superficie di proiezione.
Pertanto esistono proiezioni a cilindro, a cono e a livelli, come mostra-
to in Fig. 2.5. Ad esempio una proiezione a cilindro non subisce distor-
sione in corrispondenza dell’equatore, mentre avra distorsione massima in
corrispondenza dei poli.
La proiezione utilizzata nelle mappe OpenStreetMap e quella di Merca-
tore.
La proiezione di Mercatore
La proiezione di Mercatore e una proiezione cartografica conforme e
cilindrica proposta nel 1569 dal geografo e cartografo fiammingo Gerard de
Cremer noto come Gerardus Mercator (italianizzato in Gerardo Mercatore).
La rappresentazione di Mercatore e uno sviluppo cilindrico diretto mod-
ificato da un procedimento misto geometrico-analitico che rende le carte
isogoniche (angoli uguali). Essa e diventata la proiezione cartografica piu
usata per le mappe nautiche per la sua proprieta di rappresentare linee di
costante angolo di rotta (linee lossodromiche) con segmenti rettilinei. Men-
tre la scala delle distanze e costante in ogni direzione attorno ad ogni punto,
conservando allora gli angoli e le forme di piccoli oggetti (il che rende la
proiezione conforme), la proiezione distorce sempre piu la dimensione e le
forme degli oggetti estesi passando dall’equatore ai poli, in corrispondenza
2.3 I servers WMS 20
Fig. 2.6: La proiezione di Mercatore.
dei quali la scala della mappa aumenta a valori infiniti (secondo un grigliato
delle latitudini crescenti).
Lo schema della proiezione e rappresentato in Fig. 2.6. Si puo vedere
come le proiezioni partono dal centro della terra passando per gli angoli
crescenti di latitudine fino ad intersecare la superficie di un cilindro. La
proiezione indicata con la linea rossa fuoriesce dal cilindro e pertanto non
puo essere considerata. Per questa ragione gli angoli di latitudine sono da
considerarsi da +85,0511◦ fino a -85,0511◦ (invece che da +90◦ a -90◦). La
mappa piana risultante da questo tipo di proiezione e illustrata in Fig. 2.7
2.3 I servers WMS
Per Web Map Service (WMS) si intende una specifica tecnica definita
dall’Open Geospatial Consortium atta a produrre mappe dinamiche di dati
spazialmente riferiti a partire da informazioni geografiche. Questo stan-
dard internazionale [4] definisce una mappa come la rappresentazione di
informazioni geografiche sottoforma di immagine digitale, idonea ad essere
visualizzata su browser web. Generalmente le mappe prodotte da un servizio
WMS sono rese in un formato immagine quale PNG, GIF o JPEG, occa-
2.3 I servers WMS 21
Fig. 2.7: Risultato della proiezione di Mercatore.
sionalmente come elementi vettoriali in formato Scalable Vector Graphics
(SVG) o Web Computer Graphics Metafile (WebCGM); contrariamente a
un Web Feature Service (WFS), che restituisce dati vettoriali, o a un Web
Coverage Service (WCS), che restituisce dati raster.
Lo standard definisce tre operazioni:
♦ restituisce metadati a livello di servizio;
♦ restituisce una mappa dai parametri geografici e dimensionali definiti;
♦ restituisce informazioni sugli oggetti della cartografia visualizzata (opzionale).
Le operazioni del Web Map Service vengono invocate usando un client
che supporti il protocollo HTTP, in forma di Uniform Resource Locators
(URL). Il contenuto dell’URL dipende dalle operazioni richieste. In partico-
lare, la composizione dell’indirizzo va fatta indicando quali informazioni de-
vono essere visualizzate sulla mappa, quale porzione della Terra deve essere
rappresentata, il sistema di coordinate desiderato, il formato e le dimensioni
dell’immagine di output.
Qualora due o piu mappe siano prodotte con gli stessi parametri ge-
ografici e di dimensione dell’immagine, i risultati possono essere sovrapposti
per produrre una mappa composita. L’uso di formati che supportano la
2.3 I servers WMS 22
trasparenza (GIF o PNG per esempio) permette di visualizzare le parti di
mappa sottostanti; inoltre mappe diverse possono essere richieste a differenti
server. In questa maniera il Web Map Service abilita la creazione di una rete
di server cartografici che l’utente puo utilizzare per costruire mappe person-
alizzate. Generalmente un Web Map Service non e invocato direttamente;
vengono utilizzate applicazioni client che forniscono all’utente controlli in-
terattivi. Queste applicazioni client possono anche non essere web-based.
La specifica WMS e diventata standard ISO19128 nel 2005.
2.3.1 Il progetto OpenStreetMap
L’OpenStreetMap e un progetto collaborativo finalizzato a creare mappe
mondiali a contenuto libero. La caratteristica fondamentale dei dati ge-
ografici presenti in OSM e che possiedono una licenza libera. E cioe possi-
bile utilizzarli liberamente per qualsiasi scopo con il solo vincolo di citare la
fonte e usare la stessa licenza per eventuali lavori derivati dai dati di OSM.
Le mappe sono create usando come riferimento i dati registrati da dis-
positivi GPS portatili, fotografie aeree ed altre fonti libere. Sia le immagini
renderizzate che i dati vettoriali, oltre che lo stesso database di geodati, sono
rilasciati sotto licenza Creative Commons Attribution-ShareAlike 2.0.
OpenStreetMap e stato ispirato da siti come Wikipedia. La comunita
collabora per integrare o modificare le mappe esistenti. Infatti ogni mappa
consultabile espone in evidenza l’etichetta Edit, per procedere alla mod-
ifica dei dati. Tutti gli utenti registrati possono caricare nei database del
progetto, le tracce GPS e modificare i dati vettoriali usando gli editor forniti.
2.3.2 I tiles
Servizi come Open Street Map, Google Maps o Yahoo! Map, forniscono
le mappe sottoforma di map tiles (piastrelle), cioe di immagini con una
dimensione fissa. Per ogni fattore di zoom, la mappa del globo e suddivisa
in un reticolo di tiles sempre piu fitto. Per il primo fattore di zoom, ad
esempio, l’intero globo e compreso in un unico tile. Ad ogni incremento di
questo fattore, il numero di tile cresce come il quadrato, secondo la regola
descritta in Tabella 2.1. La risoluzione della mappa quindi, e direttamente
proporzionale al livello di zoom.
2.3 I servers WMS 23
Fig. 2.8: Una mappa con zoom differenti. Ad un incremento dello zoom itiles si quadruplicano.
Grazie a questa suddivisione delle mappe, e sufficiente scaricare dal server
solo la porzione di mappa che ci interessa. Questa porzione viene calcolata
dal client in base alla posizione che vogliamo visualizzare e allo zoom. La
richiesta e formulata sottoforma di indirizzo HTTP ad uno specifico server.
Per i server OSM, ad esempio, la richiesta di un tile allo zoom 16 assume
questa forma:
http://tile.openstreetmap.org/16/34271/22224.png
grado Zoom num. Tiles
0 1
1 2 x 2
2 4 x 4
n 2n x 2n
Tabella 2.1: Numero di tiles per fattore di zoom
2.3.3 Trasformazione di coordinate
La proiezione di Mercatore, utilizzata dal servizio OpenStreetMap, trasfor-
ma le coordinate geografiche in coordinate cartesiane bidimensionali. Queste
coordinate cartesiane sono espresse in pixel, poiche sono riferite alle immag-
ini tiles che costituiscono la mappa da visualizzare [9].
La longitudine va trasformata nella coordinata x mentre la latitudine
nella coordinata y. Il range di variazione della longitudine va da -180◦ a
+ 180◦, pertanto la trasformazione comporterebbe valori negativi di pixel.
2.3 I servers WMS 24
Per evitare cio e necessario shiftare tutto l’intervallo di longitudine di 180◦.
Pertanto la longitudine andra da 0 a 360◦. La regione R di variazione della
coordinata x, dove sono proiettate le coordinate Cartesiane assolute, dipen-
dono dal livello di zoom che andiamo a considerare. Per uno zoom pari a
2, la terra e rappresentata da un reticolo di 2*2 tiles. Dato che ogni tile ha
dimensione pari a 256 pixel, la regione R avra dimensione pari a 512*512
pixel.
La longitudine varia linearmente, quindi la coordinata x si ricava con la
formula:
x =λ+ 180◦
360◦∗R; con R = 2z ∗ t
dove λ= longitudine in gradi, R=range in pixel, z=livello di zoom,
t=dimensione singolo tile in pixel.
La latitudine varia da -85,0511◦ a + 85,0511◦. Dato che i tiles sono
quadrati, la coordinata y e mappata sullo stesso range R in pixel della
longitudine. La coordinata y si ricava dalla formula:
y =1− (
log(tan(π4+ϕ
2))
π)
2∗R; con R = 2z ∗ t
dove ϕ= longitudine in gradi, R=range in pixel, z=livello di zoom,
t=dimensione singolo tile in pixel.
Capitolo 3
Il Public Lighting Manager
L’applicazione Public Lighting Manager e stata progettata per operare in
uno scenario come quello rappresentato in Fig. 3.1. In fase di installazione
di una nuova rete pubblica di illuminazione, o in caso di adeguamento di
una rete esistente, vengono catalogati, mediante dispositivi portatili (PDA
o tablet) connessi alla rete, i dati dei singoli lampioni. Per ciascun apparato
sono registrati su un database remoto, le informazioni sulla locazione urbana,
la posizione GPS, i dati tecnici e l’indirizzo seriale. L’applicazione P.L.M.,
preleva questi dati dal database, e ricostruisce graficamente la disposizione
della rete d’illuminzione sulla mappa. Mediante l’interfaccia grafica, sem-
plice ed intuitiva, l’operatore puo selezionare ed inviare comandi di gestione
ai lampioni, sia singolarmente che per gruppi.
Nei paragrafi successivi illustreremo il funzionamento dell’applicazione
P.L.M, nei suoi aspetti principali.
3.1 L’interfaccia
L’interfaccia del P.L.M. presenta una grafica semplice ed intuitiva. L’uso
pertanto e immediato, anche per utenti non specializzati. Inoltre, la grafica
adottata si presta bene ad un successivo porting su dispositivi portatili con
touch-screen.
In Fig. 3.2 e mostrata la schermata che si presenta all’utente dopo l’avvio
dell’applicazione e la connessione ad un database.Si possono distinguere sei
zone:
1. Menu
25
3.1 L’interfaccia 26
Fig. 3.1: Scenario in cui opera il Public Lighting Manager
2. Barra degli strumenti
3. Vista mappa
4. Pannello filtro
5. Vista elenco
6. Barra di stato
Illustriamo nel dettaglio il loro utilizzo.
3.1.1 Menu
Nel menu sono raccolte tutte le funzioni dell’applicazione: dalla gestione
del database, alla modalita di visualizzazione. E’ composto dai seguenti
elementi:
• File: gestione della connessione ad database e operazioni generali del-
l’applicazione.
3.1 L’interfaccia 27
Fig. 3.2: Interfaccia grafica del P.L.M.
• Lamp: operazioni inerenti i lampioni (inserimento, eliminazione, mod-
ifica, ecc.).
• View: opzioni riguardanti le preferenze di visualizzazione.
• Help: accesso alla guida e alle informazioni generali sull’applicazione
P.L.M.
3.1.2 Barra degli strumenti
La barra degli strumenti e composta da una serie di pulsanti che perme-
ttono di accedere alle funzioni principali mediante un semplice click. Con
riferimento alla Fig. 3.3, la barra e suddivisibile come descritto di seguito:
(a) pannello database: funzioni di connessione ad un nuovo database,
apertura di file di connessione, chiusura connessione e modifica delle
voci del database.
(b) pannello mappa: funzioni di zoom in e zoom out, drag della mappa e
selezione rettangolare.
(c) pannello lamp: funzioni di inserimento di una nuova lamp, modifica,
eliminazione, accensione, spegnimento e richiamo delle informazioni.
3.1 L’interfaccia 28
(a) (b) (c)
Fig. 3.3: Pannelli degli strumenti
(a) (b) (c)
Fig. 3.4: Rappresentaizione dei lampioni:(a) stato off; (b) stato on; (c)stato di warning.
Questi pannelli si trovano tutti sul lato superiore della mappa, ma durante la
sessione possono essere spostati ai lati della mappa mediante trascinamento
con il mouse.
3.1.3 Vista mappa
In questa zona viene visualizzata la mappa OSM. Essa e navigabile medi-
ante trascinamento con il mouse (in modalita drag) e zoommabile mediante
i pulsanti sopra descritti. La mappa e composta da due livelli sovrapposti:
1. livello mappa: e sempre visibile e mostra il materiale offerto dal server
OSM
2. livello lamps: mostra la dislocazione dei lampioni sula mappa. Questi
sono rappresentati nell’attuale stato, con le icone in Fig. 3.4. Questo
livello puo essere nascosto impostando il flag nel menu View
Cliccando sulle icone, e possibile selezionare una o piu lamps.
Cliccando con il tasto destro sulla mappa, viene aperto il menu con-
testuale relativo alle lamps gia selezionate.
3.1.4 Pannello filtri
Il pannello filtri opera sulla vista elenco (Par. 3.1.5). Si possono applicare
fino a tre regole che devono essere rispettate contemporaneamente. Per
instruzioni sull’utilizzo si veda il Par. 3.3.3.
3.2 Gestione database 29
3.1.5 Vista elenco
Oltre alla vista su mappa, l’applicazione elenca le lamps in forma tabel-
lare. La vista elenco permette una rapida visione di tutti i lampioni instal-
lati. L’elenco puo essere ordinato cliccando sull’header dei campi desiderati.
E’ possibile inoltre selezionare una o piu lamps cliccando sulla rispettiva
riga.
Cliccando con il tasto destro sull’elenco, viene aperto il menu contes-
tuale relativo alle lamps gia selezionate.
I campi da visualizzare sono impostati attraverso il menu View->Table
Column mentre l’intera tabella puo essere nascosta agendo sul flag Show
Table.
3.1.6 Barra di stato
Nella barra di stato appaiono, sulla sinistra, i messaggi dell’applicazione
in risposta dei comandi impartiti dall’utente e i tool tip mentre sulla destra
sono sempre visibili le coordinate attuali (riferite alla croce al centro dello
schermo) e il livello di zoom corrente.
3.2 Gestione database
Come illustrato in Fig. 3.1, il software P.L.M. legge i dati relativi ai
lampioni da un database esterno, che puo essere raggiunto attraverso la rete
internet o attraverso una rete locale. Da questi dati ne ottiene un model,
ossia una copia temporanea dei record che servono per poter rappresentare
i lampioni e per poterli indirizzare.
Lo schema del database e di tipo “relazionale” ed e riportato in Fig. 3.5.
La flessibilita di questa particolare struttura, permette all’utente finale di
integrare il database non solo di nuove lamps, ma anche di nuovi “attributi”
per queste, senza limite alcuno. La modifica del database sara trattata nei
prossimi paragrafi.
3.2.1 Avviare una nuova connessione
Cliccando su ( File > New Connection) si apre all’utente la finestra
di dialogo in Fig. 3.6 con i seguenti campi:
3.2 Gestione database 30
Lampslampioni
id int
longitude double
latitude double
streetId intforeign key
groupId intforeign key
bodyId intforeign key
bodyDate date
bulbId intforeign key
bulbDate date
operatorId intforeign key
address varchar
Groupsgruppi
id int
groupName varchar
Streetsstrade
id int
streetName varchar
Bulbslampade
id int
bulbName varchar
Operatorsoperatori
id int
operatorName varchar
Bodiesstrutture
id int
bodyName varchar
bodyImage BLOB
n
1
n1
n
1n
1
n
1
Fig. 3.5: Struttura del database
Fig. 3.6: Finestra di dialogo per una nuova connessione
• Host Name: l’indirizzo IP del database in rete. Nel caso si utilizzi un
database locale questo valore e localhost ;
• User Name: l’utente con i diritti di lettura e scrittura del database;
• Password: parola segreta per l’accesso;
• Database Name: un server puo contenere piu database, occorre quindi
specificare il nome al quale si fa riferimento.
Compilati i campi si puo decidere se salvare la connessione in un file XML
( Save), in modo da non doverli reinserire successivamente, o se procedere
con la connessione al database ( Connect).
3.2 Gestione database 31
3.2.2 Aprire un file di connessione
Il pulsante ( File > Open connection file) permetter di aprire una
connessione salvata su file XML.
Il file di connessione deve avere la seguente struttura:
<PLAdmin i s t ra to r>
<Database> Nome d e l da tabase </Database>
<Pass> Password </Pass>
<User> Nome u t en t e </User>
<Host> I n d i r i z z o hos t </Host>
</PLAdmin i s t ra to r>
L’applicazione verifica prima la presenza del root tag <PLAdministra-
tor>, in tal caso procede con lo scaricamento dei dati, altrimenti restituisce
un messaggio di errore.
3.2.3 Modifica database
L’editor del database consente di aggiungere, eliminare o modificare tutte
le voci del database. Si puo accedere al database editor cliccando su (
File > Database editor). La finestra e composta da piu widget, accessibili
facendo click sulle icone a sinistra.
Scheda Lamps
In questa scheda (Fig. 3.7(a)) e possibile inserire una nuovo lampione a
coordinate da specificare. Ad ogni lampione e associata una serie di infor-
mazioni come la strada ove e ubicato ( Street), a quale gruppo appartiene
( Group), su che tipo di supporto e montato ( Body Type) e in che data e
stato installato( Body Date), che tipo di lampada monta ( Bulb Type) e la
data dell’ultima sostituzione ( Bulb Date), l’operatore che ha effettuato le
ultime modifiche ( Operator) ed infine l’indirizzo in formato esadecimale del
lampione ( Digital Address). Parte di queste informazioni vengono scelte at-
traverso menu a tendina, le cui voci vengono prelevate da tabelle relazionate,
che possono essere editate dalle schede seguenti.
3.2 Gestione database 32
(a) (b)
Fig. 3.7: Schede (a)“Lamps” e (b)“Groups”
Scheda Groups
La definizione di un “group” ha lo scopo di facilitare la selezione di
un insieme di lamps che rispondono a determinate caratteristiche definite
dall’utente. Si possono ad esempio definire gruppi in base all’ubicazione
(quartiere o zona), oppure in base alle caratteristiche di sezionamento della
linea elettrica.
Per aggiungere un “group” (Fig. 3.7(b)) specificarne il nome ( Name) e
cliccare sul pulsante Add.
Per modificare un “group”, effettuare doppio click sulla riga e cliccare su
Save, per eliminarlo selezionare la riga e cliccare su Delete.
Scheda Streets
E’ l’elenco delle strade dove sono ubicate le lamps. Conoscere la “vi-
a” di ubicazione di un lampione, ne permette la rapida localizzazione nel
sistema urbano. Inoltre, grazie alle funzioni che vedremo piu avanti, tale in-
formazione ci permettera di selezionare tutti gli apparati situati nella stessa
strada.
Per aggiungere una“street” (Fig. 3.8(a)) specificarne le tipologia ( Type),
il nome ( Name). e cliccare sul pulsante Add.
Per modificare una “street”, effettuare doppio click sulla riga e cliccare
su Save, per eliminarla selezionare la riga e cliccare su Delete.
3.2 Gestione database 33
(a) (b)
Fig. 3.8: Schede (a)“Streets” e (b)“Bodies”
Scheda Bodies
Elenco delle strutture dei lampioni. Oltre alla sigla body name, puo
essere associata una immagine che presenta graficamente all’utente il fattore
di forma del lampione.
Per aggiungere una struttura (Fig. 3.8(b)) specificarne il nome ( Name)
e cliccare sul pulsante Add.
Per caricare una immagine inserire il percorso del file nel campo Image...
Per modificare un “body”, effettuare doppio click sulla riga e cliccare su
Save, per eliminarlo selezionare la riga e cliccare su Delete.
Scheda Bulbs
Elenco dei diversi tipi di lampade utilizzate. In base alle diverse neces-
sita di illuminazione possono essere utilizzate tecnologie differenti (lampade
LED, a scarica, alogene ecc.). In sviluppi futuri, questa specifica sara utile
per diversificare il controllo software delle lampade.
Per aggiungere una lampada (Fig. 3.9(a)) specificarne il nome ( Name),
la potenza in watt ( Power) e cliccare sul pulsante Add.
Per modificare un “bulb”, effettuare doppio click sulla riga e cliccare su
Save, per eliminarlo selezionare la riga e cliccare su Delete.
3.3 Selezione e filtraggio 34
(a) (b)
Fig. 3.9: Schede (a)“Bulbs” e (b)“Operators”
Scheda Operators
In un contesto dove un gruppo di operatori lavora sulla stessa linea,
puo essere utile conoscere quale tecnico ha operato l’ultimo intervento sul
lampione.
Per aggiunger un nuovo operatore (Fig. 3.9(b)) specificarne nome e cog-
nome ( Name, Surname) e cliccare su Add.
Per modificare un “operator”, effettuare doppio click sulla riga e cliccare
su Save, per eliminarlo selezionare la riga e cliccare su Delete.
3.2.4 Chiusura della connessione
Il pulsante ( File > Close connection file) disconnette l’applicazione
dal database. In questo caso sia la vista mappa che la vista elenco vengono
“pulite” dalle lamps Questo comando viene eseguito automaticamente anche
nel caso in cui ci si avvii una nuova connessione.
3.3 Selezione e filtraggio
In un uso “a regime”, e facile pensare che ci si possa trovare a gestire
una rete di illuminazione pubblica molto vasta, con un numero di lampioni
nell’ordine delle migliaia di unita. Assume quindi particolare importanza
3.3 Selezione e filtraggio 35
Fig. 3.10: Scheda “Operators”
l’utilizzo di strumenti che permettano di operare la selezione delle lamps in
modi diversi, secondo le varie necessita.
3.3.1 Selezione da mappa
Questa selezione viene effettuata mediante la vista mappa. In modalita
Move map ( ) e possibile selezionare un lampione cliccando sul simbolo
all’interno della mappa. Selezioni multiple sono possibili tenendo premuto il
tasto Ctrl e facendo click sulle lamp desiderate. In modalita Rect selection
( ) i lampioni possono essere selezionati tracciando un rettangolo sulla
zona scelta. I lampioni all’interno del rettangolo vengono cosı selezionati.
La procedura di deselezione funziona secondo lo stesso principio.
3.3.2 Selezione da tabella
In tabella appaiono tutti i lapioni sottoforma di elenco. La selezione si
puo effettuare cliccando su una riga della tabella. Tenendo premuto il tasto
sinistro e muovendo il mouse e possibile selezionare record contigui. Per
selezioni multiple discontigue, invece, e sufficiente tenere premuto il tasto
Ctrl e cliccare sui record desiderati. Puo essere utile, ai fini della selezione,
ordinare l’elenco delle lamps in base ai valori di un determinato campo; per
3.4 Invio comandi 36
Fig. 3.11: Strumento di selezione in base a filtro
fare cio basta cliccare sugli header della tabella e procedere con la selezione.
La procedura di deselezione funziona secondo lo stesso principio.
3.3.3 Selezione con filtro
Lo strumento filtro (Fig. 3.11) permette di selezionare le lamps mediante
l’impostazione di determinate regole, che devono essere rispettate contem-
poraneamente. E’ possibile selezionare per gruppo ( Group), per strada (
Street) o per il tipo di lampada ( Bulb).
I filtri vengono attivati cliccando sul Radio Button Filter o Select; nel
primo caso vengono elencati solo i lampioni che rispettano le regole selezion-
ate, nel secondo caso vengono mostrati tutti i lampioni ma sono selezionati
solo quelli che rispettano le regole selezionate.
3.4 Invio comandi
Al momento del primo rilascio dell’applicazione, non esiste ancora una
interfaccia hardware definita, pertanto i comandi di output sono simulati e
limitati all’accensione e allo spegnimento delle lamps.
I comandi si applicano ai lampioni selezionati, pertanto prima di inviare
un comando occorre selezionare una o piu lamps secondo i metodi descritti
nei paragrafi precedenti.
Il comando di accensione viene inviato cliccando il pulsante , mentre
il comando di spegnimento viene inviato cliccando su . Ad ogni comando
le icone dei lampioni cambiano in base al nuovo stato.
3.4 Invio comandi 37
Tutte le operazioni di output pengono tracciate sul file di log log file.txt.
Capitolo 4
Implementazione software
L’applicazione Public Lighting Manager e stata sta scritta in linguag-
gio C++, mediante Qt Creator IDE ver.2.0.1, un potente ambiente di
sviluppo integrato e multipiattaforma, basato sul framework Qt ver.4.7.0
(32 bit), il tutto sotto sistema operativo Linux Ubuntu 10.010.
Nei capitoli successivi illustreremo il principio di funzionamento e l’im-
plementazione in codice, focalizzando l’attenzione sulle classi principali e le
routine piu importanti.
4.1 Gestione della mappa
Il sottoprogetto QMapControl implementa una widget per la gestione e
la visualizzazione delle mappe. E’ basato su un progetto open-source [12] e
opportunamente modificato per incontrare le necessita del nostro progetto.
La widget offre diverse peculiarita:
• e compatibile con diversi map provider ;
• si possono creare oggetti personalizzati da rappresentare nella mappa;
• gli oggetti possono essere posizionati a qualsiasi coordinata;
• la navigazione della mappa e personalizzabile.
In questo contesto analizzeremo le caratteristiche principali che hanno
riguardato il nostro progetto, mentre per una spiegazione piu dettagliata si
rimanda al sito dello sviluppatore.
38
4.1 Gestione della mappa 39
4.1.1 Struttura di QMapControl
Come abbiamo visto nel paragrafo precedente la widget che andiamo a
considerare deve essere in grado di rappresentare allo stesso tempo la mappa
fornita da un opportuno provider, nel nostro case OpenStreetMap, ed inoltre
degli oggetti su di essa, che devono poter essere spostati senza variare la loro
posizione in relazione alla mappa. La realizzazione pertanto si avvale di una
struttura a livelli (layer).
Classe MapControl: e la classe principale, la widget vera e propria. Qui
vengono istanziati i vari layer ed implementati i controlli necessari, come
ad esempio il panning delle mappe. Un oggetto MapControl deve essere
istanziato passando come parametro un QSize che impone le dimensioni
della widget in un certo layout. Queste saranno le dimensioni di riferimento
di tutti i layer istanziati, e quindi della mappa stessa.
Classi Geometry: sono gli oggetti che possiamo rappresentare sulla map-
pa. La classe Geometry implementa i metodi di base di tutti gli oggetti. Da
questa vengono derivate le classi Point e Light.
Classi Layer: sono i livelli che compongono la mappa. Ci sono due tipi di
layer: GeometryLayer eMapLayer, ma entrambi condividono gli stessi metodi.
ClasseMapAdapter: e una classe astratta e fornisce l’interfaccia dei meto-
di necessari alla widget, che dovranno essere implementati in modo diverso
a seconda dei server WMS che verranno utilizzati. In questo progetto viene
utilizzato il servizio OpenStreetMap, quindi le uniche classi derivate saranno
la TileMapAdapter, che gestisce l’elaborazione delle richieste ai tiles server e
la classe OSMMapAdapter, specifica per i server OperStreetMap.
4.1.2 Le geometrie
Le caratteristiche delle geometrie utilizzate nelle mappe, e i metodi da
esse supportate, sono specificate nelle Simple Feature Specification dell’Open
Geospatial Consortium [7]. La classe base, Geometry, implementa i metodi
comuni a tutte le geometrie. Da questa vendono derivate classi via via piu
complesse, che aggiungono nuovi metodi a quelli della classe base.
In questa tesina ci siamo limitati all’utilizzo delle classi Point e Light.
Mentre la prima fa parte del progetto originale del QMapControl, la seconda,
che rappresenta l’oggetto “lampione” sulla mappa, e stata implementata ad
hoc per rispondere alle necessita del presente progetto.
4.1 Gestione della mappa 40
Classe Geometry
Contiene sia metodi esplicitati che metodi virtual, da implementare nelle
sottoclassi. Elenchiamo i piu importanti:
• parentGeometry(): in caso di oggetti derivati, restituisce un puntatore
all’oggetto “padre” altrimenti un puntatore a se stesso;
• setVisible(bool visible): imposta il flag di visibilita, ;
• boundingBox(): metodo virtuale, restituisce un oggetto di tipo QRect,
con le dimensioni del rettangolo che contiene la geometria (Bounding
Box ).
Di particolare importanza e il segnale geometryClicked(), che viene emes-
so quando l’utente clicca all’interno della bounding box di un oggetto. Un
oggetto e cliccabile se il layer che lo contiene e cliccabile.
Classe Point
Un Point e una Geometry dotato di coordinate geografiche. Questa classe
puo essere utilizzata anche per disegnare una QPixmap, o una QWidgets, in
un determinato punto, basta chiamare il relativo costruttore.
Quando si disegna una pixmap, occorre tener presente che si sta aggiun-
gendo il punto in una GeometryLayer. E possibile aggiungere un punto anche
ad una MapLayer, ma questo dovrebbe essere fatto solo se il punto mantiene
costante la sua posizione. Infatti mentre il GeometryLayer viene ridisegna-
to ad ogni cambiamento del punto, il MapLayer viene ridisegnato sono in
corrispondenza della modifica della finestra principale (viewport).
Per una immagine o una widget sono possibili diversi allineamenti rispet-
to al punto specificato. La Fig. 4.2 mostra le diverse possibilita.
La classe Point permette di scalare l’immagine associata in base allo
zoom. Per fare cio, occorre impostare con il metodo setBaseLevel() il fat-
tore di zoom in corrispondenza del quale l’immagine deve avere le dimen-
sioni originali. Per altri fattori di zoom l’immagine verra cosı ingrandita o
rimpicciolita automaticamente (Fig. 4.1).
I metodi setMinSize() e setMaxSize() permettono di impostare valori di
massima e di minima dimensione per i pixmap o le widget associate al point,
per evitare ad esempio che a bassi livelli di zoom le immagini non siano piu
visibili.
4.1 Gestione della mappa 41
Fig. 4.1: Zoom di una geometria
Fig. 4.2: Allineamento di una geometria
Il metodo Touches() restituisce un valore booleano a seconda che il punto
passato in argomento tocchi o meno il punto della classe. Se al punto e
associata una pixmap, il controllo della collisione avviene considerando la
bounding box della figura.
Classe Light
La classe Light e una sottoclasse di Point, che abbiamo introdotto al
progetto originale QmapControl, per la rappresentazione dei lampioni sulla
mappa. Ogni Light e identificato da un numero intero ( id), che corrisponde
all’indice della chiave primaria del lampione nel database. In questo modo
si assicura la corrispondenza degli oggetti grafici sulla mappa con i record
del database.
La classe implementa quattro metodi che sono anche slot:
• getId(), restituitsce l’identificativo del lampione.
• setOnState(bool), imposta lo stato on/off per il lampione. In base
allo stato, la pixmap associata viene cambiata con l’immagine di un
lampione acceso o spento.
4.1 Gestione della mappa 42
• SetWarningState(bool) imposta lo stato di warning per il lampione.
In caso di warning positivo, il lampione viene rappresentato da una
pixmap con un punto interrogativo, a segnalare lo stato anomalo.
Questo stato ha priorita sullo stato on/off.
• setToMove(bool), viene chiamato quando l’utente vuole modificare la
posizione del lapione sulla mappa.
4.1.3 I livelli
La visualizzazione delle mappe nella widget QMapControl e organizzata
in livelli (detti anche layers). Ci sono due tipi di layer, i MapLayer e i
GeometryLayer. I primi possono visualizzare contenuti statici, come mappe,
ma anche geometrie, i secondi possono rappresentare solo le geometrie. La
differenza sta nella modalita con cui questi layer vengono aggiornati: mentre
gli oggetti appartenenti ad una GeometryLayer vengono ridisegnati ogni volta
che cambiano posizione, gli oggetti appartenenti ad un MapLayer vengono
ridisegnati solo in corrispondenza dell’aggiornamento dell’intera schermata
(offscreen).
Per il resto le due classi hanno gli tessi metodi, ereditati dalla classe
madre Layer. I metodi pubblici addGeometry() e removeGeometry() sono
utilizzati nella gestione delle geometrie del layer, mentre lo slot setVisible()
ne impone la visibilita.
Il segnale geometrySelect(int ID) viene emesso quando viene selezionato,
mediante click, l’oggetto con indice ID appartenente al layer.
Ogni livello e contraddistinto da un nome e tutti sono gestiti dalla classe
LayerManager. Questa classe conserva tutti i parametri necessari alla rapp-
resentazione delle mappe. Le coordinate del centro della finestra, le misure
dell’area visibile all’utente e il livello di zoom. Le misure dell’area visibile
(offscreenViewport) possono essere espresse in coordinate cartesiane o in
coordinate di proiezione. Le coordinate di proiezione sono le coordinate in
pixel relative allo specifico zoom. La widget principale fa riferimento a ques-
ta classe per variare il modo di rappresentazione della mappa, chiamandone
i relativi metodi. A sua volta LayerManager passa questi comandi a tutti i
layer presenti.
Quando si istanzia un nuovo Layer, occorre passare al costruttore il pun-
tatore ad un MapAdapter, che regola la conformita del layer con il servizio
4.1 Gestione della mappa 43
di mappe online. La classe MapAdapter verra illustrata nel prossimo para-
grafo.
4.1.4 Richiesta dei Tiles
La classe MapAdapter permette alla widget di generare nel formato cor-
retto, la richiesta dei dati cartografici per diversi servers.
Da MapAdapter vengono pertanto derivate due sottoclassi:
• TileMapAdapter, che dialoga con servers basati su immagini tiles, come
OpenStreetMap o Google Maps;
• WMSAdapter, che dialoga con servers di tipo WMS.
La classe TileMapAdapter implementa la conversione di coordinate, sec-
ondo la procedura vista nel Par.2.3.3. Queste operazioni sono necessarie per
formulare correttamente la richiesta di nuovi tiles, per una data posizione e
per un dato fattore di zoom. L’interrogazione del server avviene mediante
protocollo HTTP, componendo una stringa del tipo:
http://tile.openstreetmap.org/%1/%2/%3.png
I caratteri %1, %2, e %3 sono dei “segnaposti” che grazie alla funzione
query(int x,int y,int z) vengono sostituiti con opportuni valori:
• %1 rappresenta lo zoom, indicato come numero intero (da 0 a 18 per
server OSM);
• %2 coordinata x del tile (da 0 a 2z − 1, con z=fattore zoom);
• %3 coordinata y del tile (da 0 a 2z − 1, con z=fattore zoom).
Le coordinate dei tiles, per fattori di zoom da 0 a 3, sono rappresentate
in Fig. 4.3.
L’indirizzo dell’host e il formato della richiesta per un certo server,
vengono fornite dalle sottoclassi di TileMapAdapter. Per il server Open-
StreetMap viene utilizzata la classe OSMMapAdapter.
4.2 Struttura del progetto 44
Fig. 4.3: Ccoordinate dei tiles, per fattori di zoom 1,2 e 3
4.2 Struttura del progetto
In questo paragrafo andiamo ad elencare i file che compongono il progetto
P.L.M.
• pladministrator.cpp: e la classe principale, l’applicazione vera e pro-
pria. Qui sono implementate le funzioni principali dell’interfaccia che
illustreremo nei prossimi paragrafi;
• combodelegate.cpp: e qui implementata l’omonima classe, utilizzata
come delegate del mapper in LampPage (vedi Par.??), per l’indiciz-
zazione corretta delle voci;
• conndialog.cpp: finestra di dialogo per aprire una nuova connessione
ad un database.
• dbmanager.cpp: finestra di dialogo che riunisce una serie di widget (
QStackWidget), implementate nel file pages.cpp, per la gestione del
database dei lampioni.
• pages.cpp: l’insieme delle widget utili all’editing del database. Qui
sono implementate tutte le operazioni di inserimento, modifica e can-
cellazione dei record. Inoltre sono specificate le funzioni utili a man-
tenere l’integrita del database.
• dialogs.cpp: qui sono implementate le finestre di dialogo per la modi-
fica/visualizzazione delle lamps.
• main.cpp: classe per l’avvio dell’applicazione.
4.3 Database 45
• proxymodel.cpp: questa classe incapsula un modello predefinito, ma
stabilisce delle regole per la visualizzazione dei record.
4.3 Database
La struttura del database e rappresentata in Fig. 4.4. Secondo lo schema
classico dei database relazionali, alcuni campi della tabella principale Lamps,
sono costituiti dalle chiavi dei valori di tabelle “attributi”. Questa caratter-
istica permette di aggiornare ed integrare gli attributi secondo le necessita
dell’utente finale, in modo illimitato e flessibile.
Le istruzioni SQL che realizzano questa struttura sono le seguenti:
CREATE TABLE IF NOT EXISTS streets (
id INT NOT NULL AUTO_INCREMENT ,
streetName VARCHAR(40) UNIQUE,
PRIMARY KEY (id))ENGINE=InnoDB);
CREATE TABLE IF NOT EXISTS groups (
id INT NOT NULL AUTO_INCREMENT ,
groupName VARCHAR(40) UNIQUE,
PRIMARY KEY (id))ENGINE=InnoDB);
CREATE TABLE IF NOT EXISTS bodytype (
id INT NOT NULL AUTO_INCREMENT ,
bodyName VARCHAR(40) UNIQUE,
bodyImage BLOB,
PRIMARY KEY (id))ENGINE=InnoDB);
CREATE TABLE IF NOT EXISTS bulbtype (
id INT NOT NULL AUTO_INCREMENT ,
bulbName VARCHAR(40) UNIQUE,
PRIMARY KEY (id))ENGINE=InnoDB);
CREATE TABLE IF NOT EXISTS operators (
id INT NOT NULL AUTO_INCREMENT ,
operatorName VARCHAR(40) UNIQUE,
PRIMARY KEY (id))ENGINE=InnoDB);
4.3 Database 46
CREATE TABLE IF NOT EXISTS lamps (
id INT NOT NULL AUTO_INCREMENT ,
latitude DOUBLE,
longitude DOUBLE,
streetId INT ,
groupId INT ,
bodyId INT ,
bodyDate DATE NOT NULL,
bulbId INT ,
bulbDate DATE NOT NULL,
operatorId INT ,
address VARCHAR(40),
PRIMARY KEY (id),
FOREIGN KEY (streetId) REFERENCES streets(id),
FOREIGN KEY (groupId) REFERENCES groups(id),
FOREIGN KEY (bodyId) REFERENCES bodytype(id),
FOREIGN KEY (bulbId) REFERENCES bulbtype(id),
FOREIGN KEY (operatorId) REFERENCES operators(id)
)ENGINE=InnoDB);
Queste istruzioni sono invocate nella routine dbConnect(), che vedremo
nel dettaglio piu avanti.
4.3.1 Connessione
Come abbiamo visto nel capitolo precedente, l’utente puo scegliere se
specificare una nuova connessione o aprire un file contentente i parametri di
una connessione salvata.
Nal primo caso la funzione newConenction istanzia un nuovo oggetto della
classe ConnDialog, presente nell’omonimo file. Si tratta di una finestra di
dialogo dove inserire i quattro parametri necessari:
• Database Name;
• Password;
• User Name;
4.3 Database 47
Lampslampioni
id int
longitude double
latitude double
streetId intforeign key
groupId intforeign key
bodyId intforeign key
bodyDate date
bulbId intforeign key
bulbDate date
operatorId intforeign key
address varchar
Groupsgruppi
id int
groupName varchar
Streetsstrade
id int
streetName varchar
Bulbslampade
id int
bulbName varchar
Operatorsoperatori
id int
operatorName varchar
Bodiesstrutture
id int
bodyName varchar
bodyImage BLOB
n
1
n1
n
1n
1
n
1
Fig. 4.4: Struttura del database
• Host Address.
Se i dati inseriti sono validi viene chiamata la funzione connectPLA().
connDialog implementa anche la funzione Save, che permette di salvare
i parametri inseriti in un file XML. Le librerie Qt offrono una opportuna
API per la lettura/scrittura di file XML. In questo caso e utilizzata una
interfaccia DOM (Document Object Model), per creare una struttura ad
albero con i tag specificati dall’utente. L’“albero“ cosı creato viene salvato
su file mediante uno stream di testo ( QTextStream).
La funzione openConnectionFile(), viene invocata nel caso in cui l’utente
scelga di aprire un file di connessione salvato. L’interfaccia DOM converte
il documento XML nella struttura ad albero corrispondente. La funzione
riconosce la radice nel tag <PLAdministrator>, ed individia i nodi “figlio”
che contengono i campi necessari alla connessione, quindi viene chiamata la
funzione connectPLA.
4.3 Database 48
Funzione dbConnect
Questa funzione e quella che avvia la connessione vera e propria al
database. Il modulo QtSql fornisce una efficiente interfaccia per l’accesso
a diversi tipi di database SQL.
Un nuovo oggettoQSqlDatabase viene creato grazie al metodo addDatabase(),
specificando quale driver utilizzare per la connessione: nel nostro casoQMYSQL.
Impostati le credenziali d’accesso, il metodo open() stabilisce, di fatto,
la connessione.
In questa funzione vengono create le tabelle del database necessarie,
qualora non fossero gia presenti. Il metodo exec() dell’oggetto QSqlQuery
esegue le opportune query viste nel paragrafo precedente.
In caso di successo la funzione dbConnect() restituisce un valore booleano
true
Funzione connectPLA()
La routine ha il compito di avviare tutte le procedure per la visualiz-
zazione dei dati, in seguito ad una avvenuta connessione.
Le chiamate a initializeModel() e initializeView(), istanziano l’architettura
model/view (vedi Par 4.4).
L’interfaccia viene divisa, mediante nuovo oggetto QSplitter, cosı da per-
mettere la visualizzazione tabellare delle lamps (funzione createListGroup-
Box()). Vengono qui create anche le opportune connessioni signal/slot, per il
corretto interfacciamento della tabella con il resto dell’applicazione (funzione
createConnection()).
Ottenuti i dati dal database non rimane che graficare sulla mappa le
lamps, in base alla loro geolocalizzazione. Questo compito e realizzato dalla
funzione drawLamps().
La lettura dello stato attuale dei lampioni, con la conseguente modifica
dell’icona sulla mappa, viene effettuata da due funzioni: readStatusLamps()
che legge da un file txt esterno lo stato on/off dei lampioni e da read-
WarningLamps() che legge da un file txt esterno quali lampioni presentano
anomalie o malfunzionamenti.
4.3 Database 49
Funzione disconnectPLA()
Questa funzione puo essere invocata manualmente dall’utente mediante
il comando Close Connection, oppure automaticamente quando si avvia una
nuova connessione. L’effetto della procedura infatti e quello di salvare lo sta-
to delle lamps(funzione saveStatusLamps()), cancellare le variabili di stato
di queste ( warningLamps, turnedOnLamps), resettare sia model che prox-
yModel e chiudere la connessione ad database (metodi removeDatabase() e
close()).
4.3.2 Database Editor
La classe DBManager, implementa l’interfaccia di modifica del database.
Si tratta di una finestra di dialogo (sottoclasse di QDialog) strutturata come
una QStackedWidget, ossia un insieme widget o pages, che vengono visualiz-
zate all’interno della stessa finestra. Si puo passare da una widget all’altra
mediante un sistema di icone.
Ogni page rappresenta una tabella del database. Il costruttore DBMan-
ager() istanzia quindi le sei widget e ne organizza la paginazione.
Esso riceve come argomento un puntatore al model principale, che a sua
volta verra passato alle pages. Secondo il concetto dell’architettura MVC
infatti, le modfiche al database passano per la modifica del model associato.
Gli unici metodi della classe DBManager sono createIcons() e changePage(),
che definiscono la navigazione tra widget attraverso le icone associate.
Nel file pages.cpp sono implementate le sei widget dell’editor:
• LampPage: widget per i lampioni;
• GroupPage: widget per i gruppi
• StreetPage: widget per l’elenco vie;
• BodyPage: widget per l’elenco supporti;
• BulbPage: widget per l’elenco lampade;
• OperatorPage: widget per l’elenco degli installatori.
La classe LampPage permette l’overload di tre diversi costruttori che
differiscono per il tipo ed il numero di argomenti:
4.3 Database 50
• LampPage(QSqlRelationalTableModel *tableModel,QWidget *parent): viene
utilizzato nel Database Editor e riceve come argomento solo il model
principale;
• LampPage(QPointF* point, QSqlRelationalTableModel *tableModel,QWidget
*parent): rispetto al precedente ha in piu l’argomento di tipo QPointF.
Questo costruttore viene invocato nel caso in cui l’untente decida di
inserire una nuova lamp in un determinato punto della mappa (co-
mando add Lamp). In questo caso l’editor della lamp si apre con i
campi lonEditor e latEditor gia completati con le coordinate del punto
nell’argomento.
• LampPage(QModelIndexList indexList, QSqlRelationalTableModel *table-
Model, bool ReadOnly,QWidget *parent): riceve come argomento la lista
delle righe selezionate ( QModelIndexList) nel view. Questa variante
viene utilizzata quando si vuole visualizzare o modificare una serie di
lampioni che sono stati selezionati nel view. Il flag ReadOnly indica se
i dati delle lamps devono essere solo visualizzati (comando Info) o se
devono essere editati.
Il terzo costruttore e implementato con l’ausilio di un QDataWidgetMap-
per. Questa classe permette di “mappare” i dati di un model nei campi di
una widget. Questa funzione permette di scorrere facilmente tutti i record
del database dalla stessa widget, attraverso due pulsanti avanti e indietro e,
all’occorrenza, modificarli al volo.
L’impego di un data mapper ha richiesto pero l’implementazione di un
delegate personalizzato, il comboDelegate, che vedremo piu avanti.adatto che
vedremo piu avanti.
I metodi della classe LampPage sono:
• Next()/Previous(): sono due funzioni slot collegati ai pulsanti per scor-
rere tra i record in fase di modifica/visualizzazione delle lamps;
• addNewLamp(): il metodo, invocato dalloslot submit() aggiunge un
nuovo lampione nel database;
• submitEdit(): aggiorna i dati in seguito alla modifica dell’utente;
• uploadImage(): serve a leggere l’immagine in formato binario dal database;
4.3 Database 51
• createComboBoxModel(): questo metodo associa i menu a “discesa”
(combo box) con il contenuto delle tabelle relazionate. L’associazione
pero non e diretta ma passa per la creazione di un model “intermedio”
( QSortFilterProxyModel) sul quale possiamo agire in modo da ordinare
alfabeticamente le voci, per una lettura piu semplice.
La struttura delle widget, per l’editing delle altre tabelle, e pressoche la
stessa. Si possono quindi definire tre metodi comuni, implementati all’inizio
del file:
• createTableView(): riceve come argomento il model di una tabella re-
lazionata, ne istanzia la visualizzazione come elenco e restituisce il
puntatore al view creato;
• addNewItem(): permette di inserire un nuovo record nella tabella il cui
model viene passato come argomento;
• deleteItem(): a differenza della funzione di inserimento, riceve come
argomento l’intero model. Questo perche il metodo verifica prima
che la tabella principale non contenga delle lamps con l’attributo da
eliminare.
Le pages sono costituite da una lista (view), attraverso la quale scegliere
il record da modificare o eliminare un record, ed uno o piu campi dove poter
inserire i dati dei nuovi record. I pulsanti Add, Save e Delete sono collegati,
mediante il sistema signal/slot, rispettivamente ai seguenti metodi:
• submit(): insieme al metodo comune addNewItem() permette di ag-
giungere nuovi record alla tabella di riferimento;
• save(): salva nel model (e quindi nel database Sql) le modifiche appor-
tate ad un record;
• remove(): elimina dal model (e quindi dal database Sql) il record
selezionato.
Il database Sql e impostato per avere valori unici. Questo vuol dire che
non e possibile, ad esempio, inserire due vie con lo stesso nome. In questa
eventualita, il metodo che invia le modifiche del model al database, ossia
submitAll(), restituirebbe valore false, producendo un messaggio di errore.
4.3 Database 52
Fig. 4.5: Funzionamento di un delegate standard
Fig. 4.6: Delegate standard con proxy model intermedio
Classe ComboDelegate
La classe comboDelegate e stata scritta per rimpiazzare il delegate
standard per il widget data mapper utilizzato nella lampPage.
In Fig. 4.5 e rappresentata un menu a tendina (combo box) i cui dati
sono originati dalla tabella model. Un delegate standard interpreta la scelta
dell’utente, salvando nel model principale non il valore scelto, ma l’indice
corrispondente.
Il problema nasce nel momento in cui decidiamo di “inteporre” un model
intermedio ( proxyModel) con lo scopo di ordinare alfabeticamente le voci nel
menu (Fig. 4.6). Il delegate standard infatti non considera l’id associato alla
voce, bensı salva nel model principale l’indice con il quale la voce compare
nel menu combo, con conseguente inconsistenza dei valori.
Per questo motivo si e reso necessario reimplementare il delegate nella
classe comboDelegate, presente nell’omonimo file. In particolare sono stati
riscritti due metodi fondamentali del delegate:
• setEditorData(): legge l’indice dell’elemento nel proxy model, ricava
4.4 L’architettura Model/View 53
l’indice che l’elemento ha nel menu combo e lo seleziona;
• setModelData(): legge l’indice selezionato nel menu combo e lo trasfor-
ma nell’indice proprio dell’elemento nel proxy model.
4.4 L’architettura Model/View
Il concetto di architettura model/view e stato presentato nel corso del
par. 2.1.4. In questo paragrafo vedremo invece com’e stato implementato
nel software.
4.4.1 Implementazione del model
L’inizializzazione del model avviene grazie alla funzione initializeMod-
el(), che come abbiamo visto e invocata da connectPLA() a seguito di una
avvenuta connessione ad database.
La libreria Qt offre uno strumento adatto per gestire database relazionali:
il QSqlRelationalTableModel. Questa classe fornisce un model editabile di una
singola tabella con il supporto di chiavi esterne ( foreign keys).
Occorre quindi specificare qual’e la tabella principale del database me-
diante il metodo setTable(), e poi stabilire le relazioni di questa ( lamps con
le altre tabelle, grazie al metodo setRelation().
Normalmente, il model cosı creato, viene associato al view, che ne gestisce
la visualizzazione all’interno della widget. Nel nostro caso pero, non vogliamo
mostrare tutti i record del database, ma solo quei record che rispettano le
regole impostate dall’utente nel pannello filtri (vedi par. 3.3.3). Per questo
utilizzeremo un model “intermedio”, la classe ProxyModel.
La classe ProxyModel
Si tratta di una sottoclasse di QSortFilterProxyModel. Questa classe offre
supporto per ordinare e filtrare i dati nel passaggio da un altromodel al view.
Il model trasforma la struttura del model di origine attraverso la mappatu-
ra dei record con nuovi indici, a seconda della visualizzazione che si vuole
ottenere. Questo approccio permette di riorganizzare il modello sorgente,
senza richiedere la trasformazione dei dati originari e senza la duplicazione
di nuovi dati in memoria.
4.4 L’architettura Model/View 54
Nella classe ProxyModel viene quindi ridefinito il metodo chiave filterAc-
ceptsRow(). Questa funzione deve restiture valore booleano true se l’elemen-
to passato in argomento deve essere incluso nel model. In pratica i record
del model sorgente delle lamps, vengono inclusi nel proxy model solo se i
valori dei campi Group, Street e Bulb, corrispondono a quelli selezionati nel
pannello filtri.
Una serie di funzioni di tipo set permette di impostare le nuove stringhe
per il filtraggio, mentre la funzione clearFilters() le azzera, resettando di fatto
il filtro.
4.4.2 Implementazione del view
La visualizzazione dei dati viene inizializzata dal metodo initializeView()
ed affidata alla classe QTableView. Questa classe fornisce una view predefini-
ta per la visualizzazione di tabelle. QTableView implementa le interfacce
definite dalla classe QAbstractItemView per permettere di visualizzare i dati
forniti da modelli derivati dalla classe QAbstractItemModel.
Al view viene affidato come sorgente, non il model originale, bensı il
proxy model visto nel paragrafo precedente.
Il delegate associato, e quello standard, che implementa tutte le oper-
azioni comuni per i database relazionali: il QSqlRelationalDelegate.
L’editing diretto dei campi della tabella viene disabilitato mediante il
metodo setEditTriggers(), riservandoci di apportare tutte le modifiche al
database esclusivamente dal database editor (vedi Par 3.2.3).
All’interno della funzione initializeView() vengono definite le modalita di
selezione delle celle di tableView. Le proprieta SelectRows e ExtendedSelec-
tion, impostate grazie alle funzioni setSelectionBehavior e setSelectionMode,
impongono che la selezione sia effettuata per intere righe (e non per singole
celle) e che sia di tipo “esteso”, cioe che possono essere selezionate piu celle
mediante la combinazione ctrl + click.
Altre righe di codice servono a stabilire alcune aspetti grafici della rap-
presentazione tabellare e a definire opportuni ordinamenti.
4.5 Selezione e filtraggio 55
4.5 Selezione e filtraggio
4.5.1 Selezione singola da mappa
La selezione di una o piu lamps dalla mappa, avviene cliccando sulle
icone che le rappresentano. L’evento del mouse viene captato al livello del
geometryLayer, dalla funzione mouseEvent(). In corrispondenza del click del
mouse, la funzione cicla tutte le geometrie presenti nel layer, controllando
quali di queste intercettano (metodo Touches()) il punto di click. In ca-
so affermativo viene emesso il segnale geometrySelect(), che riporta come
argomento l’ID dell’oggetto light toccato.
Nella classe PLAdministrator, il segnale geometrySelect() e connesso con
la funzione slot mapSelect(). La funzione ha il compito di selezionare sulla
table view la riga della lamp, selezionata nella mappa. La funzione findRow()
restituisce l’indice della riga che nel dato momento contiene il record con l’ID
passato per argomento.
4.5.2 Selezione multipla da mappa
Per effettuare una selezione multipla sulla mappa, l’utente traccia una
rect selection. Questa azione genera un segnale a livello del mapcontrol col-
legato con lo slot boxSelect(). A questa viene passato il dato QRectF, che
specifica in coordinate assolute l’area selezionata. boxSelect() cicla tutte le
lamps del model, verificando quali di queste ricadono nel rettangolo speci-
ficato. La selezione viene “proiettata” sulla table view: viene istanziato un
QItemSelection per unire le singole selezioni, e questa viene ricavato il model
( QItemSelectionModel) da impostare al view.
4.5.3 La funzione performMouseSelection()
Ogni interazione con la table view che generi una variazione della se-
lezione delle righe, sia essa effettuata dall’utente o dalla chiamata di un’ap-
posita funzione, e accompagata dall’emissione del segnale selectionChanged,
collegato con lo slot performMouseSelection().
In base alle lamps selezionate sulla table view, questa funzione comunica
al livello delle lamps, quali di queste devono essere evidenziate sulla mappa.
Dalla lista delle righe selezionate in tabella ( selectedRows), viene ricavata la
lista degli ID dei lampioni ( selectedIds). Questo dato viene passato come ar-
4.6 Operazioni di Input/Output 56
gomento al signal lampsSelected() e quindi allo slot collegato lampsToSelect()
di lampsLayer.
Il metodo setViewAndZoomIn() di MapControl imposta la vista della
mappa in corrispondenza dell’ultima lamps selezionata.
4.5.4 Selezione e filtraggio da pannello
L’interazione dell’utente con il pannello filtri genera la chiamata alla
funzione slot updateUi(). In base ai radioButton selezionati la funzione puo
invocare due procedure: performFilter(), per il filtraggio dei record della view;
performSelection() per la selezione diretta dei record.
performFilter() applica i metodi set della classe ProxyModel (vedi Par.??).
I valori impostati nelle combo vengono passati al model che provvede auto-
maticamente a visualizzare solo i record che contengono questi valori.
performSelection() cicla tutte le righe del model, selezionando solo quelle
che contengono gli stessi valori impostati nelle combobox. Per fare questo
viene utililzzata la funzione booleana matchingColumn(), che restituisce true
se un valore e presente nel model ad una certa riga e ad una certa colonna.
4.6 Operazioni di Input/Output
Illustreremo in questo paragrafo le funzioni che si occupano di far dialog-
are il software Public Lighting Manager con i dispositivi di controllo della
rete di illuminazione. Al momento del rilascio del progetto, non esiste un
hardware di controllo, pertanto tutte le operazioni si limitano a leggere e
scrivere su file di testo esterni.
4.6.1 Operazioni di input
Per funzioni di input intendiamo tutte quelle “leggono“ lo stato delle
lamps, attraverso l’ascolto dei segnali di stato. Esse sono:
• readStatusLamps(): legge lo stato (acceso o spento) dei lampioni, cosı
come e stato salvato nella sessione precedente. Nell’attuale fase di sim-
ulazione, la funzione accede al file esterno status lamp.txt che contiene
la lista degli ID delle lamps con stato on.
4.6 Operazioni di Input/Output 57
• readWarningLamps(): questa funzione viene invocata per “ascoltare”
eventuali segnali di malfunzionamento o di allerta (warning) che proven-
gono dall’hardware esterno. In condizioni di lavoro, la funzione potrebbe
essere invocata ad intervalli prestabiliti oppure invocata da segnali di
trigger esterni. Nell’attuale fase di simulazione, la funzione legge dal
file ( check lamps.txt) gli ID delle lampade su cui si ipotizzi la presenza
di uno stato di warning. La chiamata viene effettuata all’interno della
funzione connectPLA(), subito dopo la connessione al database.
4.6.2 Operazioni di output
Le funzioni di output sono quelle che inviano comandi dal calcolatore
alla rete di illuminazione o ai dispositivi di controllo che la regolano. Tali
comandi devono comprendere le informazioni necessarie ad indirizzare un
certo lampione all’interno della rete.
Non esistendo al momento della stesura di questa tesina un hardware di
controllo studiato ad hoc, le funzioni di output si limitano a scrivere su un
file di testo il risultato dell’operazione. Queste funzioni sono qui elencate.
• turn off(): metodo per lo spegnimento dei lampioni.
• turn on(): metodo per l’accensione dei lampioni.
Entrambi vengono invocati mediante protocollo signal/slot quando l’u-
tente invia il comando dall’interfaccia grafica.
Questi metodi ricavano dalla table view la selezione attuale delle lamps(
QItemSelectionModel), effettuando su queste le necessarie operazioni di ac-
censione o spegnimento. Nello specifico, la routine si limita a scrivere su
un file esterno ( log file.txt) la cronologia delle operazioni effettuate (log
file), riportando per ogni riga il tipo di operazione, l’identificativo ( ID) del
lampione sul quale e stata effettuata e l’indirizzo seriale dello stesso.
Capitolo 5
Conclusioni e sviluppi futuri
Nella presente tesina e stata sviluppata una interfaccia grafica per la
gestione ed il controllo di un impianto di illuminazione pubblica.
Le condizioni di test sono state le seguenti:
• hardware - Intel Core Duo P8600 a 2.4GHz, 4GB RAM;
• sistema operativo - Linux Ubuntu v10.010, desktop GNOME v2.32.0;
• database MySql - web server locale XAMPP per Linux v1.7.4.
La vista della rete di illuminazione attraverso la mappa e immediata e
la navigazione di questa risulta agevole, in conformita con i piu noti sistemi
di fruizione cartografica.
I lampioni possono essere selezionati direttamente dalla mappa, in modo
singolo o tramite selezione rettangolare. La selezione puo avvenire anche
imponendo dei filtri, in base alla strada di ubicazione, al gruppo o in base
alla lampada montata.
E’ stato inoltre implementato un sistema di gestione del database, che
consente di aggiungere, eliminare o modificare sia i lampioni che gli “at-
tributi” ad essi associati. La struttura relazionale del database ci permette
di integrare o modificare tutti questi dati in modo illimitato e flessibile.
L’utilizzo del software e abbastanza intuitivo. L’interfaccia, chiara, rende
rapido l’apprendimento d’uso anche da parte di personale non specializzato.
Le operazioni di cancellazione, all’interno del database, richiedono con-
ferma ed inoltre sono seguite dal controllo della presenza di eventuali riferi-
menti, la cui interruzione causerebbe la perdita di consistenza dei dati.
58
59
Lo sviluppo del codice e risultato abbastanza agevole, grazie anche al
gran numero di classi gia implementate nella libreria Qt, che ci ha perme-
sso di implementare in breve tempo le widget o la connessione al database
MySql.
Alcune problematiche sono state riscontrate nelle operazioni di database,
soprattutto per quanto riguarda la gestione degli indici chiave. L’aggiunta di
nuovi elementi, infatti, sotto determinate condizioni dava origine ad errori.
Pertanto abbiamo preferito delegare la gestione degli indici al server MySql,
imponendo l’auto-incremento durante la creazione delle tabelle.
Questo progetto e stato realizzato in assenza di un hardware di controllo
ad hoc, pertanto le operazioni sui lampioni si limitano a scrivere su file di
testo. Il passo successivo, sara quello di integrare l’interfaccia con le funzioni
atte a “dialogare” con l’elettronica di controllo della rete di illuminazione.
Compatibilmente con l’hardware a disposizione, un ulteriore sviluppo
puo essere quello di integrare l’interfaccia di un sistema di widget che dia
informazioni in real time sullo stato della rete (consumi, avarie, ecc..).
Infine, ulteriori sviluppi potrebbero riguardare il porting dell’applicazione
su dispositivi mobili dotati di schermo touch screen.
Bibliografia
[1] ZigBee Alliance. Zigbee. http://www.zigbee.org.
[2] Nokia Corporation. Qt. http://qt.nokia.com.
[3] Oracle Corporation. Mysql. http://www.mysql.it.
[4] Jeff de la Beaujardiere. Opengis web map server implementation speci-
fication, version 1.3.0, reference number: Ogc 06-042. Technical report,
Open Geospatial Consortium, 2006.
[5] Parlamento Europeo. Direttiva 2006/32/ce: Efficienza degli usi finali
dell’energia e i servizi energetici. Gazzetta ufficiale dell’Unione europea,
April 2006.
[6] OSM Foundation. Openstreetmap. http://www.openstreetmap.org/.
[7] John R. Herring. Opengis implementation specification for geographic
information - simple feature access - part 1: Common architecture.
OpenGIS R© Implementation Standard, 2011.
[8] Martin Schulte-Hobein. Intelligent street lighting management using
zigbee R©. Technical report, Digi International, 2010.
[9] John P. Snyder. Map projections - a working manual. United States
Government Printing Office, 1987.
[10] Mark Summerfield and Jasmin Blanchette. C++ GUI Programming
with Qt 4. Prentice Hall, 2006.
[11] Mark Summerfield and Erik Chambe. Advanced Qt Programming.
Prentice Hall, 2010.
[12] Kai Winter. Qmapcontrol. http://medieninf.de/qmapcontrol/.
60