Add skeleton for SLD parser

This commit is contained in:
Bart van den Eijnden
2013-09-24 11:33:53 +02:00
committed by Bart van den Eijnden
parent 20d5a45b7d
commit 76454516f5
9 changed files with 883 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>countries</sld:Name>
<sld:UserStyle>
<sld:Name>countries</sld:Name>
<sld:Title>A sample style for countries</sld:Title>
<sld:IsDefault>1</sld:IsDefault>
<sld:Abstract>A sample style for countries</sld:Abstract>
<sld:FeatureTypeStyle>
<sld:Name>name</sld:Name>
<sld:Rule>
<sld:Name>Sample</sld:Name>
<sld:Title>Sample</sld:Title>
<sld:PolygonSymbolizer>
<sld:Fill>
<sld:CssParameter name="fill">#ff0000</sld:CssParameter>
<sld:CssParameter name="fill-opacity">0.6</sld:CssParameter>
</sld:Fill>
<sld:Stroke>
<sld:CssParameter name="stroke">#00FF00</sld:CssParameter>
<sld:CssParameter name="stroke-opacity">0.5</sld:CssParameter>
<sld:CssParameter name="stroke-width">4</sld:CssParameter>
</sld:Stroke>
</sld:PolygonSymbolizer>
</sld:Rule>
<sld:Rule>
<sld:TextSymbolizer>
<sld:Label>
<ogc:PropertyName>name</ogc:PropertyName>
</sld:Label>
<sld:Font>
<sld:CssParameter name="font-family">Arial</sld:CssParameter>
<sld:CssParameter name="font-size">10</sld:CssParameter>
<sld:CssParameter name="font-style">Normal</sld:CssParameter>
</sld:Font>
</sld:TextSymbolizer>
</sld:Rule>
</sld:FeatureTypeStyle>
</sld:UserStyle>
</sld:NamedLayer>
</sld:StyledLayerDescriptor>

View File

@@ -0,0 +1,61 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<meta name="viewport" content="initial-scale=1.0, user-scalable=no, width=device-width">
<link rel="stylesheet" href="../css/ol.css" type="text/css">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap.min.css" type="text/css">
<link rel="stylesheet" href="../resources/layout.css" type="text/css">
<link rel="stylesheet" href="../resources/bootstrap/css/bootstrap-responsive.min.css" type="text/css">
<title>Vector layer with styling from SLD example</title>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="brand" href="./">OpenLayers 3 Examples</a>
<ul class="nav pull-right">
<li><iframe class="github-watch-button" src="http://ghbtns.com/github-btn.html?user=openlayers&repo=ol3&type=watch&count=true"
allowtransparency="true" frameborder="0" scrolling="0" height="20" width="90"></iframe></li>
<li><a href="https://twitter.com/share" class="twitter-share-button" data-count="none" data-hashtags="openlayers">&nbsp;</a></li>
<li><div class="g-plusone-wrapper"><div class="g-plusone" data-size="medium" data-annotation="none"></div></div></li>
</ul>
</div>
</div>
</div>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div id="map" class="map"></div>
</div>
</div>
<div class="row-fluid">
<div class="span4">
<h4 id="title">Vector layer example</h4>
<p id="shortdesc">Example of a countries vector layer with country information on hover and country labels at higher zoom levels.</p>
<div id="docs">
<p>See the <a href="vector-layer-sld.js" target="_blank">vector-layer-sld.js source</a> to see how this is done.</p>
</div>
<div id="tags">vector, geojson, style, SLD, Styled Layer Descriptor</div>
</div>
<div class="span4 offset4">
<div id="info" class="alert alert-success">
&nbsp;
</div>
</div>
</div>
</div>
<script src="loader.js?id=vector-layer-sld" type="text/javascript"></script>
<script src="../resources/social-links.js" type="text/javascript"></script>
</body>
</html>

View File

