Support fillOpacity and strokeOpacity on polygon symbolizers

This commit is contained in:
Tim Schaub
2013-07-30 16:52:57 -06:00
parent f210d6d0e1
commit 993e76e3a1
3 changed files with 229 additions and 66 deletions

View File

@@ -306,11 +306,13 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPolygonFeatures_ =
var context = this.context_,
strokeColor = symbolizer.strokeColor,
strokeWidth = symbolizer.strokeWidth,
strokeOpacity = symbolizer.strokeOpacity,
fillColor = symbolizer.fillColor,
fillOpacity = symbolizer.fillOpacity,
globalAlpha,
i, ii, geometry, components, j, jj, poly,
rings, numRings, ring, dim, k, kk, vec;
context.globalAlpha = symbolizer.opacity;
if (strokeColor) {
context.strokeStyle = strokeColor;
if (strokeWidth) {
@@ -359,7 +361,17 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPolygonFeatures_ =
}
if (fillColor && strokeColor) {
// scenario 3 - fill and stroke each time
if (fillOpacity !== globalAlpha) {
goog.asserts.assertNumber(fillOpacity);
context.globalAlpha = fillOpacity;
globalAlpha = fillOpacity;
}
context.fill();
if (strokeOpacity !== globalAlpha) {
goog.asserts.assertNumber(strokeOpacity);
context.globalAlpha = strokeOpacity;
globalAlpha = strokeOpacity;
}
context.stroke();
if (i < ii - 1 || j < jj - 1) {
context.beginPath();
@@ -371,9 +383,19 @@ ol.renderer.canvas.VectorRenderer.prototype.renderPolygonFeatures_ =
if (!(fillColor && strokeColor)) {
if (fillColor) {
// scenario 2 - fill all at once
if (fillOpacity !== globalAlpha) {
goog.asserts.assertNumber(fillOpacity);
context.globalAlpha = fillOpacity;
globalAlpha = fillOpacity;
}
context.fill();
} else {
// scenario 1 - stroke all at once
if (strokeOpacity !== globalAlpha) {
goog.asserts.assertNumber(strokeOpacity);
context.globalAlpha = strokeOpacity;
globalAlpha = strokeOpacity;
}
context.stroke();
}
}

View File

@@ -11,9 +11,10 @@ goog.require('ol.style.SymbolizerLiteral');
/**
* @typedef {{fillColor: (string|undefined),
* fillOpacity: (number|undefined),
* strokeColor: (string|undefined),
* strokeWidth: (number|undefined),
* opacity: (number)}}
* strokeOpacity: (number|undefined),
* strokeWidth: (number|undefined)}}
*/
ol.style.PolygonLiteralOptions;
@@ -33,6 +34,13 @@ ol.style.PolygonLiteral = function(options) {
goog.asserts.assertString(options.fillColor, 'fillColor must be a string');
}
/** @type {number|undefined} */
this.fillOpacity = options.fillOpacity;
if (goog.isDef(options.fillOpacity)) {
goog.asserts.assertNumber(
options.fillOpacity, 'fillOpacity must be a number');
}
/** @type {string|undefined} */
this.strokeColor = options.strokeColor;
if (goog.isDef(this.strokeColor)) {
@@ -40,6 +48,13 @@ ol.style.PolygonLiteral = function(options) {
this.strokeColor, 'strokeColor must be a string');
}
/** @type {number|undefined} */
this.strokeOpacity = options.strokeOpacity;
if (goog.isDef(this.strokeOpacity)) {
goog.asserts.assertNumber(
this.strokeOpacity, 'strokeOpacity must be a number');
}
/** @type {number|undefined} */
this.strokeWidth = options.strokeWidth;
if (goog.isDef(this.strokeWidth)) {
@@ -47,14 +62,14 @@ ol.style.PolygonLiteral = function(options) {
this.strokeWidth, 'strokeWidth must be a number');
}
goog.asserts.assert(
goog.isDef(this.fillColor) ||
(goog.isDef(this.strokeColor) && goog.isDef(this.strokeWidth)),
'Either fillColor or strokeColor and strokeWidth must be set');
goog.asserts.assertNumber(options.opacity, 'opacity must be a number');
/** @type {number} */
this.opacity = options.opacity;
// fill and/or stroke properties must be defined
var fillDef = goog.isDef(this.fillColor) && goog.isDef(this.fillOpacity);
var strokeDef = goog.isDef(this.strokeColor) &&
goog.isDef(this.strokeOpacity) &&
goog.isDef(this.strokeWidth);
goog.asserts.assert(fillDef || strokeDef,
'Either fillColor and fillOpacity or ' +
'strokeColor and strokeOpacity and strokeWidth must be set');
};
goog.inherits(ol.style.PolygonLiteral, ol.style.SymbolizerLiteral);
@@ -65,9 +80,10 @@ goog.inherits(ol.style.PolygonLiteral, ol.style.SymbolizerLiteral);
*/
ol.style.PolygonLiteral.prototype.equals = function(polygonLiteral) {
return this.fillColor == polygonLiteral.fillColor &&
this.fillOpacity == polygonLiteral.fillOpacity &&
this.strokeColor == polygonLiteral.strokeColor &&
this.strokeWidth == polygonLiteral.strokeWidth &&
this.opacity == polygonLiteral.opacity;
this.strokeOpacity == polygonLiteral.strokeOpacity &&
this.strokeWidth == polygonLiteral.strokeWidth;
};
@@ -80,20 +96,54 @@ ol.style.PolygonLiteral.prototype.equals = function(polygonLiteral) {
ol.style.Polygon = function(options) {
goog.base(this);
// fill handling - if any fill property is supplied, use all defaults
var fillColor = null,
fillOpacity = null;
if (goog.isDefAndNotNull(options.fillColor) ||
goog.isDefAndNotNull(options.fillOpacity)) {
if (goog.isDefAndNotNull(options.fillColor)) {
fillColor = (options.fillColor instanceof ol.expr.Expression) ?
options.fillColor :
new ol.expr.Literal(options.fillColor);
} else {
fillColor = new ol.expr.Literal(
/** @type {string} */ (ol.style.PolygonDefaults.fillColor));
}
if (goog.isDefAndNotNull(options.fillOpacity)) {
fillOpacity = (options.fillOpacity instanceof ol.expr.Expression) ?
options.fillOpacity :
new ol.expr.Literal(options.fillOpacity);
} else {
fillOpacity = new ol.expr.Literal(
/** @type {number} */ (ol.style.PolygonDefaults.fillOpacity));
}
}
/**
* @type {ol.expr.Expression}
* @private
*/
this.fillColor_ = !goog.isDefAndNotNull(options.fillColor) ?
null :
(options.fillColor instanceof ol.expr.Expression) ?
options.fillColor : new ol.expr.Literal(options.fillColor);
this.fillColor_ = fillColor;
/**
* @type {ol.expr.Expression}
* @private
*/
this.fillOpacity_ = fillOpacity;
// stroke handling - if any stroke property is supplied, use defaults
var strokeColor = null,
strokeOpacity = null,
strokeWidth = null;
if (goog.isDefAndNotNull(options.strokeColor) ||
goog.isDefAndNotNull(options.strokeOpacity) ||
goog.isDefAndNotNull(options.strokeWidth)) {
if (goog.isDefAndNotNull(options.strokeColor)) {
@@ -105,6 +155,15 @@ ol.style.Polygon = function(options) {
/** @type {string} */ (ol.style.PolygonDefaults.strokeColor));
}
if (goog.isDefAndNotNull(options.strokeOpacity)) {
strokeOpacity = (options.strokeOpacity instanceof ol.expr.Expression) ?
options.strokeOpacity :
new ol.expr.Literal(options.strokeOpacity);
} else {
strokeOpacity = new ol.expr.Literal(
/** @type {number} */ (ol.style.PolygonDefaults.strokeOpacity));
}
if (goog.isDefAndNotNull(options.strokeWidth)) {
strokeWidth = (options.strokeWidth instanceof ol.expr.Expression) ?
options.strokeWidth :
@@ -113,6 +172,7 @@ ol.style.Polygon = function(options) {
strokeWidth = new ol.expr.Literal(
/** @type {number} */ (ol.style.PolygonDefaults.strokeWidth));
}
}
/**
@@ -125,21 +185,21 @@ ol.style.Polygon = function(options) {
* @type {ol.expr.Expression}
* @private
*/
this.strokeWidth_ = strokeWidth;
// one of stroke or fill can be null, both null is user error
goog.asserts.assert(!goog.isNull(this.fillColor_) ||
!(goog.isNull(this.strokeColor_) && goog.isNull(this.strokeWidth_)),
'Stroke or fill properties must be provided');
this.strokeOpacity_ = strokeOpacity;
/**
* @type {ol.expr.Expression}
* @private
*/
this.opacity_ = !goog.isDef(options.opacity) ?
new ol.expr.Literal(ol.style.PolygonDefaults.opacity) :
(options.opacity instanceof ol.expr.Expression) ?
options.opacity : new ol.expr.Literal(options.opacity);
this.strokeWidth_ = strokeWidth;
// one of stroke or fill can be null, both null is user error
var fill = !goog.isNull(this.fillColor_) && !goog.isNull(this.fillOpacity_);
var stroke = !goog.isNull(this.strokeColor_) &&
!goog.isNull(this.strokeOpacity_) &&
!goog.isNull(this.strokeWidth_);
goog.asserts.assert(fill || stroke,
'Stroke or fill properties must be provided');
};
goog.inherits(ol.style.Polygon, ol.style.Symbolizer);
@@ -157,31 +217,43 @@ ol.style.Polygon.prototype.createLiteral = function(opt_feature) {
goog.asserts.assertString(fillColor, 'fillColor must be a string');
}
var fillOpacity;
if (!goog.isNull(this.fillOpacity_)) {
fillOpacity = ol.expr.evaluateFeature(this.fillOpacity_, opt_feature);
goog.asserts.assertNumber(fillOpacity, 'fillOpacity must be a number');
}
var strokeColor;
if (!goog.isNull(this.strokeColor_)) {
strokeColor = ol.expr.evaluateFeature(this.strokeColor_, opt_feature);
goog.asserts.assertString(strokeColor, 'strokeColor must be a string');
}
var strokeOpacity;
if (!goog.isNull(this.strokeOpacity_)) {
strokeOpacity = ol.expr.evaluateFeature(this.strokeOpacity_, opt_feature);
goog.asserts.assertNumber(strokeOpacity, 'strokeOpacity must be a number');
}
var strokeWidth;
if (!goog.isNull(this.strokeWidth_)) {
strokeWidth = ol.expr.evaluateFeature(this.strokeWidth_, opt_feature);
goog.asserts.assertNumber(strokeWidth, 'strokeWidth must be a number');
}
goog.asserts.assert(
goog.isDef(fillColor) ||
(goog.isDef(strokeColor) && goog.isDef(strokeWidth)),
'either fillColor or strokeColor and strokeWidth must be defined');
var fill = goog.isDef(fillColor) && goog.isDef(fillOpacity);
var stroke = goog.isDef(strokeColor) && goog.isDef(strokeOpacity) &&
goog.isDef(strokeWidth);
var opacity = ol.expr.evaluateFeature(this.opacity_, opt_feature);
goog.asserts.assertNumber(opacity, 'opacity must be a number');
goog.asserts.assert(fill || stroke,
'either fill or stroke properties must be defined');
return new ol.style.PolygonLiteral({
fillColor: fillColor,
fillOpacity: fillOpacity,
strokeColor: strokeColor,
strokeWidth: strokeWidth,
opacity: opacity
strokeOpacity: strokeOpacity,
strokeWidth: strokeWidth
});
};
@@ -196,11 +268,11 @@ ol.style.Polygon.prototype.getFillColor = function() {
/**
* Get the opacity.
* @return {ol.expr.Expression} Opacity.
* Get the fill opacity.
* @return {ol.expr.Expression} Fill opacity.
*/
ol.style.Polygon.prototype.getOpacity = function() {
return this.opacity_;
ol.style.Polygon.prototype.getFillOpacity = function() {
return this.fillOpacity_;
};
@@ -213,6 +285,15 @@ ol.style.Polygon.prototype.getStrokeColor = function() {
};
/**
* Get the stroke opacity.
* @return {ol.expr.Expression} Stroke opacity.
*/
ol.style.Polygon.prototype.getStrokeOpacity = function() {
return this.strokeOpacity_;
};
/**
* Get the stroke width.
* @return {ol.expr.Expression} Stroke width.
@@ -233,12 +314,12 @@ ol.style.Polygon.prototype.setFillColor = function(fillColor) {
/**
* Set the opacity.
* @param {ol.expr.Expression} opacity Opacity.
* Set the fill opacity.
* @param {ol.expr.Expression} fillOpacity Fill opacity.
*/
ol.style.Polygon.prototype.setOpacity = function(opacity) {
goog.asserts.assertInstanceof(opacity, ol.expr.Expression);
this.opacity_ = opacity;
ol.style.Polygon.prototype.setFillOpacity = function(fillOpacity) {
goog.asserts.assertInstanceof(fillOpacity, ol.expr.Expression);
this.fillOpacity_ = fillOpacity;
};
@@ -252,6 +333,16 @@ ol.style.Polygon.prototype.setStrokeColor = function(strokeColor) {
};
/**
* Set the stroke opacity.
* @param {ol.expr.Expression} strokeOpacity Stroke opacity.
*/
ol.style.Polygon.prototype.setStrokeOpacity = function(strokeOpacity) {
goog.asserts.assertInstanceof(strokeOpacity, ol.expr.Expression);
this.strokeOpacity_ = strokeOpacity;
};
/**
* Set the stroke width.
* @param {ol.expr.Expression} strokeWidth Stroke width.
@@ -267,7 +358,8 @@ ol.style.Polygon.prototype.setStrokeWidth = function(strokeWidth) {
*/
ol.style.PolygonDefaults = new ol.style.PolygonLiteral({
fillColor: '#ffffff',
fillOpacity: 0.4,
strokeColor: '#696969',
strokeWidth: 1.5,
opacity: 0.75
strokeOpacity: 0.8,
strokeWidth: 1.5
});

View File

@@ -8,23 +8,58 @@ describe('ol.style.PolygonLiteral', function() {
var literal = new ol.style.PolygonLiteral({
strokeWidth: 3,
strokeColor: '#013',
strokeOpacity: 0.4,
fillColor: '#BADA55',
opacity: 1
fillOpacity: 0.3
});
var equalLiteral = new ol.style.PolygonLiteral({
strokeWidth: 3,
strokeColor: '#013',
strokeOpacity: 0.4,
fillColor: '#BADA55',
strokeColor: '#013',
strokeWidth: 3,
opacity: 1
fillOpacity: 0.3
});
var differentLiteral = new ol.style.PolygonLiteral({
fillColor: '#013',
var differentStrokeWidth = new ol.style.PolygonLiteral({
strokeWidth: 5,
strokeColor: '#013',
strokeOpacity: 0.4,
fillColor: '#BADA55',
fillOpacity: 0.3
});
var differentStrokeColor = new ol.style.PolygonLiteral({
strokeWidth: 3,
opacity: 1
strokeColor: '#ffff00',
strokeOpacity: 0.4,
fillColor: '#BADA55',
fillOpacity: 0.3
});
var differentStrokeOpacity = new ol.style.PolygonLiteral({
strokeWidth: 3,
strokeColor: '#013',
strokeOpacity: 0.41,
fillColor: '#BADA55',
fillOpacity: 0.3
});
var differentFillColor = new ol.style.PolygonLiteral({
strokeWidth: 3,
strokeColor: '#013',
strokeOpacity: 0.4,
fillColor: '#00ffff',
fillOpacity: 0.3
});
var differentFillOpacity = new ol.style.PolygonLiteral({
strokeWidth: 3,
strokeColor: '#013',
strokeOpacity: 0.4,
fillColor: '#BADA55',
fillOpacity: 0.31
});
expect(literal.equals(equalLiteral)).to.be(true);
expect(literal.equals(differentLiteral)).to.be(false);
expect(literal.equals(differentStrokeWidth)).to.be(false);
expect(literal.equals(differentStrokeColor)).to.be(false);
expect(literal.equals(differentStrokeOpacity)).to.be(false);
expect(literal.equals(differentFillColor)).to.be(false);
expect(literal.equals(differentFillOpacity)).to.be(false);
});
});
@@ -45,7 +80,7 @@ describe('ol.style.Polygon', function() {
it('accepts expressions', function() {
var symbolizer = new ol.style.Polygon({
opacity: ol.expr.parse('value / 100'),
fillOpacity: ol.expr.parse('value / 100'),
fillColor: ol.expr.parse('fillAttr')
});
expect(symbolizer).to.be.a(ol.style.Polygon);
@@ -57,7 +92,7 @@ describe('ol.style.Polygon', function() {
it('evaluates expressions with the given feature', function() {
var symbolizer = new ol.style.Polygon({
opacity: ol.expr.parse('value / 100'),
fillOpacity: ol.expr.parse('value / 100'),
fillColor: ol.expr.parse('fillAttr')
});
@@ -68,7 +103,7 @@ describe('ol.style.Polygon', function() {
var literal = symbolizer.createLiteral(feature);
expect(literal).to.be.a(ol.style.PolygonLiteral);
expect(literal.opacity).to.be(42 / 100);
expect(literal.fillOpacity).to.be(42 / 100);
expect(literal.fillColor).to.be('#ff0000');
expect(literal.strokeColor).to.be(undefined);
});
@@ -101,6 +136,20 @@ describe('ol.style.Polygon', function() {
});
describe('#getFillOpacity()', function() {
it('returns the fill opacity', function() {
var symbolizer = new ol.style.Polygon({
fillColor: '#ffffff',
fillOpacity: 0.123
});
var opacity = symbolizer.getFillOpacity();
expect(opacity).to.be.a(ol.expr.Literal);
expect(opacity.getValue()).to.be(0.123);
});
});
describe('#getStrokeColor()', function() {
@@ -130,15 +179,15 @@ describe('ol.style.Polygon', function() {
});
describe('#getOpacity()', function() {
describe('#getStrokeOpacity()', function() {
it('returns the stroke opacity', function() {
var symbolizer = new ol.style.Polygon({
strokeWidth: 1,
opacity: 0.123
strokeOpacity: 0.123
});
var opacity = symbolizer.getOpacity();
var opacity = symbolizer.getStrokeOpacity();
expect(opacity).to.be.a(ol.expr.Literal);
expect(opacity.getValue()).to.be(0.123);
});
@@ -228,16 +277,16 @@ describe('ol.style.Polygon', function() {
});
describe('#setOpacity()', function() {
describe('#setStrokeOpacity()', function() {
it('sets the stroke opacity', function() {
var symbolizer = new ol.style.Polygon({
strokeWidth: 1,
opacity: 0.123
strokeOpacity: 0.123
});
symbolizer.setOpacity(new ol.expr.Literal(0.321));
symbolizer.setStrokeOpacity(new ol.expr.Literal(0.321));
var opacity = symbolizer.getOpacity();
var opacity = symbolizer.getStrokeOpacity();
expect(opacity).to.be.a(ol.expr.Literal);
expect(opacity.getValue()).to.be(0.321);
});
@@ -245,11 +294,11 @@ describe('ol.style.Polygon', function() {
it('throws when not provided an expression', function() {
var symbolizer = new ol.style.Polygon({
strokeWidth: 1,
opacity: 1
strokeOpacity: 1
});
expect(function() {
symbolizer.setOpacity(0.5);
symbolizer.setStrokeOpacity(0.5);
}).throwException(function(err) {
expect(err).to.be.a(goog.asserts.AssertionError);
});