OpenLayers OpenLayers

Ticket #442: animatedZooming_1.1.patch

File animatedZooming_1.1.patch, 19.0 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: 512px; 
     6            height: 512px; 
     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.zoomToMaxExtent(); 
     46        } 
     47        // --> 
     48    </script> 
     49  </head> 
     50  <body onload="init()"> 
     51    <div id="map"></div> 
     52  </body> 
     53</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: 90000, 
     25      maxExtent: new OpenLayers.Bounds(7.92881, 52.2131, 8.18349, 52.341), 
     26      projection:"EPSG:4326", 
     27      //alternative: projection:"EPSG:31467" 
     28      controls: [new OpenLayers.Control.MouseDefaults()] 
     29    };  
     30    var map = new OpenLayers.Map('map',options); 
     31 
     32 
     33    //baselayer 
     34    var baselayer_wms = new OpenLayers.Layer.WMS( "Frida WMS",  
     35      "http://demo.intevation.org/cgi/frida-wms", { 
     36        layers: 'strassenall', 
     37        isBaseLayer: 'true', 
     38        format: 'image/png' } 
     39      ); 
     40     
     41    //green spaces 
     42    var greenspaces_wms = new OpenLayers.Layer.WMS( "green spaces",  
     43      "http://demo.intevation.org/cgi/frida-wms", { 
     44        layers: 'gruenflaechen', 
     45        isBaseLayer: "false",  
     46        transparent: "true",  
     47        format:'image/png'} 
     48      ); 
     49    greenspaces_wms.setVisibility(false); 
     50 
     51    //waters 
     52    var waters_wms = new OpenLayers.Layer.WMS( "waters",  
     53      "http://demo.intevation.org/cgi/frida-wms", { 
     54        layers: 'gewaesser', 
     55        isBaseLayer: "false",  
     56        transparent: "true",  
     57        format:'image/png'} 
     58      ); 
     59    waters_wms.setVisibility(false); 
     60     
     61    //streets 
     62    var streets_wms = new OpenLayers.Layer.WMS( "streets",  
     63      "http://demo.intevation.org/cgi/frida-wms", { 
     64        layers: 'strassenall', 
     65        isBaseLayer: "false",  
     66        transparent: "true",  
     67        format:'image/png'} 
     68      ); 
     69    streets_wms.setVisibility(false); 
     70 
     71    //poi 
     72    var poi_wms = new OpenLayers.Layer.WMS( "POI",  
     73      "http://demo.intevation.org/cgi/frida-wms", { 
     74        layers: 'sehenswuerdigkeiten', 
     75        isBaseLayer: "false",  
     76        transparent: "true",  
     77        format:'image/png'} 
     78      ); 
     79    poi_wms.setVisibility(false);         
     80     
     81 
     82    //add all layers 
     83    map.addLayers([baselayer_wms, greenspaces_wms, waters_wms,  poi_wms]); 
     84     
     85    //add controls 
     86    map.addControl(new OpenLayers.Control.PanZoomBar()); 
     87    map.addControl( new OpenLayers.Control.LayerSwitcher() ); 
     88    map.addControl(new OpenLayers.Control.MousePosition()); 
     89 
     90    //set center and zoomlevel 
     91    //map.setCenter(new OpenLayers.LonLat(lon, lat), zoom); 
     92    map.zoomToMaxExtent(); 
     93 
     94</script> 
     95</head> 
     96 
     97<body onload="init()"> 
     98    <div id="map"></div> 
     99    Free geodata powered by <a href="http://frida.intevation.de">Frida project</a> 
     100</body> 
     101 
     102</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 int */ 
     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 
     189        //get current zoomlevel 
     190        this.zoomlevel_startScale = this.map.zoom; 
     191 
     192        //get original tile size 
     193        this.tileSize_startScale = this.map.getTileSize(); 
     194 
     195        //find tile, which contains the center of the viewport 
     196        this.map.findCenterTile(); 
     197 
     198        /*    
     199        //set all active overlays temporarily invisible 
     200        for (var i = 0; i < this.map.layers.length; i++) { 
     201            var layer = this.map.layers[i]; 
     202            if (!layer.isBaseLayer) { 
     203                this.map.layers[i].div.style.display = "none"; 
     204            } 
     205        } 
     206        */ 
     207 
    171208    }, 
    172209     
    173210    /* 
     
    187224            } 
    188225            this.mouseDragStart = evt.xy.clone(); 
    189226            OpenLayers.Event.stop(evt); 
     227 
     228 
     229 
     230            //convert current sliderposition to new zoomlevel 
     231            var deltaY_zoomlevel = this.zoomStart.y - evt.xy.y 
     232            this.zoomlevel_scale=this.zoomlevel_startScale +  
     233              deltaY_zoomlevel/this.zoomStopHeight; 
     234            
     235            //check the zoomlevel validity   
     236            if (this.zoomlevel_scale < 0){ 
     237                this.zoomlevel_scale = 0;  
     238            }  
     239            if (this.zoomlevel_scale >= this.map.getNumZoomLevels()){  
     240                this.zoomlevel_scale = this.map.getNumZoomLevels() - 1;  
     241            } 
     242             
     243            //calculate the new tile size for the scale... 
     244            //...zoomIn 
     245            if (this.zoomlevel_startScale < this.zoomlevel_scale) { 
     246                this.tileSize_scale.w =  
     247                  Math.pow(2,(this.zoomlevel_scale - 
     248                  this.zoomlevel_startScale)) * this.tileSize_startScale.w; 
     249                this.tileSize_scale.h =  
     250                  Math.pow(2,(this.zoomlevel_scale - 
     251                  this.zoomlevel_startScale)) * this.tileSize_startScale.h; 
     252 
     253                // set new map resolution 
     254                this.resolution_scale =  
     255                  1/(Math.pow(2,(this.zoomlevel_scale -  
     256                  this.zoomlevel_startScale))) *  this.map.getResolution();     
     257               
     258            } 
     259            //...zoomOut / no zoomchanges 
     260            if (this.zoomlevel_startScale >= this.zoomlevel_scale) {              
     261                this.tileSize_scale.w = 
     262                  1/(Math.pow(2,(this.zoomlevel_startScale - 
     263                  this.zoomlevel_scale))) * this.tileSize_startScale.w; 
     264                this.tileSize_scale.h = 
     265                  1/(Math.pow(2,(this.zoomlevel_startScale -  
     266                  this.zoomlevel_scale))) * this.tileSize_startScale.h; 
     267 
     268                // set new map resolution 
     269                this.resolution_scale =  
     270                  Math.pow(2,(this.zoomlevel_startScale -  
     271                  this.zoomlevel_scale)) * this.map.getResolution();  
     272 
     273            } 
     274 
     275            // set new scaled tile size  
     276            this.map.scaleTileTo(this.tileSize_scale); 
     277             
     278            // set new scaled map resolution 
     279            this.map.setScaleResolution(this.resolution_scale); 
     280 
    190281        } 
    191282    }, 
    192283     
  • lib/OpenLayers/Map.js

    old new  
    708708            lonlat = this.maxExtent.getCenterLonLat(); 
    709709        } 
    710710         
    711         var zoomChanged = (this.isValidZoomLevel(zoom)) &&  
    712                           (zoom != this.getZoom()); 
     711        var zoomChanged; 
     712        //if zoomlevel not changed -> is at least one overlay active? 
     713        //The active (temporarily invisible) overlays will not 
     714        //reposition after scaling to the _same_ zoomlevel.  
     715        //So, it it is necessary to redraw the grid by calling this  
     716        //setCenter function. 
     717        if (zoom == this.getZoom()) 
     718        { 
     719            for (var i = 0; i < this.layers.length; i++) { 
     720                var layer = this.layers[i]; 
     721                if (!layer.isBaseLayer) { 
     722                    if (layer.getVisibility()) 
     723                        zoomChanged = true; 
     724                } 
     725            } 
     726        } 
     727        else { //zoomlevel changed 
     728            zoomChanged = true; 
     729        } 
     730         
     731        zoomChanged = (this.isValidZoomLevel(zoom) && zoomChanged); 
    713732 
    714733        var centerChanged = (this.isValidLonLat(lonlat)) &&  
    715734                            (!lonlat.equals(this.center)); 
     
    834853        return valid; 
    835854    }, 
    836855 
     856 
     857 
     858    /** finds and sets the tile, which contains the center  
     859     *  of the viewport 
     860     * 
     861     */ 
     862    findCenterTile: function () { 
     863        this.baseLayer.findCenterTile(); 
     864    }, 
     865 
     866    /** scales all tiles to the new size (changes size  
     867     *  and position of every tile) 
     868     *  
     869     * @param {OpenLayers.Size} 
     870     */    
     871    scaleTileTo: function (newTileSize) { 
     872       this.baseLayer.scaleTileTo(newTileSize); 
     873    }, 
     874 
     875    /** sets the map resolution during zooming/scaling 
     876     *  
     877     * @param {float} 
     878     */  
     879    setScaleResolution: function (newResolution) { 
     880        //calculate the current bounds of the new viewport 
     881        var newScaleBounds = this.calculateBounds(this.getCenter(), newResolution); 
     882         
     883        //update the overviewMap 
     884        for (i=0; i<this.controls.length; i++) { 
     885            if (this.controls[i].CLASS_NAME == "OpenLayers.Control.OverviewMap")  
     886                this.controls[i].updateOverview(newResolution, newScaleBounds); 
     887        }           
     888    }, 
     889 
     890 
     891 
    837892  /********************************************************/ 
    838893  /*                                                      */ 
    839894  /*                 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 
     39 
    2640    /** 
    2741     * @constructor 
    2842     *  
     
    139153        } 
    140154    }, 
    141155     
     156 
     157    /** finds and sets the tile, which contains the center  
     158     *  of the viewport 
     159     * 
     160     */ 
     161    findCenterTile:function() { 
     162         
     163        //get the center of the map (viewport) 
     164        var center = this.map.getCenter(); 
     165 
     166        //find tile, which contains the center of the viewport 
     167        this.centerTile = null; 
     168        if (this.grid) { 
     169            for (var iRow=0; iRow < this.grid.length; iRow++) { 
     170                for (var iCol=0; iCol < this.grid[iRow].length; iCol++) { 
     171                    var tileBounds = this.grid[iRow][iCol].bounds; 
     172                    if (tileBounds.containsLonLat(center, true)) { 
     173                        this.centerTile = this.grid[iRow][iCol]; 
     174                        this.centerRow = iRow; 
     175                        this.centerCol = iCol; 
     176                        break;  
     177                    } 
     178                } 
     179                if (this.centerTile) 
     180                    break; 
     181            } 
     182        } 
     183         
     184        //define real position of the center tile before scaling 
     185        //(It is tricky if you pan the map before scaling. Then the 
     186        //layerContainerDiv is only slided and you have to add this 
     187        //difference to the tile position) 
     188        var x = parseInt(this.centerTile.imgDiv.style.left) + 
     189          parseInt(this.map.layerContainerDiv.style.left); 
     190        var y = parseInt(this.centerTile.imgDiv.style.top) + 
     191          parseInt(this.map.layerContainerDiv.style.top); 
     192 
     193        this.centerTileStartScalePos = new OpenLayers.Pixel(x,y); 
     194    }, 
     195 
     196 
     197    /** scales all tiles to the new size (changes size  
     198     *  and position of every tile) 
     199     *  
     200     * @param {OpenLayers.Size} 
     201     */ 
     202    scaleTileTo:function(newTileSize) { 
     203         
     204        //convert the current center of the map in pixel 
     205        var centerPx = this.map.getPixelFromLonLat(this.map.getCenter()); 
     206 
     207        //reposition the center tile  
     208        if (this.centerTile ) { 
     209            //set new left position 
     210            var leftOffset = newTileSize.w / this.centerTile.size.w * 
     211              (centerPx.x - this.centerTileStartScalePos.x); 
     212            leftOffset = Math.round(leftOffset); 
     213            var newLeftPos = centerPx.x - leftOffset 
     214              - parseInt(this.map.layerContainerDiv.style.left); 
     215            this.centerTile.imgDiv.style.left = newLeftPos + "px"; 
     216 
     217            //set new top position 
     218            var topOffset = newTileSize.h / this.centerTile.size.h * 
     219              (centerPx.y - this.centerTileStartScalePos.y); 
     220            topOffset = Math.round(topOffset); 
     221            var newTopPos = centerPx.y - topOffset  
     222              - parseInt(this.map.layerContainerDiv.style.top); 
     223            this.centerTile.imgDiv.style.top = newTopPos + "px"; 
     224        } 
     225         
     226        //reposition and resize all tiles of all active layers 
     227        var baseLayerGrid = this.grid; 
     228        for (var i = 0; i < this.map.layers.length; i++) { 
     229            var layerGrid = this.map.layers[i].grid; 
     230            //go through the whole grid of every layer 
     231            for (var iRow=0; iRow < layerGrid.length; iRow++) { 
     232                for (var iCol=0; iCol < layerGrid[iRow].length; iCol++) {  
     233                    if (layerGrid[iRow][iCol].imgDiv) { 
     234                        //define the factors for rows and columns (relates to the center tile) 
     235                        var deltaRow = iRow - this.centerRow; 
     236                        var deltaCol = iCol - this.centerCol; 
     237                         
     238                        //set new left position 
     239                        var newLeftPos = parseInt(this.centerTile.imgDiv.style.left) 
     240                          + deltaCol * newTileSize.w ; 
     241                        layerGrid[iRow][iCol].imgDiv.style.left = newLeftPos + "px"; 
     242 
     243                        //set new top position 
     244                        var newTopPos = parseInt(this.centerTile.imgDiv.style.top) 
     245                          + deltaRow * newTileSize.h ; 
     246                        layerGrid[iRow][iCol].imgDiv.style.top = newTopPos + "px"; 
     247 
     248                        //set new width and height 
     249                        layerGrid[iRow][iCol].imgDiv.style.width = newTileSize.w + "px"; 
     250                        layerGrid[iRow][iCol].imgDiv.style.height = newTileSize.h + "px"; 
     251                    } 
     252                } 
     253            } 
     254        } 
     255    }, 
     256 
     257 
     258     
    142259    /** 
    143260     * @private 
    144261     *