@@ -0,0 +1,45 @@
goog.require('ol.Map');
goog.require('ol.RendererHint');
goog.require('ol.View2D');
goog.require('ol.layer.Tile');
goog.require('ol.layer.Vector');
goog.require('ol.parser.GeoJSON');
goog.require('ol.parser.ogc.SLD');
goog.require('ol.source.MapQuestOpenAerial');
goog.require('ol.source.Vector');
var raster = new ol.layer.Tile({
source: new ol.source.MapQuestOpenAerial()
});
var xhr = new XMLHttpRequest();
xhr.open('GET', 'data/countries.sld', true);
/**
* onload handler for the XHR request.
*/
xhr.onload = function() {
if (xhr.status == 200) {
var sld = new ol.parser.ogc.SLD().read(xhr.responseText);
var style = sld.namedLayers['countries'].userStyles[0];
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
parser: new ol.parser.GeoJSON(),
url: 'data/countries.geojson'
}),
style: style
});
new ol.Map({
layers: [raster, vector],
renderer: ol.RendererHint.CANVAS,
target: 'map',
view: new ol.View2D({
center: [0, 0],
zoom: 1
})
});
}
};
xhr.send();

View File

@@ -0,0 +1,38 @@
goog.provide('ol.parser.ogc.SLD');
goog.require('ol.parser.ogc.SLD_v1_0_0');
goog.require('ol.parser.ogc.SLD_v1_0_0_GeoServer');
goog.require('ol.parser.ogc.Versioned');
/**
* @define {boolean} Whether to enable SLD version 1.0.0.
*/
ol.ENABLE_SLD_1_0_0 = true;
/**
* @define {boolean} Whether to enable SLD version 1.0.0.
* GeoServer profile.
*/
ol.ENABLE_SLD_1_0_0_GEOSERVER = true;
/**
* @constructor
* @param {Object=} opt_options Options which will be set on this object.
* @extends {ol.parser.ogc.Versioned}
*/
ol.parser.ogc.SLD = function(opt_options) {
opt_options = opt_options || {};
opt_options['defaultVersion'] = '1.0.0';
this.parsers = {};
if (ol.ENABLE_SLD_1_0_0) {
this.parsers['v1_0_0'] = ol.parser.ogc.SLD_v1_0_0;
}
if (ol.ENABLE_SLD_1_0_0_GEOSERVER) {
this.parsers['v1_0_0_GEOSERVER'] = ol.parser.ogc.SLD_v1_0_0_GeoServer;
}
goog.base(this, opt_options);
};
goog.inherits(ol.parser.ogc.SLD, ol.parser.ogc.Versioned);

View File

