[OpenLayers-Commits] r5646 - in sandbox/tschaub/fractional: examples lib/OpenLayers

commits at openlayers.org commits at openlayers.org
Thu Jan 3 06:15:19 EST 2008


Author: tschaub
Date: 2008-01-03 06:15:19 -0500 (Thu, 03 Jan 2008)
New Revision: 5646

Added:
   sandbox/tschaub/fractional/examples/fractional-zoom.html
Modified:
   sandbox/tschaub/fractional/lib/OpenLayers/Layer.js
   sandbox/tschaub/fractional/lib/OpenLayers/Map.js
Log:
Allow for zooming to an arbitrary resolution.

Added: sandbox/tschaub/fractional/examples/fractional-zoom.html
===================================================================
--- sandbox/tschaub/fractional/examples/fractional-zoom.html	                        (rev 0)
+++ sandbox/tschaub/fractional/examples/fractional-zoom.html	2008-01-03 11:15:19 UTC (rev 5646)
@@ -0,0 +1,86 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <style type="text/css">
+        #map {
+            width: 512px;
+            height: 256px;
+            border: 1px solid gray;
+        }
+    </style>
+    <script src="../lib/OpenLayers.js"></script>
+    <script type="text/javascript">
+        var lon = 5;
+        var lat = 40;
+        var zoom = 5;
+        var map;
+
+        function init() {
+            var bounds = new OpenLayers.Bounds(-18.4, 28.3, -17.3, 29.0);
+            var options = {
+                maxExtent: bounds
+            };
+            map = new OpenLayers.Map('map', options);
+            var base = new OpenLayers.Layer.WMS(
+                "Bathymetry",
+                "http://213.172.37.189/scripts/mapserver/mapserv.exe?MAP=C%3A%2Finetpub%2Fwwwroot%2FCabildo%2Fwms_cabildo_vegetacion.map",
+                {layers: "BATIMETRIA"},
+                {resolutions: [0.004, 0.002, 0.001, 0.0005, 0.00025]}
+            );
+            var layer = new OpenLayers.Layer.WMS(
+                "Vegetation",
+                "http://213.172.37.189/scripts/mapserver/mapserv.exe?MAP=C%3A%2Finetpub%2Fwwwroot%2FCabildo%2Fwms_cabildo_vegetacion.map",
+                {
+                    layers: "VEGETACION",
+                    transparent: "TRUE",
+                    format: "image/png"
+                }, {
+                    isBaseLayer: false,
+                    resolutions: [0.004, 0.003, 0.001, 0.0005, 0.00025]
+                }
+            );
+            map.addLayers([base, layer]);
+
+            map.events.register("moveend", null, displayZoom);
+            map.addControl( new OpenLayers.Control.LayerSwitcher() );
+            map.setCenter(bounds.getCenterLonLat(), 1);
+            
+            update(document.getElementById("fractional"));
+            
+        }
+        
+        function displayZoom() {
+            document.getElementById("zoom").innerHTML = map.zoom.toFixed(4);
+        }
+        
+        function update(input) {
+            map.fractionalZoom = input.checked;
+        }
+    </script>
+  </head>
+  <body onload="init()">
+	<h1 id="title">Fractional Zoom Example</h1>
+
+	<div id="tags">
+	</div>
+	<p id="shortdesc">
+            Shows the use of a map with fractional (or non-discrete) zoom levels.
+	</p>
+
+	<div id="map"></div>
+        <input type="checkbox" name="fractional"
+               id="fractional" checked="checked" onclick="update(this)" />
+        <label for="fractional">Fractional Zoom</label>
+        (zoom: <span id="zoom"></span>)
+        <br /><br />
+	<div id="docs">
+            Setting the map.fractionalZoom property to true allows zooming to
+            an arbitrary level (between the min and max resolutions).  This
+            can be demonstrated by shift-dragging a box to zoom to an arbitrary
+            extent.
+	</div>
+  </body>
+</html>
+
+
+
+

