Premptively load low resolution tiles
This commit is contained in:
@@ -484,9 +484,13 @@ ol.Map.prototype.getOverlayContainer = function() {
|
|||||||
* @param {ol.Tile} tile Tile.
|
* @param {ol.Tile} tile Tile.
|
||||||
* @param {string} tileSourceKey Tile source key.
|
* @param {string} tileSourceKey Tile source key.
|
||||||
* @param {ol.Coordinate} tileCenter Tile center.
|
* @param {ol.Coordinate} tileCenter Tile center.
|
||||||
|
* @param {number} tileResolution Tile resolution.
|
||||||
* @return {number} Tile priority.
|
* @return {number} Tile priority.
|
||||||
*/
|
*/
|
||||||
ol.Map.prototype.getTilePriority = function(tile, tileSourceKey, tileCenter) {
|
ol.Map.prototype.getTilePriority =
|
||||||
|
function(tile, tileSourceKey, tileCenter, tileResolution) {
|
||||||
|
// Filter out tiles at higher zoom levels than the current zoom level, or that
|
||||||
|
// are outside the visible extent.
|
||||||
var frameState = this.frameState_;
|
var frameState = this.frameState_;
|
||||||
if (goog.isNull(frameState) || !(tileSourceKey in frameState.wantedTiles)) {
|
if (goog.isNull(frameState) || !(tileSourceKey in frameState.wantedTiles)) {
|
||||||
return ol.TileQueue.DROP;
|
return ol.TileQueue.DROP;
|
||||||
@@ -495,11 +499,14 @@ ol.Map.prototype.getTilePriority = function(tile, tileSourceKey, tileCenter) {
|
|||||||
if (!frameState.wantedTiles[tileSourceKey][coordKey]) {
|
if (!frameState.wantedTiles[tileSourceKey][coordKey]) {
|
||||||
return ol.TileQueue.DROP;
|
return ol.TileQueue.DROP;
|
||||||
}
|
}
|
||||||
|
// Prioritize tiles closest to the focus or center. The + 1 helps to
|
||||||
|
// prioritize tiles at higher zoom levels over tiles at lower zoom levels,
|
||||||
|
// even if the tile's center is close to the focus.
|
||||||
var focus = goog.isNull(this.focus_) ?
|
var focus = goog.isNull(this.focus_) ?
|
||||||
frameState.view2DState.center : this.focus_;
|
frameState.view2DState.center : this.focus_;
|
||||||
var deltaX = tileCenter.x - focus.x;
|
var deltaX = tileCenter.x - focus.x;
|
||||||
var deltaY = tileCenter.y - focus.y;
|
var deltaY = tileCenter.y - focus.y;
|
||||||
return deltaX * deltaX + deltaY * deltaY;
|
return tileResolution * (deltaX * deltaX + deltaY * deltaY + 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,6 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
|
|||||||
|
|
||||||
var tileLayer = this.getTileLayer();
|
var tileLayer = this.getTileLayer();
|
||||||
var tileSource = tileLayer.getTileSource();
|
var tileSource = tileLayer.getTileSource();
|
||||||
var tileSourceKey = goog.getUid(tileSource).toString();
|
|
||||||
var tileGrid = tileSource.getTileGrid();
|
var tileGrid = tileSource.getTileGrid();
|
||||||
if (goog.isNull(tileGrid)) {
|
if (goog.isNull(tileGrid)) {
|
||||||
tileGrid = ol.tilegrid.getForProjection(projection);
|
tileGrid = ol.tilegrid.getForProjection(projection);
|
||||||
@@ -156,19 +155,14 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
|
|||||||
tilesToDrawByZ, getTileIfLoaded);
|
tilesToDrawByZ, getTileIfLoaded);
|
||||||
|
|
||||||
var allTilesLoaded = true;
|
var allTilesLoaded = true;
|
||||||
var tile, tileCenter, tileCoord, tileState, x, y;
|
var tile, tileCoord, tileState, x, y;
|
||||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||||
|
|
||||||
tileCoord = new ol.TileCoord(z, x, y);
|
tileCoord = new ol.TileCoord(z, x, y);
|
||||||
tile = tileSource.getTile(tileCoord, tileGrid, projection);
|
tile = tileSource.getTile(tileCoord, tileGrid, projection);
|
||||||
tileState = tile.getState();
|
tileState = tile.getState();
|
||||||
if (tileState == ol.TileState.IDLE) {
|
if (tileState == ol.TileState.LOADED || tileState == ol.TileState.EMPTY) {
|
||||||
this.updateWantedTiles(frameState.wantedTiles, tileSource, tileCoord);
|
|
||||||
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
|
|
||||||
frameState.tileQueue.enqueue(tile, tileSourceKey, tileCenter);
|
|
||||||
} else if (tileState == ol.TileState.LOADED ||
|
|
||||||
tileState == ol.TileState.EMPTY) {
|
|
||||||
tilesToDrawByZ[z][tileCoord.toString()] = tile;
|
tilesToDrawByZ[z][tileCoord.toString()] = tile;
|
||||||
continue;
|
continue;
|
||||||
} else if (tileState == ol.TileState.ERROR) {
|
} else if (tileState == ol.TileState.ERROR) {
|
||||||
@@ -246,6 +240,8 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame =
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
||||||
|
this.manageTilePyramid(
|
||||||
|
frameState, tileSource, tileGrid, projection, extent, z);
|
||||||
this.scheduleExpireCache(frameState, tileSource);
|
this.scheduleExpireCache(frameState, tileSource);
|
||||||
|
|
||||||
var transform = this.transform_;
|
var transform = this.transform_;
|
||||||
|
|||||||
@@ -83,7 +83,6 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
|
|||||||
|
|
||||||
var tileLayer = this.getTileLayer();
|
var tileLayer = this.getTileLayer();
|
||||||
var tileSource = tileLayer.getTileSource();
|
var tileSource = tileLayer.getTileSource();
|
||||||
var tileSourceKey = goog.getUid(tileSource).toString();
|
|
||||||
var tileGrid = tileSource.getTileGrid();
|
var tileGrid = tileSource.getTileGrid();
|
||||||
if (goog.isNull(tileGrid)) {
|
if (goog.isNull(tileGrid)) {
|
||||||
tileGrid = ol.tilegrid.getForProjection(projection);
|
tileGrid = ol.tilegrid.getForProjection(projection);
|
||||||
@@ -113,18 +112,14 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
|
|||||||
tilesToDrawByZ, getTileIfLoaded);
|
tilesToDrawByZ, getTileIfLoaded);
|
||||||
|
|
||||||
var allTilesLoaded = true;
|
var allTilesLoaded = true;
|
||||||
var tile, tileCenter, tileCoord, tileState, x, y;
|
var tile, tileCoord, tileState, x, y;
|
||||||
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||||
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||||
|
|
||||||
tileCoord = new ol.TileCoord(z, x, y);
|
tileCoord = new ol.TileCoord(z, x, y);
|
||||||
tile = tileSource.getTile(tileCoord, tileGrid, projection);
|
tile = tileSource.getTile(tileCoord, tileGrid, projection);
|
||||||
tileState = tile.getState();
|
tileState = tile.getState();
|
||||||
if (tileState == ol.TileState.IDLE) {
|
if (tileState == ol.TileState.LOADED) {
|
||||||
this.updateWantedTiles(frameState.wantedTiles, tileSource, tileCoord);
|
|
||||||
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
|
|
||||||
frameState.tileQueue.enqueue(tile, tileSourceKey, tileCenter);
|
|
||||||
} else if (tileState == ol.TileState.LOADED) {
|
|
||||||
tilesToDrawByZ[z][tileCoord.toString()] = tile;
|
tilesToDrawByZ[z][tileCoord.toString()] = tile;
|
||||||
continue;
|
continue;
|
||||||
} else if (tileState == ol.TileState.ERROR ||
|
} else if (tileState == ol.TileState.ERROR ||
|
||||||
@@ -224,6 +219,8 @@ ol.renderer.dom.TileLayer.prototype.renderFrame =
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
||||||
|
this.manageTilePyramid(
|
||||||
|
frameState, tileSource, tileGrid, projection, extent, z);
|
||||||
this.scheduleExpireCache(frameState, tileSource);
|
this.scheduleExpireCache(frameState, tileSource);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,6 +18,12 @@ goog.require('ol.layer.LayerState');
|
|||||||
goog.require('ol.source.TileSource');
|
goog.require('ol.source.TileSource');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @define {boolean} Preemptively load low resolution tiles.
|
||||||
|
*/
|
||||||
|
ol.PREEMPTIVELY_LOAD_LOW_RESOLUTION_TILES = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
@@ -246,23 +252,6 @@ ol.renderer.Layer.prototype.updateUsedTiles =
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @protected
|
|
||||||
* @param {Object.<string, Object.<string, boolean>>} wantedTiles Wanted tiles.
|
|
||||||
* @param {ol.source.TileSource} tileSource Tile source.
|
|
||||||
* @param {ol.TileCoord} tileCoord Tile coordinate.
|
|
||||||
*/
|
|
||||||
ol.renderer.Layer.prototype.updateWantedTiles =
|
|
||||||
function(wantedTiles, tileSource, tileCoord) {
|
|
||||||
var tileSourceKey = goog.getUid(tileSource).toString();
|
|
||||||
var coordKey = tileCoord.toString();
|
|
||||||
if (!(tileSourceKey in wantedTiles)) {
|
|
||||||
wantedTiles[tileSourceKey] = {};
|
|
||||||
}
|
|
||||||
wantedTiles[tileSourceKey][coordKey] = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {function(ol.Tile): boolean} isLoadedFunction Function to
|
* @param {function(ol.Tile): boolean} isLoadedFunction Function to
|
||||||
* determine if the tile is loaded.
|
* determine if the tile is loaded.
|
||||||
@@ -293,3 +282,50 @@ ol.renderer.Layer.prototype.snapCenterToPixel =
|
|||||||
resolution * (Math.round(center.x / resolution) + (size.width % 2) / 2),
|
resolution * (Math.round(center.x / resolution) + (size.width % 2) / 2),
|
||||||
resolution * (Math.round(center.y / resolution) + (size.height % 2) / 2));
|
resolution * (Math.round(center.y / resolution) + (size.height % 2) / 2));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manage tile pyramid.
|
||||||
|
* This function performs a number of functions related to the tiles at the
|
||||||
|
* current zoom and lower zoom levels:
|
||||||
|
* - registers idle tiles in frameState.wantedTiles so that they are not
|
||||||
|
* discarded by the tile queue
|
||||||
|
* - enqueues missing tiles
|
||||||
|
* @param {ol.FrameState} frameState Frame state.
|
||||||
|
* @param {ol.source.TileSource} tileSource Tile source.
|
||||||
|
* @param {ol.tilegrid.TileGrid} tileGrid Tile grid.
|
||||||
|
* @param {ol.Projection} projection Projection.
|
||||||
|
* @param {ol.Extent} extent Extent.
|
||||||
|
* @param {number} currentZ Current Z.
|
||||||
|
* @protected
|
||||||
|
*/
|
||||||
|
ol.renderer.Layer.prototype.manageTilePyramid =
|
||||||
|
function(frameState, tileSource, tileGrid, projection, extent, currentZ) {
|
||||||
|
var tileSourceKey = goog.getUid(tileSource).toString();
|
||||||
|
if (!(tileSourceKey in frameState.wantedTiles)) {
|
||||||
|
frameState.wantedTiles[tileSourceKey] = {};
|
||||||
|
}
|
||||||
|
var wantedTiles = frameState.wantedTiles[tileSourceKey];
|
||||||
|
var tileQueue = frameState.tileQueue;
|
||||||
|
var tile, tileCenter, tileCoord, tileRange, tileResolution, x, y, z;
|
||||||
|
// FIXME this should loop up to tileGrid's minZ when implemented
|
||||||
|
for (z = currentZ; z >= 0; --z) {
|
||||||
|
tileRange = tileGrid.getTileRangeForExtentAndZ(extent, z);
|
||||||
|
tileResolution = tileGrid.getResolution(z);
|
||||||
|
for (x = tileRange.minX; x <= tileRange.maxX; ++x) {
|
||||||
|
for (y = tileRange.minY; y <= tileRange.maxY; ++y) {
|
||||||
|
if (ol.PREEMPTIVELY_LOAD_LOW_RESOLUTION_TILES || z == currentZ) {
|
||||||
|
tileCoord = new ol.TileCoord(z, x, y);
|
||||||
|
tile = tileSource.getTile(tileCoord, tileGrid, projection);
|
||||||
|
if (tile.getState() == ol.TileState.IDLE) {
|
||||||
|
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
|
||||||
|
wantedTiles[tileCoord.toString()] = true;
|
||||||
|
tileQueue.enqueue(tile, tileSourceKey, tileCenter, tileResolution);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
tileSource.useTile(z + '/' + x + '/' + y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|||||||
@@ -285,7 +285,6 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
|
|||||||
|
|
||||||
var tileLayer = this.getTileLayer();
|
var tileLayer = this.getTileLayer();
|
||||||
var tileSource = tileLayer.getTileSource();
|
var tileSource = tileLayer.getTileSource();
|
||||||
var tileSourceKey = goog.getUid(tileSource).toString();
|
|
||||||
var tileGrid = tileSource.getTileGrid();
|
var tileGrid = tileSource.getTileGrid();
|
||||||
if (goog.isNull(tileGrid)) {
|
if (goog.isNull(tileGrid)) {
|
||||||
tileGrid = ol.tilegrid.getForProjection(projection);
|
tileGrid = ol.tilegrid.getForProjection(projection);
|
||||||
@@ -394,11 +393,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
|
|||||||
tileCoord = new ol.TileCoord(z, x, y);
|
tileCoord = new ol.TileCoord(z, x, y);
|
||||||
tile = tileSource.getTile(tileCoord, tileGrid, projection);
|
tile = tileSource.getTile(tileCoord, tileGrid, projection);
|
||||||
tileState = tile.getState();
|
tileState = tile.getState();
|
||||||
if (tileState == ol.TileState.IDLE) {
|
if (tileState == ol.TileState.LOADED) {
|
||||||
this.updateWantedTiles(frameState.wantedTiles, tileSource, tileCoord);
|
|
||||||
tileCenter = tileGrid.getTileCoordCenter(tileCoord);
|
|
||||||
frameState.tileQueue.enqueue(tile, tileSourceKey, tileCenter);
|
|
||||||
} else if (tileState == ol.TileState.LOADED) {
|
|
||||||
if (mapRenderer.isTileTextureLoaded(tile)) {
|
if (mapRenderer.isTileTextureLoaded(tile)) {
|
||||||
tilesToDrawByZ[z][tileCoord.toString()] = tile;
|
tilesToDrawByZ[z][tileCoord.toString()] = tile;
|
||||||
continue;
|
continue;
|
||||||
@@ -466,6 +461,8 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame =
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
this.updateUsedTiles(frameState.usedTiles, tileSource, z, tileRange);
|
||||||
|
this.manageTilePyramid(
|
||||||
|
frameState, tileSource, tileGrid, projection, extent, z);
|
||||||
this.scheduleExpireCache(frameState, tileSource);
|
this.scheduleExpireCache(frameState, tileSource);
|
||||||
|
|
||||||
goog.vec.Mat4.makeIdentity(this.texCoordMatrix_);
|
goog.vec.Mat4.makeIdentity(this.texCoordMatrix_);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ goog.require('ol.TileState');
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {function(ol.Tile, string, ol.Coordinate): number}
|
* @typedef {function(ol.Tile, string, ol.Coordinate, number): number}
|
||||||
*/
|
*/
|
||||||
ol.TilePriorityFunction;
|
ol.TilePriorityFunction;
|
||||||
|
|
||||||
@@ -106,16 +106,20 @@ ol.TileQueue.prototype.dequeue_ = function() {
|
|||||||
* @param {ol.Tile} tile Tile.
|
* @param {ol.Tile} tile Tile.
|
||||||
* @param {string} tileSourceKey Tile source key.
|
* @param {string} tileSourceKey Tile source key.
|
||||||
* @param {ol.Coordinate} tileCenter Tile center.
|
* @param {ol.Coordinate} tileCenter Tile center.
|
||||||
|
* @param {number} tileResolution Tile resolution.
|
||||||
*/
|
*/
|
||||||
ol.TileQueue.prototype.enqueue = function(tile, tileSourceKey, tileCenter) {
|
ol.TileQueue.prototype.enqueue = function(
|
||||||
|
tile, tileSourceKey, tileCenter, tileResolution) {
|
||||||
if (tile.getState() != ol.TileState.IDLE) {
|
if (tile.getState() != ol.TileState.IDLE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var tileKey = tile.getKey();
|
var tileKey = tile.getKey();
|
||||||
if (!(tileKey in this.queuedTileKeys_)) {
|
if (!(tileKey in this.queuedTileKeys_)) {
|
||||||
var priority = this.tilePriorityFunction_(tile, tileSourceKey, tileCenter);
|
var priority = this.tilePriorityFunction_(
|
||||||
|
tile, tileSourceKey, tileCenter, tileResolution);
|
||||||
if (priority != ol.TileQueue.DROP) {
|
if (priority != ol.TileQueue.DROP) {
|
||||||
this.heap_.push([priority, tile, tileSourceKey, tileCenter]);
|
this.heap_.push(
|
||||||
|
[priority, tile, tileSourceKey, tileCenter, tileResolution]);
|
||||||
this.queuedTileKeys_[tileKey] = true;
|
this.queuedTileKeys_[tileKey] = true;
|
||||||
this.siftDown_(0, this.heap_.length - 1);
|
this.siftDown_(0, this.heap_.length - 1);
|
||||||
}
|
}
|
||||||
@@ -245,13 +249,16 @@ ol.TileQueue.prototype.siftDown_ = function(startIndex, index) {
|
|||||||
*/
|
*/
|
||||||
ol.TileQueue.prototype.reprioritize = function() {
|
ol.TileQueue.prototype.reprioritize = function() {
|
||||||
var heap = this.heap_;
|
var heap = this.heap_;
|
||||||
var i, n = 0, node, priority, tile, tileCenter, tileKey, tileSourceKey;
|
var i, n = 0, node, priority;
|
||||||
|
var tile, tileCenter, tileKey, tileResolution, tileSourceKey;
|
||||||
for (i = 0; i < heap.length; ++i) {
|
for (i = 0; i < heap.length; ++i) {
|
||||||
node = heap[i];
|
node = heap[i];
|
||||||
tile = /** @type {ol.Tile} */ (node[1]);
|
tile = /** @type {ol.Tile} */ (node[1]);
|
||||||
tileSourceKey = /** @type {string} */ (node[2]);
|
tileSourceKey = /** @type {string} */ (node[2]);
|
||||||
tileCenter = /** @type {ol.Coordinate} */ (node[3]);
|
tileCenter = /** @type {ol.Coordinate} */ (node[3]);
|
||||||
priority = this.tilePriorityFunction_(tile, tileSourceKey, tileCenter);
|
tileResolution = /** @type {number} */ (node[4]);
|
||||||
|
priority = this.tilePriorityFunction_(
|
||||||
|
tile, tileSourceKey, tileCenter, tileResolution);
|
||||||
if (priority == ol.TileQueue.DROP) {
|
if (priority == ol.TileQueue.DROP) {
|
||||||
tileKey = tile.getKey();
|
tileKey = tile.getKey();
|
||||||
delete this.queuedTileKeys_[tileKey];
|
delete this.queuedTileKeys_[tileKey];
|
||||||
|
|||||||
Reference in New Issue
Block a user