Merge pull request #237 from bartvde/sld
Add a GeoServer profile of SLD version 1.0.0 (r=@ahocevar)
This commit is contained in:
@@ -287,6 +287,7 @@
|
|||||||
"OpenLayers/Format/SLD.js",
|
"OpenLayers/Format/SLD.js",
|
||||||
"OpenLayers/Format/SLD/v1.js",
|
"OpenLayers/Format/SLD/v1.js",
|
||||||
"OpenLayers/Format/SLD/v1_0_0.js",
|
"OpenLayers/Format/SLD/v1_0_0.js",
|
||||||
|
"OpenLayers/Format/SLD/v1_0_0_GeoServer.js",
|
||||||
"OpenLayers/Format/OWSCommon.js",
|
"OpenLayers/Format/OWSCommon.js",
|
||||||
"OpenLayers/Format/OWSCommon/v1.js",
|
"OpenLayers/Format/OWSCommon/v1.js",
|
||||||
"OpenLayers/Format/OWSCommon/v1_0_0.js",
|
"OpenLayers/Format/OWSCommon/v1_0_0.js",
|
||||||
|
|||||||
@@ -23,6 +23,15 @@
|
|||||||
*/
|
*/
|
||||||
OpenLayers.Format.SLD = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {
|
OpenLayers.Format.SLD = OpenLayers.Class(OpenLayers.Format.XML.VersionedOGC, {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* APIProperty: profile
|
||||||
|
* {String} If provided, use a custom profile.
|
||||||
|
*
|
||||||
|
* Currently supported profiles:
|
||||||
|
* - GeoServer - parses GeoServer vendor specific capabilities for SLD.
|
||||||
|
*/
|
||||||
|
profile: null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APIProperty: defaultVersion
|
* APIProperty: defaultVersion
|
||||||
* {String} Version number to assume if none found. Default is "1.0.0".
|
* {String} Version number to assume if none found. Default is "1.0.0".
|
||||||
|
|||||||
@@ -338,6 +338,15 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
|||||||
"CssParameter": function(node, symbolizer) {
|
"CssParameter": function(node, symbolizer) {
|
||||||
var cssProperty = node.getAttribute("name");
|
var cssProperty = node.getAttribute("name");
|
||||||
var symProperty = this.cssMap[cssProperty];
|
var symProperty = this.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) {
|
if(symProperty) {
|
||||||
// Limited support for parsing of OGC expressions
|
// Limited support for parsing of OGC expressions
|
||||||
var value = this.readers.ogc._expression.call(this, node);
|
var value = this.readers.ogc._expression.call(this, node);
|
||||||
@@ -888,9 +897,12 @@ OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, {
|
|||||||
this.writeNode("Halo", symbolizer, node);
|
this.writeNode("Halo", symbolizer, node);
|
||||||
}
|
}
|
||||||
// add in optional Fill
|
// add in optional Fill
|
||||||
if(symbolizer.fillColor != null ||
|
if(symbolizer.fontColor != null ||
|
||||||
symbolizer.fillOpacity != null) {
|
symbolizer.fontOpacity != null) {
|
||||||
this.writeNode("Fill", symbolizer, node);
|
this.writeNode("Fill", {
|
||||||
|
fillColor: symbolizer.fontColor,
|
||||||
|
fillOpacity: symbolizer.fontOpacity
|
||||||
|
}, node);
|
||||||
}
|
}
|
||||||
return node;
|
return node;
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -0,0 +1,142 @@
|
|||||||
|
/* Copyright (c) 2006-2012 by OpenLayers Contributors (see authors.txt for
|
||||||
|
* full list of contributors). Published under the Clear BSD license.
|
||||||
|
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the
|
||||||
|
* full text of the license. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @requires OpenLayers/Format/SLD/v1_0_0.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class: OpenLayers.Format.SLD/v1_0_0_GeoServer
|
||||||
|
* Read and write SLD version 1.0.0 with GeoServer-specific enhanced options.
|
||||||
|
* See http://svn.osgeo.org/geotools/trunk/modules/extension/xsd/xsd-sld/src/main/resources/org/geotools/sld/bindings/StyledLayerDescriptor.xsd
|
||||||
|
* for more information.
|
||||||
|
*
|
||||||
|
* Inherits from:
|
||||||
|
* - <OpenLayers.Format.SLD.v1_0_0>
|
||||||
|
*/
|
||||||
|
OpenLayers.Format.SLD.v1_0_0_GeoServer = OpenLayers.Class(
|
||||||
|
OpenLayers.Format.SLD.v1_0_0, {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: version
|
||||||
|
* {String} The specific parser version.
|
||||||
|
*/
|
||||||
|
version: "1.0.0",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: profile
|
||||||
|
* {String} The specific profile
|
||||||
|
*/
|
||||||
|
profile: "GeoServer",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor: OpenLayers.Format.SLD.v1_0_0_GeoServer
|
||||||
|
* Create a new parser for GeoServer-enhanced SLD version 1.0.0.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* options - {Object} An optional object whose properties will be set on
|
||||||
|
* this instance.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: readers
|
||||||
|
* Contains public functions, grouped by namespace prefix, that will
|
||||||
|
* be applied when a namespaced node is found matching the function
|
||||||
|
* name. The function will be applied in the scope of this parser
|
||||||
|
* with two arguments: the node being read and a context object passed
|
||||||
|
* from the parent.
|
||||||
|
*/
|
||||||
|
readers: OpenLayers.Util.applyDefaults({
|
||||||
|
"sld": OpenLayers.Util.applyDefaults({
|
||||||
|
"Priority": function(node, obj) {
|
||||||
|
var value = this.readers.ogc._expression.call(this, node);
|
||||||
|
if (value) {
|
||||||
|
obj.priority = value;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"VendorOption": function(node, obj) {
|
||||||
|
if (!obj.vendorOptions) {
|
||||||
|
obj.vendorOptions = [];
|
||||||
|
}
|
||||||
|
obj.vendorOptions.push({
|
||||||
|
name: node.getAttribute("name"),
|
||||||
|
value: this.getChildValue(node)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, OpenLayers.Format.SLD.v1_0_0.prototype.readers["sld"])
|
||||||
|
}, OpenLayers.Format.SLD.v1_0_0.prototype.readers),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Property: writers
|
||||||
|
* As a compliment to the readers property, this structure contains public
|
||||||
|
* writing functions grouped by namespace alias and named like the
|
||||||
|
* node names they produce.
|
||||||
|
*/
|
||||||
|
writers: OpenLayers.Util.applyDefaults({
|
||||||
|
"sld": OpenLayers.Util.applyDefaults({
|
||||||
|
"Priority": function(priority) {
|
||||||
|
return this.writers.sld._OGCExpression.call(
|
||||||
|
this, "sld:Priority", priority
|
||||||
|
);
|
||||||
|
},
|
||||||
|
"VendorOption": function(option) {
|
||||||
|
return this.createElementNSPlus("sld:VendorOption", {
|
||||||
|
attributes: {name: option.name},
|
||||||
|
value: option.value
|
||||||
|
});
|
||||||
|
},
|
||||||
|
"TextSymbolizer": function(symbolizer) {
|
||||||
|
var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;
|
||||||
|
var node = writers["sld"]["TextSymbolizer"].apply(this, arguments);
|
||||||
|
if (symbolizer.externalGraphic || symbolizer.graphicName) {
|
||||||
|
this.writeNode("Graphic", symbolizer, node);
|
||||||
|
}
|
||||||
|
if ("priority" in symbolizer) {
|
||||||
|
this.writeNode("Priority", symbolizer.priority, node);
|
||||||
|
}
|
||||||
|
return this.addVendorOptions(node, symbolizer);
|
||||||
|
},
|
||||||
|
"PointSymbolizer": function(symbolizer) {
|
||||||
|
var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;
|
||||||
|
var node = writers["sld"]["PointSymbolizer"].apply(this, arguments);
|
||||||
|
return this.addVendorOptions(node, symbolizer);
|
||||||
|
},
|
||||||
|
"LineSymbolizer": function(symbolizer) {
|
||||||
|
var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;
|
||||||
|
var node = writers["sld"]["LineSymbolizer"].apply(this, arguments);
|
||||||
|
return this.addVendorOptions(node, symbolizer);
|
||||||
|
},
|
||||||
|
"PolygonSymbolizer": function(symbolizer) {
|
||||||
|
var writers = OpenLayers.Format.SLD.v1_0_0.prototype.writers;
|
||||||
|
var node = writers["sld"]["PolygonSymbolizer"].apply(this, arguments);
|
||||||
|
return this.addVendorOptions(node, symbolizer);
|
||||||
|
}
|
||||||
|
}, OpenLayers.Format.SLD.v1_0_0.prototype.writers["sld"])
|
||||||
|
}, OpenLayers.Format.SLD.v1_0_0.prototype.writers),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method: addVendorOptions
|
||||||
|
* Add in the VendorOption tags and return the node again.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* node - {DOMElement} A DOM node.
|
||||||
|
* symbolizer - {Object}
|
||||||
|
*
|
||||||
|
* Returns:
|
||||||
|
* {DOMElement} A DOM node.
|
||||||
|
*/
|
||||||
|
addVendorOptions: function(node, symbolizer) {
|
||||||
|
var options = symbolizer.vendorOptions;
|
||||||
|
if (options) {
|
||||||
|
for (var i=0, ii=options.length; i<ii; ++i) {
|
||||||
|
this.writeNode("VendorOption", options[i], node);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
},
|
||||||
|
|
||||||
|
CLASS_NAME: "OpenLayers.Format.SLD.v1_0_0_GeoServer"
|
||||||
|
|
||||||
|
});
|
||||||
@@ -177,7 +177,7 @@
|
|||||||
t.eq(text.label, "A ${FOO} label", "(AAA161) first rule has proper text label");
|
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(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.fontFamily, "Arial", "(AAA161) first rule has proper font family");
|
||||||
t.eq(text.fillColor, "#000000", "(AAA161) first rule has proper text fill");
|
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.haloRadius, "3", "(AAA161) first rule has proper halo radius");
|
||||||
t.eq(text.haloColor, "#ffffff", "(AAA161) first rule has proper halo color");
|
t.eq(text.haloColor, "#ffffff", "(AAA161) first rule has proper halo color");
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@
|
|||||||
"label": "This is the ${city} in ${state}.",
|
"label": "This is the ${city} in ${state}.",
|
||||||
"fontFamily": "Arial",
|
"fontFamily": "Arial",
|
||||||
"fontSize": 10,
|
"fontSize": 10,
|
||||||
"fillColor": "blue",
|
"fontColor": "blue",
|
||||||
"fontWeight": "bold",
|
"fontWeight": "bold",
|
||||||
"fontStyle": "normal",
|
"fontStyle": "normal",
|
||||||
"haloRadius": 2,
|
"haloRadius": 2,
|
||||||
|
|||||||
@@ -0,0 +1,114 @@
|
|||||||
|
<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);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test_VendorExtensions(t) {
|
||||||
|
|
||||||
|
var cases = [
|
||||||
|
"poly_label.sld"
|
||||||
|
];
|
||||||
|
var len = cases.length;
|
||||||
|
t.plan(len);
|
||||||
|
|
||||||
|
var format = new OpenLayers.Format.SLD({
|
||||||
|
profile: "GeoServer",
|
||||||
|
multipleSymbolizers: true,
|
||||||
|
namedLayersAsArray: true,
|
||||||
|
schemaLocation: "http://www.opengis.net/sld StyledLayerDescriptor.xsd"
|
||||||
|
});
|
||||||
|
|
||||||
|
var c, doc, data, out;
|
||||||
|
for (var i=0; i<len; ++i) {
|
||||||
|
c = cases[i];
|
||||||
|
doc = readXML(c);
|
||||||
|
data = format.read(doc);
|
||||||
|
out = format.write(data);
|
||||||
|
t.xml_eq(out, doc.documentElement, "round-tripped " + c);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="poly_label.sld"><!--
|
||||||
|
<StyledLayerDescriptor version="1.0.0"
|
||||||
|
xsi:schemaLocation="http://www.opengis.net/sld 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>Polygon with styled label</Name>
|
||||||
|
<UserStyle>
|
||||||
|
<Title>SLD Cook Book: Polygon with styled label</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>
|
||||||
|
<Font>
|
||||||
|
<CssParameter name="font-family">Arial</CssParameter>
|
||||||
|
<CssParameter name="font-size">11</CssParameter>
|
||||||
|
<CssParameter name="font-weight">bold</CssParameter>
|
||||||
|
<CssParameter name="font-style">normal</CssParameter>
|
||||||
|
</Font>
|
||||||
|
<Fill>
|
||||||
|
<CssParameter name="fill">#000000</CssParameter>
|
||||||
|
<CssParameter name="fill-opacity">0.5</CssParameter>
|
||||||
|
</Fill>
|
||||||
|
<Graphic>
|
||||||
|
<Mark>
|
||||||
|
<WellKnownName>square</WellKnownName>
|
||||||
|
<Fill>
|
||||||
|
<CssParameter name="fill">#59BF34</CssParameter>
|
||||||
|
<CssParameter name="fill-opacity">0.8</CssParameter>
|
||||||
|
</Fill>
|
||||||
|
<Stroke>
|
||||||
|
<CssParameter name="stroke">#2D6917</CssParameter>
|
||||||
|
</Stroke>
|
||||||
|
</Mark>
|
||||||
|
<Size>24</Size>
|
||||||
|
</Graphic>
|
||||||
|
<Priority>
|
||||||
|
<ogc:PropertyName>population</ogc:PropertyName>
|
||||||
|
</Priority>
|
||||||
|
<VendorOption name="autoWrap">60</VendorOption>
|
||||||
|
<VendorOption name="followLine">true</VendorOption>
|
||||||
|
<VendorOption name="repeat">300</VendorOption>
|
||||||
|
<VendorOption name="maxDisplacement">150</VendorOption>
|
||||||
|
<VendorOption name="forceLeftToRight">false</VendorOption>
|
||||||
|
<VendorOption name="graphic-margin">3</VendorOption>
|
||||||
|
<VendorOption name="graphic-resize">stretch</VendorOption>
|
||||||
|
<VendorOption name="group">yes</VendorOption>
|
||||||
|
<VendorOption name="spaceAround">10</VendorOption>
|
||||||
|
<VendorOption name="labelAllGroup">true</VendorOption>
|
||||||
|
<VendorOption name="maxAngleDelta">15</VendorOption>
|
||||||
|
<VendorOption name="conflictResolution">false</VendorOption>
|
||||||
|
<VendorOption name="goodnessOfFit">0.3</VendorOption>
|
||||||
|
<VendorOption name="polygonAlign">mbr</VendorOption>
|
||||||
|
</TextSymbolizer>
|
||||||
|
</Rule>
|
||||||
|
</FeatureTypeStyle>
|
||||||
|
</UserStyle>
|
||||||
|
</NamedLayer>
|
||||||
|
</StyledLayerDescriptor>
|
||||||
|
--></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -73,6 +73,7 @@
|
|||||||
<li>Format/Text.html</li>
|
<li>Format/Text.html</li>
|
||||||
<li>Format/SLD.html</li>
|
<li>Format/SLD.html</li>
|
||||||
<li>Format/SLD/v1_0_0.html</li>
|
<li>Format/SLD/v1_0_0.html</li>
|
||||||
|
<li>Format/SLD/v1_0_0_GeoServer.html</li>
|
||||||
<li>Format/Filter.html</li>
|
<li>Format/Filter.html</li>
|
||||||
<li>Format/Filter/v1.html</li>
|
<li>Format/Filter/v1.html</li>
|
||||||
<li>Format/Filter/v1_0_0.html</li>
|
<li>Format/Filter/v1_0_0.html</li>
|
||||||
|
|||||||
Reference in New Issue
Block a user