add zooming and map style selection
authorRobert Kaiser <kairo@kairo.at>
Sun, 18 Dec 2011 16:47:14 +0000 (17:47 +0100)
committerRobert Kaiser <kairo@kairo.at>
Sun, 18 Dec 2011 16:47:14 +0000 (17:47 +0100)
index.html
js/map.js
js/ui.js
style/lantea.css

index 5b4cfe6..65ec071 100644 (file)
 <html manifest="manifest.appcache">
 <head>
   <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
-  <title>Lantea</title>
+  <title>Lantea Map</title>
   <script src="js/map.js"></script>
   <script src="js/ui.js"></script>
   <link rel="stylesheet" href="style/lantea.css">
 </head>
 <body>
-<h1>Lantea</h1>
+<h1>Lantea Map</h1>
+
+<div id="overlayArea">
+<input type="button" id="zoomInButton" value="+"
+       onclick="zoomIn();">
+<input type="button" id="zoomOutButton" value="-"
+       onclick="zoomOut();"><br/>
+<input type="button" id="settingsButton" value="Settings"
+       onclick="toggleSettings();">
+<fieldset id="settings"><legend>Settings</legend>
+Map style:
+<select id="mapSelector" onclick="setMapStyle();">
+<!-- option value="osm_mapnik">OpenStreetMap (Mapnik)</option -->
+</select>
+</fieldset>
+</div>
 
 <canvas id="map" width="500" height="500">
   Please use a browser that supports &lt;canvas&gt; elements.
 </canvas>
 
-<p id="copyright">Maps &copy;
-<a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors,
-<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a></p>
+<p id="copyright"></p>
 
 </body>
 </html>
\ No newline at end of file
index 2a65f78..869ce2c 100644 (file)
--- a/js/map.js
+++ b/js/map.js
@@ -40,7 +40,22 @@ var gCanvas, gContext;
 var gTileSize = 256;
 var gMaxZoom = 18; // The minimum is 0.
 
