Bygg en treningsapplikasjonsapp Persistence & Graphing

Velkommen til den andre og siste delen i denne serien av opplæringsprogrammer for å utvikle et treningsprogram med PhoneGap. I denne opplæringen vil vi fullføre siden for sporopplæring og fullføre appen ved å opprette siden Historikk og sporinfo.


Lagre GPS-dataene

Når brukeren klikker på Stopp sporing knappen, må vi slutte å følge GPS-posisjonen og lagre alle GPS-poengene som ble spilt inn (tracking_data) i databasen. Vi vil også tilbakestille tekstinnmatingsboksen (hvis de ønsker å ta opp en annen treningsøkt med en gang), og vi vil vise en melding om at vi har stoppet plasseringssporing.

PhoneGap tilbyr både nettleserbasert lokal lagring og en SQLite-database som metoder for lagring av data på telefonen. SQL-databasen er mye kraftigere (på grunn av at du kan angi tabellskjemaer), men kommer på bekostning av kodekompleksitet. Lokal lagring er en enkel nøkkel / verdi butikk som er lett å sette opp og bruke. Data lagres ved hjelp av setItem (nøkkel, verdi) metode, og hentet ved hjelp av getItem (nøkkel) metode.

I ExerciseTracker-appen må vi lagre tracking_data (en rekke posisjonobjekter). Vi setter nøkkelen til å være track_id (teksten / ID brukeren skrev inn for sin øvelse) og verdien til å være en strengrepresentasjon av et JSON-objekt av tracking_data. Vi er tvunget til å konvertere dette arrayet til JSON fordi Local Storage kun kan lagre strenger.

 $ ("# startTracking_stop"). live ('klikk', funksjon () // Stopp sporing av brukernavigator.geolocation.clearWatch (watch_id); // Lagre sporingsdata window.localStorage.setItem (track_id, JSON.stringify (tracking_data)); // Tilbakestill watch_id og tracking_data var watch_id = null; var tracking_data = null; // Ryd opp UI $ ("# track_id") .val (""). show (); $ ("# startTracking_status ") .html (" Stoppet sporingstrening: "+ track_id +""););

Din søknad kan nå spore brukerens treningsøkter og lagre hvor de gikk på telefonen!


Nyttige utviklings snarveier

Nå vil vi legge til et par funksjoner til appen som bidrar til å redusere utviklingstiden. På hjemmesiden til ExerciseTracker vil du huske knappene "Clear Local Storage" og "Load Seed GPS Data". I den første opplæringen erklærte vi bare oppmerkningen for dem. Nå vil vi kode funksjonaliteten.

"Slett lokal lagring" og "Last inn GPS-data" -knappene på startsiden.

Som alle våre hendelsesbehandlinger i ExerciseTracker bruker vi jQuery bo() funksjon for å lytte etter klikkhendelse. Hvis knappen "Slett lokal lagring" slås av, kaller vi window.localStorage.clear () metode som sletter alle oppføringer i lokal lagring. Hvis knappen "Load Seed GPS Data" slås av, legger vi inn noen dummy GPS-data i databasen.

 $ ("# home_clearstorage_button"). live ('klikk', funksjon () window.localStorage.clear ();); $ ("# home_seedgps_button"). live ('klikk', funksjon () window.localStorage.setItem ('Eksempelblokk', '[' tidsstempel '): 1335700802000, "koordinater": "overskrift": null, " høyde ": null", lengdegrad ": 170,33488333333335," nøyaktighet ": 0," breddegrad ": - 45,87475166666666," speed ": null," altitudeAccuracy ": null, " tidsstempel ": 1335700803000", coords ":  "overskriften": null, "høyde": null "lengdegrad": 170,33481666666665, "nøyaktighet": 0, "breddegrad": - 45,87465, "speed": null, "altitudeAccuracy": null,  "tidsstempel": 1335700804000 "coords":  "overskriften": null, "høyde": null "lengdegrad": 170,33426999999998, "nøyaktighet": 0, "breddegrad": - 45,873708333333326, "speed": null, "altitudeAccuracy": null ,  "tidsstempel": 1335700805000, "coords":  "heading": null, "høyde": null, "lengde": 170,33318333333335, "presisjon": 0, "breddegrad": - 45,87178333333333, "speed": null , "altitudeAccuracy": null,  "tidsstempel": 1335700806000, "coords":  "overskriften": null, "høyde": null, "lengde": 170,33416166666666, "presisjon": 0, "breddegrad": - 45.871478333333336, "speed": null, "altitudeAccuracy": null,  "ti mestamp ": 1335700807000," coords ": " overskriften ": null," høyde ": null," lengdegrad ": 170,33526833333332," nøyaktighet ": 0," breddegrad ": - 45,873394999999995," speed ": null," altitudeAccuracy" : null,  "tidsstempel": 1335700808000, "coords":  "heading": null, "høyde": null, "lengde": 170,33427333333336, "presisjon": 0, "breddegrad": - 45,873711666666665, "speed ": null," altitudeAccuracy ": null, " tidsstempel ": 1335700809000," coords ": " heading ": null," høyde ": null", lengdegrad ": 170,33488333333335," nøyaktighet ": 0," breddegrad ": -45,87475166666666," speed ": null," altitudeAccuracy ": null] '); );

Historikkside

Fullført historikkside

Historiesiden viser alle treningsøktene brukeren har registrert. Når de klikker på en treningsøkt, åpner vi Sporinfo-siden, som inneholder detaljert informasjon (for eksempel avstand som er tilbrakt, tid tatt og rute plottet på et Google Map). Nedenfor er merket for historisiden.

 

Historie

  • Hjem
  • Spor treningsøkt
  • Historie

Nå må vi kode funksjonaliteten. Når brukeren laster inn siden, må vi generere en HTML-liste som inneholder alle registrerte treningsøkter. Fordi window.localStorage er bare et annet Javascript-objekt, vi kan ringe lengde() metode for å finne ut hvor mange treningsøkter brukeren har registrert. Vi kan deretter iterere over vår database som ringer til window.localStorage.key () metode (som returnerer en nøkkel for en gitt indeks) for å finne navnene på alle treningsøktene.

 // Når brukeren ser historikk siden $ ('# historie'). Live ('siderhow', funksjon () // Teller antall oppføringer i lokalStorage og vis denne informasjonen til brukeren tracks_recorded = window.localStorage.length ; $ ("# tracks_recorded"). html (""+ tracks_recorded +" trening (er) registrert "); // Tøm listen over innspilt spor $ (" # history_tracklist "). tom (); // Iterer over alle innspilte spor, fylle listen for (i = 0; i"+ window.localStorage.key (i) +""); // Fortell jQueryMobile for å oppdatere listen $ (" # history_tracklist "). Listview ('refresh'););

Vise historikk siden skal nå vise alle spore treningsøkter.


Spor informasjonsside

Sporinfo-siden viser informasjon om en individuell treningsøkt brukeren har fullført. Vi vil beregne avstanden de reiste, tiden det tok dem for å fullføre treningen, og også ruten tatt på et Google Map.

Fullført sporinfo-side

 

Vise enkelt trening

  • Hjem
  • Spor treningsøkt
  • Historie

Sporinfo-siden viser dynamisk, ikke statisk, informasjon. Innholdet på siden avhenger av hvilken trening brukeren klikket på fra siden Historikk. Så, vi trenger en måte å kommunisere hva treningen ble klikket på siden Sporinfo.

Når brukeren klikker en treningslink, setter vi inn en track_id attributt til

element. Da, når Track Info-siden er lastet, henter vi det track_id og vise riktig treningsinformasjon.

 $ ("# history_tracklist li a"). live ('klikk', funksjon () $ ("# track_info"). Attr ("track_id", $ (dette) .text ());); // Når brukeren ser spor info siden $ ('# track_info') live ('siderhow', funksjon () // Finn spor_id av treningen de ser var nøkkel = $ (dette) .attr track_id "); // Oppdater sporinfo-sideoverskriften til track_id $ (" # track_info div [data-roll = header] h1 "). tekst (nøkkel); // Få alle GPS-dataene for de spesifikke treningsvarnene = window.localStorage.getItem (key); // Slå de strengede GPS-dataene tilbake i en JS-objektdata = JSON.parse (data);

Beregner Avstanden til treningen

Chris Veness har skrevet en flott forklaring på hvordan å beregne avstanden mellom to GPS koordinater. Jeg brukte koden som en base for gps_distance funksjon.

 funksjon gps_distance (lat1, lon1, lat2, lon2) // http://www.movable-type.co.uk/scripts/latlong.html var R = 6371; // km var dLat = (lat2-lat1) * (Math.PI / 180); var dLon = (lon2-lon1) * (Math.PI / 180); var lat1 = lat1 * (Math.PI / 180); var lat2 = lat2 * (Math.PI / 180); var a = Math.sin (dLat / 2) * Math.sin (dLat / 2) + Math.sin (dLon / 2) * Math.sin (dLon / 2) * Math.cos (lat1) * Math.cos LAT2); var c = 2 * Math.atan2 (Math.sqrt (a), Math.sqrt (1-a)); var d = R * c; returnere d; 

Nå som vi har en funksjon for å beregne avstanden mellom to GPS-koordinater, og en matrise med GPS-koordinater brukeren registrert, kan vi summere alle de enkelte avstandene mellom tilstøtende punkter for å beregne den totale avstanden brukeren reiste.

 // Beregn total tilbakestilt avstand total_km = 0; for (i = 0; i < data.length; i++) if(i == (data.length - 1)) break;  total_km += gps_distance(data[i].coords.latitude, data[i].coords.longitude, data[i+1].coords.latitude, data[i+1].coords.longitude);  total_km_rounded = total_km.toFixed(2);

Beregning av treningsvarighet

Hver av GPS Stilling objekter har a tidsstempel Egenskap. Vi trekker bare tidsstempelet til den første registrerte GPS-posisjonen fra den siste innspillte GPS-posisjonen, for å gi oss den totale tiden som trengs for trening i millisekunder. Vi gjør deretter noen konverteringer for å beregne total tid i både minutter og sekunder.

 // Beregn total tid tatt for sporet start_time = nytt Dato (data [0] .timestamp) .getTime (); end_time = new Date (data [data.length-1] .timestamp) .getTime (); total_time_ms = end_time - start_time; total_time_s = total_time_ms / 1000; final_time_m = Math.floor (total_time_s / 1000); final_time_s = total_time_s - (final_time_m * 60); // Vis total avstand og tid $ ("# track_info_info"). Html ('Reiste '+ total_km_rounded +' km i '+ final_time_m +' m og '+ final_time_s +' s');

Plotting av ruten på Google Map

Til slutt må vi plotte treningsruten på et Google Map. Vi starter med å sette den innledende breddegraden og lengden som Google Map vil bli sentrert på som koordinatene til det første GPS-punktet. Vi erklærer deretter alternativobjektet som inneholder ulike innstillinger for Google Map. Vi lager deretter kartet, og angir at vi vil ha HTML-elementet med ID-en map_canvas å holde kartet.

 // Sett den innledende Lat og Long av Google Map var myLatLng = new google.maps.LatLng (data [0] .coords.latitude, data [0] .coords.longitude); // Alternativer for Google Map var myOptions = zoom: 15, senter: myLatLng, mapTypeId: google.maps.MapTypeId.ROADMAP; // Opprett Google Map, sett inn alternativer var kart = nytt google.mapsMap (document.getElementById ("map_canvas"), myOptions);

Hvis kartet ikke lastes inn, må du kontrollere at du gir riktig API-nøkkel i > av Google Map API i index.html. Med vårt kart opprettet, kan vi da plotte brukerens rute. Vi lager en matrise og fyller den med forekomster av google.maps.LatLng erstatte verdiene til hvert av GPS-punktene. Vi lager deretter en google.maps.PolyLine basert på disse koordinatene, og bruk linjen til kartet.

 var trackCoords = []; // Legg til hver GPS-oppføring i en matrise for (i = 0; i 

Konklusjon

Dette avslutter opplæringen om å bygge PhoneGap app ExerciseTracker. Jeg håper du har lært mye om de ulike teknologiene vi brukte. Hvis du har spørsmål, vennligst legg inn dem i kommentarene nedenfor!