limit the length of track sections to paint at once on app load; implement a display...
authorRobert Kaiser <kairo@kairo.at>
Mon, 3 Nov 2014 03:09:46 +0000 (04:09 +0100)
committerRobert Kaiser <kairo@kairo.at>
Mon, 3 Nov 2014 03:09:46 +0000 (04:09 +0100)
TODO
index.html
js/map.js
js/ui.js
manifest.appcache
style/lantea.css

diff --git a/TODO b/TODO
index ac6da7952e4dbb0099546972dedba6566973826a..c73ceb48a4709a86401f832807a2a10647129b75 100644 (file)
--- 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)
 
index c83bc9317ec61dd09e8f3d78d1294b2b880f8af3..3a17444a1b61845df91f06d6a8657a74850bd020 100644 (file)
@@ -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"
index ffafab4f8dfd768837f8ea67446851ce9336e5e2..f9ce632f83c9ecdb2d497bc159b16025a52d0177 100644 (file)
--- 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;
index 0e0650f1e44b095848a6b2ac2d2369dff4c1ecf6..5e4869c5d2862128f7a1cbd12bd4985d69e5333e 100644 (file)
--- 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++) {
index 37528eb17c1db094d9c6cba328a6501337a8eb4b..64cfc967c74fc33cdfd246a2af9839e8e1aa7300 100644 (file)
@@ -1,6 +1,6 @@
 CACHE MANIFEST
 
-# 2014-09-11
+# 2014-11-02
 index.html
 manifest.webapp
 js/map.js
index 6fa7aa013091b76ad1a4d1f144a20092b66e8634..e4e62a6eaf532d47d03b5d94b72d18753a36b7e6 100644 (file)
@@ -78,6 +78,10 @@ h1 {
   border-radius: 3px;
 }
 
+#trackData {
+  margin: 0;
+}
+
 #map, #track {
   position: fixed;
   border: 0;