From 0ba7961df48b81d9e021bbcac817c6ff57ee6be0 Mon Sep 17 00:00:00 2001 From: crschmidt Date: Wed, 9 Aug 2006 03:47:33 +0000 Subject: [PATCH] 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 --- lib/OpenLayers/Control/LayerSwitcher.js | 10 +- lib/OpenLayers/Layer.js | 5 + lib/OpenLayers/Layer/Grid.js | 136 ++++++++++++------------ lib/OpenLayers/Layer/KaMap.js | 16 ++- lib/OpenLayers/Layer/WMS.js | 16 +-- lib/OpenLayers/Layer/WorldWind.js | 34 +++--- lib/OpenLayers/Tile.js | 11 ++ lib/OpenLayers/Tile/Image.js | 32 +++++- lib/OpenLayers/Util.js | 39 ++++++- 9 files changed, 194 insertions(+), 105 deletions(-) diff --git a/lib/OpenLayers/Control/LayerSwitcher.js b/lib/OpenLayers/Control/LayerSwitcher.js index 6abb85e1a1..18a5559344 100644 --- a/lib/OpenLayers/Control/LayerSwitcher.js +++ b/lib/OpenLayers/Control/LayerSwitcher.js @@ -26,6 +26,10 @@ OpenLayers.Control.LayerSwitcher.prototype = /** @type Array */ baseLayerInputs: null, + + /** @type DOMElement */ + dataLbl: null, + /** @type DOMElement */ dataLayersDiv: null, @@ -223,8 +227,6 @@ OpenLayers.Control.LayerSwitcher.prototype = this.div.style.width = "0px"; this.div.style.height = "0px"; -// this.div.style.backgroundColor = "transparent"; - this.showControls(true); if (e != null) { @@ -331,7 +333,7 @@ OpenLayers.Control.LayerSwitcher.prototype = // maximize button div var img = imgLocation + 'layer-switcher-maximize.png'; this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv( - "OpenLayers_Control_ResizeDiv", + "OpenLayers_Control_MaximizeDiv", null, sz, img, @@ -350,7 +352,7 @@ OpenLayers.Control.LayerSwitcher.prototype = var img = imgLocation + 'layer-switcher-minimize.png'; var sz = new OpenLayers.Size(18,18); this.minimizeDiv = OpenLayers.Util.createAlphaImageDiv( - "OpenLayers_Control_ResizeDiv", + "OpenLayers_Control_MinimizeDiv", null, sz, img, diff --git a/lib/OpenLayers/Layer.js b/lib/OpenLayers/Layer.js index 036378cfb9..b073b9b8d4 100644 --- a/lib/OpenLayers/Layer.js +++ b/lib/OpenLayers/Layer.js @@ -30,6 +30,11 @@ OpenLayers.Layer.prototype = { */ isBaseLayer: false, + /** asserts whether or not the layer's images have an alpha channel + * + * @type boolean */ + alpha: false, + // OPTIONS /** @type Array */ diff --git a/lib/OpenLayers/Layer/Grid.js b/lib/OpenLayers/Layer/Grid.js index 991474500c..ee1f876cf2 100644 --- a/lib/OpenLayers/Layer/Grid.js +++ b/lib/OpenLayers/Layer/Grid.js @@ -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