@@ -0,0 +1,429 @@
goog.provide('ol.parser.ogc.SLD_v1');
goog.require('goog.dom.xml');
goog.require('goog.object');
goog.require('ol.parser.XML');
goog.require('ol.parser.ogc.Filter_v1_0_0');
goog.require('ol.style.Fill');
goog.require('ol.style.Rule');
goog.require('ol.style.Shape');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
goog.require('ol.style.Text');
/**
* Read Styled Layer Descriptor (SLD).
*
* @constructor
* @extends {ol.parser.XML}
*/
ol.parser.ogc.SLD_v1 = function() {
this.defaultNamespaceURI = 'http://www.opengis.net/sld';
this.readers = {
'http://www.opengis.net/sld': {
'StyledLayerDescriptor': function(node, sld) {
sld.version = node.getAttribute('version');
this.readChildNodes(node, sld);
},
'Name': function(node, obj) {
obj.name = this.getChildValue(node);
},
'Title': function(node, obj) {
obj.title = this.getChildValue(node);
},
'Abstract': function(node, obj) {
obj.description = this.getChildValue(node);
},
'NamedLayer': function(node, sld) {
var layer = {
userStyles: [],
namedStyles: []
};
this.readChildNodes(node, layer);
sld.namedLayers[layer.name] = layer;
},
'NamedStyle': function(node, layer) {
layer.namedStyles.push(
this.getChildValue(node.firstChild)
);
},
'UserStyle': function(node, layer) {
var obj = {rules: []};
this.featureTypeCounter = -1;
this.readChildNodes(node, obj);
layer.userStyles.push(new ol.style.Style(obj));
},
'IsDefault': function(node, style) {
if (this.getChildValue(node) === '1') {
style.isDefault = true;
}
},
'FeatureTypeStyle': function(node, style) {
++this.featureTypeCounter;
var obj = {
rules: style.rules
};
this.readChildNodes(node, obj);
},
'Rule': function(node, obj) {
var config = {symbolizers: []};
this.readChildNodes(node, config);
var rule = new ol.style.Rule(config);
obj.rules.push(rule);
},
'ElseFilter': function(node, rule) {
rule.elseFilter = true;
},
'MinScaleDenominator': function(node, rule) {
rule.minScaleDenominator = parseFloat(this.getChildValue(node));
},
'MaxScaleDenominator': function(node, rule) {
rule.maxScaleDenominator = parseFloat(this.getChildValue(node));
},
'TextSymbolizer': function(node, rule) {
var config = {};
this.readChildNodes(node, config);
config.zIndex = this.featureTypeCounter;
rule.symbolizers.push(
new ol.style.Text(/** @type {ol.style.TextOptions} */(config))
);
},
'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;
goog.object.extend(symbolizer, config);
},
'AnchorPoint': function(node, symbolizer) {
this.readChildNodes(node, symbolizer);
},
'AnchorPointX': function(node, symbolizer) {
var ogcreaders = this.readers['http://www.opengis.net/ogc'];
var labelAnchorPointX = ogcreaders._expression.call(this, node);
// always string, could be empty string
if (labelAnchorPointX) {
symbolizer.labelAnchorPointX = labelAnchorPointX;
}
},
'AnchorPointY': function(node, symbolizer) {
var ogcreaders = this.readers['http://www.opengis.net/ogc'];
var labelAnchorPointY = ogcreaders._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 ogcreaders = this.readers['http://www.opengis.net/ogc'];
var labelXOffset = ogcreaders._expression.call(this, node);
// always string, could be empty string
if (labelXOffset) {
symbolizer.labelXOffset = labelXOffset;
}
},
'DisplacementY': function(node, symbolizer) {
var ogcreaders = this.readers['http://www.opengis.net/ogc'];
var labelYOffset = ogcreaders._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 ogcreaders = this.readers['http://www.opengis.net/ogc'];
var labelPerpendicularOffset = ogcreaders._expression.call(this, node);
// always string, could be empty string
if (labelPerpendicularOffset) {
symbolizer.labelPerpendicularOffset = labelPerpendicularOffset;
}
},
'Label': function(node, symbolizer) {
var ogcreaders = this.readers['http://www.opengis.net/ogc'];
var value = ogcreaders._expression.call(this, node);
if (value) {
symbolizer.text = value;
}
},
'Font': function(node, symbolizer) {
this.readChildNodes(node, symbolizer);
},
'Halo': function(node, symbolizer) {
// halo has a fill, so send fresh object
var obj = {};
this.readChildNodes(node, obj);
symbolizer.haloRadius = obj.haloRadius;
symbolizer.haloColor = obj['fillColor'];
symbolizer.haloOpacity = obj['fillOpacity'];
},
'Radius': function(node, symbolizer) {
var ogcreaders = this.readers['http://www.opengis.net/ogc'];
var radius = ogcreaders._expression.call(this, node);
if (goog.isDef(radius)) {
}
},
'RasterSymbolizer': function(node, rule) {
var config = {};
this.readChildNodes(node, config);
config.zIndex = this.featureTypeCounter;
/* TODO
rule.symbolizers.push(
new OpenLayers.Symbolizer.Raster(config)
);
*/
},
'Geometry': function(node, obj) {
obj.geometry = {};
this.readChildNodes(node, obj.geometry);
},
'ColorMap': function(node, symbolizer) {
symbolizer.colorMap = [];
this.readChildNodes(node, symbolizer.colorMap);
},
'ColorMapEntry': function(node, colorMap) {
var q = node.getAttribute('quantity');
var o = node.getAttribute('opacity');
colorMap.push({
color: node.getAttribute('color'),
quantity: q !== null ? parseFloat(q) : undefined,
label: node.getAttribute('label') || undefined,
opacity: o !== null ? parseFloat(o) : undefined
});
},
'LineSymbolizer': function(node, rule) {
var config = {};
this.readChildNodes(node, config);
config.zIndex = this.featureTypeCounter;
rule.symbolizers.push(
new ol.style.Stroke(config)
);
},
'PolygonSymbolizer': function(node, rule) {
var config = {
fill: false,
stroke: false
};
this.readChildNodes(node, config);
config.zIndex = this.featureTypeCounter;
if (config.fill === true) {
var fill = {
color: config['fillColor'],
opacity: config['fillOpacity']
};
rule.symbolizers.push(
new ol.style.Fill(fill)
);
}
if (config.stroke === true) {
var stroke = {
color: config['strokeColor'],
opacity: config['strokeOpacity'],
width: config['strokeWidth']
};
rule.symbolizers.push(
new ol.style.Stroke(stroke)
);
}
},
'PointSymbolizer': function(node, rule) {
var config = {
fill: null,
stroke: null,
graphic: null
};
this.readChildNodes(node, config);
config.zIndex = this.featureTypeCounter;
// TODO shape or icon?
rule.symbolizers.push(
new ol.style.Shape(config)
);
},
'Stroke': function(node, symbolizer) {
symbolizer.stroke = true;
this.readChildNodes(node, symbolizer);
},
'Fill': function(node, symbolizer) {
symbolizer.fill = true;
this.readChildNodes(node, symbolizer);
},
'CssParameter': function(node, symbolizer) {
var cssProperty = node.getAttribute('name');
var symProperty = ol.parser.ogc.SLD_v1.cssMap_[cssProperty];
// for labels, fill should map to fontColor and fill-opacity
// to fontOpacity
if (symbolizer.label) {
if (cssProperty === 'fill') {
symProperty = 'fontColor';
} else if (cssProperty === 'fill-opacity') {
symProperty = 'fontOpacity';
}
}
if (symProperty) {
// Limited support for parsing of OGC expressions
var ogcreaders = this.readers['http://www.opengis.net/ogc'];
var value = ogcreaders._expression.call(this, node);
// always string, could be an empty string
if (value) {
symbolizer[symProperty] = value;
}
}
},
'Graphic': function(node, symbolizer) {
symbolizer.graphic = true;
var graphic = {};
// painter's order not respected here, clobber previous with next
this.readChildNodes(node, graphic);
// directly properties with names that match symbolizer properties
var properties = [
'stroke', 'strokeColor', 'strokeWidth', 'strokeOpacity',
'strokeLinecap', 'fill', 'fillColor', 'fillOpacity',
'graphicName', 'rotation', 'graphicFormat'
];
var prop, value;
for (var i = 0, ii = properties.length; i < ii; ++i) {
prop = properties[i];
value = graphic[prop];
if (goog.isDef(value)) {
symbolizer[prop] = value;
}
}
// set other generic properties with specific graphic property names
if (goog.isDef(graphic.opacity)) {
symbolizer.graphicOpacity = graphic.opacity;
}
if (goog.isDef(graphic.size)) {
var pointRadius = graphic.size / 2;
if (isNaN(pointRadius)) {
// likely a property name
symbolizer.graphicWidth = graphic.size;
} else {
symbolizer.pointRadius = graphic.size / 2;
}
}
if (goog.isDef(graphic.href)) {
symbolizer.externalGraphic = graphic.href;
}
if (goog.isDef(graphic.rotation)) {
symbolizer.rotation = graphic.rotation;
}
},
'ExternalGraphic': function(node, graphic) {
this.readChildNodes(node, graphic);
},
'Mark': function(node, graphic) {
this.readChildNodes(node, graphic);
},
'WellKnownName': function(node, graphic) {
graphic.graphicName = this.getChildValue(node);
},
'Opacity': function(node, obj) {
var ogcreaders = this.readers['http://www.opengis.net/ogc'];
var opacity = ogcreaders._expression.call(this, node);
// always string, could be empty string
if (opacity) {
obj.opacity = opacity;
}
},
'Size': function(node, obj) {
var ogcreaders = this.readers['http://www.opengis.net/ogc'];
var size = ogcreaders._expression.call(this, node);
// always string, could be empty string
if (size) {
obj.size = size;
}
},
'Rotation': function(node, obj) {
var ogcreaders = this.readers['http://www.opengis.net/ogc'];
var rotation = ogcreaders._expression.call(this, node);
// always string, could be empty string
if (rotation) {
obj.rotation = rotation;
}
},
'OnlineResource': function(node, obj) {
obj.href = this.getAttributeNS(
node, 'http://www.w3.org/1999/xlink', 'href'
);
},
'Format': function(node, graphic) {
graphic.graphicFormat = this.getChildValue(node);
}
}
};
this.filter_ = new ol.parser.ogc.Filter_v1_0_0();
for (var uri in this.filter_.readers) {
for (var key in this.filter_.readers[uri]) {
if (!goog.isDef(this.readers[uri])) {
this.readers[uri] = {};
}
this.readers[uri][key] = goog.bind(this.filter_.readers[uri][key],
this.filter_);
}
}
goog.base(this);
};
goog.inherits(ol.parser.ogc.SLD_v1, ol.parser.XML);
/**
* @private
*/
ol.parser.ogc.SLD_v1.cssMap_ = {
'stroke': 'strokeColor',
'stroke-opacity': 'strokeOpacity',
'stroke-width': 'strokeWidth',
'stroke-linecap': 'strokeLinecap',
'stroke-dasharray': 'strokeDashstyle',
'fill': 'fillColor',
'fill-opacity': 'fillOpacity',
'font-family': 'fontFamily',
'font-size': 'fontSize',
'font-weight': 'fontWeight',
'font-style': 'fontStyle'
};
/**
* @param {string|Document|Element} data Data to read.
* @return {Object} An object representing the document.
*/
ol.parser.ogc.SLD_v1.prototype.read = function(data) {
if (goog.isString(data)) {
data = goog.dom.xml.loadXml(data);
}
if (data && data.nodeType == 9) {
data = data.documentElement;
}
var obj = {namedLayers: {}};
this.readNode(data, obj);
return obj;
};

