974 lines
40 KiB
HTML
974 lines
40 KiB
HTML
<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_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,
|
|
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>
|
|
</body>
|
|
</html>
|