add a first version of a library view into Lantea
[lantea.git] / js / map.js
index 2532a034aeb76d92b1bdc5e6141cfd99cce604fb..b63aea5fe1272ffd773cc4464cc02781765b6e4b 100644 (file)
--- a/js/map.js
+++ b/js/map.js
@@ -14,34 +14,68 @@ var gCurLocColor = "#A00000";
 var gMapStyles = {
   // OSM tile usage policy: http://wiki.openstreetmap.org/wiki/Tile_usage_policy
   // Find some more OSM ones at http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_servers
+  // and http://wiki.openstreetmap.org/wiki/Tiles or http://wiki.openstreetmap.org/wiki/TMS
   osm_mapnik:
     {name: "OpenStreetMap (Mapnik)",
-     url: "http://tile.openstreetmap.org/{z}/{x}/{y}.png",
+     url: "https://[a-c].tile.openstreetmap.org/{z}/{x}/{y}.png",
      copyright: 'Map data and imagery &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>'},
   osm_cyclemap:
     {name: "Cycle Map (OSM)",
-     url: "http://[a-c].tile.opencyclemap.org/cycle/{z}/{x}/{y}.png",
+     url: "https://[a-c].tile.thunderforest.com/cycle/{z}/{x}/{y}.png", // "http://[a-c].tile.opencyclemap.org/cycle/{z}/{x}/{y}.png",
      copyright: 'Map data and imagery &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>'},
   osm_transmap:
     {name: "Transport Map (OSM)",
-     url: "http://[a-c].tile2.opencyclemap.org/transport/{z}/{x}/{y}.png",
+     url: "https://[a-c].tile.thunderforest.com/transport/{z}/{x}/{y}.png", // "http://[a-c].tile2.opencyclemap.org/transport/{z}/{x}/{y}.png",
      copyright: 'Map data and imagery &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>'},
+  osm_germany:
+    {name: "OSM German Style",
+     url: "https://tilecache[1-4].kairo.at/osmde/{z}/{x}/{y}.png", // route through CORS+SSL tilecache @ kairo.at
+     //url: "http://[a-d].tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png", // https is not supported at all
+     copyright: 'Map data and imagery &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>'},
+  oepnvkarte:
+    {name: "ÖPNV-Karte (OSM)",
+     url: "https://tilecache[1-4].kairo.at/oepnv/{z}/{x}/{y}.png", // route through CORS+SSL tilecache @ kairo.at
+     //url: "http://tileserver.memomaps.de/tilegen/{z}/{x}/{y}.png", // memomaps.de does not support CORS or https at this time :(
+     copyright: 'Map data &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>, tiles by <a href="http://memomaps.de">MeMoMaps</a> under <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>.'},
   mapquest_open:
     {name: "MapQuest OSM",
-     url: "http://otile[1-4].mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png",
-     copyright: 'Map data &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> and contributors (<a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>), tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a>.'},
+     url: "https://tilecache[1-4].kairo.at/mapqosm/{z}/{x}/{y}.png", // route through CORS+SSL tilecache @ kairo.at
+     //url: "http://otile[1-4].mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png", // https has wrong cert, akamai instead of mqcdn
+     copyright: 'Map data &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> and contributors (<a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>), tiles courtesy of <a href="http://www.mapquest.com/">MapQuest</a>.'},
   mapquest_aerial:
     {name: "MapQuest Open Aerial",
-     url: "http://otile[1-4].mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg",
+     url: "https://tilecache[1-4].kairo.at/mapqsat/{z}/{x}/{y}.png", // route through CORS+SSL tilecache @ kairo.at
+     //url: "http://otile[1-4].mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg",
      copyright: 'Tiles Courtesy of <a href="http://www.mapquest.com/">MapQuest</a>, portions Courtesy NASA/JPL-Caltech and U.S. Depart. of Agriculture, Farm Service Agency.'},