View File

@@ -0,0 +1,18 @@
goog.provide('ol.parser.ogc.SLD_v1_0_0');
goog.require('ol.parser.ogc.SLD_v1');
/**
* @constructor
* @extends {ol.parser.ogc.SLD_v1}
*/
ol.parser.ogc.SLD_v1_0_0 = function() {
goog.base(this);
this.version = '1.0.0';
this.schemaLocation = 'http://www.opengis.net/sld ' +
'http://schemas.opengis.net/sld/1.0.0/StyledLayerDescriptor.xsd';
};
goog.inherits(ol.parser.ogc.SLD_v1_0_0,
ol.parser.ogc.SLD_v1);

View File

@@ -0,0 +1,43 @@
goog.provide('ol.parser.ogc.SLD_v1_0_0_GeoServer');
goog.require('goog.functions');
goog.require('goog.object');
goog.require('ol.parser.ogc.SLD_v1_0_0');
/**
* @constructor
* @extends {ol.parser.ogc.SLD_v1_0_0}
*/
ol.parser.ogc.SLD_v1_0_0_GeoServer = function() {
goog.base(this);
this.profile = 'GeoServer';
goog.object.extend(this.readers['http://www.opengis.net/sld'], {
'Priority': function(node, obj) {
var ogcreaders = this.readers['http://www.opengis.net/ogc'];
var value = ogcreaders._expression.call(this, node);
if (value) {
obj.priority = value;
}
},
'VendorOption': function(node, obj) {
if (!goog.isDef(obj.vendorOptions)) {
obj.vendorOptions = {};
}
obj.vendorOptions[node.getAttribute('name')] =
this.getChildValue(node);
},
'TextSymbolizer': goog.functions.sequence(
this.readers['http://www.opengis.net/sld']['TextSymbolizer'],
function(node, rule) {
var symbolizer = rule.symbolizers[rule.symbolizers.length - 1];
if (!goog.isDef(symbolizer.graphic)) {
symbolizer.graphic = false;
}
}
)
});
};
goog.inherits(ol.parser.ogc.SLD_v1_0_0_GeoServer,
ol.parser.ogc.SLD_v1_0_0);

