A.T.P.: Un esempio di applicazione ibrida – Parte 6
Nella scorsa parte di questa serie, ho mostrato spiegato cosa è un accordion e come si può realizzare in jQuery Mobile. Successivamente, ho illustrato il codice delle pagine rimanenti e dell’unico foglio di stile personalizzato presente nell’applicazione. In questa sesta parte mostrerò i due database contenenti i dati relativi alle fermate fittizie dei mezzi pubblici che vengono impiegati dalla pagina ricerca.html ed il codice del file JavaScript che inizializza il comportamento delle pagine di Audero Trip Planner.
I database
Come già accennato, la nostra demo usufruisce di posizione geografiche prestabilite per segnalare le fermate dei mezzi pubblici e delle postazioni delle biciclette da utilizzare nell’effettuare i percorsi “calcolati”. Entrambi i database sono presenti nella cartella database e si chiamano database.json e database-bike.json. Il primo contiene i dati delle fermate dei mezzi su gomma e su rotaia mentre il secondo le (poche) fermate fittizie per il servizio di bike sharing. Entrambi i file sono caricati in modo asincrono utilizzando il metodo $.get() di jQuery quando è scaturito l’evento pageinit sulla pagina ricerca.html. I database sono stati scritti utilizzando il formato JSON che è divenuto uno dei più usati per lo scambio di informazioni andando a sostituire formati precedentemente usati come XML. Il loro contenuto è usato, assieme alle API di Google Maps ed al codice scritto da noi, per mostrare il percorso ed i vari segnaposti delle fermate.
Il seguente listato (piuttosto lungo) rappresenta il contenuto del file database.json:
{
"origin": {
"id": 2295,
"name": "CINTIA-UNIVERSITA'",
"lat":40.83985,
"lng":14.18760
},
"destination": {
"id": 666,
"name": "VIA ELDORADO-CASTEL DELL'OVO",
"lat":40.82876,
"lng":14.24766
},
"path": {
"routes":[
[
{
"id": "R6",
"type": "bus",
"co2": 23,
"startTime": "2012-05-22T20:13:12+00:00",
"endTime": "2012-05-22T20:33:12+00:00",
"coords":[
{
"id": 2761,
"name": "CINTIA-PARCO SAN PAOLO",
"lat": 40.83732,
"lng": 14.18925
},
{
"id": 2135,
"name": "CINTIA-TANGENZIALE",
"lat": 40.83579,
"lng": 14.19027
},
{
"id": 2136,
"name": "CINTIA-PARCO SAN PAOLO",
"lat": 40.83360,
"lng": 14.19076
},
{
"id": 2185,
"name": "D'ANNUNZIO-CIMITERO",
"lat": 40.83144,
"lng": 14.19102
},
{
"id": 2655,
"name": "DE GENNARO-D'ANNUNZIO",
"lat": 40.82954,
"lng": 14.19357
},
{
"id": 2299,
"name": "MARINO-STADIO SAN PAOLO",
"lat": 40.82605,
"lng": 14.19417
},
{
"id": 2153,
"name": "TECCHIO-MOSTRA",
"lat": 40.82509,
"lng": 14.19275
},
{
"id": 2466,
"name": "TECCHIO-DIOCLEZIANO",
"lat": 40.82340,
"lng": 14.19279
},
{
"id": 2731,
"name": "TECCHIO-CAMPI FLEGREI",
"lat": 40.82306,
"lng": 14.19457
},
{
"id": 2902,
"name": "TECCHIO-CAMPI FLEGREI",
"lat": 40.82301,
"lng": 14.19409
}
]
},
{
"id": "R2",
"type": "bus",
"co2": 80,
"startTime": "2012-05-22T20:45:12+00:00",
"endTime": "2012-05-22T20:59:12+00:00",
"coords":[
{
"id": 2902,
"name": "TECCHIO-CAMPI FLEGREI",
"lat": 40.82301,
"lng": 14.19409
},
{
"id": "9999",
"name": "DEI FIORI",
"lat":40.82943,
"lng":14.22137
},
{
"id": "9998",
"name": "DELLE FARFALLE",
"lat":40.82876,
"lng":14.24766
}
]
}
]
,
[
{
"id": "R6",
"type": "bus",
"co2": 23,
"startTime": "2012-05-22T20:13:12+00:00",
"endTime": "2012-05-22T20:33:12+00:00",
"coords":[
{
"id": 2761,
"name": "CINTIA-PARCO SAN PAOLO",
"lat": 40.83732,
"lng": 14.18925
},
{
"id": 2135,
"name": "CINTIA-TANGENZIALE",
"lat": 40.83579,
"lng": 14.19027
},
{
"id": 2136,
"name": "CINTIA-PARCO SAN PAOLO",
"lat": 40.83360,
"lng": 14.19076
},
{
"id": 2185,
"name": "D'ANNUNZIO-CIMITERO",
"lat": 40.83144,
"lng": 14.19102
},
{
"id": 2655,
"name": "DE GENNARO-D'ANNUNZIO",
"lat": 40.82954,
"lng": 14.19357
},
{
"id": 2299,
"name": "MARINO-STADIO SAN PAOLO",
"lat": 40.82605,
"lng": 14.19417
},
{
"id": 2153,
"name": "TECCHIO-MOSTRA",
"lat": 40.82509,
"lng": 14.19275
},
{
"id": 2466,
"name": "TECCHIO-DIOCLEZIANO",
"lat": 40.82340,
"lng": 14.19279
},
{
"id": 2731,
"name": "TECCHIO-CAMPI FLEGREI",
"lat": 40.82306,
"lng": 14.19457
},
{
"id": 2902,
"name": "TECCHIO-CAMPI FLEGREI",
"lat": 40.82301,
"lng": 14.19409
}
]
},
{
"id": "6873",
"type": "metro",
"co2": 40,
"startTime": "2012-05-22T34:12:12+00:00",
"endTime": "2012-05-22T20:39:12+00:00",
"coords":[
{
"id": 9573,
"name": "CAMPI FLEGREI",
"lat":40.82305,
"lng":14.19371
},
{
"id": 9570,
"name": "PIAZZA AMEDEO",
"lat":40.83827,
"lng":14.23265
}
]
},
{
"id": "C21",
"type": "bus",
"co2": 80,
"startTime": "2012-05-22T20:45:12+00:00",
"endTime": "2012-05-22T21:09:12+00:00",
"coords":[
{
"id": 9192,
"name": "PIAZZA AMEDEO",
"lat":40.83827,
"lng":14.23265
},
{
"id": 9153,
"name": "RIVIERA DI CHIAIA",
"lat":40.83358,
"lng":14.23162
},
{
"id": 5382,
"name": "VIA ELDORADO-CASTEL DELL'OVO",
"lat":40.82876,
"lng":14.24766
}
]
}
]
,
[
{
"id": "R6",
"type": "bus",
"co2": 40,
"startTime": "2012-05-22T20:16:12+00:00",
"endTime": "2012-05-22T20:39:12+00:00",
"coords":[
{
"id": 2186,
"name": "CINTIA-MONTE SANT'ANGELO",
"lat":40.84046,
"lng":14.18724
},
{
"id": 2708,
"name": "CINTIA-TRAIANO",
"lat":40.848562,
"lng":14.181515
},
{
"id": 2769,
"name": "MONTAGNA SPACCATA 209",
"lat": 40.851272,
"lng": 14.17848
}
]
},
{
"id": "C12",
"type": "bus",
"co2": 15,
"startTime": "2012-05-22T20:16:12+00:00",
"endTime": "2012-05-22T20:39:12+00:00",
"coords":[
{
"id": 2769,
"name": "MONTAGNA SPACCATA 209",
"lat":40.851272,
"lng":14.17848
},
{
"id": 2761,
"name": "LA TRENCIA",
"lat":40.85119,
"lng":14.17801
}
]
}
,
{
"id": "98476",
"type": "metro",
"co2": 100,
"startTime": "2012-05-22T20:44:12+00:00",
"endTime": "2012-05-22T20:51:12+00:00",
"coords":[
{
"id": 9876,
"name": "LA TRENCIA",
"lat":40.85119,
"lng":14.17801
},
{
"id": 9875,
"name": "PIAVE",
"lat":40.84314,
"lng":14.20638
},
{
"id": 9873,
"name": "MONTESANTO",
"lat":40.84702,
"lng":14.24484
}
]
},
{
"id": "C47",
"type": "bus",
"co2": 66,
"startTime": "2012-05-22T20:54:12+00:00",
"endTime": "2012-05-22T21:20:12+00:00",
"coords":[
{
"id": 1649,
"name": "DEL LAMPO",
"lat":40.84702,
"lng":14.24484
},
{
"id": 1645,
"name": "DEI PESCATORI",
"lat": 40.84269,
"lng": 14.25244
},
{
"id": 1641,
"name": "DEI VIANDANTI",
"lat":40.82876,
"lng":14.24766
}
]
}
]
]
}
}
Il prossimo, invece, è il contenuto del file database-bike.json.
{
"stations": [
{
"name": "Piazza del Plebiscito",
"coords": {
"lat": 40.837028,
"lng": 14.248538
},
"details": {
"available_bycicles": 5,
"vacancies": 7
}
}, {
"name": "Riviera di Chiaia",
"coords": {
"lat": 40.83372,
"lng": 14.23355
},
"details": {
"available_bycicles": 2,
"vacancies": 16
}
}, {
"name": "Campi flegrei",
"coords": {
"lat": 40.82220,
"lng": 14.19460
},
"details": {
"available_bycicles": 5,
"vacancies": 7
}
}, {
"name": "Fuorigrotta",
"coords": {
"lat": 40.83441,
"lng": 14.19970
},
"details": {
"available_bycicles": 5,
"vacancies": 7
}
}
]
}
Funzioni utili
La nostra demo contiene solo due file JavaScript che ne determinano il comportamento. Essi sono utility.js and maps.js. Il primo, di cui parlerò in questo articolo, contiene tre metodi utili per inizializzare l’applicazione mentre il secondo le funzioni che lavorano con le API di Google Maps per mostrare la mappa, il percorso, i segnaposti delle fermate e così via.
Utility.js
All’interno del file in esame vi è una variabile chiamata Utility che possiede i metodi usati nell’applicazione. Chi conosce JavaScript, avrà sicuramente riconosciuto l’uso di un object literal, il nome con cui vengono chiamati gli oggetti creati in questo modo. Come alcuni di voi sapranno, in JavaScript vi sono vari modi per creare oggetti, in quanto il linguaggio è Object Oriented ma non nell’usuale concezione associata a questo concetto. Ad ogni modo, al suo interno, si trovano tre metodi che sono usati per inizializzare varie parti dell’applicazione.
Il primo, onDeviceReady(), è quello eseguito all’avvio di Audero Trip Planner e non fa altro che associare ad alcuni eventi le funzioni di callback, il cui scopo è inizializzare la pagina index.html e ricerca.html, presenti all’interno dello stesso file come si evince dalla riga $("#cerca-pagina").live("pageinit", Utility.initRicerca);. La funzione initIndex(), come detto, inizializza la homepage. In realtà, le uniche componenti che vengono gestite, sono le due etichette indicanti “La mia posizione” che, una volta cliccate, faranno partire la ricerca della posizione attuale dell’utente e la successiva chiamata alle API di Google Maps per rintracciare l’indirizzo fisico associato alla posizione. La terza ed ultima funzione, initRicerca(), gestisce il caricamento del file database.json. Una volta caricato, i dati vengono passati alla classe AuderoMap di cui parlerò nella prossima ed ultima parte della serie. Inoltre, associamo una funzione che calcola e mostra il nuovo percorso quando è scaturito l’evento generato in occasione del tocco da parte dell’utente su una parte dell’accordion, relativa ad un percorso differente rispetto a quello mostrato.
var Utility = {
onDeviceReady: function()
{
Utility.initIndex();
$.mobile.loading("hide");
$("#cerca-pagina").live("pageinit", Utility.initRicerca);
$("#home-pagina").live(
"pagebeforeshow",
function(event)
{
$("#da, #a").val("");
}
);
$("#home-pagina").live(
"pageinit",
function()
{
$.mobile.loading("show");
}
);
},
initIndex: function()
{
$("#da-link, #a-link").click(function(event) {
$.mobile.loading("show");
var addressId = this.id.substring(0, this.id.indexOf("-"));
navigator.geolocation.getCurrentPosition(function(position) {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
"location": new google.maps.LatLng(position.coords.latitude, position.coords.longitude)
},
function(results, status) {
$.mobile.loading("hide");
if (status == google.maps.GeocoderStatus.OK)
$("#" + addressId).val(results[0].formatted_address);
else
navigator.notification.alert(
"Geolocalizzazione fallita. Impossibile recuperare la tua posizione",
function(){},
"Errore"
);
});
},
function(error){
$.mobile.loading("hide");
navigator.notification.alert(
"Geolocalizzazione fallita. Impossibile recuperare la tua posizione",
function(){},
"Errore"
);
});
});
},
initRicerca: function()
{
$.getJSON(
"database/database.json",
function(data) {
map = new AuderoMap(data, "map");
map.calculateRoute(0);
map.displayMap("map");
}
);
$(".percorso").on(
"expand",
function() {
var routeNumber = parseInt($(this).attr("id").match(/\d/g));
map.calculateRoute(routeNumber);
}
);
}
}
Conclusioni
In questa sesta parte della serie dedicata ad A.T.P., ho mostrato i due database contenenti i dati relativi alle fermate dei mezzi pubblici ed il codice del file utility.js. Nella settima ed ultima parte della serie, illustrerò brevemente il contenuto del file maps.js e darò il link dove scaricare l’intero progetto “Audero Trip Planner”.