Add support for "else" symbolizers

When a style has no rules, the "else" symbolizers apply.  When a style has rules and none of them apply to the given feature, the "else" symbolizers apply.  Note that this is different than default symbolizer properties that might be merged into all symbolizers (as in OL2) - I don't think we should support that.
This commit is contained in:
Tim Schaub
2013-08-15 10:34:24 -04:00
parent 6078fe7b02
commit bad401bc17
5 changed files with 145 additions and 49 deletions

View File

@@ -41,8 +41,7 @@ ol.expr.register('getOpacity', function() {
return 0.75 * (1 - delta / 12);
});
var style = new ol.style.Style({rules: [
new ol.style.Rule({
var style = new ol.style.Style({
symbolizers: [
new ol.style.Fill({
color: '#ffff33',
@@ -52,8 +51,7 @@ var style = new ol.style.Style({rules: [
color: '#ffffff',
})
]
})
]});
});
var vector = new ol.layer.Vector({
source: new ol.source.Vector({

View File

@@ -23,8 +23,7 @@ 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({
style: new ol.style.Style({
symbolizers: [
new ol.style.Fill({
color: '#BADA55',
@@ -37,7 +36,6 @@ var vector = new ol.layer.Vector({
})
]
})
]})
});
var map = new ol.Map({

View File

@@ -642,7 +642,10 @@
/**
* @typedef {Object} ol.style.StyleOptions
* @property {Array.<ol.style.Rule>} rules Rules.
* @property {Array.<ol.style.Rule>|undefined} rules Rules.
* @property {Array.<ol.style.Symbolizer>|undefined} symbolizers Symbolizers
* (that apply if no rules are provided or where none of the provided rules
* apply).
*/
/**

View File

@@ -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.<ol.style.Symbolizer>}
* @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,8 +67,6 @@ 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(),
@@ -65,8 +75,6 @@ ol.style.Style.defaults = new ol.style.Style({
new ol.style.Fill(),
new ol.style.Stroke()
]
})
]
});

View File

@@ -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() {