diff --git a/src/ol/feature.js b/src/ol/feature.js index 162a5d7a3a..3af0f64d80 100644 --- a/src/ol/feature.js +++ b/src/ol/feature.js @@ -20,6 +20,12 @@ ol.Feature = function(opt_values) { */ this.geometryName_; + /** + * @type {Array.} + * @private + */ + this.symbolizers_ = null; + }; goog.inherits(ol.Feature, ol.Object); @@ -50,6 +56,22 @@ ol.Feature.prototype.getGeometry = function() { }; +/** + * @return {Array.} Symbolizer literals. + */ +ol.Feature.prototype.getSymbolizerLiterals = function() { + var symbolizerLiterals = null; + if (!goog.isNull(this.symbolizers_)) { + var numSymbolizers = this.symbolizers_.length; + symbolizerLiterals = new Array(numSymbolizers); + for (var i = 0; i < numSymbolizers; ++i) { + symbolizerLiterals[i] = this.symbolizers_[i].createLiteral(this); + } + } + return symbolizerLiterals; +}; + + /** * @inheritDoc * @param {string} key Key. @@ -74,6 +96,15 @@ ol.Feature.prototype.setGeometry = function(geometry) { }; +/** + * @param {Array.} symbolizers Symbolizers for this + * features. If set, these take precedence over layer style. + */ +ol.Feature.prototype.setSymbolizers = function(symbolizers) { + this.symbolizers_ = symbolizers; +}; + + /** * @const * @type {string} diff --git a/src/ol/layer/vectorlayer.js b/src/ol/layer/vectorlayer.js index 6397544d57..6703ec3e3c 100644 --- a/src/ol/layer/vectorlayer.js +++ b/src/ol/layer/vectorlayer.js @@ -42,16 +42,21 @@ ol.layer.Vector.prototype.groupFeaturesBySymbolizerLiteral = var uniqueLiterals = {}, featuresBySymbolizer = [], style = this.style_, - feature, literals, literal, uniqueLiteral, key; - for (var i = 0, ii = features.length; i < ii; ++i) { + numFeatures = features.length, + i, j, l, feature, literals, numLiterals, literal, uniqueLiteral, key; + for (i = 0; i < numFeatures; ++i) { feature = features[i]; - literals = goog.isNull(style) ? - ol.style.Style.applyDefaultStyle(feature) : - style.apply(feature); - for (var j = 0, jj = literals.length; j < jj; ++j) { + literals = feature.getSymbolizerLiterals(); + if (goog.isNull(literals)) { + literals = goog.isNull(style) ? + ol.style.Style.applyDefaultStyle(feature) : + style.apply(feature); + } + numLiterals = literals.length; + for (j = 0; j < numLiterals; ++j) { literal = literals[j]; - for (var l in uniqueLiterals) { - uniqueLiteral = featuresBySymbolizer[uniqueLiterals[key]][1]; + for (l in uniqueLiterals) { + uniqueLiteral = featuresBySymbolizer[uniqueLiterals[l]][1]; if (literal.equals(uniqueLiteral)) { literal = uniqueLiteral; break; diff --git a/test/spec/ol/layer/vectorlayer.test.js b/test/spec/ol/layer/vectorlayer.test.js index 7450ba4ca3..8cc0f941da 100644 --- a/test/spec/ol/layer/vectorlayer.test.js +++ b/test/spec/ol/layer/vectorlayer.test.js @@ -4,26 +4,28 @@ describe('ol.layer.Vector', function() { describe('#groupFeaturesBySymbolizerLiteral()', function() { + var layer = new ol.layer.Vector({ + source: new ol.source.Vector({ + projection: ol.projection.getFromCode('EPSG:4326') + }), + style: new ol.style.Style({ + rules: [ + new ol.style.Rule({ + symbolizers: [ + new ol.style.Line({ + strokeWidth: 2, + strokeStyle: new ol.Expression('colorProperty'), + opacity: 1 + }) + ] + }) + ] + }) + }); + var features; + it('groups equal symbolizers', function() { - var layer = new ol.layer.Vector({ - source: new ol.source.Vector({ - projection: ol.projection.getFromCode('EPSG:4326') - }), - style: new ol.style.Style({ - rules: [ - new ol.style.Rule({ - symbolizers: [ - new ol.style.Line({ - strokeWidth: 2, - strokeStyle: new ol.Expression('colorProperty'), - opacity: 1 - }) - ] - }) - ] - }) - }); - var features = [ + features = [ new ol.Feature({ g: new ol.geom.LineString([[-10, -10], [10, 10]]), colorProperty: '#BADA55' @@ -44,10 +46,39 @@ describe('ol.layer.Vector', function() { expect(groups[0][1].strokeStyle).toBe('#BADA55'); expect(groups[1][0].length).toBe(2); expect(groups[1][1].strokeStyle).toBe('#013'); - - layer.dispose(); }); + it('groups equal symbolizers also when defined on features', function() { + var symbolizer = new ol.style.Line({ + strokeWidth: 3, + strokeStyle: new ol.Expression('colorProperty'), + opacity: 1 + }); + var anotherSymbolizer = new ol.style.Line({ + strokeWidth: 3, + strokeStyle: '#BADA55', + opacity: 1 + }); + var featureWithSymbolizers = new ol.Feature({ + g: new ol.geom.LineString([[-10, -10], [-10, 10]]), + colorProperty: '#BADA55' + }); + featureWithSymbolizers.setSymbolizers([symbolizer]); + var anotherFeatureWithSymbolizers = new ol.Feature({ + g: new ol.geom.LineString([[-10, 10], [-10, -10]]) + }); + anotherFeatureWithSymbolizers.setSymbolizers([anotherSymbolizer]); + features.push(featureWithSymbolizers, anotherFeatureWithSymbolizers); + + var groups = layer.groupFeaturesBySymbolizerLiteral(features); + expect(groups.length).toBe(3); + expect(groups[2][0].length).toBe(2); + expect(groups[2][1].strokeWidth).toBe(3); + + }); + + layer.dispose(); + }); });