OpenLayers OpenLayers

Ticket #442: animatedZooming_1.2.patch

File animatedZooming_1.2.patch, 25.1 kB (added by emanuel, 3 years ago)
  • demo.html

    old new  
     1<html xmlns="http://www.w3.org/1999/xhtml"> 
     2  <head> 
     3    <style type="text/css"> 
     4        #map { 
     5            width: 100%; 
     6            height: 100%; 
     7            border: 1px solid black; 
     8        } 
     9    </style> 
     10    <title>Animated Zooming Demo</title> 
     11    <script src="./lib/OpenLayers.js"></script> 
     12    <script type="text/javascript"> 
     13        <!-- 
     14        function init(){ 
     15            var map = new OpenLayers.Map('map', { controls: [] }); 
     16 
     17            map.addControl(new OpenLayers.Control.PanZoomBar()); 
     18            map.addControl(new OpenLayers.Control.MouseToolbar()); 
     19            map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':false})); 
     20            map.addControl(new OpenLayers.Control.MousePosition()); 
     21            map.addControl(new OpenLayers.Control.OverviewMap()); 
     22          
     23 
     24 
     25            var ol_wms = new OpenLayers.Layer.WMS( "OpenLayers WMS",  
     26                "http://labs.metacarta.com/wms/vmap0", 
     27                {layers: 'basic'} ); 
     28 
     29            var jpl_wms = new OpenLayers.Layer.WMS( "NASA Global Mosaic", 
     30                "http://wms.jpl.nasa.gov/wms.cgi",  
     31                {layers: "modis,global_mosaic"}); 
     32 
     33            var dm_wms = new OpenLayers.Layer.WMS( "DM Solutions Demo", 
     34                "http://www2.dmsolutions.ca/cgi-bin/mswms_gmap", 
     35                {layers: "bathymetry,land_fn,park,drain_fn,drainage," + 
     36                         "prov_bound,fedlimit,rail,road,popplace", 
     37                 transparent: "true", format: "image/png" }); 
     38 
     39            ol_wms.setVisibility(false); 
     40            jpl_wms.setVisibility(false); 
     41            dm_wms.setVisibility(false); 
     42 
     43            map.addLayers([ol_wms, jpl_wms, dm_wms]); 
     44 
     45            if (!map.getCenter()) //map.zoomTo(6); 
     46            map.zoomToMaxExtent(); 
     47        } 
     48        // --> 
     49    </script> 
     50  </head> 
     51  <body onload="init()"> 
     52    <div id="map"></div> 
     53    <div id="testlabel"></div> 
     54  </body> 
     55</html> 
  • demo_frida.html

    old new  
     1<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
     2        "http://www.w3.org/TR/2000/REC-xhtml1-20000126/DTD/xhtml1-strict.dtd"> 
     3<html xmlns="http://www.w3.org/1999/xhtml"> 
     4 
     5<head>   
     6  <style type="text/css"> 
     7      #map { 
     8          width: 512px; 
     9          height: 512px; 
     10          border: 1px solid black; 
     11      } 
     12  </style> 
     13  <title>Frida Demo - Free Vector-Geodata Osnabrueck, Germany</title> 
     14  <script src="./lib/OpenLayers.js"></script> 
     15  <script type="text/javascript"> 
     16  
     17  function init() { 
     18    var lon=0; 
     19    var lat=0; 
     20    var zoom=0; 
     21 
     22    var options = { 
     23      //maxScale: 1000, 
     24      //minScale: 1000000, 
     25      maxResolution: 10, 
     26      maxExtent: new OpenLayers.Bounds(7.92881, 52.2131, 8.18349, 52.341), 
     27      projection:"EPSG:4326", 
     28      //alternative: projection:"EPSG:31467" 
     29      controls: [new OpenLayers.Control.MouseDefaults()] 
     30    };  
     31    var map = new OpenLayers.Map('map',options); 
     32 
     33 
     34    //baselayer 
     35    var baselayer_wms = new OpenLayers.Layer.WMS( "Frida WMS",  
     36      "http://demo.intevation.org/cgi/frida-wms", { 
     37        layers: 'strassenall', 
     38        isBaseLayer: 'true', 
     39        format: 'image/png' } 
     40      ); 
     41     
     42    //green spaces 
     43    var greenspaces_wms = new OpenLayers.Layer.WMS( "green spaces",  
     44      "http://demo.intevation.org/cgi/frida-wms", { 
     45        layers: 'gruenflaechen', 
     46        isBaseLayer: "false",  
     47        transparent: "true",  
     48        format:'image/png'} 
     49      ); 
     50    greenspaces_wms.setVisibility(false); 
     51 
     52    //waters 
     53    var waters_wms = new OpenLayers.Layer.WMS( "waters",  
     54      "http://demo.intevation.org/cgi/frida-wms", { 
     55        layers: 'gewaesser', 
     56        isBaseLayer: "false",  
     57        transparent: "true",  
     58        format:'image/png'} 
     59      ); 
     60    waters_wms.setVisibility(false); 
     61     
     62    //streets 
     63    var streets_wms = new OpenLayers.Layer.WMS( "streets",  
     64      "http://demo.intevation.org/cgi/frida-wms", { 
     65        layers: 'strassenall', 
     66        isBaseLayer: "false",  
     67        transparent: "true",  
     68        format:'image/png'} 
     69      ); 
     70    streets_wms.setVisibility(false); 
     71 
     72    //poi 
     73    var poi_wms = new OpenLayers.Layer.WMS( "POI",  
     74      "http://demo.intevation.org/cgi/frida-wms", { 
     75        layers: 'sehenswuerdigkeiten', 
     76        isBaseLayer: "false",  
     77        transparent: "true",  
     78        format:'image/png'} 
     79      ); 
     80    poi_wms.setVisibility(false);         
     81     
     82 
     83    //add all layers 
     84    map.addLayers([baselayer_wms, greenspaces_wms, waters_wms,  poi_wms]); 
     85     
     86    //add controls 
     87    map.addControl(new OpenLayers.Control.PanZoomBar()); 
     88    map.addControl( new OpenLayers.Control.LayerSwitcher() ); 
     89    map.addControl(new OpenLayers.Control.MousePosition()); 
     90 
     91    //set center and zoomlevel 
     92    //map.setCenter(new OpenLayers.LonLat(lon, lat), zoom); 
     93    map.zoomToMaxExtent(); 
     94 
     95</script> 
     96</head> 
     97 
     98<body onload="init()"> 
     99    <div id="map"></div> 
     100    Free geodata powered by <a href="http://frida.intevation.de">Frida project</a> 
     101</body> 
     102 
     103</html> 
  • lib/OpenLayers/Control/OverviewMap.js

    old new  
    383383                (resRatio <= this.maxRatio) && 
    384384                (this.ovmap.getExtent().containsBounds(testExtent))); 
    385385    }, 
    386      
    387     updateOverview: function() { 
    388         var mapRes = this.map.getResolution(); 
     386 
     387    /*  
     388     * Updates the overview map. If the map is scaling (by zooming) the parameters 
     389     * define the values of the new resolution and bounds. 
     390     * 
     391     * @param {float} newResolution 
     392     * @param {OpenLayers.Bounds} bounds 
     393     */     
     394    updateOverview: function(newResolution, bounds) { 
     395        //set new map resolution only by scaling 
     396        if (newResolution) 
     397            var mapRes = newResolution; 
     398        else 
     399            var mapRes = this.map.getResolution(); 
    389400        var targetRes = this.ovmap.getResolution(); 
    390401        var resRatio = targetRes / mapRes; 
    391402        if(resRatio > this.maxRatio) { 
     
    397408        } 
    398409        this.ovmap.setCenter(this.map.center, 
    399410                            this.ovmap.getZoomForResolution(targetRes)); 
    400         this.updateRectToMap(); 
     411        this.updateRectToMap(bounds); 
    401412    }, 
    402413     
    403414    createMap: function() { 
     
    421432    }, 
    422433         
    423434    /** 
    424      * Updates the extent rectangle position and size to match the map extent 
     435     * Updates the extent rectangle position and size to match the map extent   
     436     * If the map is scaling (by zooming) the parameter defines the 
     437     * new bounds of the current map 
     438     * 
     439     * @param {OpenLayers.Bounds} bounds 
    425440     */ 
    426     updateRectToMap: function() { 
     441    updateRectToMap: function(bounds) { 
    427442        // The base layer for overview map needs to be in the same projection 
    428443        // as the base layer for the main map.  This should be made more robust. 
    429444        if(this.map.units != 'degrees') { 
     
    431446                alert('The overview map only works when it is in the same projection as the main map'); 
    432447            } 
    433448        } 
    434         var pxBounds = this.getRectBoundsFromMapBounds(this.map.getExtent()); 
     449 
     450        if (!bounds) 
     451            bounds=this.map.getExtent(); 
     452        var pxBounds = this.getRectBoundsFromMapBounds(bounds); 
    435453        this.setRectPxBounds(pxBounds); 
    436454    }, 
    437455     
  • lib/OpenLayers/Control/PanZoomBar.js

    old new  
    2323    /** @type int */ 
    2424    zoomStopHeight: 11, 
    2525 
     26    /** @type int */ 
     27    zoomlevel_startScale: null,   
     28     
     29    /** @type float */ 
     30    zoomlevel_scale: null,    
     31      
     32    /** @type OpenLayers.Size */ 
     33    tileSize_startScale: null,  
     34     
     35    /** @type OpenLayers.Size */ 
     36    tileSize_scale: null, 
     37  
     38    /** @type float */ 
     39    resolution_scale: null, 
     40 
    2641    initialize: function() { 
    2742        OpenLayers.Control.PanZoom.prototype.initialize.apply(this, arguments); 
    2843        this.position = new OpenLayers.Pixel(OpenLayers.Control.PanZoomBar.X, 
    2944                                             OpenLayers.Control.PanZoomBar.Y); 
     45        this.tileSize_scale = new OpenLayers.Size(); 
    3046    }, 
    3147 
    3248    /** 
     
    168184        this.zoomStart = evt.xy.clone(); 
    169185        this.div.style.cursor = "move"; 
    170186        OpenLayers.Event.stop(evt); 
     187 
     188        // only for WMS layer 
     189        if (this.map.baseLayer.CLASS_NAME == "OpenLayers.Layer.WMS") { 
     190            // get current zoomlevel 
     191            this.zoomlevel_startScale = this.map.zoom; 
     192 
     193            // get original tile size 
     194            this.tileSize_startScale = this.map.getTileSize(); 
     195 
     196            // find and set tile, which contains the center of the viewport 
     197            this.map.baseLayer.setCenterTile();        
     198 
     199            // set zoomOutTile visible   
     200            this.map.baseLayer.zoomOutTile.imgDiv.style.display = "block"; 
     201        } 
    171202    }, 
    172203     
    173204    /* 
     
    187218            } 
    188219            this.mouseDragStart = evt.xy.clone(); 
    189220            OpenLayers.Event.stop(evt); 
     221 
     222            // only for WMS layer 
     223            if (this.map.baseLayer.CLASS_NAME == "OpenLayers.Layer.WMS") { 
     224 
     225                // convert current sliderposition to new zoomlevel 
     226                var deltaY_zoomlevel = this.zoomStart.y - evt.xy.y 
     227                this.zoomlevel_scale=this.zoomlevel_startScale +  
     228                  deltaY_zoomlevel/this.zoomStopHeight; 
     229                
     230                // check the zoomlevel validity  
     231                if (this.zoomlevel_scale < 0) { 
     232                    this.zoomlevel_scale = 0;  
     233                }  
     234                if (this.zoomlevel_scale > (this.map.getNumZoomLevels()-1)) {  
     235                    this.zoomlevel_scale = this.map.getNumZoomLevels() - 1;  
     236                } 
     237                 
     238                // calculate the new tile size for the scale... 
     239                // ...zoomIn 
     240                if (this.zoomlevel_startScale < this.zoomlevel_scale) { 
     241                    this.tileSize_scale.w =  
     242                      Math.pow(2,(this.zoomlevel_scale - 
     243                      this.zoomlevel_startScale)) * this.tileSize_startScale.w; 
     244                    this.tileSize_scale.h =  
     245                      Math.pow(2,(this.zoomlevel_scale - 
     246                      this.zoomlevel_startScale)) * this.tileSize_startScale.h; 
     247 
     248                    // set new map resolution 
     249                    this.resolution_scale =  
     250                      1/(Math.pow(2,(this.zoomlevel_scale -  
     251                      this.zoomlevel_startScale))) *  this.map.getResolution();     
     252                } 
     253                // ...zoomOut / no zoom changes 
     254                if (this.zoomlevel_startScale >= this.zoomlevel_scale) {              
     255                    this.tileSize_scale.w = 
     256                      1/(Math.pow(2,(this.zoomlevel_startScale - 
     257                      this.zoomlevel_scale))) * this.tileSize_startScale.w; 
     258                    this.tileSize_scale.h = 
     259                      1/(Math.pow(2,(this.zoomlevel_startScale -  
     260                      this.zoomlevel_scale))) * this.tileSize_startScale.h; 
     261 
     262                    // set new map resolution 
     263                    this.resolution_scale =  
     264                      Math.pow(2,(this.zoomlevel_startScale -  
     265                      this.zoomlevel_scale)) * this.map.getResolution();  
     266                } 
     267 
     268 
     269                // scale all tiles to the new scaled size            
     270                this.map.baseLayer.scaleTileTo(this.tileSize_scale); 
     271                 
     272                // scale the zoomOut tile (to prevent a white frame during 
     273                // zoomOut) 
     274                this.map.baseLayer.scaleZoomOutTile(this.tileSize_scale, 
     275                                                    this.zoomlevel_scale,  
     276                                                    this.resolution_scale); 
     277 
     278                // set new scaled map resolution 
     279                this.map.setScaleResolution(this.resolution_scale); 
     280            } 
    190281        } 
    191282    }, 
    192283     
     
    206297            this.moveZoomBar(); 
    207298            this.mouseDragStart = null; 
    208299            OpenLayers.Event.stop(evt); 
     300     
     301            // only for WMS layer 
     302            if (this.map.baseLayer.CLASS_NAME == "OpenLayers.Layer.WMS") { 
     303                // set zoomOutTile invisible  
     304                this.map.baseLayer.zoomOutTile.imgDiv.style.display = "none"; 
     305            } 
    209306        } 
    210307    }, 
    211308     
  • lib/OpenLayers/Map.js

    old new  
    300300            if (this.baseLayer == null) { 
    301301                // set the first baselaye we add as the baselayer 
    302302                this.setBaseLayer(layer); 
     303 
     304                // only for WMS layer: preload a bigger tile for zooming out 
     305                if (layer.CLASS_NAME == "OpenLayers.Layer.WMS") { 
     306                    layer.setZoomOutTile(); 
     307                } 
     308               
    303309            } else { 
    304310                layer.setVisibility(false); 
    305311            } 
     
    708714            lonlat = this.maxExtent.getCenterLonLat(); 
    709715        } 
    710716         
    711         var zoomChanged = (this.isValidZoomLevel(zoom)) &&  
    712                           (zoom != this.getZoom()); 
     717        var zoomChanged; 
     718        //if zoomlevel not changed -> is at least one overlay active? 
     719        //The active (temporarily invisible) overlays will not 
     720        //reposition after scaling to the _same_ zoomlevel.  
     721        //So, it it is necessary to redraw the grid by calling this  
     722        //setCenter function. 
     723        if (zoom == this.getZoom()) 
     724        { 
     725            for (var i = 0; i < this.layers.length; i++) { 
     726                var layer = this.layers[i]; 
     727                if (!layer.isBaseLayer) { 
     728                    if (layer.getVisibility()) 
     729                        zoomChanged = true; 
     730                } 
     731            } 
     732        } 
     733        else { //zoomlevel changed 
     734            zoomChanged = true; 
     735        } 
     736         
     737        zoomChanged = (this.isValidZoomLevel(zoom) && zoomChanged); 
    713738 
    714739        var centerChanged = (this.isValidLonLat(lonlat)) &&  
    715740                            (!lonlat.equals(this.center)); 
     
    834859        return valid; 
    835860    }, 
    836861 
     862 
     863    /** Sets the map resolution during zooming/scaling. 
     864     *  
     865     * @param {float} newResolution 
     866     */  
     867    setScaleResolution: function (newResolution) { 
     868        //calculate the current bounds of the new viewport 
     869        var newScaleBounds = this.calculateBounds(this.getCenter(), newResolution); 
     870         
     871        //update the overviewMap 
     872        for (i=0; i<this.controls.length; i++) { 
     873            if (this.controls[i].CLASS_NAME == "OpenLayers.Control.OverviewMap")  
     874                this.controls[i].updateOverview(newResolution, newScaleBounds); 
     875        }           
     876    }, 
     877 
     878 
     879 
    837880  /********************************************************/ 
    838881  /*                                                      */ 
    839882  /*                 Layer Options                        */ 
  • lib/OpenLayers/Layer/Grid.js

    old new  
    2323    /** @type Integer */ 
    2424    buffer: 2, 
    2525 
     26    /** @type OpenLayers.Tile */ 
     27    centerTile: null, 
     28 
     29    /** @type Integer */ 
     30    centerRow: null, 
     31 
     32    /** @type Integer */ 
     33    centerCol: null, 
     34 
     35    /** @type OpenLayers.Pixel */    
     36    centerTileStartScalePos: null, 
     37 
     38    /** @type OpenLayers.Tile */ 
     39    zoomOutTile: null, 
     40 
     41 
    2642    /** 
    2743     * @constructor 
    2844     *  
     
    139155        } 
    140156    }, 
    141157     
     158 
     159    /**  
     160     * Finds and sets the tile, which contains the center  
     161     * of the viewport. 
     162     * 
     163     */ 
     164    setCenterTile:function() { 
     165         
     166        //get the center of the map (viewport) 
     167        var center = this.map.getCenter(); 
     168 
     169        //find tile, which contains the center of the viewport 
     170        this.centerTile = null; 
     171        if (this.grid) { 
     172            for (var iRow=0; iRow < this.grid.length; iRow++) { 
     173                for (var iCol=0; iCol < this.grid[iRow].length; iCol++) { 
     174                    var tileBounds = this.grid[iRow][iCol].bounds; 
     175                    if (tileBounds.containsLonLat(center, true)) { 
     176                        this.centerTile = this.grid[iRow][iCol]; 
     177                        this.centerRow = iRow; 
     178                        this.centerCol = iCol; 
     179                        break;  
     180                    } 
     181                } 
     182                if (this.centerTile) 
     183                    break; 
     184            } 
     185        } 
     186         
     187        //define real position of the center tile before scaling 
     188        //(It is tricky if you pan the map before scaling. Then the 
     189        //layerContainerDiv is only slided and you have to add this 
     190        //difference to the tile position) 
     191        var x = parseInt(this.centerTile.imgDiv.style.left)  
     192          + parseInt(this.map.layerContainerDiv.style.left); 
     193        var y = parseInt(this.centerTile.imgDiv.style.top) 
     194          + parseInt(this.map.layerContainerDiv.style.top); 
     195 
     196        this.centerTileStartScalePos = new OpenLayers.Pixel(x,y); 
     197 
     198 
     199        this.grid_visible = []; 
     200        var extent = this.map.getExtent(); 
     201 
     202        // find all visible tiles of each active layers 
     203        for (var i = 0; i < this.map.layers.length; i++) { 
     204            // find only active layers 
     205            if (this.map.layers[i].visibility) { 
     206                var layerGrid = this.map.layers[i].grid; 
     207                 
     208                // go through the whole grid of every layer 
     209                for (var iRow=0; iRow < layerGrid.length; iRow++) { 
     210                    for (var iCol=0; iCol < layerGrid[iRow].length; iCol++) {  
     211                        var tile = layerGrid[iRow][iCol]; 
     212                        if (tile.imgDiv){ 
     213                            // if tile outside the viewport, set it 
     214                            // invisible  
     215                            if (extent.containsBounds(tile.bounds,true, false)) { 
     216                                tile.imgDiv.style.display = "block"; 
     217                            } 
     218                        } 
     219                    } 
     220                }  
     221            } 
     222        }             
     223 
     224    }, 
     225 
     226 
    142227    /** 
     228     * Scales all tiles of each active layer to the new tile size  
     229     * (changes size and position of every tile). 
     230     *  
     231     * @param {OpenLayers.Size} newTileSize 
     232     */ 
     233    scaleTileTo:function(newTileSize) { 
     234         
     235        //convert the current center of the map in pixel 
     236        var centerPx = this.map.getPixelFromLonLat(this.map.getCenter()); 
     237 
     238        //reposition the center tile  
     239        if (this.centerTile ) { 
     240            //set new left position 
     241            var leftOffset = newTileSize.w / this.centerTile.size.w 
     242              * ( centerPx.x -  this.centerTileStartScalePos.x); 
     243            leftOffset = Math.round(leftOffset); 
     244            var newLeftPos = centerPx.x - leftOffset 
     245              - parseInt(this.map.layerContainerDiv.style.left); 
     246            this.centerTile.imgDiv.style.left = newLeftPos + "px"; 
     247 
     248            //set new top position 
     249            var topOffset = newTileSize.h / this.centerTile.size.h 
     250              * (centerPx.y - this.centerTileStartScalePos.y); 
     251            topOffset = Math.round(topOffset); 
     252            var newTopPos = centerPx.y - topOffset  
     253              - parseInt(this.map.layerContainerDiv.style.top); 
     254            this.centerTile.imgDiv.style.top = newTopPos + "px"; 
     255        } 
     256         
     257        // reposition and resize all _visible_ tiles of all active layers 
     258        for (var i = 0; i < this.map.layers.length; i++) { 
     259            // find only active layers 
     260            if (this.map.layers[i].visibility) { 
     261                var layerGrid = this.map.layers[i].grid; 
     262 
     263                // go through the whole grid of every layer 
     264                for (var iRow=0; iRow < layerGrid.length; iRow++) { 
     265                    for (var iCol=0; iCol < layerGrid[iRow].length; iCol++) {                          
     266                        var tile = layerGrid[iRow][iCol]; 
     267                        if (tile.imgDiv) { 
     268                            if (tile.imgDiv.style.display == "block") { 
     269                                //define the factors for rows and columns 
     270                                //(relates to the center tile) 
     271                                var deltaRow = iRow - this.centerRow; 
     272                                var deltaCol = iCol - this.centerCol; 
     273                                 
     274                                //set new left position 
     275                                var newLeftPos = parseInt(this.centerTile.imgDiv.style.left) 
     276                                  + deltaCol * newTileSize.w ; 
     277                                tile.imgDiv.style.left = newLeftPos + "px"; 
     278 
     279                                //set new top position 
     280                                var newTopPos = parseInt(this.centerTile.imgDiv.style.top) 
     281                                  + deltaRow * newTileSize.h ; 
     282                                tile.imgDiv.style.top = newTopPos + "px"; 
     283 
     284                                //set new width and height 
     285                                tile.imgDiv.style.width = newTileSize.w + "px"; 
     286                                tile.imgDiv.style.height = newTileSize.h + "px"; 
     287                            } 
     288                        } 
     289                    } 
     290                } 
     291            } 
     292        } 
     293    }, 
     294 
     295     
     296    /** 
     297     * Returns the only tile of zoomlevel 0. 
     298     * 
     299     * @returns the tile of zoomlevel 0 
     300     * @type OpenLayers.Tile 
     301     */ 
     302    getZoomOutTile:function() { 
     303        var bounds = this.map.getMaxExtent(); 
     304        var resolution = this.map.getMaxResolution(); 
     305 
     306        var tilelon = resolution * this.tileSize.w; 
     307        var tilelat = resolution * this.tileSize.h; 
     308         
     309        var tileoffsetlon = bounds.left; 
     310        var tileoffsetlat = bounds.bottom; 
     311         
     312        var tileBounds = new OpenLayers.Bounds(tileoffsetlon,  
     313                                               tileoffsetlat,  
     314                                               tileoffsetlon + tilelon, 
     315                                               tileoffsetlat + tilelat); 
     316 
     317        this.zoomOutTile = this.addTile(tileBounds, null); 
     318        return this.zoomOutTile; 
     319    }, 
     320 
     321 
     322    /** 
     323     * Initializes zoomOut tile and sets a bigger tile size. 
     324     * 
     325     */ 
     326    setZoomOutTile:function() { 
     327        //get zoomOut tile 
     328        this.zoomOutTile = this.getZoomOutTile(); 
     329 
     330        // draw tile -> sets imgDiv 
     331        this.zoomOutTile.draw(); 
     332 
     333        // hid tile until the user drags the zoombar 
     334        this.zoomOutTile.imgDiv.style.width = 0; 
     335        this.zoomOutTile.imgDiv.style.height = 0; 
     336 
     337        // set a bigger tile size for zoomOutTile (change WMS url in imgDiv) 
     338        var newTileSize = new OpenLayers.Size(this.tileSize.w*4, this.tileSize.h * 4);         
     339        var wmsUrl = this.zoomOutTile.imgDiv.src; 
     340        var sizeStr_old = "WIDTH="+this.tileSize.w+"&HEIGHT="+this.tileSize.h; 
     341        var sizeStr_new = "WIDTH="+newTileSize.w+"&HEIGHT="+newTileSize.h; 
     342 
     343        wmsUrl = url.replace(sizeStr_old,sizeStr_new);  
     344        this.zoomOutTile.imgDiv.src = wmsUrl; 
     345    }, 
     346 
     347 
     348    /** 
     349     * Reposition and resize the zoomOut tile to prevent a white frame 
     350     * during zoomOut. 
     351     * 
     352     * @param {OpenLayers.Size} newTileSize 
     353     * @param {float} newZoomlevel 
     354     * @param {float} newResolution 
     355     */ 
     356    scaleZoomOutTile: function(newTileSize, newZoomlevel, newResolution) { 
     357 
     358        //convert the current center of the map in pixel 
     359        var centerPx = this.map.getPixelFromLonLat(this.map.getCenter()); 
     360    
     361        //set new size (width and height) 
     362        this.zoomOutTile.imgDiv.style.width = this.map.tileSize.w  
     363          * Math.pow(2, newZoomlevel); 
     364        this.zoomOutTile.imgDiv.style.height = this.map.tileSize.h  
     365          * Math.pow(2, newZoomlevel); 
     366 
     367        //set new position (top and left) 
     368        var bounds = this.zoomOutTile.bounds; 
     369        var extent = this.map.getExtent(); 
     370        var maxExtent = this.map.getMaxExtent(); 
     371 
     372        var resolution = this.map.getMaxResolution(); 
     373        var centerLonLat = extent.getCenterLonLat(); 
     374          
     375        if( bounds.containsLonLat(centerLonLat) 
     376            && !(extent.equals(maxExtent))) { 
     377            var offsetlon = bounds.left - centerLonLat.lon; 
     378            var offsetlat = -bounds.top + centerLonLat.lat; 
     379             
     380            var offsetx = offsetlon / newResolution 
     381              - parseInt(this.map.layerContainerDiv.style.left); 
     382            var offsety = offsetlat / newResolution 
     383              - parseInt(this.map.layerContainerDiv.style.top); 
     384             
     385            this.zoomOutTile.imgDiv.style.left = centerPx.x + offsetx;   
     386            this.zoomOutTile.imgDiv.style.top = centerPx.y + offsety; 
     387        } 
     388    }, 
     389     
     390     
     391    /** 
    143392     * @private 
    144393     *  
    145394     * @returns A Bounds object representing the bounds of all the currently