Relazione del progetto di RAS Mobile Orientation Local Search

Pagina creata da Nicolo' Vitiello
 
CONTINUA A LEGGERE
Relazione del progetto di RAS Mobile Orientation Local Search
Relazione del progetto di RAS
                      Mobile Orientation Local Search
                          Alessandro Giannini, Matteo Mancini

                                      19 ottobre 2009

                                                        Descrizione del progetto

    Il progetto da noi svolto consiste in una MIDlet per la ricerca e la visualizzazione
di punti di interesse sfruttando le Location API (JSR 174) e i servizi di Google Local
Search e Google Static Map.
    Le applicazioni per mobile con funzionalità di ricerca di POI (Point of Interest),
come Google Maps Mobile, assumono implicitamente che la posizione corrente del ter-
minale sia il centro della ricerca; l’utente immette l’oggetto della ricerca (ad esempio
“ristoranti”, “alberghi” e cosı̀ via) e l’applicazione interroga un webservice che restitu-
isce una lista di risultati: i punti di interesse cercati che si trovano nelle vicinanze del
mobile. Oltre al centro della ricerca, solitamente l’utente non può specificarne neanche
il raggio.
    La MIDlet che abbiamo realizzato abbatte le due limitazioni di cui sopra: oltre
all’oggetto della ricerca, l’utente ha la possibilità di deciderne il raggio (in metri) e il
punto geografico che costituisce il suo centro. Il raggio di ricerca è un parametro che
viene immesso in una text box, mentre il centro di ricerca viene calcolato in funzione
di tre parametri:
  1. la posizione attuale P del mobile;
  2. la distanza in linea d’aria d dal centro di ricerca;
  3. l’orientamento del mobile.
Molto semplicemente, se indichiamo con α l’angolo che il terminale forma con il nord
(ricavabile a partire dalle informazioni sull’orientamento), il centro di ricerca C viene
ricavato come in figura.
   Abbiamo anche indicato il raggio r della ricerca e, di conseguenza, l’area in cui
verranno cercati i punti di interesse (area del cerchio centrato su C).
   Dei tre parametri elencati, la posizione e l’orientamento del mobile sono ricavabili
grazie alle Location API, mentre la distanza d è immessa dall’utente in una text box.
Se la distanza è zero, si ricade nella situazione di una ricerca che ha come centro il
mobile.

                                             1
Avere la possibilità di specificare un centro di ricerca diverso dal mobile potrebbe
essere conveniente in alcune situazioni, ad esempio:
  • indicare a un amico, che si trova in una determinata posizione rispetto al mobile,
    i punti di interesse a lui circostanti;
  • programmare un’uscita in un determinato posto e, di conseguenza, scoprire dei
    punti di interesse intorno ad esso;
  • scoprire semplicemente cosa c’è in una determinata direzione a una determinata
    distanza.
    Il fatto di poter decidere il raggio di ricerca è chiaramente utile in funzione della
capacità di spostamento dell’utente: chi si trova a piedi avrà interesse a punti relati-
vamente vicini a lui, e quindi specificherà un raggio di qualche centinaio di metri; chi
si trova su un mezzo di trasporto indicherà un raggio di qualche chilometro. Chi non
ha interesse a specificare un raggio in particolare può immettere il valore 0, e allora
la ricerca prenderà in considerazione qualsiasi punto di interesse, indipendentemente
dalla sua distanza rispetto al centro di ricerca.

                                                        Struttura della MIDlet

    La MIDlet è composta da tre packages: il package mols che contiene le classi del
progetto, e i package org.json.me e org.json.me.util contenenti una versione per
mobile del parser Json; questi ultimi due package sono necessari per interpretare le
risposte ottenute dal servizio di Google Local Search, appunto in formato Json. Il
supporto, da parte del mobile, delle Location API, è un prerequisito fondamentale per
il corretto funzionamento della MIDlet. La documentazione javadoc è disponibile nella
directory del progetto nella cartella docs.
    Il package mols comprende quattro classi:

                                            2
• Mols - la classe MIDlet del progetto;
  • GeoUtils - contiene alcuni metodi statici per calcoli di tipo geografico, come il
    calcolo delle coordinate del centro di ricerca e il calcolo approssimato della distanza
    tra due punti geografici;
  • GoogleRequestStub - come dice il nome, questa classe contiene gli stub per
    l’interfacciamento con i servizi di Google utilizzati nella MIDlet;
  • POI - estensione della classe Landmark delle Location API.
   Abbiamo concentrato nelle classi GeoUtils e GoogleRequestStub i metodi statici
