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 383 383 (resRatio <= this.maxRatio) && 384 384 (this.ovmap.getExtent().containsBounds(testExtent))); 385 385 }, 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(); 389 400 var targetRes = this.ovmap.getResolution(); 390 401 var resRatio = targetRes / mapRes; 391 402 if(resRatio > this.maxRatio) { … … 397 408 } 398 409 this.ovmap.setCenter(this.map.center, 399 410 this.ovmap.getZoomForResolution(targetRes)); 400 this.updateRectToMap( );411 this.updateRectToMap(bounds); 401 412 }, 402 413 403 414 createMap: function() { … … 421 432 }, 422 433 423 434 /** 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 425 440 */ 426 updateRectToMap: function( ) {441 updateRectToMap: function(bounds) { 427 442 // The base layer for overview map needs to be in the same projection 428 443 // as the base layer for the main map. This should be made more robust. 429 444 if(this.map.units != 'degrees') { … … 431 446 alert('The overview map only works when it is in the same projection as the main map'); 432 447 } 433 448 } 434 var pxBounds = this.getRectBoundsFromMapBounds(this.map.getExtent()); 449 450 if (!bounds) 451 bounds=this.map.getExtent(); 452 var pxBounds = this.getRectBoundsFromMapBounds(bounds); 435 453 this.setRectPxBounds(pxBounds); 436 454 }, 437 455 -
lib/OpenLayers/Control/PanZoomBar.js
old new 23 23 /** @type int */ 24 24 zoomStopHeight: 11, 25 25 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 26 41 initialize: function() { 27 42 OpenLayers.Control.PanZoom.prototype.initialize.apply(this, arguments); 28 43 this.position = new OpenLayers.Pixel(OpenLayers.Control.PanZoomBar.X, 29 44 OpenLayers.Control.PanZoomBar.Y); 45 this.tileSize_scale = new OpenLayers.Size(); 30 46 }, 31 47 32 48 /** … … 168 184 this.zoomStart = evt.xy.clone(); 169 185 this.div.style.cursor = "move"; 170 186 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 } 171 202 }, 172 203 173 204 /* … … 187 218 } 188 219 this.mouseDragStart = evt.xy.clone(); 189 220 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 } 190 281 } 191 282 }, 192 283 … … 206 297 this.moveZoomBar(); 207 298 this.mouseDragStart = null; 208 299 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 } 209 306 } 210 307 }, 211 308 -
lib/OpenLayers/Map.js
old new 300 300 if (this.baseLayer == null) { 301 301 // set the first baselaye we add as the baselayer 302 302 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 303 309 } else { 304 310 layer.setVisibility(false); 305 311 } … … 708 714 lonlat = this.maxExtent.getCenterLonLat(); 709 715 } 710 716 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); 713 738 714 739 var centerChanged = (this.isValidLonLat(lonlat)) && 715 740 (!lonlat.equals(this.center)); … … 834 859 return valid; 835 860 }, 836 861 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 837 880 /********************************************************/ 838 881 /* */ 839 882 /* Layer Options */ -
lib/OpenLayers/Layer/Grid.js
old new 23 23 /** @type Integer */ 24 24 buffer: 2, 25 25 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 26 42 /** 27 43 * @constructor 28 44 * … … 139 155 } 140 156 }, 141 157 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 142 227 /** 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 /** 143 392 * @private 144 393 * 145 394 * @returns A Bounds object representing the bounds of all the currently
