diff --git a/lib/OpenLayers/Format/SLD/v1.js b/lib/OpenLayers/Format/SLD/v1.js
index a6fe969c4a..f934f80d65 100644
--- a/lib/OpenLayers/Format/SLD/v1.js
+++ b/lib/OpenLayers/Format/SLD/v1.js
@@ -220,6 +220,78 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
);
}
},
+ "LabelPlacement": function(node, symbolizer) {
+ this.readChildNodes(node, symbolizer);
+ },
+ "PointPlacement": function(node, symbolizer) {
+ var config = {};
+ this.readChildNodes(node, config);
+ config.labelRotation = config.rotation;
+ delete config.rotation;
+ var labelAlign,
+ x = symbolizer.labelAnchorPointX,
+ y = symbolizer.labelAnchorPointY;
+ if (x <= 1/3) {
+ labelAlign = 'l';
+ } else if (x > 1/3 && x < 2/3) {
+ labelAlign = 'c';
+ } else if (x >= 2/3) {
+ labelAlign = 'r';
+ }
+ if (y <= 1/3) {
+ labelAlign += 'b';
+ } else if (y > 1/3 && y < 2/3) {
+ labelAlign += 'm';
+ } else if (y >= 2/3) {
+ labelAlign += 't';
+ }
+ config.labelAlign = labelAlign;
+ OpenLayers.Util.applyDefaults(symbolizer, config);
+ },
+ "AnchorPoint": function(node, symbolizer) {
+ this.readChildNodes(node, symbolizer);
+ },
+ "AnchorPointX": function(node, symbolizer) {
+ var labelAnchorPointX = this.readers.ogc._expression.call(this, node);
+ // always string, could be empty string
+ if(labelAnchorPointX) {
+ symbolizer.labelAnchorPointX = labelAnchorPointX;
+ }
+ },
+ "AnchorPointY": function(node, symbolizer) {
+ var labelAnchorPointY = this.readers.ogc._expression.call(this, node);
+ // always string, could be empty string
+ if(labelAnchorPointY) {
+ symbolizer.labelAnchorPointY = labelAnchorPointY;
+ }
+ },
+ "Displacement": function(node, symbolizer) {
+ this.readChildNodes(node, symbolizer);
+ },
+ "DisplacementX": function(node, symbolizer) {
+ var labelXOffset = this.readers.ogc._expression.call(this, node);
+ // always string, could be empty string
+ if(labelXOffset) {
+ symbolizer.labelXOffset = labelXOffset;
+ }
+ },
+ "DisplacementY": function(node, symbolizer) {
+ var labelYOffset = this.readers.ogc._expression.call(this, node);
+ // always string, could be empty string
+ if(labelYOffset) {
+ symbolizer.labelYOffset = labelYOffset;
+ }
+ },
+ "LinePlacement": function(node, symbolizer) {
+ this.readChildNodes(node, symbolizer);
+ },
+ "PerpendicularOffset": function(node, symbolizer) {
+ var labelPerpendicularOffset = this.readers.ogc._expression.call(this, node);
+ // always string, could be empty string
+ if(labelPerpendicularOffset) {
+ symbolizer.labelPerpendicularOffset = labelPerpendicularOffset;
+ }
+ },
"Label": function(node, symbolizer) {
var value = this.readers.ogc._expression.call(this, node);
if (value) {
@@ -885,16 +957,26 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
}
// add in optional Font
if(symbolizer.fontFamily != null ||
- symbolizer.fontSize != null ||
- symbolizer.fontWeight != null ||
- symbolizer.fontStyle != null) {
- this.writeNode("Font", symbolizer, node);
+ symbolizer.fontSize != null ||
+ symbolizer.fontWeight != null ||
+ symbolizer.fontStyle != null) {
+ this.writeNode("Font", symbolizer, node);
+ }
+ // add in optional LabelPlacement
+ if (symbolizer.labelAnchorPointX != null ||
+ symbolizer.labelAnchorPointY != null ||
+ symbolizer.labelAlign != null ||
+ symbolizer.labelXOffset != null ||
+ symbolizer.labelYOffset != null ||
+ symbolizer.labelRotation != null ||
+ symbolizer.labelPerpendicularOffset != null) {
+ this.writeNode("LabelPlacement", symbolizer, node);
}
// add in optional Halo
if(symbolizer.haloRadius != null ||
- symbolizer.haloColor != null ||
- symbolizer.haloOpacity != null) {
- this.writeNode("Halo", symbolizer, node);
+ symbolizer.haloColor != null ||
+ symbolizer.haloOpacity != null) {
+ this.writeNode("Halo", symbolizer, node);
}
// add in optional Fill
if(symbolizer.fontColor != null ||
@@ -906,6 +988,109 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
}
return node;
},
+ "LabelPlacement": function(symbolizer) {
+ var node = this.createElementNSPlus("sld:LabelPlacement");
+ if (symbolizer.labelAnchorPointX != null ||
+ symbolizer.labelAnchorPointY != null ||
+ symbolizer.labelAlign != null ||
+ symbolizer.labelXOffset != null ||
+ symbolizer.labelYOffset != null ||
+ symbolizer.labelRotation != null) {
+ this.writeNode("PointPlacement", symbolizer, node);
+ }
+ if (symbolizer.labelPerpendicularOffset != null) {
+ this.writeNode("LinePlacement", symbolizer, node);
+ }
+ return node;
+ },
+ "LinePlacement": function(symbolizer) {
+ var node = this.createElementNSPlus("sld:LinePlacement");
+ this.writeNode("PerpendicularOffset", symbolizer.labelPerpendicularOffset, node);
+ return node;
+ },
+ "PerpendicularOffset": function(value) {
+ return this.createElementNSPlus("sld:PerpendicularOffset", {
+ value: value
+ });
+ },
+ "PointPlacement": function(symbolizer) {
+ var node = this.createElementNSPlus("sld:PointPlacement");
+ if (symbolizer.labelAnchorPointX != null ||
+ symbolizer.labelAnchorPointY != null ||
+ symbolizer.labelAlign != null) {
+ this.writeNode("AnchorPoint", symbolizer, node);
+ }
+ if (symbolizer.labelXOffset != null ||
+ symbolizer.labelYOffset != null) {
+ this.writeNode("Displacement", symbolizer, node);
+ }
+ if (symbolizer.labelRotation != null) {
+ this.writeNode("Rotation", symbolizer.labelRotation, node);
+ }
+ return node;
+ },
+ "AnchorPoint": function(symbolizer) {
+ var node = this.createElementNSPlus("sld:AnchorPoint");
+ var x = symbolizer.labelAnchorPointX,
+ y = symbolizer.labelAnchorPointY;
+ if (x != null) {
+ this.writeNode("AnchorPointX", x, node);
+ }
+ if (y != null) {
+ this.writeNode("AnchorPointY", y, node);
+ }
+ if (x == null && y == null) {
+ var xAlign = symbolizer.labelAlign.substr(0, 1),
+ yAlign = symbolizer.labelAlign.substr(1, 1);
+ if (xAlign === "l") {
+ x = 0;
+ } else if (xAlign === "c") {
+ x = 0.5;
+ } else if (xAlign === "r") {
+ x = 1;
+ }
+ if (yAlign === "b") {
+ y = 0;
+ } else if (yAlign === "m") {
+ y = 0.5;
+ } else if (yAlign === "t") {
+ y = 1;
+ }
+ this.writeNode("AnchorPointX", x, node);
+ this.writeNode("AnchorPointY", y, node);
+ }
+ return node;
+ },
+ "AnchorPointX": function(value) {
+ return this.createElementNSPlus("sld:AnchorPointX", {
+ value: value
+ });
+ },
+ "AnchorPointY": function(value) {
+ return this.createElementNSPlus("sld:AnchorPointY", {
+ value: value
+ });
+ },
+ "Displacement": function(symbolizer) {
+ var node = this.createElementNSPlus("sld:Displacement");
+ if (symbolizer.labelXOffset != null) {
+ this.writeNode("DisplacementX", symbolizer.labelXOffset, node);
+ }
+ if (symbolizer.labelYOffset != null) {
+ this.writeNode("DisplacementY", symbolizer.labelYOffset, node);
+ }
+ return node;
+ },
+ "DisplacementX": function(value) {
+ return this.createElementNSPlus("sld:DisplacementX", {
+ value: value
+ });
+ },
+ "DisplacementY": function(value) {
+ return this.createElementNSPlus("sld:DisplacementY", {
+ value: value
+ });
+ },
"Font": function(symbolizer) {
var node = this.createElementNSPlus("sld:Font");
// add in CssParameters
diff --git a/tests/Format/SLD/v1_0_0.html b/tests/Format/SLD/v1_0_0.html
index 98f4cd161b..af58c30c7d 100644
--- a/tests/Format/SLD/v1_0_0.html
+++ b/tests/Format/SLD/v1_0_0.html
@@ -47,6 +47,19 @@
'bold' +
'normal' +
'' +
+ '' +
+ '' +
+ '' +
+ '0.5' +
+ '0.5' +
+ '' +
+ '' +
+ '5' +
+ '5' +
+ '' +
+ '45' +
+ '' +
+ '' +
'' +
'3' +
'' +
@@ -509,7 +522,55 @@
t.xml_eq(got, exp, "duplicated rules to write zIndex as FeatureTypeStyle elements");
}
-
+
+ function test_label_LinePlacement(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true
+ });
+ var style = new OpenLayers.Style2({
+ rules: [
+ new OpenLayers.Rule({
+ symbolizers: [
+ new OpenLayers.Symbolizer.Line({
+ strokeColor: "red",
+ strokeWidth: 3
+ }),
+ new OpenLayers.Symbolizer.Text({
+ label: "${FOO}",
+ labelPerpendicularOffset: 10
+ })
+ ]
+ })
+ ]
+ });
+ var got = format.writeNode("sld:UserStyle", style);
+ var exp = readXML("label_lineplacement_test.sld").documentElement;
+ t.xml_eq(got, exp, "LinePlacement written out correctly");
+ }
+
+ function test_labelAlignToAnchorPosition(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true
+ });
+ var style = new OpenLayers.Style2({
+ rules: [
+ new OpenLayers.Rule({
+ symbolizers: [
+ new OpenLayers.Symbolizer.Text({
+ label: "${FOO}",
+ labelAlign: "rb"
+ })
+ ]
+ })
+ ]
+ });
+ var got = format.writeNode("sld:UserStyle", style);
+ var exp = readXML("label_pointplacement_test.sld").documentElement;
+ t.xml_eq(got, exp, "PointPlacement with labelAlign written out correctly");
+ }
+
function test_read_FeatureTypeStyles(t) {
t.plan(13);
@@ -585,7 +646,6 @@
doc = readXML("polygon_labelhalo.sld");
out = format.write(format.read(doc));
t.xml_eq(out, doc.documentElement, "round-tripped polygon_labelhalo.sld");
-
}
@@ -867,5 +927,46 @@
-->
+
+