|
/* Copyright (c) 2006-2010 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/Rule.js |
|
* @requires OpenLayers/Format/SLD.js |
|
* @requires OpenLayers/Format/Filter/v1_0_0.js |
|
*/ |
|
|
|
/** |
|
* Class: OpenLayers.Format.SLD.v1 |
|
* Superclass for SLD version 1 parsers. |
|
* |
|
* Inherits from: |
|
* - <OpenLayers.Format.Filter.v1_0_0> |
|
*/ |
|
OpenLayers.Format.SLD.v1 = OpenLayers.Class(OpenLayers.Format.Filter.v1_0_0, { |
|
|
|
/** |
|
* Property: namespaces |
|
* {Object} Mapping of namespace aliases to namespace URIs. |
|
*/ |
|
namespaces: { |
|
sld: "http://www.opengis.net/sld", |
|
ogc: "http://www.opengis.net/ogc", |
|
gml: "http://www.opengis.net/gml", |
|
xlink: "http://www.w3.org/1999/xlink", |
|
xsi: "http://www.w3.org/2001/XMLSchema-instance" |
|
}, |
|
|
|
/** |
|
* Property: defaultPrefix |
|
*/ |
|
defaultPrefix: "sld", |
|
|
|
/** |
|
* Property: schemaLocation |
|
* {String} Schema location for a particular minor version. |
|
*/ |
|
schemaLocation: null, |
|
|
|
/** |
|
* APIProperty: multipleSymbolizers |
|
* {Boolean} Support multiple symbolizers per rule. Default is false. if |
|
* true, an OpenLayers.Style2 instance will be created to represent |
|
* user styles instead of an OpenLayers.Style instace. The |
|
* OpenLayers.Style2 class allows collections of rules with multiple |
|
* symbolizers, but is not currently useful for client side rendering. |
|
* If multiple symbolizers is true, multiple FeatureTypeStyle elements |
|
* are preserved in reading/writing by setting symbolizer zIndex values. |
|
* In addition, the <defaultSymbolizer> property is ignored if |
|
* multiple symbolizers are supported (defaults should be applied |
|
* when rendering). |
|
*/ |
|
multipleSymbolizers: false, |
|
|
|
/** |
|
* Property: featureTypeCounter |
|
* {Number} Private counter for multiple feature type styles. |
|
*/ |
|
featureTypeCounter: null, |
|
|
|
/** |
|
* APIProperty: defaultSymbolizer. |
|
* {Object} A symbolizer with the SLD defaults. |
|
*/ |
|
defaultSymbolizer: { |
|
fillColor: "#808080", |
|
fillOpacity: 1, |
|
strokeColor: "#000000", |
|
strokeOpacity: 1, |
|
strokeWidth: 1, |
|
strokeDashstyle: "solid", |
|
pointRadius: 3, |
|
graphicName: "square" |
|
}, |
|
|
|
/** |
|
* Constructor: OpenLayers.Format.SLD.v1 |
|
* Instances of this class are not created directly. Use the |
|
* <OpenLayers.Format.SLD> constructor instead. |
|
* |
|
* Parameters: |
|
* options - {Object} An optional object whose properties will be set on |
|
* this instance. |
|
*/ |
|
initialize: function(options) { |
|
OpenLayers.Format.Filter.v1_0_0.prototype.initialize.apply(this, [options]); |
|
}, |
|
|
|
/** |
|
* Method: read |
|
* |
|
* Parameters: |
|
* data - {DOMElement} An SLD document element. |
|
* options - {Object} Options for the reader. |
|
* |
|
* Valid options: |
|
* namedLayersAsArray - {Boolean} Generate a namedLayers array. If false, |
|
* the namedLayers property value will be an object keyed by layer name. |
|
* Default is false. |
|
* |
|
* Returns: |
|
* {Object} An object representing the SLD. |
|
*/ |
|
read: function(data, options) { |
|
options = OpenLayers.Util.applyDefaults(options, this.options); |
|
var sld = { |
|
namedLayers: options.namedLayersAsArray === true ? [] : {} |
|
}; |
|
this.readChildNodes(data, sld); |
|
return sld; |
|
}, |
|
|
|
/** |
|
* 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": { |
|
"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); |
|
// give each of the user styles this layer name |
|
for(var i=0, len=layer.userStyles.length; i<len; ++i) { |
|
layer.userStyles[i].layerName = layer.name; |
|
} |
|
if(sld.namedLayers instanceof Array) { |
|
sld.namedLayers.push(layer); |
|
} else { |
|
sld.namedLayers[layer.name] = layer; |
|
} |
|
}, |
|
"NamedStyle": function(node, layer) { |
|
layer.namedStyles.push( |
|
this.getChildName(node.firstChild) |
|
); |
|
}, |
|
"UserStyle": function(node, layer) { |
|
var obj = {defaultsPerSymbolizer: true, rules: []}; |
|
this.featureTypeCounter = -1; |
|
this.readChildNodes(node, obj); |
|
var style; |
|
if (this.multipleSymbolizers) { |
|
delete obj.defaultsPerSymbolizer; |
|
style = new OpenLayers.Style2(obj); |
|
} else { |
|
style = new OpenLayers.Style(this.defaultSymbolizer, obj); |
|
} |
|
layer.userStyles.push(style); |
|
}, |
|
"IsDefault": function(node, style) { |
|
if(this.getChildValue(node) == "1") { |
|
style.isDefault = true; |
|
} |
|
}, |
|
"FeatureTypeStyle": function(node, style) { |
|
++this.featureTypeCounter; |
|
var obj = { |
|
rules: this.multipleSymbolizers ? style.rules : [] |
|
}; |
|
this.readChildNodes(node, obj); |
|
if (!this.multipleSymbolizers) { |
|
style.rules = obj.rules; |
|
} |
|
}, |
|
"Rule": function(node, obj) { |
|
var config; |
|
if (this.multipleSymbolizers) { |
|
config = {symbolizers: []}; |
|
} |
|
var rule = new OpenLayers.Rule(config); |
|
this.readChildNodes(node, rule); |
|
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); |
|
if (this.multipleSymbolizers) { |
|
config.zIndex = this.featureTypeCounter; |
|
rule.symbolizers.push( |
|
new OpenLayers.Symbolizer.Text(config) |
|
); |
|
} else { |
|
rule.symbolizer["Text"] = OpenLayers.Util.applyDefaults( |
|
config, rule.symbolizer["Text"] |
|
); |
|
} |
|
}, |
|
"Label": function(node, symbolizer) { |
|
// only supporting literal or property name |
|
var obj = {}; |
|
this.readChildNodes(node, obj); |
|
if(obj.property) { |
|
symbolizer.label = "${" + obj.property + "}"; |
|
} else { |
|
var value = this.readOgcExpression(node); |
|
if(value) { |
|
symbolizer.label = 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 radius = this.readOgcExpression(node); |
|
if(radius != null) { |
|
// radius is only used for halo |
|
symbolizer.haloRadius = radius; |
|
} |
|
}, |
|
"RasterSymbolizer": function(node, rule) { |
|
var config = {}; |
|
this.readChildNodes(node, config); |
|
if (this.multipleSymbolizers) { |
|
config.zIndex = this.featureTypeCounter; |
|
rule.symbolizers.push( |
|
new OpenLayers.Symbolizer.Raster(config) |
|
); |
|
} else { |
|
rule.symbolizer["Raster"] = OpenLayers.Util.applyDefaults( |
|
config, rule.symbolizer["Raster"] |
|
); |
|
} |
|
}, |
|
"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); |
|
if (this.multipleSymbolizers) { |
|
config.zIndex = this.featureTypeCounter; |
|
rule.symbolizers.push( |
|
new OpenLayers.Symbolizer.Line(config) |
|
); |
|
} else { |
|
rule.symbolizer["Line"] = OpenLayers.Util.applyDefaults( |
|
config, rule.symbolizer["Line"] |
|
); |
|
} |
|
}, |
|
"PolygonSymbolizer": function(node, rule) { |
|
var config = { |
|
fill: false, |
|
stroke: false |
|
}; |
|
if (!this.multipleSymbolizers) { |
|
config = rule.symbolizer["Polygon"] || config; |
|
} |
|
this.readChildNodes(node, config); |
|
if (this.multipleSymbolizers) { |
|
config.zIndex = this.featureTypeCounter; |
|
rule.symbolizers.push( |
|
new OpenLayers.Symbolizer.Polygon(config) |
|
); |
|
} else { |
|
rule.symbolizer["Polygon"] = config; |
|
} |
|
}, |
|
"PointSymbolizer": function(node, rule) { |
|
var config = { |
|
fill: false, |
|
stroke: false, |
|
graphic: false |
|
}; |
|
if (!this.multipleSymbolizers) { |
|
config = rule.symbolizer["Point"] || config; |
|
} |
|
this.readChildNodes(node, config); |
|
if (this.multipleSymbolizers) { |
|
config.zIndex = this.featureTypeCounter; |
|
rule.symbolizers.push( |
|
new OpenLayers.Symbolizer.Point(config) |
|
); |
|
} else { |
|
rule.symbolizer["Point"] = 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 = this.cssMap[cssProperty]; |
|
if(symProperty) { |
|
// Limited support for parsing of OGC expressions |
|
var value = this.readOgcExpression(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); |