diff --git a/src/ol/style/style.js b/src/ol/style/style.js index 40875ef7f3..c6f3e02afb 100644 --- a/src/ol/style/style.js +++ b/src/ol/style/style.js @@ -4,6 +4,7 @@ goog.require('ol.Feature'); goog.require('ol.geom.GeometryType'); goog.require('ol.style.Rule'); goog.require('ol.style.Literal'); +goog.require('ol.style.PolygonLiteral'); @@ -68,3 +69,56 @@ ol.style.Style.applyDefaultStyle = function(feature) { } return symbolizerLiterals; }; + + +/** + * Collapse partial polygon symbolizers. + * @param {Array.} literals Input literals. + * @return {Array.} Reduced literals. + */ +ol.style.Style.reduceLiterals = function(literals) { + var reduced = []; + var literal, stroke, fill, key, value; + for (var i = 0, ii = literals.length; i < ii; ++i) { + literal = literals[i]; + if (literal instanceof ol.style.PolygonLiteral) { + if (goog.isDef(literal.strokeColor) && + !goog.isDef(literal.fillColor)) { + // stroke only, check for previous fill only + if (fill) { + for (key in literal) { + value = literal[key]; + if (goog.isDef(value)) { + fill[key] = value; + } + } + fill = null; + } else { + stroke = literal; + reduced.push(stroke); + } + } else if (goog.isDef(literal.fillColor) + && !goog.isDef(literal.strokeColor)) { + // fill only, check for previous stroke only + if (stroke) { + for (key in literal) { + value = literal[key]; + if (goog.isDef(value)) { + stroke[key] = value; + } + } + stroke = null; + } else { + fill = literal; + reduced.push(fill); + } + } else { + // both stroke and fill, proceed + reduced.push(literal); + } + } else { + reduced.push(literal); + } + } + return reduced; +}; diff --git a/test/spec/ol/style/style.test.js b/test/spec/ol/style/style.test.js index 6a35416548..bbe23ff25a 100644 --- a/test/spec/ol/style/style.test.js +++ b/test/spec/ol/style/style.test.js @@ -58,13 +58,116 @@ describe('ol.style.Style', function() { }); + describe('#reduceLiterals', function() { + + it('collapses stroke or fill only literals where possible', function() { + var literals = [ + new ol.style.PolygonLiteral({ + fillColor: '#ff0000', + fillOpacity: 0.5 + }), + new ol.style.PolygonLiteral({ + strokeColor: '#00ff00', + strokeOpacity: 0.6, + strokeWidth: 3 + }) + ]; + + var reduced = ol.style.Style.reduceLiterals(literals); + expect(reduced).to.have.length(1); + + var poly = reduced[0]; + expect(poly.fillColor).to.be('#ff0000'); + expect(poly.fillOpacity).to.be(0.5); + expect(poly.strokeColor).to.be('#00ff00'); + expect(poly.strokeOpacity).to.be(0.6); + expect(poly.strokeWidth).to.be(3); + }); + + it('leaves complete polygon literals alone', function() { + var literals = [ + new ol.style.PolygonLiteral({ + fillColor: '#ff0000', + fillOpacity: 0.5, + strokeColor: '#00ff00', + strokeOpacity: 0.6, + strokeWidth: 3 + }), + new ol.style.PolygonLiteral({ + strokeColor: '#0000ff', + strokeOpacity: 0.7, + strokeWidth: 1 + }) + ]; + + var reduced = ol.style.Style.reduceLiterals(literals); + expect(reduced).to.have.length(2); + + var first = reduced[0]; + expect(first.fillColor).to.be('#ff0000'); + expect(first.fillOpacity).to.be(0.5); + expect(first.strokeColor).to.be('#00ff00'); + expect(first.strokeOpacity).to.be(0.6); + expect(first.strokeWidth).to.be(3); + + var second = reduced[1]; + expect(second.fillColor).to.be(undefined); + expect(second.fillOpacity).to.be(undefined); + expect(second.strokeColor).to.be('#0000ff'); + expect(second.strokeOpacity).to.be(0.7); + expect(second.strokeWidth).to.be(1); + }); + + it('leaves other literals alone', function() { + var literals = [ + new ol.style.PolygonLiteral({ + strokeColor: '#00ff00', + strokeOpacity: 0.6, + strokeWidth: 3 + }), + new ol.style.PolygonLiteral({ + fillColor: '#ff0000', + fillOpacity: 0.5 + }), + new ol.style.TextLiteral({ + color: '#ffffff', + fontFamily: 'Arial', + fontSize: 11, + text: 'Test', + opacity: 0.5 + }) + ]; + + var reduced = ol.style.Style.reduceLiterals(literals); + expect(reduced).to.have.length(2); + + var first = reduced[0]; + expect(first.fillColor).to.be('#ff0000'); + expect(first.fillOpacity).to.be(0.5); + expect(first.strokeColor).to.be('#00ff00'); + expect(first.strokeOpacity).to.be(0.6); + expect(first.strokeWidth).to.be(3); + + var second = reduced[1]; + expect(second.color).to.be('#ffffff'); + expect(second.fontFamily).to.be('Arial'); + expect(second.fontSize).to.be(11); + expect(second.text).to.be('Test'); + expect(second.opacity).to.be(0.5); + }); + + + }) + }); goog.require('ol.Feature'); goog.require('ol.geom.LineString'); goog.require('ol.geom.Point'); goog.require('ol.geom.Polygon'); +goog.require('ol.style.PolygonLiteral'); goog.require('ol.style.Rule'); goog.require('ol.style.Shape'); goog.require('ol.style.ShapeLiteral'); goog.require('ol.style.Style'); +goog.require('ol.style.TextLiteral');