summaryrefslogtreecommitdiff
path: root/misc/openlayers/tests/Format/SLD/v1_0_0.html
diff options
context:
space:
mode:
Diffstat (limited to 'misc/openlayers/tests/Format/SLD/v1_0_0.html')
-rw-r--r--misc/openlayers/tests/Format/SLD/v1_0_0.html1028
1 files changed, 1028 insertions, 0 deletions
diff --git a/misc/openlayers/tests/Format/SLD/v1_0_0.html b/misc/openlayers/tests/Format/SLD/v1_0_0.html
new file mode 100644
index 0000000..fbc18a6
--- /dev/null
+++ b/misc/openlayers/tests/Format/SLD/v1_0_0.html
@@ -0,0 +1,1028 @@
+<html>
+<head>
+ <script src="../../OLLoader.js"></script>
+ <script type="text/javascript">
+
+ var xml = new OpenLayers.Format.XML();
+ function readXML(id) {
+ return xml.read(document.getElementById(id).firstChild.nodeValue);
+ }
+
+ var sld =
+ '<StyledLayerDescriptor version="1.0.0" ' +
+ 'xmlns="http://www.opengis.net/sld" ' +
+ 'xmlns:gml="http://www.opengis.net/gml" ' +
+ 'xmlns:ogc="http://www.opengis.net/ogc" ' +
+ 'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
+ 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
+ 'xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd">' +
+ '<NamedLayer>' +
+ '<Name>AAA161</Name>' +
+ '<UserStyle>' +
+ '<FeatureTypeStyle>' +
+ '<Rule>' +
+ '<Name>stortsteen</Name>' +
+ '<ogc:Filter>' +
+ '<ogc:PropertyIsEqualTo>' +
+ '<ogc:PropertyName>CTE</ogc:PropertyName>' +
+ '<ogc:Literal>V0305</ogc:Literal>' +
+ '</ogc:PropertyIsEqualTo>' +
+ '</ogc:Filter>' +
+ '<MaxScaleDenominator>50000</MaxScaleDenominator>' +
+ '<PolygonSymbolizer>' +
+ '<Fill>' +
+ '<CssParameter name="fill">#ffffff</CssParameter>' +
+ '</Fill>' +
+ '<Stroke>' +
+ '<CssParameter name="stroke">#000000</CssParameter>' +
+ '</Stroke>' +
+ '</PolygonSymbolizer>' +
+ '<TextSymbolizer>' +
+ '<Label>' +
+ 'A <ogc:PropertyName>FOO</ogc:PropertyName> label' +
+ '</Label>' +
+ '<Font>' +
+ '<CssParameter name="font-family">Arial</CssParameter>' +
+ '<CssParameter name="font-size">14</CssParameter>' +
+ '<CssParameter name="font-weight">bold</CssParameter>' +
+ '<CssParameter name="font-style">normal</CssParameter>' +
+ '</Font>' +
+ '<LabelPlacement>' +
+ '<PointPlacement>' +
+ '<AnchorPoint>' +
+ '<AnchorPointX>0.5</AnchorPointX>' +
+ '<AnchorPointY>0.5</AnchorPointY>' +
+ '</AnchorPoint>' +
+ '<Displacement>' +
+ '<DisplacementX>5</DisplacementX>' +
+ '<DisplacementY>5</DisplacementY>' +
+ '</Displacement>' +
+ '<Rotation>45</Rotation>' +
+ '</PointPlacement>' +
+ '</LabelPlacement>' +
+ '<Halo>' +
+ '<Radius>3</Radius>' +
+ '<Fill>' +
+ '<CssParameter name="fill">#ffffff</CssParameter>' +
+ '</Fill>' +
+ '</Halo>' +
+ '<Fill>' +
+ '<CssParameter name="fill">#000000</CssParameter>' +
+ '</Fill>' +
+ '</TextSymbolizer>' +
+ '</Rule>' +
+ '<Rule>' +
+ '<Name>betonbekleding</Name>' +
+ '<ogc:Filter>' +
+ '<ogc:PropertyIsLessThan>' +
+ '<ogc:PropertyName>CTE</ogc:PropertyName>' +
+ '<ogc:Literal>1000</ogc:Literal>' +
+ '</ogc:PropertyIsLessThan>' +
+ '</ogc:Filter>' +
+ '<MaxScaleDenominator>50000</MaxScaleDenominator>' +
+ '<PolygonSymbolizer>' +
+ '<Fill>' +
+ '<CssParameter name="fill">#ffff00</CssParameter>' +
+ '</Fill>' +
+ '<Stroke>' +
+ '<CssParameter name="stroke">#0000ff</CssParameter>' +
+ '</Stroke>' +
+ '</PolygonSymbolizer>' +
+ '</Rule>' +
+ '</FeatureTypeStyle>' +
+ '</UserStyle>' +
+ '</NamedLayer>' +
+ '<NamedLayer>' +
+ '<Name>Second Layer</Name>' +
+ '<UserStyle>' +
+ '<FeatureTypeStyle>' +
+ '<Rule>' +
+ '<Name>first rule second layer</Name>' +
+ '<ogc:Filter>' +
+ '<ogc:Or>' +
+ '<ogc:PropertyIsBetween>' +
+ '<ogc:PropertyName>number</ogc:PropertyName>' +
+ '<ogc:LowerBoundary>' +
+ '<ogc:Literal>1064866676</ogc:Literal>' +
+ '</ogc:LowerBoundary>' +
+ '<ogc:UpperBoundary>' +
+ '<ogc:Literal>1065512599</ogc:Literal>' +
+ '</ogc:UpperBoundary>' +
+ '</ogc:PropertyIsBetween>' +
+ '<ogc:PropertyIsLike wildCard="*" singleChar="." escape="!">' +
+ '<ogc:PropertyName>cat</ogc:PropertyName>' +
+ '<ogc:Literal>*dog.food!*good</ogc:Literal>' +
+ '</ogc:PropertyIsLike>' +
+ '<ogc:Not>' +
+ '<ogc:PropertyIsLessThanOrEqualTo>' +
+ '<ogc:PropertyName>FOO</ogc:PropertyName>' +
+ '<ogc:Literal>5000</ogc:Literal>' +
+ '</ogc:PropertyIsLessThanOrEqualTo>' +
+ '</ogc:Not>' +
+ '</ogc:Or>' +
+ '</ogc:Filter>' +
+ '<MaxScaleDenominator>10000</MaxScaleDenominator>' +
+ '<PointSymbolizer>' +
+ '<Graphic>' +
+ '<Mark>' +
+ '<WellKnownName>star</WellKnownName>' +
+ '<Fill>' +
+ '<CssParameter name="fill">lime</CssParameter>' +
+ '</Fill>' +
+ '<Stroke>' +
+ '<CssParameter name="stroke">olive</CssParameter>' +
+ '<CssParameter name="stroke-width">2</CssParameter>' +
+ '</Stroke>' +
+ '</Mark>' +
+ '<Size><ogc:PropertyName>SIZE</ogc:PropertyName></Size>' +
+ '</Graphic>' +
+ '</PointSymbolizer>' +
+ '</Rule>' +
+ '</FeatureTypeStyle>' +
+ '</UserStyle>' +
+ '</NamedLayer>' +
+ '</StyledLayerDescriptor>';
+
+ function test_read(t) {
+ t.plan(23);
+
+ var xml = new OpenLayers.Format.XML();
+ var sldxml = xml.read(sld);
+
+ // test that format options are considered in read
+ var parser = new OpenLayers.Format.SLD({
+ version: "1.0.0",
+ namedLayersAsArray: true
+ });
+ var obj = parser.read(sldxml);
+ t.ok(obj.namedLayers instanceof Array, "namedLayersAsArray option for read works");
+
+ parser = new OpenLayers.Format.SLD.v1_0_0();
+ var obj = parser.read(sldxml, {namedLayersAsArray: true});
+ t.ok(obj.namedLayers instanceof Array, "namedLayersAsArray option for read works");
+ var arrayLen = obj.namedLayers.length;
+
+ var obj = parser.read(sldxml);
+ t.eq(typeof obj.namedLayers, "object", "read returns a namedLayers object by default");
+ // test the named layer count
+ var count = 0;
+ for(var key in obj.namedLayers) {
+ ++count;
+ }
+ t.eq(count, arrayLen, "number of named layers in array equals number of named layers in object");
+
+ var layer, style, rule;
+
+ // check the first named layer
+ layer = obj.namedLayers["AAA161"];
+ t.ok(layer, "first named layer exists");
+ t.ok(layer.userStyles instanceof Array, "(AAA161) layer has array of user styles");
+ t.eq(layer.userStyles.length, 1, "(AAA161) first layer has a single user style");
+ t.eq(layer.userStyles[0].rules.length, 2, "(AAA161) first style has two rules");
+ var rule = layer.userStyles[0].rules[0];
+ t.ok(rule.filter, "(AAA161) first rule has a filter");
+ var symbolizer = rule.symbolizer;
+ t.ok(symbolizer, "(AAA161) first rule has a symbolizer");
+ var poly = symbolizer["Polygon"];
+ 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, "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.fontColor, "#000000", "(AAA161) first rule has proper text fill");
+ t.eq(text.haloRadius, "3", "(AAA161) first rule has proper halo radius");
+ t.eq(text.haloColor, "#ffffff", "(AAA161) first rule has proper halo color");
+
+
+ // check the first user style
+ style = layer.userStyles[0];
+ t.ok(style instanceof OpenLayers.Style, "(AAA161,0) user style is instance of OpenLayers.Style");
+ t.eq(style.rules.length, 2, "(AAA161,0) user style has 2 rules");
+
+ // check the second rule
+ rule = style.rules[1];
+ var feature = {
+ layer: {
+ map: {
+ getScale: function(){
+ return 40000;
+ }
+ }
+ },
+ attributes: {
+ CTE: "900"
+ }
+ };
+ 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.
+
+ }
+
+ function test_write(t) {
+ t.plan(3);
+
+ // 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);
+ var obj = parser.read(sldxml);
+
+ var node = parser.write(obj);
+ t.xml_eq(node, sld, "SLD correctly written");
+
+ obj = parser.read(sldxml, {namedLayersAsArray: true});
+ node = parser.write(obj);
+ t.xml_eq(node, sld, "SLD from namedLayers array correctly written");
+
+ // test that 0 fill opacity gets written
+ var symbolizer = {
+ fillColor: "red",
+ fillOpacity: 0
+ };
+ var root = parser.createElementNSPlus("PolygonSymbolizer");
+ var got = parser.writeNode("Fill", symbolizer, root);
+ var expect =
+ '<Fill xmlns="http://www.opengis.net/sld">' +
+ '<CssParameter name="fill">red</CssParameter>' +
+ '<CssParameter name="fill-opacity">0</CssParameter>' +
+ '</Fill>';
+ t.xml_eq(got, expect, "zero fill opacity written");
+ }
+
+ function test_writePointSymbolizer(t) {
+
+ t.plan(3);
+
+ var parser = new OpenLayers.Format.SLD.v1_0_0();
+ var symbolizer, node, exp;
+
+ // test symbolizer with fill color only
+ symbolizer = {
+ "fillColor": "blue"
+ };
+ node = parser.writeNode("sld:PointSymbolizer", symbolizer);
+ exp =
+ '<PointSymbolizer xmlns="http://www.opengis.net/sld">' +
+ '<Graphic>' +
+ '<Mark>' +
+ '<Fill>' +
+ '<CssParameter name="fill">blue</CssParameter>' +
+ '</Fill>' +
+ '<Stroke/>' +
+ '</Mark>' +
+ '</Graphic>' +
+ '</PointSymbolizer>';
+ t.xml_eq(node, exp, "fillColor only written");
+
+ // test symbolizer with stroke color only
+ symbolizer = {
+ "strokeColor": "blue"
+ };
+ node = parser.writeNode("sld:PointSymbolizer", symbolizer);
+ exp =
+ '<PointSymbolizer xmlns="http://www.opengis.net/sld">' +
+ '<Graphic>' +
+ '<Mark>' +
+ '<Fill/>' +
+ '<Stroke>' +
+ '<CssParameter name="stroke">blue</CssParameter>' +
+ '</Stroke>' +
+ '</Mark>' +
+ '</Graphic>' +
+ '</PointSymbolizer>';
+ t.xml_eq(node, exp, "strokeColor only written");
+
+ // test symbolizer with graphic name only
+ symbolizer = {
+ "graphicName": "star"
+ };
+ node = parser.writeNode("sld:PointSymbolizer", symbolizer);
+ exp =
+ '<PointSymbolizer xmlns="http://www.opengis.net/sld">' +
+ '<Graphic>' +
+ '<Mark>' +
+ '<WellKnownName>star</WellKnownName>' +
+ '<Fill/>' +
+ '<Stroke/>' +
+ '</Mark>' +
+ '</Graphic>' +
+ '</PointSymbolizer>';
+ t.xml_eq(node, exp, "graphicName only written");
+
+
+ }
+
+
+ function test_writeLineSymbolizer(t) {
+
+ t.plan(1);
+
+ var parser = new OpenLayers.Format.SLD.v1_0_0();
+ var symbolizer, node, exp;
+
+ // test symbolizer with fill color only
+ symbolizer = {
+ strokeDashstyle: "4 4",
+ strokeLinecap: "round",
+ strokeColor: "#0000ff",
+ strokeWidth: 2
+ };
+ node = parser.writeNode("sld:LineSymbolizer", symbolizer);
+ exp =
+ '<LineSymbolizer xmlns="http://www.opengis.net/sld">' +
+ '<Stroke>' +
+ '<CssParameter name="stroke">#0000ff</CssParameter>' +
+ '<CssParameter name="stroke-width">2</CssParameter>' +
+ '<CssParameter name="stroke-dasharray">4 4</CssParameter>' +
+ '<CssParameter name="stroke-linecap">round</CssParameter>' +
+ '</Stroke>' +
+ '</LineSymbolizer>';
+ t.xml_eq(node, exp, "line symbolizer correctly written");
+
+
+ }
+
+ function test_writeTextSymbolizer(t) {
+ t.plan(1);
+ var parser = new OpenLayers.Format.SLD.v1_0_0();
+ var symbolizer = {
+ "Text": {
+ "label": "This is the ${city} in ${state}.",
+ "fontFamily": "Arial",
+ "fontSize": 10,
+ "fontColor": "blue",
+ "fontWeight": "bold",
+ "fontStyle": "normal",
+ "haloRadius": 2,
+ "haloColor": "white"
+ }
+ };
+ var node = parser.writers["sld"]["TextSymbolizer"].apply(
+ parser, [symbolizer["Text"]]
+ );
+
+ var expected =
+ '<TextSymbolizer xmlns="http://www.opengis.net/sld">' +
+ '<Label>' +
+ 'This is the ' +
+ '<ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">city</ogc:PropertyName>' +
+ ' in ' +
+ '<ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">state</ogc:PropertyName>' +
+ '.' +
+ '</Label>' +
+ '<Font>' +
+ '<CssParameter name="font-family">Arial</CssParameter>' +
+ '<CssParameter name="font-size">10</CssParameter>' +
+ '<CssParameter name="font-weight">bold</CssParameter>' +
+ '<CssParameter name="font-style">normal</CssParameter>' +
+ '</Font>' +
+ '<Halo>' +
+ '<Radius>2</Radius>' +
+ '<Fill>' +
+ '<CssParameter name="fill">white</CssParameter>' +
+ '</Fill>' +
+ '</Halo>' +
+ '<Fill>' +
+ '<CssParameter name="fill">blue</CssParameter>' +
+ '</Fill>' +
+ '</TextSymbolizer>';
+
+ t.xml_eq(node, expected, "TextSymbolizer correctly written");
+
+ }
+
+ function test_writeSpatialFilter(t) {
+
+ t.plan(1);
+
+ var format = new OpenLayers.Format.SLD.v1_0_0();
+
+ var rule = new OpenLayers.Rule({
+ name: "test",
+ filter: new OpenLayers.Filter.Spatial({
+ type: OpenLayers.Filter.Spatial.BBOX,
+ value: new OpenLayers.Bounds(0, 0, 10, 10)
+ })
+ });
+
+ var sld = format.writeNode("sld:Rule", rule);
+
+ var expect =
+ '<Rule xmlns="http://www.opengis.net/sld">' +
+ '<Name>test</Name>' +
+ '<ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<ogc:BBOX>' +
+ '<gml:Box xmlns:gml="http://www.opengis.net/gml">' +
+ '<gml:coordinates decimal="." cs="," ts=" ">0,0 10,10</gml:coordinates>' +
+ '</gml:Box>' +
+ '</ogc:BBOX>' +
+ '</ogc:Filter>' +
+ '</Rule>';
+
+ t.xml_eq(sld, expect, "rule with spatial filter correctly written");
+
+ }
+
+ function test_RasterSymbolizer(t) {
+ t.plan(4);
+
+ var format = new OpenLayers.Format.SLD.v1_0_0();
+
+ var snippet =
+ '<sld:RasterSymbolizer xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc">' +
+ '<sld:Geometry>' +
+ '<ogc:PropertyName>geom</ogc:PropertyName>' +
+ '</sld:Geometry>' +
+ '<sld:Opacity>1</sld:Opacity>' +
+ '<sld:ColorMap>' +
+ '<sld:ColorMapEntry color="#000000" opacity="0.5" quantity="0" label="nodata"/>' +
+ '<sld:ColorMapEntry color="#00FFFF" quantity="1" label="values"/>' +
+ '<sld:ColorMapEntry color="#FF0000" quantity="1000" label="values"/>' +
+ '</sld:ColorMap>' +
+ '</sld:RasterSymbolizer>';
+ var expected = new OpenLayers.Format.XML().read(snippet).documentElement;
+
+ var symbolizer = {};
+ format.readNode(expected, {symbolizer: symbolizer});
+
+ t.eq(symbolizer.Raster.colorMap[0].quantity, 0, "quantity set correctly");
+ t.eq(symbolizer.Raster.colorMap[0].opacity, 0.5, "opacity set correctly");
+ t.eq(symbolizer.Raster.colorMap[1].opacity, undefined, "non-existent opacity results in undefined");
+
+ var got = format.writeNode("sld:RasterSymbolizer", symbolizer["Raster"]);
+
+ t.xml_eq(got, expected, "Successfully round tripped RasterSymbolizer");
+ }
+
+ function test_zIndex(t) {
+ t.plan(1);
+
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true
+ });
+
+ // three zIndex values -> three FeatureTypeStyle elements
+ var style = new OpenLayers.Style2({
+ rules: [
+ new OpenLayers.Rule({
+ filter: new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.EQUAL_TO,
+ property: "foo",
+ value: "bar"
+ }),
+ minScaleDenominator: 100000,
+ maxScaleDenominator: 200000,
+ symbolizers: [
+ new OpenLayers.Symbolizer.Line({
+ strokeColor: "green",
+ strokeWidth: 2,
+ zIndex: 2
+ }),
+ new OpenLayers.Symbolizer.Line({
+ strokeColor: "red",
+ strokeWidth: 3,
+ zIndex: -1
+ }),
+ new OpenLayers.Symbolizer.Line({
+ strokeColor: "blue",
+ strokeWidth: 1,
+ zIndex: 5
+ })
+ ]
+ }),
+ new OpenLayers.Rule({
+ filter: new OpenLayers.Filter.Comparison({
+ type: OpenLayers.Filter.Comparison.EQUAL_TO,
+ property: "foo",
+ value: "baz"
+ }),
+ symbolizers: [
+ new OpenLayers.Symbolizer.Line({
+ strokeColor: "#000000",
+ strokeWidth: 2,
+ zIndex: 2
+ })
+ ]
+ })
+ ]
+ });
+
+ var got = format.writeNode("sld:UserStyle", style);
+ var exp = readXML("zindex_test.sld").documentElement;
+ t.xml_eq(got, exp, "duplicated rules to write zIndex as FeatureTypeStyle elements");
+
+ }
+
+ function test_whitespace(t) {
+ t.plan(1);
+ var xml = readXML("propertyisbetweenwhitespace.sld");
+ var output = new OpenLayers.Format.SLD().read(xml);
+ var filter = output.namedLayers['geonode:US_Stat0'].userStyles[0].rules[0].filter;
+ t.eq(filter.lowerBoundary, 29.7, "whitespace ignored in values and value transformed to number");
+ }
+
+ function test_label_LinePlacement(t) {
+ t.plan(1);
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true
+ });
+ // labelPerpendicularOffset takes precedence over labelAlign
+ 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,
+ labelAlign: "rb"
+ })
+ ]
+ })
+ ]
+ });
+ 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);
+
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true,
+ namedLayersAsArray: true
+ });
+ var doc = readXML("line_linewithborder.sld");
+
+ var obj = format.read(doc);
+
+ t.eq(obj.namedLayers.length, 1, "got one named layer");
+ var namedLayer = obj.namedLayers[0];
+
+ t.eq(namedLayer.userStyles.length, 1, "got one user style");
+ var userStyle = namedLayer.userStyles[0];
+ t.ok(userStyle instanceof OpenLayers.Style2, "user style represented with OpenLayers.Style2");
+
+ // check rules and symbolizers
+ var rule, symbolizer;
+
+ t.eq(userStyle.rules.length, 2, "pulled two rules (from two FeatureTypeStyle elements)");
+ rule = userStyle.rules[0];
+ t.ok(rule instanceof OpenLayers.Rule, "first rule is an OpenLayers.Rule");
+
+ t.eq(rule.symbolizers && rule.symbolizers.length, 1, "first rule has one symbolizer");
+ symbolizer = rule.symbolizers[0];
+ t.ok(symbolizer instanceof OpenLayers.Symbolizer, "first symbolizer in first rule is an OpenLayers.Symbolizer");
+ t.ok(symbolizer instanceof OpenLayers.Symbolizer.Line, "first symbolizer in first rule is an OpenLayers.Symbolizer.Line");
+ t.eq(symbolizer.zIndex, 0, "symbolizer from first FeatureTypeStyle element has zIndex 0");
+
+ rule = userStyle.rules[1];
+ t.eq(rule.symbolizers && rule.symbolizers.length, 1, "second rule has one symbolizer");
+ symbolizer = rule.symbolizers[0];
+ t.ok(symbolizer instanceof OpenLayers.Symbolizer, "first symbolizer in second rule is an OpenLayers.Symbolizer");
+ t.ok(symbolizer instanceof OpenLayers.Symbolizer.Line, "first symbolizer in second rule is an OpenLayers.Symbolizer.Line");
+ t.eq(symbolizer.zIndex, 1, "symbolizer from second FeatureTypeStyle element has zIndex 1");
+
+ }
+
+ function test_roundtrip(t) {
+
+ t.plan(5);
+
+ var format = new OpenLayers.Format.SLD.v1_0_0({
+ multipleSymbolizers: true,
+ namedLayersAsArray: true
+ });
+ var doc, out;
+
+ // two FeatureTypeStyle elements and line symbolizers
+ doc = readXML("line_linewithborder.sld");
+ out = format.write(format.read(doc));
+ t.xml_eq(out, doc.documentElement, "round-tripped line_linewithborder.sld");
+
+ // three FeatureTypeStyle elements and line symbolizers
+ doc = readXML("line_attributebasedline.sld");
+ out = format.write(format.read(doc));
+ t.xml_eq(out, doc.documentElement, "round-tripped line_attributebasedline.sld");
+
+ // point symbolizer and text symbolizer
+ doc = readXML("point_pointwithdefaultlabel.sld");
+ out = format.write(format.read(doc));
+ t.xml_eq(out, doc.documentElement, "round-tripped point_pointwithdefaultlabel.sld");
+
+ // polygon symbolizer with fill only
+ doc = readXML("polygon_simplepolygon.sld");
+ out = format.write(format.read(doc));
+ t.xml_eq(out, doc.documentElement, "round-tripped polygon_simplepolygon.sld");
+
+ // polygon symbolizer and text symbolizer with halo
+ doc = readXML("polygon_labelhalo.sld");
+ out = format.write(format.read(doc));
+ t.xml_eq(out, doc.documentElement, "round-tripped polygon_labelhalo.sld");
+ }
+
+ </script>
+</head>
+<body>
+<div id="line_linewithborder.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Line with border</Name>
+ <UserStyle>
+ <Title>SLD Cook Book: Line w2th border</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">#333333</CssParameter>
+ <CssParameter name="stroke-width">5</CssParameter>
+ <CssParameter name="stroke-linecap">round</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">#6699FF</CssParameter>
+ <CssParameter name="stroke-width">3</CssParameter>
+ <CssParameter name="stroke-linecap">round</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="line_attributebasedline.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Attribute-based line</Name>
+ <UserStyle>
+ <Title>SLD Cook Book: Attribute-based line</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <Name>local-road</Name>
+ <ogc:Filter>
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>type</ogc:PropertyName>
+ <ogc:Literal>local-road</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">#009933</CssParameter>
+ <CssParameter name="stroke-width">2</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <Name>secondary</Name>
+ <ogc:Filter>
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>type</ogc:PropertyName>
+ <ogc:Literal>secondary</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">#0055CC</CssParameter>
+ <CssParameter name="stroke-width">3</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ <FeatureTypeStyle>
+ <Rule>
+ <Name>highway</Name>
+ <ogc:Filter>
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>type</ogc:PropertyName>
+ <ogc:Literal>highway</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <LineSymbolizer>
+ <Stroke>
+ <CssParameter name="stroke">#FF0000</CssParameter>
+ <CssParameter name="stroke-width">6</CssParameter>
+ </Stroke>
+ </LineSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="point_pointwithdefaultlabel.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Point with default label</Name>
+ <UserStyle>
+ <Title>GeoServer SLD Cook Book: Point with default label</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <PointSymbolizer>
+ <Graphic>
+ <Mark>
+ <WellKnownName>circle</WellKnownName>
+ <Fill>
+ <CssParameter name="fill">#FF0000</CssParameter>
+ </Fill>
+ </Mark>
+ <Size>6</Size>
+ </Graphic>
+ </PointSymbolizer>
+ <TextSymbolizer>
+ <Label>
+ <ogc:PropertyName>name</ogc:PropertyName>
+ </Label>
+ <Fill>
+ <CssParameter name="fill">#000000</CssParameter>
+ </Fill>
+ </TextSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="polygon_simplepolygon.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Simple polygon</Name>
+ <UserStyle>
+ <Title>SLD Cook Book: Simple polygon</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <PolygonSymbolizer>
+ <Fill>
+ <CssParameter name="fill">#000080</CssParameter>
+ </Fill>
+ </PolygonSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="polygon_labelhalo.sld"><!--
+<StyledLayerDescriptor version="1.0.0"
+ xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd"
+ xmlns="http://www.opengis.net/sld"
+ xmlns:ogc="http://www.opengis.net/ogc"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <NamedLayer>
+ <Name>Label halo</Name>
+ <UserStyle>
+ <Title>SLD Cook Book: Label halo</Title>
+ <FeatureTypeStyle>
+ <Rule>
+ <PolygonSymbolizer>
+ <Fill>
+ <CssParameter name="fill">#40FF40</CssParameter>
+ </Fill>
+ <Stroke>
+ <CssParameter name="stroke">#FFFFFF</CssParameter>
+ <CssParameter name="stroke-width">2</CssParameter>
+ </Stroke>
+ </PolygonSymbolizer>
+ <TextSymbolizer>
+ <Label>
+ <ogc:PropertyName>name</ogc:PropertyName>
+ </Label>
+ <Halo>
+ <Radius>3</Radius>
+ <Fill>
+ <CssParameter name="fill">#FFFFFF</CssParameter>
+ </Fill>
+ </Halo>
+ </TextSymbolizer>
+ </Rule>
+ </FeatureTypeStyle>
+ </UserStyle>
+ </NamedLayer>
+</StyledLayerDescriptor>
+--></div>
+<div id="zindex_test.sld"><!--
+<sld:UserStyle xmlns:sld="http://www.opengis.net/sld">
+ <sld:FeatureTypeStyle>
+ <sld:Rule>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>foo</ogc:PropertyName>
+ <ogc:Literal>bar</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <sld:MinScaleDenominator>100000</sld:MinScaleDenominator>
+ <sld:MaxScaleDenominator>200000</sld:MaxScaleDenominator>
+ <sld:LineSymbolizer>
+ <sld:Stroke>
+ <sld:CssParameter name="stroke">red</sld:CssParameter>
+ <sld:CssParameter name="stroke-width">3</sld:CssParameter>
+ </sld:Stroke>
+ </sld:LineSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+ <sld:FeatureTypeStyle>
+ <sld:Rule>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>foo</ogc:PropertyName>
+ <ogc:Literal>bar</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <sld:MinScaleDenominator>100000</sld:MinScaleDenominator>
+ <sld:MaxScaleDenominator>200000</sld:MaxScaleDenominator>
+ <sld:LineSymbolizer>
+ <sld:Stroke>
+ <sld:CssParameter name="stroke">green</sld:CssParameter>
+ <sld:CssParameter name="stroke-width">2</sld:CssParameter>
+ </sld:Stroke>
+ </sld:LineSymbolizer>
+ </sld:Rule>
+ <sld:Rule>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>foo</ogc:PropertyName>
+ <ogc:Literal>baz</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <sld:LineSymbolizer>
+ <sld:Stroke>
+ <sld:CssParameter name="stroke">#000000</sld:CssParameter>
+ <sld:CssParameter name="stroke-width">2</sld:CssParameter>
+ </sld:Stroke>
+ </sld:LineSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+ <sld:FeatureTypeStyle>
+ <sld:Rule>
+ <ogc:Filter xmlns:ogc="http://www.opengis.net/ogc">
+ <ogc:PropertyIsEqualTo>
+ <ogc:PropertyName>foo</ogc:PropertyName>
+ <ogc:Literal>bar</ogc:Literal>
+ </ogc:PropertyIsEqualTo>
+ </ogc:Filter>
+ <sld:MinScaleDenominator>100000</sld:MinScaleDenominator>
+ <sld:MaxScaleDenominator>200000</sld:MaxScaleDenominator>
+ <sld:LineSymbolizer>
+ <sld:Stroke>
+ <sld:CssParameter name="stroke">blue</sld:CssParameter>
+ <sld:CssParameter name="stroke-width">1</sld:CssParameter>
+ </sld:Stroke>
+ </sld:LineSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+</sld:UserStyle>
+--></div>
+<div id="label_lineplacement_test.sld"><!--
+<sld:UserStyle xmlns:sld="http://www.opengis.net/sld">
+ <sld:FeatureTypeStyle>
+ <sld:Rule>
+ <sld:LineSymbolizer>
+ <sld:Stroke>
+ <sld:CssParameter name="stroke">red</sld:CssParameter>
+ <sld:CssParameter name="stroke-width">3</sld:CssParameter>
+ </sld:Stroke>
+ </sld:LineSymbolizer>
+ <sld:TextSymbolizer>
+ <sld:Label><ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">FOO</ogc:PropertyName></sld:Label>
+ <sld:LabelPlacement>
+ <sld:LinePlacement>
+ <sld:PerpendicularOffset>10</sld:PerpendicularOffset>
+ </sld:LinePlacement>
+ </sld:LabelPlacement>
+ </sld:TextSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+</sld:UserStyle>
+--></div>
+<div id="label_pointplacement_test.sld"><!--
+<sld:UserStyle xmlns:sld="http://www.opengis.net/sld">
+ <sld:FeatureTypeStyle>
+ <sld:Rule>
+ <sld:TextSymbolizer>
+ <sld:Label><ogc:PropertyName xmlns:ogc="http://www.opengis.net/ogc">FOO</ogc:PropertyName></sld:Label>
+ <sld:LabelPlacement>
+ <sld:PointPlacement>
+ <sld:AnchorPoint>
+ <sld:AnchorPointX>1</sld:AnchorPointX>
+ <sld:AnchorPointY>0</sld:AnchorPointY>
+ </sld:AnchorPoint>
+ </sld:PointPlacement>
+ </sld:LabelPlacement>
+ </sld:TextSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+</sld:UserStyle>
+--></div>
+<div id="propertyisbetweenwhitespace.sld"><!--
+<sld:StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml" version="1.0.0">
+ <sld:NamedLayer>
+ <sld:Name>geonode:US_Stat0</sld:Name>
+ <sld:UserStyle>
+ <sld:Name>US_Stat0_5cbbe918</sld:Name>
+ <sld:Title>BMI&lt;25</sld:Title>
+ <sld:FeatureTypeStyle>
+ <sld:Name>name</sld:Name>
+ <sld:Rule>
+ <sld:Title>BMI&lt;25</sld:Title>
+ <ogc:Filter>
+ <ogc:PropertyIsBetween>
+ <ogc:PropertyName>Hlt_st_BMI</ogc:PropertyName>
+ <ogc:LowerBoundary>
+ <ogc:Literal>
+
+
+ 29.7
+
+
+ </ogc:Literal>
+ </ogc:LowerBoundary>
+ <ogc:UpperBoundary>
+ <ogc:Literal>
+
+
+ 36.2
+
+
+ </ogc:Literal>
+ </ogc:UpperBoundary>
+ </ogc:PropertyIsBetween>
+ </ogc:Filter>
+ <sld:PolygonSymbolizer>
+ <sld:Fill>
+ <sld:CssParameter name="fill">#C0F58C</sld:CssParameter>
+ </sld:Fill>
+ <sld:Stroke/>
+ </sld:PolygonSymbolizer>
+ </sld:Rule>
+ </sld:FeatureTypeStyle>
+ </sld:UserStyle>
+ </sld:NamedLayer>
+</sld:StyledLayerDescriptor>
+--></div>
+</body>
+</html>