update cached tiles if they're older than two weeks; add a button to clear the cache
authorRobert Kaiser <robert@widebook.box.kairo.at>
Sun, 30 Dec 2012 20:50:56 +0000 (21:50 +0100)
committerRobert Kaiser <robert@widebook.box.kairo.at>
Sun, 30 Dec 2012 20:50:56 +0000 (21:50 +0100)
TODO
index.html
js/map.js
manifest.appcache

diff --git a/TODO b/TODO
index bc104a0..e6ed5e7 100644 (file)
--- a/TODO
+++ b/TODO
@@ -3,10 +3,8 @@ Tasks to complete for Lantea Maps:
 Required:
 
 * Improve tile cache:
-** Use an intelligent algorithm to automatically try (async) updating tiles if they have a certain age
-*** If they have changed, possibly also try (async) updates of other cached zoom levels covering this area
-** Clear cached tiles option
-** Pre-cache tiles in adjecent areas and possibly zoom levels
+** If cached tiles have changed, possibly also try (async) updates of other cached zoom levels covering this area
+** Pre-cache tiles in adjacent areas and possibly zoom levels
 * Show a notification when we are loading tiles or saved data
 * Display length and duration of track
 * Display movement speed
index 2a73e5a..1f95b6e 100644 (file)
@@ -41,7 +41,9 @@
 Map style:
 <select id="mapSelector" onchange="setMapStyle();">
 <!-- option value="osm_mapnik">OpenStreetMap (Mapnik)</option -->
-</select>
+</select><br/>
+<input type="button" id="clearCacheButton" value="Clear Cached Maps"
+       onclick="gTileService.clearDB();">
 </fieldset>
 </div>
 
index b5fe9e2..9ffc81c 100644 (file)
--- a/js/map.js
+++ b/js/map.js
@@ -649,36 +649,40 @@ function clearTrack() {
 var gTileService = {
   objStore: "tilecache",
 
+  ageLimit: 14 * 86400, // 2 weeks
+
   get: function(aStyle, aCoords, aCallback) {
     var norm = normalizeCoords(aCoords);
     var dbkey = aStyle + "::" + norm.x + "," + norm.y + "," + norm.z;
     this.getDBCache(dbkey, function(aResult, aEvent) {
       if (aResult) {
         // We did get a cached object.
-        // TODO: Look at the timestamp and trigger a reload when it's too old.
         aCallback(aResult.image, aStyle, aCoords);
+        // Look at the timestamp and return if it's not too old.
+        if (aResult.timestamp + this.ageLimit > Date.now())
+          return;
+        // Reload cached tile otherwise.
+        console.log("reload cached tile: " + dbkey);
       }
-      else {
-        // Retrieve image from the web and store it in the cache.
-        var XHR = new XMLHttpRequest();
-        XHR.open("GET",
-                 gMapStyles[aStyle].url
-                   .replace("{x}", norm.x)
-                   .replace("{y}", norm.y)
-                   .replace("{z}", norm.z)
-                   .replace("[a-c]", String.fromCharCode(97 + Math.floor(Math.random() * 2)))
-                   .replace("[1-4]", 1 + Math.floor(Math.random() * 3)),
-                 true);
-        XHR.responseType = "blob";
-        XHR.addEventListener("load", function () {
-          if (XHR.status === 200) {
-            var blob = XHR.response;
-            gTileService.setDBCache(dbkey, {image: blob, timestamp: Date.now()});
-            aCallback(blob, aStyle, aCoords);
-          }
-        }, false);
-        XHR.send();
-      }
+      // Retrieve image from the web and store it in the cache.
+      var XHR = new XMLHttpRequest();
+      XHR.open("GET",
+                gMapStyles[aStyle].url
+                  .replace("{x}", norm.x)
+                  .replace("{y}", norm.y)
+                  .replace("{z}", norm.z)
+                  .replace("[a-c]", String.fromCharCode(97 + Math.floor(Math.random() * 2)))
+                  .replace("[1-4]", 1 + Math.floor(Math.random() * 3)),
+                true);
+      XHR.responseType = "blob";
+      XHR.addEventListener("load", function () {
+        if (XHR.status === 200) {
+          var blob = XHR.response;
+          gTileService.setDBCache(dbkey, {image: blob, timestamp: Date.now()});
+          aCallback(blob, aStyle, aCoords);
+        }
+      }, false);
+      XHR.send();
     });
   },
 
@@ -731,5 +735,23 @@ var gTileService = {
       if (aCallback)
         aCallback(success, event);
     }
+  },
+
+  clearDB: function(aCallback) {
+    if (!mainDB)
+      return;
+    var success = false;
+    var transaction = mainDB.transaction([this.objStore], "readwrite");
+    var request = transaction.objectStore(this.objStore).clear();
+    request.onsuccess = function(event) {
+      success = true;
+      if (aCallback)
+        aCallback(success, event);
+    };
+    request.onerror = function(event) {
+      // Errors can be handled here.
+      if (aCallback)
+        aCallback(success, event);
+    }
   }
 };
index de51bb0..6a4d8c0 100644 (file)
@@ -1,6 +1,6 @@
 CACHE MANIFEST
 
-# 2012-12-17
+# 2012-12-30
 manifest.webapp
 js/map.js
 js/ui.js