di utilità acceduti dalla classe MIDlet. Quest ultima costituisce il cuore del progetto
e, oltre ad estendere chiaramente la classe MIDlet, implementa un certo numero di
interfacce:
  • CommandListener e ItemCommandListener - per gestire i comandi utente;
  • Runnable - per poter usare la classe come thread separato durante la connessione
    ai servizi di Google o delle Location API.
   La costruzione dell’interfaccia utente avviene interamente nel costruttore della classe
MIDlet; qui vengono inizializzate anche le variabili di controllo e della logica interna
di cui parleremo subito. I comandi utente sono raccolti e gestiti dalle implementazioni
delle classi CommandListener e ItemCommandListener; la gestione di un comando
avviene in due passi: il primo consiste nell’aggiornamento delle variabili di controllo
per richiedere la specifica operazione, mentre il secondo passo consiste nella chiamata
alla routine di disegno. La routine di disegno si chiama paintMe; essa gestisce ed ag-
giorna il contenuto della schermata in funzione dello stato corrente dell’applicazione e
del valore delle variabili di controllo.
   Se un comando utente innesca una connessione ad internet (si pensi al comando
“cerca punti di interesse”), la chiamata alla routine di disegno avviene indirettamente
attraverso il metodo repaint. Il compito svolto da repaint è lanciare la routine
paintMe in un thread separato, e modificare l’interfaccia utente in modo da riflettere il
fatto che sta avendo luogo una connessione ad internet. Quando si conclude il dialogo
con il webservice cui si sta accedendo, la routine paintMe visualizza i risultati, il thread
lanciato da repaint termina e l’interfaccia grafica viene aggiornata. Per realizzare il
funzionamento descritto, abbiamo aggiunto Runnable tra le interfacce implementate
dalla MIDlet, ed inserito nel corrispondente metodo run l’invocazione a paintMe.
   Da quanto detto possiamo suddividere la classe MIDlet in più blocchi logici:
  • costruttore - costruzione dell’interfaccia grafica, inizializzazione delle variabili di
    controllo e di logica interna;
  • metodi commandAction - gestione dei comandi utente, modifica delle variabili di
    controllo e di logica interna, invocazione delle routine di disegno;
  • metodi paintMe e repaint - aggiornamento schermata in funzione dello stato
    dell’applicazione e delle variabili di controllo.
con i quali abbiamo cercato di strutturare la MIDlet secondo uno schema Model-View-
Controller.

                                             3
Comportamento della MIDlet

   Le possibili schermate in cui ci si può trovare durante l’utilizzo della MIDlet sono
essenzialmente sei:
  1. schermata iniziale - mostra, su una mappa, la posizione attuale del mobile;
  2. schermata impostazioni - usata per settare i parametri di ricerca dei punti di
     interesse;
  3. schermata di ricerca - in questa form si richiede all’utente di orientare il mobile
     verso la direzione in cui si vuole effettuare la ricerca, e di innescare la ricerca
     stessa;
  4. schermata risultati - mostra i risultati della ricerca uno dopo l’altro;
  5. schermata dettagli - mostra informazioni dettagliate su un punto di interesse
     particolare;
  6. mappe d’insieme o mappa particolare - form in cui si visualizza su mappa:
       • un particolare punto di interesse P isolatamente, oppure
       • il punto P evidenziando anche la posizione relativa rispetto al mobile e al
         centro di ricerca, oppure
       • tutti i punti di interesse trovati, la posizione del mobile e del centro di ricerca.
    Il flusso di controllo tra le schermate è mostrato in Figura
    Al suo avvio, la MIDlet si connette al servizio Google Static Map per mostrare
all’utente una mappa centrata sulla posizione del mobile (vedi Figura 1). Per questo
esempio abbiamo usato l’emulatore di default, cioé il DefaultCldcPhone1, e tramite il
generatore di eventi esterni abbiamo impostato la posizione del mobile su un punto
della città di Pisa.

       Figura 1: schermata iniziale con evidenziata la posizione del mobile, e voci di menu.

   Il passo successivo è selezionare la voce Impostazioni dal menu, per accedere alla
schermata in cui si settano i parametri per la ricerca dei punti di interesse (Figura 2).

                                                4
Figura 2: schermata impostazioni e voci di menu.

   La schermata di impostazioni è abbastanza autoesplicativa. Si noti che, oltre ai
