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 @@ --> +
+