diff --git a/src/ol/framestate.js b/src/ol/framestate.js index 574fefe20f..d0b7ec4570 100644 --- a/src/ol/framestate.js +++ b/src/ol/framestate.js @@ -1,4 +1,6 @@ // FIXME add view3DState +// FIXME rename tileUsage to usedTiles +// FIXME factor out common code between tileUsage and wantedTiles goog.provide('ol.FrameState'); goog.provide('ol.PostRenderFunction'); @@ -29,7 +31,8 @@ goog.require('ol.layer.LayerState'); * tileUsage: Object.>, * time: number, * view2DState: ol.View2DState, - * viewHints: Array.}} + * viewHints: Array., + * wantedTiles: Object.>}} */ ol.FrameState; diff --git a/src/ol/map.js b/src/ol/map.js index 2609269db2..33fdaed885 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -453,19 +453,24 @@ ol.Map.prototype.getOverlayContainer = function() { /** * @param {ol.Tile} tile Tile. + * @param {string} tileSourceKey Tile source key. * @param {ol.Coordinate} tileCenter Tile center. - * @param {number} tileResolution Tile resolution. * @return {number|undefined} Tile priority. */ -ol.Map.prototype.getTilePriority = function(tile, tileCenter, tileResolution) { - if (goog.isNull(this.frameState_)) { +ol.Map.prototype.getTilePriority = function(tile, tileSourceKey, tileCenter) { + var frameState = this.frameState_; + if (goog.isNull(frameState) || !(tileSourceKey in frameState.wantedTiles)) { return undefined; - } else { - var center = this.frameState_.view2DState.center; - var deltaX = tileCenter.x - center.x; - var deltaY = tileCenter.y - center.y; - return Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution; } + var zKey = tile.tileCoord.z.toString(); + if (!(zKey in frameState.wantedTiles[tileSourceKey]) || + !frameState.wantedTiles[tileSourceKey][zKey].contains(tile.tileCoord)) { + return undefined; + } + var center = frameState.view2DState.center; + var deltaX = tileCenter.x - center.x; + var deltaY = tileCenter.y - center.y; + return deltaX * deltaX + deltaY * deltaY; }; @@ -630,7 +635,8 @@ ol.Map.prototype.renderFrame_ = function(time) { tileUsage: {}, time: time, view2DState: view2DState, - viewHints: viewHints + viewHints: viewHints, + wantedTiles: {} }; } diff --git a/src/ol/renderer/canvas/canvastilelayerrenderer.js b/src/ol/renderer/canvas/canvastilelayerrenderer.js index 4c17795648..66c9cf6e25 100644 --- a/src/ol/renderer/canvas/canvastilelayerrenderer.js +++ b/src/ol/renderer/canvas/canvastilelayerrenderer.js @@ -87,6 +87,7 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = var tileLayer = this.getTileLayer(); var tileSource = tileLayer.getTileSource(); + var tileSourceKey = goog.getUid(tileSource).toString(); var tileGrid = tileSource.getTileGrid(); var tileSize = tileGrid.getTileSize(); var z = tileGrid.getZForResolution(view2DState.resolution); @@ -165,7 +166,7 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = tileState = tile.getState(); if (tileState == ol.TileState.IDLE) { tileCenter = tileGrid.getTileCoordCenter(tileCoord); - frameState.tileQueue.enqueue(tile, tileCenter, tileResolution); + frameState.tileQueue.enqueue(tile, tileSourceKey, tileCenter); } else if (tileState == ol.TileState.LOADED) { tilesToDrawByZ[z][tileCoord.toString()] = tile; continue; @@ -216,6 +217,7 @@ ol.renderer.canvas.TileLayer.prototype.renderFrame = } this.updateTileUsage(frameState.tileUsage, tileSource, z, tileRange); + this.updateWantedTiles(frameState.wantedTiles, tileSource, z, tileRange); var transform = this.transform_; goog.vec.Mat4.makeIdentity(transform); diff --git a/src/ol/renderer/dom/domtilelayerrenderer.js b/src/ol/renderer/dom/domtilelayerrenderer.js index 58a55295f7..fa9a86b1ae 100644 --- a/src/ol/renderer/dom/domtilelayerrenderer.js +++ b/src/ol/renderer/dom/domtilelayerrenderer.js @@ -83,6 +83,7 @@ ol.renderer.dom.TileLayer.prototype.renderFrame = var tileLayer = this.getTileLayer(); var tileSource = tileLayer.getTileSource(); + var tileSourceKey = goog.getUid(tileSource).toString(); var tileGrid = tileSource.getTileGrid(); var z = tileGrid.getZForResolution(view2DState.resolution); var tileResolution = tileGrid.getResolution(z); @@ -132,7 +133,7 @@ ol.renderer.dom.TileLayer.prototype.renderFrame = tileState = tile.getState(); if (tileState == ol.TileState.IDLE) { tileCenter = tileGrid.getTileCoordCenter(tileCoord); - frameState.tileQueue.enqueue(tile, tileCenter, tileResolution); + frameState.tileQueue.enqueue(tile, tileSourceKey, tileCenter); } else if (tileState == ol.TileState.LOADED) { tilesToDrawByZ[z][tileCoord.toString()] = tile; continue; @@ -237,6 +238,7 @@ ol.renderer.dom.TileLayer.prototype.renderFrame = } this.updateTileUsage(frameState.tileUsage, tileSource, z, tileRange); + this.updateWantedTiles(frameState.wantedTiles, tileSource, z, tileRange); }; diff --git a/src/ol/renderer/layerrenderer.js b/src/ol/renderer/layerrenderer.js index 6e1a4fd729..c019c12276 100644 --- a/src/ol/renderer/layerrenderer.js +++ b/src/ol/renderer/layerrenderer.js @@ -151,3 +151,28 @@ ol.renderer.Layer.prototype.updateTileUsage = tileUsage[sourceKey][zKey] = tileRange; } }; + + +/** + * @protected + * @param {Object.>} wantedTiles Wanted + * tile ranges. + * @param {ol.source.Source} source Source. + * @param {number} z Z. + * @param {ol.TileRange} tileRange Tile range. + */ +ol.renderer.Layer.prototype.updateWantedTiles = + function(wantedTiles, source, z, tileRange) { + var sourceKey = goog.getUid(source).toString(); + var zKey = z.toString(); + if (sourceKey in wantedTiles) { + if (zKey in wantedTiles[sourceKey]) { + wantedTiles[sourceKey][zKey].extend(tileRange); + } else { + wantedTiles[sourceKey][zKey] = tileRange; + } + } else { + wantedTiles[sourceKey] = {}; + wantedTiles[sourceKey][zKey] = tileRange; + } +}; diff --git a/src/ol/renderer/webgl/webgltilelayerrenderer.js b/src/ol/renderer/webgl/webgltilelayerrenderer.js index de1f18e1e2..93654d0a98 100644 --- a/src/ol/renderer/webgl/webgltilelayerrenderer.js +++ b/src/ol/renderer/webgl/webgltilelayerrenderer.js @@ -270,6 +270,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = var tileLayer = this.getTileLayer(); var tileSource = tileLayer.getTileSource(); + var tileSourceKey = goog.getUid(tileSource).toString(); var tileGrid = tileSource.getTileGrid(); var z = tileGrid.getZForResolution(view2DState.resolution); var tileResolution = tileGrid.getResolution(z); @@ -392,7 +393,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = tileState = tile.getState(); if (tileState == ol.TileState.IDLE) { tileCenter = tileGrid.getTileCoordCenter(tileCoord); - frameState.tileQueue.enqueue(tile, tileCenter, tileResolution); + frameState.tileQueue.enqueue(tile, tileSourceKey, tileCenter); } else if (tileState == ol.TileState.LOADED) { if (mapRenderer.isTileTextureLoaded(tile)) { tilesToDrawByZ[z][tileCoord.toString()] = tile; @@ -460,6 +461,7 @@ ol.renderer.webgl.TileLayer.prototype.renderFrame = } this.updateTileUsage(frameState.tileUsage, tileSource, z, tileRange); + this.updateWantedTiles(frameState.wantedTiles, tileSource, z, tileRange); goog.vec.Mat4.makeIdentity(this.matrix_); goog.vec.Mat4.translate(this.matrix_, diff --git a/src/ol/tilequeue.js b/src/ol/tilequeue.js index 9fea413f33..d914257beb 100644 --- a/src/ol/tilequeue.js +++ b/src/ol/tilequeue.js @@ -21,7 +21,7 @@ goog.require('ol.TileState'); /** - * @typedef {function(ol.Tile, ol.Coordinate, number): (number|undefined)} + * @typedef {function(ol.Tile, string, ol.Coordinate): (number|undefined)} */ ol.TilePriorityFunction; @@ -102,18 +102,18 @@ ol.TileQueue.prototype.dequeue_ = function() { /** * Enqueue a tile. O(logn). * @param {ol.Tile} tile Tile. + * @param {string} tileSourceKey Tile source key. * @param {ol.Coordinate} tileCenter Tile center. - * @param {number} tileResolution Tile resolution. */ -ol.TileQueue.prototype.enqueue = function(tile, tileCenter, tileResolution) { +ol.TileQueue.prototype.enqueue = function(tile, tileSourceKey, tileCenter) { if (tile.getState() != ol.TileState.IDLE) { return; } var tileKey = tile.getKey(); if (!(tileKey in this.queuedTileKeys_)) { - var priority = this.tilePriorityFunction_(tile, tileCenter, tileResolution); + var priority = this.tilePriorityFunction_(tile, tileSourceKey, tileCenter); if (goog.isDef(priority)) { - this.heap_.push([priority, tile, tileCenter, tileResolution]); + this.heap_.push([priority, tile, tileSourceKey, tileCenter]); this.queuedTileKeys_[tileKey] = true; this.siftDown_(0, this.heap_.length - 1); } else { @@ -245,13 +245,13 @@ ol.TileQueue.prototype.siftDown_ = function(startIndex, index) { ol.TileQueue.prototype.reprioritize = function() { var heap = this.heap_; var count = heap.length; - var i, priority, node, tile, tileCenter, tileResolution; + var i, priority, node, tile, tileCenter, tileSourceKey; for (i = count - 1; i >= 0; i--) { node = heap[i]; tile = /** @type {ol.Tile} */ (node[1]); - tileCenter = /** @type {ol.Coordinate} */ (node[2]); - tileResolution = /** @type {number} */ (node[3]); - priority = this.tilePriorityFunction_(tile, tileCenter, tileResolution); + tileSourceKey = /** @type {string} */ (node[2]); + tileCenter = /** @type {ol.Coordinate} */ (node[3]); + priority = this.tilePriorityFunction_(tile, tileSourceKey, tileCenter); if (goog.isDef(priority)) { node[0] = priority; } else { diff --git a/test/spec/ol/tilequeue.test.js b/test/spec/ol/tilequeue.test.js index 3c5bc8a055..f4fa134a1c 100644 --- a/test/spec/ol/tilequeue.test.js +++ b/test/spec/ol/tilequeue.test.js @@ -23,7 +23,7 @@ describe('ol.TileQueue', function() { for (i = 0; i < num; i++) { tile = new ol.Tile(); priority = Math.floor(Math.random() * 100); - tq.heap_.push([priority, tile, new ol.Coordinate(0, 0), 1]); + tq.heap_.push([priority, tile, '', new ol.Coordinate(0, 0)]); tq.queuedTileKeys_[tile.getKey()] = true; } }