diff --git a/examples/kml-timezones.js b/examples/kml-timezones.js index f5b93ee1e6..1bce4ed208 100644 --- a/examples/kml-timezones.js +++ b/examples/kml-timezones.js @@ -41,19 +41,17 @@ ol.expr.register('getOpacity', function() { return 0.75 * (1 - delta / 12); }); -var style = new ol.style.Style({rules: [ - new ol.style.Rule({ - symbolizers: [ - new ol.style.Fill({ - color: '#ffff33', - opacity: ol.expr.parse('getOpacity()') - }), - new ol.style.Stroke({ - color: '#ffffff', - }) - ] - }) -]}); +var style = new ol.style.Style({ + symbolizers: [ + new ol.style.Fill({ + color: '#ffff33', + opacity: ol.expr.parse('getOpacity()') + }), + new ol.style.Stroke({ + color: '#ffffff', + }) + ] +}); var vector = new ol.layer.Vector({ source: new ol.source.Vector({ diff --git a/examples/topojson.js b/examples/topojson.js index 9f172aecf8..75a4187120 100644 --- a/examples/topojson.js +++ b/examples/topojson.js @@ -23,21 +23,19 @@ var vector = new ol.layer.Vector({ url: 'data/topojson/world-110m.json', parser: new ol.parser.TopoJSON() }), - style: new ol.style.Style({rules: [ - new ol.style.Rule({ - symbolizers: [ - new ol.style.Fill({ - color: '#BADA55', - opacity: 0.5 - }), - new ol.style.Stroke({ - color: '#FFF', - opacity: 1, - width: 1.5 - }) - ] - }) - ]}) + style: new ol.style.Style({ + symbolizers: [ + new ol.style.Fill({ + color: '#BADA55', + opacity: 0.5 + }), + new ol.style.Stroke({ + color: '#FFF', + opacity: 1, + width: 1.5 + }) + ] + }) }); var map = new ol.Map({ diff --git a/src/objectliterals.jsdoc b/src/objectliterals.jsdoc index 8bef3bb5b5..cc90365820 100644 --- a/src/objectliterals.jsdoc +++ b/src/objectliterals.jsdoc @@ -642,7 +642,10 @@ /** * @typedef {Object} ol.style.StyleOptions - * @property {Array.} rules Rules. + * @property {Array.|undefined} rules Rules. + * @property {Array.|undefined} symbolizers Symbolizers + * (that apply if no rules are provided or where none of the provided rules + * apply). */ /** diff --git a/src/ol/style/style.js b/src/ol/style/style.js index 7932ee652e..d5e7c42298 100644 --- a/src/ol/style/style.js +++ b/src/ol/style/style.js @@ -9,6 +9,7 @@ goog.require('ol.style.PolygonLiteral'); goog.require('ol.style.Rule'); goog.require('ol.style.Shape'); goog.require('ol.style.Stroke'); +goog.require('ol.style.Symbolizer'); @@ -24,6 +25,15 @@ ol.style.Style = function(options) { */ this.rules_ = goog.isDef(options.rules) ? options.rules : []; + /** + * Symbolizers that apply if no rules are given or where none of the given + * rules apply (these are the "else" symbolizers). + * @type {Array.} + * @private + */ + this.symbolizers_ = goog.isDef(options.symbolizers) ? + options.symbolizers : []; + }; @@ -35,18 +45,20 @@ ol.style.Style = function(options) { */ ol.style.Style.prototype.createLiterals = function(feature) { var rules = this.rules_, - literals = [], - rule, symbolizers; + symbolizers = [], + applies = false, + rule; for (var i = 0, ii = rules.length; i < ii; ++i) { rule = rules[i]; if (rule.applies(feature)) { - symbolizers = rule.getSymbolizers(); - for (var j = 0, jj = symbolizers.length; j < jj; ++j) { - literals.push(symbolizers[j].createLiteral(feature)); - } + applies = true; + symbolizers.push.apply(symbolizers, rule.getSymbolizers()); } + } if (!applies) { + // these are the "else" symbolizers + symbolizers = this.symbolizers_; } - return ol.style.Style.reduceLiterals_(literals); + return ol.style.Style.createLiterals(symbolizers, feature); }; @@ -55,17 +67,13 @@ ol.style.Style.prototype.createLiterals = function(feature) { * @type {ol.style.Style} */ ol.style.Style.defaults = new ol.style.Style({ - rules: [ - new ol.style.Rule({ - symbolizers: [ - new ol.style.Shape({ - fill: new ol.style.Fill(), - stroke: new ol.style.Stroke() - }), - new ol.style.Fill(), - new ol.style.Stroke() - ] - }) + symbolizers: [ + new ol.style.Shape({ + fill: new ol.style.Fill(), + stroke: new ol.style.Stroke() + }), + new ol.style.Fill(), + new ol.style.Stroke() ] }); diff --git a/test/spec/ol/style/style.test.js b/test/spec/ol/style/style.test.js index 296193d206..8eb2ec2fe0 100644 --- a/test/spec/ol/style/style.test.js +++ b/test/spec/ol/style/style.test.js @@ -2,10 +2,40 @@ goog.provide('ol.test.style.Style'); describe('ol.style.Style', function() { + describe('constructor', function() { + + it('creates a style instance given rules', function() { + var style = new ol.style.Style({ + rules: [ + new ol.style.Rule({ + filter: 'foo == "bar"', + symbolizers: [ + new ol.style.Fill({ + color: '#ff0000' + }) + ] + }) + ] + }); + expect(style).to.be.a(ol.style.Style); + }); + + it('creates a style instance given only "else" symbolizers', function() { + var style = new ol.style.Style({ + symbolizers: [ + new ol.style.Fill({ + color: '#ff0000' + }) + ] + }); + expect(style).to.be.a(ol.style.Style); + }); + + }); + describe('#createLiterals()', function() { it('creates symbolizer literals for a feature', function() { - var style = new ol.style.Style({ rules: [ new ol.style.Rule({ @@ -13,16 +43,20 @@ describe('ol.style.Style', function() { symbolizers: [ new ol.style.Shape({ size: 4, - fill: new ol.style.Fill({color: '#BADA55'}) + fill: new ol.style.Fill({ + color: ol.expr.parse('fillColor') + }) }) ] }) ] }); var feature = new ol.Feature({ + fillColor: '#BADA55', geometry: new ol.geom.Point([1, 2]) }); feature.set('foo', 'bar'); + var literals = style.createLiterals(feature); expect(literals).to.have.length(1); expect(literals[0].fillColor).to.be('#BADA55'); @@ -31,6 +65,61 @@ describe('ol.style.Style', function() { expect(style.createLiterals(feature)).to.have.length(0); }); + it('uses the "else" symbolizers when no rules are provided', function() { + var style = new ol.style.Style({ + symbolizers: [ + new ol.style.Stroke({ + color: '#ff0000' + }) + ] + }); + + var feature = new ol.Feature({ + geometry: new ol.geom.LineString([[1, 2], [3, 4]]) + }); + + var literals = style.createLiterals(feature); + expect(literals).to.have.length(1); + expect(literals[0].color).to.be('#ff0000'); + }); + + it('uses the "else" symbolizers when no rules apply', function() { + var style = new ol.style.Style({ + rules: [ + new ol.style.Rule({ + filter: 'name == "match"', + symbolizers: [ + new ol.style.Stroke({ + color: '#ff00ff' + }) + ] + }) + ], + // these are the "else" symbolizers + symbolizers: [ + new ol.style.Stroke({ + color: '#00ff00' + }) + ] + }); + + var feature = new ol.Feature({ + geometry: new ol.geom.LineString([[1, 2], [3, 4]]) + }); + + var literals = style.createLiterals(feature); + expect(literals).to.have.length(1); + expect(literals[0].color).to.be('#00ff00'); + + feature = new ol.Feature({ + name: 'match', + geometry: new ol.geom.LineString([[1, 2], [3, 4]]) + }); + literals = style.createLiterals(feature); + expect(literals).to.have.length(1); + expect(literals[0].color).to.be('#ff00ff'); + }); + }); describe('ol.style.Style.defaults.createLiterals(feature)', function() {