From 9d5451b1d699bc8d3b8b3d9e0ce7577aba30286f Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 3 Apr 2014 10:41:02 -0600 Subject: [PATCH 1/4] Provide a reference to the layer --- src/ol/layer/layerbase.js | 4 +++- test/spec/ol/layer/layer.test.js | 5 +++++ test/spec/ol/layer/layergroup.test.js | 32 ++++++++++++++++++++++++--- 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/ol/layer/layerbase.js b/src/ol/layer/layerbase.js index 46bc1b7d2c..160fd04b7d 100644 --- a/src/ol/layer/layerbase.js +++ b/src/ol/layer/layerbase.js @@ -25,7 +25,8 @@ ol.layer.LayerProperty = { /** - * @typedef {{brightness: number, + * @typedef {{layer: ol.layer.Layer, + * brightness: number, * contrast: number, * hue: number, * opacity: number, @@ -126,6 +127,7 @@ ol.layer.Base.prototype.getLayerState = function() { var maxResolution = this.getMaxResolution(); var minResolution = this.getMinResolution(); return { + layer: /** @type {ol.layer.Layer} */ (this), brightness: goog.isDef(brightness) ? goog.math.clamp(brightness, -1, 1) : 0, contrast: goog.isDef(contrast) ? Math.max(contrast, 0) : 1, hue: goog.isDef(hue) ? hue : 0, diff --git a/test/spec/ol/layer/layer.test.js b/test/spec/ol/layer/layer.test.js index 4d8f1b516c..afafb9a617 100644 --- a/test/spec/ol/layer/layer.test.js +++ b/test/spec/ol/layer/layer.test.js @@ -48,6 +48,7 @@ describe('ol.layer.Layer', function() { it('provides default layerState', function() { expect(layer.getLayerState()).to.eql({ + layer: layer, brightness: 0, contrast: 1, hue: 0, @@ -90,6 +91,7 @@ describe('ol.layer.Layer', function() { expect(layer.getMinResolution()).to.be(0.25); expect(layer.get('foo')).to.be(42); expect(layer.getLayerState()).to.eql({ + layer: layer, brightness: 0.5, contrast: 10, hue: 180, @@ -132,6 +134,7 @@ describe('ol.layer.Layer', function() { layer.setMaxResolution(500); layer.setMinResolution(0.25); expect(layer.getLayerState()).to.eql({ + layer: layer, brightness: -0.7, contrast: 0.3, hue: -0.3, @@ -152,6 +155,7 @@ describe('ol.layer.Layer', function() { layer.setSaturation(-0.7); layer.setVisible(false); expect(layer.getLayerState()).to.eql({ + layer: layer, brightness: 1, contrast: 0, hue: 42, @@ -170,6 +174,7 @@ describe('ol.layer.Layer', function() { layer.setSaturation(42); layer.setVisible(true); expect(layer.getLayerState()).to.eql({ + layer: layer, brightness: -1, contrast: 42, hue: -100, diff --git a/test/spec/ol/layer/layergroup.test.js b/test/spec/ol/layer/layergroup.test.js index d3a29cfd15..20650c8bb4 100644 --- a/test/spec/ol/layer/layergroup.test.js +++ b/test/spec/ol/layer/layergroup.test.js @@ -44,6 +44,7 @@ describe('ol.layer.Group', function() { it('provides default layerState', function() { expect(layerGroup.getLayerState()).to.eql({ + layer: layerGroup, brightness: 0, contrast: 1, hue: 0, @@ -170,6 +171,7 @@ describe('ol.layer.Group', function() { expect(layerGroup.getMaxResolution()).to.be(500); expect(layerGroup.getMinResolution()).to.be(0.25); expect(layerGroup.getLayerState()).to.eql({ + layer: layerGroup, brightness: 0.5, contrast: 10, hue: 180, @@ -212,6 +214,7 @@ describe('ol.layer.Group', function() { layerGroup.setMaxResolution(500); layerGroup.setMinResolution(0.25); expect(layerGroup.getLayerState()).to.eql({ + layer: layerGroup, brightness: -0.7, contrast: 0.3, hue: -0.3, @@ -232,6 +235,7 @@ describe('ol.layer.Group', function() { layerGroup.setSaturation(-0.7); layerGroup.setVisible(false); expect(layerGroup.getLayerState()).to.eql({ + layer: layerGroup, brightness: 1, contrast: 0, hue: 42, @@ -250,6 +254,7 @@ describe('ol.layer.Group', function() { layerGroup.setSaturation(42); layerGroup.setVisible(true); expect(layerGroup.getLayerState()).to.eql({ + layer: layerGroup, brightness: -1, contrast: 42, hue: -100, @@ -345,7 +350,14 @@ describe('ol.layer.Group', function() { expect(layerStatesArray).to.be.a(Array); expect(layerStatesArray.length).to.be(2); expect(layerStatesArray[0]).to.eql(layer1.getLayerState()); - expect(layerStatesArray[0]).to.eql(layerGroup.getLayerState()); + + // layer state should match except for layer reference + var layerState = goog.object.clone(layerStatesArray[0]); + delete layerState.layer; + var groupState = goog.object.clone(layerGroup.getLayerState()); + delete groupState.layer; + expect(layerState).to.eql(groupState); + expect(layerStatesArray[1]).to.eql(layer2.getLayerState()); goog.dispose(layerGroup); @@ -367,8 +379,21 @@ describe('ol.layer.Group', function() { obj = layerGroup.getLayerStatesArray(); layersArray = obj.layers; layerStatesArray = obj.layerStates; - expect(layerStatesArray[0]).to.eql(layerGroup.getLayerState()); - expect(layerStatesArray[1]).to.eql({ + + // compare layer state to group state + var groupState, layerState; + + // layer state should match except for layer reference + layerState = goog.object.clone(layerStatesArray[0]); + delete layerState.layer; + groupState = goog.object.clone(layerGroup.getLayerState()); + delete groupState.layer; + expect(layerState).to.eql(groupState); + + // layer state should be transformed (and we ignore layer reference) + layerState = goog.object.clone(layerStatesArray[1]); + delete layerState.layer; + expect(layerState).to.eql({ brightness: 1, contrast: 100, hue: 360, @@ -392,6 +417,7 @@ describe('ol.layer.Group', function() { goog.require('goog.dispose'); goog.require('goog.events.EventType'); +goog.require('goog.object'); goog.require('ol.ObjectEventType'); goog.require('ol.layer.Layer'); goog.require('ol.layer.Group'); From aa3a20e91174fd2eae28d9404eb723eb899bac1b Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 3 Apr 2014 11:46:17 -0600 Subject: [PATCH 2/4] Provide layer states array in frame state --- externs/oli.js | 4 +++ src/ol/map.js | 1 + src/ol/renderer/canvas/canvasmaprenderer.js | 9 +++---- src/ol/renderer/dom/dommaprenderer.js | 10 +++---- src/ol/renderer/webgl/webglmaprenderer.js | 30 ++++++++++----------- 5 files changed, 28 insertions(+), 26 deletions(-) diff --git a/externs/oli.js b/externs/oli.js index 51e181fc27..be5000cc35 100644 --- a/externs/oli.js +++ b/externs/oli.js @@ -72,6 +72,10 @@ oli.FrameState.prototype.layersArray; oli.FrameState.prototype.layerStates; +/** @type {Array.} */ +oli.FrameState.prototype.layerStatesArray; + + /** @type {Object.} */ oli.FrameState.prototype.logos; diff --git a/src/ol/map.js b/src/ol/map.js index 34f5d37071..b490cd89e6 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -1226,6 +1226,7 @@ ol.Map.prototype.renderFrame_ = function(time) { index: this.frameIndex_++, layersArray: layersArray, layerStates: layerStates, + layerStatesArray: layerStatesArray, logos: {}, pixelRatio: this.pixelRatio_, pixelToCoordinateMatrix: this.pixelToCoordinateMatrix_, diff --git a/src/ol/renderer/canvas/canvasmaprenderer.js b/src/ol/renderer/canvas/canvasmaprenderer.js index 7ff360992f..e0d499a520 100644 --- a/src/ol/renderer/canvas/canvasmaprenderer.js +++ b/src/ol/renderer/canvas/canvasmaprenderer.js @@ -151,15 +151,14 @@ ol.renderer.canvas.Map.prototype.renderFrame = function(frameState) { this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState); - var layerStates = frameState.layerStates; - var layersArray = frameState.layersArray; + var layerStatesArray = frameState.layerStatesArray; var viewResolution = frameState.view2DState.resolution; var i, ii, layer, layerRenderer, layerState; - for (i = 0, ii = layersArray.length; i < ii; ++i) { - layer = layersArray[i]; + for (i = 0, ii = layerStatesArray.length; i < ii; ++i) { + layerState = layerStatesArray[i]; + layer = layerState.layer; layerRenderer = this.getLayerRenderer(layer); goog.asserts.assertInstanceof(layerRenderer, ol.renderer.canvas.Layer); - layerState = layerStates[goog.getUid(layer)]; if (!layerState.visible || layerState.sourceState != ol.source.State.READY || viewResolution >= layerState.maxResolution || diff --git a/src/ol/renderer/dom/dommaprenderer.js b/src/ol/renderer/dom/dommaprenderer.js index 0eaa8410bb..8f5eec30ca 100644 --- a/src/ol/renderer/dom/dommaprenderer.js +++ b/src/ol/renderer/dom/dommaprenderer.js @@ -117,21 +117,21 @@ ol.renderer.dom.Map.prototype.renderFrame = function(frameState) { }); } - var layerStates = frameState.layerStates; - var layersArray = frameState.layersArray; + var layerStatesArray = frameState.layerStatesArray; var i, ii, layer, layerRenderer, layerState; - for (i = 0, ii = layersArray.length; i < ii; ++i) { - layer = layersArray[i]; + for (i = 0, ii = layerStatesArray.length; i < ii; ++i) { + layerState = layerStatesArray[i]; + layer = layerState.layer; layerRenderer = /** @type {ol.renderer.dom.Layer} */ ( this.getLayerRenderer(layer)); goog.asserts.assertInstanceof(layerRenderer, ol.renderer.dom.Layer); addChild.call(this, layerRenderer.getTarget(), i); - layerState = frameState.layerStates[goog.getUid(layer)]; if (layerState.sourceState == ol.source.State.READY) { layerRenderer.prepareFrame(frameState, layerState); } } + var layerStates = frameState.layerStates; var layerKey; for (layerKey in this.getLayerRenderers()) { if (!(layerKey in layerStates)) { diff --git a/src/ol/renderer/webgl/webglmaprenderer.js b/src/ol/renderer/webgl/webglmaprenderer.js index aea240c698..df1f4597d1 100644 --- a/src/ol/renderer/webgl/webglmaprenderer.js +++ b/src/ol/renderer/webgl/webglmaprenderer.js @@ -441,27 +441,26 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { this.textureCache_.set((-frameState.index).toString(), null); ++this.textureCacheFrameMarkerCount_; - /** @type {Array.} */ - var layersToDraw = []; - var layersArray = frameState.layersArray; + /** @type {Array.} */ + var layerStatesToDraw = []; + var layerStatesArray = frameState.layerStatesArray; var viewResolution = frameState.view2DState.resolution; - var i, ii, layer, layerRenderer, layerState; - for (i = 0, ii = layersArray.length; i < ii; ++i) { - layer = layersArray[i]; - layerState = frameState.layerStates[goog.getUid(layer)]; + var i, ii, layerState; + for (i = 0, ii = layerStatesArray.length; i < ii; ++i) { + layerState = layerStatesArray[i]; if (layerState.visible && layerState.sourceState == ol.source.State.READY && viewResolution < layerState.maxResolution && viewResolution >= layerState.minResolution) { - layersToDraw.push(layer); + layerStatesToDraw.push(layerState); } } - for (i = 0, ii = layersToDraw.length; i < ii; ++i) { - layer = layersToDraw[i]; - layerRenderer = this.getLayerRenderer(layer); + var layerRenderer; + for (i = 0, ii = layerStatesToDraw.length; i < ii; ++i) { + layerState = layerStatesToDraw[i]; + layerRenderer = this.getLayerRenderer(layerState.layer); goog.asserts.assertInstanceof(layerRenderer, ol.renderer.webgl.Layer); - layerState = frameState.layerStates[goog.getUid(layer)]; layerRenderer.prepareFrame(frameState, layerState); } @@ -481,10 +480,9 @@ ol.renderer.webgl.Map.prototype.renderFrame = function(frameState) { this.dispatchComposeEvent_(ol.render.EventType.PRECOMPOSE, frameState); - for (i = 0, ii = layersToDraw.length; i < ii; ++i) { - layer = layersToDraw[i]; - layerState = frameState.layerStates[goog.getUid(layer)]; - layerRenderer = this.getLayerRenderer(layer); + for (i = 0, ii = layerStatesToDraw.length; i < ii; ++i) { + layerState = layerStatesToDraw[i]; + layerRenderer = this.getLayerRenderer(layerState.layer); goog.asserts.assertInstanceof(layerRenderer, ol.renderer.webgl.Layer); layerRenderer.composeFrame(frameState, layerState, context); } From 78324fb54b449a6c4467452df20cadb8274a871d Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 3 Apr 2014 12:02:58 -0600 Subject: [PATCH 3/4] Remove layers array from frame state --- externs/oli.js | 4 ---- src/ol/control/attributioncontrol.js | 6 +++--- src/ol/map.js | 1 - 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/externs/oli.js b/externs/oli.js index be5000cc35..675505c8ae 100644 --- a/externs/oli.js +++ b/externs/oli.js @@ -64,10 +64,6 @@ oli.FrameState.prototype.focus; oli.FrameState.prototype.index; -/** @type {Array.} */ -oli.FrameState.prototype.layersArray; - - /** @type {Object.} */ oli.FrameState.prototype.layerStates; diff --git a/src/ol/control/attributioncontrol.js b/src/ol/control/attributioncontrol.js index 1433b40908..109faf06f9 100644 --- a/src/ol/control/attributioncontrol.js +++ b/src/ol/control/attributioncontrol.js @@ -74,13 +74,13 @@ ol.control.Attribution.prototype.getSourceAttributions = function(frameState) { var i, ii, j, jj, tileRanges, source, sourceAttribution, sourceAttributionKey, sourceAttributions, sourceKey; - var layers = frameState.layersArray; + var layerStatesArray = frameState.layerStatesArray; /** @type {Object.} */ var attributions = goog.object.clone(frameState.attributions); /** @type {Object.} */ var hiddenAttributions = {}; - for (i = 0, ii = layers.length; i < ii; i++) { - source = layers[i].getSource(); + for (i = 0, ii = layerStatesArray.length; i < ii; i++) { + source = layerStatesArray[i].layer.getSource(); sourceKey = goog.getUid(source).toString(); sourceAttributions = source.getAttributions(); if (goog.isNull(sourceAttributions)) { diff --git a/src/ol/map.js b/src/ol/map.js index b490cd89e6..5463e5174a 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -1224,7 +1224,6 @@ ol.Map.prototype.renderFrame_ = function(time) { extent: null, focus: goog.isNull(this.focus_) ? view2DState.center : this.focus_, index: this.frameIndex_++, - layersArray: layersArray, layerStates: layerStates, layerStatesArray: layerStatesArray, logos: {}, From 78260363075129de694625d16e4886c383229b65 Mon Sep 17 00:00:00 2001 From: Tim Schaub Date: Thu, 3 Apr 2014 12:39:48 -0600 Subject: [PATCH 4/4] Make getLayerStatesArray return an array of layer states --- src/ol/layer/layer.js | 13 ++++-------- src/ol/layer/layerbase.js | 11 +++------- src/ol/layer/layergroup.js | 19 ++++++++---------- src/ol/map.js | 10 +++------ src/ol/renderer/maprenderer.js | 9 +++------ test/spec/ol/layer/layergroup.test.js | 29 ++++++--------------------- 6 files changed, 27 insertions(+), 64 deletions(-) diff --git a/src/ol/layer/layer.js b/src/ol/layer/layer.js index b9e7cb6ab5..55850bafb5 100644 --- a/src/ol/layer/layer.js +++ b/src/ol/layer/layer.js @@ -57,15 +57,10 @@ ol.layer.Layer.prototype.getLayersArray = function(opt_array) { /** * @inheritDoc */ -ol.layer.Layer.prototype.getLayerStatesArray = function(opt_obj) { - var obj = (goog.isDef(opt_obj)) ? opt_obj : { - layers: [], - layerStates: [] - }; - goog.asserts.assert(obj.layers.length === obj.layerStates.length); - obj.layers.push(this); - obj.layerStates.push(this.getLayerState()); - return obj; +ol.layer.Layer.prototype.getLayerStatesArray = function(opt_states) { + var states = (goog.isDef(opt_states)) ? opt_states : []; + states.push(this.getLayerState()); + return states; }; diff --git a/src/ol/layer/layerbase.js b/src/ol/layer/layerbase.js index 160fd04b7d..a55b2b9aa4 100644 --- a/src/ol/layer/layerbase.js +++ b/src/ol/layer/layerbase.js @@ -150,14 +150,9 @@ ol.layer.Base.prototype.getLayersArray = goog.abstractMethod; /** - * @param {{ - * layers: Array., - * layerStates: Array.}=} opt_obj Object that store - * both the layers and the layerStates (to be modified in place). - * @return {{ - * layers: Array., - * layerStates: Array.}} Object that store both the - * layers and the layerStates. + * @param {Array.=} opt_states Optional list of layer + * states (to be modified in place). + * @return {Array.} List of layer states. */ ol.layer.Base.prototype.getLayerStatesArray = goog.abstractMethod; diff --git a/src/ol/layer/layergroup.js b/src/ol/layer/layergroup.js index 390cff2c0b..d814571de3 100644 --- a/src/ol/layer/layergroup.js +++ b/src/ol/layer/layergroup.js @@ -183,22 +183,19 @@ ol.layer.Group.prototype.getLayersArray = function(opt_array) { /** * @inheritDoc */ -ol.layer.Group.prototype.getLayerStatesArray = function(opt_obj) { - var obj = (goog.isDef(opt_obj)) ? opt_obj : { - layers: [], - layerStates: [] - }; - goog.asserts.assert(obj.layers.length === obj.layerStates.length); - var pos = obj.layers.length; +ol.layer.Group.prototype.getLayerStatesArray = function(opt_states) { + var states = (goog.isDef(opt_states)) ? opt_states : []; + + var pos = states.length; this.getLayers().forEach(function(layer) { - layer.getLayerStatesArray(obj); + layer.getLayerStatesArray(states); }); var ownLayerState = this.getLayerState(); var i, ii, layerState; - for (i = pos, ii = obj.layerStates.length; i < ii; i++) { - layerState = obj.layerStates[i]; + for (i = pos, ii = states.length; i < ii; i++) { + layerState = states[i]; layerState.brightness = goog.math.clamp( layerState.brightness + ownLayerState.brightness, -1, 1); layerState.contrast *= ownLayerState.contrast; @@ -212,7 +209,7 @@ ol.layer.Group.prototype.getLayerStatesArray = function(opt_obj) { layerState.minResolution, ownLayerState.minResolution); } - return obj; + return states; }; diff --git a/src/ol/map.js b/src/ol/map.js index 5463e5174a..9c5d171858 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -1207,14 +1207,10 @@ ol.Map.prototype.renderFrame_ = function(time) { if (goog.isDef(size) && hasArea(size) && goog.isDef(view2D) && view2D.isDef()) { var viewHints = view.getHints(); - var obj = this.getLayerGroup().getLayerStatesArray(); - var layersArray = obj.layers; - var layerStatesArray = obj.layerStates; + var layerStatesArray = this.getLayerGroup().getLayerStatesArray(); var layerStates = {}; - var layer; - for (i = 0, ii = layersArray.length; i < ii; ++i) { - layer = layersArray[i]; - layerStates[goog.getUid(layer)] = layerStatesArray[i]; + for (i = 0, ii = layerStatesArray.length; i < ii; ++i) { + layerStates[goog.getUid(layerStatesArray[i].layer)] = layerStatesArray[i]; } view2DState = view2D.getView2DState(); frameState = /** @type {oli.FrameState} */ ({ diff --git a/src/ol/renderer/maprenderer.js b/src/ol/renderer/maprenderer.js index 6632fc3328..f041562fe9 100644 --- a/src/ol/renderer/maprenderer.js +++ b/src/ol/renderer/maprenderer.js @@ -97,15 +97,12 @@ ol.renderer.Map.prototype.disposeInternal = function() { ol.renderer.Map.prototype.forEachFeatureAtPixel = function(coordinate, frameState, callback, thisArg, layerFilter, thisArg2) { - var obj = this.map_.getLayerGroup().getLayerStatesArray(); - var layers = obj.layers; - var layerStates = obj.layerStates; - goog.asserts.assert(layers.length == layerStates.length); - var numLayers = layers.length; + var layerStates = this.map_.getLayerGroup().getLayerStatesArray(); + var numLayers = layerStates.length; var i; for (i = numLayers - 1; i >= 0; --i) { var layerState = layerStates[i]; - var layer = layers[i]; + var layer = layerState.layer; if (layerState.visible && layerFilter.call(thisArg2, layer)) { var layerRenderer = this.getLayerRenderer(layer); var result = layerRenderer.forEachFeatureAtPixel( diff --git a/test/spec/ol/layer/layergroup.test.js b/test/spec/ol/layer/layergroup.test.js index 20650c8bb4..d28ca09773 100644 --- a/test/spec/ol/layer/layergroup.test.js +++ b/test/spec/ol/layer/layergroup.test.js @@ -297,19 +297,10 @@ describe('ol.layer.Group', function() { describe('#getLayerStatesArray', function() { - var layerGroup; - var layersArray; - var layerStatesArray; - var obj; - it('returns an empty array if no layer', function() { - layerGroup = new ol.layer.Group(); + var layerGroup = new ol.layer.Group(); - obj = layerGroup.getLayerStatesArray(); - layersArray = obj.layers; - layerStatesArray = obj.layerStates; - expect(layersArray).to.be.a(Array); - expect(layersArray.length).to.be(0); + var layerStatesArray = layerGroup.getLayerStatesArray(); expect(layerStatesArray).to.be.a(Array); expect(layerStatesArray.length).to.be(0); @@ -336,17 +327,11 @@ describe('ol.layer.Group', function() { }); it('does not transform layerStates by default', function() { - layerGroup = new ol.layer.Group({ + var layerGroup = new ol.layer.Group({ layers: [layer1, layer2] }); - obj = layerGroup.getLayerStatesArray(); - layersArray = obj.layers; - layerStatesArray = obj.layerStates; - expect(layersArray).to.be.a(Array); - expect(layersArray.length).to.be(2); - expect(layersArray[0]).to.be(layer1); - expect(layersArray[1]).to.be(layer2); + var layerStatesArray = layerGroup.getLayerStatesArray(); expect(layerStatesArray).to.be.a(Array); expect(layerStatesArray.length).to.be(2); expect(layerStatesArray[0]).to.eql(layer1.getLayerState()); @@ -364,7 +349,7 @@ describe('ol.layer.Group', function() { }); it('transforms layerStates correctly', function() { - layerGroup = new ol.layer.Group({ + var layerGroup = new ol.layer.Group({ layers: [layer1, layer2], brightness: 0.5, contrast: 10, @@ -376,9 +361,7 @@ describe('ol.layer.Group', function() { minResolution: 0.2 }); - obj = layerGroup.getLayerStatesArray(); - layersArray = obj.layers; - layerStatesArray = obj.layerStates; + var layerStatesArray = layerGroup.getLayerStatesArray(); // compare layer state to group state var groupState, layerState;