Merge pull request #587 from ahocevar/587

Layer.WMS: BBOX precision errors in URLs. r=@bartvde
This commit is contained in:
ahocevar
2012-10-12 08:53:23 -07:00
8 changed files with 167 additions and 183 deletions

View File

@@ -271,6 +271,20 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* tile that could not be loaded.
*/
/**
* Property: gridLayout
* {Object} Object containing properties tilelon, tilelat, startcol,
* startrow
*/
gridLayout: null,
/**
* Property: rowSign
* {Number} 1 for grids starting at the top, -1 for grids starting at the
* bottom. This is used for several grid index and offset calculations.
*/
rowSign: null,
/**
* Constructor: OpenLayers.Layer.Grid
* Create a new grid layer
@@ -302,6 +316,8 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
this.moveTimerId = null;
}, this);
}
this.rowSign = this.tileOriginCorner.substr(0, 1) === "t" ? 1 : -1;
},
/**
@@ -364,6 +380,7 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
}
this.grid = [];
this.gridResolution = null;
this.gridLayout = null;
}
},
@@ -867,35 +884,24 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* resolution - {Number}
*
* Returns:
* {Object} containing properties tilelon, tilelat, tileoffsetlat,
* tileoffsetlat, tileoffsetx, tileoffsety
* {Object} Object containing properties tilelon, tilelat, startcol,
* startrow
*/
calculateGridLayout: function(bounds, origin, resolution) {
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 * 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 * tileSize.h;
var tileoffsetlat = origin.lat + tilerow * tilelat;
var rowSign = this.rowSign;
var offsetlat = rowSign * (origin.lat - bounds.top + tilelat);
var tilerow = Math[~rowSign ? 'floor' : 'ceil'](offsetlat/tilelat) - this.buffer * rowSign;
return {
tilelon: tilelon, tilelat: tilelat,
tileoffsetlon: tileoffsetlon, tileoffsetlat: tileoffsetlat,
tileoffsetx: tileoffsetx, tileoffsety: tileoffsety
startcol: tilecol, startrow: tilerow
};
},
@@ -926,6 +932,32 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
return origin;
},
/**
* Method: getTileBoundsForGridIndex
*
* Parameters:
* row - {Number} The row of the grid
* col - {Number} The column of the grid
*
* Returns:
* {<OpenLayers.Bounds>} The bounds for the tile at (row, col)
*/
getTileBoundsForGridIndex: function(row, col) {
var origin = this.getTileOrigin();
var tileLayout = this.gridLayout;
var tilelon = tileLayout.tilelon;
var tilelat = tileLayout.tilelat;
var startcol = tileLayout.startcol;
var startrow = tileLayout.startrow;
var rowSign = this.rowSign;
return new OpenLayers.Bounds(
origin.lon + (startcol + col) * tilelon,
origin.lat - (startrow + row * rowSign) * tilelat * rowSign,
origin.lon + (startcol + col + 1) * tilelon,
origin.lat - (startrow + (row - 1) * rowSign) * tilelat * rowSign
);
},
/**
* Method: initGriddedTiles
*
@@ -955,50 +987,38 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
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;
this.gridLayout = tileLayout;
var tilelon = tileLayout.tilelon;
var tilelat = tileLayout.tilelat;
var startX = tileoffsetx;
var startLon = tileoffsetlon;
var rowidx = 0;
var layerContainerDivLeft = this.map.layerContainerOriginPx.x;
var layerContainerDivTop = this.map.layerContainerOriginPx.y;
var tileBounds = this.getTileBoundsForGridIndex(0, 0);
var startPx = this.map.getViewPortPxFromLonLat(
new OpenLayers.LonLat(tileBounds.left, tileBounds.top)
);
startPx.x = Math.round(startPx.x) - layerContainerDivLeft;
startPx.y = Math.round(startPx.y) - layerContainerDivTop;
var tileData = [], center = this.map.getCenter();
var rowidx = 0;
do {
var row = this.grid[rowidx++];
var row = this.grid[rowidx];
if (!row) {
row = [];
this.grid.push(row);
}
tileoffsetlon = startLon;
tileoffsetx = startX;
var colidx = 0;
do {
var tileBounds =
new OpenLayers.Bounds(tileoffsetlon,
tileoffsetlat,
tileoffsetlon + tilelon,
tileoffsetlat + tilelat);
var x = tileoffsetx;
x -= layerContainerDivLeft;
var y = tileoffsety;
y -= layerContainerDivTop;
var px = new OpenLayers.Pixel(x, y);
var tile = row[colidx++];
tileBounds = this.getTileBoundsForGridIndex(rowidx, colidx);
var px = startPx.clone();
px.x = px.x + colidx * Math.round(tileSize.w);
px.y = px.y + rowidx * Math.round(tileSize.h);
var tile = row[colidx];
if (!tile) {
tile = this.addTile(tileBounds, px);
this.addTileMonitoringHooks(tile);
@@ -1013,14 +1033,12 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
Math.pow(tileCenter.lat - center.lat, 2)
});
tileoffsetlon += tilelon;
tileoffsetx += Math.round(tileSize.w);
} while ((tileoffsetlon <= bounds.right + tilelon * this.buffer)
colidx += 1;
} while ((tileBounds.right <= bounds.right + tilelon * this.buffer)
|| colidx < minCols);
tileoffsetlat -= tilelat;
tileoffsety += Math.round(tileSize.h);
} while((tileoffsetlat >= bounds.bottom - tilelat * this.buffer)
rowidx += 1;
} while((tileBounds.bottom >= bounds.bottom - tilelat * this.buffer)
|| rowidx < minRows);
//shave off exceess rows and colums
@@ -1198,31 +1216,23 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* if false, then append to end
* tileSize - {Object} rendered tile size; object with w and h properties
*/
shiftRow:function(prepend, tileSize) {
var modelRowIndex = (prepend) ? 0 : (this.grid.length - 1);
shiftRow: function(prepend, tileSize) {
var grid = this.grid;
var modelRow = grid[modelRowIndex];
var rowIndex = prepend ? 0 : (grid.length - 1);
var sign = prepend ? -1 : 1;
var deltaLat = this.getServerResolution() * -sign * this.tileSize.h;
var rowSign = this.rowSign;
var tileLayout = this.gridLayout;
tileLayout.startrow += sign * rowSign;
var row = (prepend) ? grid.pop() : grid.shift();
for (var i=0, len=modelRow.length; i<len; i++) {
var modelTile = modelRow[i];
var bounds = modelTile.bounds.clone();
var position = modelTile.position.clone();
bounds.bottom = bounds.bottom + deltaLat;
bounds.top = bounds.top + deltaLat;
position.y = position.y + sign * tileSize.h;
row[i].moveTo(bounds, position);
}
if (prepend) {
grid.unshift(row);
} else {
grid.push(row);
var modelRow = grid[rowIndex];
var row = grid[prepend ? 'pop' : 'shift']();
for (var i=0, len=row.length; i<len; i++) {
var tile = row[i];
var position = modelRow[i].position.clone();
position.y += tileSize.h * sign;
tile.moveTo(this.getTileBoundsForGridIndex(rowIndex, i), position);
}
grid[prepend ? 'unshift' : 'push'](row);
},
/**
@@ -1235,27 +1245,19 @@ OpenLayers.Layer.Grid = OpenLayers.Class(OpenLayers.Layer.HTTPRequest, {
* tileSize - {Object} rendered tile size; object with w and h properties
*/
shiftColumn: function(prepend, tileSize) {
var grid = this.grid;
var colIndex = prepend ? 0 : (grid[0].length - 1);
var sign = prepend ? -1 : 1;
var deltaLon = this.getServerResolution() * sign * this.tileSize.w;
var tileLayout = this.gridLayout;
tileLayout.startcol += sign;
for (var i=0, len=this.grid.length; i<len; i++) {
var row = this.grid[i];
var modelTileIndex = (prepend) ? 0 : (row.length - 1);
var modelTile = row[modelTileIndex];
var bounds = modelTile.bounds.clone();
var position = modelTile.position.clone();
bounds.left = bounds.left + deltaLon;
bounds.right = bounds.right + deltaLon;
position.x = position.x + sign * tileSize.w;
var tile = prepend ? this.grid[i].pop() : this.grid[i].shift();
tile.moveTo(bounds, position);
if (prepend) {
row.unshift(tile);
} else {
row.push(tile);
}
for (var i=0, len=grid.length; i<len; i++) {
var row = grid[i];
var position = row[colIndex].position.clone();
var tile = row[prepend ? 'pop' : 'shift']();
position.x += tileSize.w * sign;
tile.moveTo(this.getTileBoundsForGridIndex(i, colIndex), position);
row[prepend ? 'unshift' : 'push'](tile);
}
},