View File

@@ -0,0 +1,78 @@
goog.provide('ol.test.parser.ogc.SLD_v1_0_0');
describe('ol.parser.ogc.SLD_v1_0_0', function() {
var parser = new ol.parser.ogc.SLD();
describe('reading and writing', function() {
it('Handles reading', function(done) {
var url = 'spec/ol/parser/ogc/xml/sld_v1_0_0.xml';
afterLoadXml(url, function(xml) {
var obj = parser.read(xml);
expect(obj.version).to.equal('1.0.0');
var style = obj.namedLayers['AAA161'].userStyles[0];
expect(style).to.be.a(ol.style.Style);
expect(style.rules_.length).to.equal(2);
var first = style.rules_[0];
expect(first).to.be.a(ol.style.Rule);
expect(first.filter_).to.be.a(ol.expr.Comparison);
expect(first.filter_.getLeft()).to.be.a(ol.expr.Identifier);
expect(first.filter_.getLeft().getName()).to.equal('CTE');
expect(first.filter_.getOperator()).to.equal(ol.expr.ComparisonOp.EQ);
expect(first.filter_.getRight()).to.be.a(ol.expr.Literal);
expect(first.filter_.getRight().getValue()).to.equal('V0305');
expect(first.getSymbolizers().length).to.equal(3);
expect(first.getSymbolizers()[0]).to.be.a(ol.style.Fill);
expect(first.getSymbolizers()[0].getColor().getValue()).to.equal(
'#ffffff');
expect(first.getSymbolizers()[0].getOpacity().getValue()).to.equal(0.4);
expect(first.getSymbolizers()[1]).to.be.a(ol.style.Stroke);
expect(first.getSymbolizers()[1].getColor().getValue()).to.equal(
'#000000');
expect(first.getSymbolizers()[2]).to.be.a(ol.style.Text);
expect(first.getSymbolizers()[2].getText()).to.be.a(ol.expr.Call);
expect(first.getSymbolizers()[2].getText().getArgs().length).to.equal(
3);
expect(first.getSymbolizers()[2].getText().getArgs()[0]).to.be.a(
ol.expr.Literal);
expect(first.getSymbolizers()[2].getText().getArgs()[0].getValue()).
to.equal('A');
expect(first.getSymbolizers()[2].getText().getArgs()[1]).to.be.a(
ol.expr.Identifier);
expect(first.getSymbolizers()[2].getText().getArgs()[1].getName()).
to.equal('FOO');
expect(first.getSymbolizers()[2].getText().getArgs()[2]).to.be.a(
ol.expr.Literal);
expect(first.getSymbolizers()[2].getText().getArgs()[2].getValue()).
to.equal('label');
expect(first.getSymbolizers()[2].getColor().getValue()).to.equal(
ol.style.TextDefaults.color);
expect(first.getSymbolizers()[2].getFontFamily().getValue()).to.equal(
'Arial');
// TODO add tests for haloRadius and haloColor
var second = style.rules_[1];
expect(second.filter_).to.be.a(ol.expr.Comparison);
expect(second.getSymbolizers().length).to.equal(2);
expect(second.getSymbolizers()[0]).to.be.a(ol.style.Fill);
expect(second.getSymbolizers()[1]).to.be.a(ol.style.Stroke);
done();
});
});
});
});
goog.require('goog.net.XhrIo');
goog.require('ol.parser.ogc.SLD_v1_0_0');
goog.require('ol.parser.ogc.SLD');
goog.require('ol.expr.Call');
goog.require('ol.expr.Comparison');
goog.require('ol.expr.ComparisonOp');
goog.require('ol.expr.Identifier');
goog.require('ol.expr.Literal');
goog.require('ol.style.Fill');
goog.require('ol.style.Rule');
goog.require('ol.style.Stroke');
goog.require('ol.style.Style');
goog.require('ol.style.Text');

View File

@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="UTF-8"?>
<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>