Tesi di Laurea GECO MOBILE Una realizzazione J2ME per la

Transcript

Tesi di Laurea GECO MOBILE Una realizzazione J2ME per la
Università degli studi di Salerno
Facoltà di Scienze Matematiche Fisiche e Naturali
Corso di Laurea in Informatica
Tesi di Laurea
GECO MOBILE
Una realizzazione J2ME
per la georeferenziazione di utenti
all’interno di una mobile community
Relatori:
Dott.ssa Monica Sebillo
Dott. Michele Di Capua
Candidato:
Guardi Giovanni
056/100656
Anno accademico 2006 / 2007
1
Ringraziamenti
I miei più sentiti ringraziamenti alle persone che hanno reso
possibile la realizzazione di questa tesi, la prof. Monica Sebillo e il
dott. Michele Di Capua,
per l’ampia disponibilità e continua
assistenza concessa.
Ringraziamenti, inoltre, al dott. De Chiara e a tutto lo staff di U-S
che mi hanno sostenuto soprattutto nei momenti di maggiore
bisogno.
Un affettuoso ringraziamento ai miei Genitori che mi hanno dato
la possibilità di studiare sostenendomi in tutte le mie scelte. A loro
dedico con gioia il raggiungimento di questo importante traguardo.
A Tutti Voi Grazie.
2
Prefazione
Il progetto GECO MOBILE, illustrato in questa tesi, nasce dalla
volontà di realizzare una infrastruttura software in grado di erogare
servizi ad utenti di una mobile community1. Data la natura opensource2 del progetto, la prima necessità è stata quella di verificare
l’esistenza di librerie o servizi, con tale licensa [1], per l’erogazione
di mappe. Sono state comunque analizzate anche le soluzioni
commerciali disponibili di vari produttori come TomTom, Nokia
Maps e GoogleMapsMobile. Al momento della stesura di questo
documento infatti, esistono poche applicazioni mobili (tra cui la
stessa Google Mobile) che prelevano e visualizzano mappe da
Google e tutte con licenza commerciale. Il progetto quindi si
propone di realizzare una possibile alternativa open-source per un
servizio di visualizzazione grafica di mappe su dispositivo mobile,
da integrare in una architettura più ampia che realizza
l’infrastruttura di gestione di una mobile community. [2]
1
Una mobile community è costituita da un gruppo di utenti dotati di un terminale mobile in
grado di connettersi ad un server centrale per scambio di informazioni.
2
Open-source indica un software rilasciato con un tipo di licenza per la quale il codice
sorgente è lasciato alla disponibilità di eventuali sviluppatori
3
INDICE
1. INTRODUZIONE....................................................................... 6
1.2. Tempificazione delle attività ................................................ 10
1.3. Definizioni, Acronimi e Abbreviazioni............................... 11
2. DISPOSITIVI MOBILI E GIS ................................................ 13
2.2. Tecnologie e Linguaggi di Programmazione ....................... 15
2.2.1. Java2 Micro Edition ....................................................... 17
Configurazioni, Profili ed Optional-Package ....................... 18
Ambiente di sviluppo............................................................ 23
2.3. Connessioni di rete e Thread ................................................ 25
2.4. Mobile GIS ........................................................................... 31
2.4.1. Google Maps Mobile ..................................................... 34
3. REQUISITI DEL SISTEMA ................................................ 36
3.1. Requisiti funzionali............................................................... 37
3.2. Requisiti non funzionali........................................................ 38
3.3. Modello dei Casi d’uso......................................................... 38
3.3.1. Attori .............................................................................. 39
3.3.2. Diagramma dei casi d’uso.............................................. 40
3.3.3. Descrizione dei Casi d’uso............................................. 41
4. ANALISI DEI REQUISITI E MODELLI DI SISTEMA..... 48
4.1 Dizionario dei dati ................................................................. 48
4.2 Modelli dinamici.................................................................... 52
4.2.1 Sequence diagram ........................................................... 52
5. LA GEOREFERENZIAZIONE DI UTENTI ........................ 55
5.1 PROGETTAZIONE .............................................................. 55
5.2. Interfaccia utente .................................................................. 56
5.2.1. Descrizione dell’interfaccia utente .............................. 56
5.2 IMPLEMENTAZIONE ......................................................... 59
5.2.1 Suddivisione del sistema in componenti........................ 59
4
5.2.2. Descrizione dei sottosistemi ....................................... 59
Package principale ................................................................ 60
Algoritmo di gestione dei tiles.............................................. 67
Algoritmi di gestione delle funzioni del menù. .................... 79
Algoritmi di gestione delle funzioni di messaggistica. ........ 82
Package bluetooth................................................................. 88
Package funzioni................................................................... 89
Librerie matematiche esterne................................................ 91
6. L’ESEMPIO DELLA GIS COMMUNITY............................ 93
7. CONCLUSIONI ........................................................................ 98
8. SVILUPPI FUTURI................................................................ 100
APPENDICE A ........................................................................... 102
WEBGRAFIA.............................................................................. 106
BIBLIOGRAFIA......................................................................... 111
5
1. INTRODUZIONE
I sistemi moderni di georeferenziazione ed i navigatori satellitari
sono oramai una realtà ben consolidata e fanno parte del vivere
quotidiano anche di gran parte degli utenti di telefonia mobile. Gli
attuali sistemi di navigazione offrono potenti strumenti per la
navigazione tra cui calcoli di percorsi e tracciabilità di flotte
(marine e terrestri) commerciali. Ciò nonostante, non sono
altrettanto diffusi i sistemi di navigazione in cui al posto di percorsi
stradali vengano messe in risalto le informazioni sugli utenti. In
questa tesi, infatti, si è concentrata l’attenzione sull’utente e sulla
possibilità di fornire servizi, fin ad oggi legati al web ed al
personal-computer, che, oltre a mettere in comunicazione gli utenti
stessi, consentano anche di fornire informazioni sulla loro posizione
geografica.
Nasce così GECO MOBILE, un sistema client/server in cui la
componente server [rif. Giuseppe] gestisce la logica di back-end,
con,
ad
esempio,
funzionalità
di
registrazione
utenti,
visualizzazione geografica di una vmobil communty, ecc. La parte
client da me sviluppata, invece, consente ad un dispositivo mobile
di collegarsi al sistema e di visualizzare una mappa geografica su
6
cui sono indicate le posizioni degli singoli utenti della comunità.
tramite “marker3”. Su tale mappa ogni utente può visualizzare la
porzione di mappa di maggior interesse grazie alle funzioni di
zooming (ingrandimento di un immagine) e panning (scorrimento
dell’immagine nelle 4 direzioni). In aggiunta, sono state realizzate
le funzioni di base di quella che chiameremo “mobile community”
[3] con le quali si possono inviare e ricevere messaggi, conoscere
informazioni dettagliate di un utente, avere una lista di utenti che si
trovano entro un raggio di azione definito come parametro
dall’utilizzatore.
Il client quindi è in grado di impersonare uno specifico utente di
una community tramite un id assegnatogli durante la fase di
registrazione, recuperare mappe su cui georeferenziare utenti, ossia,
gestire le informazioni di tipo geografico che riguardano la
posizione degli utenti stessi e che fanno parte di una stessa
community, e fornire un servizio di localizzazione (LBS4) e di
comunicazione integrato. Come server di mappe è stato utilizzato
un servizio gratuito di Google che consente di prelevare porzioni di
3
Un marker è un segnaposto grafico molto in uso su mappe geografiche per identificare un
punto di interesse
4
Location Based Service
7
mappa sotto forma di immagini (chiamati tiles) di dimensioni
ridotte.
Il client mobile, quindi, ricompone la mappa da visualizzare
utilizzando i tiles richiesti “on-demand” al servizio di Google. I
tiles hanno dimensione fissata e si è reso necessario definire un
algoritmo per ricomporre la mappa principale e per navigare tale
mappa. I servizi che il dispositivo richiede in aggiunta, via http,
sono: la visualizzazione degli utenti “attivi” della community, la
visualizzazione degli utenti che si trovano ad una certa distanza
impostata dall’utente, l’invio delle proprie coordinate, prese dal
ricevitore GPS, al database centralizzato. Le coordinate che
vengono inviate fanno riferimento alla posizione corrente e
vengono acquisite tramite segnale NMEA, opportunamente filtrato,
prelevato da dispositivo GPS via protocollo bluetooth.[6]
8
Organizzazione della Tesi
Nel capitolo 1 viene illustrato lo scopo del progetto con un
resoconto dei tempi impiegati per l’attività di ricerca, studio e
implementazione del sistema.
Nel capitolo 2 vengono trattati i dispositivi hardware, il linguaggio
di programmazione adoperato e il significato di Gis per mobile.
Nel capitolo 3 vengono analizzati i requisiti del client mobile ed i
suoi
use-case.
Viene,
inoltre,
data
una
prima
specifica
dell’interfaccia utente.
Nel capitolo 4 vengono esplicitati gli use case sotto forma di
sequence diagram in modo da dare una visione temporale degli
eventi secondo il linguaggio UML.
Nel capitolo 5 vengono analizzate le strategie di progettazione e
viene fatta una analisi approfondita sull’implementazione passando
in rassegna i diversi punti salienti del codice sorgente.
Il capitolo 6 mostra una serie di screenshot dell’applicazione e del
suo funzionamento per dare un’ idea più visiva della realizzazione.
9
Il capitolo 7 illustra i risultati raggiunti in termini di ricerca di una
soluzione open source e in termini di implementazione.
Il capitolo 8 infine descrive gli eventuali sviluppi successivi.
1.2. Tempificazione delle attività
La progettazione è stata articolata in più fasi con i necessari ricicli,
come riportato nel seguente diagramma di Gantt :
10
1.3. Definizioni, Acronimi e Abbreviazioni
GECO
GeoCoded Community , community geografica
Tile
unità grafica minima di Google. Singola cella
256x256 contenente una porzione di mappa.
Panning
Spostamento della mappa in una delle 4 direzioni
Zooming
Ingrandimento della mappa
Georeferenziazione
Visualizzazione di oggetti reali su di una mappa
geografica.
GPS
Global Positioning System (sistema di localizzazione
satellitare)
NMEA
Standard Europeo per segnali GPS di latitudine,
longitudine, altitudine,..
GIS
Geographic Information System
11
J2EE
Java 2 Enterprise Editino. Piattaforma di sviluppo
software basata su tecnologia java ed orientato ai
servizi lato server.
J2ME
Java 2 micro Editino. Piattaforma di sviluppo
software basata su tecnologia java ed orientata ai
dispositivi mobili come palmari, PDA e cellulari.
12
2. DISPOSITIVI MOBILI E GIS
Col termine GIS (Geografic Information System) si vuol indicare
tutto l’insieme delle procedure, dell’hardware, del software, delle
banche dati e delle persone che agiscono su dati di tipo spaziale per
analisi, interpretazione e produzione di un output. [7] Un GIS
interpreta il mondo reale attraverso immagini di vario tipo, ne
specifica il significato ed effettua elaborazioni e manipolazioni atte
a produrre un ben determinato risultato in output secondo gli
schemi e i criteri predeterminati dal sistema stesso. [8] In un GIS
vengono combinati strati di informazione in merito ad un
determinato
luogo
geografico
per
meglio
capire
le
sue
caratteristiche ed eventuali correlazioni con altri fenomeni o luoghi.
[9]
La funzione dei GIS è quindi quella di creare un output che
può prendere la forma di MAPPE, DIAGRAMMI e REPORT.
Questo output è creato dopo le fasi di cattura, immagazzinamento,
query ed analisi di dati spaziali. Un dato geografico, dovendo
trattare con macchine e personal-computer, può essere di 3 tipologie
diverse: punto, linea o poligono. [10]
Il dato geografico è composto da 2 parti:
13
- una parte descrittiva, che rappresenta le caratteristiche del
dato stesso (es. nome di un fiume, di una strada, etc)
- una parte spaziale, che per sua natura è legata ad altre
componenti, e rappresenta il mondo reale.
Grazie ai GIS (Biallo, 2005)è possibile analizzare un’area specifica
del territorio per conoscerne caratteristiche descrittive, spaziali e,
attraverso analisi e sovrapposizione di mappe, fornire ad un utente
esperto gli strumenti necessari che sono alla base di un processo
decisionale. Esistono ad oggi numerosi software GIS sia opensource che proprietari e in svariati campi applicativi[11].
14
2.2. Tecnologie e Linguaggi di Programmazione
L’evoluzione dei dispositivi mobili e’ in continuo avanzamento. Un
tempo un telefono cellulare era adoperato solo per effettuare
chiamate e con qualche funzione di messagistica. Oggi i telefoni
cellulari stanno divenendo sempre più simili a dei veri e propri
microcomputer grazie ai quali sono state realizzate molte altre
funzionalità. I telefoni cellulari moderni si sono variegati in base a 3
tipologie principali:
1) Mobile Phone: altresì chiamato cellular phone, e’ il
classico dispositivo elettronico per la comunicazione mobile
attraverso le reti di telefonia mobile. Solitamente offre pochi
servizi aggiuntivi tra cui invio e ricezione SMS, MMS,
EMAIL e raramente servizi multimediali come foto e video.
2) Smartphone: è un dispositivo portatile che abbina
funzionalità di gestione dei dati personali e di telefono. Può
derivare dall’evoluzione di un PDA a cui si aggiungono
funzioni di telefono o, viceversa, da un telefono a cui si
aggiungono funzioni di un PDA. La loro caratteristica più
interessante è la
15
possibilità
di
installare
altri
programmi
applicativi
estendendone le funzionalità.
3) PDA: acronimo di Personal Digital Assistant. E’ un
computer di dimensioni contenute in grado di eseguire tutte le
funzionalità
di
uno
smartphone
e
oltre
ma
non
necessariamente quelle di telefonia. [12]
Ognuna di queste tipologie si differenzia per il tipo di sistema
operativo che adopera e per i servizi di cui e’ dotato. I Mobile
Phone sono ovviamente i dispositivi più limitati in termini di risorse
di cui dispongono e di potenza di calcolo. Su di essi si e’ basata la
nostra attenzione. SmartPhone e PDA sono tecnologicamente più
avanzati e offrono maggiore capacità di immagazzinamento e
maggiore potenza di calcolo. La capacità di immagazzinamento dei
dati e’ data da due fattori: la memoria di base di cui dispone il
dispositivo e la memoria aggiuntiva che, se presente, può essere
ampliata con memorie di vario tipo.
La quasi totalità di dispositivi mobili disponibili delle 3 tipologie
consente di eseguire applicazioni java grazie alla cosiddetta “virtual
machine” che la SUN MICROSYSTEM realizzato sotto forma di
specifiche e requisiti minimi che devono essere soddisfatti.
16
2.2.1. Java2 Micro Edition
Nel
1990,
Sun
Microsystem
realizzò
un
linguaggio
di
programmazione per i dispositivi elettronici che fu inizialmente
chiamato “OAK”. Oggi tale linguaggio è conosciuto come JAVA.
Successivamente JAVA fu distinto in 3 diverse piattaforme (Figura
1): J2EE per le soluzioni “enterprise”, J2SE per le soluzioni
“desktop” e le applicazioni internet e J2ME per gli “embedded
device”
Figura 1 Piattaforme Java
Purtroppo la grande varietà di dispositivi mobili, le diverse
caratteristiche tecnologiche e i diversi sistemi operativi ha reso
necessario effettuare una ulteriore differenziazione nell’ambito
17
della stessa J2ME[13]. Allo scopo di specializzare le piattaforma
target di sviluppo, nell’ambito mobile, sono state introdotte le
definizioni di
configurazione, profilo ed optional package.
Attraverso quello che viene chiamato JCP (Java Community
Process) e le JSR (Java Specification Request), la SUN estende
continuamente la piattaforma J2ME e data la veloce evoluzione dei
dispositivi attuali è facile prevedere in un futuro non molto lontano
una nuova evoluzione anche della piattaforma stessa. [14]
Configurazioni, Profili ed Optional-Package
Le 3 tipologie si differenziano come detto precedentemente in base
a caratteristiche tecnologiche differenti. Per questo motivo SUN ha
creato le configurazioni che rappresentano java virtual machine
differenti a seconda delle potenzialità del dispositivo.
Esistono 2 tipi di Configurazioni: CLDC (Connected Limited
Device Configuration) e CDC (Connected Device Configuration).
CLDC: Interfaccia utente semplificata, quantità di memoria limitata
(da 150kb a 512kb), processori a 16 o 32 bit,
18
CDC: Maggiori interfacce disponibili, maggiore quantità di
memoria a disposizione, connettività a diverse tipologie di reti.
Figura 2 Configurazioni, profili ed optional-package
In particolare la CLDC si occupa di:
• definire le caratteristiche del linguaggio Java e della Virtual
Machine supportate;
• fornire un set minimo di librerie di base;
• gestire gli stream di I/O;
• sicurezza;
• networking;
• internazionalizzazione;
19
lasciando ai profili:
• la gestione del ciclo di vita delle applicazioni (installazione,
lancio, cancellazione);
• l'implementazione di interfacce utenti;
• la "cattura" e la gestione degli eventi;
• l'interazione tra l'utente e l'applicazione;
Data la notevole diversità degli apparati elettronici, oltre alle
configurazioni son stati introdotti i profili che vanno a ridefinire e a
specializzare ulteriormente la categoria cui appartengono (CDC o
CLDC).
Un
profilo
quindi
completa
una
configurazione
aggiungendo ulteriori informazioni (e quindi classi) per la specifica
tipologia di device utilizzata. Entrambe le configurazioni in j2me
hanno uno o più profili associati. Profili e Configurazioni
definiscono quindi un insieme di JAVA API. Nello specifico, il
profilo classico di riferimento per CLDC per dispositivi mobili è
MIDP mentre per CDC è il Foundation Profile.
20
Le midlet java sono quindi le applicazioni java per dispositivi
mobili basate sul profilo MIDP. Attualmente, la versione di
riferimento per MIDP è la 2.1 che definisce, in aggiunta alle classi
di CLDC, altri 3 packages: [15]
Javax.microedition.lcdui
Javax.microedition.midlet
Javax.microedition.rms
La classe lcdui è quella incaricata di gestire l’interfaccia utente.
Essa contiene le api per la grafica di “alto-livello” e di “bassolivello”. La classe midlet è fondamentale per un applicazione midlet
la quale deve contenere almeno una classe derivata dalla classe
astratta javax.microedition.midlet.MIDlet. la versione 2.1 di MIDP
estende le precedenti con un insieme di api per il multimedia ed i
giochi. Alcune di esse sono servite per implementare funzioni come
panning e grafica nel progetto realizzato. [16]
La classe rms si occupa di gestire i meccanismi di memorizzazione
e di archiviazione sul dispositivo mobile ed è stata presa in
considerazione per eventuali sviluppi futuri.
21
In aggiunta a configurazioni e profili, gli optional-package servono
a definire librerie esterne per usi specifici. Essi estendono
l’ambiente di runtime ma non sempre sono così universali come
configurazioni e profili. Alcuni dispositivi supportano gli optionalpackage mentre altri no ed è per questo che sono definiti “optional”.
Nel nostro progetto abbiamo fatto uso di un optional-package
appartenente alle specifiche JSR82 (le API Bluetooth) e di due
librerie per i calcoli matematici necessari a gestire i tiles e la veste
grafica (Sanna, 2007). Di questi parleremo nel dettaglio più avanti.
[17]
22
Ambiente di sviluppo
Per la scrittura del codice della midlet sono stati presi in
considerazione diversi fattori nella scelta dell’ambiente di sviluppo.
Trattandosi di un applicazione strettamente legata ai dispositivi
mobili, la nostra attenzione si è rivolta a quei tool che mettono a
disposizione una serie di utilità configurabili e che allo stesso tempo
siano compatibili con la stragrande maggioranza dei dispositivi in
commercio. La scelta è caduta su ECLIPSE con il suo add-on
ECLIPSE-ME. Per testare la midlet nella fase di pre-rilascio sul
dispositivo invece si è utilizzato il classico WTK della SUN
MICROSYSTEM. Vediamo a grandi linee gli step del processo
produttivo.
Innanzitutto, si necessita di una J2SE SDK, ossia la virtual machine
standard in versione 6.0 per l’ambiente di base dove eseguire
applicazioni JAVA e per poter lanciare il WTK. Fare riferimento
alla bibliografia per i link su JAVA SDK.
Abbiamo poi scaricato l’IDE open-source ECLIPSE da usare con la
suddetta SDK e nella modalità aggiornamento abbiamo inserito il
link da cui scaricare e installare automaticamente il plug-in
ECLIPSEME che ha aggiunto “features” ad eclipse consentendo lo
23
sviluppo di quella che da questo momento chiameremo MIDLETSUITE.
In definitiva, abbiamo scaricato ed installato dal sito SUN il WTK
che, dopo averlo opportunamente integrato in Eclipse, ci ha
consentito di effettuare i testing necessari come se si utilizzasse un
dispositivo reale. Tralasciamo qui di menzionare le modalità di
configurazione dei software di sviluppo.
24
2.3. Connessioni di rete e Thread
Gestione degli stream : java.io
L'input e l'output di Java si basano sul concetto di stream, cioè un
generico flusso di byte "in transito" da una sorgente verso una
destinazione indipendentemente dal tipo di sorgente, di destinazione
e di percorso. Il package java.io non poteva quindi mancare nella
CLDC, esso costituisce un sottoinsieme dell'omonimo della
Standard Edition. In particolare nella CLDC sono state eliminate
tutte le classi riguardanti le operazioni su file, questo perché la
maggior parte dei dispositivi che utilizzeranno la CLDC, come già
abbiamo detto, non possiedono un vero e proprio file system (i
palmari palmOS ne sono un esempio, ma anche i cellulari e gli
smart-phone). Le operazioni di I/O da/su file sono comunque
garantite dal "Generic Connection Framework". Le due classi,
InputStreamReader e OutputStreamWriter, rappresentano l'unico
supporto all'internazionalizzazione di cui la CLDC dispone e
permettono la conversione di sequenze di byte in caratteri Unicode
e vicerversa:
InputStreamReader(InputStream
is,
OutputStreamWriter(OutputStream os, String encoding);
String
encoding);
25
La CLDC supporta di default la codifica ISO-8859_1 come è
possibile vedere "interrogando" le proprietà di sistema
(System.getProperty("microedition.encoding")) altri tipi di codifica
possono, però essere presenti in implementazioni particolari. Il
mancato supporto per una codifica richiesta lancerà, ovviamente,
una UnsupportedEncodingException. Tali proprietà son servite nel
sistema,
come
si
vedrà
successivamente
nella
parte
dell’implementazione, per inviare messaggi e per richiedere i tiles a
google il quale deve essere informato del tipo di client che effettua
la richiesta.
Il "Generic Connection Framework"
Come è noto i package java.io e java.net nella Standard Edition
forniscono un insieme completo di strumenti per la gestione
dell'Input - Output sia per quanto riguarda l'I/O da file sia per quello
legato a connessioni di rete. Sfortunatamente però hanno
dimensioni tali (circa 200 Kbyte) da impedirne "la completa
importazione" nella CLDC, inoltre molte delle funzionalità che
garantiscono sono poco (o per nienete) utili in dispositivi embedded
e nell'elettronica di consumo in generale. Inoltre molti di questi
26
apparati dispongono di metodi di comunicazione "inusuali" e molto
specifici
(infrarossi,
bluetooth),
E’ necessario quindi estrapolare dalla Standard Edition (java.io,
java.net) le funzionalità principali e adattarle a questo contesto
garantendo.
E' stato quindi pensato quello che viene definito "Generic
Connection Framework", implementato in un insieme di interfacce
che rappresentano vari livelli di astrazione di metodologie di
connessione. La decisione di non implementare direttamente, a
livello di configurazione, i vari protocolli, ma di lasciare questo
compito al livello applicazione (o profilo), rientra nella logica di un
approccio generico al problema. In questo modo la configurazione
fornisce gli "strumenti generici di base" permettendo il supporto di
molti protocolli e l'utilizzo sui più disparati dispositivi. Alla radice
della gerarchia, l'interfaccia Connection, rappresenta una generica
connessione che può essere aperta e chiusa attraverso i metodi
open() (che in realtà non è public ma viene richiamato dal metodo
statico open() presente nell’ unica classe Connector) e close().
InputConnection e OutputConnection rappresentano un dispositivo
dal quale i dati possono essere rispettivamente letti o scritti,
attraverso
gli
opportuni
stream
(openInputStream-
27
openDataInputStream
/
openOutputStream-
openDataOutputStream), StreamConnection è la combinazione di
Input/Output-Connection e costituisce normalmente il punto di
partenza per le classi che implementano le interfacce di
comunicazione. La sua estensione ContentConnection dispone di
alcuni metodi (getEncoding, getType, getLength) che consentono di
ottenere
informazioni
sui
dati
trasmessi.[18]
Type ed Encoding sono serviti nel progetto per informare Google di
quale tipologia di browser effettua la richiesta delle mappe
(operazione obbligatoria per prelevare tiles).
Figura 1 - Gerarchia delle interfaccie del "Generic Connection Framework".
Qualunque tipo connessione viene aperta utilizzando il metodo
open() della classe Connector: [19]
Connector.open(string_connection);
28
dove string_connection ha il seguente formato:
<protocol>:<address>;<parameters>
protocol indica il tipo connessione che si intende utilizzare (es. http,
datagram, scrittura su file, ecc.), address permette di individuare la
destinazione (può essere un indirizzo IP ma anche il nome di un
file) , parameters contiene una serie di informazioni aggiuntive che
possono essere funzionali per un dato tipo di connessione (ad es.
baudrate
per
comunicazioni
su
porta
seriale).
"THREADING" in J2ME
J2ME fornisce 2 varianti della classe Thread sottoinsiemi della
J2SE. Per CLDC vengono forniti solo i seguenti metodi:
activeCount() , currentThread(), getPriority(), isAlive(), join(), run(),
setPriority(), sleep(), start(), yield().
Da notare la mancanza dei metodi per fermare o interrompere un
thread. Il solo modo che abbiamo avuto per fermare un thread è
stato quello di impostare la sua variabile di riferimento a NULL
come nell’esempio sottostante:
public class AnotherThread implements Runnable {
private Thread mostRecent = null;
public Thread restart(){
mostRecent = new Thread( this );
29
mostRecent.start();
}
public void run(){
Thread thisThread = Thread.currentThread();
while( mostRecent == thisThread ){
// do something
}
}
public void stopAll(){
mostRecent = null;
}
}
Nella nostra applicazione l’uso dei thread è stato fondamentale
poiché l’uso di una connessione o di una richiesta di I/O risulta
essere “bloccante” per il sistema. Situazione questa non tollerabile
data la natura stessa dei dispositivi e la possibilità del verificarsi di
ulteriori eventi come telefonate o la gestione di una eccezione nel
funzionamento e la midlet manderebbe irrimediabilmente in blocco
tutto il sistema.[20]
30
2.4. Mobile GIS
Con mobile-gis facciamo riferimento al GIS per dispositivi
elettronici di telecomunicazioni (mobile-phone, smartphone, etc). Il
GIS per dispositivi mobile si è sviluppato negli ultimi 10 anni e sta
prendendo le forme più disparate: mobile gis sono ad esempio i
software commerciali della ESRI come ARCPAD oppure le
applicazioni satellitari di navigazione come Tom Tom per
dispositivi
mobili.
L’integrazione
tra
telecomunicazioni
e
comunicazione dei dati ha contribuito alla creazione di una
infrastruttura di rete globale che sembrerebbe essere disponibile
dappertutto, in ogni momento e attraverso una moltitudine di
apparecchiature differenti. Assumendo che col passare del tempo
questa rete globale sarà via via sempre più disponibile, gli
sviluppatori trovano sempre nuove modalità di realizzazione per le
applicazioni che sono uniche per questi dispositivi mobili e si
differenziano non poco da quelle per workstation classiche. Ecco
alcune delle proprietà di un sistema mobile: [21]
1. la stessa applicazione per più devices. In un ambiente fatto da
terminali mobili, i servizi devono essere in grado di
presentarsi alla maggior parte di essi con funzionalità
consistenti e un interfaccia amichevole.
31
2. in un mondo mobile “always on” gli utenti accedono alle
informazioni indipendentemente dal luogo e dal tempo.
3. combinare dati reali con dati digitali. Nelle postazioni fisse, il
digitale ed il mondo reale sono grosso modo separati.
Viceversa, nei sistemi mobili essi devono essere combinati.
Avendo a che fare col mondo reale, i dati, come ad esempio
la posizione geografica, ci permettono di avere applicazioni
realtime.
4. architettura dei dati. Durante la fase di design ed
implementazione bisogna fare attenzione anche alle strutture
utilizzate. Quando un contesto necessità di essere aggiornato
o vengono aggiunte ulteriori informazioni al sistema
sottostante, una buona soluzione sarebbe quella di cambiare il
minimo possibile nell’architettura. [22]
Col termine Mobile-GIS si definisce un sistema integrato di
hardware e software per l’accesso ai dati spaziali e ai servizi
attraverso un dispositivo mobile via rete wireless. Il Wireless-GIS è
una sottocategoria del Mobile-GIS che focalizza la sua attenzione
sulla capacità di una rete wireless. Vi sono 2 aree di maggior
applicazione per un Mobile-GIS:
32
1. Field-based GIS, che focalizza sulla collezione, validazione e
aggiornamento di dati GIS(dati spaziali e attributi).
2. Location-based services (LBS), che focalizza sulle funzioni
di localizzazione orientate al business come ad esempio il
tracking di flotte marine o terrestri.
L’architettura di un Mobile-GIS e’ molto simile a quella di un
Internet-based GIS. Utilizza cioè un architettura client/server
tipicamente attraverso quella che viene definita come “Three Tiered
Architecture” (i.e. MVC). [23]
In un sistema LBS [24] vi sono racchiuse 4 importanti tecnologie:
mobile phones, acquisizione di locazioni (automatiche o manuali),
tecnologia internet wireless e le soluzioni GIS per il wireless.
Per acquisizione di locazioni si intende la possibilità di tenere
traccia della locazione geografica del dispositivo mobile [25].
Questo è stato utilizzato nel progetto quando vengono storicizzate
le posizioni degli utenti a seguito del loro invio delle coordinate.
Negli sviluppi futuri un accenno agli eventuali modi di valorizzare
queste informazioni.
33
Per tecnologia internet wireless si fa riferimento alla rete italiana
3G, GSM, GPRS, EDGE e così via. Per la nostra applicazione si è
fatto largo uso del GPRS (General Racket Radio Services) che è un
servizio di comunicazione “always on” che trasferisce informazioni
allo stesso modo di internet ossia in pacchetti per poi essere
riassemblati al ricevimento dal terminale.
2.4.1. Google Maps Mobile
Un esempio [26] di applicazione LBS per mobile viene da qualche
anno fornita da un applicazione realizzata dal noto motore di ricerca
Google. Si chiama Google Maps Mobile ed e’ giunta gia da
Novembre 2007 alla versione 2.x.
Google Maps per mobile è un'applicazione scaricabile che consente
di visualizzare mappe e immagini satellitari, trovare attività
commerciali locali e ottenere indicazioni stradali direttamente sul
dispositivo mobile. [27]
GoogleMapsMobile offre 2 diverse tipologie di localizzazione della
posizione: una puo essere fornita da un GPS esterno o interno
mentre in alternativa si può scegliere di adoperare un sistema che
sfrutta la triangolazione tra celle. [28] La triangolazione tra celle è
una tecnica di rilevamento della posizione che fa uso delle stesse
34
celle usata per la comunicazione voce. [29] Con tale tecnica si
riesce ad approssimare un punto in base ai suoi tempi di risposta da
3 diverse celle che formano un triangolo nel quale è contenuto il
punto stesso. [30] Tempi di risposta e approssimazione sono però
peggiori di quelli forniti da un GPS ma hanno il vantaggio di essere
sempre disponibili e di non soffrire dei cosiddetti “luoghi chiusi”
come nel GPS. Senza soffermarci troppo sull’applicazione in sè, è
da notare che le mappe prelevate da essa si riferiscono, come nella
nostra applicazione, ad un indirizzo http diverso da quello a cui ci si
è abituati navigando tra le mappe di google da un browser internet.
L’indirizzo in questione è di tipo [31]
http://mt.google.com/mt?n=404&v=w2.17&x=????&y=????&z
oom=??
Il link classico a cui siamo abituati è invece http://maps.google.it
ma mentre questo fornisce un reale servizio di localizzazione, il
precedente funge da contenitore di tiles e non è funzionalmente
adatto ad effettuare alcuna operazione, se non quella di mostrare il
tile stesso.
35
3. REQUISITI DEL SISTEMA
Lo scopo generale del progetto è quello di realizzare una
applicazione J2ME in grado di connettersi ad un server e da questi
reperire servizi tipici di una community web. [32] In particolare
sull’applicazione mobile realizzata l’utente connesso sarà in grado
di visualizzare la lista delle community a cui appartiene , ne potrà
selezionare una visualizzandone la posizione degli utenti che in
quel momento sono connessi, ed inoltre potrà usufruire di una serie
di servizi integrati, tra cui, ad esempio, eseguire una ricerca degli
utenti a una certa distanza o mandare un messaggio a un particolare
utente.
La strategia adoperata e’ di tipo CLIENT/SERVER. Il Server
sottostante è preesistente ed è stato implementato secondo il pattern
MVC5 (Model View Controller) e si occupa di gestire i servizi lato
web e di rispondere alle richieste del client. Il client sviluppato
prevede la definizione di una sola tipologia di utente che da questo
momento chiameremo utente semplice.
L’utente semplice può :
5
Paradigma di programmazione largamente diffuso che tende a scomporre un sistema in tre
livelli indipendenti..
36
• Effettuare Login.
• Visualizzare la lista delle community a cui appartiene.
• Selezionare una community.
• Visualizzare su mappa geografica la posizione degli utenti
che in quel momento sono attivi.
• Inviare messaggi ad altri utenti “attivi”.
• Richiedere una lista di tutti gli utenti che si trovano in un
raggio di x metri impostato dall’utente stesso.
• Utilizzare un navigatore GPS per le proprie coordinate da
inviare al server.
3.1. Requisiti funzionali
Per la realizzazione degli obiettivi proposti nel progetto di
sviluppo, è
necessario realizzare le seguenti funzionalità per
l’utente semplice :
• Autenticazione dell’utente da dispositivo mobile
• Visualizzazione delle community disponibili.
• Visualizzazione della mappa e relative funzioni di
panning, zoom, ecc.
• Invio coordinate GPS (acquisite via Bluetooth)
37
• Invio ricezione messggi
• Ricerca utenti a distanza
3.2. Requisiti non funzionali
Oltre ai requisiti funzionali, il sistema proposto deve
presentare le seguenti caratteristiche:
• Tutelare la privacy degli utenti
• Minimizzare il traffico di rete
L’utente dal proprio dispositivo mobile dopo aver avviato
l’applicazione e essersi collegato al GPS inizierà a inviare le sue
Coordinate. Definiamo un utente attivo se dall’ultimo invio delle
coordinate non è trascorso un certo timeou configurabile , e non
attivo in caso contrario.
3.3. Modello dei Casi d’uso
I casi che andremo a descrivere prendono in considerazione il
punto di vista dell’utente finale ovvero ignora i particolari
implementativi focalizzandosi sugli aspetti funzionali del sistema
da realizzare.
38
3.3.1. Attori
Utente Semplice: è l’utente finale del sistema, che grazie ai servizi
realizzati potrà avere a disposizione la posizione geografica esatta
degli amici della sua community. In particolare potrà :
1. Autenticarsi da dispositivo mobile.
2. Scegliere una community .
3. Visualizzare la posizione degli altri utenti della community
attivi su mappa geografica
4. Chiedere la lista degli utenti che si trovano entro una certa
distanza dalla sua posizione
39
Verranno mostrate di seguito le principali funzionalità legate
all’utente semplice.
3.3.2. Diagramma dei casi d’uso
40
3.3.3. Descrizione dei Casi d’uso.
Use Case
Invio/Ricezione Messaggi
Permette di inviare un messaggio di testo ad un altor utente della
community.
Participating Actors
1. utente semplice
Preconditions
1. l’utente deve lanciare la midlet e loggarsi nel sistema.
Flow of Events
1. L’utente accede alla community tramite la voce VISUALIZZA
COMMUNITY che appare nel menu dopo aver effettuato il
logging.
2. Il sistema consente di scegliere una delle community a cui ci si
è registrati.
3. L’utente effettua la scelta.
4. Il sistema provvede a inviare la richiesta al Server con i dati
suddetti e allo stesso tempo carica la mappa iniziale di default.
Mostra i marker degli utenti “visibili” .
5. L’utente può visualizzare l’elenco degli altri partecipanti e
inviare un messaggio a uno di essi.
6. Se l’operazione va a buon fine compare un messaggio di
conferma.
41
Postconditions
Viene inviato il messaggio di testo al DB contenente mittente e
destinatario. Il destinatario riceve il messaggio dopo un certo tempo
prefissato dall’utente.
Exceptions
Siccome le operazioni avvengono in maniera asincrona, se l’utente
destinatario e’ uscito dal sistema prima della ricezione del messaggio
quest’ultimo gli sarà recapitato al suo prossimo accesso.
Use Case Name
Visualizzazione Utenti
Permette all’utente di visualizzare oltre ai marker sulla mappa anche
una lista completa di tutti gli utenti appartenenti alla community e
loggiati in quel momento.
Participating Actors
1. utente semplice
Preconditions
1. I’utente deve essere loggato
42
Flow of Events
1. l’utente visualizza la mappa.
2. dal menu’ a tendina seleziona la voce VISUALIZZA UTENTI
3. Il sistema fa una richiesta al DB e mostra un elenco di tutti gli
utenti loggiati in quel momento.
4. Un ulteriore menù a tendina consente di visualizzare la scheda
anagrafica dell’utente selezionato.
Post Conditions
Non necessarie
Exceptions
Non necessarie
Use Case Name
Visualizza Utenti a distaza <= “X metri”
Permette all’utente di visualizzare l’elenco degli utenti che si trovano
in un raggio di “x” metri da se stesso
Participating Actors
43
1. utente semplice
Preconditions
1. I’utente deve essere autenticato e deve aver attivato il sistema
GPS per il controllo delle coordinate.
Flow of Events
1. l’utente seleziona la community a cui è interessato.
2. Il sistema mostra la mappa e conosce gia gli utenti loggiati in
quel momento.
3. l’utente attiva il navigatore GPS via Bluetooth.
4. il sistema ora conosce le coordinate dell’utente e inizia a
mandarle al DB.
5. l’utente entra nel menù a tendina e seleziona la voce
VISUALIZZA UTENTI A DISTANZA.
6. inserisce una distanza in metri nell’apposita form.
7. i sistema visualizza l’elenco ordinato in modo crescente degli
utenti a quella distanza.
Post Conditions
Non necessarie
Exceptions
Non necessarie
44
Use Case Name
Zoom-in/zoom-out
Participating Actors
1. utente semplice
Precoditions
1. l’utente deve visualizzare correttamente la mappa.
Flow of Events
1. L’utente , seleziona il tasto dal menu.
2. il sistema effettua un calcolo per mostrare i nuovi tiles al
nuovo livello di zoom.
3. i nuovi tiles prendono il posto dei precedenti e vengono
visualizzati.
PostConditions
Non necessarie
Exception
Non necessarie
45
Use Case Name
Visualizzazione Utenti su Mappa
Permette all’utente di visualizzare la posizione geografica degli utenti
che appartengono alla community selezionata
Participating Actors
1. utente semplice
Preconditions
1. I’utente deve essere registrato ed identificato dal sistema.
2. l’utente deve essere iscritto alla mobile communty che vuole
visualizzare
Flow of Events
1. l’utente accede alla visualizzazione delle community a cui
appartiene.
2. Il sistema mostra la lista delle community a cui l’utente4 si è
precedentemente iscritto.
3. L’utente selezionala community di cui vuol visualizzare la
posizione degli utenti.
4. il Sistema mostra la mappa geografica , indicando con degli
omini rossi gli utenti non attivi , e verdi quelli attivi
Postconditions
Non necessarie
Exceptions
46
l’utente potrebbe non visualizzare nessun oggetto se gli utenti non
hanno ancora inviato le coordinate al data base.
47
4. ANALISI DEI REQUISITI E MODELLI DI
SISTEMA
4.1 Dizionario dei dati
I
seguenti
oggetti
sono
quelli
coinvolti
nell’implementazione delle funzionalità che sono messe a
disposizione dal sottosistema. Viene data la descrizione del dato e
la sua collocazione nei seguenti sequenze in termini di oggetti del
dominio (Entità Objects), oggetti di confine (Boundary Objects) e
controllori di funzioni (Control Objects).
Sequence Diagram
Login
Operazione di autenticazione iniziale e accesso al sistema
Entity Object
•
login: la stessa creata lato web sul sito di riferimento di GECO
SERVER.
•
password: la stessa creata sul sito di riferimento. Viene
visualizzata asteriscata.
•
user: è l’utente del sistema che effettua l’autenticazione.
Boundary Object
48
•
Entra: tasto che richiama una form di avvenuto accesso e
visualizzazione del corrispettivo id legato a login e password.
Control Object
Nessun oggetto di controllo. Solo una form di richiesta autenticazione
con login e password
Sequence Diagram
Entra
Operazione di accesso al sistema con login e password precedentemente
specificate.
Entity Object
•
idutente: la stringa numerica che è strettamente legata alla login
e password e viene restituita dal server.
•
user: è l’utente che visualizza i messaggi di autenticazione e id
relativi alla sua login e pass.
Boundary Object
•
vedicommunity: tasto che consente di visualizzare le community
legate allo specifico idutente restituito dal server.
•
Indietro: tasto per ripetere la fase di autenticazione iniziale.
49
Control Object
•
EffettuaLogin.java: classe di connessione al server che controlla
username e password e visualizza relativo messaggio di avvenuta
autenticazione in caso positivo o di tipo di errore in caso contrario.
Sequence Diagram
Vedi Community
Operazione di visualizzazione delle community legate allo specifico idutente
Entity Object
•
Lista Community: è la lista delle community associate allo
specifico utente.
•
user: è l’utente che continua nella fase di accesso selezionando
una delle community dalla lista delle community.
Boundary Object
•
Scegli: tasto che consente di specificare la community da utilizzare
nella fase successiva per mostrare la mappa e i relativi utenti
collegati.
Control Object
50
•
VisualizzaCommunityUtente.java: classe di connessione al server
che recupera la lista delle community collegate allo specifico
idutente.
Sequence Diagram
Scegli Community
Operazione legata al tasto “Scegli” che seleziona la community e mostra la
mappa con i relativi utenti ad essa collegati.
Entity Object
•
Mappa: è la mappa di Google visualizzata con le impostazioni
iniziali di default.
•
Utenti: sono gli utenti collegati in quel momento e che appartengono
alla specifica community selezionata nella fase precedente.
•
user: è l’utente che ha selezionato la community e ne visualizza la
mappa e gli utenti ed è in grado di interagire con essi.
Boundary Object
•
Menu: sono le funzioni disponibili una volta ottenuta la
visualizzazione grafica della mappa e comprendono lo zoom e le
funzioni di interazione con gli altri utenti, oltre alla funzione di uscita
dalla midlet.
Control Object
51
•
MostraMappa.java: funzione di passaggio e controllo dei dati di
login, password e selezione della community al visualizzatore
principale di mappe MyCanvas.
•
4.2 Modelli dinamici
4.2.1 Sequence diagram
Possiamo suddividere le sequenze di operazioni in due filoni
principali: uno per la fase iniziale di accesso al sistema e
visualizzazione mappa e l’altro di utilizzo delle funzioni di
interazione con gli utenti della community.
Nella prima fase quindi l’utente inserisce i propri dati di accesso,
seleziona la community a cui vuole partecipare e inizia a
visualizzare le dovute informazioni ossia la mappa e gli utenti
collegati in quel momento. Questa fase comporta le connessioni sia
al server su cui e’ installato il GECO SERVER sia a Google per il
reperimento dei tiles per costruire la mappa. Nella fase di accesso le
operazioni sono sequenziali su una linea temporale e sono previste
interazioni solo col sistema sottostante per l’autenticazione e la
scelta di una community.
52
Accesso e visualizzazione mappa
53
Nella seconda fase si può accedere alle funzioni del menù per
interagire con la mappa e con gli altri utenti della community attivi
in quel momento.
Funzioni del Menu
54
5. LA GEOREFERENZIAZIONE DI UTENTI
5.1 PROGETTAZIONE
La progettazione del sistema è stata eseguita considerando i
seguenti fattori:
• Linguaggio di programmazione
• Database
• Know-How personali ed aziendali
Allo stato attuale i linguaggi di programmazione utili alla
realizzazione di un client mobile sono molteplici. Abbiamo deciso
di utilizzare JAVA come linguaggio base poiché è facilmente
espandibile ed integrabile in diverse altre tecnologie e soprattutto
perché è open-source. La scelta del DB è anch’essa orientata
all’open-source e ci siamo affidati ad un database di largo uso nella
comunità scientifica e che consenta di trattare dati di tipo spaziale.
Abbiamo quindi preferito POSTGRESQL con il suo add-on
POSTGIS. Ultime ma non meno importanti per la scelta delle
strategia da utilizzare sono state le conoscenze personali e quelle
55
messe
a
disposizione
Personalmente
il
mio
dal
team
di
background
Unlimited
universitario
Software.
si
fonda
principalmente su JAVA e quello aziendale, pur avendo a
disposizione una più ampia scelta come ad esempio il linguaggio
Microsoft Visual Basic, ha una radicata esperienza sulla gestione
del database posgresql/postgis in ambito Java. Mettendo insieme le
due cose, le conoscenze aziendali e il mio personale background, ci
siamo definitivamente orientati a Java come linguaggio di
programmazione e Postgis come database.
5.2. Interfaccia utente
L’interfaccia proposta dal sistema è stata progettata in maniera tale
da garantire all’utente sicurezza e familiarità con l’applicazione. Si
e’ utilizzato l’approccio tipico di applicazioni J2ME con utilizzo di
menù a tendina e funzioni semplificate.
5.2.1. Descrizione dell’interfaccia utente
Possiamo suddividere l’interfaccia utente in due aree principali,
1. l’area in cui visualizza la mappa
56
2. i menù in cui accede alle funzioni del sistema.
Descriveremo ora le diverse funzioni del sistema accessibili dal
menù:
Funzione Zoom-In
Vogliamo avere un livello di dettaglio della mappa maggiore di
quello attuale.
Percorso Navigazione: Menu > Zoom In
Funzione Zoom-Out
Si richiede al sistema di ritornare ad un livello di zoom meno
dettagliato ma che mostri una porzione di mappa più estesa.
Percorso Navigazione: Menu > Zoom Out
Funzione Visualizza Utenti
Si richiede al sistema di visualizzare la lista degli utenti collegati in
quel momento.
Percorso Navigazione: Menu > Visualizza Utenti
Funzione Visualizza Utenti a Distanza
57
Si richiede al sistema di visualizzare la lista degli utenti collegati in
quel momento e alla distanza specificata dall’utente.
Percorso Navigazione: Menu > Visualizza Utenti a distanza
Funzione REFRESH MAPPA
Si richiede al sistema di aggiornare le posizioni correnti degli altri
utenti effettuando una nuova richiesta di coordinate al server.
Percorso Navigazione: Menu > Refresh Mappa
Funzione GPS
Si richiede al sistema di attivare la procedura di ricerca,
identificazione e associazione al sistema di un dispositivo GPS
bluetooth.
Percorso Navigazione: Menu > GPS
58
5.2 IMPLEMENTAZIONE
5.2.1 Suddivisione del sistema in componenti
GECO client e’ suddiviso in 3 package logici: il package
midlet, il package funzioni ed il package bluetooth. In ogni package
sono raggruppate le funzioni logicamente correlate. Nel package
midlet sono contenute 25 classi per l’avvio della midlet stessa e la
gestione dei thread della inerenti alla visualizzazione dei dati
provenienti dagli altri package. Nel package funzioni sono
contenute 10 classi per la gestione delle connessioni e per le
operazioni fondamentali su tiles e coordinate geografiche. Nel
package bluetooth sono contenute 2 classi per la gestione del
dispositivo GPS via bluetooth e per la manipolazione delle
informazioni geografiche provenienti dal dispositivo stesso.
5.2.2. Descrizione dei sottosistemi
Verranno di seguito descritte le principali classi dei 3
package che realizzano le funzionalità più importanti del progetto.
59
Package principale
La prima classe da analizzare e’ la StartMidlet.java. si tratta
della classe di avvio della midlet suite. Al suo interno sono stati
implementati i principali metodi che una midlet eseguibile deve
contenere [33] e in aggiunta sono stati implementati altri metodi che
servono alle funzionalità del sistema. Per questa e per tutte le altre
classi si è adottato lo schema di implementazione tipico di
applicazioni grafiche. In particolare la veste grafica (Muchow, 2002)
richiede numerosi thread e listener necessari alle operazioni di base
come panning e zooming nonché di invio e ricezione dati tramite
connessioni http.
Questi sono i metodi che tengono traccia del canvas, dell’id
dell’utente, del flag gps e dell’id della community. Avendo a che
fare con Servlet e Jsp lato server si è voluti seguire l’approccio
tipico di queste applicazioni, ossia la possibilità (specie nei siti di ecommerce) di mantenere attive sessioni e tenere traccia durante tali
sessioni dei dati relativi all’acquirente. L’unica differenza è stata
che, mentre lato server questa soluzione è intrinseca al modello di
implementazione,
nel
nostro
progetto
abbiamo
dovuto
implementare e tenere traccia manualmente di ogni informazione
60
necessaria a realizzare uno specifico “stato” della midlet-suite.
L’esempio tipico sono le funzioni get() e set() che vanno prese in
considerazione quando durante la navigazione di una mappa si
accede ad una funzionalità del menù (cosa particolarmente evidente
per la funzione GPS).
public void SetMC(MyCanvas m){MC=m;}
public void setFlagGPS(){flagGPS=true;}
public boolean getFlagGPS(){return flagGPS;}
public void setIDUtente(int id){
idutente=id;
}
public int getIDUtente(){
return idutente;
}
public MyCanvas getMC(){
return MC;
}
public void setMC(MyCanvas myc){
MC=myc;
}
public String getIDCommunity(){
return idcommunity;
}
public void setIdCommunityy(String s){idcommunity=s;}
public Display getDispl(){
return Display.getDisplay(this);
}
public void startGPS() {
Display.getDisplay(this).setCurrent(get_mainForm());
mainForm.addCommand(backCommand);
doDiscovery();}
61
Questa è la funzione di attivazione del gps via bluetooth. Il
semplice metodo ha dietro tutta una fase di riconoscimento,
selezione e associazione (pairing) del dispositivo che viene
garantita dal metodo doDiscovery().
private void doDiscovery() {
discovery = new Discovery(this);
new Thread(new Runnable() {
public void run() {
try {
discovery.performDiscovery();
} catch (Exception ex) {
alert(AlertType.ERROR,
"discovery", ex);
}
}
}).start();
}
E qui invece si vede come si attiva il thread durante la fase di
attivazione del gps dal menu del dispositivo. La doDiscovery() è
la prima fase di ricerca dei dispositivi bluetooth visibili nel
raggio di azione del dispositivo mobile. E’ richiesta la
precedente abilitazione del bluetooth da parte dell’utente
altrimenti la funzione lancia un messaggio di errore. Tale
messaggio è gestito dalla funzione
alert(final AlertType type,
final String message, final Throwable th)
ed è strettamente
legate ai metodi di implementazione del bluetooth. Vi è infine
un metodo doConnect() che si occupa di eseguire la connessione
al dispositivo gps e gestisce in maniera del tutto trasparente
62
all’utente le varie fasi in modo da semplificare al massimo le
operazioni di associazione di un dispositivo bluetooth per
l’utente. L’unica cosa richiesta all’utente è di abilitare il
bluetooth nel dispositivo mobile e di selezionare “GPS” [34]
nelle funzioni del menù.
public void alert(final AlertType
type, final String message, final Throwable th) {
alert.setType(type);
alert.setTimeout(Alert.FOREVER);
final String exMsg = th == null ? null
th.getMessage();
final String text = exMsg == null ? message
message + ": " + exMsg;
alert.setString(text);
if (DEBUG) {
System.err.println(text);
status.setText(text);
if (th != null) {
th.printStackTrace();
}
}
Display.getDisplay(this).setCurrent(alert,
mainForm);
:
:
}
Passiamo ora a esaminare il modo in cui vengono inizializzate le
connessioni di rete e la richiesta di tiles.
Questa porzione di codice attiva la form iniziale e mette in
ascolto la midlet in attesa della digitazione del tasto di login o di
uscita.
public void startApp()
{
try
{
63
Form f=new Form("");
f.setTicker(title);
Image img=Image.createImage("/mondo.gif");
f.append(img);
d.setCurrent(f);
f.addCommand(cmdCommand3);
f.addCommand(cmdCommand4);
f.setCommandListener(newCommandActionIniziale(d,this));
}
catch(Exception e)
{
e. printStackTrace();
}
}
CommandActionIniziale è quindi la seconda classe java da
analizzare e di seguito ne mostriamo porzioni di codice:
public void commandAction(Command cc, Displayable arg1) {
if(cc.getLabel().equals("Login")){
Form form = new Form("Effettua Login");
login
=
new
TextField("Login",
null,30,TextField.ANY);
password=newTextField("Password",null,15,TextField.
PASSWORD);
}
else{
if(cc.getLabel().equals("Entra")){
if(mm==null){
return;
}
Thread t = new Thread(new EffettuaLogin(
password.getString(), d, mm));
t.start();
}
}
if(cc.getLabel().equals("Exit")){
mm.exitApp();
}
login.getString(),
64
Nel caso in cui l’autenticazione va a buon fine, si passa alla
chiamata della classe CommandActionIniziale2(). Vediamola
qui di seguito nelle sue parti più importanti:
public CommandActionIniziale2(Display dd,StartMidlet m,String
login,String password) {
vis=new VisualizzaCommunityUtente(login, password,
dd);
t=new Thread(vis);
t.start();
}
……………….
if(v.isEmpty()){
Form f=new Form("Errore : ");
StringItem str=new StringItem("ATTENZIONE : ","Non ci sono
cmmunity Registrate, Riprova dopo Eserti registrato a qualche
community");
}
else{
l.setTitle("Seleziona La Tua Community
:");
Enumeration e=v.elements();
while(e.hasMoreElements()){
Community
c=(Community)e.nextElement();
String
temp=""+c.getID()+"
"+c.getNome();
mm.setIdCommunityy(c.getID());
La classe verifica la disponibilità di community registrate per lo
specifico utente attraverso l’esecuzione di un nuovo thread della
classe VisualizzaCommunityUtente. Successivamente mostra le
community registrare oppure un messaggio di errore. Diamo uno
sguardo a questa classe:
public
VisualizzaCommunityUtente(String
password,Display dd)
login,String
65
{
URL="http://www.us.it/ServerGeco/ServletLoginClient?login="+login+"&password="+p
assword+"&comando=visualizzacommunity";
V=new Vector();
}
public void run()
{
try
{
conn = (HttpConnection)Connector.open(URL);
int c;
ByteArrayOutputStream
baos
ByteArrayOutputStream();
is = conn.openInputStream();
=
new
while ((c = is.read()) != -1)
{
baos.write(c);
}
String s = new String(baos.toByteArray());
System.out.println(s);
String temp="";
int conta=0;
String idcomunity="";
String nomecomunity="";
for(int i=0;i<s.length();i++){
if(s.charAt(i)!=' '){
temp=temp+s.charAt(i);
}else{
if(conta==0){
conta++;
idcomunity=temp;
temp="";
}else{
if(conta==1){
conta++;
nomecomunity=temp;
temp="";
V.addElement(new
Community(idcomunity,nomecomunity));
idcomunity="";
nomecomunity="";
conta=0;
}
}
}
}
baos.close();
is.close();
conn.close();
}
66
Si può notare che si esegue un thread di connessione al Server
Geco e si memorizzano in un Vettore la lista delle community
registrate per lo specifico utente.
Ritornando alla classe CommandActionIniziale2.java da cui era
partita la richiesta, la seguente porzione di codice realizza la
visualizzazione della mappa. Da questo momento inizia la parte
dell’algoritmo principale di gestione dei tiles:
if(cc.getLabel().equals("Scegli")){
idcomunity=l.getString(l.getSelectedIndex());
mostramappa=new MostraMappa(idcomunity,d,mm);
mm.setMappa(mostramappa);
t=new Thread(mostramappa);
t.start();
Algoritmo di gestione dei tiles.
Vedremo ora come vengono richiesti i tiles e come vengono
gestiti dall’ algoritmo. Passiamo quindi alla rappresentazione
grafica e le funzioni di disegno [35]. Per far ciò è necessario
analizzare la classe MyCanvas.java:
public class MyCanvas extends Canvas
implements CommandListener,ActionListener,GPSInfo.Listener
{………….
67
public MyCanvas(StartMidlet exiter,String idcom)
throws Exception
protected void paint(Graphics g)
{
try
{
m_panner.paint(g);
}
public void performAction()
{
repaint();
}
protected void keyPressed(int keyCode)
{
m_panner.keyPressed(getGameAction(keyCode));
}
protected void keyReleased(int keyCode)
{
m_panner.keyReleased(getGameAction(keyCode));
}
protected void pointerPressed(int x, int y)
{
m_panner.pointerPressed(x, y);
}
protected void pointerDragged(int x, int y)
{
m_panner.pointerDragged(x, y);
}
public void commandAction(Command c, Displayable d)
{
if(c == AppExiter.EXIT)
{
m_updater.cancel();
m_appExiter.exitApp();
}
}
public static void register(ActionListener obj)
{
m_updater.register(obj);
}
private static final
ActionUpdater(1000, 25);
ActionUpdater
m_updater
=
new
Come è facile notare, la classe MyCanvas estende Canvas [36],
la classe base per la grafica in J2ME, ed implementa 3 listener.
68
Vi sono poi i thread per le interazioni con l’utente ma soprattutto
vi è il sistema che consente di effettuare il panning sui tiles. E’
infatti l’ImagePanner che consente di spostarsi un immagine
quando questa risulti essere più ampia delle dimensioni del
display in uso. E’ l’ActionListener
che “registra” gli
spostamenti con i tasti direzione e la funzione paint, che sfrutta
tale listener, ridisegna di volta in volta la grafica. Inoltre sono
presenti anche (ma solo parzialmente) i metodi per gestire un
dispositivo touchscreen sul quale viene comunque garantito il
panning dell’immagine. La classe fondamentale quindi che si
occupa di gestire le immagini e di effettuare il panning è
ImagePanner.java. Vediamo nel dettaglio come funziona:
public ImagePanner(Canvas screen,String idcom,StartMidlet ex)
throws Exception
{
latitudine=0.0;
longitudine=0.0;
idutente=0;
threadinserisci=new
ThreadInserisciCoordinateGPS(exiter.getIDUtente(),latitudine,lo
ngitudine,exiter);
idcomunity=idcom;
zoom = 9;
posizione=new GeoLocation(42, 13);
tileDiProva
=
new
TileUtils(posizione.getLatitudine(),
posizione.getLongitudine(), zoom);
x_tile=tileDiProva.getTileCoord().getX();
y_tile=tileDiProva.getTileCoord().getY();
x_tileA=x_tile;
y_tileA=y_tile;
x_tileB=x_tile+1;
69
y_tileB=y_tile;
x_tileC=x_tile;
y_tileC=y_tile+1;
x_tileD=x_tile+1;
y_tileD=y_tile+1;
marker=Image.createImage("/marker.png");
MyCanvas.register(this);
m_screenWidth = screen.getWidth();
m_screenHeight = screen.getHeight();
xx=m_screenWidth/2;
yy=m_screenHeight/2;
int tempDiYY =yy;
listaImmagini=new Hashtable();
c=new
CalcolaArea(xx,yy,m_screenHeight,m_screenWidth,null);
imgA=c.drawRettangoloA(x_tile,y_tile,zoom);
imgB=c.drawRettangoloB(x_tile+1,y_tile,zoom);
imgC=c.drawRettangoloC(x_tile,y_tile+1,zoom);
imgD=c.drawRettangoloD(x_tile+1,y_tile+1,zoom);
listaImmagini.put("A",new
TileImmagine(imgA,xx256,yy-256,x_tileA,y_tileA,"A"));
listaImmagini.put("B",new
TileImmagine(imgB,xx,yy256,x_tileB,y_tileB,"B"));
listaImmagini.put("C",new
TileImmagine(imgC,xx256,yy,x_tileC,y_tileC,"C"));
listaImmagini.put("D",new
TileImmagine(imgD,xx,yy,x_tileD,y_tileD,"D"));
timer=new Timer();
timerricezionesms=new Timer();
con=new HttpConnector(idcomunity);
t=new Thread(con);
t.start();
}
Vengono settate le coordinate iniziali da cui partire, viene settato
un determinato livello di zoom iniziale e si passa alla richiesta
dei tiles. A tal fine è fondamentale la classe TileUtils.java [37]
che analizzeremo nel prossimo package. Da questo momento
70
andiamo a richiedere a Google i 4 tiles che ci serviranno per
mostrare la mappa iniziale. Ogni tile è identificato da due
coordinate x ed y. Il primo tile (tile A), ad esempio, conterrà i
valori x_tileA = 1500 e y_tileA = 1780 entrambi di tipo intero. I
restanti tile (tile B, tile C, tile D) sono identificati partendo dalle
coordinate del primo tile e aggiungendo +1 alle loro coordinate
di riferimento a seconda se si trova a destra, in basso o in basso a
destra del tile A. In pratica le mappe di google sono
rappresentate come una griglia dove ogni quadrato identifica un
tile e ogni tile è identificato dalle sue coordinate x ed y. Questa
tecnica di rappresentazione dei tile prende il nome di “raster
gerarchico”. E’ un albero (denominato quad-tree) dove ad ogni
livello di zoom ci sono dei tile in una griglia. Ogni tile ad un
livello z viene suddiviso in 4 tiles nel livello sottostante. La
struttura quindi è un albero quando si prende in considerazione il
livello di zoom e consiste di 4 tile quando si passa a considerare
il livello sottostante [38].
Tornando alla nostra visualizzazione della mappa quindi, ogni
tile viene disegnato come un immagine in un rettangolo
passandogli la x e la y del tile in questione [39]:
71
imgA=c.drawRettangoloA(x_tile,y_tile,zoom);
Precedentemente abbiamo suddiviso il nostro display in 4 parti
virtuali:
m_screenWidth = screen.getWidth();
m_screenHeight = screen.getHeight();
xx=m_screenWidth/2;
yy=m_screenHeight/2;
Questo ci servirà poiché xx ed yy sono le coordinate del punto
centrale del display del dispositivo grazie al quale potremo
agganciare i 4 tiles in modo affiancato (secondo certi criteri che
stabiliremo a breve) e contigui l’uno all’altro. [40]
Inoltre, con un hastable, teniamo traccia di quali sono i tiles
visualizzati. Questo per garantire il caricamento dinamico dei
tiles e, in futuro, per realizzare i meccanismi di cache:
private Hashtable listaImmagini:
listaImmagini.put("A",newTileImmagine(imgA,xx-256,yy256,x_tileA,y_tileA,"A"));
Prendiamo in considerazione il punto centrale del display. Se
tracciamo due linee, una verticale e una orizzontale, che passano
per esso, avremmo suddiviso il display in 4 parti. I nostri tiles
andranno a posizionarsi esattamente in queste 4 parti. Nello
specifico, il tile A sarà posizionato nel quadrato in alto a sinistra,
72
il tile B in alto a destra, il tile C in basso a sinistra e il tile D in
basso a destra. Poiché i nostri tiles hanno dimensione 256x256
[41] ognuno è ovvio domandarsi come essi possano essere
piazzati nei suddetti quadrati visto che ogni dispositivo ha
dimensioni di schermo differenti e di certo quasi nessuno di essi
avrà dimensioni tali da contenere anche un singolo tile. Ebbene,
ogni tile verrà posizionato nel rispettivo quadrato andando a far
combaciare solo un angolo per ognuno di essi con il punto
centrale del display. Quindi, ad esempio, per il tile A solo il suo
angolo in basso a destra combacia col punto centrale mentre per
il tile B solo il suo angolo in basso a sinistra. La restante
porzione di tile non viene visualizzata ma il dispositivo ha
comunque conoscenza del fatto che il tile esiste ed è completo.
E’ solo una questione di visualizzazione. Grazie a questo
meccanismo di gestione dei tiles possiamo effettuare panning su
questi primi 4 senza perdere alcuna informazione della mappa.
Vediamo ora come si naviga sulla mappa quando ci si sposta
oltre il confine di uno dei 4 tiles. Questa strategia di caricamento
di 4 tiles e il loro aggiornamento automatico durante lo scrolling
della mappa è alla base delll’algoritmo sviluppato in azienda ed
73
è un punto centrale di tutto il progetto, in quanto si presta in
modo
naturale
L’approccio
all’integrazione
adottato
risulta
delle
altre
fondamentale
componenti.
per
i
futuri
meccanismi che si intendono realizzare e che sono stati
ipotizzati nel capitolo degli sviluppi futuri.
Supponiamo di spostarci in alto. Il panning consente di scorrere
la mappa a velocità selezionabile durante l’implementazione
grazie alla seguente riga di codice:
m_updater = new ActionUpdater(1000, 25);
dove i valori 1000 e 25 indicano rispettivamente la initSleep,
ossia il tempo di caricamento iniziale e l’intervallo. In altre
parole consente di selezionare la velocità di scorrimento della
mappa. Proseguendo verso l’alto quindi e giungendo al margine
superiore di un tile (in realtà i margini vengono raggiunti per due
tiles alla volta), ossia quando il margine superiore del tile
coincide col margine superiore del display, la mappa si blocca,
non avendo altre immagini o porzioni di immagini da
visualizzare. In questo momento il controllo degli off-set fa
scattare la richiesta di altri due tiles:
public void performAction()
{
74
switch(m_gameAction)
{
case Canvas.UP:
if(yy-256!=0){
yy+=1;
}
else{
System.out.println("caricati 2 nuovi tile");
this.AggiornaUP();
}
La funzione AggiornaUP() effettua un rimescolamento dei 4
tiles come mostrato nel seguente codice:
public void AggiornaUP(){
yy=0;
Image temp1=imgA;
Image temp2=imgB;
imgC=null;
imgD=null;
imgA=null;
imgB=null;
CalcolaArea
c
m_screenHeight,
=
new
CalcolaArea(xx,
m_screenWidth, null );
yy,
y_tile=y_tile-1;
x_tileC=x_tileA;
y_tileC=y_tileA;
x_tileD=x_tileB;
y_tileD=y_tileB;
x_tileA=x_tile;
y_tileA=y_tile;
x_tileB=x_tile+1;
y_tileB=y_tile;
imgA=c.drawRettangoloC(x_tile,y_tile,zoom);
imgB=c.drawRettangoloC(x_tile+1,y_tile,zoom);
imgC=temp1;
imgD=temp2;
75
In altre parole, ci troviamo nel caso in cui siamo giunti ai
margini superiori dei tile A e B. Continuando a salire siamo
costretti a richiedere i due nuovi tiles della parte superiore. I tiles
C e D conterranno adesso quelli che erano A e B mentre questi
ultimi verranno aggiornati con i nuovi tiles caricati dalla
funzione CalcolaArea della omonima classe del package
“funzioni” [42].
Una delle cose che sicuramente andiamo a disegnare oltre ai tiles
sono i cosiddetti markers [43]. Distinguiamo ora due diverse
tipologie di markers: il marker ke identifica la nostra posizione e
i marker prelevati dal server che identificano la posizione degli
altri utenti La porzione di codice seguente illustra il
funzionamento:
public void paint(Graphics g) throws IOException
{ ……..
……………
private TileUtils tileDiProva;
SimplePoint
punto=tileDiProva.getTileCoordinate(geo.getLatitudine(),
geo.getLongitudine(), zoom);
if(punto.getX()==A.getTileX()
punto.getY()==A.getTileY()){
&&
76
myPoint
=
tileDiProva.getBitmapCoordinate(geo.getLatitudine(),geo.getLong
itudine(),zoom);
g.drawImage(marker,
A.getAngoloX()+(myPoint.getX()%256),
A.getAngoloY()+(myPoint.getY()%256),
Graphics.TOP|Graphics.LEFT);
}
if(punto.getX()==B.getTileX()
punto.getY()==B.getTileY()){
&&
myPoint
=
tileDiProva.getBitmapCoordinate(geo.getLatitudine(),geo.getLong
itudine(),zoom);
g.drawImage(marker,
B.getAngoloX()+(myPoint.getX()%256),
B.getAngoloY()+(myPoint.getY()%256),
Graphics.TOP|Graphics.LEFT);
}
if(punto.getX()==C.getTileX()
punto.getY()==C.getTileY()){
&&
myPoint
=
tileDiProva.getBitmapCoordinate(geo.getLatitudine(),geo.getLong
itudine(),zoom);
g.drawImage(marker,
C.getAngoloX()+(myPoint.getX()%256),
C.getAngoloY()+(myPoint.getY()%256),
Graphics.TOP|Graphics.LEFT);
}
if(punto.getX()==D.getTileX()
punto.getY()==D.getTileY()){
&&
myPoint
=
tileDiProva.getBitmapCoordinate(geo.getLatitudine(),geo.getLong
itudine(),zoom);
g.drawImage(marker,
D.getAngoloX()+(myPoint.getX()%256),
D.getAngoloY()+(myPoint.getY()%256),
Graphics.TOP|Graphics.LEFT);
}
Questa prima porzione mostra come disegnare il nostro marker
derivato dalle coordinate del dispositivo gps. Per capirne il
77
funzionamento dobbiamo fare alcune considerazioni. Nella
nostra classe TileUtils.java del package funzioni riusciamo,
avendo coordinate in termini di latitudine e longitudine e avendo
un tiles su cui visualizzarle, a posizionare il nostro marker
poiché vi sono delle funzioni di trasformazione che convertono
coordinate geografiche (LAT/LON) [44] in coordinate grafiche
del dispositivo (X e Y) con una approssimazione di uno o due
pixel6 al massimo. Sappiamo quindi come rappresentare queste
coordinate sul display. Il problema fondamentale però è che
dobbiamo anche sapere se un marker (il nostro o quello degli
altri utenti) deve essere o meno visualizzato sulla mappa. E
inoltre, anche sapendo se deve essere o meno visualizzato,
dobbiamo essere certi che appartenga ad uno dei 4 tiles. In altre
parole, avendo la nostra posizione geografica, per disegnare un
marker sul dispositivo dobbiamo verificare che quella posizione
sia “visibile” in quel preciso istante e, in caso affermativo,
stabilire quale dei 4 tiles contiene quelle coordinate e quindi
quel marker. Nel codice precedente si effettua innanzitutto una
trasformazione per conoscere le coordinate del tile che contiene
il marker (i.e. le coordinate lat=40 e lon=15 sono contenute, a
6
6 pixel è l’unità minima fondamentale di un display.
78
livello di zoom 6, dal tile x= 1020 e y= 1840) e poi si
controllano queste coordinate di tile con le coordinate dei 4 tiles
attualmente in uso. Il marker potrà così essere posizionato
correttamente sul suo tile di appartenenza [45].
Identica situazione per i marker degli altri utenti. Si recuperano
le coordinate degli utenti dal server sotto forma di punti
geografici. Si effettua la conversione per sapere le coordinate del
tile che contiene quel punto e si controlla se il tile di
appartenenza del punto è uno dei 4 tiles del dispositivo e lo si
disegna [46].
Algoritmi di gestione delle funzioni del menù.
Restando all’interno della classe ImagePanner.java diamo un
breve accenno alle restanti funzioni del menù.
La porzione di codice seguente richiede una lista di utenti nelle
due versioni possibili: utenti della community e utenti a
distanza.
if(cc.getLabel().equals("VediUtenti")){
Thread t=new Thread(new
exiter.getIDCommunity(),
exiter.getDispl()));
SelezionaUtentiAll(
exiter,
79
t.start();
}
if(cc.getLabel().equals("VediUtentiADistanza")){
TextField
distanza=new
TextField("Distanza
m.",null,15,TextField.ANY);
CommandActionConferma
cdd
=
new
CommandActionConferma(exiter.getDispl(),
exiter,
distanza);
f.setCommandListener(cdd);
exiter.getDispl().setCurrent(f);
}
Questa porzione di codice che segue realizza lo zoom-in e lo
zoom-out. Per lo zoom-in è da notare la chiara esplicitazione del
concetto di raster gerarchico e di quad-tree. x_tile e y_tile
vengono moltiplicati per 2 poiché, dato un tile, al livello
sottostante esso viene suddiviso in 4 e oguno dei risultanti avrà
ovviamente un maggiorelivello di dettaglio.[47] La semplice
moltiplicazione fornisce, dei 4, il tile in alto a sinistra. Poiché
abbiamo una costruzione basata su offset abbiamo preferito
prelevare il tile in basso a destra aggiungendo la quantità di una
unità (+1). Questa situazione è ovviamente migliorabile in
termini di precisione come si vedrà nel capitolo sugli sviluppi
futuri. [48]
Stessa situazione per lo zoom-out con l’unica differenza che il
processo matematico è inverso. Ossia, dato un tile, esso
costituisce la quarta parte del tile che lo contiene al livello
80
superiore. Per reperire il tile di livello superiore si effettua una
divisione per 2. [49]
if(cc.getLabel().equals("ZoomIn")){
if(zoom>0){
zoom=zoom-1;
x_tile=(x_tile*2)+1;
y_tile = (y_tile*2)+1;
prenditile.setX_tile(x_tile);
prenditile.setY_tile(y_tile);
prenditile.setZoom(zoom);
if(prendiimmagini==null)
prendiimmagini=new
Thread(prenditile);
prendiimmagini.start();
else{
if(cc.getLabel().equals("ZoomOut")){
if(zoom<14){
zoom=zoom+1;
x_tile=(x_tile/2);
y_tile = (y_tile/2);
prenditile.setX_tile(x_tile);
prenditile.setY_tile(y_tile);
prenditile.setZoom(zoom);
if(prendiimmagini==null)
prendiimmagini=new
Thread(prenditile);
prendiimmagini.start();
81
Algoritmi di gestione delle funzioni di messaggistica.
Torniamo alla lista degli utenti (sia completa che degli utenti a
distanza).
Una volta ottenuto l’elenco degli altri utenti attivi abbiamo detto
che è possibile inviare dei messaggi. La clsse che gestisce utenti
e messaggi è SelezionaUtentiAll.java. Oltre alle solite procedure
di connessione, vediamo come il codice che segue gestisce i
messaggi:
public SelezionaUtentiAll(String idcommu,StartMidlet m,Display
d) {
………………….
public void setDisplay(Vector v){
if(V.size()!=0){
f = new Form("Lista utenti :");
List
l=new
List("Lista
UtentiCommunity",List.IMPLICIT);
for(int i=0;i<v.size();i++){
Utente u=(Utente)v.elementAt(i);
l.append(u.getID(), null);
}
Command
inviamess=new
Command("InviaMessaggio",Command.OK,1);
Command
visualizza=new
Command("VisualizzaScheda",Command.OK,1);
l.setCommandListener(new
CommandActionMessaggi(l,idutente,mm,this));
…………..}
else{
Come si può notare, la classe effettua una richiesta al server
degli utenti collegati e gestisce la possibilità di visualizzare una
scheda utente (che per il momento fornisce solo una anagrafica)
e di mandare un messaggio. Questi sono i tipici servizi di una
82
community. La classe CommandActionMessaggi.java è il
listener in ascolto alla digitazione del tasto “InviaMessaggio” e
di “VisualizzaScheda”. Vediamo come funziona e come è
gestito il meccanismo di messaggistica:
public
CommandActionMessaggi(List
l,String
idmittente,StartMidlet m,SelezionaUtentiAll selezionautenti) {
destinatario=l.getString(l.getSelectedIndex());
mittente=idmittente;
lista=l;
seleziona=selezionautenti;
}
public void commandAction(Command cc, Displayable arg1) {
…………………………………
if(cc.getLabel().equals("InviaMessaggio")){
t= new TextBox("", "", 10, TextField.URL);
destinatario=lista.getString(lista.getSelectedIndex());
Display display=mm.getDispl();
Form f=new Form("");
t.setTitle("Invia Messaggio A "+destinatario);
……………………………
}
if(cc.getLabel().equals("Invia")){
String mess="";
mess=t.getString();
ThreadInserisciMessaggistica
thr=new
ThreadInserisciMessaggistica(destinatario,mittente,mess,mm);
th=new Thread(thr);
th.start();
}
Una
volta
scritto
il
messaggio
da
inviare,
la
classe
ThreadInserisciMessaggistica.java si occupa di inoltrare la richiesta.
Questa è una fase particolarmente delicata in quanto se non
vengono effettuate delle opportune modifiche al messaggio stesso
esso non viene interpretato nel modo corretto dalla servlet di
83
GecoServer.
Analizziamo
la
classe
ThreadInserisciMessaggistica.java e vediamo cosa si intende per
“interpretato”:
public ThreadInserisciMessaggistica(String destinatario,String
mittente,String text,StartMidlet m){
………………………………
codifica=new UrlCodec();
messaggio=UrlCodec.encode(messaggio);
URL="http://www.us.it/ServerGeco/ServletInviaMessaggio?mittente="+idmittente+"&d
estinatario="+iddestinatario+"&msg="+messaggio;
}
public void run(){
HttpConnection conn = null;
InputStream is = null;
int rc = -1;
try
{
conn = (HttpConnection)Connector.open(URL);
int c;
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream();
is = conn.openInputStream();
while ((c = is.read()) != -1)
{
baos.write(c);
}
String s = new String(baos.toByteArray());
this.setDisplay(s);
}
}
Nel codice precedente si vede quindi come il messaggio debba
essere “codificato” in maniera opportuna per poter essere
interpretato lato server. Questa procedura prende il nome di “URL
ENCODING” In mancanza di questa codifica, la servlet
riceverebbe un messaggio con all’interno dei codici alfanumerici
84
dovuti alla spaziatura tra parole o all’inserimento di caratteri
speciali.
Lo vediamo nel codice di UrlCodec.java che segue:
public class UrlCodec {
public
static
final
int[]
array
={0x20,0x22,0x23,0x24,0x25,0x26,0x2A,0x2B,0x2C,0x2F,0x3A,0x3B,0
x3C,0x3D,0x3E,0x3F,0x40,0x5b,0x5c,0x5d,0x60,0x7b,0x7c,0x7d,0x7e
};
public UrlCodec() {
}
public static boolean isProtected(char c){
for(int i=0;i<array.length;i++){
if(c==array[i])
return true;
}
return false;
}
public static String encode(String input){
StringBuffer buffer=new StringBuffer();
for(int i=0;i<input.length();i++){
if(isProtected(input.charAt(i))){
buffer.append("%"+Integer.toHexString(input.charAt(i)));
}
else{
buffer.append(input.charAt(i));
}
}
return buffer.toString();
}
A questo punto è quindi possibile inserire spazi e altri caratteri
speciali nel testo senza che questo influenzi il buon esito dell’invio.
Resta quindi da capire come il destinatario riceve il messaggio.
Dobbiamo quindi analizzare la classe ThreadRiceviMessaggio.java
che è stata instanziata nel panner la prima volta:
85
public ThreadRiceviMessaggio(int idIN,StartMidlet m) {
timerricezionesms=new Timer();
URL="http://www.us.it/ServerGeco/ServletRecapitaMessaggio?id="+id;
}
public void run(){
……………………..
try
{
conn = (HttpConnection)Connector.open(URL);
int c;
ByteArrayOutputStream
baos
=
new
ByteArrayOutputStream();
is = conn.openInputStream();
while ((c = is.read()) != -1)
{
baos.write(c);
}
String s = new String(baos.toByteArray());
if(!s.equals(null)){
String temp="";
int conta=0;
String idmittente="";
String testo="";
for(int i=0;i<s.length();i++){
if(s.charAt(i)!=','){
temp=temp+s.charAt(i);
}
else{
if(conta==0){
conta++;
idmittente=temp;
temp="";
}
else{
if(conta==1){
conta++;
testo=temp;
mess=new Messaggio();
mess.setMittente(idmittente);
mess.setMessaggio(testo);
idmittente="";
}}
this.alert(V);
……………………. . . .
if(!mes.isEmpty()){
mm.mappa.mc.m_panner.m_gameAction=0;
Form
f=new
Form("Ricevuto
"+V.size()+"
Messaggi");
this.setFlag();
alert.setTimeout(Alert.FOREVER);
alert.setTitle("Hai ricevuto nuovi Messaggi");
String text="";
Enumeration enumerazione=mes.elements();
86
while(enumerazione.hasMoreElements())
{
Messaggio
messs=(Messaggio)enumerazione.nextElement();
text
=text+"FROM
"+messs.getMittente()+":"+messs.getMessaggio()+"\n";
}
mes.removeAllElements();
Command cmd =new Command("OK",Command.OK,1);
alert.setString(text);
alert.addCommand(cmd);
alert.setCommandListener(mm);
mm.mappa.mc.m_panner.threadricevimessaggio.cancel();
}
Da notare come il destinatario, ad intervalli regolari impostati dalla
classe timer ed eventualmente parametrizzabile dall’utente, riceva
tutti gli eventuali messaggi degli altri utenti. Il sistema in
automatico legge dal database ogni x secondi gli eventuali messaggi
per l’utente. Se sono presenti messaggi la midlet blocca il panning e
provvede a gestirli. Ad ogni intervallo, il sistema richiede i nuovi
messaggi e l’architettura sottostante si preoccupa di marcare
suddetti messaggi come “gia letti” per evitare un secondo invio
degli stessi. Anche nel caso in cui vi fossero più messaggi da parte
di più utenti, la suddetta classe mostra una “pop-up7” per ognuno di
essi visualizzando per primo il messaggio più recente. L’utente
quindi visualizza il testo del messaggio accompagnato dall’id del
mittente e, una volta letto, può digitare il tasto “OK” e procedere
alla lettura della prossima pop-up. Terminati tutti i messaggi,
7
Messaggio istantaneo visualizzato in un apposito riquadro solitamente più piccolo del display
in uso
87
l’utente può proseguire nell’utilizzo dell’applicazione. Da notare
che i messaggi risiedono sul server e che, siccome gli eventi si
susseguono in modo asincrono nella community, potrebbe capitare
che un utente esca dal sistema prima di ricevere un messaggio
inviatogli da un altro utente attivo. Il mittente quindi non riesce ad
accorgersi in tempo che il destinatario non risulta più collegato e
procede all’invio del messaggio. Questa situazione non desiderata
comporterebbe ovviamente la perdita del messaggio se non fosse
presente il flag di lettura dello stesso. In tal modo, il destinatario
scollegatosi appena pochi secondi prima, riuscirà a visualizzare il
messaggio al suo prossimo login nel sistema. Ovviamente, un
timestamp sul messaggio avviserà il destinatario del giorno e
dell’ora esatta in cui gli è stato inviato.
Package bluetooth
Del package bluetooth da notare solo la classe GPSInfo.java che
effettua il parsing delle stringhe inviate dal dispositivo GPS.
Mostriamo solo i metodi relativi alla gestione dei dati:
88
public String getUTC() {
return utc;
}
public double getLatitude() {
return lat;
}
public double getLongitude() {
return lon;
}
public int getSatelliteCount() {
return nsat;
}
public double getAccuracy() {
return accuracy;
}
public double getAltitude() {
return alt;
}
La classe quindi lavora sui dati del gps e opera delle opportune
scomposizioni della stringa ricevuta in maniera tale da poter fornire
i singoli dati attraverso i suddetti metodi.
Package funzioni
Del package funzioni invece sono da notare le classi TileUtils.java e
CaricaImmagine.java.
Iniziamo
ad
analizzare
la
classe
CaricaImmagine:
public CaricaImmagine(int xx,int yy,int z){
x=xx;
y=yy;
zoom=z;
89
}
public Image getImmagine() {
String
utl="http://mt1.google.com/mt?n=404&x="+x+"&y="+y+"&zoom="+zoom
;
Come gia detto all’inizio del documento la modalità di visione
mappe è completamente diversa dal servizio di mappe fornito da
Google. Questo url nel codice in alto, opportunamente modificato
in modo da inserire valori al posto delle variabili, fornisce la
visualizzazione di un solo tile. Uno studio approfondito è stato
effettuato su questo url e sul tile da esso fornito. L’url in questione,
d’altra parte,
non è unico. Siamo giunti alla conclusione che
Google gestisce diversi server su cui tiene memorizzate le mappe e
per di più ha anche diverse versioni di mappe che differiscono, ad
un rapido sguardo, per colore e informazioni presenti.
try {
conn=(HttpConnection)Connector.open(utl);
conn.setRequestProperty("UserAgent","Profile/MIDP-2.0 Configuration/CLDC-1.1");
Inoltre, dopo aver lavorato per circa due mesi all’applicazione, non
era più possibile visualizzare mappe. Dopo un attento studio
abbiamo trovato soluzione con la porzione di codice di cui sopra.
Facciamo un passo indietro. L’url dal quale preleviamo tiles poteva
essere aperto in un qualsivoglia browser, sia esso un web-browser o
90
un mobile-browser. Dopo oltre due mesi di sviluppo, google, senza
alcun preavviso ne documentazione a riguardo, ha impostato i suoi
server in maniera tale che ad ogni richiesta di tile dovesse essere
esplicito il tipo di browser che la sta effettuando. La difficoltà di
interpretazione di questo meccanismo è stato soprattutto il fatto che
sembrava scontato che un browser desse informazioni di se stesso
ma, mentre questo può essere vero per un web-browser, non lo è di
sicuro per il client emulato dal WTK della SUN. Su un dispositivo
reale, invece, il problema sembrava non porsi
Librerie matematiche esterne
Per realizzare le trasformazioni da coordinate geografiche in
coordinate grafiche sul display, per posizionare correttamente
un marker sul tile di riferimento avendo le sue coordinate e per
sapere le coordinate x ed y del tile che contiene uno specifico
punto identificato dalle sue coordinate geografiche è stato
necessario utilizzare la classe TileUtils.java.[50] Questa classe
utilizza due librerie esterne, MatC e MatFP per poter calcolare
91
funzioni matematiche che non sono presenti nella libreria di base
di J2ME. In particolar modo si è dovuta implementare la
funzione logaritmo poiché essa, pur essendo presente nelle
suddette librerie, necessitava di una opportuna correzione in
quanto il risultato del logaritmo non era corretto. Abbiamo
quindi in parte riscritto la libreria MathC affinché fornisse il
corretto valore del calcolo dei logaritmi. La libreria MathFP
invece contiene le funzioni di seno e coseno, anch’esse non
presenti nella libreria di base. La funzione atan (arctangente) di
suddetta classe infatti viene utilizzata in TileUtils.java assieme
alle altre per il corretto posizionamento del punto sul display.
[51]
92
6. L’ESEMPIO DELLA GIS COMMUNITY
Vediamo, schermata per schermata come si presenta la midlet
all’utente.
A sinistra la schermata di avvio. A destra la prima schermata di
autenticazione con login e password.
93
L’avvenuta autenticazione con la scelta della community a cui ci
si è registrati. Lesempio mostra solo una community ma ve ne
potrebbero essere diverse.
94
La visualizzazione della mappa di default con i relativi
marker degli utenti attivi nella community scelta.
95
Esempio di uso delle funzioni. A sinistra la funzione di
attivazione del gps. A destra un esempio di zoom-in sulla mappa
di default.
96
Esempio di zoom-out a sinistra ed a destra l’uso della funzione
di ricerca di utenti a distanza con inserimento parametro in
metri.
97
7. CONCLUSIONI
Lo svolgimento del lavoro ha portato alla realizzazione di un
sistema concreto ed utilizzabile a tutti gli effetti. Il sistema è stato
realizzato rispettando in pieno le premesse iniziali, legate
all’utilizzo di software open source. Sono state realizzate le
principali funzioni e servizi previsti che consentono la gestione base
di una mobile community, e soprattutto,
è stata trovata una
soluzione software che ha consentito la visualizzazione di mappe
avanzate, come quelle fornite dal servizo di Google Maps, sui
dispositivi mobili di utilizzo comune e con capacità limitate.
In aprticolare la soluzione software proposta, basata sull’ algoritmo
descritto nel capitol 5, può essere facilmente riutilizzata in altri
contesti applicativi, in virtù del fatto che la classi sviluppate sono
state progettate ed organizzate come una libreria indipendente.
Il capitolo 6 mostra chiaramente con degli esempi il livello
operativo raggiunto nello sviluppo del progetto, in termini di
fruizione di servizi, usabilità dell’interfaccia, ecc. Il sistema è stato
testato con successo nella pratica, tramite l’utilizzo di dispositivi
mobili e supporti hardware illustrati in una scheda tecnica sintetica
presentata nell’appendice A. Una opportuna configurazione dei
98
tempi (timeout) di aggiornamento dei servizi di localizzazione, ha
inoltre evidenziato, come l’uso di questo sistema, per un utente,
possa anche essere considerato relativamente economico, rispetto ai
costi di traffico dati su canale GPRS, calcolati sulle tariffe medie
dei principali operatori di telefonia.
99
8. SVILUPPI FUTURI
J2ME mette a disposizione un sistema di memorizzazione dati sul
dispositivo detto RMS8 attraverso il quale sarebbe possibile, in
maniera ottimizzata, tenere traccia dei tiles scaricati, sia per evitare
un ulteriore download degli stessi e quindi velocizzare il processo
di visualizzazione della mappa e sia per ottimizzare il traffico dati
sulla rete GPRS. In altre parole, un meccanismo per mantenere, in
un database del dispositivo, dati persistenti garantirebbe la fruizione
di mappe già scaricate anche in assenza di connessione.
Con l’evoluzione al WEB2.0 è possibile ipotizzare l’integrazione
con altre tecnologie di sviluppo per Java come JAVAFX MOBILE.
JavaFx mobile è un framework progettato per realizzare
applicazioni mobili ricche di contenuti multimediali, di maggior
impatto sull’utente finale ed abilita molte altre funzionalità del
sistema di reti wireless. Con JavaFx quindi sarebbe possibile
realizzare nuove funzionalità avanzate ad uso delle community,
come esecuzione di file audio e video. Completamente basata sulle
8
Record Management Store. Il sistema di j2me per la memorizzazione dei dati su dispositivi
mobili.
100
pre-esistenti API di Java Micro Edition, il framework JAVAFX
consentirebbe maggiore rapidità di sviluppo e maggiori contenuti.
Attualmente il progetto Geco Client è installabile anche su
dispositivi PDA. Purtroppo, non essendo stati implementati i metodi
del touchscreen, è possibile scorrere la mappa in maniera limitata al
classico
joystick
presente
sui
dispositivi.
Sarebbe
quindi
interessante realizzare una interfaccia per PDA per migliorarne
l’usabilità. La struttura stessa del PDA consentirebbe anche un’
evoluzione dei marker: il Touch Pen9 (o stilo) consente infatti un
rapido ed immediato accesso all’interfaccia grafica e, inoltre, l’uso
della stilo faciliterebbe la possibilità di selezionare aree di interesse
(tramite dragging) e garantirebbe una migliore interazione.
9
La penna classica con cui sono dotati i dispositivi a touchscreen
101
APPENDICE A
L’applicazione è stata testata su diverse tipologie di cellulari, ed in
particolare test esaustivi sono stati fatti per:
• smartphone nokia E65
• palmare nokia 6630
• smartphone HTC P3300
con le seguenti antenne gps:
• Antenna GPS Bluetooth blumax Sirf Star 3
• Antenna GPS Blutooth RoyalTek RBT 2010 Sirf Star 3
Caratteristiche tecniche:
Nokia E65:
Caratteristiche
Reti
Dimensione display
[pixel]
Colore del display
Funzione palmare
Connessioni internet
Connessioni pc
Browser web
Altre informazioni
Sistema operativo
Memoria
Memoria ram
disponibile [mb]
Dual mode umts/gsm
(900/1800/1900)
352 x 416
16 milioni di colori tft
Si
Gprs,edge
Wifi,bluetooth,infrarossi,cavo
usb
Wap
Symbian 9.1 - serie 60 3rd
edition
70
102
Nokia 6630:
Caratteristiche
Dual mode umts/gsm
(900/1800/1900)
Dimensione display [pixel] 176 x 208
Colore del display
65000 colori tft
Funzione palmare
Si
Connessioni internet
Gprs,edge
Connessioni pc
bluetooth,cavo usb
Browser web
Wap
Altre informazioni
Symbian 8.0 - serie
Sistema operativo
60 3rd edition
Memoria
Memoria ram disponibile [mb] 10
Reti
HTC P3300:
Caratteristiche
Reti
Dimensione display
[pixel]
Colore del display
Funzione palmare
Connessioni internet
Connessioni pc
Browser web
Altre informazioni
Sistema operativo
Memoria
Memoria rom
Dual mode gsm
(900/1800/1900)
2.8” matrice attiva TFT
65000 colori tft
Si
Gprs, Edge
WI-FI, bluetooth,cavo
usb
Wap
Windows Mobile 5.0
128
103
disponibile [mb]
Memoria ram
disponibile [mb]
64
Antenna GPS Bluetooth blumax Sirf Star 3:
*Chipset Sirf Star III
*Frequenza: L1, 1.575,42 Mhz
* Canali: 20
* DGPS: SBAS (WAAS, EGNOS)
* Posizione: 10m 90%
* Velocita: 0.1 metri/secondo, senza SA'
* Tempo: 1 microsecondo sincronizzato al riferimento GPS
* Riacquisizione: 0.1 sec
* Cold Start : 42 sec
* Warm Start: 35 sec
* Hot Start : 1 sec
* Altitudine: <18,000 metri; Velocita': <515 metri/sec;
* Collegamento Bluetooth (classe 2) SPP - Serial Port Profile
* Protocollo:NMEA GGA, GLL, GSA, GSV; RMC, VTG,
57600 bps
* Autonomia: 17 ore di funzionamento continuo
Antenna GPS Blutooth RoyalTek RBT 2010 Sirf Star 3:
* Chipset Sirf Star III
* Frequenza: L1, 1.575,42 Mhz
* Canali: 20
* DGPS: SBAS (WAAS, EGNOS)
* Sensibilita': -159dBm
* Posizione: 10m 90%
* Velocita: 0.1 metri/secondo, senza SA'
* Tempo: 1 microsecondo sincronizzato al riferimento
GPS
* Riacquisizione: 0.1 sec
* Cold Start : 42 sec
104
* Warm Start: 35 sec
* Hot Start : 1 sec
* Altitudine: <18,000 metri; Velocita': <515 metri/sec;
* Protocollo:NMEA GGA, GLL, GSA, GSV; RMC, VTG,
57600 bps
* Autonomia: 17 ore di funzionamento continuo
* Dimensioni 70 x 41 x 30 mm; Peso: 85gr
Guida all’istallazione e configurazione del sistema:
Requisiti software
CLDC/MIDP 1.1/2.0 o superiore.
Requisiti hardware
• Il dispositivo mobile deve avere capacità di calcolo
sufficiente
(smartphone o palmare).
• Il dispositivo deve essere dotato di antenna GPS esterna o
interna (per navigazione con sistema di coordinate
LAT/LON).
Passi da compiere per l’installazione:
1. scaricare la midlet da sito (es. www.u-s.it).
2. eseguire il deploy della midlet sul dispositivo mobile
3. lanciare la midlet.
Modi per effettuare il deploy della midlet:
1. via cavo usb con nokia tool (solo per dispositivi nokia)
2. via OTA (Over The Air) con bluetooth
105
WEBGRAFIA
(i link di seguito riportati sono stati visitati nel periodo che va da
ottobre 2007 a febbraio 2008)
[1] http://j2memap.8motions.com/
[2]
http://www.easywms.com/easywms/?q=en/suas-mapserver-mobile-
client-ii
[3] http://developers.sun.com/mobility/midp/articles/bluetooth2/
[4] https://meapplicationdevelopers.dev.java.net/
[5] http://www.substanceofcode.com/software/mobile-trail-explorer/
[6] http://www.metah.ch/blog/?p=178
[7] http://rilievo.poliba.it/fotosat/convegno2003.html
[8] http://en.wikipedia.org/wiki/Geocoding
[9] http://it.wikipedia.org/wiki/Wikipedia:Bar/Google_Maps
[10] http://www.secondarydata.com/software/mrslgeo.asp
[11] http://www.slideshare.net/mra1124/geo-mapping/
[12] ] http://forums.java.net/jive/forum.jspa?forumID=111
[13] http://j2me.javastaff.com/
106
[14]
http://www.cs.sjsu.edu/faculty/pearce/j2me/J2ME%20Programming.htm
[15]http://www.massimocarli.it/site/index.php?option=com_content&task
=category&sectionid=5&id=35&Itemid=32
[16] http://www.jcp.org/en/jsr/tech?listBy=1&listByType=platform
[17] http://mobile.html.it/guide/leggi/124/guida-j2me/
[18] http://today.java.net/pub/a/today/2004/10/08/J2ME-2.html
[19] http://www.mokabyte.it/2002/07/j2me-6.htm
[20] http://www.java2s.com/Code/Java/J2ME/HttpConnection.htm
[21]http://www2.mokabyte.it/cms/article.run?articleId=Y72-YYX-A2UODE_7f000001_30480431_a21c5804
[22]
http://www.giuseppesicari.it/articoli/java-2-micro-edition/location-
api/
[23] http://www.javaportal.it/rw/24746/editorial.html
[24] http://www.ddj.com/mobile/184406388
[25] http://today.java.net/pub/a/today/2004/04/01/gis.html
[26]http://www.mobileutopia.com/Code/0emq1a0y6_Info+on+the+JSR+179+-+Location+API
107
[27]http://www.forum.nokia.com/info/sw.nokia.com/id/175bf8e6-a1f54d3d-a5916fc936506a6b/MIDP_Location_API_Developers_Guide_v2_0_en.pdf.html
[28] http://www2.mokabyte.it/cms/article.run?articleId=Y72-YYX-A2UODE_7f000001_30480431_a21c5804
[29] http://mapki.com/wiki/Satellite_Tile_Layout
[30] http://blog.grimpoteuthis.org/2005/02/mapping-google.html
[31] http://it.wikipedia.org/wiki/Keyhole_Markup_Language
[32]http://www.java2s.com/Code/Java/J2ME/UseGETorPOSTtocommuni
catewith
aJavaservlet.htm
[33] http://www.developer.com/java/j2me/article.php/10934_1561591_4
[34] http://www.ros-softair.net/Uso_GPS.html
[35] http://www.microjava.com/articles/techtalk/midp2_games
[36] http://www.wmlscript.it/j2me_pro/locationapi.php
[37] http://www.mgmaps.com/cache/MapTileCacher.perl
[38] http://www.cse.buffalo.edu/~ajay/googlemaps.html
[39] http://mapki.com/wiki/Lat/Lon_To_Tile
[40]http://maps.google.com/mapdata?latitude_e6=40803210&longitude_e6
=14197070&zm=340000&w=800&h=600&cc=us&min_priority=2
108
[41]http://dunck.us/collab/Simple_20Analysis_20of_20Google_20Map_20a
nd_20Satellite_20Tiles
[42]
http://googlemapsapi.blogspot.com/2006/08/draggable-markers-
and.html
[43] http://mapki.com/index.php?title=Icon_Image_Sets
[44] http://mapki.com/index.php?title=Lat/Lon_To_Tile
[45] http://snippets.dzone.com/posts/show/531
[46] http://mapki.com/wiki/Automatic_Tile_Cutter
[47] http://mapki.com/wiki/Tile_utility_code_in_Java
[48]http://code.djangoproject.com/browser/django/branches/gis/django/co
ntrib/gis/maps/google/zoom.py
[49]http://it.wikipedia.org/wiki/Wikipedia:Mappa_dei_wikipediani
[50] http://www.nabble.com/Re:-Logaritmo-em-JavaME-p13355848.html
[51] http://home.rochester.rr.com/ohommes/MathFP/index.html
[52] http://www.faunalia.it/pdf/Mondogis_2005_49.pdf
[53]
http://www.bostongis.com/PrinterFriendly.aspx?content_name=postgis_tu
t01
109
[54]
http://www.bostongis.com/postgis_quickguide.bqg?outputformat=PDF
110
BIBLIOGRAFIA
Giuseppe Balzano (2007/2008) GECO MOBILE:un’infrastruttura java di
utenti di una mobile community, Salerno, Università degli Studi.
H. Bergsten (2004) Java Server Pages 2nd Editino, O'Reilly.
Giovanni Biallo (2005) Introduzione ai Sistemi Informativi Geografici, I
quaderni di MondoGis.
Martin C. Brown (2006) Hacking Google Maps and Google Earth, Wiley
Publishing.
D. Crane, E. Pascarello (2006) Ajax in Action, Manning.
Bruce Eckel (2006) Thinking in Java 3rd Edition.
Schuyler Erle, Rich Gibson (2006) Google Maps Hacks, O'Reilly.
B. Hopkins, R. Antony (2003) Bluetooth for Java, Apress.
B. Momjian (2001) PostgreSQL Introduction and Concept, Addison Wesley.
John W. Muchow (2002) J2ME: guida pratica alla programmazione dei
dispositivi wireless, Mc Graw Hill.
Stefano Sanna (2007) Java Micro Edition: sviluppare applicazioni networkoriented per telefoni cellulari e PDA, HOEPLI.
111