punti di interesse di default, è possibile specificare una qualsiasi stringa nel campo
“Altro”. Nell’esempio compare la stringa “ristoranti”. Più stringhe di ricerca possono
essere separate dal carattere “|” (esempio: “ristoranti|polizia”).
   A questo punto, selezionando Cerca POI, si visualizza la schermata di Figura 3.

                        Figura 3: schermata di ricerca e voci di menu.

   L’utente orienta il mobile verso la direzione desiderata e sceglie Cerca. Ora avviene
la connessione a Google Local Search e la ricerca dei punti di interesse con i parametri
specificati. Se ci sono risultati, essi vengono listati come in Figura 4.
   La lista dei risultati è numerata, e ad ogni punto di interesse sono associate la
distanza dal mobile e la distanza dal centro di ricerca. Come si nota, i valori in
figura sono compatibili con i parametri di ricerca specificati precedentemente. I valori
riportati sono distanze in linea d’aria, che non tengono conto della curvatura terrestre.
   Una volta ottenuti i risultati, è possibile visualizzarli su mappa scegliendo la voce
Mappa d’insieme. La mappa d’insieme consente di verificare la correttezza della ricer-

                                              5
Figura 4: risultati della ricerca con voci di menu.

ca rispetto all’orientamento del mobile. Per mezzo del generatore di eventi abbiamo
impostato un orientamento del terminale di 100 gradi rispetto al nord, ottenendo il
risultato di Figura 5.

               Figura 5: risultati della ricerca visualizzati sulla mappa d’insieme.

    Come si nota, l’orientamento è stato correttamente rilevato e trattato in fase di
ricerca. La mappa d’insieme mostra i punti di interesse con dei marker numerati, e tale
numerazione corrisponde a quella della lista dei risultati. Scegliendo la voce Indietro,
si ritorna alla schermata dei risultati; selezionando un elemento della lista e scegliendo
Dettagli si passa alla schermata di Figura 6.
    Oltre ad avere accesso alle informazioni dettagliate relative al punto selezionato, è
possibile visualizzare su mappa il punto stesso selezionando Visualizza su mappa o,
alternativamente, Mappa POI dal menu (Figura 7).
    Sempre dalla schermata dettagli, selezionando Mappa d’insieme si visualizza la po-
sizione del punto d’interesse rispetto a quella del mobile e del centro di ricerca (Figura

                                                6
Figura 6: dettagli di un punto di interesse particolare.

                     Figura 7: mappa di un punto d’interesse particolare.

8). La posizione del mobile è indicata con M, il centro di ricerca con C e il punto
d’interesse con P.
   Da ogni schermata è possibile ritornare a quella principale scegliendo Home dal
menu.

                                  Ambiente di lavoro e test della MIDlet

   Abbiamo sviluppato la MIDlet con l’IDE J2ME Sdk, rilasciato recentemente dal-
la Sun; il progetto è, chiaramente, una MIDP Application in cui come API opzionali
abbiamo selezionato solo le Location API. Per testare la MIDlet abbiamo usato l’em-
ulatore di default, ossia il DefaultCldcPhone1. Posizione del mobile, orientamento e
altre caratteristiche di tipo geografico sono state settate grazie al generatore di eventi
esterno. Purtroppo non siamo riusciti a modificare la posizione di default del mobile,

                                               7
Figura 8: mappa d’insieme relativa a un punto d’interesse particolare.

che ha latitudine e longitudine uguali a 2; queste coordinate fanno sı̀ che, all’avvio della
MIDlet, il mobile sia collocato virtualmente in mare aperto. Per modificare la posizione
ci sono due possibilità: immettere le coordinate a mano oppure utilizzare un file xml
di script contenente la posizione desiderata, da importare all’interno del generatore di
eventi. Abbiamo adottato questa seconda soluzione, e incluso nella directory di proget-
to la cartella emu scripts, contenente il file startpos.xml che posiziona il mobile nella
città di Pisa, come mostrato in Figura 1.

           Figura 9: importazione della posizione iniziale del mobile con file di script.

   Per effettuare l’importazione descritta sopra, è necessario aprire il generatore di
eventi, cliccare su Browse e quindi selezionare il file di script. A questo punto bisogna

                                                 8
cliccare sul pulsante di play, posto in basso nella finestra (Figura 9), ed infine scegliere
la voce Aggiorna mappa dal menu della MIDlet (Figura 1, a destra).
    Per coordinarci nel lavoro abbiamo usufruito del servizio gratuito di hosting di pro-
getti offerto da Google. Grazie a questo è possibile reperire via svn anonimo il progetto
sviluppato, all’indirizzo https://mols-gm-ras.googlecode.com/svn.

                                 Appendice: calcolo del centro di ricerca

   Il calcolo del punto centrale della ricerca viene effettuato dal metodo getSearchCentre
