diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js index a6e5519ec2..b99be5e1ca 100644 --- a/src/ol/renderer/canvas/canvastilelayerrenderer.js +++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js @@ -10,6 +10,7 @@ goog.require('ol.Extent'); goog.require('ol.Size'); goog.require('ol.Tile'); goog.require('ol.TileCoord'); +goog.require('ol.TileRange'); goog.require('ol.TileState'); goog.require('ol.layer.TileLayer'); goog.require('ol.renderer.Map'); @@ -51,6 +52,18 @@ ol.renderer.canvas.TileLayer = function(mapRenderer, tileLayer) { */ this.transform_ = goog.vec.Mat4.createNumber(); + /** + * @private + * @type {number} + */ + this.renderedCanvasZ_ = NaN; + + /** + * @private + * @type {ol.TileRange} + */ + this.renderedCanvasTileRange_ = null; + /** * @private * @type {Array.} @@ -118,7 +131,8 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = var tileRangeHeight = tileRange.getHeight(); var canvasSize = new ol.Size( - tileSize.width * tileRangeWidth, tileSize.height * tileRangeHeight); + tileSize.width * tileRange.getWidth(), + tileSize.height * tileRange.getHeight()); var canvas, context; if (goog.isNull(this.canvas_)) { @@ -130,18 +144,45 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = this.canvas_ = canvas; this.canvasSize_ = canvasSize; this.context_ = context; - this.renderedTiles_ = new Array(tileRangeWidth * tileRangeHeight); + this.renderedCanvasTileRange_ = null; } else { canvas = this.canvas_; context = this.context_; - if (!this.canvasSize_.equals(canvasSize)) { + if (this.canvasSize_.width < canvasSize.width || + this.canvasSize_.height < canvasSize.height) { canvas.width = canvasSize.width; canvas.height = canvasSize.height; this.canvasSize_ = canvasSize; - this.renderedTiles_ = new Array(tileRangeWidth * tileRangeHeight); + this.renderedCanvasTileRange_ = null; + } else if (z != this.renderedCanvasZ_ || + !this.renderedCanvasTileRange_.containsTileRange(tileRange)) { + this.renderedCanvasTileRange_ = null; } } + var canvasTileRange, canvasTileRangeWidth, minX, minY; + if (z != this.renderedCanvasZ_ || + goog.isNull(this.renderedCanvasTileRange_)) { + canvasTileRangeWidth = canvasSize.width / tileSize.width; + var canvasTileRangeHeight = canvasSize.height / tileSize.height; + minX = tileRange.minX + + Math.floor((canvasTileRangeWidth - tileRange.getWidth()) / 2); + minY = tileRange.minY + + Math.floor((canvasTileRangeHeight - tileRange.getHeight()) / 2); + this.renderedCanvasZ_ = z; + this.renderedCanvasTileRange_ = new ol.TileRange( + minX, minY, + minX + canvasTileRangeWidth - 1, minY + canvasTileRangeHeight - 1); + this.renderedTiles_ = + new Array(canvasTileRangeWidth * canvasTileRangeHeight); + canvasTileRange = this.renderedCanvasTileRange_; + } else { + canvasTileRange = this.renderedCanvasTileRange_; + canvasTileRangeWidth = canvasTileRange.getWidth(); + } + + goog.asserts.assert(canvasTileRange.containsTileRange(tileRange)); + /** * @type {Object.>} */ @@ -178,10 +219,10 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = var zs = goog.array.map(goog.object.getKeys(tilesToDrawByZ), Number); goog.array.sort(zs); var opaque = tileSource.getOpaque(); - var origin = tileGrid.getTileCoordExtent( - new ol.TileCoord(z, tileRange.minX, tileRange.maxY)).getTopLeft(); + var origin = tileGrid.getTileCoordExtent(new ol.TileCoord( + z, canvasTileRange.minX, canvasTileRange.maxY)).getTopLeft(); var currentZ, i, index, scale, tileCoordKey, tileExtent, tilesToDraw; - var ix, iy, interimTileExtent, interimTileRange, maxX, maxY, minX, minY; + var ix, iy, interimTileExtent, interimTileRange, maxX, maxY; var height, width; for (i = 0; i < zs.length; ++i) { currentZ = zs[i]; @@ -190,11 +231,12 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = if (currentZ == z) { for (tileCoordKey in tilesToDraw) { tile = tilesToDraw[tileCoordKey]; - index = (tile.tileCoord.y - tileRange.minY) * tileRangeWidth + - (tile.tileCoord.x - tileRange.minX); + index = + (tile.tileCoord.y - canvasTileRange.minY) * canvasTileRangeWidth + + (tile.tileCoord.x - canvasTileRange.minX); if (this.renderedTiles_[index] != tile) { - x = tileSize.width * (tile.tileCoord.x - tileRange.minX); - y = tileSize.height * (tileRange.maxY - tile.tileCoord.y); + x = tileSize.width * (tile.tileCoord.x - canvasTileRange.minX); + y = tileSize.height * (canvasTileRange.maxY - tile.tileCoord.y); tileState = tile.getState(); if (tileState == ol.TileState.EMPTY || !opaque) { context.clearRect(x, y, tileSize.width, tileSize.height); @@ -223,14 +265,15 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = } interimTileRange = tileGrid.getTileRangeForExtentAndZ(tileExtent, z); - minX = Math.max(interimTileRange.minX, tileRange.minX); - maxX = Math.min(interimTileRange.maxX, tileRange.maxX); - minY = Math.max(interimTileRange.minY, tileRange.minY); - maxY = Math.min(interimTileRange.maxY, tileRange.maxY); + minX = Math.max(interimTileRange.minX, canvasTileRange.minX); + maxX = Math.min(interimTileRange.maxX, canvasTileRange.maxX); + minY = Math.max(interimTileRange.minY, canvasTileRange.minY); + maxY = Math.min(interimTileRange.maxY, canvasTileRange.maxY); for (ix = minX; ix <= maxX; ++ix) { for (iy = minY; iy <= maxY; ++iy) { - this.renderedTiles_[(iy - tileRange.minY) * tileRangeWidth + - (ix - tileRange.minX)] = undefined; + index = (iy - canvasTileRange.minY) * canvasTileRangeWidth + + (ix - canvasTileRange.minX); + this.renderedTiles_[index] = undefined; } } }