-//drawMap();
+var gMapStyles = {
+  // OSM tile usage policy: http://wiki.openstreetmap.org/wiki/Tile_usage_policy
+  osm_mapnik:
+    {name: "OpenStreetMap (Mapnik)",
+     url: "http://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://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'},
+  osm_tilesathome:
+    {name: "OpenStreetMap (OSMarender)",
+     url: "http://tah.openstreetmap.org/Tiles/tile/{z}/{x}/{y}.png",
+     copyright: 'Map data and imagery &copy; <a href="http://www.openstreetmap.org/">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>'},
+  mapquest_open:
+    {name: "MapQuest Open",
+     url: "http://otile1.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png",
+     copyright: 'Data, imagery and map information provided by MapQuest, <a href="http://www.openstreetmap.org/">OpenStreetMap</a> and contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>.'}
+};
+var gActiveMap = "osm_mapnik";
 
 var gPos = {x: 35630000.0, // Current position in the map in pixels at the maximum zoom level (18)
             y: 23670000.0, // The range is 0-67108864 (2^gMaxZoom * gTileSize)
@@ -55,9 +70,11 @@ var gTiles = {};
 var gDragging = false;
 var gZoomTouchID;
 
-window.onload = function() {
+function initMap() {
   gCanvas = document.getElementById("map");
   gContext = gCanvas.getContext("2d");
+  if (!gActiveMap)
+    gActiveMap = "osm_mapnik";
 
   gCanvas.addEventListener("mouseup", mapEvHandler, false);
   gCanvas.addEventListener("mousemove", mapEvHandler, false);
@@ -73,11 +90,8 @@ window.onload = function() {
   gCanvas.addEventListener("DOMMouseScroll", mapEvHandler, false);
   gCanvas.addEventListener("mousewheel", mapEvHandler, false);
 
-  resizeAndDraw();
-}
-
-window.onresize = function() {
-  resizeAndDraw();
+  document.getElementById("copyright").innerHTML =
+      gMapStyles[gActiveMap].copyright;
 }
 
 function resizeAndDraw() {
@@ -85,7 +99,7 @@ function resizeAndDraw() {
   var viewportHeight = window.innerHeight;
 
   var canvasWidth = viewportWidth * 0.98;
-  var canvasHeight = (viewportHeight-110) * 0.98;
+  var canvasHeight = (viewportHeight - 100) * 0.98;
   gCanvas.style.position = "fixed";
   gCanvas.width = canvasWidth;
   gCanvas.height = canvasHeight;
@@ -106,6 +120,15 @@ function zoomOut() {
   }
 }
 
+function setMapStyle() {
+  var mapSel = document.getElementById("mapSelector");
+  if (mapSel.selectedIndex >= 0 && gActiveMap != mapSel.value) {
+    gActiveMap = mapSel.value;
+    gTiles = {};
+    drawMap();
+  }
+}
+
 // A sane mod function that works for negative numbers.
 // Returns a % b.
 function mod(a, b) {
@@ -120,8 +143,9 @@ function normaliseIndices(x, y, z) {
 
 function tileURL(x, y, z) {
   var norm = normaliseIndices(x, y, z);
-  var url = "http://tile.openstreetmap.org/" + norm.z + "/" + norm.x + "/" + norm.y + ".png";
-  return url;
+  return gMapStyles[gActiveMap].url.replace("{x}", norm.x)
+                                   .replace("{y}", norm.y)
+                                   .replace("{z}", norm.z);
 }
 
 // Returns true if the tile is outside the current view.
@@ -162,7 +186,7 @@ function drawMap() {
   var z = Math.round(gPos.z);
   var wid = gCanvas.width * Math.pow(2, gMaxZoom - z); // Width in level 18 pixels.
   var ht = gCanvas.height * Math.pow(2, gMaxZoom - z); // Height in level 18 pixels.
-  var sz = gTileSize * Math.pow(2, gMaxZoom - z); // Tile size in level 18 pixels.
+  var size = gTileSize * Math.pow(2, gMaxZoom - z); // Tile size in level 18 pixels.
 
   var xMin = gPos.x - wid / 2; // Corners of the window in level 18 pixels.
   var yMin = gPos.y - ht / 2;
@@ -170,10 +194,10 @@ function drawMap() {
   var yMax = gPos.y + ht / 2;
 
   // Go through all the tiles we want. If any of them aren't loaded or being loaded, do so.
-  for (var x = Math.floor(xMin / sz); x < Math.ceil(xMax / sz); ++x) {
-    for (var y = Math.floor(yMin / sz); y < Math.ceil(yMax / sz); ++y) {
-      var xoff = (x * sz - xMin) / Math.pow(2, gMaxZoom - z);
-      var yoff = (y * sz - yMin) / Math.pow(2, gMaxZoom - z);
+  for (var x = Math.floor(xMin / size); x < Math.ceil(xMax / size); x++) {
+    for (var y = Math.floor(yMin / size); y < Math.ceil(yMax / size); y++) {
+      var xoff = (x * size - xMin) / Math.pow(2, gMaxZoom - z);
+      var yoff = (y * size - yMin) / Math.pow(2, gMaxZoom - z);
       var tileKey = encodeIndex(x, y, z);
       if (gTiles[tileKey] && gTiles[tileKey].complete) {
         // Round here is **CRUICIAL** otherwise the images are filtered and the performance sucks (more than expected).
index 74ea521..f82dddb 100644 (file)
--- a/js/ui.js
+++ b/js/ui.js
  *
  * ***** END LICENSE BLOCK ***** */
 
+window.onload = function() {
+  var mSel = document.getElementById("mapSelector");
+  for (var mapStyle in gMapStyles) {
+    var opt = document.createElement("option");
+    opt.value = mapStyle;
+    opt.text = gMapStyles[mapStyle].name;
+    mSel.add(opt, null);
+  }
 
+  initMap();
+  resizeAndDraw();
+}
+
+window.onresize = function() {
+  resizeAndDraw();
+}
+
+function toggleSettings() {
+  var fs = document.getElementById("settings");
+  if (fs.style.display != "block") {
+    fs.style.display = "block";
+  }
+  else {
+    fs.style.display = "none";
+  }
+}
index 47af3ca..d39eed6 100644 (file)
 
 body {
   font-family: sans-serif;
+  margin: 0;
+}
+
+h1 {
+  display: none;
+}
+
+#overlayArea {
+  position: absolute;
+  /* width: 30em; */
+  left: 1%;
+  top: 1em;
+  z-index: 5;
+}
+
+#settings {
+  display: none;
+  background-color: rgba(255, 255, 255, .8);
+  border: 0;
+  border-radius: 5px;
+}
+
+#settings > legend {
+  display: none;
+  background-color: rgba(255, 255, 255, .8);
+  border-radius: 3px;
+}
+
+#map {
+  border: 0;
+  top: 1em;
+  left: 1%;
+  right: 1%;
+  z-index: 1;
 }
 
 #copyright {