OpenLayers OpenLayers

Changeset 5982

Show
Ignore:
Timestamp:
02/04/08 01:23:54 (1 year ago)
Author:
tschaub
Message:

Adding fractionalZoom property to the map. This allows zooming to an arbitrary level, making it possible to have non-discrete resolutions for layers that support it. This property should not be set to true for layers with fixed zoom levels (commercial layers or others with cached tiles). r=elemoine,crschmidt,ahocevar (closes #1243)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/openlayers/lib/OpenLayers/Control/Navigation.js

    r5891 r5982  
    138138        var deltaX  = size.w/2 - evt.xy.x; 
    139139        var deltaY  = evt.xy.y - size.h/2; 
    140         var newRes  = this.map.baseLayer.resolutions[newZoom]
     140        var newRes  = this.map.baseLayer.getResolutionForZoom(newZoom)
    141141        var zoomPoint = this.map.getLonLatFromPixel(evt.xy); 
    142142        var newCenter = new OpenLayers.LonLat( 
  • trunk/openlayers/lib/OpenLayers/Layer.js

    r5918 r5982  
    759759    getResolution: function() { 
    760760        var zoom = this.map.getZoom(); 
    761         return this.resolutions[zoom]
     761        return this.getResolutionForZoom(zoom)
    762762    }, 
    763763 
     
    814814 
    815815    /** 
     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    /** 
    816839     * APIMethod: getZoomForResolution 
    817840     *  
     
    832855     */ 
    833856    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; 
    840873                    break; 
    841874                } 
    842                 minDiff = diff; 
     875            } 
     876            var dRes = highRes - lowRes; 
     877            if(dRes > 0) { 
     878                zoom = lowZoom + ((resolution - lowRes) / dRes); 
    843879            } 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                    } 
    846896                } 
    847897            } 
    848         } 
    849         return Math.max(0, i-1); 
     898            zoom = Math.max(0, i-1); 
     899        } 
     900        return zoom; 
    850901    }, 
    851902     
  • trunk/openlayers/lib/OpenLayers/Map.js

    r5973 r5982  
    6666     */ 
    6767    id: null, 
     68     
     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, 
    6876     
    6977    /** 
     
    12671275                zoom = this.getZoom();  
    12681276            } 
    1269             var resolution = null; 
    1270             if(this.baseLayer != null) { 
    1271                 resolution = this.baseLayer.resolutions[zoom]; 
    1272             } 
     1277            var resolution = this.getResolutionForZoom(zoom); 
    12731278            var extent = this.calculateBounds(lonlat, resolution);  
    12741279            if(!this.restrictedExtent.containsBounds(extent)) { 
     
    13271332            if (zoomChanged) { 
    13281333                this.zoom = zoom; 
    1329                 this.resolution = this.baseLayer.getResolution(); 
     1334                this.resolution = this.getResolutionForZoom(zoom); 
    13301335                // zoom level has changed, increment viewRequestID. 
    13311336                this.viewRequestID++; 
     
    15961601 
    15971602    /** 
     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    /** 
    15981621     * APIMethod: getZoomForResolution 
    15991622     *  
  • trunk/openlayers/tests/test_Layer.html

    r5918 r5982  
    177177    function test_06_Layer_getZoomForResolution(t) { 
    178178 
    179         t.plan(8); 
     179        t.plan(12); 
    180180 
    181181        var layer = new OpenLayers.Layer('Test Layer'); 
    182              
     182        layer.map = {}; 
     183         
    183184        //make some dummy resolutions 
    184185        layer.resolutions = [128, 64, 32, 16, 8, 4, 2]; 
     
    194195        t.eq(layer.getZoomForResolution(65, true), 1, "closest res"); 
    195196        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"); 
    196207 
    197208    } 
     
    302313        t.ok(layer.imageSize.equals(desiredImageSize), "image size correctly calculated"); 
    303314    } 
     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    } 
    304350 
    305351 
  • trunk/openlayers/tests/test_Map.html

    r5505 r5982  
    959959             "map extent not restricted with null restrictedExtent for se"); 
    960960    } 
     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    } 
    961977 
    962978    function test_99_Map_destroy (t) {