No more percentage based positioning.

Client zoom now supports both over- and undersampling.
This commit is contained in:
ahocevar
2012-06-10 16:53:56 +02:00
parent 405cebd482
commit f0ad48597f
12 changed files with 202 additions and 331 deletions

View File

@@ -22,12 +22,6 @@ OpenLayers.Control.PinchZoom = OpenLayers.Class(OpenLayers.Control, {
*/
type: OpenLayers.Control.TYPE_TOOL,
/**
* Property: containerCenter
* {Object} Cached object representing the layer container center (in pixels).
*/
containerCenter: null,
/**
* Property: pinchOrigin
* {Object} Cached object representing the pinch start (in pixels).
@@ -70,57 +64,6 @@ OpenLayers.Control.PinchZoom = OpenLayers.Class(OpenLayers.Control, {
}, this.handlerOptions);
},
/**
* APIMethod: activate
* Activate this control. Must be called after the control is added to a
* map.
*
* Returns:
* {Boolean} The control was successfully activated.
*/
activate: function() {
var activated = OpenLayers.Control.prototype.activate.apply(this,arguments);
if (activated) {
this.map.events.on({
moveend: this.updateContainerCenter,
scope: this
});
this.updateContainerCenter();
}
return activated;
},
/**
* APIMethod: deactivate
* Deactivate this control.
*
* Returns:
* {Boolean} The control was successfully deactivated.
*/
deactivate: function() {
var deactivated = OpenLayers.Control.prototype.deactivate.apply(this,arguments);
if (this.map && this.map.events) {
this.map.events.un({
moveend: this.updateContainerCenter,
scope: this
});
}
return deactivated;
},
/**
* Method: updateContainerCenter
* Must be called each time the layer container moves.
*/
updateContainerCenter: function() {
var container = this.map.layerContainerDiv;
// the layer container div is a square of 100px/100px
this.containerCenter = {
x: parseInt(container.style.left, 10) + 50,
y: parseInt(container.style.top, 10) + 50
};
},
/**
* Method: pinchStart
*
@@ -144,12 +87,12 @@ OpenLayers.Control.PinchZoom = OpenLayers.Class(OpenLayers.Control, {
*/
pinchMove: function(evt, pinchData) {
var scale = pinchData.scale;
var containerCenter = this.containerCenter;
var containerOrigin = this.map.layerContainerOriginPx;
var pinchOrigin = this.pinchOrigin;
var current = evt.xy;
var dx = Math.round((current.x - pinchOrigin.x) + (scale - 1) * (containerCenter.x - pinchOrigin.x));
var dy = Math.round((current.y - pinchOrigin.y) + (scale - 1) * (containerCenter.y - pinchOrigin.y));
var dx = Math.round((current.x - pinchOrigin.x) + (scale - 1) * (containerOrigin.x - pinchOrigin.x));
var dy = Math.round((current.y - pinchOrigin.y) + (scale - 1) * (containerOrigin.y - pinchOrigin.y));
this.applyTransform(
"translate(" + dx + "px, " + dy + "px) scale(" + scale + ")"

View File

@@ -168,8 +168,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
/**
* Property: gridResolution
* {Number} The resolution of the current grid. Used for backbuffering.
* This property is updated each the grid is initialized.
* {Number} The resolution of the current grid. Used for backbuffer and
* client zoom. This property is updated every time the grid is
* initialized.
*/
gridResolution: null,
@@ -458,7 +459,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
}
if(!zoomChanged || this.transitionEffect === 'resize') {
this.applyBackBuffer(serverResolution);
this.applyBackBuffer(resolution);
}
this.initSingleTile(bounds);
@@ -477,25 +478,9 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
this.map.getMaxExtent()
});
if(resolution !== serverResolution) {
bounds = this.map.calculateBounds(null, serverResolution);
if(forceReTile) {
// stretch the layer div
var scale = serverResolution / resolution;
this.transformDiv(scale);
}
} else {
// reset the layer width, height, left, top, to deal with
// the case where the layer was previously transformed
this.div.style.width = '100%';
this.div.style.height = '100%';
this.div.style.left = '0%';
this.div.style.top = '0%';
}
if(forceReTile) {
if(zoomChanged && this.transitionEffect === 'resize') {
this.applyBackBuffer(serverResolution);
this.applyBackBuffer(resolution);
}
this.initGriddedTiles(bounds);
} else {
@@ -620,7 +605,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
/**
* Method: getServerResolution
* Return the closest highest server-supported resolution. Throw an
* Return the closest server-supported resolution. Throw an
* exception if none is found in the serverResolutions array.
*
* Parameters:
@@ -628,23 +613,24 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* map resolution is used.
*
* Returns:
* {Number} The closest highest server resolution value.
* {Number} The closest server resolution value.
*/
getServerResolution: function(resolution) {
var distance = Number.POSITIVE_INFINITY;
resolution = resolution || this.map.getResolution();
if(this.serverResolutions &&
OpenLayers.Util.indexOf(this.serverResolutions, resolution) === -1) {
var i, serverResolution;
var i, newDistance, newResolution, serverResolution;
for(i=this.serverResolutions.length-1; i>= 0; i--) {
serverResolution = this.serverResolutions[i];
if(serverResolution > resolution) {
resolution = serverResolution;
newResolution = this.serverResolutions[i];
newDistance = Math.abs(newResolution - resolution);
if (newDistance > distance) {
break;
}
distance = newDistance;
serverResolution = newResolution;
}
if(i === -1) {
throw 'no appropriate resolution in serverResolutions';
}
resolution = serverResolution;
}
return resolution;
},
@@ -665,33 +651,6 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
this.map.getZoomForResolution(resolution) + (this.zoomOffset || 0);
},
/**
* Method: transformDiv
* Transform the layer div.
*
* Parameters:
* scale - {Number} The value by which the layer div is to
* be scaled.
*/
transformDiv: function(scale) {
// scale the layer div
this.div.style.width = 100 * scale + '%';
this.div.style.height = 100 * scale + '%';
// and translate the layer div as necessary
var size = this.map.getSize();
var lcX = parseInt(this.map.layerContainerDiv.style.left, 10);
var lcY = parseInt(this.map.layerContainerDiv.style.top, 10);
var x = (lcX - (size.w / 2.0)) * (scale - 1);
var y = (lcY - (size.h / 2.0)) * (scale - 1);
this.div.style.left = x + '%';
this.div.style.top = y + '%';
},
/**
* Method: getResolutionScale
* Return the value by which the layer is currently scaled.
@@ -733,21 +692,26 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
};
this.backBufferResolution = this.gridResolution;
}
var style = backBuffer.style;
// scale the back buffer
var ratio = this.backBufferResolution / resolution;
style.width = 100 * ratio + '%';
style.height = 100 * ratio + '%';
// scale the tiles inside the back buffer
var tiles = backBuffer.childNodes, tile;
for (var i=tiles.length-1; i>=0; --i) {
tile = tiles[i];
tile.style.top = ((ratio * tile._i * tile._h) | 0) + 'px';
tile.style.left = ((ratio * tile._j * tile._w) | 0) + 'px';
tile.style.width = Math.round(ratio * tile._w) + 'px';
tile.style.height = Math.round(ratio * tile._h) + 'px';
}
// and position it (based on the grid's top-left corner)
var position = this.getViewPortPxFromLonLat(
this.backBufferLonLat, resolution);
var leftOffset = parseInt(this.map.layerContainerDiv.style.left, 10);
var topOffset = parseInt(this.map.layerContainerDiv.style.top, 10);
backBuffer.style.left = Math.round(position.x - leftOffset) + '%';
backBuffer.style.top = Math.round(position.y - topOffset) + '%';
var leftOffset = this.map.layerContainerOriginPx.x;
var topOffset = this.map.layerContainerOriginPx.y;
backBuffer.style.left = Math.round(position.x - leftOffset) + 'px';
backBuffer.style.top = Math.round(position.y - topOffset) + 'px';
},
/**
@@ -765,19 +729,17 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
backBuffer.id = this.div.id + '_bb';
backBuffer.className = 'olBackBuffer';
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].createBackBuffer();
if(!tile) {
continue;
var tile = this.grid[i][j],
markup = this.grid[i][j].createBackBuffer();
if (markup) {
markup._i = i;
markup._j = j;
markup._w = tile.size.w;
markup._h = tile.size.h;
backBuffer.appendChild(markup);
}
// to be able to correctly position the back buffer we
// place the tiles grid at (0, 0) in the back buffer
tile.style.top = (i * this.tileSize.h) + '%';
tile.style.left = (j * this.tileSize.w) + '%';
backBuffer.appendChild(tile);
}
}
}
@@ -923,16 +885,22 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
var tilelon = resolution * this.tileSize.w;
var tilelat = resolution * this.tileSize.h;
var ratio = resolution / this.map.getResolution(),
tileSize = {
w: Math.round(this.tileSize.w * ratio),
h: Math.round(this.tileSize.h * ratio)
};
var offsetlon = bounds.left - origin.lon;
var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;
var tilecolremain = offsetlon/tilelon - tilecol;
var tileoffsetx = -tilecolremain * this.tileSize.w;
var tileoffsetx = -tilecolremain * tileSize.w;
var tileoffsetlon = origin.lon + tilecol * tilelon;
var offsetlat = bounds.top - (origin.lat + tilelat);
var tilerow = Math.ceil(offsetlat/tilelat) + this.buffer;
var tilerowremain = tilerow - offsetlat/tilelat;
var tileoffsety = -tilerowremain * this.tileSize.h;
var tileoffsety = -tilerowremain * tileSize.h;
var tileoffsetlat = origin.lat + tilerow * tilelat;
return {
@@ -982,19 +950,25 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
// tiles required to cover the viewport plus at least one for panning
var viewSize = this.map.getSize();
var minRows = Math.ceil(viewSize.h/this.tileSize.h) +
2 * this.buffer + 1;
var minCols = Math.ceil(viewSize.w/this.tileSize.w) +
2 * this.buffer + 1;
var origin = this.getTileOrigin();
var resolution = this.getServerResolution();
var tileLayout = this.calculateGridLayout(bounds, origin, resolution);
var resolution = this.map.getResolution(),
serverResolution = this.getServerResolution(),
ratio = resolution / serverResolution,
tileSize = {
w: this.tileSize.w / ratio,
h: this.tileSize.h / ratio
};
var minRows = Math.ceil(viewSize.h/tileSize.h) +
2 * this.buffer + 1;
var minCols = Math.ceil(viewSize.w/tileSize.w) +
2 * this.buffer + 1;
var tileLayout = this.calculateGridLayout(bounds, origin, serverResolution);
var tileoffsetx = Math.round(tileLayout.tileoffsetx); // heaven help us
var tileoffsety = Math.round(tileLayout.tileoffsety);
var tileoffsetlon = tileLayout.tileoffsetlon;
var tileoffsetlat = tileLayout.tileoffsetlat;
@@ -1006,8 +980,8 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
var rowidx = 0;
var layerContainerDivLeft = parseInt(this.map.layerContainerDiv.style.left);
var layerContainerDivTop = parseInt(this.map.layerContainerDiv.style.top);
var layerContainerDivLeft = this.map.layerContainerOriginPx.x;
var layerContainerDivTop = this.map.layerContainerOriginPx.y;
var tileData = [], center = this.map.getCenter();
do {
@@ -1051,27 +1025,29 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
});
tileoffsetlon += tilelon;
tileoffsetx += this.tileSize.w;
tileoffsetx += tileSize.w;
} while ((tileoffsetlon <= bounds.right + tilelon * this.buffer)
|| colidx < minCols);
tileoffsetlat -= tilelat;
tileoffsety += this.tileSize.h;
tileoffsety += tileSize.h;
} while((tileoffsetlat >= bounds.bottom - tilelat * this.buffer)
|| rowidx < minRows);
//shave off exceess rows and colums
this.removeExcessTiles(rowidx, colidx);
var resolution = this.getServerResolution(),
immediately = resolution === this.gridResolution;
// store the resolution of the grid
this.gridResolution = this.getServerResolution();
this.gridResolution = resolution;
//now actually draw the tiles
tileData.sort(function(a, b) {
return a.distance - b.distance;
});
for (var i=0, ii=tileData.length; i<ii; ++i) {
tileData[i].tile.draw();
tileData[i].tile.draw(immediately);
}
},
@@ -1194,28 +1170,27 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
return;
}
var buffer = this.buffer + 1;
var scale = this.getResolutionScale();
while(true) {
var tlTile = this.grid[0][0];
var tlViewPort = {
x: (this.grid[0][0].position.x * scale) +
parseInt(this.div.style.left, 10) +
parseInt(this.map.layerContainerDiv.style.left),
y: (this.grid[0][0].position.y * scale) +
parseInt(this.div.style.top, 10) +
parseInt(this.map.layerContainerDiv.style.top)
x: tlTile.position.x +
this.map.layerContainerOriginPx.x,
y: tlTile.position.y +
this.map.layerContainerOriginPx.y
};
var ratio = this.getServerResolution() / this.map.getResolution();
var tileSize = {
w: this.tileSize.w * scale,
h: this.tileSize.h * scale
w: Math.round(this.tileSize.w * ratio),
h: Math.round(this.tileSize.h * ratio)
};
if (tlViewPort.x > -tileSize.w * (buffer - 1)) {
this.shiftColumn(true);
this.shiftColumn(true, tileSize);
} else if (tlViewPort.x < -tileSize.w * buffer) {
this.shiftColumn(false);
this.shiftColumn(false, tileSize);
} else if (tlViewPort.y > -tileSize.h * (buffer - 1)) {
this.shiftRow(true);
this.shiftRow(true, tileSize);
} else if (tlViewPort.y < -tileSize.h * buffer) {
this.shiftRow(false);
this.shiftRow(false, tileSize);
} else {
break;
}
@@ -1229,15 +1204,15 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* Parameters:
* prepend - {Boolean} if true, prepend to beginning.
* if false, then append to end
* tileSize - {<OpenLayers.Size>} rendered tile size
*/
shiftRow:function(prepend) {
shiftRow:function(prepend, tileSize) {
var modelRowIndex = (prepend) ? 0 : (this.grid.length - 1);
var grid = this.grid;
var modelRow = grid[modelRowIndex];
var resolution = this.getServerResolution();
var deltaY = (prepend) ? -this.tileSize.h : this.tileSize.h;
var deltaLat = resolution * -deltaY;
var sign = prepend ? -1 : 1;
var deltaLat = this.getServerResolution() * -sign * this.tileSize.h;
var row = (prepend) ? grid.pop() : grid.shift();
@@ -1247,7 +1222,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
var position = modelTile.position.clone();
bounds.bottom = bounds.bottom + deltaLat;
bounds.top = bounds.top + deltaLat;
position.y = position.y + deltaY;
position.y = position.y + sign * tileSize.h;
row[i].moveTo(bounds, position);
}
@@ -1265,11 +1240,11 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* Parameters:
* prepend - {Boolean} if true, prepend to beginning.
* if false, then append to end
* tileSize - {<OpenLayers.Size>} rendered tile size
*/
shiftColumn: function(prepend) {
var deltaX = (prepend) ? -this.tileSize.w : this.tileSize.w;
var resolution = this.getServerResolution();
var deltaLon = resolution * deltaX;
shiftColumn: function(prepend, tileSize) {
var sign = prepend ? -1 : 1;
var deltaLon = this.getServerResolution() * sign * this.tileSize.w;
for (var i=0, len=this.grid.length; i<len; i++) {
var row = this.grid[i];
@@ -1280,7 +1255,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
var position = modelTile.position.clone();
bounds.left = bounds.left + deltaLon;
bounds.right = bounds.right + deltaLon;
position.x = position.x + deltaX;
position.x = position.x + sign * tileSize.w;
var tile = prepend ? this.grid[i].pop() : this.grid[i].shift();
tile.moveTo(bounds, position);

View File

@@ -482,9 +482,9 @@ OpenLayers.Layer.Vector = OpenLayers.Class(OpenLayers.Layer, {
viewHeight = viewSize.h,
offsetLeft = (viewWidth / 2 * this.ratio) - viewWidth / 2,
offsetTop = (viewHeight / 2 * this.ratio) - viewHeight / 2;
offsetLeft += parseInt(this.map.layerContainerDiv.style.left, 10);
offsetLeft += this.map.layerContainerOriginPx.x;
offsetLeft = -Math.round(offsetLeft);
offsetTop += parseInt(this.map.layerContainerDiv.style.top, 10);
offsetTop += this.map.layerContainerOriginPx.y;
offsetTop = -Math.round(offsetTop);
this.div.style.left = offsetLeft + 'px';

View File

@@ -423,6 +423,12 @@ OpenLayers.Map = OpenLayers.Class({
*/
paddingForPopups : null,
/**
* Property: layerContainerOriginPx
* {Object} Cached object representing the layer container origin (in pixels).
*/
layerContainerOriginPx: null,
/**
* Property: minPx
* {Object} An object with a 'x' and 'y' values that is the lower
@@ -575,9 +581,8 @@ OpenLayers.Map = OpenLayers.Class({
// the layerContainerDiv is the one that holds all the layers
id = this.id + "_OpenLayers_Container";
this.layerContainerDiv = OpenLayers.Util.createDiv(id);
this.layerContainerDiv.style.width = '100px';
this.layerContainerDiv.style.height = '100px';
this.layerContainerDiv.style.zIndex=this.Z_INDEX_BASE['Popup']-1;
this.layerContainerOriginPx = {x: 0, y: 0};
this.viewPortDiv.appendChild(this.layerContainerDiv);
@@ -1752,13 +1757,13 @@ OpenLayers.Map = OpenLayers.Class({
this.center = null;
if (dx) {
this.layerContainerDiv.style.left =
parseInt(this.layerContainerDiv.style.left) - dx + "px";
(this.layerContainerOriginPx.x -= dx) + "px";
this.minPx.x -= dx;
this.maxPx.x -= dx;
}
if (dy) {
this.layerContainerDiv.style.top =
parseInt(this.layerContainerDiv.style.top) - dy + "px";
(this.layerContainerOriginPx.y -= dy) + "px";
this.minPx.y -= dy;
this.maxPx.y -= dy;
}
@@ -1919,8 +1924,11 @@ OpenLayers.Map = OpenLayers.Class({
// (re)set the layerContainerDiv's location
if (zoomChanged || this.layerContainerOrigin == null) {
this.layerContainerOrigin = this.getCachedCenter();
this.layerContainerDiv.style.left = "0px";
this.layerContainerDiv.style.top = "0px";
var style = this.layerContainerDiv.style;
style.left = "0px";
style.top = "0px";
this.layerContainerOriginPx.x = 0;
this.layerContainerOriginPx.y = 0;
var maxExtent = this.getMaxExtent({restricted: true});
var maxExtentCenter = maxExtent.getCenterLonLat();
var lonDelta = this.center.lon - maxExtentCenter.lon;
@@ -2006,12 +2014,14 @@ OpenLayers.Map = OpenLayers.Class({
var newPx = this.getViewPortPxFromLonLat(lonlat);
if ((originPx != null) && (newPx != null)) {
var oldLeft = parseInt(this.layerContainerDiv.style.left);
var oldTop = parseInt(this.layerContainerDiv.style.top);
var oldLeft = this.layerContainerOriginPx.x;
var oldTop = this.layerContainerOriginPx.y;
var newLeft = Math.round(originPx.x - newPx.x);
var newTop = Math.round(originPx.y - newPx.y);
this.layerContainerDiv.style.left = newLeft + "px";
this.layerContainerDiv.style.top = newTop + "px";
this.layerContainerDiv.style.left =
(this.layerContainerOriginPx.x = newLeft) + "px";
this.layerContainerDiv.style.top =
(this.layerContainerOriginPx.y = newTop) + "px";
var dx = oldLeft - newLeft;
var dy = oldTop - newTop;
this.minPx.x -= dx;
@@ -2572,8 +2582,8 @@ OpenLayers.Map = OpenLayers.Class({
getViewPortPxFromLayerPx:function(layerPx) {
var viewPortPx = null;
if (layerPx != null) {
var dX = parseInt(this.layerContainerDiv.style.left);
var dY = parseInt(this.layerContainerDiv.style.top);
var dX = this.layerContainerOriginPx.x;
var dY = this.layerContainerOriginPx.y;
viewPortPx = layerPx.add(dX, dY);
}
return viewPortPx;
@@ -2592,8 +2602,8 @@ OpenLayers.Map = OpenLayers.Class({
getLayerPxFromViewPortPx:function(viewPortPx) {
var layerPx = null;
if (viewPortPx != null) {
var dX = -parseInt(this.layerContainerDiv.style.left);
var dY = -parseInt(this.layerContainerDiv.style.top);
var dX = -this.layerContainerOriginPx.x;
var dY = -this.layerContainerOriginPx.y;
layerPx = viewPortPx.add(dX, dY);
if (isNaN(layerPx.x) || isNaN(layerPx.y)) {
layerPx = null;

View File

@@ -193,21 +193,21 @@ OpenLayers.Tile = OpenLayers.Class({
* is to call <clear> and return the result from <shouldDraw>.
*
* Parameters:
* deferred - {Boolean} When drawing was aborted by returning false from a
* *beforedraw* listener, the queue manager needs to pass true, so the
* tile will not be cleared and immediately be drawn. Otherwise, the
* tile will be cleared and a *beforedraw* event will be fired.
* immediately - {Boolean} When e.g. drawing was aborted by returning false
* from a *beforedraw* listener, the queue manager needs to pass true,
* so the tile will not be cleared and immediately be drawn. Otherwise,
* the tile will be cleared and a *beforedraw* event will be fired.
*
* Returns:
* {Boolean} Whether or not the tile should actually be drawn.
*/
draw: function(deferred) {
if (!deferred) {
draw: function(immediately) {
if (!immediately) {
//clear tile's contents and mark as not drawn
this.clear();
}
var draw = this.shouldDraw();
if (draw && !deferred) {
if (draw && !immediately) {
draw = this.events.triggerEvent("beforedraw") !== false;
}
return draw;

View File

@@ -212,11 +212,15 @@ OpenLayers.Tile.Image = OpenLayers.Class(OpenLayers.Tile, {
positionTile: function() {
var style = this.getTile().style,
size = this.frame ? this.size :
this.layer.getImageSize(this.bounds);
style.left = this.position.x + "%";
style.top = this.position.y + "%";
style.width = size.w + "%";
style.height = size.h + "%";
this.layer.getImageSize(this.bounds),
ratio = 1;
if (this.layer instanceof OpenLayers.Layer.Grid) {
ratio = this.layer.getServerResolution() / this.layer.map.getResolution();
}
style.left = (this.position.x | 0) + "px";
style.top = (this.position.y | 0) + "px";
style.width = Math.round(ratio * size.w) + "px";
style.height = Math.round(ratio * size.h) + "px";
},
/**

View File

@@ -49,8 +49,8 @@
log.push(transform);
}
control.containerCenter = {
x: 0, y: 0
map.layerContainerOriginPx = {
x: -50, y: -50
};
control.pinchOrigin = {
@@ -60,10 +60,10 @@
var cases = [
{x: 100, y: 60, scale: 1, transform: "translate(0px, 10px) scale(1)"},
{x: 150, y: 60, scale: 1, transform: "translate(50px, 10px) scale(1)"},
{x: 150, y: 60, scale: 2, transform: "translate(-50px, -40px) scale(2)"},
{x: 50, y: 20, scale: 2.5, transform: "translate(-200px, -105px) scale(2.5)"},
{x: 150, y: 60, scale: 2, transform: "translate(-50px, -40px) scale(2)"},
{x: 50, y: 20, scale: 0.25, transform: "translate(25px, 8px) scale(0.25)"}
{x: 150, y: 60, scale: 2, transform: "translate(-100px, -90px) scale(2)"},
{x: 50, y: 20, scale: 2.5, transform: "translate(-275px, -180px) scale(2.5)"},
{x: 150, y: 60, scale: 2, transform: "translate(-100px, -90px) scale(2)"},
{x: 50, y: 20, scale: 0.25, transform: "translate(63px, 45px) scale(0.25)"}
];
var len = cases.length;

View File

@@ -78,8 +78,8 @@
t.eq( tile.url,
url + "?" + OpenLayers.Util.getParameterString(tParams),
"image src is created correctly via addtile" );
t.eq( tile.getTile().style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.top, "6px", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5px", "image top is set correctly via addtile" );
var firstChild = layer.div.firstChild;
t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );

View File

@@ -821,12 +821,8 @@
var exc;
layer.serverResolutions = [0.5];
try {
res = layer.getServerResolution(1);
} catch(e) {
exc = e;
}
t.ok(exc != undefined, '[4] getServerResolution generates exception');
res = layer.getServerResolution(1);
t.eq(res, 0.5, '[4] getServerResolution return value is correct');
}
function test_getServerZoom(t) {
@@ -864,12 +860,8 @@
var exc;
layer.serverResolutions = [0.5];
resolution = 1;
try {
zoom = layer.getServerZoom();
} catch(e) {
exc = e;
}
t.ok(exc != undefined, '[4] getServerZoom generates exception');
zoom = layer.getServerZoom();
t.eq(zoom, 0, '[4] getServerZoom return value is correct');
map.destroy();
}
@@ -891,47 +883,47 @@
map.setCenter(new OpenLayers.LonLat(0, 0), 2);
// test initial conditions
t.eq(layer.div.style.width, '100%', 'layer div scale is 1');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, 'layer div scale is 1');
// change from resolution 8 to 4
map.zoomTo(3);
t.eq(layer.div.style.width, '200%', '[8->4] layer div scale is 2');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 2, '[8->4] layer div scale is 2');
// change from resolution 8 to 2
map.zoomTo(2); map.zoomTo(4);
t.eq(layer.div.style.width, '400%', '[8->2] layer div scale is 4');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[8->2] layer div scale is 4');
// change from resolution 8 to 1
map.zoomTo(2); map.zoomTo(5);
t.eq(layer.div.style.width, '800%', '[8->1] layer div scale is 8');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[8->1] layer div scale is 8');
// change from resolution 4 to 2
map.zoomTo(3); map.zoomTo(4);
t.eq(layer.div.style.width, '400%', '[4->2] layer div scale is 4');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[4->2] layer div scale is 4');
// change from resolution 4 to 1
map.zoomTo(3); map.zoomTo(5);
t.eq(layer.div.style.width, '800%', '[4->1] layer div scale is 8');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[4->1] layer div scale is 8');
// change from resolution 2 to 1
map.zoomTo(4); map.zoomTo(5);
t.eq(layer.div.style.width, '800%', '[2->1] layer div scale is 8');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 8, '[2->1] layer div scale is 8');
// change from resolution 1 to 2
map.zoomTo(5); map.zoomTo(4);
t.eq(layer.div.style.width, '400%', '[1->2] layer div scale is 4');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 4, '[1->2] layer div scale is 4');
// change from resolution 1 to 4
map.zoomTo(5); map.zoomTo(3);
t.eq(layer.div.style.width, '200%', '[1->4] layer div scale is 2');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 2, '[1->4] layer div scale is 2');
// change from resolution 1 to 8
map.zoomTo(5); map.zoomTo(2);
t.eq(layer.div.style.width, '100%', '[1->8] layer div scale is 1');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, '[1->8] layer div scale is 1');
// change from resolution 1 to 16
map.zoomTo(5); map.zoomTo(1);
t.eq(layer.div.style.width, '100%', '[1->16] layer div scale is 1');
t.eq(parseInt(layer.div.lastChild.style.width) / layer.tileSize.w, 1, '[1->16] layer div scale is 1');
map.destroy();
}
@@ -1022,63 +1014,8 @@
map.destroy();
}
function test_transformDiv(t) {
t.plan(8);
var map = new OpenLayers.Map('map4');
var layer = new OpenLayers.Layer.WMS('', '', {}, {
isBaseLayer: true
});
map.addLayer(layer);
map.zoomToMaxExtent();
// the layer container's dimensions are 100px width 100px height
// the position of the viewport center is 384, 256
layer.transformDiv(2);
t.eq(layer.div.style.width, '200%', '[1] layer div has correct width');
t.eq(layer.div.style.height, '200%', '[1] layer div has correct height');
t.eq(layer.div.style.left, '-384%', '[1] layer div has correct left');
t.eq(layer.div.style.top, '-256%', '[1] layer div has correct top');
// now move the layer container and test again
map.layerContainerDiv.style.left = '-1024px';
map.layerContainerDiv.style.top = '768px';
layer.transformDiv(2);
t.eq(layer.div.style.width, '200%', '[2] layer div has correct width');
t.eq(layer.div.style.height, '200%', '[2] layer div has correct height');
t.eq(layer.div.style.left, '-1408%', '[2] layer div has correct left');
t.eq(layer.div.style.top, '512%', '[2] layer div has correct top');
map.destroy();
}
function test_getResolutionScale(t) {
t.plan(1);
var map = new OpenLayers.Map('map');
var layer = new OpenLayers.Layer.WMS('', '', {}, {
isBaseLayer: true
});
map.addLayer(layer);
map.zoomToMaxExtent();
layer.transformDiv(2);
var scale = layer.getResolutionScale();
t.eq(scale, 2, 'getResolutionScale returns correct value');
map.destroy();
}
function test_applyBackBuffer(t) {
t.plan(16);
t.plan(12);
var map = new OpenLayers.Map('map2');
var layer = new OpenLayers.Layer.WMS('', '', {}, {
@@ -1103,19 +1040,16 @@
return backBuffer;
};
layer.gridResolution = 32;
layer.backBufferResolution = 2;
layer.grid[0][0].bounds = new OpenLayers.Bounds(0, 1, 1, 0);
layer.applyBackBuffer(2);
t.ok(layer.backBuffer === backBuffer,
'back buffer set in layer');
t.ok(layer.div.firstChild === backBuffer,
'back buffer inserted as first child');
t.eq(layer.backBuffer.style.width, '1600%',
'back buffer has correct width');
t.eq(layer.backBuffer.style.height, '1600%',
'back buffer has correct height');
t.eq(layer.backBuffer.style.left, '250%',
t.eq(layer.backBuffer.style.left, '250px',
'back buffer has correct left');
t.eq(layer.backBuffer.style.top, '275%',
t.eq(layer.backBuffer.style.top, '275px',
'back buffer has correct top');
// test #3
@@ -1124,21 +1058,18 @@
return backBuffer;
};
layer.gridResolution = 32;
layer.backBufferResolution = 2;
layer.grid[0][0].bounds = new OpenLayers.Bounds(0, 1, 1, 0);
map.layerContainerDiv.style.left = '20px';
map.layerContainerDiv.style.top = '-20px';
map.layerContainerOriginPx.x = 20;
map.layerContainerOriginPx.y = -20;
layer.applyBackBuffer(2);
t.ok(layer.backBuffer === backBuffer,
'back buffer set in layer');
t.ok(layer.div.firstChild === backBuffer,
'back buffer inserted as first child');
t.eq(layer.backBuffer.style.width, '1600%',
'back buffer has correct width');
t.eq(layer.backBuffer.style.height, '1600%',
'back buffer has correct height');
t.eq(layer.backBuffer.style.left, '230%',
t.eq(layer.backBuffer.style.left, '230px',
'back buffer has correct left');
t.eq(layer.backBuffer.style.top, '295%',
t.eq(layer.backBuffer.style.top, '295px',
'back buffer has correct top');
// test #4
@@ -1189,15 +1120,21 @@
return document.createElement('div');
};
backBuffer = layer.createBackBuffer();
layer.backBufferResolution = 1;
layer.gridResolution = 1;
layer.backBuffer = backBuffer;
layer.div.appendChild(backBuffer);
layer.backBufferLonLat = new OpenLayers.Bounds(0, 0);
layer.applyBackBuffer(1);
t.ok(backBuffer != undefined,
'createBackBuffer returns a back buffer');
t.eq(backBuffer.childNodes[0].style.left, '0%',
t.eq(backBuffer.childNodes[0].style.left, '0px',
'first tile has correct left');
t.eq(backBuffer.childNodes[0].style.top, '0%',
t.eq(backBuffer.childNodes[0].style.top, '0px',
'first tile has correct top');
t.eq(backBuffer.childNodes[1].style.left, '256%',
t.eq(backBuffer.childNodes[1].style.left, '256px',
'second tile has correct left');
t.eq(backBuffer.childNodes[1].style.top, '0%',
t.eq(backBuffer.childNodes[1].style.top, '0px',
'second tile has correct top');
map.destroy();
@@ -1257,8 +1194,8 @@
map.setCenter(new OpenLayers.LonLat(50, 50));
t.ok(layer.backBuffer && layer.backBuffer.parentNode === layer.div,
'backbuffer inserted after map move');
t.eq(layer.backBuffer.style.left, '-25%');
t.eq(layer.backBuffer.style.top, '-28%');
t.eq(layer.backBuffer.style.left, '-25px');
t.eq(layer.backBuffer.style.top, '-28px');
// zoom
map.zoomTo(1);
t.eq(layer.backBuffer, null,
@@ -1289,7 +1226,8 @@
map.addLayer(layer);
map.setCenter(new OpenLayers.LonLat(0, 0), 2);
layer.createBackBuffer = function() {
var origCreateBackBuffer = OpenLayers.Tile.Image.prototype.createBackBuffer;
OpenLayers.Tile.Image.prototype.createBackBuffer = function() {
return document.createElement('div');
};
@@ -1304,61 +1242,61 @@
// change resolution from 8 to 4
map.zoomTo(3);
t.eq(layer.backBuffer.style.width, '100%',
t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
'[8->4] back buffer not scaled');
removeBackBuffer();
// change resolution from 8 to 2
map.zoomTo(2); removeBackBuffer(); map.zoomTo(4);
t.eq(layer.backBuffer.style.width, '100%',
t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
'[8->2] back buffer not scaled');
removeBackBuffer();
// change resolution from 16 to 4
map.zoomTo(1); removeBackBuffer(); map.zoomTo(3);
t.eq(layer.backBuffer.style.width, '200%',
t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 2,
'[16->4] back buffer width is as expected');
t.eq(layer.backBuffer.style.width, '200%',
t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 2,
'[16->4] back buffer height is as expected');
removeBackBuffer();
// change resolution from 32 to 1
map.zoomTo(0); removeBackBuffer(); map.zoomTo(5);
t.eq(layer.backBuffer.style.width, '400%',
t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 4,
'[32->1] back buffer width is as expected');
t.eq(layer.backBuffer.style.width, '400%',
t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 4,
'[32->1] back buffer height is as expected');
removeBackBuffer();
// change resolution from 4 to 2
map.zoomTo(3); removeBackBuffer(); map.zoomTo(4);
t.eq(layer.backBuffer.style.width, '100%',
t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
'[4->2] back buffer not scaled');
removeBackBuffer();
// change resolution from 4 to 1
map.zoomTo(3); removeBackBuffer(); map.zoomTo(5);
t.eq(layer.backBuffer.style.width, '100%',
t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
'[4->1] back buffer not scaled');
removeBackBuffer();
// change resolution from 1 to 4
map.zoomTo(5); removeBackBuffer(); map.zoomTo(3);
t.eq(layer.backBuffer.style.width, '100%',
t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
'[1->4] back buffer not scaled');
removeBackBuffer();
// change resolution from 4 to 8
map.zoomTo(3); removeBackBuffer(); map.zoomTo(2);
t.eq(layer.backBuffer.style.width, '100%',
t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 1,
'[4->8] back buffer not scaled');
removeBackBuffer();
// change resolution from 4 to 16
map.zoomTo(3); removeBackBuffer(); map.zoomTo(1);
t.eq(layer.backBuffer.style.width, '50%',
t.eq(parseInt(layer.backBuffer.firstChild.style.width) / parseInt(layer.div.lastChild.style.width), 0.5,
'[4->16] back buffer width is as expected');
t.eq(layer.backBuffer.style.width, '50%',
t.eq(parseInt(layer.backBuffer.firstChild.style.height) / parseInt(layer.div.lastChild.style.height), 0.5,
'[4->16] back buffer height is as expected');
removeBackBuffer();
@@ -1367,6 +1305,7 @@
//
map.destroy();
OpenLayers.Tile.Image.prototype.createBackBuffer = origCreateBackBuffer
}
function test_delayed_back_buffer_removal(t) {

View File

@@ -58,8 +58,8 @@
t.eq( tile.url,
url + "?" + OpenLayers.Util.getParameterString(tParams).replace(/,/g, "+"),
"image src is created correctly via addtile" );
t.eq( tile.getTile().style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.top, "6px", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5px", "image top is set correctly via addtile" );
var firstChild = layer.div.firstChild;
t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );

View File

@@ -89,8 +89,8 @@
t.eq( tile.url,
layer.getFullRequestString(tParams),
"image src is created correctly via addtile" );
t.eq( tile.getTile().style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.top, "6px", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5px", "image top is set correctly via addtile" );
var firstChild = layer.div.firstChild;
t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );
@@ -120,8 +120,8 @@
t.eq( tile.url,
layer.getFullRequestString(tParams),
"image src is created correctly via addtile" );
t.eq( tile.getTile().style.top, "6%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5%", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.top, "6px", "image top is set correctly via addtile" );
t.eq( tile.getTile().style.left, "5px", "image top is set correctly via addtile" );
var firstChild = layer.div.firstChild;
t.eq( firstChild.nodeName.toLowerCase(), "img", "div first child is an image object" );

View File

@@ -155,8 +155,8 @@
t.delay_call(0.1, function() {
t.eq( tile.imgDiv.src, expected.src, "tile.draw creates an image");
});
t.eq( tile.imgDiv.style.width, "5%", "Image width is correct" );
t.eq( tile.imgDiv.style.height, "6%", "Image height is correct" );
t.eq( tile.imgDiv.style.width, "5px", "Image width is correct" );
t.eq( tile.imgDiv.style.height, "6px", "Image height is correct" );
t.ok( tile.imgDiv.parentNode === layer.div, "Image is directly appended to the layer div" );
// this should trigger a "reload" event (since the image never actually