della classe GeoUtils. I parametri noti sono:

  • la posizione attuale P del mobile, che ha latitudine latP e longitudine lngP (ai fini
    del calcolo ignoriamo l’altitudine dei punti):

                                        P = (latP , lngP )

     Le coordinate di P sono ricavate grazie alle location API.
  • la distanza d, in linea d’aria, di P dal centro di ricerca, immessa dall’utente;
  • l’angolo α formato dal dispositivo rispetto al nord terrestre. Il metodo statico:

                              Orientation.getOrientation()

     permette di ottenere un oggetto Orientation che incapsula tutte le informazioni
     riguardanti l’orientamento attuale del mobile. Tra i metodi di questo oggetto, il
     seguente:

                                    getCompassAzimuth()

     restituisce il valore in gradi dell’angolo α. Il valore di α è compreso tra 0◦ e 360◦ .

I valori da determinare sono le coordinate geografiche del punto C:

                                     C = (latC , lngC )

mostrato in figura (10).
   Dato che l’applicazione sviluppata consente la ricerca dei punti di interesse nei parag-
gi del mobile, si suppone che la distanza d sia tale da poter considerare i punti P e C
giacenti sullo stesso piano; in altre parole, ignoriamo nei calcoli la curvatura terrestre.
   Supponiamo di voler determinare la latitudine del punto C a partire da quella di
P . La latitudine di P rappresenta l’angolo in gradi che separa P dall’equatore. Per
convenzione, tutti i punti che si trovano sull’equatore hanno latitudine 0; la latitudine
cresce fino ad arrivare a 90 in corrispondenza del polo nord, e decresce fino ad arrivare
a -90 in corrispondenza del polo sud.
   Supponendo che la terra sia una sfera avente un raggio di R metri, possiamo calcolare
la distanza di P dall’equatore moltiplicando R per la latitudine di P espressa in radianti.
Essendo latP un angolo espresso in gradi, la conversione in radianti si effettua nel modo
seguente:
                                                      π
                                   rad latP = latP ·
                                                     180
                                             9
Figura 10: collocazione del centro di ricerca.

                   Figura 11: rappresentazione grafica della latitudine di P.

e quindi:
                           distanza equatore = rad latP · R
Per ricavare la distanza di C dall’equatore basta sommare a alla quantità trovata (vedi
figura (10)). Ovviamente abbiamo:

                                       a = d · cos(α)

Sia x la distanza trovata; a questo punto possiamo dedurre la latitudine di C con un
procedimento inverso a quello spiegato:
  • dividiamo x per R ottenendo la latitudine di C in radianti;
  • eseguiamo la conversione in gradi dividendo per π e moltiplicando per 180.
Mettendo insieme tutti i passi abbiamo:
                                                     
                                      πR                 180
                       latC = latP ·      + d · cos(α) ·
                                      180                πR

                                              10
da cui:
                                                       180
                             latC = latP + d · cos(α) ·                             (1)
                                                       πR
   Per trovare la longitudine di C seguiamo lo stesso ragionamento. La longitudine
di P rappresenta l’angolo in gradi che P forma con il meridiano 0, e varia da +180 a
−180. Convertiamo quindi la longitudine di P in radianti e ricaviamo la distanza che
separa P dal meridiano 0; sia y la distanza ottenuta. Sommiamo a y la quantità b (vedi
figura (10)), che è uguale a:
                                      b = d · sin(α)
ottenendo la distanza che separa C dal meridiano 0, quindi ricaviamo la longitudine di
P con passaggi analoghi a quelli mostrati in precedenza.
                                                       
                                       πR                  180
                        lngC = lngP ·       + d · sin(α) ·
                                       180                 πR
Quindi:
                                                          180
                             lngC = lngP + d · sin(α) ·                             (2)
                                                          πR
Riassumendo, i risultati ottenuti sono i seguenti:
                                                     180
                          latC = latP + d · cos(α) · πR
                         
                         
                                                                                    (3)
                          lng = lng + d · sin(α) · 180
                         
                         
                               C           P
                                                      πR
In entrambe le equazioni compare la costante 180
                                              πR
                                                 , che possiamo definire come campo
statico. Per quanto riguarda la quantità R, una buona approssimazione è data dal
raggio quadratico medio della terra:

                                  R ≈ 6372795, 48m

Dalle formule si vede che, se d = 0, il punto C coincide con il punto P .

                                           11
Puoi anche leggere