-  opengeoserver_arial:
-    {name: "OpenGeoServer Aerial",
-     url: "http://services.opengeoserver.org/tiles/1.0.0/globe.aerial_EPSG3857/{z}/{x}/{y}.png?origin=nw",
-     copyright: 'Tiles by <a href="http://www.opengeoserver.org/">OpenGeoServer.org</a>, <a href="https://creativecommons.org/licenses/by/3.0/at/">CC-BY 3.0 AT</a>.'},
-  google_map:
-    {name: "Google Maps",
-     url: " http://mt1.google.com/vt/x={x}&y={y}&z={z}",
-     copyright: 'Map data and imagery &copy; <a href="http://maps.google.com/">Google</a>'},
+  osm_hot:
+    {name: "OSM HOT style",
+     url: "https://tilecache[1-4].kairo.at/osmhot/{z}/{x}/{y}.png", // route through CORS+SSL tilecache @ kairo.at
+     //url: "http://[a-c].tile.openstreetmap.fr/hot/{z}/{x}/{y}.png", // https has CAcert which doesn't work in browsers
+     copyright: 'Map data and imagery &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>'},
+  hikebike:
+    {name: "Hike and Bike (OSM)",
+     url: "https://tilecache[1-4].kairo.at/hikebike/{z}/{x}/{y}.png", // route through CORS+SSL tilecache @ kairo.at
+     //url: "http://toolserver.org/tiles/hikebike/{z}/{x}/{y}.png", // toolserver.org does not support CORS at this time :(
+     copyright: 'Map data and imagery &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>'},
+  outdoors:
+    {name: "Outdoors (OSM)",
+     url: "https://[a-c].tile.thunderforest.com/outdoors/{z}/{x}/{y}.png", // url: "http://[a-c].tile.opencyclemap.org/outdoors/{z}/{x}/{y}.png",
+     copyright: 'Map data &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> and contributors (<a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>), tiles by <a href="http://www.thunderforest.com/">Thunderforest</a>.'},
+  stamen_toner:
+    {name: "Stamen Toner (B+W)",
+     url: "https://tilecache[1-4].kairo.at/toner/{z}/{x}/{y}.png", // route through CORS+SSL tilecache @ kairo.at
+     //url: "http://[a-c].tile.stamen.com/toner/{z}/{x}/{y}.jpg", // https has wrong cert, .ssl.fastly.net instead of .tile.stamen.com
+     copyright: 'Map data &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>, tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>.'},
+  stamen_terrain:
+    {name: "Stamen Terrain (USA only)",
+     url: "https://tilecache[1-4].kairo.at/terrain/{z}/{x}/{y}.png", // route through CORS+SSL tilecache @ kairo.at
+     //url: "http://[a-c].tile.stamen.com/terrain/{z}/{x}/{y}.jpg", // https has wrong cert, .ssl.fastly.net instead of .tile.stamen.com
+     copyright: 'Map data &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>, tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>.'},
+  stamen_watercolor:
+    {name: "Stamen Watercolor (artistic)",
+     url: "https://tilecache[1-4].kairo.at/watercolor/{z}/{x}/{y}.png", // route through CORS+SSL tilecache @ kairo.at
+     //url: "http://[a-c].tile.stamen.com/watercolor/{z}/{x}/{y}.jpg", // https has wrong cert, .ssl.fastly.net instead of .tile.stamen.com
+     copyright: 'Map data &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://www.openstreetmap.org/copyright">ODbL/CC-BY-SA</a>, tiles by <a href="http://stamen.com">Stamen Design</a>, under <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a>.'},
 };
 
 var gLastMouseX = 0;
@@ -54,7 +88,7 @@ var gMapPrefsLoaded = false;
 var gDragging = false;
 var gDragTouchID, gPinchStartWidth;
 
-var gGeoWatchID;
+var gGeoWatchID, gGPSWakeLock;
 var gTrack = [];
 var gLastTrackPoint, gLastDrawnPoint;
 var gCenterPosition = true;
@@ -87,8 +121,6 @@ function initMap() {
   }
   gTrackCanvas = document.getElementById("track");
   gTrackContext = gTrackCanvas.getContext("2d");
