better back buffer code, and support for singleTile
This commit is contained in:
@@ -111,7 +111,17 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
*/
|
||||
timerId: null,
|
||||
|
||||
backBufferData: null,
|
||||
/**
|
||||
* Property: backBuffer
|
||||
* {DOMElement} The back buffer.
|
||||
*/
|
||||
backBuffer: null,
|
||||
|
||||
/**
|
||||
* Property: lastResolution
|
||||
* {Object} The last resolution of the grid.
|
||||
*/
|
||||
lastResolution: null,
|
||||
|
||||
/**
|
||||
* Constructor: OpenLayers.Layer.Grid
|
||||
@@ -135,8 +145,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
this.events.addEventType("tileloaded");
|
||||
|
||||
this.grid = [];
|
||||
this.backBufferData = {};
|
||||
|
||||
|
||||
this._moveGriddedTiles = OpenLayers.Function.bind(
|
||||
this.moveGriddedTiles, this
|
||||
);
|
||||
@@ -219,10 +228,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
return obj;
|
||||
},
|
||||
|
||||
setBackBufferData: function() {
|
||||
this.backBufferData.resolution = this.getServerResolution();
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: moveTo
|
||||
* This function is called whenever the map is moved. All the moving
|
||||
@@ -247,7 +252,13 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
|
||||
// total bounds of the tiles
|
||||
var tilesBounds = this.getTilesBounds();
|
||||
|
||||
|
||||
// the new map resolution
|
||||
var resolution = this.map.getResolution();
|
||||
|
||||
// the server-supported resolution for the new map resolution
|
||||
var serverResolution = this.getServerResolution(resolution);
|
||||
|
||||
if (this.singleTile) {
|
||||
|
||||
// We want to redraw whenever even the slightest part of the
|
||||
@@ -255,6 +266,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
// (thus, we do not specify partial -- its default is false)
|
||||
if ( forceReTile ||
|
||||
(!dragging && !tilesBounds.containsBounds(bounds))) {
|
||||
if(this.lastResolution === serverResolution ||
|
||||
(this.lastResolution &&
|
||||
this.transitionEffect === 'resize')) {
|
||||
this.insertBackBuffer(serverResolution, tilesBounds);
|
||||
}
|
||||
this.initSingleTile(bounds);
|
||||
}
|
||||
} else {
|
||||
@@ -267,10 +283,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
forceReTile = forceReTile ||
|
||||
!tilesBounds.containsBounds(bounds, true);
|
||||
|
||||
var resolution = this.map.getResolution();
|
||||
var serverResolution =
|
||||
this.getServerResolution(resolution);
|
||||
|
||||
if(resolution !== serverResolution) {
|
||||
bounds = this.map.calculateBounds(null, serverResolution);
|
||||
if(forceReTile) {
|
||||
@@ -288,30 +300,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
}
|
||||
|
||||
if(forceReTile) {
|
||||
|
||||
if(OpenLayers.Util.indexOf(
|
||||
this.SUPPORTED_TRANSITIONS,
|
||||
this.transitionEffect) != -1) {
|
||||
if(!this.backBufferData.backBuffer) {
|
||||
this.backBufferData.backBuffer = this.createBackBuffer();
|
||||
if(this.backBufferData.backBuffer) {
|
||||
this.div.insertBefore(this.backBufferData.backBuffer,
|
||||
this.div.firstChild);
|
||||
}
|
||||
}
|
||||
if(this.backBufferData.backBuffer && this.backBufferData.resolution) {
|
||||
var resolution = this.getServerResolution();
|
||||
var scale = this.backBufferData.resolution / resolution;
|
||||
this.backBufferData.backBuffer.style.width = 100 * scale + '%';
|
||||
this.backBufferData.backBuffer.style.height = 100 * scale + '%';
|
||||
var lonLat = {lon: tilesBounds.left, lat: tilesBounds.top},
|
||||
position = this.getViewPortPxFromLonLat(lonLat, resolution);
|
||||
this.backBufferData.backBuffer.style.left = position.x + '%';
|
||||
this.backBufferData.backBuffer.style.top = position.y + '%';
|
||||
}
|
||||
|
||||
if(this.transitionEffect === 'resize' &&
|
||||
(this.lastResolution &&
|
||||
(this.lastResolution !== serverResolution))) {
|
||||
this.insertBackBuffer(serverResolution, tilesBounds);
|
||||
}
|
||||
|
||||
this.initGriddedTiles(bounds);
|
||||
} else {
|
||||
this.scheduleMoveGriddedTiles();
|
||||
@@ -320,31 +313,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
}
|
||||
},
|
||||
|
||||
createBackBuffer: function() {
|
||||
var backBuffer;
|
||||
if(this.grid.length > 0) {
|
||||
var backBuffer = document.createElement('div');
|
||||
backBuffer.id = this.div.id + '_bb';
|
||||
backBuffer.style.position = 'absolute';
|
||||
backBuffer.style.left = '0%';
|
||||
backBuffer.style.top = '0%';
|
||||
backBuffer.style.width = '100%';
|
||||
backBuffer.style.height = '100%';
|
||||
for(var i=0, lenI=this.grid.length; i<lenI; i++) {
|
||||
for(var j=0, lenJ=this.grid[i].length; j<lenJ; j++) {
|
||||
var tile = this.grid[i][j].cloneMarkup();
|
||||
if(!tile) {
|
||||
return;
|
||||
}
|
||||
tile.style.left = (j * this.tileSize.w) + '%';
|
||||
tile.style.top = (i * this.tileSize.h) + '%';
|
||||
backBuffer.appendChild(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
return backBuffer;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: getServerResolution
|
||||
* Return the server-supported resolution that is the closest to
|
||||
@@ -415,7 +383,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
this.div.style.top = y + '%';
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Method: getResolutionScale
|
||||
* Return the value by which the layer is currently scaled.
|
||||
@@ -427,6 +394,75 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
return parseInt(this.div.style.width, 10) / 100;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: insertBackBuffer
|
||||
* Insert a back buffer for a better transition.
|
||||
*
|
||||
* Parameters:
|
||||
* resolution - {Number} The resolution to transition to.
|
||||
* tilesBounds - {<OpenLayers.Bounds>} The current bounds of the tiles.
|
||||
*/
|
||||
insertBackBuffer: function(resolution, tilesBounds) {
|
||||
var backBuffer = this.backBuffer;
|
||||
if(!backBuffer) {
|
||||
backBuffer = this.createBackBuffer();
|
||||
if(!backBuffer) {
|
||||
return;
|
||||
}
|
||||
this.div.insertBefore(backBuffer, this.div.firstChild);
|
||||
this.backBuffer = backBuffer;
|
||||
}
|
||||
|
||||
var style = backBuffer.style;
|
||||
|
||||
// scale
|
||||
var ratio = this.lastResolution / resolution;
|
||||
style.width = 100 * ratio + '%';
|
||||
style.height = 100 * ratio + '%';
|
||||
|
||||
// and position
|
||||
var position = this.getViewPortPxFromLonLat(
|
||||
{lon: tilesBounds.left, lat: tilesBounds.top}, 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) + '%';
|
||||
backBuffer.style.top = (position.y - topOffset) + '%';
|
||||
},
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Returns:
|
||||
* {DOMElement} The DOM element for the back buffer, undefined if the
|
||||
* back buffer couldn't have been created.
|
||||
*/
|
||||
createBackBuffer: function() {
|
||||
var backBuffer;
|
||||
if(this.grid.length > 0) {
|
||||
var backBuffer = document.createElement('div');
|
||||
backBuffer.id = this.div.id + '_bb';
|
||||
backBuffer.style.position = 'absolute';
|
||||
backBuffer.style.width = '100%';
|
||||
backBuffer.style.height = '100%';
|
||||
for(var i=0, lenI=this.grid.length; i<lenI; i++) {
|
||||
for(var j=0, lenJ=this.grid[i].length; j<lenJ; j++) {
|
||||
var tile = this.grid[i][j].cloneMarkup();
|
||||
if(!tile) {
|
||||
return;
|
||||
}
|
||||
// to be able to correctly position the back buffer we
|
||||
// place the first tile at (0, 0) in the back buffer
|
||||
tile.style.left = (j * this.tileSize.w) + '%';
|
||||
tile.style.top = (i * this.tileSize.h) + '%';
|
||||
backBuffer.appendChild(tile);
|
||||
}
|
||||
}
|
||||
}
|
||||
return backBuffer;
|
||||
},
|
||||
|
||||
/**
|
||||
* Method: moveByPx
|
||||
* Move the layer based on pixel vector.
|
||||
@@ -846,11 +882,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
||||
//if that was the last tile, then trigger a 'loadend' on the layer
|
||||
if (this.numLoadingTiles == 0) {
|
||||
this.events.triggerEvent("loadend");
|
||||
if(this.backBufferData.backBuffer) {
|
||||
this.div.removeChild(this.backBufferData.backBuffer);
|
||||
this.backBufferData.backBuffer = null;
|
||||
if(this.backBuffer && this.backBuffer.parentNode) {
|
||||
this.div.removeChild(this.backBuffer);
|
||||
this.backBuffer = null;
|
||||
}
|
||||
this.setBackBufferData();
|
||||
this.lastResolution = this.getServerResolution();
|
||||
}
|
||||
};
|
||||
tile.events.register("loadend", this, tile.onLoadEnd);
|
||||
|
||||
Reference in New Issue
Block a user