better back buffer code, and support for singleTile
This commit is contained in:
+101
-65
@@ -111,7 +111,17 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
*/
|
*/
|
||||||
timerId: null,
|
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
|
* Constructor: OpenLayers.Layer.Grid
|
||||||
@@ -135,8 +145,7 @@ 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
|
||||||
);
|
);
|
||||||
@@ -219,10 +228,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
return obj;
|
return obj;
|
||||||
},
|
},
|
||||||
|
|
||||||
setBackBufferData: function() {
|
|
||||||
this.backBufferData.resolution = this.getServerResolution();
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method: moveTo
|
* Method: moveTo
|
||||||
* This function is called whenever the map is moved. All the moving
|
* 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
|
// total bounds of the tiles
|
||||||
var tilesBounds = this.getTilesBounds();
|
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) {
|
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
|
||||||
@@ -255,6 +266,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
// (thus, we do not specify partial -- its default is false)
|
// (thus, we do not specify partial -- its default is false)
|
||||||
if ( forceReTile ||
|
if ( forceReTile ||
|
||||||
(!dragging && !tilesBounds.containsBounds(bounds))) {
|
(!dragging && !tilesBounds.containsBounds(bounds))) {
|
||||||
|
if(this.lastResolution === serverResolution ||
|
||||||
|
(this.lastResolution &&
|
||||||
|
this.transitionEffect === 'resize')) {
|
||||||
|
this.insertBackBuffer(serverResolution, tilesBounds);
|
||||||
|
}
|
||||||
this.initSingleTile(bounds);
|
this.initSingleTile(bounds);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -267,10 +283,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
forceReTile = forceReTile ||
|
forceReTile = forceReTile ||
|
||||||
!tilesBounds.containsBounds(bounds, true);
|
!tilesBounds.containsBounds(bounds, true);
|
||||||
|
|
||||||
var resolution = this.map.getResolution();
|
|
||||||
var serverResolution =
|
|
||||||
this.getServerResolution(resolution);
|
|
||||||
|
|
||||||
if(resolution !== serverResolution) {
|
if(resolution !== serverResolution) {
|
||||||
bounds = this.map.calculateBounds(null, serverResolution);
|
bounds = this.map.calculateBounds(null, serverResolution);
|
||||||
if(forceReTile) {
|
if(forceReTile) {
|
||||||
@@ -288,30 +300,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(forceReTile) {
|
if(forceReTile) {
|
||||||
|
if(this.transitionEffect === 'resize' &&
|
||||||
if(OpenLayers.Util.indexOf(
|
(this.lastResolution &&
|
||||||
this.SUPPORTED_TRANSITIONS,
|
(this.lastResolution !== serverResolution))) {
|
||||||
this.transitionEffect) != -1) {
|
this.insertBackBuffer(serverResolution, tilesBounds);
|
||||||
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 + '%';
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initGriddedTiles(bounds);
|
this.initGriddedTiles(bounds);
|
||||||
} else {
|
} else {
|
||||||
this.scheduleMoveGriddedTiles();
|
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
|
* Method: getServerResolution
|
||||||
* Return the server-supported resolution that is the closest to
|
* 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 + '%';
|
this.div.style.top = y + '%';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method: getResolutionScale
|
* Method: getResolutionScale
|
||||||
* Return the value by which the layer is currently scaled.
|
* 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;
|
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
|
* Method: moveByPx
|
||||||
* Move the layer based on pixel vector.
|
* 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 that was the last tile, then trigger a 'loadend' on the layer
|
||||||
if (this.numLoadingTiles == 0) {
|
if (this.numLoadingTiles == 0) {
|
||||||
this.events.triggerEvent("loadend");
|
this.events.triggerEvent("loadend");
|
||||||
if(this.backBufferData.backBuffer) {
|
if(this.backBuffer && this.backBuffer.parentNode) {
|
||||||
this.div.removeChild(this.backBufferData.backBuffer);
|
this.div.removeChild(this.backBuffer);
|
||||||
this.backBufferData.backBuffer = null;
|
this.backBuffer = null;
|
||||||
}
|
}
|
||||||
this.setBackBufferData();
|
this.lastResolution = this.getServerResolution();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tile.events.register("loadend", this, tile.onLoadEnd);
|
tile.events.register("loadend", this, tile.onLoadEnd);
|
||||||
|
|||||||
Reference in New Issue
Block a user