-  if (!gMap.activeMap)
-    gMap.activeMap = "osm_mapnik";
 
   //gDebug = true;
   if (gDebug) {
@@ -132,8 +164,6 @@ function loadPrefs(aEvent) {
       document.addEventListener("visibilitychange", visibilityEvHandler, false);
 
       console.log("Events added.");
-      document.getElementById("copyright").innerHTML =
-          gMapStyles[gMap.activeMap].copyright;
 
       console.log("Init loading tile...");
       gLoadingTile = new Image();
@@ -151,6 +181,21 @@ function loadPrefs(aEvent) {
       gAction.removeEventListener(aEvent.type, loadPrefs, false);
     gAction.addEventListener("prefs-step", loadPrefs, false);
     gWaitCounter++;
+    gPrefs.get("active_map_style", function(aValue) {
+      if (aValue && gMapStyles[aValue]) {
+        gMap.activeMap = aValue;
+      }
+      else {
+        gMap.activeMap = "osm_mapnik";
+      }
+      document.getElementById("mapSelector").value = gMap.activeMap;
+      document.getElementById("copyright").innerHTML =
+          gMapStyles[gMap.activeMap].copyright;
+      gWaitCounter--;
+      var throwEv = new CustomEvent("prefs-step");
+      gAction.dispatchEvent(throwEv);
+    });
+    gWaitCounter++;
     gPrefs.get("position", function(aValue) {
       if (aValue && aValue.x && aValue.y && aValue.z) {
         gMap.pos = aValue;
@@ -161,10 +206,12 @@ function loadPrefs(aEvent) {
     });
     gWaitCounter++;
     gPrefs.get("center_map", function(aValue) {
-      if (aValue === undefined)
+      if (aValue === undefined) {
         document.getElementById("centerCheckbox").checked = true;
-      else
+      }
+      else {
         document.getElementById("centerCheckbox").checked = aValue;
+      }
       setCentering(document.getElementById("centerCheckbox"));
       gWaitCounter--;
       var throwEv = new CustomEvent("prefs-step");
@@ -172,10 +219,12 @@ function loadPrefs(aEvent) {
     });
     gWaitCounter++;
     gPrefs.get("tracking_enabled", function(aValue) {
-      if (aValue === undefined)
+      if (aValue === undefined) {
         document.getElementById("trackCheckbox").checked = true;
-      else
+      }
+      else {
         document.getElementById("trackCheckbox").checked = aValue;
+      }
       gWaitCounter--;
       var throwEv = new CustomEvent("prefs-step");
       gAction.dispatchEvent(throwEv);
@@ -533,7 +582,7 @@ var gMap = {
           }
         }
       }
-      console.log("Cleaning complete, " + Object.keys(gMap.glTextures).length + " textures left)");
+      console.log("Cleaning complete, " + Object.keys(gMap.glTextures).length + " textures left");
     }
   },
 
@@ -598,10 +647,13 @@ function setMapStyle() {
   var mapSel = document.getElementById("mapSelector");
   if (mapSel.selectedIndex >= 0 && gMap.activeMap != mapSel.value) {
     gMap.activeMap = mapSel.value;
+    gPrefs.set("active_map_style", gMap.activeMap);
     document.getElementById("copyright").innerHTML =
         gMapStyles[gMap.activeMap].copyright;
-    showUI();
-    gMap.draw();
+    if (!gWaitCounter) { // Only do this when prefs are loaded already.
+      showUI();
+      gMap.draw();
+    }
   }
 }
 
@@ -809,12 +861,12 @@ var mapEvHandler = {
 
       // Bail out if the started touch can't be found.
       if (touchEvent && gDragging &&
-          !aEvent.changedTouches.identifiedTouch(gDragTouchID))
+          !aEvent.targetTouches.item(0))
         return;
     }
 
     var coordObj = touchEvent ?
-                   aEvent.changedTouches.identifiedTouch(gDragTouchID) :
+                   aEvent.targetTouches.item(0) :
                    aEvent;
 
     switch (aEvent.type) {
@@ -829,8 +881,7 @@ var mapEvHandler = {
                          aEvent.targetTouches.item(0).clientY, 2)
             );
           }
-          gDragTouchID = aEvent.changedTouches.item(0).identifier;
-          coordObj = aEvent.changedTouches.identifiedTouch(gDragTouchID);
+          coordObj = aEvent.targetTouches.item(0);
         }
         var x = coordObj.clientX - gGLMapCanvas.offsetLeft;
         var y = coordObj.clientY - gGLMapCanvas.offsetTop;
@@ -1080,6 +1131,9 @@ function startTracking() {
   if (gGeolocation) {
     gActionLabel.textContent = "Establishing Position";
     gAction.style.display = "block";
+    if (navigator.requestWakeLock) {
+      gGPSWakeLock = navigator.requestWakeLock("gps");
+    }
     gGeoWatchID = gGeolocation.watchPosition(
       function(position) {
         if (gActionLabel.textContent) {
@@ -1135,6 +1189,10 @@ function endTracking() {
     gActionLabel.textContent = "";
     gAction.style.display = "none";
   }
+  if (navigator.requestWakeLock && gGPSWakeLock) {
+    console.log("releasing WakeLock");
+    gGPSWakeLock.unlock();
+  }
   if (gGeoWatchID) {
     gGeolocation.clearWatch(gGeoWatchID);
   }
@@ -1173,6 +1231,7 @@ var gTileService = {
                   .replace("{y}", norm.y)
                   .replace("{z}", norm.z)
                   .replace("[a-c]", String.fromCharCode(97 + Math.floor(Math.random() * 3)))
+                  .replace("[a-d]", String.fromCharCode(97 + Math.floor(Math.random() * 4)))
                   .replace("[1-4]", 1 + Math.floor(Math.random() * 4)),
                 true);
       XHR.responseType = "blob";
@@ -1246,11 +1305,13 @@ var gTileService = {
     var request = transaction.objectStore(this.objStore).clear();
     request.onsuccess = function(event) {
       success = true;
+      console.log("Cache cleared.");
       if (aCallback)
         aCallback(success, event);
     };
     request.onerror = function(event) {
       // Errors can be handled here.
+      console.log("Error clearing cache!");
       if (aCallback)
         aCallback(success, event);
     }