From db08102fe4ed38895b3b9ba2285ca5500b65fa55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89ric=20Lemoine?= Date: Sun, 30 Oct 2011 23:20:42 +0100 Subject: [PATCH] correct bug where the value stored for the top-left corner of the back buffer may be incorrect, thanks @ahocevar for catching the issue --- lib/OpenLayers/Layer/Grid.js | 90 +++++++++++++++++++----------------- 1 file changed, 47 insertions(+), 43 deletions(-) diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 22075ad44a..ce6332a3c9 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -118,15 +118,26 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { backBuffer: null, /** - * Property: backBufferData - * {Object} An object containing states necessary for the back buffer. It - * includes two state properties: - * - *resolution* the last resolution of the tiles. Used as the "from - * resolution" when transitioning. - * - *lonlat* the geographic coordinates of the tiles grid's top-left - * corner. + * Property: gridResolution + * {Number} The resolution of the current grid. Used for backbuffering. + * This property is updated each the grid is initialized. */ - backBufferData: null, + gridResolution: null, + + /** + * Property: backBufferResolution + * {Number} The resolution of the current back buffer. This property is + * updated each time a back buffer is created. + */ + backBufferResolution: null, + + /** + * Property: backBufferLonLat + * {Object} The top-left corner of the current back buffer. Includes lon + * and lat properties. This object is updated each time a back buffer + * is created. + */ + backBufferLonLat: null, /** * Constructor: OpenLayers.Layer.Grid @@ -150,7 +161,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { this.events.addEventType("tileloaded"); this.grid = []; - this.backBufferData = {}; this._moveGriddedTiles = OpenLayers.Function.bind( this.moveGriddedTiles, this @@ -177,9 +187,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { */ destroy: function() { this.clearGrid(); + // clearGrid should remove any back buffer from the layer, + // so no need to call removeBackBuffer here + this.grid = null; this.tileSize = null; - this.backBufferData = null; OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this, arguments); }, @@ -199,6 +211,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { } } this.grid = []; + this.gridResolution = null; } }, @@ -231,6 +244,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { // we do not want to copy reference to grid, so we make a new array obj.grid = []; + obj.gridResolution = null; return obj; }, @@ -266,9 +280,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { // the server-supported resolution for the new map resolution var serverResolution = this.getServerResolution(resolution); - // the last resolution of the tiles - var lastResolution = this.backBufferData.resolution; - if (this.singleTile) { // We want to redraw whenever even the slightest part of the @@ -289,8 +300,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { this.removeBackBuffer(); } - if(!zoomChanged || (lastResolution && - this.transitionEffect === 'resize')) { + if(!zoomChanged || this.transitionEffect === 'resize') { this.applyBackBuffer(serverResolution); } @@ -323,8 +333,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { } if(forceReTile) { - if(zoomChanged && this.transitionEffect === 'resize' && - lastResolution) { + if(zoomChanged && this.transitionEffect === 'resize') { this.applyBackBuffer(serverResolution); } this.initGriddedTiles(bounds); @@ -432,18 +441,28 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { } this.div.insertBefore(backBuffer, this.div.firstChild); this.backBuffer = backBuffer; + + // set some information in the instance for subsequent + // calls to applyBackBuffer where the same back buffer + // is reused + var topLeftTileBounds = this.grid[0][0].bounds; + this.backBufferLonLat = { + lon: topLeftTileBounds.left, + lat: topLeftTileBounds.top + }; + this.backBufferResolution = this.gridResolution; } var style = backBuffer.style; // scale the back buffer - var ratio = this.backBufferData.resolution / resolution; + var ratio = this.backBufferResolution / resolution; style.width = 100 * ratio + '%'; style.height = 100 * ratio + '%'; // and position it (based on the grid's top-left corner) var position = this.getViewPortPxFromLonLat( - this.backBufferData.lonlat, resolution); + this.backBufferLonLat, resolution); var leftOffset = parseInt(this.map.layerContainerDiv.style.left, 10); var topOffset = parseInt(this.map.layerContainerDiv.style.top, 10); backBuffer.style.left = (position.x - leftOffset) + '%'; @@ -452,12 +471,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { /** * Method: createBackBuffer - * Create a back buffer. We apply a best effort strategy here - if for any - * reason we cannot clone a tile's markup we give up right away. + * Create a back buffer. * * Returns: * {DOMElement} The DOM element for the back buffer, undefined if the - * back buffer couldn't have been created. + * grid isn't initialized yet. */ createBackBuffer: function() { var backBuffer; @@ -493,26 +511,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { if(this.backBuffer && this.backBuffer.parentNode) { this.div.removeChild(this.backBuffer); this.backBuffer = null; - } - }, - - /** - * Method: updateBackBufferData - * Upstate states in the backBufferData property - */ - updateBackBufferData: function() { - // updateBackBufferData is called asynchronously when tiles are - // received, so we need to check that the map is still there - if(this.map) { - var resolution = this.map.getResolution(); - this.backBufferData.resolution = this.getServerResolution(resolution); - } - // the top left tile might have been destroyed, so its bounds - // property may be null - var topLeftTile = this.grid[0][0]; - if(topLeftTile.bounds) { - this.backBufferData.lonlat = {lon: topLeftTile.bounds.left, - lat: topLeftTile.bounds.top}; + this.backBufferResolution = null; } }, @@ -645,6 +644,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { //remove all but our single tile this.removeExcessTiles(1,1); + + // store the resolution of the grid + this.gridResolution = this.getServerResolution(); }, /** @@ -805,6 +807,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { //shave off exceess rows and colums this.removeExcessTiles(rowidx, colidx); + // store the resolution of the grid + this.gridResolution = this.getServerResolution(); + //now actually draw the tiles this.spiralTileLoad(); }, @@ -936,7 +941,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, { if (this.numLoadingTiles == 0) { this.events.triggerEvent("loadend"); this.removeBackBuffer(); - this.updateBackBufferData(); } }; tile.events.register("loadend", this, tile.onLoadEnd);