Modified: sandbox/tschaub/fractional/lib/OpenLayers/Layer.js
===================================================================
--- sandbox/tschaub/fractional/lib/OpenLayers/Layer.js	2008-01-03 11:10:48 UTC (rev 5645)
+++ sandbox/tschaub/fractional/lib/OpenLayers/Layer.js	2008-01-03 11:15:19 UTC (rev 5646)
@@ -729,7 +729,7 @@
      */
     getResolution: function() {
         var zoom = this.map.getZoom();
-        return this.resolutions[zoom];
+        return this.getResolutionForZoom(zoom);
     },
 
     /** 
@@ -784,6 +784,29 @@
     },
 
     /**
+     * APIMethod: getResolutionForZoom
+     * 
+     * Parameter:
+     * zoom - {Float}
+     * 
+     * Returns:
+     * {Float} A suitable resolution for the specified zoom.
+     */
+    getResolutionForZoom: function(zoom) {
+        zoom = Math.max(0, Math.min(zoom, this.resolutions.length - 1));
+        var resolution;
+        if(this.map.fractionalZoom) {
+            var low = Math.floor(zoom);
+            var high = Math.ceil(zoom);
+            resolution = this.resolutions[high] +
+                ((zoom-low) * (this.resolutions[low]-this.resolutions[high]));
+        } else {
+            resolution = this.resolutions[Math.round(zoom)];
+        }
+        return resolution;
+    },
+
+    /**
      * APIMethod: getZoomForResolution
      * 
      * Parameters:
@@ -802,22 +825,50 @@
      *     value and the 'closest' specification.
      */
     getZoomForResolution: function(resolution, closest) {
-        var diff;
-        var minDiff = Number.POSITIVE_INFINITY;
-        for(var i=0; i < this.resolutions.length; i++) {            
-            if (closest) {
-                diff = Math.abs(this.resolutions[i] - resolution);
-                if (diff > minDiff) {
+        var zoom;
+        if(this.map.fractionalZoom) {
+            var lowZoom = 0;
+            var highZoom = this.resolutions.length - 1;
+            var highRes = this.resolutions[lowZoom];
+            var lowRes = this.resolutions[highZoom];
+            var res;
+            for(var i=0; i<this.resolutions.length; ++i) {
+                res = this.resolutions[i];
+                if(res >= resolution) {
+                    highRes = res;
+                    lowZoom = i;
+                }
+                if(res <= resolution) {
+                    lowRes = res;
+                    highZoom = i;
                     break;
                 }
-                minDiff = diff;
+            }
+            var dRes = highRes - lowRes;
+            if(dRes > 0) {
+                zoom = lowZoom + ((resolution - lowRes) / dRes);
             } else {
-                if (this.resolutions[i] < resolution) {
-                    break;
+                zoom = lowZoom;
+            }
+        } else {
+            var diff;
+            var minDiff = Number.POSITIVE_INFINITY;
+            for(var i=0; i < this.resolutions.length; i++) {            
+                if (closest) {
+                    diff = Math.abs(this.resolutions[i] - resolution);
+                    if (diff > minDiff) {
+                        break;
+                    }
+                    minDiff = diff;
+                } else {
+                    if (this.resolutions[i] < resolution) {
+                        break;
+                    }
                 }
             }
+            zoom = Math.max(0, i-1);
         }
-        return Math.max(0, i-1);
+        return zoom;
     },
     
     /**

Modified: sandbox/tschaub/fractional/lib/OpenLayers/Map.js
===================================================================
--- sandbox/tschaub/fractional/lib/OpenLayers/Map.js	2008-01-03 11:10:48 UTC (rev 5645)
+++ sandbox/tschaub/fractional/lib/OpenLayers/Map.js	2008-01-03 11:15:19 UTC (rev 5646)
@@ -42,6 +42,14 @@
     id: null,
     
     /**
+     * Property: fractionalZoom
+     * {Boolean} For a base layer that supports it, allow the map resolution
+     *     to be set to a value between one of the values in the resolutions
+     *     array.  Default is false.
+     */
+    fractionalZoom: false,
+    
+    /**
      * APIProperty: events
      * {<OpenLayers.Events>} An events object that handles all 
      *                       events on the map
@@ -1234,10 +1242,7 @@
             if(zoom == null) { 
                 zoom = this.getZoom(); 
             }
-            var resolution = null;
-            if(this.baseLayer != null) {
-                resolution = this.baseLayer.resolutions[zoom];
-            }
+            var resolution = this.getResolutionForZoom(zoom);
             var extent = this.calculateBounds(lonlat, resolution); 
             if(!this.restrictedExtent.containsBounds(extent)) {
                 var maxCenter = this.restrictedExtent.getCenterLonLat(); 
@@ -1294,7 +1299,7 @@
 
             if (zoomChanged) {
                 this.zoom = zoom;
-                this.resolution = this.baseLayer.getResolution();
+                this.resolution = this.getResolutionForZoom(zoom);
                 // zoom level has changed, increment viewRequestID.
                 this.viewRequestID++;
             }    
@@ -1567,6 +1572,28 @@
     },
 
     /**
+     * APIMethod: getResolutionForZoom
+     * 
+     * Parameter:
+     * zoom - {Float}
+     * 
+     * Returns:
+     * {Float} A suitable resolution for the specified zoom.  If no baselayer
+     *     is set, returns null.
+     */
+    getResolutionForZoom: function(zoom) {
+        var resolution = null;
+        if(this.baseLayer) {
+            if(this.baseLayer.getResolutionForZoom) {
+                resolution = this.baseLayer.getResolutionForZoom(zoom);
+            } else {
+                resolution = this.baseLayer.resolutions[Math.round(zoom)];
+            }
+        }
+        return resolution;
+    },
+
+    /**
      * APIMethod: getZoomForResolution
      * 
      * Parameter:



More information about the Commits mailing list