From: Robert Kaiser <kairo@kairo.at>
Date: Mon, 3 Nov 2014 03:09:46 +0000 (+0100)
Subject: limit the length of track sections to paint at once on app load; implement a display... 
X-Git-Tag: producution~23
X-Git-Url: https://git-public.kairo.at/?a=commitdiff_plain;h=7a076538678eb75b90e066df5e2d51346067927d;p=lantea.git

limit the length of track sections to paint at once on app load; implement a display of track length and duration
---

diff --git a/TODO b/TODO
index ac6da79..c73ceb4 100644
--- a/TODO
+++ b/TODO
@@ -7,12 +7,12 @@ Required:
 ** Pre-cache tiles in adjacent areas and possibly zoom levels
 * Improve texture cleaning algorithm
 * Show a notification when we are loading tiles or saved data
-* Display length and duration of track
 * Display movement speed
 * Display location accuracy
 * Show a better visible marker for the current location, possibly also indicating movement direction/speed
 * Smooth animations for zooming, probably using some WebGL magic
 * Use available larger/smaller tiles with resizing as loading placeholders while zooming in/out
+* Find better UI for track length/duration display
 * Better GPX saving implementation [blocked by missing web APIs]
 ** Set file name to save into to a good default (date + maybe some location name)
 
diff --git a/index.html b/index.html
index c83bc93..3a17444 100644
--- a/index.html
+++ b/index.html
@@ -22,6 +22,8 @@
 <input type="button" id="trackButton" value="Track"
        onclick="toggleTrackArea();"><br/>
 <fieldset id="trackArea"><legend>Track</legend>
+<p id="trackData"><span id="trackLength">0</span> km,
+<span id="trackDuration">0</span> min</p>
 <input type="button" id="saveTrackButton" value="Save"
        onclick="saveTrack();">
 <input type="button" id="dumpTrackButton" value="Dump"
diff --git a/js/map.js b/js/map.js
index ffafab4..f9ce632 100644
--- a/js/map.js
+++ b/js/map.js
@@ -187,11 +187,14 @@ function loadPrefs(aEvent) {
       if (aTPoint) {
         // Add in front and return new length.
         var tracklen = gTrack.unshift(aTPoint);
-        // Redraw track periodically, larger distance the longer it gets.
+        // Redraw track periodically, larger distance the longer it gets
+        // (but clamped to the first value over a certain limit).
         // Initial paint will do initial track drawing.
         if (tracklen % redrawBase == 0) {
           drawTrack();
-          redrawBase = tracklen;
+          if (redrawBase < 1000) {
+            redrawBase = tracklen;
+          }
         }
       }
       else {
@@ -651,7 +654,7 @@ function decodeIndex(encodedIdx) {
 }
 
 function drawTrack() {
-  if (document.hidden != true) { // Only draw if we're actually visible.
+  if (gTrackContext && (document.hidden != true)) { // Only draw if we're actually visible.
     gLastDrawnPoint = null;
     gCurPosMapCache = undefined;
     gTrackContext.clearRect(0, 0, gTrackCanvas.width, gTrackCanvas.height);
@@ -737,6 +740,50 @@ function undrawCurrentLocation() {
   }
 }
 
+function calcTrackDuration() {
+  // Get the duration of the track in s.
+  var tDuration = 0;
+  if (gTrack.length > 1) {
+    for (var i = 1; i < gTrack.length; i++) {
+      tDuration += (gTrack[i].time - gTrack[i-1].time);
+    }
+  }
+  return Math.round(tDuration / 1000); // The timestamps are in ms but we return seconds.
+}
+
+function calcTrackLength() {
+  // Get the length of the track in km.
+  var tLength = 0;
+  if (gTrack.length > 1) {
+    for (var i = 1; i < gTrack.length; i++) {
+      tLength += getPointDistance(gTrack[i-1].coords, gTrack[i].coords);
+    }
+  }
+  return tLength;
+}
+
+function getPointDistance(aGPSPoint1, aGPSPoint2) {
+  // Get the distance in km between the two given GPS points.
+  // See http://stackoverflow.com/questions/365826/calculate-distance-between-2-gps-coordinates
+  // Earth is almost exactly a sphere and we calculate small distances on the surface, so we can do spherical great-circle math.
+  // Also see http://en.wikipedia.org/wiki/Great-circle_distance
+  var R = 6371; // km
+  var dLat = deg2rad(aGPSPoint2.latitude - aGPSPoint1.latitude);
+  var dLon = deg2rad(aGPSPoint2.longitude - aGPSPoint1.longitude);
+  var lat1 = deg2rad(aGPSPoint1.latitude);
+  var lat2 = deg2rad(aGPSPoint2.latitude);
+
+  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));
+  return R * c;
+}
+
+function deg2rad(aDegreeValue) {
+  // Convert an angle in degrees to radiants.
+  return aDegreeValue * (Math.PI / 180);
+}
+
 var mapEvHandler = {
   handleEvent: function(aEvent) {
     var touchEvent = aEvent.type.indexOf('touch') != -1;
diff --git a/js/ui.js b/js/ui.js
index 0e0650f..5e4869c 100644
--- a/js/ui.js
+++ b/js/ui.js
@@ -144,6 +144,11 @@ function showUI() {
 
 function maybeHideUI() {
   gUIHideCountdown--;
+  if (document.getElementById("trackArea").style.display == "block") {
+    // If track area is visible, update track data.
+    document.getElementById("trackLength").textContent = calcTrackLength().toFixed(1);
+    document.getElementById("trackDuration").textContent = Math.round(calcTrackDuration()/60);
+  }
   if (gUIHideCountdown <= 0) {
     var areas = document.getElementsByClassName('overlayArea');
     for (var i = 0; i <= areas.length - 1; i++) {
diff --git a/manifest.appcache b/manifest.appcache
index 37528eb..64cfc96 100644
--- a/manifest.appcache
+++ b/manifest.appcache
@@ -1,6 +1,6 @@
 CACHE MANIFEST
 
-# 2014-09-11
+# 2014-11-02
 index.html
 manifest.webapp
 js/map.js
diff --git a/style/lantea.css b/style/lantea.css
index 6fa7aa0..e4e62a6 100644
--- a/style/lantea.css
+++ b/style/lantea.css
@@ -78,6 +78,10 @@ h1 {
   border-radius: 3px;
 }
 
+#trackData {
+  margin: 0;
+}
+
 #map, #track {
   position: fixed;
   border: 0;