Ticket #1243: fractional.patch
| File fractional.patch, 12.2 kB (added by tschaub, 1 year ago) |
|---|
-
tests/test_Map.html
old new 958 958 se.toString(), 959 959 "map extent not restricted with null restrictedExtent for se"); 960 960 } 961 962 function test_Map_getResolutionForZoom(t) { 963 t.plan(2); 964 var map = new OpenLayers.Map("map"); 965 var res = map.getResolutionForZoom(); 966 t.eq(res, null, "getResolutionForZoom returns null for no base layer"); 967 map.fractionalZoom = true; 968 var layer = new OpenLayers.Layer("test", {isBaseLayer: true}); 969 layer.getResolutionForZoom = function() { 970 t.ok(true, "getResolutionForZoom calls base layer getResolutionForZoom"); 971 } 972 map.addLayer(layer); 973 var res = map.getResolutionForZoom(); 974 layer.destroy(); 975 map.destroy(); 976 } 961 977 962 978 function test_99_Map_destroy (t) { 963 979 t.plan( 3 ); -
tests/test_Layer.html
old new 176 176 177 177 function test_06_Layer_getZoomForResolution(t) { 178 178 179 t.plan( 8);179 t.plan(12); 180 180 181 181 var layer = new OpenLayers.Layer('Test Layer'); 182 182 layer.map = {}; 183 183 184 //make some dummy resolutions 184 185 layer.resolutions = [128, 64, 32, 16, 8, 4, 2]; 185 186 … … 193 194 194 195 t.eq(layer.getZoomForResolution(65, true), 1, "closest res"); 195 196 t.eq(layer.getZoomForResolution(63, true), 1, "closest res"); 197 198 layer.map.fractionalZoom = true; 199 t.eq(layer.getZoomForResolution(64), 1, 200 "(fractionalZoom) correct zoom for res in array"); 201 t.eq(layer.getZoomForResolution(48).toPrecision(6), (1.5).toPrecision(6), 202 "(fractionalZoom) linear scaling for res between entries"); 203 t.eq(layer.getZoomForResolution(200).toPrecision(6), (0).toPrecision(6), 204 "(fractionalZoom) doesn't return zoom below zero"); 205 t.eq(layer.getZoomForResolution(1).toPrecision(6), (layer.resolutions.length - 1).toPrecision(6), 206 "(fractionalZoom) doesn't return zoom above highest index"); 196 207 197 208 } 198 209 … … 301 312 t.ok(layer.imageOffset.equals(desiredImageOffset), "image offset correctly calculated"); 302 313 t.ok(layer.imageSize.equals(desiredImageSize), "image size correctly calculated"); 303 314 } 315 316 function test_Layer_getResolution(t) { 317 t.plan(1); 318 var layer = new OpenLayers.Layer("test"); 319 layer.map = { 320 getZoom: function() {return "foo";} 321 }; 322 layer.getResolutionForZoom = function(zoom) { 323 t.eq(zoom, "foo", "getResolution calls getResolutionForZoom"); 324 } 325 layer.getResolution(); 326 layer.map = null; 327 layer.destroy(); 328 } 329 330 function test_Layer_getResolutionForZoom(t) { 331 t.plan(5); 332 var layer = new OpenLayers.Layer("test"); 333 layer.map = {fractionalZoom: false}; 334 layer.resolutions = ["zero", "one", "two"]; 335 t.eq(layer.getResolutionForZoom(0), "zero", 336 "(fractionalZoom false) returns resolution for given index"); 337 t.eq(layer.getResolutionForZoom(0.9), "one", 338 "(fractionalZoom false) returns resolution for float index"); 339 340 layer.resolutions = [2, 4, 6, 8]; 341 layer.map.fractionalZoom = true; 342 t.eq(layer.getResolutionForZoom(1).toPrecision(6), (4).toPrecision(6), 343 "(fractionalZoom true) returns resolution for integer zoom"); 344 t.eq(layer.getResolutionForZoom(1.5).toPrecision(6), (5).toPrecision(6), 345 "(fractionalZoom true) returns resolution for float zoom"); 346 t.eq(layer.getResolutionForZoom(3.5).toPrecision(6), (8).toPrecision(6), 347 "(fractionalZoom true) returns resolution for zoom beyond res length - 1"); 348 349 } 304 350 305 351 306 352 -
lib/OpenLayers/Map.js
old new 67 67 id: null, 68 68 69 69 /** 70 * Property: fractionalZoom 71 * {Boolean} For a base layer that supports it, allow the map resolution 72 * to be set to a value between one of the values in the resolutions 73 * array. Default is false. 74 */ 75 fractionalZoom: false, 76 77 /** 70 78 * APIProperty: events 71 79 * {<OpenLayers.Events>} An events object that handles all 72 80 * events on the map … … 1266 1274 if(zoom == null) { 1267 1275 zoom = this.getZoom(); 1268 1276 } 1269 var resolution = null; 1270 if(this.baseLayer != null) { 1271 resolution = this.baseLayer.resolutions[zoom]; 1272 } 1277 var resolution = this.getResolutionForZoom(zoom); 1273 1278 var extent = this.calculateBounds(lonlat, resolution); 1274 1279 if(!this.restrictedExtent.containsBounds(extent)) { 1275 1280 var maxCenter = this.restrictedExtent.getCenterLonLat(); … … 1326 1331 1327 1332 if (zoomChanged) { 1328 1333 this.zoom = zoom; 1329 this.resolution = this. baseLayer.getResolution();1334 this.resolution = this.getResolutionForZoom(zoom); 1330 1335 // zoom level has changed, increment viewRequestID. 1331 1336 this.viewRequestID++; 1332 1337 } … … 1595 1600 }, 1596 1601 1597 1602 /** 1603 * APIMethod: getResolutionForZoom 1604 * 1605 * Parameter: 1606 * zoom - {Float} 1607 * 1608 * Returns: 1609 * {Float} A suitable resolution for the specified zoom. If no baselayer 1610 * is set, returns null. 1611 */ 1612 getResolutionForZoom: function(zoom) { 1613 var resolution = null; 1614 if(this.baseLayer) { 1615 resolution = this.baseLayer.getResolutionForZoom(zoom); 1616 } 1617 return resolution; 1618 }, 1619 1620 /** 1598 1621 * APIMethod: getZoomForResolution 1599 1622 * 1600 1623 * Parameter: -
lib/OpenLayers/Control/Navigation.js
old new 137 137 var size = this.map.getSize(); 138 138 var deltaX = size.w/2 - evt.xy.x; 139 139 var deltaY = evt.xy.y - size.h/2; 140 var newRes = this.map.baseLayer. resolutions[newZoom];140 var newRes = this.map.baseLayer.getResolutionForZoom(newZoom); 141 141 var zoomPoint = this.map.getLonLatFromPixel(evt.xy); 142 142 var newCenter = new OpenLayers.LonLat( 143 143 zoomPoint.lon + deltaX * newRes, -
lib/OpenLayers/Layer.js
old new 758 758 */ 759 759 getResolution: function() { 760 760 var zoom = this.map.getZoom(); 761 return this. resolutions[zoom];761 return this.getResolutionForZoom(zoom); 762 762 }, 763 763 764 764 /** … … 813 813 }, 814 814 815 815 /** 816 * APIMethod: getResolutionForZoom 817 * 818 * Parameter: 819 * zoom - {Float} 820 * 821 * Returns: 822 * {Float} A suitable resolution for the specified zoom. 823 */ 824 getResolutionForZoom: function(zoom) { 825 zoom = Math.max(0, Math.min(zoom, this.resolutions.length - 1)); 826 var resolution; 827 if(this.map.fractionalZoom) { 828 var low = Math.floor(zoom); 829 var high = Math.ceil(zoom); 830 resolution = this.resolutions[high] + 831 ((zoom-low) * (this.resolutions[low]-this.resolutions[high])); 832 } else { 833 resolution = this.resolutions[Math.round(zoom)]; 834 } 835 return resolution; 836 }, 837 838 /** 816 839 * APIMethod: getZoomForResolution 817 840 * 818 841 * Parameters: … … 831 854 * value and the 'closest' specification. 832 855 */ 833 856 getZoomForResolution: function(resolution, closest) { 834 var diff; 835 var minDiff = Number.POSITIVE_INFINITY; 836 for(var i=0; i < this.resolutions.length; i++) { 837 if (closest) { 838 diff = Math.abs(this.resolutions[i] - resolution); 839 if (diff > minDiff) { 857 var zoom; 858 if(this.map.fractionalZoom) { 859 var lowZoom = 0; 860 var highZoom = this.resolutions.length - 1; 861 var highRes = this.resolutions[lowZoom]; 862 var lowRes = this.resolutions[highZoom]; 863 var res; 864 for(var i=0; i<this.resolutions.length; ++i) { 865 res = this.resolutions[i]; 866 if(res >= resolution) { 867 highRes = res; 868 lowZoom = i; 869 } 870 if(res <= resolution) { 871 lowRes = res; 872 highZoom = i; 840 873 break; 841 874 } 842 minDiff = diff; 875 } 876 var dRes = highRes - lowRes; 877 if(dRes > 0) { 878 zoom = lowZoom + ((resolution - lowRes) / dRes); 843 879 } else { 844 if (this.resolutions[i] < resolution) { 845 break; 880 zoom = lowZoom; 881 } 882 } else { 883 var diff; 884 var minDiff = Number.POSITIVE_INFINITY; 885 for(var i=0; i < this.resolutions.length; i++) { 886 if (closest) { 887 diff = Math.abs(this.resolutions[i] - resolution); 888 if (diff > minDiff) { 889 break; 890 } 891 minDiff = diff; 892 } else { 893 if (this.resolutions[i] < resolution) { 894 break; 895 } 846 896 } 847 897 } 898 zoom = Math.max(0, i-1); 848 899 } 849 return Math.max(0, i-1);900 return zoom; 850 901 }, 851 902 852 903 /** -
examples/fractional-zoom.html
old new 1 <html xmlns="http://www.w3.org/1999/xhtml"> 2 <head> 3 <style type="text/css"> 4 #map { 5 width: 512px; 6 height: 256px; 7 border: 1px solid gray; 8 } 9 </style> 10 <script src="../lib/OpenLayers.js"></script> 11 <script type="text/javascript"> 12 var map; 13 14 function init() { 15 map = new OpenLayers.Map('map'); 16 var wms = new OpenLayers.Layer.WMS( 17 "OpenLayers WMS", 18 "http://labs.metacarta.com/wms/vmap0", 19 {layers: 'basic'} 20 ); 21 map.addLayers([wms]); 22 23 map.events.register("moveend", null, displayZoom); 24 map.addControl( new OpenLayers.Control.LayerSwitcher() ); 25 26 map.zoomToMaxExtent(); 27 28 update(document.getElementById("fractional")); 29 30 } 31 32 function displayZoom() { 33 document.getElementById("zoom").innerHTML = map.zoom.toFixed(4); 34 } 35 36 function update(input) { 37 map.fractionalZoom = input.checked; 38 } 39 </script> 40 </head> 41 <body onload="init()"> 42 <h1 id="title">Fractional Zoom Example</h1> 43 44 <div id="tags"> 45 </div> 46 <p id="shortdesc"> 47 Shows the use of a map with fractional (or non-discrete) zoom levels. 48 </p> 49 50 <div id="map"></div> 51 <input type="checkbox" name="fractional" 52 id="fractional" checked="checked" onclick="update(this)" /> 53 <label for="fractional">Fractional Zoom</label> 54 (zoom: <span id="zoom"></span>) 55 <br /><br /> 56 <div id="docs"> 57 <p> 58 Setting the map.fractionalZoom property to true allows zooming to 59 an arbitrary level (between the min and max resolutions). This 60 can be demonstrated by shift-dragging a box to zoom to an arbitrary 61 extent. 62 </p> 63 </div> 64 </body> 65 </html> 66 67 68 69
