Commit tile-reuse branch back to trunk. This branch offers numerous performance
improvements in the form of reduced memory use and lower element creating costs, hopefully making the OpenLayers code more usable in internet explorer as well as less of a memory hog in Firefox and other browsers. Additionally, a buffer is available around the main map grid which allows tiles to be loaded outside of the viewing area for faster dragging. git-svn-id: http://svn.openlayers.org/trunk/openlayers@1137 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
This commit is contained in:
@@ -20,11 +20,8 @@ OpenLayers.Layer.Grid.prototype =
|
||||
* @type Array(Array) */
|
||||
grid: null,
|
||||
|
||||
/** asserts whether or not the layer's images have an alpha channel
|
||||
*
|
||||
* @type boolean */
|
||||
alpha: false,
|
||||
|
||||
/** @type Integer */
|
||||
buffer: 2,
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
@@ -37,6 +34,7 @@ OpenLayers.Layer.Grid.prototype =
|
||||
initialize: function(name, url, params, options) {
|
||||
OpenLayers.Layer.HTTPRequest.prototype.initialize.apply(this,
|
||||
arguments);
|
||||
this.grid = new Array();
|
||||
},
|
||||
|
||||
/** on destroy, clear the grid.
|
||||
@@ -132,37 +130,33 @@ OpenLayers.Layer.Grid.prototype =
|
||||
*
|
||||
* @param {OpenLayers.Bounds} bounds
|
||||
* @param {Boolean} zoomChanged
|
||||
* @param {Boolean} minor
|
||||
* @param {Boolean} dragging
|
||||
*/
|
||||
moveTo:function(bounds, zoomChanged, minor) {
|
||||
moveTo:function(bounds, zoomChanged, dragging) {
|
||||
if (bounds == null) {
|
||||
bounds = this.map.getExtent();
|
||||
}
|
||||
if (bounds != null) {
|
||||
if (!this.getVisibility()) {
|
||||
if (zoomChanged) {
|
||||
//now clear out the old grid and start a new one
|
||||
this.clearGrid();
|
||||
this.grid = null;
|
||||
// FIX ME FIX ME FIX ME -- should be this.hideGrid() basically
|
||||
}
|
||||
} else if (!this.grid.length || zoomChanged
|
||||
|| !this.getGridBounds().containsBounds(bounds, true)) {
|
||||
this._initTiles();
|
||||
} else {
|
||||
if (!this.grid || zoomChanged) {
|
||||
this._initTiles();
|
||||
} else if (this.getGridBounds().containsBounds(bounds, true) == false) {
|
||||
this._initTiles();
|
||||
} else {
|
||||
var i = 0;
|
||||
while (this.getGridBounds().bottom > bounds.bottom) {
|
||||
this.insertRow(false);
|
||||
}
|
||||
while (this.getGridBounds().left > bounds.left) {
|
||||
this.insertColumn(true);
|
||||
}
|
||||
while (this.getGridBounds().top < bounds.top) {
|
||||
this.insertRow(true);
|
||||
}
|
||||
while (this.getGridBounds().right < bounds.right) {
|
||||
this.insertColumn(false);
|
||||
while (true) {
|
||||
var topLeft = this.map.getViewPortPxFromLayerPx( this.grid[0][0].position );
|
||||
if (topLeft.x > -this.tileSize.w * (this.buffer - 1)) {
|
||||
this.shiftColumn(true);
|
||||
} else if (topLeft.x < -this.tileSize.w * this.buffer) {
|
||||
this.shiftColumn(false);
|
||||
} else if (topLeft.y > -this.tileSize.w * (this.buffer - 1)) {
|
||||
this.shiftRow(true);
|
||||
} else if (topLeft.y < -this.tileSize.h * this.buffer) {
|
||||
this.shiftRow(false);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,19 +182,11 @@ OpenLayers.Layer.Grid.prototype =
|
||||
topRightTile.bounds.right,
|
||||
topRightTile.bounds.top);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
_initTiles:function() {
|
||||
|
||||
//first of all, clear out the main div
|
||||
this.div.innerHTML = "";
|
||||
|
||||
//now clear out the old grid and start a new one
|
||||
this.clearGrid();
|
||||
this.grid = new Array();
|
||||
|
||||
var viewSize = this.map.getSize();
|
||||
var bounds = this.map.getExtent();
|
||||
var extent = this.map.getMaxExtent();
|
||||
@@ -209,13 +195,13 @@ OpenLayers.Layer.Grid.prototype =
|
||||
var tilelat = resolution * this.tileSize.h;
|
||||
|
||||
var offsetlon = bounds.left - extent.left;
|
||||
var tilecol = Math.floor(offsetlon/tilelon);
|
||||
var tilecol = Math.floor(offsetlon/tilelon) - this.buffer;
|
||||
var tilecolremain = offsetlon/tilelon - tilecol;
|
||||
var tileoffsetx = -tilecolremain * this.tileSize.w;
|
||||
var tileoffsetlon = extent.left + tilecol * tilelon;
|
||||
|
||||
var offsetlat = bounds.top - (extent.bottom + tilelat);
|
||||
var tilerow = Math.ceil(offsetlat/tilelat);
|
||||
var tilerow = Math.ceil(offsetlat/tilelat) + this.buffer;
|
||||
var tilerowremain = tilerow - offsetlat/tilelat;
|
||||
var tileoffsety = -tilerowremain * this.tileSize.h;
|
||||
var tileoffsetlat = extent.bottom + tilerow * tilelat;
|
||||
@@ -227,12 +213,24 @@ OpenLayers.Layer.Grid.prototype =
|
||||
|
||||
var startX = tileoffsetx;
|
||||
var startLon = tileoffsetlon;
|
||||
|
||||
|
||||
var newGrid = (this.grid.length == 0);
|
||||
var rowidx = 0;
|
||||
|
||||
do {
|
||||
var row = new Array();
|
||||
this.grid.push(row);
|
||||
var row;
|
||||
|
||||
if (newGrid) {
|
||||
row = new Array();
|
||||
this.grid.push(row);
|
||||
} else {
|
||||
row = this.grid[rowidx++];
|
||||
}
|
||||
|
||||
tileoffsetlon = startLon;
|
||||
tileoffsetx = startX;
|
||||
|
||||
var colidx = 0;
|
||||
|
||||
do {
|
||||
var tileBounds = new OpenLayers.Bounds(tileoffsetlon,
|
||||
@@ -247,19 +245,24 @@ OpenLayers.Layer.Grid.prototype =
|
||||
y -= parseInt(this.map.layerContainerDiv.style.top);
|
||||
|
||||
var px = new OpenLayers.Pixel(x, y);
|
||||
var tile;
|
||||
|
||||
var tile = this.addTile(tileBounds, px);
|
||||
|
||||
tile.draw(this.alpha);
|
||||
row.push(tile);
|
||||
if (newGrid) {
|
||||
tile = this.addTile(tileBounds, px);
|
||||
tile.draw();
|
||||
row.push(tile);
|
||||
} else {
|
||||
tile = row[colidx++];
|
||||
tile.moveTo(tileBounds, px);
|
||||
}
|
||||
|
||||
tileoffsetlon += tilelon;
|
||||
tileoffsetx += this.tileSize.w;
|
||||
} while (tileoffsetlon < bounds.right)
|
||||
} while (tileoffsetlon <= bounds.right + tilelon * this.buffer)
|
||||
|
||||
tileoffsetlat -= tilelat;
|
||||
tileoffsety += this.tileSize.h;
|
||||
} while(tileoffsetlat > bounds.bottom - tilelat)
|
||||
} while(tileoffsetlat >= bounds.bottom - tilelat * this.buffer)
|
||||
|
||||
},
|
||||
|
||||
@@ -376,16 +379,16 @@ OpenLayers.Layer.Grid.prototype =
|
||||
* @param {Boolean} prepend if true, prepend to beginning.
|
||||
* if false, then append to end
|
||||
*/
|
||||
insertRow:function(prepend) {
|
||||
shiftRow:function(prepend) {
|
||||
var modelRowIndex = (prepend) ? 0 : (this.grid.length - 1);
|
||||
var modelRow = this.grid[modelRowIndex];
|
||||
|
||||
var newRow = new Array();
|
||||
|
||||
var resolution = this.map.getResolution();
|
||||
var deltaY = (prepend) ? -this.tileSize.h : this.tileSize.h;
|
||||
var deltaLat = resolution * -deltaY;
|
||||
|
||||
var row = (prepend) ? this.grid.pop() : this.grid.shift();
|
||||
|
||||
for (var i=0; i < modelRow.length; i++) {
|
||||
var modelTile = modelRow[i];
|
||||
var bounds = modelTile.bounds.clone();
|
||||
@@ -393,18 +396,14 @@ OpenLayers.Layer.Grid.prototype =
|
||||
bounds.bottom = bounds.bottom + deltaLat;
|
||||
bounds.top = bounds.top + deltaLat;
|
||||
position.y = position.y + deltaY;
|
||||
var newTile = this.addTile(bounds, position);
|
||||
newTile.draw(this.alpha);
|
||||
newRow.push(newTile);
|
||||
row[i].moveTo(bounds, position);
|
||||
}
|
||||
|
||||
if (prepend) {
|
||||
this.grid.unshift(row);
|
||||
} else {
|
||||
this.grid.push(row);
|
||||
}
|
||||
|
||||
if (newRow.length>0){
|
||||
if (prepend) {
|
||||
this.grid.unshift(newRow);
|
||||
} else {
|
||||
this.grid.push(newRow);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -413,15 +412,14 @@ OpenLayers.Layer.Grid.prototype =
|
||||
* @param {Boolean} prepend if true, prepend to beginning.
|
||||
* if false, then append to end
|
||||
*/
|
||||
insertColumn:function(prepend) {
|
||||
var modelCellIndex;
|
||||
shiftColumn: function(prepend) {
|
||||
var deltaX = (prepend) ? -this.tileSize.w : this.tileSize.w;
|
||||
var resolution = this.map.getResolution();
|
||||
var deltaLon = resolution * deltaX;
|
||||
|
||||
for (var i=0; i<this.grid.length; i++) {
|
||||
var row = this.grid[i];
|
||||
modelTileIndex = (prepend) ? 0 : (row.length - 1);
|
||||
var modelTileIndex = (prepend) ? 0 : (row.length - 1);
|
||||
var modelTile = row[modelTileIndex];
|
||||
|
||||
var bounds = modelTile.bounds.clone();
|
||||
@@ -429,13 +427,13 @@ OpenLayers.Layer.Grid.prototype =
|
||||
bounds.left = bounds.left + deltaLon;
|
||||
bounds.right = bounds.right + deltaLon;
|
||||
position.x = position.x + deltaX;
|
||||
var newTile = this.addTile(bounds, position);
|
||||
newTile.draw(this.alpha);
|
||||
|
||||
|
||||
var tile = prepend ? this.grid[i].pop() : this.grid[i].shift()
|
||||
tile.moveTo(bounds, position);
|
||||
if (prepend) {
|
||||
row = row.unshift(newTile);
|
||||
this.grid[i].unshift(tile);
|
||||
} else {
|
||||
row = row.push(newTile);
|
||||
this.grid[i].push(tile);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -15,8 +15,8 @@ OpenLayers.Layer.KaMap.prototype =
|
||||
*
|
||||
* @type Boolean
|
||||
*/
|
||||
isBaseLayer: true,
|
||||
|
||||
isBaseLayer: true,
|
||||
|
||||
units: 'degrees',
|
||||
scales: {inches: 1, feet: 12, miles: 63360.0, meters: 39.3701, kilometers: 39370.1, degrees: 4374754},
|
||||
|
||||
@@ -44,7 +44,8 @@ OpenLayers.Layer.KaMap.prototype =
|
||||
);
|
||||
}
|
||||
},
|
||||
addTile:function(bounds,position) {
|
||||
|
||||
getURL:function(bounds) {
|
||||
var zoom = this.map.getZoom();
|
||||
var maxRes = this.map.maxResolution;
|
||||
var mapRes = this.map.getResolution();
|
||||
@@ -53,14 +54,19 @@ OpenLayers.Layer.KaMap.prototype =
|
||||
var cellSize = new OpenLayers.Size(mapRes*this.tileSize.w, mapRes*this.tileSize.h);
|
||||
var pX = Math.round(((bounds.left) / cellSize.w) * this.tileSize.w);
|
||||
var pY = -Math.round(((bounds.top) / cellSize.h) * this.tileSize.h);
|
||||
var url = this.getFullRequestString(
|
||||
return this.getFullRequestString(
|
||||
{ t: pY,
|
||||
l: pX,
|
||||
s: scale
|
||||
});
|
||||
},
|
||||
|
||||
addTile:function(bounds,position) {
|
||||
var url = this.getURL(bounds);
|
||||
return new OpenLayers.Tile.Image(this, position, bounds,
|
||||
url, this.tileSize);
|
||||
},
|
||||
|
||||
_initTiles:function() {
|
||||
|
||||
//first of all, clear out the main div
|
||||
@@ -112,7 +118,7 @@ OpenLayers.Layer.KaMap.prototype =
|
||||
new OpenLayers.Pixel(tileoffsetx - parseInt(this.map.layerContainerDiv.style.left),
|
||||
tileoffsety - parseInt(this.map.layerContainerDiv.style.top))
|
||||
);
|
||||
tile.draw((this.alpha));
|
||||
tile.draw();
|
||||
row.push(tile);
|
||||
|
||||
tileoffsetlon += tilelon;
|
||||
|
||||
@@ -82,7 +82,14 @@ OpenLayers.Layer.WMS.prototype =
|
||||
|
||||
return obj;
|
||||
},
|
||||
|
||||
|
||||
getURL: function (bounds) {
|
||||
return this.getFullRequestString(
|
||||
{BBOX:bounds.toBBOX(),
|
||||
WIDTH:this.tileSize.w,
|
||||
HEIGHT:this.tileSize.h});
|
||||
},
|
||||
|
||||
/**
|
||||
* addTile creates a tile, initializes it, and
|
||||
* adds it to the layer div.
|
||||
@@ -93,16 +100,11 @@ OpenLayers.Layer.WMS.prototype =
|
||||
* @type OpenLayers.Tile.Image
|
||||
*/
|
||||
addTile:function(bounds,position) {
|
||||
url = this.getFullRequestString(
|
||||
{BBOX:bounds.toBBOX(),
|
||||
WIDTH:this.tileSize.w,
|
||||
HEIGHT:this.tileSize.h});
|
||||
|
||||
url = this.getURL(bounds);
|
||||
return new OpenLayers.Tile.Image(this, position, bounds,
|
||||
url, this.tileSize);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Catch changeParams and uppercase the new params to be merged in
|
||||
* before calling changeParams on the super class.
|
||||
|
||||
@@ -38,18 +38,9 @@ OpenLayers.Layer.WorldWind.prototype =
|
||||
}
|
||||
},
|
||||
addTile:function(bounds,position) {
|
||||
var zoom = this.map.getZoom();
|
||||
var extent = this.map.getMaxExtent();
|
||||
zoom = zoom - Math.log(this.map.maxResolution / (this.lzd/512))/Math.log(2);
|
||||
if (this.map.getResolution() <= (this.lzd/512) && zoom <= this.zoomLevels) {
|
||||
var deg = this.lzd/Math.pow(2,zoom);
|
||||
var x = Math.floor((bounds.left - extent.left)/deg);
|
||||
var y = Math.floor((bounds.bottom - extent.bottom)/deg);
|
||||
var url = this.getFullRequestString(
|
||||
{ L: zoom,
|
||||
X: x,
|
||||
Y: y
|
||||
});
|
||||
if (this.map.getResolution() <= (this.lzd/512)
|
||||
&& this.getZoom() <= this.zoomLevels) {
|
||||
|
||||
return new OpenLayers.Tile.Image(this, position, bounds,
|
||||
url, this.tileSize);
|
||||
} else {
|
||||
@@ -62,6 +53,25 @@ OpenLayers.Layer.WorldWind.prototype =
|
||||
}
|
||||
},
|
||||
|
||||
getZoom: function () {
|
||||
var zoom = this.map.getZoom();
|
||||
var extent = this.map.getMaxExtent();
|
||||
zoom = zoom - Math.log(this.map.maxResolution / (this.lzd/512))/Math.log(2);
|
||||
return zoom;
|
||||
},
|
||||
|
||||
getURL: function (bounds) {
|
||||
var deg = this.lzd/Math.pow(2,this.getZoom());
|
||||
var x = Math.floor((bounds.left - extent.left)/deg);
|
||||
var y = Math.floor((bounds.bottom - extent.bottom)/deg);
|
||||
return this.getFullRequestString(
|
||||
{ L: zoom,
|
||||
X: x,
|
||||
Y: y
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/** @final @type String */
|
||||
CLASS_NAME: "OpenLayers.Layer.WorldWind"
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user