diff --git a/src/ol/PluggableMap.js b/src/ol/PluggableMap.js index 5c47f8dffd..97ecd273ec 100644 --- a/src/ol/PluggableMap.js +++ b/src/ol/PluggableMap.js @@ -41,7 +41,6 @@ import {create as createTransform, apply as applyTransform} from './transform.js * @property {null|import("./extent.js").Extent} extent * @property {import("./coordinate.js").Coordinate} focus * @property {number} index - * @property {Object} layerStates * @property {Array} layerStatesArray * @property {import("./transform.js").Transform} pixelToCoordinateTransform * @property {Array} postRenderFunctions @@ -55,7 +54,7 @@ import {create as createTransform, apply as applyTransform} from './transform.js /** - * @typedef {function(PluggableMap, ?FrameState): boolean} PostRenderFunction + * @typedef {function(PluggableMap, ?FrameState): any} PostRenderFunction */ @@ -1161,11 +1160,6 @@ class PluggableMap extends BaseObject { let frameState = null; if (size !== undefined && hasArea(size) && view && view.isDef()) { const viewHints = view.getHints(this.frameState_ ? this.frameState_.viewHints : undefined); - const layerStatesArray = this.getLayerGroup().getLayerStatesArray(); - const layerStates = {}; - for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) { - layerStates[getUid(layerStatesArray[i].layer)] = layerStatesArray[i]; - } viewState = view.getState(this.pixelRatio_); frameState = /** @type {FrameState} */ ({ animate: false, @@ -1173,8 +1167,7 @@ class PluggableMap extends BaseObject { extent: extent, focus: this.focus_ ? this.focus_ : viewState.center, index: this.frameIndex_++, - layerStates: layerStates, - layerStatesArray: layerStatesArray, + layerStatesArray: this.getLayerGroup().getLayerStatesArray(), pixelRatio: this.pixelRatio_, pixelToCoordinateTransform: this.pixelToCoordinateTransform_, postRenderFunctions: [], diff --git a/src/ol/layer/Layer.js b/src/ol/layer/Layer.js index 723c7b5be1..d735a4eeef 100644 --- a/src/ol/layer/Layer.js +++ b/src/ol/layer/Layer.js @@ -3,7 +3,6 @@ */ import {listen, unlistenByKey} from '../events.js'; import EventType from '../events/EventType.js'; -import {getUid} from '../util.js'; import {getChangeEventType} from '../Object.js'; import BaseLayer from './Base.js'; import LayerProperty from './Property.js'; @@ -219,7 +218,6 @@ class Layer extends BaseLayer { layerState.zIndex = Infinity; } renderEvent.frameState.layerStatesArray.push(layerState); - renderEvent.frameState.layerStates[getUid(this)] = layerState; }, this); this.mapRenderKey_ = listen(this, EventType.CHANGE, map.render, map); this.changed(); diff --git a/src/ol/renderer/Map.js b/src/ol/renderer/Map.js index dcd4f96a69..ef2cb51338 100644 --- a/src/ol/renderer/Map.js +++ b/src/ol/renderer/Map.js @@ -107,12 +107,12 @@ class MapRenderer extends Disposable { const viewResolution = viewState.resolution; /** + * @param {boolean} managed Managed layer. * @param {import("../Feature.js").FeatureLike} feature Feature. * @param {import("../layer/Layer.js").default} layer Layer. * @return {?} Callback result. */ - function forEachFeatureAtCoordinate(feature, layer) { - const managed = frameState.layerStates[getUid(layer)].managed; + function forEachFeatureAtCoordinate(managed, feature, layer) { if (!(getUid(feature) in frameState.skippedFeatureUids && !managed)) { return callback.call(thisArg, feature, managed ? layer : null); } @@ -141,9 +141,10 @@ class MapRenderer extends Disposable { const layerRenderer = this.getLayerRenderer(layer); const source = layer.getSource(); if (layerRenderer && source) { + const callback = forEachFeatureAtCoordinate.bind(null, layerState.managed); result = layerRenderer.forEachFeatureAtCoordinate( source.getWrapX() ? translatedCoordinate : coordinate, - frameState, hitTolerance, forEachFeatureAtCoordinate); + frameState, hitTolerance, callback); } if (result) { return result; @@ -249,19 +250,6 @@ class MapRenderer extends Disposable { return layerRenderer; } - /** - * @param {import("../PluggableMap.js").default} map Map. - * @param {import("../PluggableMap.js").FrameState} frameState Frame state. - * @private - */ - removeUnusedLayerRenderers_(map, frameState) { - for (const layerKey in this.layerRenderers_) { - if (!frameState || !(layerKey in frameState.layerStates)) { - this.removeLayerRendererByKey_(layerKey).dispose(); - } - } - } - /** * Render. * @abstract @@ -276,7 +264,9 @@ class MapRenderer extends Disposable { * @protected */ scheduleExpireIconCache(frameState) { - frameState.postRenderFunctions.push(/** @type {import("../PluggableMap.js").PostRenderFunction} */ (expireIconCache)); + if (iconImageCache.canExpireCache()) { + frameState.postRenderFunctions.push(expireIconCache); + } } /** @@ -284,12 +274,12 @@ class MapRenderer extends Disposable { * @protected */ scheduleRemoveUnusedLayerRenderers(frameState) { + const layerStatesMap = getLayerStatesMap(frameState.layerStatesArray); for (const layerKey in this.layerRenderers_) { - if (!(layerKey in frameState.layerStates)) { - frameState.postRenderFunctions.push( - /** @type {import("../PluggableMap.js").PostRenderFunction} */ (this.removeUnusedLayerRenderers_.bind(this)) - ); - return; + if (!(layerKey in layerStatesMap)) { + frameState.postRenderFunctions.push(function() { + this.removeLayerRendererByKey_(layerKey).dispose(); + }.bind(this)); } } } @@ -304,6 +294,16 @@ function expireIconCache(map, frameState) { iconImageCache.expire(); } +/** + * @param {Array} layerStatesArray Layer states array. + * @return {Object} States mapped by layer uid. + */ +function getLayerStatesMap(layerStatesArray) { + return layerStatesArray.reduce(function(acc, state) { + acc[getUid(state.layer)] = state; + return acc; + }, {}); +} /** * @param {import("../layer/Layer.js").State} state1 First layer state. diff --git a/src/ol/source/Raster.js b/src/ol/source/Raster.js index 6f3cbe229c..0e448d69f8 100644 --- a/src/ol/source/Raster.js +++ b/src/ol/source/Raster.js @@ -1,7 +1,6 @@ /** * @module ol/source/Raster */ -import {getUid} from '../util.js'; import ImageCanvas from '../ImageCanvas.js'; import TileQueue from '../TileQueue.js'; import {createCanvasContext2D} from '../dom.js'; @@ -185,16 +184,6 @@ class RasterSource extends ImageSource { return 1; }, this.changed.bind(this)); - const layerStatesArray = getLayerStatesArray(this.layers_); - - /** - * @type {Object} - */ - const layerStates = {}; - for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) { - layerStates[getUid(layerStatesArray[i].layer)] = layerStatesArray[i]; - } - /** * The most recently requested frame state. * @type {import("../PluggableMap.js").FrameState} @@ -225,8 +214,7 @@ class RasterSource extends ImageSource { extent: null, focus: null, index: 0, - layerStates: layerStates, - layerStatesArray: layerStatesArray, + layerStatesArray: getLayerStatesArray(this.layers_), pixelRatio: 1, pixelToCoordinateTransform: createTransform(), postRenderFunctions: [], diff --git a/src/ol/style/IconImageCache.js b/src/ol/style/IconImageCache.js index 0780d814e1..b9809c7c89 100644 --- a/src/ol/style/IconImageCache.js +++ b/src/ol/style/IconImageCache.js @@ -37,11 +37,18 @@ class IconImageCache { this.cacheSize_ = 0; } + /** + * @return {boolean} Can expire cache. + */ + canExpireCache() { + return this.cacheSize_ > this.maxCacheSize_; + } + /** * FIXME empty description for jsdoc */ expire() { - if (this.cacheSize_ > this.maxCacheSize_) { + if (this.canExpireCache()) { let i = 0; for (const key in this.cache_) { const iconImage = this.cache_[key]; diff --git a/test/spec/ol/layer/layer.test.js b/test/spec/ol/layer/layer.test.js index ff3aeb97a5..e077455ac1 100644 --- a/test/spec/ol/layer/layer.test.js +++ b/test/spec/ol/layer/layer.test.js @@ -1,4 +1,3 @@ -import {getUid} from '../../../../src/ol/util.js'; import Map from '../../../../src/ol/Map.js'; import Layer, {visibleAtResolution} from '../../../../src/ol/layer/Layer.js'; import {get as getProjection} from '../../../../src/ol/proj.js'; @@ -396,15 +395,12 @@ describe('ol.layer.Layer', function() { map: map }); const frameState = { - layerStatesArray: [], - layerStates: {} + layerStatesArray: [] }; - map.dispatchEvent(new RenderEvent('precompose', null, - frameState, null, null)); + map.dispatchEvent(new RenderEvent('precompose', null, frameState, null, null)); expect(frameState.layerStatesArray.length).to.be(1); const layerState = frameState.layerStatesArray[0]; expect(layerState.layer).to.equal(layer); - expect(frameState.layerStates[getUid(layer)]).to.equal(layerState); }); }); diff --git a/test/spec/ol/renderer/canvas/vectorlayer.test.js b/test/spec/ol/renderer/canvas/vectorlayer.test.js index d540eb781d..b34d91ead7 100644 --- a/test/spec/ol/renderer/canvas/vectorlayer.test.js +++ b/test/spec/ol/renderer/canvas/vectorlayer.test.js @@ -1,4 +1,3 @@ -import {getUid} from '../../../../../src/ol/util.js'; import Feature from '../../../../../src/ol/Feature.js'; import Map from '../../../../../src/ol/Map.js'; import View from '../../../../../src/ol/View.js'; @@ -203,14 +202,13 @@ describe('ol.renderer.canvas.VectorLayer', function() { const spy = sinon.spy(); const coordinate = [0, 0]; const frameState = { - layerStates: {}, + layerStatesArray: [{}], skippedFeatureUids: {}, viewState: { resolution: 1, rotation: 0 } }; - frameState.layerStates[getUid(layer)] = {}; renderer.forEachFeatureAtCoordinate( coordinate, frameState, 0, spy, undefined); expect(spy.callCount).to.be(1); diff --git a/test/spec/ol/renderer/canvas/vectortilelayer.test.js b/test/spec/ol/renderer/canvas/vectortilelayer.test.js index 5521b586af..8e44634d7a 100644 --- a/test/spec/ol/renderer/canvas/vectortilelayer.test.js +++ b/test/spec/ol/renderer/canvas/vectortilelayer.test.js @@ -1,4 +1,3 @@ -import {getUid} from '../../../../../src/ol/util.js'; import {clear} from '../../../../../src/ol/obj.js'; import Feature from '../../../../../src/ol/Feature.js'; import Map from '../../../../../src/ol/Map.js'; @@ -329,7 +328,7 @@ describe('ol.renderer.canvas.VectorTileLayer', function() { const spy = sinon.spy(); const coordinate = [0, 0]; const frameState = { - layerStates: {}, + layerStatesArray: [{}], skippedFeatureUids: {}, viewState: { projection: getProjection('EPSG:3857'), @@ -337,7 +336,6 @@ describe('ol.renderer.canvas.VectorTileLayer', function() { rotation: 0 } }; - frameState.layerStates[getUid(layer)] = {}; renderer.renderedTiles = [new TileClass([0, 0, -1], undefined, 1)]; renderer.forEachFeatureAtCoordinate( coordinate, frameState, 0, spy, undefined);