sviluppo di un'applicazione windows phone 7.5 per la visualizzazione di dati di emissioni...
TRANSCRIPT
Università degli Studi di Trieste
Facoltà di Ingegneria
Corso di Laurea Triennale in Ingegneria dell’Informazione
Curriculum Informatica
SVILUPPO DI UN’APPLICAZIONE WINDOWS
PHONE 7.5 PER LA VISUALIZZAZIONE DI DATI
DI EMISSIONI INQUINANTI
Relatore:
Chiar.mo Prof. Maurizio FERMEGLIA
Laureando:
Marco VIRGOLIN
Anno accademico 2011/2012
A tutti coloro che mi hanno
supportato (e sopportato)
in questo percorso
i
Indice
1. Introduzione ..................................................................................................................................................... 1
1.1 Obiettivo della tesi ................................................................................................................................................... 1
1.2 Stato dell’arte e motivazioni ................................................................................................................................. 1
1.3 Vincoli di progetto ................................................................................................................................................... 2
1.4 Tecnologie software utilizzate ............................................................................................................................. 3
1.4.1 Visual Studio 2010 ............................................................................................................................................ 3
1.4.2 Windows Phone SDK 7.1.1 ............................................................................................................................ 3
1.5 Obiettivi tattici ........................................................................................................................................................... 3
1.6 Risultato della tesi .................................................................................................................................................... 4
2. Analisi ................................................................................................................................................................. 5
2.1 Sistema Operativo Windows Phone 7.5 ........................................................................................................... 5
2.2 Controllo Map: Bing Maps .................................................................................................................................... 6
2.3 PRTR database ........................................................................................................................................................... 6
2.4 Windows Communication Foundation e PRTRService ............................................................................... 7
2.5 Model View ViewModel ......................................................................................................................................... 8
3. Progettazione .................................................................................................................................................. 8
3.1 Use Case Diagram .................................................................................................................................................... 9
3.2 Class Diagram .......................................................................................................................................................... 10
4. Realizzazione ................................................................................................................................................. 16
4.1 Applicazione Windows Phone ........................................................................................................................... 17
4.1.1 Interfaccia utente ............................................................................................................................................ 17
4.1.1.1 MainPage .................................................................................................................................................. 17
4.1.1.2 SettingsPage ............................................................................................................................................ 17
4.1.1.3 ResultsPage .............................................................................................................................................. 17
4.1.1.4 AboutPage ................................................................................................................................................ 20
4.1.2 Interfacciamento a web service ................................................................................................................. 20
4.1.3 Esempio d’uso .................................................................................................................................................. 20
4.1.4 Implementazione ............................................................................................................................................ 21
4.1.4.1 Referenziazione di web service ......................................................................................................... 21
ii
4.1.4.2 Memorizzazione delle impostazioni ............................................................................................... 22
4.1.4.3 Avvio dell’applicazione ......................................................................................................................... 23
4.1.4.4 Implementazione delle mappe ......................................................................................................... 24
4.1.4.5 Localizzazione del dispositivo ........................................................................................................... 25
4.1.4.6 Scelta del centro d’analisi.................................................................................................................... 26
4.1.4.7 Generazione dei pushpin rappresentanti gli impianti industriali ......................................... 27
4.1.4.8 Geolocalizzazione ................................................................................................................................... 28
4.1.4.9 Visualizzazione dei risultati ................................................................................................................. 29
4.2 Web Service .............................................................................................................................................................. 32
4.2.1 Interfacciamento al client ............................................................................................................................ 32
4.2.2 Implementazione ............................................................................................................................................ 33
5. Conclusioni .................................................................................................................................................... 35
5.1 Quantificazione del lavoro svolto ..................................................................................................................... 35
5.2 Stato attuale del lavoro ........................................................................................................................................ 36
6. Bibliografia ..................................................................................................................................................... 37
1
1. Introduzione
Questa tesi tratta la progettazione e lo sviluppo di un’applicazione per smartphone atta
alla visualizzazione di dati di emissioni inquinanti presenti nel database PRTR
dell’Università di Trieste.
1.1 Obiettivo della tesi
L’obiettivo del presente lavoro è lo sviluppo di un’applicazione intuitiva, veloce ed efficace
per la consultazione di dati relativi alle emissioni inquinanti e la localizzazione degli
impianti industriali interessati. Considerata la diffusione del cellulare smartphone nella
società odierna e la rapida crescita del relativo mercato, il software, oggetto del presente
lavoro, è stato sviluppato per questo dispositivo.
1.2 Stato dell’arte e motivazioni
Attualmente esistono già due modalità per effettuare l’interrogazione al database PRTR
dell’Università di Trieste, ovvero tramite web form1 oppure tramite applicazione stand-
alone sviluppata da Raffaele Bernardi Google Earth PRTR Interface2 che utilizza il plug-in
Google Earth per la visualizzazione del globo terrestre.
L’idea di realizzare un’applicazione smartphone atta ad interrogare il database nasce
dall’intento di superare i limiti insiti nelle altre due applicazioni attualmente usate.
Infatti la web form non risulta essere uno strumento di facile consultazione per un utente
generico, in quanto presuppone l’inserimento delle coordinate geografiche per definire il
centro del cerchio su cui effettuare l’analisi.
1 Disponibile all’indirizzo http://prtr.units.it/RegionalEmissions.aspx
2 R. Bernardi (2010) Progetto e sviluppo di un applicativo basato su Google Earth per la visualizzazione di dati
di emissioni inquinanti, tesi di laurea triennale, Università degli studi di Trieste
2
La web form come appare sul browser Google Chrome
Dall’altro lato la seconda applicazione, che invece permette di identificare il centro del
cerchio di analisi direttamente dal mappamondo tridimensionale tramite il plug-in Google
Earth, può essere utilizzata solo su personal computer, mentre lo smartphone è un oggetto
che l’utente porta comunemente con sé.
Un software smartphone, dunque, presenta il vantaggio di un’elevata fruibilità del
prodotto grazie alla facile trasportabilità del dispositivo e all’intuitività e la semplicità che
caratterizzano questo genere di applicazioni.
Si è deciso di sviluppare l’applicazione per il sistema operativo Windows Phone 7.5 visto il
supporto offerto dall’organizzazione studentesca EESTEC LC Trieste, promotrice di
laboratori di sviluppo di applicazioni Windows Phone durante l’anno accademico.
1.3 Vincoli di progetto
I vincoli di progetto sono determinati dalle caratteristiche intrinseche degli strumenti
Windows Phone 7.5, dalla struttura e dalle stored procedure del database PRTR nonché
dalla necessità di interporre un servizio web tra applicazione e database per garantire la
comunicazione. In questo lavoro sono stati sviluppati i metodi di accesso ai dati su un web
service già disponibile.
Nello specifico i vincoli sono i seguenti :
3
conformità del software ai requisiti Microsoft3 per lo sviluppo di applicazioni
Windows Phone;
utilizzo di un provider di mappe per la visualizzazione geografica della terra;
utilizzo del web service disponibile;
utilizzo di stored procedure e tabelle presenti nel database;
rispetto dell’asincronismo per i metodi del web service utilizzati nell’applicazione.
1.4 Tecnologie software utilizzate
1.4.1 Visual Studio 2010
L’applicazione smartphone ed le funzionalità del web service a disposizione (denominato
in seguito PRTRService) sono stati scritti utilizzando l’ambiente di sviluppo integrato
Microsoft Visual Studio 2010 Ultimate. Tale applicativo offre strumenti per migliorare la
produttività del programmatore quali ad esempio IntelliSense, il Class Diagram e il
designer virtuale delle GUI. Per creare un progetto Windows Phone Application è
necessario ampliare le funzionalità di Visual Studio installando il Software Development Kit
di Windows Phone.
1.4.2 Windows Phone SDK 7.1.1
L’SDK di Windows Phone è il pacchetto necessario per creare applicazioni e giochi per
dispositivi Windows Phone 7.0 e 7.5. Oltre a consentire lo sviluppo di tali applicazioni su
Visual Studio, esso offre anche una serie di strumenti utili al programmatore, quali il
Windows Phone Emulator, Microsoft Express Blend 4 for Windows Phone e Microsoft
Advertising SDK for Windows Phone.
1.5 Obiettivi tattici
Il lavoro è stato suddiviso nelle seguenti fasi:
studio delle tecnologie atte alla realizzazione di applicazioni smartphone
o Windows Phone SDK, Visual Studio Ultimate 2010 e linguaggi XAML, C#;
analisi delle principali stored procedure e delle tabelle del database PRTR
3 Consultabili all’indirizzo http://tinyurl.com/76xhyjf
4
o in particolare le tabelle ReportPeriod, Facility e la stored procedure
Statistics_GetByRegion;
studio delle tecnologie implementate nella realizzazione di un web service
o WCF, contratti, servizi, endpoint;
analisi delle modalità di gestione delle interazioni tra applicazione e web service,
web service e database;
individuazione delle funzioni disponibili nell’applicazione;
individuazione delle funzionalità da esporre sul web service;
progettazione dell’applicazione smartphone;
progettazione e sviluppo del web service (non a cura del laureando);
integrazione tra web service e database;
test del web service tramite semplice applicativo console sviluppata ad hoc;
sviluppo dell’applicazione smartphone;
lancio dell’applicazione smartphone sul mercato
o certificazione sul Marketplace di Windows Phone;
1.6 Risultato della tesi
Il presente lavoro ha portato alla realizzazione dell’applicazione Pollutant Releases,
scaricabile gratuitamente dal Marketplace di Windows Phone4. L’utilizzo del software non
richiede particolari caratteristiche hardware, è disponibile in lingua inglese ed è accessibile
da tutti i paesi ad eccezione di alcuni stati medio-orientali, come ad esempio la Cina, dove
non vengono distribuite le applicazioni che implementano Bing Maps.
La pagina web dell’applicazione nel Marketplace di Windows Phone
4 Link all’applicazione: http://tinyurl.com/d84mffk
5
A sinistra la pagina principale dell’applicazione, a destra la pagina che espone i risultati dell’analisi
2. Analisi
Oggetto dell’analisi sono stati i seguenti aspetti: il sistema operativo smartphone
utilizzato, il controllo atto a gestire la visualizzazione della mappa, il database con i dati
delle emissioni inquinanti e la tecnologia implementata nel web service da interporre tra
database e applicazione.
2.1 Sistema Operativo Windows Phone 7.5
Windows Phone è il sistema operativo Microsoft, successore di Windows Mobile, utilizzato
in smartphone, Pocket PC e Portable Media Center.
L’applicazione qui discussa è stata sviluppata per la versione 7.5 Mango, che rappresenta
l’aggiornamento del sistema operativo più grande finora realizzato ed è stata rilasciata il 27
settembre 2011.
6
I due aspetti principali che caratterizzano le applicazioni smartphone sono l’interfaccia
grafica e la logica. Per Windows Phone l’interfaccia grafica viene scritta in linguaggio
XAML5 e viene salvata in file con estensione .xaml, mentre la logica è gestita in C# e viene
salvata in file .xaml.cs.
2.2 Controllo Map: Bing Maps
Per lo sviluppo di applicazioni Windows Phone il controllo Map consente l’utilizzo di Bing
Maps. Bing Maps è il servizio mappe offerto da Bing (analogo a Google Maps, Nokia maps
etc.), atto alla visualizzazione di cartine stradali, immagini satellitari e prospettive
ravvicinate a diverse risoluzioni su quasi tutto il pianeta. Oltre a permettere la
visualizzazione di mappe, BingMaps fornisce diversi servizi come ad esempio il calcolo di
tragitti tra un luogo e l’altro.
Nell’applicazione smartphone devono essere implementati servizi basilari per un facile
utilizzo di Bing Maps, come ad esempio la regolazione dello zoom, lo spostamento della
visualizzazione sul mondo tramite interazioni con il touchscreen nonché l’identificazione di
punti specifici sulla mappa utilizzando dei pushpin.
Per quanto concerne altri servizi, come la ricerca della posizione dell’utente o la
visualizzazione di un luogo previo l’inserimento del relativo indirizzo, è necessario
implementare metodi aggiuntivi non disponibili fra quelli offerti dal controllo Map.
2.3 PRTR database
I Pollutant Release and Transfer Register sono database che memorizzano i dati di
emissioni inquinanti emesse nell’ambiente da impianti industriali. Esistono diversi PRTR, a
titolo d’esempio possono essere citati il National Pollutant Inventory in Australia,
l’European Pollutant Emission Register in Europa e il Toxics Release Inventory negli Stati
Uniti.
L’università di Trieste, assieme all’organizzazione ICS-UNIDO6, ha sviluppato un PRTR che
attualmente memorizza i dati riguardanti le città di Alessandria d’Egitto, Ankara ed Atene.
5 eXtensible Application Markup Language, ha come fondamento XML ed è utilizzato per descrivere
l’interfaccia grafica di applicazioni basate sulla libreria Windows Presentation Foundation. 6 International Centre for Science and High Technology – United Nations Industrial Development
Organization. Ha sede a Trieste (IT) ed è finanziata dal Ministero degli Affari Esteri italiano.
7
È opportuno specificare alcune caratteristiche dei dati presenti nel database in questione,
nonché quelle relative all’applicazione oggetto della presente discussione. I dati vengono
riportati secondo i seguenti criteri:
prodotto chimico inquinante;
elemento dell’ambiente inquinato: aria, acqua, terra, sottosuolo;
zona di emissione o trasferimento interessata;
impianto industriale che produce gli inquinanti;
periodo;
I componenti del PRTR database di interesse per il presente lavoro sono:
la table ReportPeriod, di cui in particolare i campi
o ID (int): codice numerico identificativo del periodo;
o Title (nvarchar): nome del periodo, ad esempio “Year 2012, months 7-12”;
la table Facility, di cui in particolare i campi
o IDFacility (int): codice identificativo dell’impianto;
o LongitudeDeg, LongitudeMin, LongitudeSec (int): rispettivamente gradi,
minuti e secondi di longitudine;
o LatitudeDeg, LatitudeMin, LatitudeSec (int): analogo per la latitudine;
la stored procedure Statistics_GetByRegion: fornisce tutti gli inquinanti in un dato
periodo (identificato dal suo id) ed in una data zona circolare (il cui centro è
identificato da latitudine e longitudine, e il raggio è specificato dall’utente); le
quantità di sostanze inquinanti emesse sono misurate in chilogrammi e distinte per
elemento dell’ambiente inquinato;
Per ulteriori informazioni riguardo la base di dati si rimanda alla relativa documentazione
tecnica.
2.4 Windows Communication Foundation e PRTRService
Windows Communication Foundation (WCF) è un componente del .NET framework atto a
rappresentare i modelli di comunicazione tra sistemi distribuiti.
Esso fornisce un modello unificato di programmazione e relative API, evitando così al
programmatore di dover scegliere tra differenti tecnologie come Web Service, Remoting,
Message Queuing e Enterprise Service in base alla relativa applicazione.
Il web service PRTRService è un servizio dati WCF che espone metodi di interrogazione al
PRTR database, ove il database management system è Microsoft SQL Server 2008.
8
2.5 Model View ViewModel
Il Model View ViewModel (MVVM) è il pattern architetturale consigliato per la gestione e
visualizzazione dei dati in ambiente .NET. Esso è stato applicato nella costruzione del
servizio web e dell’applicazione Windows Phone. In particolare i Model sono stati definiti
nel servizio web mentre i rispettivi ViewModel e le View nell’applicazione Windows Phone.
3. Progettazione
Per quanto concerne la progettazione viene fatto uso degli standard Unified Modeling
Language. In particolare sono illustrati alcuni dei diagrammi caratteristici:
lo Use Case Diagram: il diagramma che descrive il funzionamento di un sistema dal
punto di vista degli attori interagenti;
il Class Diagram: il diagramma che espone le classi dell’applicazione e le relazioni tra
di esse.
Nel presente lavoro non viene trattata la progettazione del web service in quanto il
laureando non se ne è occupato.
9
3.1 Use Case Diagram
Il principale utilizzo dell’applicazione smartphone consta nell’esplorazione della mappa
fornita dal server Bing Maps, dopo che su di essa appaiono i pushpin delle installazioni
industriali. Le coordinate degli impianti sono memorizzate nel database e rese accessibili
all’applicazione tramite il web service PRTRService. Oltre all’esplorazione manuale è
possibile localizzare la propria posizione o specificare un indirizzo utilizzando il servizio di
georeferenziazione7 del web service GeocodeService.
7 Viene utilizzato il metodo Geocode atto a fornire informazioni relative alla dislocazione geografica di un
indirizzo, dato come parametro di input
10
Scelto un punto d’interesse attraverso un apposito pushpin posizionabile sulla mappa o
usando la localizzazione del dispositivo, l’utente può passare alla visualizzazione dei
risultati. Di default vengono visualizzati i risultati per il periodo più recente, ma è possibile
scegliere un qualsiasi altro periodo. È altresì possibile scegliere la lunghezza del raggio del
cerchio di analisi modificando le impostazioni, oltre ad attivare o disabilitare il servizio di
localizzazione. L’estrazione dei periodi e l’uso di stored procedure avviene attraverso il
servizio web PRTRService, analogamente a quanto avviene per l’ottenimento delle
coordinate degli impianti industriali.
3.2 Class Diagram
Il diagramma alla pagina seguente, generato con Visual Studio 2010, presenta le classi
create o modificate dal laureando e alcune di quelle generate automaticamente in seguito
alla referenziazione del relativo web service (riconoscibili dal simbolo posto sopra di
esse).
Le classi con il suffisso Page contengono la logica degli omonimi file con estensione .xaml
(che descrivono le GUI) e presentano sempre il metodo InitializeComponent()8 : void
all’interno del proprio costruttore.
La classe GeocodeServiceClient presenta le funzionalità offerte dal web service
GeocodeService, mentre StatisticsClient quelle offerte da PRTRService. Da quest’ultimo
provengono anche EmissionInfo, FacilityInfo e PeriodInfo: Model associati ai relativi
ViewModel implementati a livello di applicazione.
8 Inizializza l’interfaccia grafica descritta nel relativo file .xaml
11
Di seguito l’elenco dettagliato delle singole classi con relativi attributi e metodi:
App – classe generata automaticamente dall’ambiente di sviluppo alla creazione del
progetto Windows Phone Application. Essa contiene metodi per l’inizializzazione dei
componenti software, per il supporto al debug, per la gestione delle eccezzioni e
12
per la gestione del comportamento dell’applicazione all’avvio, alla sospensione e
alla chiusura. Di questi è stato modificato il metodo che gestisce l’avvio:
o – Application_Launching(object sender, LaunchingEventArgs e) : void
Controlla che le impostazioni salvate contengano informazioni riguardo
l’attivazione del servizio di localizzazione e la lunghezza del raggio di analisi
e, qualora non le trovi9, le genera e le salva;
MainPage – contiene la logica della pagina principale dell’applicazione, presenta i
seguenti metodi:
o + MainPage()
Costruttore, inizializza l’interfaccia grafica MainPage.xaml tramite il metodo
InitializeComponent() e chiama il metodo GenerateFacilities();
o – GenerateFacilities() : void
Utilizza il metodo LoadFacilities() di StatisticsClient, crea e posiziona un
pushpin per ogni impianto industriale ottenuto;
o – txtSearch_KeyDown(object sender, KeyEventArgs e) : void
Si occupa di riconoscere la pressione del tasto Enter quando si digita
l’indirizzo di un posto da visualizzare sulla mappa, di creare e di avviare una
nuova richiesta di geolocalizzazione10 dove il parametro di input è l’indirizzo
digitato;
o + Geocode (GeocodeRequest geocodeRequest) : GeocodeResponse
Viene eseguito automaticamente in modo asincrono dopo che il processo di
geolocalizzazione è terminato e mostra la mappa associata all’indirizzo
fornito o comunica all’utente che la ricerca non ha prodotto risultati;
o – SwitchViewMode(object sender, EventArgs e) : void
Associato all’opzione switch view del menù, alterna la visualizzazione delle
mappe fra satellitare e stradale;
o – GetMyPosition(object sender, EventArgs e) : void
Associato al bottone find me del menù, avvia il processo di localizzazione del
dispositivo qualora il servizio sia abilitato;
o – myWatcher_PositionChanged(object sender,
GeoPositionChangedEventArgs <GeoCoordinate> e) : void
All’aggiornamento della posizione del dispositivo modifica il pushpin
identificativo della stessa sulla mappa;
o – SetMyPoView(object sender, EventArgs e) : void
Associato al bottone set pov del menù, abilita la possibilità di posizionare
manualmente il pushpin centro del cerchio di analisi sulla mappa; 9 In teoria questo avviene solamente se l’applicazione non è stata mai avviata in precedenza
10 Nell’applicazione tale metodo è scisso nei metodi con suffisso _Async e _Completed per garantire
l’asincronismo
13
o – SetMyPoVonMap(object sender, GestureEventArgs e) : void
Crea il pushpin myPoV, centro del cerchio di analisi sulla mappa, al tocco
dell’utente sul controllo Map;
o – textSearch_GotFocus(object sender, RoutedEventArgs e) : void
Si occupa di selezionare tutto il contenuto del campo di ricerca dell’indirizzo
al tocco dell’utente11;
o – ScanResults(object sender, EventArgs e) : void
Converte le coordinate del centro d’analisi da decimali in gradi, minuti,
secondi sfruttando la classe Utilities ed effettua la navigazione alla pagina
ResultsPage;
o – GotoSettingsPage(object sender, EventArgs e) : void
Effettua la navigazione alla pagina SettingsPage;
o – GotoAboutPage(object sender, EventArgs e) : void
Effettua la navigazione alla pagina AboutPage;
AboutPage – contiene la logica della pagina contenente informazioni generali
sull’applicazione, il database PRTR, il web service e l’indirizzo e-mail del laureando.
Presenta i metodi:
o + AboutPage()
Costruttore, chiama il metodo InitializeComponent() : void che Inizializza
l’interfaccia grafica AboutPage.xaml;
o – btnMail.Click() : void
Intercetta la pressione del bottone contenente l’indirizzo e-mail del
laureando e manda alla selezione del client di posta elettronica con cui
spedire una e-mail a tale indirizzo;
o – btnWebSiteClick() : void
Intercetta la pressione del bottone contenente il l’indirizzo web
http://prtr.units.it/ e apre la pagina a tale indirizzo con il browser12;
AppSettings – classe statica in cui sono raccolte variabili utili a diverse classi, non
presenta metodi. Le variabili di AppSettings sono trattate nel capitolo di
realizzazione13.
SettingsPage – contiene la logica della pagina contenente le impostazioni
modificabili dall’utente, presenta i metodi:
o + SettingsPage()
11
Usato in molte applicazioni, è uno dei piccoli accorgimenti che migliorano l’esperienza dell’utente 12
Internet Explorer Mobile 13
Pagina 22
14
Costruttore, chiama il metodo InitializeComponent() : void che Inizializza
l’interfaccia grafica SettingsPage.xaml e mette in evidenza le opzioni
selezionate dall’utente e salvate in memoria;
o – EnableLocation() : void
Abilita l’utilizzo del servizio di localizzazione;
o – DisableLocation() : void
Disabilità l’utilizzo del servizio di localizzazione;
o – listRadius_SelectionChanged(object sender, SelectionChangedEventArgs e) :
void
Imposta il valore del raggio selezionato dall’utente;
Utilities – classe statica che contiene metodi di supporto alle altre classi:
o + $ CantConnectToInternet() : bool
Controlla se il dispositivo è connesso ad Internet e in caso di mancata
connessione comunica all’utente l’assenza di rete;
o + $ DecToDeg(double number) : int[]
Converte un double in gradi, minuti e secondi di tipo int;
o + $ DegToDec(int[] degreenumber) : double
Converte gradi, minuti e secondi di tipo int in un double;
ResultsPage – contiene la logica della pagina che mostra i dati delle emissioni
inquinanti dato il cerchio di analisi. Presenta i seguenti metodi:
o + ResultsPage()
Costruttore che inizializza l’interfaccia ResultsPage.xaml tramite
InitializeComponent(), controlla se si il dispositivo è connesso ad Internet
tramite il metodo +$CantConnectToInternet() della classe statica Utilities e, in
caso che questo generi un risultato false, avvia il metodo –GenerateAppBar();
o – GenerateAppBar() : void
Utilizza al suo interno il metodo LoadPeriods() di StatisticsClient;
o + LoadPeriods()14 : PeriodInfo[]
Utilizza il metodo LoadPeriods() di StatisticsClient da cui ottiene una lista di
oggetti di classe PeriodInfo con la quale genera un menù AppBar dove le
voci dei menù corrispondono con il nome di ciascun periodo della lista; fatto
ciò chiama il metodo GenerateGrid(idPeriod) dove il parametro idPeriod è l’id
del periodo più recente;
o – GenerateGrid(idPeriod) : void
14
Nell’applicazione tale metodo è scisso nei metodi con suffisso _Async e _Completed per garantire
l’asincronismo
15
Metodo atto alla generazione della tabella contenente i dati delle emissioni
inquinanti: chiama il metodo GenerateFields(), genera le righe della tabella e
utilizza al suo interno il metodo GetByRegion per ottenere i dati con cui
riempire le celle e chiama il metodo GenerateTotalRow(totalAir,
totalUnderground, totalWater, totalLand, totalTotal, counter);
o – GenerateFields() : void
Genera dinamicamente i campi della tabella mostrata;
o + GetByRegion(longitudeDeg, longitudeMin, longitudeSec, latitudeDeg,
latitudeMin, latitudeSec, radius, “en-US”, periodId)13 : EmissionInfo[]
Utilizza l’omonimo metodo offerto dal web service PRTRService per ottenere
la lista di oggetti EmissionInfo contenenti ciascuno i dati relativi a una
tipologia di agente inquinante in una data zona e in un dato periodo.
Quando la lista è piena genera le righe della tabella contenenti tali dati con
l’ausilio del metodo EmissionInfoPropToArray(EmissionInfos[i]);
o – EmissionInfoPropToArray(EmissionInfos[i]) : string[]
Dato l’oggetto EmissionInfoViewModel alla i-esima posizione nella lista
EmissionInfos, genera un array di stringhe contenente le proprietà del
parametro in input;
o – GenerateTotalRow(totalAir, totalUnderground, totalWater, totalLand,
totalTotal, counter) : void
Crea l’ultima riga della tabella, le cui celle contengono i dati passati al
metodo come parametri, ovvero la somma delle quantità di ogni campo;
o – periodMenu_Click(object sender, EventArgs e) : void
Cancella i dati della tabella mostrata nella pagina e chiama il metodo
GenerateGrid(idPeriod) dove idPeriod è l’identificativo del periodo scelto
dall’utente nel menù AppBar;
ApplicationBarPeriodItem – classe che estende ApplicationBarMenuItem, presenta
tutte le proprietà e i metodi della classe estesa più una proprietà aggiuntiva:
o <<property>> + Id : Integer
Proprietà atta alla memorizzazione dell’identificativo del periodo;
EmissionInfoViewModel – classe ViewModel che, in quanto tale, presenta le
proprietà dell’oggetto EmissionInfo che sono effettivamente utilizzate
nell’applicazione:
o <<property>> + Fullname : string
Il nome dell’inquinante;
o <<property>> + QuantityWater : int
16
La quantità di inquinante emessa nell’acqua, espressa in chilogrammi;
o <<property>> + QuantityAir : int
La quantità di inquinante emessa nell’aria, espressa in chilogrammi;
o <<property>> + QuantityInjection : int
La quantità di inquinante emessa nel sottosuolo, espressa in chilogrammi;
o <<property>> + QuantityLand : int
La quantità di inquinante emessa nel terreno, espressa in chilogrammi;
o <<property>> + QuantityTotal : int
La somma di tutte le quantità sopracitate;
FacilityInfoViewModel – classe che presenta le proprietà dell’oggetto FacilityInfo
utilizzate nell’applicazione:
o <<property>> + Id : int
Intero identificativo utilizzato come chiave primaria del record del relativo
impianto;
o <<property>> + LatitudeDeg, LatitudeMin, LatitudeSec, LongitudeDeg,
LongitudeMin, LongitudeSec: int
Interi che esprimono, rispettivamente, i gradi, i minuti e i secondi della
latitudine e della longitudine che sono le coordinate di ubicazione
dell’impianto;
PeriodInfoViewModel – classe che presenta le proprietà dell’oggetto PeriodInfo
utilizzate nell’applicazione:
o <<property>> + Id : int
Intero identificativo utilizzato come chiave primaria del record del relativo
periodo;
o <<property>> + Title : string
Nome del periodo.
4. Realizzazione
La trattazione della realizzazione è suddivisa in due parti: l’applicazione smartphone e il
servizio web, di cui vengono trattati solo gli aspetti sviluppati dal laureando.
17
4.1 Applicazione Windows Phone
4.1.1 Interfaccia utente
L’interfaccia utente dell’applicazione è costituita da quattro pagine: MainPage,
SettingsPage, ResultsPage e AboutPage. Le pagine possono essere visualizzate sia in
modalità Portrait (cellulare in posizione verticale), sia Landscape (cellulare in posizione
orizzontale), ad eccezione di AboutPage che presenta solo la visualizzazione verticale. Il
colore dello sfondo delle pagine e quello dei caratteri in primo piano15 vengono importati
dal tema del sistema operativo.
4.1.1.1 MainPage
MainPage è la pagina che si apre all’avvio dell’applicazione. Essa presenta il controllo map
per visualizzare la mappa, una textbox in cui inserire un indirizzo al fine di cercare la relativa
mappa e il menù Application Bar16, composto dai seguenti elementi:
15
Terminologia utilizzata nella pagina di impostazioni Tema di Windows Phone 7.5 16
Proposto come menù di default nelle applicazioni Windows Phone
18
bottone find me ( ): utilizza la localizzazione del dispositivo (se abilitata) per
individuare la posizione geografica dell’utente sulla mappa. Il pushpin che indica la
posizione dell’utente definisce anche la posizione del centro del raggio di analisi;
bottone set pov ( ): una volta premuto set pov si può toccare un punto sulla
mappa affinché appaia un pushpin che indica la posizione del centro del raggio di
analisi;
bottone scan ( ): se è stato definito il centro di analisi (tramite find me o set pov),
va alla pagina ResultsPage;
voce di menù switch view: questa voce permette di cambiare tipologia di
visualizzazione delle mappe da cartine stradali a immagini satellitari e viceversa;
voce di menù settings: va alla pagina SettingsPage;
voce di menù about: va alla pagina AboutPage.
Nel caso in cui l’applicazione non riesca ad accedere ad una connessione internet viene
visualizzato un messaggio di avviso e l’esperienza utente ne viene fortemente limitata: non
vengono visualizzate le mappe né i pushpin degli impianti e il servizio di localizzazione non
è disponibile.
4.1.1.2 SettingsPage
19
In questa pagina l’utente può selezionare se consentire o meno all’applicazione di
accedere al servizio di localizzazione17 del cellulare utilizzando gli appositi radio button.
L’utente può inoltre modificare l’ampiezza del raggio di analisi toccando sul touch screen
uno dei valori disponibili.
La modifica delle impostazioni viene immediatamente memorizzata e rimane salvata finché
l’applicazione è installata.
4.1.1.3 ResultsPage
La pagina rende visibili i risultati della stored procedure Statistics_GetByRegion organizzati
in una tabella dinamica. Di default il periodo di analisi è quello più recente disponibile
nella tabella ReportPeriod del database PRTR, l’utente può selezionare un periodo diverso
dal menù appbar generato dinamicamente con le voci di tutti i periodi presenti in tale
tabella. In caso di assenza di connessione Internet non è ovviamente possibile visualizzare
alcun dato.
17 Le normative Microsoft riguardo la tutela della privacy impongono di fornire informazioni riguardo
l’utilizzo del servizio di localizzazione da parte dell’applicazione
20
4.1.1.4 AboutPage
La pagina presenta alcune informazioni riguardo l’applicazione, il progetto PRTR e il
contatto dello sviluppatore.
4.1.2 Interfacciamento a web service
L’applicazione utilizza i servizi offerti dai web service GeocodeService e PRTRService
referenziando i web service stessi e istanziando un oggetto della classe definita dal relativo
contratto, tramite il quale possono essere chiamati i metodi esposti.
4.1.3 Esempio d’uso
Si supponga che l’utente voglia visualizzare le emissioni inquinanti in un raggio di 40 km
dalla propria posizione. Una volta avviata l’applicazione, egli apre il menù application bar,
tocca la voce settings e si assicura che nella pagina apertasi il servizio di localizzazione sia
abilitato e che il raggio di scansione sia impostato al numero di chilometri desiderati,
21
dopodiché torna alla main page tramite il bottone back18 ( ). A questo punto l’utente
tocca il bottone find me ( ) e, di conseguenza, sulla mappa appare il pushpin che indica la
sua posizione. È così definito il cerchio di interesse per l’analisi, dove il centro è il pushpin
rappresentante la posizione dell’utente e il raggio è quello precedentemente scelto. Si
possono ora visualizzare le emissioni inquinanti presenti in tale zona toccando il pulsante
scan ( ), che apre la pagina contenete i risultati della ricerca. Una volta giunto in questa,
all’utente compaiono le emissioni registrate nel periodo più recente disponibile, che può
essere cambiato con uno degli altri periodi di analisi a disposizione selezionando
quest’ultimo nel menù application bar.
4.1.4 Implementazione
In questo capitolo viene trattata l’implementazione degli aspetti più rilevanti inerenti la
logica e, in alcuni casi, l’interfaccia grafica dell’applicazione Windows Phone.
4.1.4.1 Referenziazione di web service
La referenziazione di un web service WCF (come GeocodeService e PRTRService) è un
procedimento molto semplice se si utilizza l’IDE Visual Studio, grazie all’opzione Add
Service Reference. A titolo d’esempio viene riportata la referenziazione di PRTRService.
Dal menù Solution Explorer si clicca con il tasto destro sulla voce Service
References;
Si seleziona Add Service Reference;
Nella campo Address della nuova finestra apparsa si inserisce l’indirizzo del web
service, in questo caso: http://prtrws.units.it/statistics.svc?wsdl, e si clicca Go;
Si immette il namespace da utilizzare, in questo caso Statistics, e si clicca Ok.
A questo punto l’IDE genera automaticamente il codice che referenzia il web service.
18
Presente in tutti gli smartphone con s.o. Windows Phone, assieme al bottone Home ( ) e Search ( )
22
Finestra Add Service Reference di Visual Studio 2010
Per utilizzare i servizi nel codice dell’applicazione è sufficiente istanziare la classe auto-
generata da Visual Studio definita dal contratto di servizio e chiamare i metodi desiderati.
4.1.4.2 Memorizzazione delle impostazioni
La classe statica AppSettings funge da magazzino dati per l’applicazione, infatti contiene
solo variabili, le quali sono utilizzate in modo condiviso dalle altre classi.
18 public static class AppSettings 19 { 20 public static IsolatedStorageSettings appSettings = 21 IsolatedStorageSettings.ApplicationSettings; 22 public static double[] longAndLatInDecimal = new double[2]; 23 24 public static int[] longInDegrees = new int[3]; 25 public static int[] latInDegrees = new int[3]; 26 }
La variabile più importante della classe in questione è appSettings, la quale riferisce un
oggetto di tipo IsolatedStorageSettings. Tale oggetto è adatto alla memorizzazione
23
persistente delle impostazioni dell’applicazione19, le quali vengono salvate sotto forma di
coppia chiave-valore.
Gli array longAndLatInDecimal, longInDegrees e latInDegrees sono utilizzati per contenere,
rispettivamente, i valori di longitudine e latitudine espressi in decimi; il valore della
longitudine espresso in gradi e il valore della latitudine espresso in gradi.
Proseguendo nella trattazione si può vedere come le variabili qui esposte vengano
utilizzate.
4.1.4.3 Avvio dell’applicazione
Come detto in precedenza, nella classe App è stato modificato il metodo
Application_Launching (di default già definito ma privo di corpo) affinché al primo avvio
dell’applicazione vengano generate le impostazioni di localizzazione e lunghezza del
raggio di analisi.
62 // Codice da eseguire all'avvio dell'applicazione (ad esempio da Start) 63 // Questo codice non verrà eseguito quando l'applicazione viene riattivata 64 private void Application_Launching(object sender, LaunchingEventArgs e) 65 { […] 67 if (!AppSettings.appSettings.Contains("Location")) 68 { 69 MessageBoxResult m = MessageBox.Show("Sharing this information helps us" + 70 " to provide and improve our mapping and local search services. We won't" + 71 " store the information or use it to identify or contact you.","Allow this" 72 + " application to access and use your location?", 73 MessageBoxButton.OKCancel); 74 if (m == MessageBoxResult.OK) 75 { 76 AppSettings.appSettings.Add("Location", true); 77 } 78 else 79 { 80 AppSettings.appSettings.Add("Location", false); 81 } 82 AppSettings.appSettings.Save(); 83 } 84 85 86 if (!AppSettings.appSettings.Contains("Radius")) 87 { 88 AppSettings.appSettings.Add("Radius", 20); 89 AppSettings.appSettings.Save(); 90 } 91 }
19
In particolare tale memoria è accessibile unicamente dall’applicazione che la utilizza
24
All’avvio dell’applicazione viene controllato l’IsolatedStorageSettings appSettings: se esso
non contiene la chiave Location, allora viene utilizzata una MessageBox per chiedere
all’utente se desidera che l’applicazione sia abilitata a localizzare il dispositivo smartphone.
La risposta di tipo bool viene dunque memorizzata nella chiave Location.
In modo analogo, qualora non sia salvata la lunghezza del raggio di analisi, questa viene
impostata a 20 (km) e memorizzata.
4.1.4.4 Implementazione delle mappe
Il controllo che consente di navigare nelle mappe Bing Maps è implementato
nell’interfaccia utente della pagina MainPage.xaml:
1 <phone:PhoneApplicationPage .. […] 15 xmlns:myMap="clr-namespace:Microsoft.Phone.Controls.Maps; assembly=Microsoft.Phone.Controls.Maps">
Nella dichiarazione dei namespaces nella root tag viene mappato il namespace relativo al
controllo.
27 <Grid x:Name="MapPanel" Grid.Row="0" Margin="0,0,12,0"> 28 <myMap:Map Margin="12,0,0,0" HorizontalAlignment="Stretch" 29 Name="bingMap" 30 VerticalAlignment="Stretch"
31 CredentialsProvider=" " 32 Tap="SetMyPoVonMap" ZoomBarVisibility="Visible" 33 ZoomLevel="2" ScaleVisibility="Visible"> 34 </myMap:Map> 35 </Grid>
Nel corpo della pagina viene dichiarato il controllo ed i relativi attributi, i quali specificano
le proprietà relative al controllo stesso, quelle relative alla visualizzazione delle mappe e
quelle relative alla gestione di eventi. In particolare:
il valore di Name specifica il nome che può essere utilizzato come riferimento al
controllo nel codice C#;
il valore di CredentialsProvider riporta la chiave20 per l’autenticazione
dell’applicazione che utilizza il servizio Bing Maps;
l’attributo Tap21 intercetta il tocco dell’utente sul controllo ed avvia il metodo
SetMyPoVonMap.
20
Una stringa alfanumerica necessaria per l’utilizzo delle API di Bing Maps
25
4.1.4.5 Localizzazione del dispositivo
La localizzazione del dispositivo viene effettuata nella logica della pagina MainPage ed
utilizza la classe GeoCoordinateWatcher della libreria System.Device.Location.
36 GeoCoordinateWatcher myWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High); […] 118 private void GetMyPosition(object sender, EventArgs e) 119 { […] 124 if ((bool)AppSettings.appSettings["Location"] != true) 125 MessageBox.Show("The location service is disabled. Go to the settings" 126 + " page to turn location service on"); 127 else 128 { 129 myWatcher.MovementThreshold = 20; 130 myWatcher.PositionChanged += new 131 EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>> 132 (myWatcher_PositionChanged); 133 myWatcher.Start(); 134 } 135 } 136 137 void myWatcher_PositionChanged(object sender, 138 GeoPositionChangedEventArgs<GeoCoordinate> e) 139 { 140 var myPosition = myWatcher.Position; 141 142 if (!myPosition.Location.IsUnknown) 143 { 144 txtSearch.Text = ""; 145 myPosPin.Location = myPosition.Location; 146 myPosPin.Template = (ControlTemplate) 147 Application.Current.Resources["myPosPinTemplate"]; 148 149 bingMap.Children.Remove(myPoVPin); 150 bingMap.Children.Remove(myPosPin); 151 bingMap.Children.Add(myPosPin); 152 bingMap.SetView(myPosition.Location, 17); 153 154 AppSettings.longAndLatInDecimal[0] = myPosition.Location.Longitude; 155 AppSettings.longAndLatInDecimal[1] = myPosition.Location.Latitude; 156 157 povSet = true; 158 } 159 }
La variabile myWatcher si riferisce ad una istanza della classe GeoCoordinateWatcher, di
cui viene specificato il livello di accuratezza di rilevamento della posizione. Il metodo
GetMyPosition viene avviato al tocco del tasto find me ( ): se è possibile usufruire del
servizio di localizzazione, allora esso assegna a myWatcher la proprietà
MovementThreshold e l’evento PositionChanged, dopodiché avvia l'acquisizione dei dati
dal provider di posizione corrente con il metodo Start. PositionChanged indica che è
cambiata la posizione del dispositivo e l’handler assegnatogli viene avviato quando la
distanza in metri tra l’ultima e la nuova posizione registrata è pari o superiore a quella
21
Tap è un GestureEvent del tutto analogo a Click
26
assegnata a MovementThreshold22. Si noti che dopo l’esecuzione di questo metodo
l’applicazione effettua continuamente la localizzazione del dispositivo, provocando così un
forte consumo di batteria dello stesso. Per ovviare a questo problema, negli altri metodi di
MainPage è solitamente presente il comando myWatcher.Stop(), che interrompe il
processo di localizzazione.
myWatcher_PositionChanged viene chiamato dall’evento myWatcher.PositionChanged e si
occupa di rimuove gli eventuali pushpin identificativi del centro del cerchio di analisi
presenti, posizionare il pushpin rappresentante la posizione dell’utente (la cui
raffigurazione è descritta in un template) e salvare le coordinate nell’apposito array della
classe AppSettings. Infine, il metodo setta il valore della variabile di tipo bool povSet a
true, ad indicare che è presente il centro d’analisi e quindi è possibile passare alla
visualizzazione dei risultati.
4.1.4.6 Scelta del centro d’analisi
Come detto precendemente, oltre ad utilizzare la posizione dell’utente come centro del
cerchio d’analisi, è possibile sceglierne uno a piacere in qualsiasi punto della Terra.
169 private void SetMyPoView(object sender, EventArgs e) 170 { 171 myWatcher.Stop(); 172 173 ApplicationBarIconButton btnPoV = 174 (ApplicationBarIconButton)ApplicationBar.Buttons[1]; 175 if (povActive) 176 { 177 povActive = false; 178 btnPoV.IconUri = new Uri("/Images/appbar.eye.png", UriKind.Relative); 179 } 180 181 else 182 { 183 povActive = true; 184 btnPoV.IconUri = 185 new Uri("/Images/appbar.location.round.png", UriKind.Relative); 186 } 187 } 188 189 private void SetMyPoVonMap(object sender, GestureEventArgs e) 190 { 191 if (povActive) 192 { 193 myPoVPin.Location = 194 bingMap.ViewportPointToLocation(e.GetPosition(this.bingMap)); 195 myPoVPin.Template = 196 (ControlTemplate)Application.Current.Resources["myPoWTemplate"]; 197 198 bingMap.Children.Remove(myPosPin); 199 bingMap.Children.Remove(myPoVPin); 200 bingMap.Children.Add(myPoVPin);
22
La proprietà accetta dati di tipo double
27
201 202 AppSettings.longAndLatInDecimal[0] = myPoVPin.Location.Longitude; 203 AppSettings.longAndLatInDecimal[1] = myPoVPin.Location.Latitude; 204 205 povSet = true; 206 207 ApplicationBarIconButton btnPoV = 208 (ApplicationBarIconButton)ApplicationBar.Buttons[1]; 209 btnPoV.IconUri = new Uri("/Images/appbar.eye.png", UriKind.Relative); 210 povActive = false; 211 } 212 }
Quando l’utente tocca il tasto set pov ( ) viene eseguito il metodo SetMyPoView, il quale,
alternativamente, modifica l’icona del tasto stesso ( ) e assegna alla variabile-flag
povActive il valore true oppure reimposta l’icona di partenza ( ) e assegna a povActive il
valore false. Questo serve ad attivare la possibilità di posizionare il pushpin indicante il
centro d’analisi o disattivarla se è già attiva.
SetMyPoVonMap viene lanciato quando l’utente tocca il controllo Map. La condizione if
alla riga 191 fa sì che il metodo effettui i suoi comandi solo se è stato precedentemente
premuto il tasto set pov ( ). Se la condizione è soddisfatta, le coordinate del punto della
mappa toccato dall’utente vengono salvate nell’array longAndLatInDecimal e utilizzate per
generare il pushpin myPoVPin. Sono inoltre eseguite procedure analoghe a quelle
effettuate nel metodo myWatcher_PositionChanged precedentemente discusso.
4.1.4.7 Generazione dei pushpin rappresentanti gli impianti industriali
Il seguente estratto di codice è scritto all’interno del metodo GenerateFacilities, a sua volta
chiamato dal costruttore MainPage. Per ottenere le coordinate degli impianti viene
utilizzato il metodo LoadFacilities offerto dal web service PRTRService.
238 int[] latitudeDeg = new int[3]; 239 int[] longitudeDeg = new int[3]; 240 241 var statistics = new StatisticsClient("BasicHttpBinding_IStatistics"); 242 243 statistics.LoadFacilitiesAsync(); 244 245 statistics.LoadFacilitiesCompleted += (s, e) => 246 { 247 foreach (var item in e.Result) 248 { […] 260 var myFacility = new FacilityInfoViewModel 261 { 262 LatitudeDeg = item.latitudeDeg, 263 LatitudeMin = item.latitudeMin, 264 LatitudeSec = item.latitudeSec, 265 LongitudeDeg = item.longitudeDeg, 266 LongitudeMin = item.longitudeMin, 267 LongitudeSec = item.longitudeSec
28
268 }; 269 270 latitudeDeg[0] = myFacility.LatitudeDeg; 271 latitudeDeg[1] = myFacility.LatitudeMin; 272 latitudeDeg[2] = myFacility.LatitudeSec; 273 longitudeDeg[0] = myFacility.LongitudeDeg; 274 longitudeDeg[1] = myFacility.LongitudeMin; 275 longitudeDeg[2] = myFacility.LongitudeSec; 276 277 double latitude = Utilities.DegToDec(latitudeDeg); 278 double longitude = Utilities.DegToDec(longitudeDeg); 279 280 Location location = new Location{ Latitude=latitude, 281 Longitude=longitude }; 282 283 bingMap.Children.Add(new Pushpin { 284 Template = 285 (ControlTemplate) 286 Application.Current.Resources["myFacilityPinTemplate"], 287 Location = location 288 }); 289 } 290 };
La variabile statistics riferisce un oggetto di classe StatisticsClient, che è stata generata
dall’ambiente di sviluppo al referenziamento del web service PRTRService. Viene dunque
utilizzato il metodo LoadFacilities in modo asincrono, dove al completamento dello stesso
la variabile e.Result contiene la lista di oggetti FacilityInfo. Per ogni oggetto ottenuto viene
costruito il relativo ViewModel FacilityInfoViewModel e viene generato un pushpin nella
mappa. Si noti che le coordinate degli impianti nel database PRTR sono espresse in gradi,
mentre Bing Maps utilizza coordinate espresse come numero decimale, pertanto si ricorre
al metodo DegToDec della classe Utilities che effettua la conversione richiesta.
4.1.4.8 Geolocalizzazione
Il servizio di geolocalizzazione offerto dal web service GeocodeService è utilizzato quando
l’utente digita un indirizzo nell’apposito campo di ricerca e preme invio da tastiera.
48 private void txtSearch_KeyDown(object sender, KeyEventArgs e) 49 { 50 if (e.Key == Key.Enter) 51 { […] 59 if (txtSearch.Text != "") 60 { […] 62 GeocodeRequest geocodeRequest = new GeocodeRequest(); 63 geocodeRequest.Credentials = new Credentials(); 64 geocodeRequest.Credentials.ApplicationId =
65 " "; 66 67 geocodeRequest.Query = txtSearch.Text; 68 69 FilterBase[] filters = new FilterBase[1]; 70 filters[0] = new ConfidenceFilter()
29
71 { 72 MinimumConfidence = Confidence.High 73 }; 74 75 GeocodeOptions geocodeOptions = new GeocodeOptions(); 76 geocodeOptions.Filters = 77 new ObservableCollection<FilterBase>(filters); 78 geocodeRequest.Options = geocodeOptions; 79 80 GeocodeServiceClient geocodeService = 81 new GeocodeServiceClient("BasicHttpBinding_IGeocodeService"); 82 geocodeService.GeocodeCompleted += 83 new EventHandler<GeocodeCompletedEventArgs> 84 (geocodeService_GeocodeCompleted); 85 geocodeService.GeocodeAsync(geocodeRequest); 86 } 87 } 88 } 89 90 void geocodeService_GeocodeCompleted(object sender, GeocodeCompletedEventArgs e) 91 { 92 GeocodeResponse geocodeResponse = e.Result; 93 var geoResult = 94 (from r in geocodeResponse.Results orderby (int)r.Confidence ascending 95 select r).FirstOrDefault(); 96 97 if (geoResult != null) 98 { 99 txtSearch.Text = geoResult.DisplayName; 100 bingMap.SetView(geoResult.BestView); 101 } 102 else 103 MessageBox.Show("Can't find the specified location"); 104 }
txtSearch_KeyDown intercetta la digitazione del tasto Invio nel campo txtSearch. La classe
GeocodeRequest, propria del web service GeocodeService, permette di definire i parametri
della richiesta di geolocalizzazione per mezzo delle sue proprietà. Le credenziali specificate
a riga 65 sono le stesse che permettono di utilizzare le mappe Bing Maps, le opzioni sono
definite nell’oggetto di tipo GeocodeOptions e settano il filtro che imposta il livello di
confidenza della geolocalizzazione ed infine alla proprietà Query viene assegnato il testo
inserito dall’utente nel campo di ricerca. Pronta la richiesta, essa viene utilizzata come
parametro per il metodo GeocodeAsync.
La proprietà Results della classe GeocodeResponse può contenere un array di oggetti
GeocodeResult. La variabile geoResult riferisce quello tra essi che risulta più affidabile
grazie alla espressione LINQ scritta nelle righe 94 e 95. Infine, qualora sia stato
effettivamente trovato un risultato, l’indirizzo di questo viene scritto nel campo di ricerca e
il controllo Map mostra la relativa mappa con l’ausilio della proprietà BestView.
4.1.4.9 Visualizzazione dei risultati
Segue il codice del metodo GenerateGrid della classe ResultsPage, che si occupa di
costruire la tabella in cui vengono esposti i dati delle emissioni inquinanti presenti nel
30
cerchio d’analisi il cui centro e raggio sono stati precedentemente definiti dall’utente
rispettivamente nelle pagine Main e Settings.
35 private void GenerateGrid(int idPeriod) 36 { 37 double totalAir = 0, totalUnderground = 0, 38 totalWater = 0, totalLand = 0, totalTotal = 0; 39 40 float radius = float.Parse(AppSettings.appSettings["Radius"].ToString()); 41 42 GenerateFields(); 43 44 var statistics = new StatisticsClient("BasicHttpBinding_IStatistics"); 45 46 statistics.GetByRegionAsync( 47 AppSettings.longInDegrees[0], 48 AppSettings.longInDegrees[1], 49 AppSettings.longInDegrees[2], 50 AppSettings.latInDegrees[0], 51 AppSettings.latInDegrees[1], 52 AppSettings.latInDegrees[2], 53 radius, 54 "en-US", 55 idPeriod 56 ); 57 58 statistics.GetByRegionCompleted += (s, e) => 59 { 60 List<EmissionInfoViewModel> EmissionInfos = 61 new List<EmissionInfoViewModel>(); 62 63 foreach (var item in e.Result) 64 { 65 EmissionInfos.Add(new EmissionInfoViewModel 66 { 67 FullName = item.FullName, 68 QuantityAir = item.QuantityAir, 69 QuantityInjection = item.QuantityInjection, 70 QuantityLand = item.QuantityLand, 71 QuantityWater = item.QuantityWater, 72 QuantityTotal = item.QuantityTotal 73 }); 74 75 RowDefinition row = new RowDefinition(); 76 gridResults.RowDefinitions.Add(row); 77 78 string[] emissionProperties = 79 EmissionInfoPropToArray(EmissionInfos[EmissionInfos.Count - 1]); 80 81 for (int j = 0; j < emissionProperties.Length; j++) 82 { 83 TextBlock txtData = new TextBlock(); 84 txtData.Text = emissionProperties[j]; 85 txtData.TextAlignment = TextAlignment.Center; 86 txtData.Margin = new Thickness(10,5,10,5); 87 Grid.SetRow(txtData, EmissionInfos.Count); 88 Grid.SetColumn(txtData, j); 89 gridResults.Children.Add(txtData); 90 } 91 92 totalAir += item.QuantityAir; 93 totalUnderground += item.QuantityInjection; 94 totalWater += item.QuantityWater; 95 totalLand += item.QuantityLand;
31
96 totalTotal += item.QuantityTotal; 97 98 } 99 100 if ( EmissionInfos.Count > 0 ) 101 { 102 RowDefinition row = new RowDefinition(); 103 gridResults.RowDefinitions.Add(row); 104 GenerateTotalRow(totalAir, totalUnderground, 105 totalWater, totalLand, totalTotal, EmissionInfos.Count ); 106 } 107 108 }; 109 }
Per generare e riempire le celle contenenti i dati delle emissioni si utilizza il metodo
GenerateGrid. Tra le diverse variabili inizializzate dal metodo, radius riferisce la lunghezza
del raggio estrapolata dalla memoria dell’applicazione. Il metodo GenerateFields costruisce
e riempie dinamicamente le prime celle della griglia, ovvero quelle rappresentanti i campi:
Chemical, Air, Underground, Water, Land e Total. Segue la chiamata del metodo
GetByRegion del web service PRTRService, che ha come parametri gli stessi della stored
procedure Statistics_GetByRegion23. Il metodo asincrono chiamato prosegue a riga 58
costruendo i ViewModel delle EmissionInfo e aggiungendo alla tabella gridResults una
nuova riga per ciascuno di essi. Le proprietà dell’EmissionInfoViewModel generato
vengono memorizzate nell’array di stringhe emissionProperties, grazie al metodo
EmissionInfoPropToArray. Il ciclo successivo crea un oggetto Text Block che funge da cella
per ogni stringa contenuta in emissionProperties. Il posizionamento della cella viene
specificato da Grid.SetRow e Grid.SetColumn e infine essa viene aggiunta alla tabella con il
metodo Add invocato sull’oggetto Children, proprietà della classe Grid. Qualora venga
trovata almeno una emissione, viene chiamato il metodo GenerateTotalRow il quale crea la
riga della tabella che contiene le somme dei vari campi.
Si ricorda che quando l’utente accede alla pagina ResultsPage, l’id del periodo utilizzato
come parametro nella chiamata del metodo GenerateGrid è quello del periodo più recente.
Quando invece l’utente seleziona dal menù un periodo differente, viene eseguito il codice
seguente:
161 private void periodMenu_Click(object sender, EventArgs e) 162 { 163 ApplicationBarPeriodItem period = (ApplicationBarPeriodItem)sender; 164 int id = period.Id; 165 txtPeriod.Text = period.Text; 166 gridResults.Children.Clear(); 167 GenerateGrid(id); 168 }
Con gridResults.Children.Clear la tabella viene completamente svuotata, dopodiché viene
effettuata una nuova chiamata a GenerateGrid con l’id del periodo selezionato.
23
Tale stored procedure viene utilizzata nel metodo GetByRegion di PRTRService, pagina 33
32
4.2 Web Service
4.2.1 Interfacciamento al client
Il web service WCF espone i servizi alle applicazioni attraverso il contratto, una speciale
interfaccia su cui viene applicato l’attributo ServiceContract. I metodi offerti hanno
l’attributo OperationContract. Ad esempio per i metodi GetByRegion e LoadPeriods del
contratto IStatistics di PRTRService è utilizzata la seguente sintassi:
9 [ServiceContract] 10 public interface IStatistics 11 { 12 [OperationContract] 13 EmissionInfo[] GetByRegion( 14 int longitudeDeg, 15 int longitudeMin, 16 int longitudeSec, 17 int latitudeDeg, 18 int latitudeMin, 19 int latitudeSec, 20 float range, 21 string cultureCode, 22 int idPeriod 23 ); 24 25 [OperationContract] 26 PeriodInfo[] LoadPeriods(); 27 […] 47 }
I modelli del servizio web sono esposti quando hanno l’attributo DataContract e le loro
proprietà sono esposte quando hanno l’attributo DataMember. Ad esempio il modello
EmissionInfo è così definito:
9 [DataContract] 10 public class EmissionInfo 11 { 12 [DataMember] 13 public string Emissions_Field_Air_Title { get; set; } 14 [DataMember] 15 public string Emissions_Field_Injection_Title { get; set; } 16 [DataMember] 17 public string Emissions_Field_Water_Title { get; set; } 18 [DataMember] 19 public string Emissions_Field_Land_Title { get; set; } 20 [DataMember] 21 public int IDPeriod { get; set; } 22 [DataMember] 23 public string FullName { get; set; } 24 [DataMember] 25 public string Title { get; set; } 26 [DataMember] 27 public DateTime StartDate { get; set; } 28 [DataMember] 29 public DateTime EndDate { get; set; } 30 [DataMember]
33
31 public double QuantityAir { get; set; } 32 [DataMember] 33 public double QuantityInjection { get; set; } 34 [DataMember] 35 public double QuantityWater { get; set; } 36 [DataMember] 37 public double QuantityLand { get; set; } 38 [DataMember] 39 public double QuantityTotal { get; set; } 40 }
4.2.2 Implementazione
La realizzazione dei metodi esposti nel contratto è definita in una classe che implementa il
contratto stesso. Il seguente codice riporta il funzionamento dei metodi GetByRegion e
LoadPeriods, mentre gli altri sono molto simili a questi e quindi non vengono discussi.
12 public class StatisticsService:IStatistics 13 { 14 EmissionInfo[] IStatistics.GetByRegion(int longitudeDeg, int longitudeMin, 15 int longitudeSec, int latitudeDeg, int latitudeMin, int latitudeSec, 16 float range, string cultureCode, int idPeriod) 17 { 18 var list = new List<EmissionInfo>(); 19 20 SqlConnection connection = new SqlConnection(); 21 connection.ConnectionString = 22 ConfigurationManager.ConnectionStrings["PRTR"].ConnectionString; 23 connection.Open(); 24 String storedProcedure = "Statistics_GetByRegion"; 25 SqlCommand command = new SqlCommand(storedProcedure, connection); 26 command.CommandType = CommandType.StoredProcedure; 27 28 command.Parameters.Add("@LongitudeDeg", SqlDbType.Int).Value = longitudeDeg; 29 command.Parameters.Add("@LongitudeMin", SqlDbType.Int).Value = longitudeMin; 30 command.Parameters.Add("@LongitudeSec", SqlDbType.Int).Value = longitudeSec; 31 command.Parameters.Add("@LatitudeDeg", SqlDbType.Int).Value = latitudeDeg; 32 command.Parameters.Add("@LatitudeMin", SqlDbType.Int).Value = latitudeMin; 33 command.Parameters.Add("@LatitudeSec", SqlDbType.Int).Value = latitudeSec; 34 command.Parameters.Add("@Range", SqlDbType.Float).Value = range; 35 command.Parameters.Add("@CultureCode", SqlDbType.NVarChar).Value = 36 cultureCode; 37 command.Parameters.Add("@IDPeriod", SqlDbType.Int).Value = idPeriod; 38 39 SqlDataReader dataReader = command.ExecuteReader(); 40 41 if (dataReader.HasRows) 42 { 43 while (dataReader.Read()) 44 { 45 list.Add(new EmissionInfo 46 { 47 Title = dataReader["Title"].ToString(), 48 Emissions_Field_Air_Title = 49 dataReader["Emissions_Field_Air_Title"].ToString(), 50 Emissions_Field_Injection_Title = 51 dataReader["Emissions_Field_Injection_Title"].ToString(), 52 Emissions_Field_Land_Title = 53 dataReader["Emissions_Field_Land_Title"].ToString(),
34
54 Emissions_Field_Water_Title = 55 dataReader["Emissions_Field_Water_Title"].ToString(), 56 StartDate = (DateTime)dataReader["StartDate"], 57 EndDate = (DateTime)dataReader["EndDate"], 58 FullName = dataReader["FullName"].ToString(), 59 IDPeriod = (int)dataReader["IDPeriod"], 60 QuantityAir = (double)dataReader["QuantityAir"], 61 QuantityInjection = (double)dataReader["QuantityInjection"], 62 QuantityLand = (double)dataReader["QuantityLand"], 63 QuantityWater = (double)dataReader["QuantityWater"], 64 QuantityTotal = (double)dataReader["QuantityTotal"] 65 }); 66 } 67 } 68 69 connection.Close(); 70 return list.ToArray(); 71 } 72 73 PeriodInfo[] IStatistics.LoadPeriods() 74 { 75 var list = new List<PeriodInfo>(); 76 77 SqlConnection connection = new SqlConnection(); 78 connection.ConnectionString = 79 ConfigurationManager.ConnectionStrings["PRTR"].ConnectionString; 80 String query = "SELECT * FROM ReportPeriod ORDER BY EndDate DESC"; 81 connection.Open(); 82 SqlCommand command = new SqlCommand(query, connection); 83 SqlDataReader dataReader = command.ExecuteReader(); 84 85 if (dataReader.HasRows) 86 { 87 while (dataReader.Read()) 88 { 89 list.Add(new PeriodInfo 90 { 91 id_Period = (int)dataReader["ID"], 92 title_Period = dataReader["Title"].ToString() 93 }); 94 } 95 } 96 97 dataReader.Close(); 98 connection.Close(); 99 100 return list.ToArray(); 101 } […] 276 }
La differenza principale nel funzionamento dei due metodi consiste nell’uso di una stored
procedure piuttosto che di una query. In entrambi i casi i metodi accettano come
parametri gli stessi della relativa stored procedure / query che implementano al loro
interno e ritornano una lista di oggetti EmissionInfo / PeriodInfo. Per accedere ai dati
presenti nel database PRTR viene effettuata una connessione Sql: la variabile connection
referenzia un’istanza della classe SqlConnection dove la proprietà ConnectionString
permette di identificare il nome del database. La stored procedure e la query sono salvate
come stringhe e utilizzate, assieme al parametro di connessione, per definire
35
l’SqlCommand command. Nella riga 26 viene specificato che il comando sql da eseguire è
una stored procedure, dopodiché seguono i parametri della stessa. Per l’esecuzione di
query invece non è necessario definire il CommandType. Aperta la connessione sql con il
metodo Open, si possono cominciare a leggere i dati individuati dallo SqlCommand.
Poiché i dati devono essere solamente visualizzati, si è scelto di utilizzare la classe
SqlDataReader, che legge e mantiene in memoria un record alla volta e risulta pertanto
una procedura leggera e veloce. La lettura dati funziona dunque per iterazione,
consultando record per record, finché non si raggiunge la fine della tabella. Per ciascun
record trovato viene generato un nuovo oggetto EmissionInfo / PeriodInfo e aggiunto nel
relativo array EmissionInfos / PeriodInfos. Infine, i metodi terminano l’esecuzione dello
SqlDataReader, chiudono la connessione sql e ritornano la lista di oggetti.
5. Conclusioni
L’obiettivo di creare un’applicazione smartphone per il sistema operativo Windows Phone
nel rispetto dei vincoli specificati nell’introduzione è stato raggiunto.
Per realizzare applicazioni con le stesse funzionalità per altri sistemi operativi (Android, iOS,
BlackBerry etc.) le procedure utilizzate sono analoghe. Tuttavia bisogna usare altri
linguaggi di scrittura (xml, java-android, objective-c etc.) ed altre tecnologie, ad esempio
Google Maps anziché Bing Maps etc.
Recentemente si è assistito ad un’importante innovazione nello sviluppo di applicazioni
smartphone. Infatti, il 13 giugno 2012, è stata rilasciata la versione stabile di PhoneGap,
una tecnologia open-source che permette di sviluppare un’unica applicazione mobile
“ibrida” con i linguaggi HTML5, CSS3 e Javascript. Tale software utilizza interfacce grafiche
web invece di quelle native e, quindi, può essere utilizzato dai vari sistemi operativi
smartphone, anche se con eventuali limitazioni.
5.1 Quantificazione del lavoro svolto
In riferimento al lavoro svolto sono riportati alcuni indici, suddivisi per linguaggio
utilizzato. Non sono stati considerati elementi dell’applicativo auto-generati dall’ambiente
di sviluppo.
Riguardo l’applicazione Windows Phone:
36
Logica, linguaggio C#:
- 978 righe di codice
- 10 classi
- 35 metodi
Interfaccia grafica, linguaggio XAML:
- 300 righe di codice
Riguardo il web service PRTRService:
Linguaggio C#:
- 418 righe di codice
- 5 classi
- 4 metodi
5.2 Stato attuale del lavoro
Attualmente l’applicazione è scaricabile gratuitamente dal Marketplace di Windows Phone,
nella sua versione 1.0.1.0. Le funzionalità offerte dal servizio web sono state ampliate, in
particolare il laureando ha costruito metodi che implementano le stored procedure
Statistics_GetByFacilityChemical e Statistics_GetByPeriod del database PRTR.
37
6. Bibliografia
Testi consultati:
Charles Petzold (2010) Programming Windows Phone 7, Redmond, Microsoft Press
Raffaele Bernardi (2010) Progetto e sviluppo di un applicativo basato su Google Earth
per la visualizzazione di dati di emissioni inquinanti, tesi di laurea triennale,
Università degli studi di Trieste
Rob Miles (2011) Windows Phone Programming in C#
Pollutant Release and Transfer Register Version 3.0 Technical Documentation
Siti web consultati:
http://create.msdn.com/en-US/education/quickstarts/
http://en.wikipedia.org/wiki/
http://www.ibm.com/developerworks/rational/library/content/RationalEdge/sep04/
bell/
http://msdn.microsoft.com/en-us/library
http://msdn.microsoft.com/it-it/library
http://programming4.us/mobile/3478.aspx
http://techknackblogs.com/2011/07/bing-maps-app-for-windows-phone-7-with-
code/
http://windowsphonegeek.com/Articles