correct bug where the value stored for the top-left corner of the back buffer may be incorrect, thanks @ahocevar for catching the issue

This commit is contained in:
Éric Lemoine
2011-10-30 23:20:42 +01:00
parent c0d210ef05
commit db08102fe4
+47 -43
View File
@@ -118,15 +118,26 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
backBuffer: null, backBuffer: null,
/** /**
* Property: backBufferData * Property: gridResolution
* {Object} An object containing states necessary for the back buffer. It * {Number} The resolution of the current grid. Used for backbuffering.
* includes two state properties: * This property is updated each the grid is initialized.
* - *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.
*/ */
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 * Constructor: OpenLayers.Layer.Grid
@@ -150,7 +161,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
this.events.addEventType("tileloaded"); this.events.addEventType("tileloaded");
this.grid = []; this.grid = [];
this.backBufferData = {};
this._moveGriddedTiles = OpenLayers.Function.bind( this._moveGriddedTiles = OpenLayers.Function.bind(
this.moveGriddedTiles, this this.moveGriddedTiles, this
@@ -177,9 +187,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
*/ */
destroy: function() { destroy: function() {
this.clearGrid(); this.clearGrid();
// clearGrid should remove any back buffer from the layer,
// so no need to call removeBackBuffer here
this.grid = null; this.grid = null;
this.tileSize = null; this.tileSize = null;
this.backBufferData = null;
OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this, arguments); OpenLayers.Layer.HTTPRequest.prototype.destroy.apply(this, arguments);
}, },
@@ -199,6 +211,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
} }
} }
this.grid = []; 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 // we do not want to copy reference to grid, so we make a new array
obj.grid = []; obj.grid = [];
obj.gridResolution = null;
return obj; return obj;
}, },
@@ -266,9 +280,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
// the server-supported resolution for the new map resolution // the server-supported resolution for the new map resolution
var serverResolution = this.getServerResolution(resolution); var serverResolution = this.getServerResolution(resolution);
// the last resolution of the tiles
var lastResolution = this.backBufferData.resolution;
if (this.singleTile) { if (this.singleTile) {
// We want to redraw whenever even the slightest part of the // 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(); this.removeBackBuffer();
} }
if(!zoomChanged || (lastResolution && if(!zoomChanged || this.transitionEffect === 'resize') {
this.transitionEffect === 'resize')) {
this.applyBackBuffer(serverResolution); this.applyBackBuffer(serverResolution);
} }
@@ -323,8 +333,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
} }
if(forceReTile) { if(forceReTile) {
if(zoomChanged && this.transitionEffect === 'resize' && if(zoomChanged && this.transitionEffect === 'resize') {
lastResolution) {
this.applyBackBuffer(serverResolution); this.applyBackBuffer(serverResolution);
} }
this.initGriddedTiles(bounds); this.initGriddedTiles(bounds);
@@ -432,18 +441,28 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
} }
this.div.insertBefore(backBuffer, this.div.firstChild); this.div.insertBefore(backBuffer, this.div.firstChild);
this.backBuffer = backBuffer; 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; var style = backBuffer.style;
// scale the back buffer // scale the back buffer
var ratio = this.backBufferData.resolution / resolution; var ratio = this.backBufferResolution / resolution;
style.width = 100 * ratio + '%'; style.width = 100 * ratio + '%';
style.height = 100 * ratio + '%'; style.height = 100 * ratio + '%';
// and position it (based on the grid's top-left corner) // and position it (based on the grid's top-left corner)
var position = this.getViewPortPxFromLonLat( var position = this.getViewPortPxFromLonLat(
this.backBufferData.lonlat, resolution); this.backBufferLonLat, resolution);
var leftOffset = parseInt(this.map.layerContainerDiv.style.left, 10); var leftOffset = parseInt(this.map.layerContainerDiv.style.left, 10);
var topOffset = parseInt(this.map.layerContainerDiv.style.top, 10); var topOffset = parseInt(this.map.layerContainerDiv.style.top, 10);
backBuffer.style.left = (position.x - leftOffset) + '%'; backBuffer.style.left = (position.x - leftOffset) + '%';
@@ -452,12 +471,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
/** /**
* Method: createBackBuffer * Method: createBackBuffer
* Create a back buffer. We apply a best effort strategy here - if for any * Create a back buffer.
* reason we cannot clone a tile's markup we give up right away.
* *
* Returns: * Returns:
* {DOMElement} The DOM element for the back buffer, undefined if the * {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() { createBackBuffer: function() {
var backBuffer; var backBuffer;
@@ -493,26 +511,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
if(this.backBuffer && this.backBuffer.parentNode) { if(this.backBuffer && this.backBuffer.parentNode) {
this.div.removeChild(this.backBuffer); this.div.removeChild(this.backBuffer);
this.backBuffer = null; this.backBuffer = null;
} this.backBufferResolution = 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};
} }
}, },
@@ -645,6 +644,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
//remove all but our single tile //remove all but our single tile
this.removeExcessTiles(1,1); 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 //shave off exceess rows and colums
this.removeExcessTiles(rowidx, colidx); this.removeExcessTiles(rowidx, colidx);
// store the resolution of the grid
this.gridResolution = this.getServerResolution();
//now actually draw the tiles //now actually draw the tiles
this.spiralTileLoad(); this.spiralTileLoad();
}, },
@@ -936,7 +941,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
if (this.numLoadingTiles == 0) { if (this.numLoadingTiles == 0) {
this.events.triggerEvent("loadend"); this.events.triggerEvent("loadend");
this.removeBackBuffer(); this.removeBackBuffer();
this.updateBackBufferData();
} }
}; };
tile.events.register("loadend", this, tile.onLoadEnd); tile.events.register("loadend", this, tile.onLoadEnd);