OpenLayers OpenLayers

Changeset 3194

Show
Ignore:
Timestamp:
05/26/07 15:20:00 (2 years ago)
Author:
emanuel
Message:

OL 2.4 RC5 with animated zooming and panning

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • sandbox/emanuel/animatedZooming/examples/controls.html

    r2803 r3194  
    1515 
    1616            map.addControl(new OpenLayers.Control.PanZoomBar()); 
    17             map.addControl(new OpenLayers.Control.MouseToolbar()); 
     17            map.addControl(new OpenLayers.Control.MouseDefaults()); 
    1818            map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':false})); 
    1919            map.addControl(new OpenLayers.Control.Permalink()); 
  • sandbox/emanuel/animatedZooming/lib/OpenLayers/Control/MouseDefaults.js

    r3042 r3194  
    102102    */ 
    103103    defaultDblClick: function (evt) { 
    104         var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );  
    105         this.map.setCenter(newCenter, this.map.zoom + 1); 
    106         OpenLayers.Event.stop(evt); 
    107         return false; 
     104        if (!this.map.zoomanimationActive){ 
     105            // convert the (old) center of the map in pixel 
     106            var centerPx = this.map.getPixelFromLonLat(this.map.getCenter()); 
     107             
     108            // pan to new center    
     109            var deltaX = evt.xy.x - centerPx.x;  
     110            var deltaY = evt.xy.y - centerPx.y;  
     111            this.map.pan(deltaX, deltaY,true); 
     112 
     113            // zoom to new level  
     114            this.map.zoomIn();  
     115 
     116            OpenLayers.Event.stop(evt); 
     117            return false; 
     118        } 
    108119    }, 
    109120 
     
    204215    defaultWheelUp: function(evt) { 
    205216        if (this.map.getZoom() <= this.map.getNumZoomLevels()) { 
    206             this.map.setCenter(this.map.getLonLatFromPixel(evt.xy), 
    207                                this.map.getZoom() + 1); 
     217            if (!this.map.zoomanimationActive) { 
     218                // convert the current center of the map in pixel 
     219                var centerPx = this.map.getPixelFromLonLat(this.map.getCenter()); 
     220 
     221                // determine lonlat from target (mouse position) 
     222                var targetLonLat = this.map.getLonLatFromViewPortPx( evt.xy );  
     223 
     224                // determine offset target-center in pixel 
     225                var offset = new OpenLayers.Pixel(); 
     226                offset.x = evt.xy.x - centerPx.x; 
     227                offset.y = evt.xy.y - centerPx.y; 
     228 
     229                // convert offset of zoomlevel n to zoomlevel n+1 
     230                offset.x = offset.x / 2; 
     231                offset.y = offset.y / 2; 
     232 
     233                // pan to new center    
     234                this.map.pan(offset.x, offset.y, true); 
     235 
     236                // zoom to new level  
     237                this.map.zoomIn(); 
     238            } 
    208239        } 
    209240    }, 
     
    214245    defaultWheelDown: function(evt) { 
    215246        if (this.map.getZoom() > 0) { 
    216             this.map.setCenter(this.map.getLonLatFromPixel(evt.xy), 
    217                                this.map.getZoom() - 1); 
     247            if (!this.map.zoomanimationActive) { 
     248                // convert the current center of the map in pixel 
     249                var centerPx = this.map.getPixelFromLonLat(this.map.getCenter()); 
     250 
     251                // determine lonlat from target (mouse position) 
     252                var targetLonLat = this.map.getLonLatFromViewPortPx( evt.xy );  
     253 
     254                // determine offset target-center in pixel... 
     255                var offset = new OpenLayers.Pixel(); 
     256                offset.x = evt.xy.x - centerPx.x; 
     257                offset.y = evt.xy.y - centerPx.y; 
     258 
     259                // convert offset of zoomlevel n to zoomlevel n-1 
     260                offset.x = -offset.x; 
     261                offset.y = -offset.y; 
     262 
     263                // pan to new center    
     264                this.map.pan(offset.x, offset.y, true); 
     265 
     266                // zoom to new level  
     267                this.map.zoomOut(); 
     268            } 
    218269        } 
    219270    }, 
     
    224275    zoomBoxEnd: function(evt) { 
    225276        if (this.mouseDragStart != null) { 
    226             if (Math.abs(this.mouseDragStart.x - evt.xy.x) > 5 ||     
    227                 Math.abs(this.mouseDragStart.y - evt.xy.y) > 5) {    
    228                 var start = this.map.getLonLatFromViewPortPx( this.mouseDragStart );  
    229                 var end = this.map.getLonLatFromViewPortPx( evt.xy ); 
    230                 var top = Math.max(start.lat, end.lat); 
    231                 var bottom = Math.min(start.lat, end.lat); 
    232                 var left = Math.min(start.lon, end.lon); 
    233                 var right = Math.max(start.lon, end.lon); 
    234                 var bounds = new OpenLayers.Bounds(left, bottom, right, top); 
    235                 this.map.zoomToExtent(bounds); 
    236             } else { 
    237                 var end = this.map.getLonLatFromViewPortPx( evt.xy ); 
    238                 this.map.setCenter(new OpenLayers.LonLat( 
    239                   (end.lon), 
    240                   (end.lat) 
    241                  ), this.map.getZoom() + 1); 
    242             }     
     277            if (!this.map.zoomanimationActive) { 
     278                if (Math.abs(this.mouseDragStart.x - evt.xy.x) > 5 ||     
     279                    Math.abs(this.mouseDragStart.y - evt.xy.y) > 5) {    
     280                    var start = this.map.getLonLatFromViewPortPx( this.mouseDragStart );  
     281                    var end = this.map.getLonLatFromViewPortPx( evt.xy ); 
     282                    var top = Math.max(start.lat, end.lat); 
     283                    var bottom = Math.min(start.lat, end.lat); 
     284                    var left = Math.min(start.lon, end.lon); 
     285                    var right = Math.max(start.lon, end.lon); 
     286                    var bounds = new OpenLayers.Bounds(left, bottom, right, top); 
     287                    this.map.zoomToExtent(bounds); 
     288                } else { 
     289                    // convert the (old) center of the map in pixel 
     290                    var centerPx = this.map.getPixelFromLonLat(this.map.getCenter()) 
     291                    // pan to new center    
     292                    var deltaX = evt.xy.x - centerPx.x;  
     293                    var deltaY = evt.xy.y - centerPx.y;  
     294                    this.map.pan(deltaX, deltaY,true); 
     295 
     296                    // zoom to new level  
     297                    this.map.zoomIn();         
     298                }     
     299            } 
    243300            this.removeZoomBox(); 
    244        
     301       
    245302    }, 
    246303 
  • sandbox/emanuel/animatedZooming/lib/OpenLayers/Control/MouseToolbar.js

    r3042 r3194  
    124124    */ 
    125125    defaultDblClick: function (evt) { 
    126         this.switchModeTo("pan"); 
    127         this.performedDrag = false; 
    128         var newCenter = this.map.getLonLatFromViewPortPx( evt.xy );  
    129         this.map.setCenter(newCenter, this.map.zoom + 1); 
    130         OpenLayers.Event.stop(evt); 
    131         return false; 
     126        if (!this.map.zoomanimationActive){ 
     127            this.switchModeTo("pan"); 
     128            this.performedDrag = false; 
     129 
     130            // convert the (old) center of the map in pixel 
     131            var centerPx = this.map.getPixelFromLonLat(this.map.getCenter()); 
     132 
     133            // pan to new center    
     134            var deltaX = evt.xy.x - centerPx.x;  
     135            var deltaY = evt.xy.y - centerPx.y;  
     136            this.map.pan(deltaX, deltaY,true); 
     137 
     138            // zoom to new level  
     139            this.map.zoomIn(); 
     140 
     141            OpenLayers.Event.stop(evt); 
     142            return false; 
     143        } 
    132144    }, 
    133145 
  • sandbox/emanuel/animatedZooming/lib/OpenLayers/Control/OverviewMap.js

    r3133 r3194  
    165165        this.div.appendChild(this.element); 
    166166 
    167         this.map.events.register('moveend', this, this.update); 
    168          
    169         // Set up events.  The image div recenters the map on click. 
     167        // update overviewmap during map is panning 
     168        this.map.events.register('move', this, this.update); 
     169         
     170        // Set up events.  The image div recenters the map on doubleclick. 
    170171        // The extent rectangle can be dragged to recenter the map. 
    171172        // If the mousedown happened elsewhere, then mousemove and mouseup 
     
    190191            OpenLayers.Event.stop(e); 
    191192        }); 
    192         this.rectEvents.register('dblclick', this, this.rectDblClick ); 
    193193        this.mapDivEvents = new OpenLayers.Events(this, this.mapDiv); 
    194         this.mapDivEvents.register('click', this, this.mapDivClick); 
     194        this.mapDivEvents.register('dblclick', this, this.mapDivDblClick); 
    195195 
    196196        // Optionally add min/max buttons if the control will go in the 
     
    330330    }, 
    331331     
     332 
    332333    /** 
    333334    * @param {OpenLayers.Event} evt 
    334335    */ 
    335     rectDblClick: function(evt) { 
    336         this.performedRectDrag = false; 
    337         OpenLayers.Event.stop(evt); 
    338         this.updateOverview(); 
    339     }, 
    340  
    341     /** 
    342     * @param {OpenLayers.Event} evt 
    343     */ 
    344     mapDivClick: function(evt) { 
     336    mapDivDblClick: function(evt) { 
    345337        var pxBounds = this.getRectPxBounds(); 
    346338        var pxCenter = pxBounds.getCenterPixel(); 
     
    355347        var newLeft = Math.max(0, (left + deltaX)); 
    356348        newLeft = Math.min(newLeft, this.ovmap.size.w - width); 
    357         this.setRectPxBounds(new OpenLayers.Bounds(newLeft, 
     349        pxBounds = new OpenLayers.Bounds(newLeft, 
    358350                                                   newTop + height, 
    359351                                                   newLeft + width, 
    360                                                    newTop))
    361         this.updateMapToRect(); 
     352                                                   newTop)
     353        this.updateMapToRect(pxBounds); 
    362354        OpenLayers.Event.stop(evt); 
    363355    }, 
     
    407399            this.createMap(); 
    408400        } 
    409          
     401 
    410402        if(!this.isSuitableOverview()) { 
    411403            this.updateOverview(); 
    412404        } 
    413          
     405 
    414406        // update extent rectangle 
    415407        this.updateRectToMap(); 
    416     }, 
    417      
     408 
     409        this.updateOverview(); 
     410    }, 
     411 
    418412    /** 
    419413     * Determines if the overview map is suitable given the extent and 
     
    427421                                Math.max(mapExtent.bottom, maxExtent.bottom), 
    428422                                Math.min(mapExtent.right, maxExtent.right), 
    429                                 Math.min(mapExtent.top, maxExtent.top));         
     423                                Math.min(mapExtent.top, maxExtent.top)); 
    430424        var resRatio = this.ovmap.getResolution() / this.map.getResolution(); 
    431425        return ((resRatio > this.minRatio) && 
     
    433427                (this.ovmap.getExtent().containsBounds(testExtent))); 
    434428    }, 
    435      
    436     updateOverview: function() { 
    437         var mapRes = this.map.getResolution(); 
     429 
     430    /*  
     431     * Updates the overview map. If the map is scaling (by zooming) the parameters 
     432     * define the values of the new resolution and bounds. 
     433     * 
     434     * @param {float} newResolution 
     435     * @param {OpenLayers.Bounds} bounds 
     436     */     
     437    updateOverview: function(newResolution, bounds) { 
     438        //set new map resolution only by scaling 
     439        if (newResolution) 
     440            var mapRes = newResolution; 
     441        else 
     442            var mapRes = this.map.getResolution(); 
    438443        var targetRes = this.ovmap.getResolution(); 
    439444        var resRatio = targetRes / mapRes; 
     
    447452        this.ovmap.setCenter(this.map.center, 
    448453                            this.ovmap.getZoomForResolution(targetRes)); 
    449         this.updateRectToMap(); 
     454        this.updateRectToMap(bounds); 
    450455    }, 
    451456     
     
    471476         
    472477    /** 
    473      * Updates the extent rectangle position and size to match the map extent 
    474      */ 
    475     updateRectToMap: function() { 
     478     * Updates the extent rectangle position and size to match the map extent   
     479     * If the map is scaling (by zooming) the parameter defines the 
     480     * new bounds of the current map 
     481     * 
     482     * @param {OpenLayers.Bounds} bounds 
     483     */ 
     484    updateRectToMap: function(bounds) { 
    476485        // The base layer for overview map needs to be in the same projection 
    477486        // as the base layer for the main map.  This should be made more robust. 
     
    481490            } 
    482491        } 
    483         var pxBounds = this.getRectBoundsFromMapBounds(this.map.getExtent()); 
     492 
     493        if (!bounds) 
     494            bounds=this.map.getExtent(); 
     495        var pxBounds = this.getRectBoundsFromMapBounds(bounds); 
    484496        if (pxBounds) { 
    485497          this.setRectPxBounds(pxBounds); 
     
    490502     * Updates the map extent to match the extent rectangle position and size 
    491503     */ 
    492     updateMapToRect: function() { 
    493         var pxBounds = this.getRectPxBounds(); 
     504    updateMapToRect: function(pxBounds) { 
     505        if (!pxBounds) 
     506            var pxBounds = this.getRectPxBounds(); 
    494507        var lonLatBounds = this.getMapBoundsFromRectBounds(pxBounds); 
    495         this.map.setCenter(lonLatBounds.getCenterLonLat(), this.map.zoom); 
     508 
     509        var centerPx = this.map.getViewPortPxFromLonLat(lonLatBounds.getCenterLonLat()); 
     510 
     511        var resolution = this.map.getResolution(); 
     512         
     513        var width = lonLatBounds.getWidth(); 
     514        width = width / resolution; 
     515        var height = lonLatBounds.getHeight(); 
     516        height = height / resolution; 
     517 
     518        // pan to recenter rectangle 
     519        this.map.pan(centerPx.x-width/2,centerPx.y-height/2); 
    496520    }, 
    497521     
  • sandbox/emanuel/animatedZooming/lib/OpenLayers/Control/PanZoom.js

    r3033 r3194  
    1616 
    1717    /** @type int */ 
    18     slideFactor: 50
     18    slideFactor: 75
    1919 
    2020    /** @type Array of Button Divs */ 
     
    134134        switch (this.action) { 
    135135            case "panup":  
    136                 this.map.pan(0, -50); 
     136                this.map.pan(0, -this.slideFactor); 
    137137                break; 
    138138            case "pandown":  
    139                 this.map.pan(0, 50); 
     139                this.map.pan(0, this.slideFactor); 
    140140                break; 
    141141            case "panleft":  
    142                 this.map.pan(-50, 0); 
     142                this.map.pan(-this.slideFactor, 0); 
    143143                break; 
    144144            case "panright":  
    145                 this.map.pan(50, 0); 
     145                this.map.pan(this.slideFactor, 0); 
    146146                break; 
    147147            case "zoomin":  
  • sandbox/emanuel/animatedZooming/lib/OpenLayers/Control/PanZoomBar.js

    r3042 r3194  
    181181        var top = OpenLayers.Util.pagePosition(evt.object)[1]; 
    182182        var levels = Math.floor((y - top)/this.zoomStopHeight); 
    183         this.map.zoomTo((this.map.getNumZoomLevels() -1) -  levels); 
     183 
     184        if (!this.map.zoomanimationActive) 
     185            this.map.zoomTo((this.map.getNumZoomLevels() -1) -  levels); 
     186 
    184187        OpenLayers.Event.stop(evt); 
    185188    }, 
     
    194197        this.map.events.register("mouseup", this, this.passEventToSlider); 
    195198        this.mouseDragStart = evt.xy.clone(); 
    196         this.zoomStart = evt.xy.clone(); 
     199        this.map.zoomStart = evt.xy.clone(); 
    197200        this.div.style.cursor = "move"; 
     201 
     202        // get and set some settings for zoom animation  
     203        this.map.prepareZoomAnimation(); 
     204         
    198205        // reset the div offsets just in case the div moved 
    199206        this.zoombarDiv.offsets = null;  
     
    217224            } 
    218225            this.mouseDragStart = evt.xy.clone(); 
     226            
     227            // set current slider position 
     228            var sliderPosition = new OpenLayers.Pixel(evt.xy.x, evt.xy.y);  
     229 
     230            // run zoom animation -> scale tile(s) 
     231            this.map.runZoomAnimation(this.zoomStopHeight, sliderPosition); 
     232       
    219233            OpenLayers.Event.stop(evt); 
    220234        } 
     
    228242    zoomBarUp:function(evt) { 
    229243        if (!OpenLayers.Event.isLeftClick(evt)) return; 
    230         if (this.zoomStart) { 
     244        if (this.map.zoomStart) { 
    231245            this.div.style.cursor=""; 
    232246            this.map.events.unregister("mouseup", this, this.passEventToSlider); 
    233247            this.map.events.unregister("mousemove", this, this.passEventToSlider); 
    234             var deltaY = this.zoomStart.y - evt.xy.y 
    235             this.map.zoomTo(this.map.zoom + Math.round(deltaY/this.zoomStopHeight)); 
     248            var deltaY = this.map.zoomStart.y - evt.xy.y; 
     249 
     250            // zoom map to new zoomlevel 
     251            var finalZoomlevel = this.map.zoom + Math.round(deltaY/this.zoomStopHeight); 
     252 
     253            // finish zoom animation 
     254            this.map.finishZoomAnimation(finalZoomlevel); 
     255 
    236256            this.moveZoomBar(); 
    237257            this.mouseDragStart = null; 
     
    242262    /*  
    243263    * Change the location of the slider to match the current zoom level. 
     264    * 
     265    * @param {float} zoomlevel 
    244266    */ 
    245     moveZoomBar:function() { 
    246         var newTop =  
    247             ((this.map.getNumZoomLevels()-1) - this.map.getZoom()) *  
     267    moveZoomBar:function(zoomlevel) { 
     268        // check if zoomlevel is not a number 
     269        if (isNaN(zoomlevel)) { 
     270            zoomlevel = this.map.getZoom(); 
     271        } 
     272 
     273        // set new top position 
     274        var newTop = ((this.map.getNumZoomLevels()-1) - zoomlevel) * 
    248275            this.zoomStopHeight + this.startTop + 1; 
    249276        this.slider.style.top = newTop + "px"; 
  • sandbox/emanuel/animatedZooming/lib/OpenLayers/Layer.js

    r3162 r3194  
    141141    displayOutsideMaxExtent: false, 
    142142     
    143      
     143    /** did the image finish loading before a new draw was initiated? 
     144     * @type Boolean */ 
     145    doneLoading: false, 
     146 
     147    /** @type Boolen */ 
     148    firstCall: true,  
     149 
     150 
    144151    /** 
    145152     * @constructor 
     
    165172            this.events = new OpenLayers.Events(this, this.div,  
    166173                                                this.EVENT_TYPES); 
    167         } 
     174            this.events.register("loadend", this, this.setLoadendVisibility); 
     175        } 
     176         
    168177    }, 
    169178     
     
    546555    getResolution: function() { 
    547556        var zoom = this.map.getZoom(); 
     557        if (zoom >= this.map.getNumZoomLevels()) 
     558            zoom = this.map.getNumZoomLevels() - 1; 
    548559        return this.resolutions[zoom]; 
    549560    }, 
     
    611622            if (center) { 
    612623                var res  = this.map.getResolution(); 
    613          
    614                 var delta_x = viewPortPx.x - (size.w / 2); 
    615                 var delta_y = viewPortPx.y - (size.h / 2); 
     624 
     625                var delta_x = viewPortPx.x - Math.ceil(size.w / 2); 
     626                var delta_y = viewPortPx.y - Math.ceil(size.h / 2); 
     627 
    616628             
    617629                lonlat = new OpenLayers.LonLat(center.lon + delta_x * res , 
     
    629641     * @type OpenLayers.Pixel 
    630642     */ 
    631     getViewPortPxFromLonLat: function (lonlat) { 
     643    getViewPortPxFromLonLat: function (lonlat, resolution) { 
    632644        var px = null;  
    633645        if (lonlat != null) { 
    634             var resolution = this.map.getResolution(); 
     646            if (!resolution) 
     647                resolution = this.map.getResolution(); 
    635648            var extent = this.map.getExtent(); 
    636649            px = new OpenLayers.Pixel( 
     
    667680            this.opacity = opacity; 
    668681            for(var i=0; i<this.div.childNodes.length; ++i) { 
    669                 var element = this.div.childNodes[i].firstChild
     682                var element = this.div.childNodes[i]
    670683                OpenLayers.Util.modifyDOMElement(element, null, null, null,  
    671684                                                 null, null, null, opacity); 
     
    682695    }, 
    683696 
     697 
     698 
     699 
     700    /********************************************************/ 
     701    /*                                                      */ 
     702    /*       Baselayer Functions for zooming/scaling        */ 
     703    /*                                                      */ 
     704    /********************************************************/ 
     705 
     706    /**  
     707     * Initializes zoomOut tile and sets a x-times bigger tile size. 
     708     * 
     709     * Default function; will override in subclasses, 
     710     * otherwise it returns false 
     711     *  
     712     * @returns false if no zoomOutTile is set 
     713     * @type Boolean 
     714     */ 
     715    setZoomOutTile:function() { 
     716        return false; 
     717    }, 
     718 
     719    /** 
     720     * Initializes zoomOut tile and sets a x-times bigger tile size. 
     721     *  
     722     * special function; shares with some baselayers; calls from subclasses 
     723     * 
     724     */ 
     725    setZoomOutTile_share:function() { 
     726        if (!this.zoomOutTile) { 
     727            var bounds = this.map.getMaxExtent(); 
     728            var resolution = this.resolutions[0];  
     729 
     730            // calculate tile bounds 
     731            var n = 0; 
     732            do { 
     733                resolution = resolution * Math.pow(2, n); 
     734                 
     735                var tilelon = resolution * this.map.tileSize.w; 
     736                var tilelat = resolution * this.map.tileSize.h; 
     737             
     738                var tileoffsetlon = bounds.left; 
     739                var tileoffsetlat = bounds.bottom; 
     740                 
     741                var tileBounds = new OpenLayers.Bounds(tileoffsetlon,  
     742                                                       tileoffsetlat,  
     743                                                       tileoffsetlon + tilelon, 
     744                                                       tileoffsetlat + tilelat); 
     745                n++; 
     746            } 
     747            while (!tileBounds.containsBounds(bounds, false, true)); 
     748 
     749            var tileSize = new OpenLayers.Size(); 
     750            tileSize.w = this.map.zoomOutTileSizeFactor * this.map.tileSize.w; 
     751            tileSize.h = this.map.zoomOutTileSizeFactor * this.map.tileSize.h; 
     752 
     753            // formulate request url string 
     754            var url = this.getURL(tileBounds, tileSize);  
     755            // default start position 
     756            var pos = new OpenLayers.Pixel (0,0);  
     757            // default start size 
     758            var tilesize = new OpenLayers.Size(0,0); 
     759 
     760            this.zoomOutTile = new OpenLayers.Tile.Image(this, pos, tileBounds,  
     761                                                        url, tileSize); 
     762 
     763            // draw tile -> sets imgDiv 
     764            this.zoomOutTile.draw(); 
     765 
     766            // resize zoomOutTile 
     767            this.zoomOutTile.imgDiv.style.width = 0; 
     768            this.zoomOutTile.imgDiv.style.height = 0; 
     769             
     770            // set zoomOut tile invisible  
     771            if (this.map.baseLayer.zoomOutTile) 
     772                this.map.baseLayer.zoomOutTile.imgDiv.style.display = "none"; 
     773        } 
     774    }, 
     775  
     776    /**  
     777     * Gets the current tile size of the layer. 
     778     * 
     779     * Default function; will override in subclasses, 
     780     * otherwise it returns false - that means: no scaling possible! 
     781     *  
     782     * @returns null if no tile size set 
     783     * @type OpenLayers.Size 
     784     */ 
     785    getTileSize:function() { 
     786        return null; 
     787    }, 
     788 
     789 
     790    /**  
     791     * Gets tile, which contains the center of the viewport. 
     792     * 
     793     * Default function; will override in subclasses, 
     794     * otherwise it returns null - that means: no scaling possible! 
     795     *  
     796     * @returns returns null if no center tile set 
     797     * @type OpenLayers.Tile 
     798     */ 
     799    getCenterTile:function() { 
     800        return null; 
     801    }, 
     802 
     803 
     804    /**  
     805     * Sets all tiles outside the viewport invisible.  
     806     * Only for baselayers with a grid of tiles. 
     807     * 
     808     * Default function; will override in subclasses, 
     809     * otherwise it returns false 
     810     *  
     811     * @returns false if baselayer has no grid 
     812     * @type Boolean 
     813     */ 
     814    setTilesOutsideInvisible:function() { 
     815        return false; 
     816    }, 
     817 
     818    /** 
     819     * Scales tile to the new tile size (changes size and position). 
     820     * If you have a grid, the tile is the center tile. Otherwise it's 
     821     * the only one. 
     822     *  
     823     * @param {OpenLayers.Tile} tile 
     824     * @param {OpenLayers.Size} newTileSize 
     825     *  
     826     * @returns true if tile is scaled, otherwise false 
     827     * @type Boolean 
     828     */ 
     829    scaleTileTo:function(tile, newTileSize) { 
     830        //convert the center of the map in pixel 
     831        var centerPx = this.map.getPixelFromLonLat(this.map.getCenter()); 
     832 
     833        //reposition and resize the tile  
     834        if (tile) { 
     835            if ((newTileSize.w < Math.pow(2,15)) && 
     836                (newTileSize.h < Math.pow(2,15)) ){ 
     837 
     838                // set real start position of centerTile 
     839                var startPosX = (tile.position.x + 
     840                  parseInt(this.map.layerContainerDiv.style.left)); 
     841                // set new left position 
     842                var leftOffset = newTileSize.w / tile.size.w 
     843                  * (centerPx.x - startPosX); 
     844                leftOffset = Math.round(leftOffset); 
     845                var newLeftPos = centerPx.x - leftOffset 
     846                  - parseInt(this.map.layerContainerDiv.style.left); 
     847                tile.imgDiv.style.left = Math.round(newLeftPos) + "px"; 
     848 
     849                // set real start position of centerTile 
     850                var startPosY = (tile.position.y + 
     851                  parseInt(this.map.layerContainerDiv.style.top)); 
     852                //set new top position 
     853                var topOffset = newTileSize.h / tile.size.h 
     854                  * (centerPx.y - startPosY); 
     855                topOffset = Math.round(topOffset); 
     856                var newTopPos = centerPx.y - topOffset  
     857                  - parseInt(this.map.layerContainerDiv.style.top); 
     858                tile.imgDiv.style.top = Math.round(newTopPos) + "px"; 
     859 
     860                //set new width and height 
     861                tile.imgDiv.style.width = Math.round(newTileSize.w) + "px"; 
     862                tile.imgDiv.style.height = Math.round(newTileSize.h) + "px"; 
     863            } 
     864            return true; 
     865        } 
     866        else { 
     867            return false; 
     868        } 
     869    },  
     870 
     871    /**  
     872     * Scales all tiles of a grid to the new tile size  
     873     * (changes size and position). 
     874     * 
     875     * Default function; will override in subclasses, 
     876     * otherwise it returns false 
     877     *  
     878     * @param {OpenLayers.Tile} centerTile 
     879     * @param {OpenLayers.Size} newTileSize 
     880     * 
     881     * @returns false if no grid is scaled 
     882     * @type Boolean 
     883     */ 
     884    scaleTilesOfGrid:function(centertile, newTileSize) { 
     885        return false; 
     886    }, 
     887 
     888 
     889    /** 
     890     * Reposition and resize the zoomOut tile to prevent a white frame 
     891     * during zoomOut. 
     892     * 
     893     * @param {float} newZoomlevel 
     894     * @param {float} newResolution 
     895     * 
     896     * @returns false if no zoomOutTile scaled 
     897     * @type Boolean 
     898     */ 
     899    scaleZoomOutTile: function(newZoomlevel, newResolution) { 
     900        return false; 
     901    }, 
     902 
     903    /** 
     904     * The actual zoomOutTile scale function: 
     905     * Reposition and resize the zoomOut tile to prevent a white frame 
     906     * during zoomOut. 
     907     * 
     908     * special function; shares with some baselayers; calls from subclasses 
     909     * 
     910     * @param {float} newZoomlevel 
     911     * @param {float} newResolution 
     912     * 
     913     * @returns true after the zoomOutTile is scaled 
     914     * @type Boolean 
     915     */ 
     916    scaleZoomOutTile_share: function(newZoomlevel, newResolution) { 
     917 
     918        //convert the current center of the map in pixel 
     919        var centerPx = this.map.getPixelFromLonLat(this.map.getCenter()); 
     920 
     921 
     922        var newTileSize = new OpenLayers.Size(); 
     923        newTileSize.w = Math.round(this.map.tileSize.w * Math.pow(2, newZoomlevel)); 
     924        newTileSize.h = Math.round(this.map.tileSize.h * Math.pow(2, newZoomlevel)); 
     925 
     926        // handles bug in ie:  
     927        // turn zoomOut tile scale off, if tileSize > 2^15  
     928        var ieBug; 
     929        if (navigator.appName == "Microsoft Internet Explorer"){  
     930            if ((newTileSize.w > Math.pow(2,15)) && 
     931                (newTileSize.h > Math.pow(2,15)) ){ 
     932                ieBug = true; 
     933                this.map.baseLayer.zoomOutTile.imgDiv.style.display = "none"; 
     934            } 
     935            else { 
     936                ieBug = false; 
     937            } 
     938        } 
     939        else { 
     940            ieBug = false; 
     941        } 
     942 
     943        if (!ieBug && !this.firstCall) { 
     944            //set new size (width and height) 
     945            this.zoomOutTile.imgDiv.style.width = newTileSize.w + "px";           
     946            this.zoomOutTile.imgDiv.style.height = newTileSize.h + "px"; 
     947 
     948            //set new position (top and left) 
     949            var bounds = this.zoomOutTile.bounds; 
     950            var extent = this.map.getExtent(); 
     951            var maxExtent = this.map.getMaxExtent(); 
     952 
     953            var resolution = this.map.getMaxResolution(); 
     954            var centerLonLat = extent.getCenterLonLat(); 
     955              
     956            var offsetlon = bounds.left - centerLonLat.lon; 
     957            var offsetlat = -bounds.top + centerLonLat.lat; 
     958             
     959            var offsetx = offsetlon / newResolution 
     960              - parseInt(this.map.layerContainerDiv.style.left); 
     961            var offsety = offsetlat / newResolution 
     962              - parseInt(this.map.layerContainerDiv.style.top); 
     963             
     964            this.zoomOutTile.imgDiv.style.left =  
     965                Math.round(centerPx.x + offsetx) + "px";   
     966            this.zoomOutTile.imgDiv.style.top =  
     967                Math.round(centerPx.y + offsety) + "px"; 
     968         
     969             
     970            this.map.baseLayer.zoomOutTile.imgDiv.style.display = "block"; 
     971        } 
     972         
     973        return true; 
     974    }, 
     975 
     976    /**  
     977     * Clones layerContainer for "smooth tile update". 
     978     * So, it gets no blank map while map is loading in new zoomlevel. 
     979     * 
     980     * Default function; will override in subclasses, 
     981     * otherwise it returns false 
     982     *  
     983     * @returns false if no layerContainer cloned 
     984     * @type Boolean 
     985     */ 
     986    cloneBaseLayerDiv:function() { 
     987        return false; 
     988    }, 
     989 
     990    /**  
     991     * The actual clone function: 
     992     * Hold scaled map while tiles are loading successive. 
     993     *   
     994     * special function; shares with some baselayers; calls from subclasses 
     995     * 
     996     */ 
     997    cloneBaseLayerDiv_share:function() { 
     998        // function for map only; not for overviewmap! 
     999        if (this.map.div.id == "map") {   
     1000             
     1001            // 1. clone baseLayerDiv with all childs (replace, if already exist) 
     1002            if (this.map.baseLayerDivClone){ 
     1003                this.map.layerContainerDiv.removeChild(this.map.baseLayerDivClone); 
     1004                this.map.baseLayerDivClone = null; 
     1005            } 
     1006            this.map.baseLayerDivClone = this.map.baseLayer.div.cloneNode(true); 
     1007            this.map.baseLayerDivClone.id = 
     1008                this.map.baseLayer.div.id + "_clone"; 
     1009                     
     1010     
     1011            // 2. append baseLayerDivClone to layerContainer 
     1012            // (now the cloned div is above the original; it hides the original) 
     1013            this.map.layerContainerDiv.appendChild(this.map.baseLayerDivClone); 
     1014 
     1015            // 3. set zIndex  
     1016            this.map.baseLayerDivClone.style.zIndex--;  
     1017                 
     1018            // 4. set zoomOut tile (of original div) invisible  
     1019            if (this.map.baseLayer.zoomOutTile) 
     1020                this.map.baseLayer.zoomOutTile.imgDiv.style.display = "none"; 
     1021 
     1022            // 5. adjust left and top position  
     1023            // (if map is panning before, layerContainer is displaced) 
     1024            if (this.map.layerContainerDiv.style.left != "") 
     1025                this.map.baseLayerDivClone.style.left +=  
     1026                    parseInt(this.map.layerContainerDiv.style.left); 
     1027            if (this.map.layerContainerDiv.style.top != "") 
     1028                this.map.baseLayerDivClone.style.top +=  
     1029                    parseInt(this.map.layerContainerDiv.style.top);            
     1030        } 
     1031    }, 
     1032 
     1033 
     1034    /** 
     1035     * Sets visibility of map after zoomend/loadend: 
     1036     * - freezed/cloned layerContainer invisible 
     1037    &nb