Add skeleton for SLD parser
This commit is contained in:
committed by
Bart van den Eijnden
parent
20d5a45b7d
commit
76454516f5
42
examples/data/countries.sld
Normal file
42
examples/data/countries.sld
Normal 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>
|
||||||
61
examples/vector-layer-sld.html
Normal file
61
examples/vector-layer-sld.html
Normal 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"> </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">
|
||||||
|
|
||||||
|
</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>
|
||||||
45
examples/vector-layer-sld.js
Normal file
45
examples/vector-layer-sld.js
Normal 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();
|
||||||
38
src/ol/parser/ogc/sldparser.js
Normal file
38
src/ol/parser/ogc/sldparser.js
Normal 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);
|
||||||
429
src/ol/parser/ogc/sldparser_v1.js
Normal file
429
src/ol/parser/ogc/sldparser_v1.js
Normal 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;
|
||||||
|
};
|
||||||
18
src/ol/parser/ogc/sldparser_v1_0_0.js
Normal file
18
src/ol/parser/ogc/sldparser_v1_0_0.js
Normal 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);
|
||||||
43
src/ol/parser/ogc/sldparser_v1_0_0_GeoServer.js
Normal file
43
src/ol/parser/ogc/sldparser_v1_0_0_GeoServer.js
Normal 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);
|
||||||
78
test/spec/ol/parser/ogc/sld_v1_0_0.test.js
Normal file
78
test/spec/ol/parser/ogc/sld_v1_0_0.test.js
Normal 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');
|
||||||
129
test/spec/ol/parser/ogc/xml/sld_v1_0_0.xml
Normal file
129
test/spec/ol/parser/ogc/xml/sld_v1_0_0.xml
Normal 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>
|
||||||
Reference in New Issue
Block a user