Merge pull request #519 from twpayne/tile-garbage-clean-ups

Tile garbage clean-ups
This commit is contained in:
Tom Payne
2013-04-09 13:12:01 -07:00
11 changed files with 162 additions and 49 deletions

View File

@@ -92,6 +92,27 @@ ol.Extent.prototype.containsCoordinate = function(coordinate) {
};
/**
* @param {number} minX Minimum X.
* @param {number} minY Minimum Y.
* @param {number} maxX Maximum X.
* @param {number} maxY Maximum Y.
* @param {ol.Extent|undefined} extent Extent.
* @return {ol.Extent} Extent.
*/
ol.Extent.createOrUpdate = function(minX, minY, maxX, maxY, extent) {
if (goog.isDef(extent)) {
extent.minX = minX;
extent.minY = minY;
extent.maxX = maxX;
extent.maxY = maxY;
return extent;
} else {
return new ol.Extent(minX, minY, maxX, maxY);
}
};
/**
* Checks if the passed extent is contained or on the edge of the
* extent.

View File

@@ -201,6 +201,8 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
tilesToDrawByZ, getTileIfLoaded);
var allTilesLoaded = true;
var tmpExtent = new ol.Extent(0, 0, 0, 0);
var tmpTileRange = new ol.TileRange(0, 0, 0, 0);
var childTileRange, fullyLoaded, tile, tileState, x, y;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
@@ -216,9 +218,10 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
allTilesLoaded = false;
fullyLoaded = tileGrid.forEachTileCoordParentTileRange(
tile.tileCoord, findLoadedTiles);
tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
if (!fullyLoaded) {
childTileRange = tileGrid.getTileCoordChildTileRange(tile.tileCoord);
childTileRange = tileGrid.getTileCoordChildTileRange(
tile.tileCoord, tmpTileRange, tmpExtent);
if (!goog.isNull(childTileRange)) {
findLoadedTiles(z + 1, childTileRange);
}
@@ -232,7 +235,7 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
goog.array.sort(zs);
var opaque = tileSource.getOpaque();
var origin = tileGrid.getTileCoordExtent(new ol.TileCoord(
z, canvasTileRange.minX, canvasTileRange.maxY)).getTopLeft();
z, canvasTileRange.minX, canvasTileRange.maxY), tmpExtent).getTopLeft();
var currentZ, i, index, scale, tileCoordKey, tileExtent, tilesToDraw;
var ix, iy, interimTileExtent, interimTileRange, maxX, maxY;
var height, width;
@@ -263,7 +266,7 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
scale = tileGrid.getResolution(currentZ) / tileResolution;
for (tileCoordKey in tilesToDraw) {
tile = tilesToDraw[tileCoordKey];
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord);
tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
x = (tileExtent.minX - origin[0]) / tileResolution;
y = (origin[1] - tileExtent.maxY) / tileResolution;
width = scale * tileSize.width;
@@ -276,7 +279,7 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
context.drawImage(tile.getImage(), x, y, width, height);
}
interimTileRange =
tileGrid.getTileRangeForExtentAndZ(tileExtent, z);
tileGrid.getTileRangeForExtentAndZ(tileExtent, z, tmpTileRange);
minX = Math.max(interimTileRange.minX, canvasTileRange.minX);
maxX = Math.min(interimTileRange.maxX, canvasTileRange.maxX);
minY = Math.max(interimTileRange.minY, canvasTileRange.minY);

View File

@@ -14,6 +14,7 @@ goog.require('ol.Coordinate');
goog.require('ol.Extent');
goog.require('ol.Tile');
goog.require('ol.TileCoord');
goog.require('ol.TileRange');
goog.require('ol.TileState');
goog.require('ol.ViewHint');
goog.require('ol.dom');
@@ -115,6 +116,8 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
tilesToDrawByZ, getTileIfLoaded);
var allTilesLoaded = true;
var tmpExtent = new ol.Extent(0, 0, 0, 0);
var tmpTileRange = new ol.TileRange(0, 0, 0, 0);
var childTileRange, fullyLoaded, tile, tileState, x, y;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
@@ -131,9 +134,10 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
allTilesLoaded = false;
fullyLoaded = tileGrid.forEachTileCoordParentTileRange(
tile.tileCoord, findLoadedTiles);
tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
if (!fullyLoaded) {
childTileRange = tileGrid.getTileCoordChildTileRange(tile.tileCoord);
childTileRange = tileGrid.getTileCoordChildTileRange(
tile.tileCoord, tmpTileRange, tmpExtent);
if (!goog.isNull(childTileRange)) {
findLoadedTiles(z + 1, childTileRange);
}
@@ -212,7 +216,7 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
} else {
if (!frameState.viewHints[ol.ViewHint.ANIMATING] &&
!frameState.viewHints[ol.ViewHint.INTERACTING]) {
tileLayerZ.removeTilesOutsideExtent(extent);
tileLayerZ.removeTilesOutsideExtent(extent, tmpTileRange);
}
}
}
@@ -351,11 +355,12 @@ ol.renderer.dom.TileLayerZ_.prototype.getResolution = function() {
/**
* @param {ol.Extent} extent Extent.
* @param {ol.TileRange=} opt_tileRange Temporary ol.TileRange object.
*/
ol.renderer.dom.TileLayerZ_.prototype.removeTilesOutsideExtent =
function(extent) {
var tileRange =
this.tileGrid_.getTileRangeForExtentAndZ(extent, this.tileCoordOrigin_.z);
function(extent, opt_tileRange) {
var tileRange = this.tileGrid_.getTileRangeForExtentAndZ(
extent, this.tileCoordOrigin_.z, opt_tileRange);
var tilesToRemove = [];
var tile, tileCoordKey;
for (tileCoordKey in this.tiles_) {

View File

@@ -199,6 +199,8 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
tilesToDrawByZ, getTileIfLoaded);
var allTilesLoaded = true;
var tmpExtent = new ol.Extent(0, 0, 0, 0);
var tmpTileRange = new ol.TileRange(0, 0, 0, 0);
var childTileRange, fullyLoaded, tile, tileState, x, y;
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
@@ -217,9 +219,10 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
allTilesLoaded = false;
fullyLoaded = tileGrid.forEachTileCoordParentTileRange(
tile.tileCoord, findLoadedTiles);
tile.tileCoord, findLoadedTiles, null, tmpTileRange, tmpExtent);
if (!fullyLoaded) {
childTileRange = tileGrid.getTileCoordChildTileRange(tile.tileCoord);
childTileRange = tileGrid.getTileCoordChildTileRange(
tile.tileCoord, tmpTileRange, tmpExtent);
if (!goog.isNull(childTileRange)) {
findLoadedTiles(z + 1, childTileRange);
}
@@ -235,7 +238,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
var u_tileOffset = goog.vec.Vec4.createFloat32();
goog.array.forEach(zs, function(z) {
goog.object.forEach(tilesToDrawByZ[z], function(tile) {
var tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord);
var tileExtent = tileGrid.getTileCoordExtent(tile.tileCoord, tmpExtent);
var sx = 2 * tileExtent.getWidth() / framebufferExtentSize.width;
var sy = 2 * tileExtent.getHeight() / framebufferExtentSize.height;
var tx = 2 * (tileExtent.minX - framebufferExtent.minX) /

View File

@@ -6,6 +6,7 @@ goog.require('goog.asserts');
goog.require('goog.math');
goog.require('goog.object');
goog.require('goog.uri.utils');
goog.require('ol.Extent');
goog.require('ol.TileCoord');
goog.require('ol.TileUrlFunction');
goog.require('ol.TileUrlFunctionType');
@@ -113,6 +114,8 @@ ol.source.WMTS = function(options) {
}));
}
var tmpExtent = new ol.Extent(0, 0, 0, 0);
var tmpTileCoord = new ol.TileCoord(0, 0, 0);
tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
function(tileCoord, projection) {
var tileGrid = this.getTileGrid();
@@ -134,8 +137,10 @@ ol.source.WMTS = function(options) {
(extent.maxX - extent.minX) /
(tileExtent.maxX - tileExtent.minX));
x = goog.math.modulo(x, numCols);
tileExtent = tileGrid.getTileCoordExtent(
new ol.TileCoord(tileCoord.z, x, tileCoord.y));
tmpTileCoord.z = tileCoord.z;
tmpTileCoord.x = x;
tmpTileCoord.y = tileCoord.y;
tileExtent = tileGrid.getTileCoordExtent(tmpTileCoord, tmpExtent);
}
if (!tileExtent.intersects(extent)) {
return null;

View File

@@ -61,6 +61,8 @@ ol.source.XYZ = function(options) {
var extent = options.extent;
if (goog.isDefAndNotNull(extent)) {
var tmpExtent = new ol.Extent(0, 0, 0, 0);
var tmpTileCoord = new ol.TileCoord(0, 0, 0);
tileUrlFunction = ol.TileUrlFunction.withTileCoordTransform(
function(tileCoord) {
if (options.maxZoom < tileCoord.z) {
@@ -72,8 +74,10 @@ ol.source.XYZ = function(options) {
return null;
}
var x = goog.math.modulo(tileCoord.x, n);
var tileExtent = tileGrid.getTileCoordExtent(
new ol.TileCoord(tileCoord.z, x, tileCoord.y));
tmpTileCoord.z = tileCoord.z;
tmpTileCoord.x = x;
tmpTileCoord.y = tileCoord.y;
var tileExtent = tileGrid.getTileCoordExtent(tmpTileCoord, tmpExtent);
// FIXME we shouldn't need a typecast here
if (!tileExtent.intersects(/** @type {ol.Extent} */ (extent))) {
return null;

View File

@@ -83,6 +83,25 @@ ol.TileCoord.createFromString = function(str) {
};
/**
* @param {number} z Z.
* @param {number} x X.
* @param {number} y Y.
* @param {ol.TileCoord|undefined} tileCoord Tile coordinate.
* @return {ol.TileCoord} Tile coordinate.
*/
ol.TileCoord.createOrUpdate = function(z, x, y, tileCoord) {
if (goog.isDef(tileCoord)) {
tileCoord.z = z;
tileCoord.x = x;
tileCoord.y = y;
return tileCoord;
} else {
return new ol.TileCoord(z, x, y);
}
};
/**
* @param {number} z Z.
* @param {number} x X.

View File

@@ -92,20 +92,29 @@ ol.tilegrid.TileGrid = function(options) {
};
/**
* @private
* @type {ol.TileCoord}
*/
ol.tilegrid.TileGrid.tmpTileCoord_ = new ol.TileCoord(0, 0, 0);
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {function(this: T, number, ol.TileRange): boolean} callback Callback.
* @param {T=} opt_obj Object.
* @param {ol.TileRange=} opt_tileRange Temporary ol.TileRange object.
* @param {ol.Extent=} opt_extent Temporary ol.Extent object.
* @return {boolean} Callback succeeded.
* @template T
*/
ol.tilegrid.TileGrid.prototype.forEachTileCoordParentTileRange =
function(tileCoord, callback, opt_obj) {
var tileCoordExtent = this.getTileCoordExtent(tileCoord);
function(tileCoord, callback, opt_obj, opt_tileRange, opt_extent) {
var tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);
var z = tileCoord.z - 1;
while (z >= 0) {
if (callback.call(
opt_obj, z, this.getTileRangeForExtentAndZ(tileCoordExtent, z))) {
if (callback.call(opt_obj, z,
this.getTileRangeForExtentAndZ(tileCoordExtent, z, opt_tileRange))) {
return true;
}
--z;
@@ -168,13 +177,16 @@ ol.tilegrid.TileGrid.prototype.getResolutions = function() {
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {ol.TileRange=} opt_tileRange Temporary ol.TileRange object.
* @param {ol.Extent=} opt_extent Temporary ol.Extent object.
* @return {ol.TileRange} Tile range.
*/
ol.tilegrid.TileGrid.prototype.getTileCoordChildTileRange =
function(tileCoord) {
function(tileCoord, opt_tileRange, opt_extent) {
if (tileCoord.z < this.resolutions_.length) {
var tileCoordExtent = this.getTileCoordExtent(tileCoord);
return this.getTileRangeForExtentAndZ(tileCoordExtent, tileCoord.z + 1);
var tileCoordExtent = this.getTileCoordExtent(tileCoord, opt_extent);
return this.getTileRangeForExtentAndZ(
tileCoordExtent, tileCoord.z + 1, opt_tileRange);
} else {
return null;
}
@@ -184,9 +196,11 @@ ol.tilegrid.TileGrid.prototype.getTileCoordChildTileRange =
/**
* @param {number} z Z.
* @param {ol.TileRange} tileRange Tile range.
* @param {ol.Extent=} opt_extent Temporary ol.Extent object.
* @return {ol.Extent} Extent.
*/
ol.tilegrid.TileGrid.prototype.getTileRangeExtent = function(z, tileRange) {
ol.tilegrid.TileGrid.prototype.getTileRangeExtent =
function(z, tileRange, opt_extent) {
var origin = this.getOrigin(z);
var resolution = this.getResolution(z);
var tileSize = this.getTileSize(z);
@@ -201,26 +215,34 @@ ol.tilegrid.TileGrid.prototype.getTileRangeExtent = function(z, tileRange) {
/**
* @param {ol.Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {ol.TileRange=} opt_tileRange Temporary tile range object.
* @return {ol.TileRange} Tile range.
*/
ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndResolution = function(
extent, resolution) {
var min = this.getTileCoordForXYAndResolution_(
extent.minX, extent.minY, resolution, false);
var max = this.getTileCoordForXYAndResolution_(
extent.maxX, extent.maxY, resolution, true);
return new ol.TileRange(min.x, min.y, max.x, max.y);
ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndResolution =
function(extent, resolution, opt_tileRange) {
var tileCoord = ol.tilegrid.TileGrid.tmpTileCoord_;
this.getTileCoordForXYAndResolution_(
extent.minX, extent.minY, resolution, false, tileCoord);
var minX = tileCoord.x;
var minY = tileCoord.y;
this.getTileCoordForXYAndResolution_(
extent.maxX, extent.maxY, resolution, true, tileCoord);
return ol.TileRange.createOrUpdate(
minX, minY, tileCoord.x, tileCoord.y, opt_tileRange);
};
/**
* @param {ol.Extent} extent Extent.
* @param {number} z Z.
* @param {ol.TileRange=} opt_tileRange Temporary tile range object.
* @return {ol.TileRange} Tile range.
*/
ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndZ = function(extent, z) {
ol.tilegrid.TileGrid.prototype.getTileRangeForExtentAndZ =
function(extent, z, opt_tileRange) {
var resolution = this.getResolution(z);
return this.getTileRangeForExtentAndResolution(extent, resolution);
return this.getTileRangeForExtentAndResolution(
extent, resolution, opt_tileRange);
};
@@ -241,9 +263,11 @@ ol.tilegrid.TileGrid.prototype.getTileCoordCenter = function(tileCoord) {
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @param {ol.Extent=} opt_extent Temporary extent object.
* @return {ol.Extent} Extent.
*/
ol.tilegrid.TileGrid.prototype.getTileCoordExtent = function(tileCoord) {
ol.tilegrid.TileGrid.prototype.getTileCoordExtent =
function(tileCoord, opt_extent) {
var origin = this.getOrigin(tileCoord.z);
var resolution = this.getResolution(tileCoord.z);
var tileSize = this.getTileSize(tileCoord.z);
@@ -251,7 +275,7 @@ ol.tilegrid.TileGrid.prototype.getTileCoordExtent = function(tileCoord) {
var minY = origin[1] + tileCoord.y * tileSize.height * resolution;
var maxX = minX + tileSize.width * resolution;
var maxY = minY + tileSize.height * resolution;
return new ol.Extent(minX, minY, maxX, maxY);
return ol.Extent.createOrUpdate(minX, minY, maxX, maxY, opt_extent);
};
@@ -262,12 +286,13 @@ ol.tilegrid.TileGrid.prototype.getTileCoordExtent = function(tileCoord) {
*
* @param {ol.Coordinate} coordinate Coordinate.
* @param {number} resolution Resolution.
* @param {ol.TileCoord=} opt_tileCoord Destination ol.TileCoord object.
* @return {ol.TileCoord} Tile coordinate.
*/
ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution = function(
coordinate, resolution) {
coordinate, resolution, opt_tileCoord) {
return this.getTileCoordForXYAndResolution_(
coordinate[0], coordinate[1], resolution, false);
coordinate[0], coordinate[1], resolution, false, opt_tileCoord);
};
@@ -278,11 +303,12 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndResolution = function(
* @param {boolean} reverseIntersectionPolicy Instead of letting edge
* intersections go to the higher tile coordinate, let edge intersections
* go to the lower tile coordinate.
* @param {ol.TileCoord=} opt_tileCoord Temporary ol.TileCoord object.
* @return {ol.TileCoord} Tile coordinate.
* @private
*/
ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function(
x, y, resolution, reverseIntersectionPolicy) {
x, y, resolution, reverseIntersectionPolicy, opt_tileCoord) {
var z = this.getZForResolution(resolution);
var scale = resolution / this.getResolution(z);
var origin = this.getOrigin(z);
@@ -299,20 +325,21 @@ ol.tilegrid.TileGrid.prototype.getTileCoordForXYAndResolution_ = function(
tileCoordY = Math.floor(tileCoordY);
}
return new ol.TileCoord(z, tileCoordX, tileCoordY);
return ol.TileCoord.createOrUpdate(z, tileCoordX, tileCoordY, opt_tileCoord);
};
/**
* @param {ol.Coordinate} coordinate Coordinate.
* @param {number} z Z.
* @param {ol.TileCoord=} opt_tileCoord Destination ol.TileCoord object.
* @return {ol.TileCoord} Tile coordinate.
*/
ol.tilegrid.TileGrid.prototype.getTileCoordForCoordAndZ =
function(coordinate, z) {
function(coordinate, z, opt_tileCoord) {
var resolution = this.getResolution(z);
return this.getTileCoordForXYAndResolution_(
coordinate[0], coordinate[1], resolution, false);
coordinate[0], coordinate[1], resolution, false, opt_tileCoord);
};

View File

@@ -42,11 +42,13 @@ goog.inherits(ol.tilegrid.XYZ, ol.tilegrid.TileGrid);
/**
* @inheritDoc
*/
ol.tilegrid.XYZ.prototype.getTileCoordChildTileRange = function(tileCoord) {
ol.tilegrid.XYZ.prototype.getTileCoordChildTileRange =
function(tileCoord, opt_tileRange) {
if (tileCoord.z < this.maxZoom_) {
return new ol.TileRange(
return ol.TileRange.createOrUpdate(
tileCoord.x << 1, tileCoord.y << 1,
tileCoord.x + 1 << 1, tileCoord.y + 1 << 1);
tileCoord.x + 1 << 1, tileCoord.y + 1 << 1,
opt_tileRange);
} else {
return null;
}
@@ -57,8 +59,9 @@ ol.tilegrid.XYZ.prototype.getTileCoordChildTileRange = function(tileCoord) {
* @inheritDoc
*/
ol.tilegrid.XYZ.prototype.forEachTileCoordParentTileRange =
function(tileCoord, callback, opt_obj) {
var tileRange = new ol.TileRange(0, 0, tileCoord.x, tileCoord.y);
function(tileCoord, callback, opt_obj, opt_tileRange) {
var tileRange = ol.TileRange.createOrUpdate(
0, 0, tileCoord.x, tileCoord.y, opt_tileRange);
var z;
for (z = tileCoord.z - 1; z >= 0; --z) {
tileRange.minX = tileRange.maxX >>= 1;

View File

@@ -64,6 +64,27 @@ ol.TileRange.boundingTileRange = function(var_args) {
};
/**
* @param {number} minX Minimum X.
* @param {number} minY Minimum Y.
* @param {number} maxX Maximum X.
* @param {number} maxY Maximum Y.
* @param {ol.TileRange|undefined} tileRange TileRange.
* @return {ol.TileRange} Tile range.
*/
ol.TileRange.createOrUpdate = function(minX, minY, maxX, maxY, tileRange) {
if (goog.isDef(tileRange)) {
tileRange.minX = minX;
tileRange.minY = minY;
tileRange.maxX = maxX;
tileRange.maxY = maxY;
return tileRange;
} else {
return new ol.TileRange(minX, minY, maxX, maxY);
}
};
/**
* @param {ol.TileCoord} tileCoord Tile coordinate.
* @return {boolean} Contains tile coordinate.

View File

@@ -3,6 +3,7 @@ goog.provide('ol.TileUrlFunctionType');
goog.require('goog.array');
goog.require('goog.math');
goog.require('ol.Extent');
goog.require('ol.TileCoord');
@@ -68,6 +69,7 @@ ol.TileUrlFunction.createFromTileUrlFunctions = function(tileUrlFunctions) {
*/
ol.TileUrlFunction.createFromParamsFunction =
function(baseUrl, params, paramsFunction) {
var tmpExtent = new ol.Extent(0, 0, 0, 0);
return function(tileCoord, projection) {
if (goog.isNull(tileCoord)) {
return undefined;
@@ -77,7 +79,7 @@ ol.TileUrlFunction.createFromParamsFunction =
tileGrid = ol.tilegrid.getForProjection(projection);
}
var size = tileGrid.getTileSize(tileCoord.z);
var extent = tileGrid.getTileCoordExtent(tileCoord);
var extent = tileGrid.getTileCoordExtent(tileCoord, tmpExtent);
return paramsFunction.call(this, baseUrl, params,
extent, size, projection);
}