diff --git a/lib/OpenLayers/Format/Filter/v1.js b/lib/OpenLayers/Format/Filter/v1.js
index 76b0c5743f..dfc3bc6829 100644
--- a/lib/OpenLayers/Format/Filter/v1.js
+++ b/lib/OpenLayers/Format/Filter/v1.js
@@ -77,6 +77,27 @@ OpenLayers.Format.Filter.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
*/
readers: {
"ogc": {
+ "_expression": function(node) {
+ // only the simplest of ogc:expression handled
+ // "some text and an attribute"}
+ var obj, value = "";
+ for(var child=node.firstChild; child; child=child.nextSibling) {
+ switch(child.nodeType) {
+ case 1:
+ obj = this.readNode(child);
+ if (obj.property) {
+ value += "${" + obj.property + "}";
+ } else if (obj.value !== undefined) {
+ value += obj.value;
+ }
+ break;
+ case 3: // text node
+ case 4: // cdata section
+ value += child.nodeValue;
+ }
+ }
+ return value;
+ },
"Filter": function(node, parent) {
// Filters correspond to subclasses of OpenLayers.Filter.
// Since they contain information we don't persist, we
@@ -166,11 +187,11 @@ OpenLayers.Format.Filter.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
},
"LowerBoundary": function(node, filter) {
filter.lowerBoundary = OpenLayers.String.numericIf(
- this.readOgcExpression(node));
+ this.readers.ogc._expression.call(this, node));
},
"UpperBoundary": function(node, filter) {
filter.upperBoundary = OpenLayers.String.numericIf(
- this.readOgcExpression(node));
+ this.readers.ogc._expression.call(this, node));
},
"Intersects": function(node, obj) {
this.readSpatial(node, obj, OpenLayers.Filter.Spatial.INTERSECTS);
@@ -218,26 +239,6 @@ OpenLayers.Format.Filter.v1 = OpenLayers.Class(OpenLayers.Format.XML, {
obj.filters.push(filter);
},
- /**
- * Method: readOgcExpression
- * Limited support for OGC expressions.
- *
- * Parameters:
- * node - {DOMElement} A DOM element that contains an ogc:expression.
- *
- * Returns:
- * {String} A value to be used in a symbolizer.
- */
- readOgcExpression: function(node) {
- var obj = {};
- this.readChildNodes(node, obj);
- var value = obj.value;
- if(value === undefined) {
- value = this.getChildValue(node);
- }
- return value;
- },
-
/**
* Method: writeOgcExpression
* Limited support for writing OGC expressions. Currently it supports
diff --git a/lib/OpenLayers/Format/SLD/v1.js b/lib/OpenLayers/Format/SLD/v1.js
index 8f9f39d903..5003a3d08f 100644
--- a/lib/OpenLayers/Format/SLD/v1.js
+++ b/lib/OpenLayers/Format/SLD/v1.js
@@ -219,16 +219,9 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
}
},
"Label": function(node, symbolizer) {
- // only supporting literal or property name
- var obj = {};
- this.readChildNodes(node, obj);
- if(obj.property) {
- symbolizer.label = "${" + obj.property + "}";
- } else {
- var value = this.readOgcExpression(node);
- if(value) {
- symbolizer.label = value;
- }
+ var value = this.readers.ogc._expression.call(this, node);
+ if (value) {
+ symbolizer.label = value;
}
},
"Font": function(node, symbolizer) {
@@ -243,7 +236,7 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
symbolizer.haloOpacity = obj.fillOpacity;
},
"Radius": function(node, symbolizer) {
- var radius = this.readOgcExpression(node);
+ var radius = this.readers.ogc._expression.call(this, node);
if(radius != null) {
// radius is only used for halo
symbolizer.haloRadius = radius;
@@ -345,7 +338,7 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
var symProperty = this.cssMap[cssProperty];
if(symProperty) {
// Limited support for parsing of OGC expressions
- var value = this.readOgcExpression(node);
+ var value = this.readers.ogc._expression.call(this, node);
// always string, could be an empty string
if(value) {
symbolizer[symProperty] = value;
@@ -376,7 +369,13 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
symbolizer.graphicOpacity = graphic.opacity;
}
if(graphic.size != undefined) {
- symbolizer.pointRadius = graphic.size / 2;
+ var pointRadius = graphic.size / 2;
+ if (isNaN(pointRadius)) {
+ // likely a property name
+ symbolizer.graphicWidth = graphic.size;
+ } else {
+ symbolizer.pointRadius = graphic.size / 2;
+ }
}
if(graphic.href != undefined) {
symbolizer.externalGraphic = graphic.href;
@@ -395,21 +394,21 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
graphic.graphicName = this.getChildValue(node);
},
"Opacity": function(node, obj) {
- var opacity = this.readOgcExpression(node);
+ var opacity = this.readers.ogc._expression.call(this, node);
// always string, could be empty string
if(opacity) {
obj.opacity = opacity;
}
},
"Size": function(node, obj) {
- var size = this.readOgcExpression(node);
+ var size = this.readers.ogc._expression.call(this, node);
// always string, could be empty string
if(size) {
obj.size = size;
}
},
"Rotation": function(node, obj) {
- var rotation = this.readOgcExpression(node);
+ var rotation = this.readers.ogc._expression.call(this, node);
// always string, could be empty string
if(rotation) {
obj.rotation = rotation;
@@ -530,6 +529,36 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
*/
writers: OpenLayers.Util.applyDefaults({
"sld": {
+ "_OGCExpression": function(nodeName, value) {
+ // only the simplest of ogc:expression handled
+ // {label: "some text and a ${propertyName}"}
+ var node = this.createElementNSPlus(nodeName);
+ var tokens = typeof value == "string" ?
+ value.split("${") :
+ [value];
+ node.appendChild(this.createTextNode(tokens[0]));
+ var item, last;
+ for(var i=1, len=tokens.length; i 0) {
+ this.writeNode(
+ "ogc:PropertyName",
+ {property: item.substring(0, last)},
+ node
+ );
+ node.appendChild(
+ this.createTextNode(item.substring(++last))
+ );
+ } else {
+ // no ending }, so this is a literal ${
+ node.appendChild(
+ this.createTextNode("${" + item)
+ );
+ }
+ }
+ return node;
+ },
"StyledLayerDescriptor": function(sld) {
var root = this.createElementNSPlus(
"sld:StyledLayerDescriptor",
@@ -897,32 +926,9 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
return node;
},
"Label": function(label) {
- // only the simplest of ogc:expression handled
- // {label: "some text and a ${propertyName}"}
- var node = this.createElementNSPlus("sld:Label");
- var tokens = label.split("${");
- node.appendChild(this.createTextNode(tokens[0]));
- var item, last;
- for(var i=1, len=tokens.length; i 0) {
- this.writeNode(
- "ogc:PropertyName",
- {property: item.substring(0, last)},
- node
- );
- node.appendChild(
- this.createTextNode(item.substring(++last))
- );
- } else {
- // no ending }, so this is a literal ${
- node.appendChild(
- this.createTextNode("${" + item)
- );
- }
- }
- return node;
+ return this.writers.sld._OGCExpression.call(
+ this, "sld:Label", label
+ );
},
"Halo": function(symbolizer) {
var node = this.createElementNSPlus("sld:Halo");
@@ -1030,6 +1036,8 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
}
if(symbolizer.pointRadius != undefined) {
this.writeNode("Size", symbolizer.pointRadius * 2, node);
+ } else if (symbolizer.graphicWidth != undefined) {
+ this.writeNode("Size", symbolizer.graphicWidth, node);
}
if(symbolizer.rotation != undefined) {
this.writeNode("Rotation", symbolizer.rotation, node);
@@ -1070,9 +1078,9 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
});
},
"Size": function(value) {
- return this.createElementNSPlus("sld:Size", {
- value: value
- });
+ return this.writers.sld._OGCExpression.call(
+ this, "sld:Size", value
+ );
},
"Rotation": function(value) {
return this.createElementNSPlus("sld:Rotation", {
diff --git a/tests/Format/SLD/v1_0_0.html b/tests/Format/SLD/v1_0_0.html
index 8e2c0a238a..a31ba6a5f3 100644
--- a/tests/Format/SLD/v1_0_0.html
+++ b/tests/Format/SLD/v1_0_0.html
@@ -39,7 +39,7 @@
'' +
'' +
'' +
'' +
'Arial' +
@@ -121,6 +121,7 @@
'2' +
'' +
'' +
+ 'SIZE' +
'' +
'' +
'' +
@@ -130,7 +131,7 @@
'';
function test_read(t) {
- t.plan(22);
+ t.plan(23);
var xml = new OpenLayers.Format.XML();
var sldxml = xml.read(sld);
@@ -173,7 +174,7 @@
t.eq(poly.fillColor, "#ffffff", "(AAA161) first rule has proper fill");
t.eq(poly.strokeColor, "#000000", "(AAA161) first rule has proper stroke");
var text = symbolizer["Text"];
- t.eq(text.label, "${FOO}", "(AAA161) first rule has proper text label");
+ t.eq(text.label, "A ${FOO} label", "(AAA161) first rule has proper text label");
t.eq(layer.userStyles[0].propertyStyles["label"], true, "label added to propertyStyles");
t.eq(text.fontFamily, "Arial", "(AAA161) first rule has proper font family");
t.eq(text.fillColor, "#000000", "(AAA161) first rule has proper text fill");
@@ -203,6 +204,12 @@
t.ok(typeof rule.maxScaleDenominator == "number", "MaxScaleDenominator is a number");
t.eq(rule.evaluate(feature), true, "numeric filter comparison evaluates correctly");
+ // check for PropertyName size
+ layer = obj.namedLayers["Second Layer"];
+ style = layer.userStyles[0];
+ rule = style.rules[0];
+ t.eq(rule.symbolizer["Point"].graphicWidth, "${SIZE}", "dynamic size correctly set on graphicWidth");
+
// etc. I'm convinced read works, really wanted to test write (since examples don't test that)
// I'll add more tests here later.
@@ -211,7 +218,7 @@
function test_write(t) {
t.plan(3);
- // read first - testing that write produces the SLD aboce
+ // read first - testing that write produces the SLD above
var parser = new OpenLayers.Format.SLD.v1_0_0();
var xml = new OpenLayers.Format.XML();
var sldxml = xml.read(sld);