/* 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.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 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 * 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. * * Parameters: * sym - {String} A symbolizer property name. * * Returns: * {String} A CSS property name or null if none found. */ getCssProperty: function(sym) { var css = null; for(var prop in this.cssMap) { if(this.cssMap[prop] == sym) { css = prop; break; } } return css; }, /** * Method: getGraphicFormat * Given a href for an external graphic, try to determine the mime-type. * This method doesn't try too hard, and will fall back to * if one of the known is not * the file extension of the provided href. * * Parameters: * href - {String} * * Returns: * {String} The graphic format. */ getGraphicFormat: function(href) { var format, regex; for(var key in this.graphicFormats) { if(this.graphicFormats[key].test(href)) { format = key; break; } } return format || this.defautlGraphicFormat; }, /** * Property: defaultGraphicFormat * {String} If none other can be determined from , this * default will be returned. */ defaultGraphicFormat: "image/png", /** * Property: graphicFormats * {Object} Mapping of image mime-types to regular extensions matching * well-known file extensions. */ graphicFormats: { "image/jpeg": /\.jpe?g$/i, "image/gif": /\.gif$/i, "image/png": /\.png$/i }, /** * Method: write * * Parameters: * sld - {Object} An object representing the SLD. * * Returns: * {DOMElement} The root of an SLD document. */ write: function(sld) { return this.writers.sld.StyledLayerDescriptor.apply(this, [sld]); }, /** * 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": { "StyledLayerDescriptor": function(sld) { var root = this.createElementNSPlus( "sld:StyledLayerDescriptor", {attributes: { "version": this.VERSION, "xsi:schemaLocation": this.schemaLocation }} ); // For ArcGIS Server it is necessary to define this // at the root level (see ticket:2166). root.setAttribute("xmlns:ogc", this.namespaces.ogc); root.setAttribute("xmlns:gml", this.namespaces.gml); // add in optional name if(sld.name) { this.writeNode("Name", sld.name, root); } // add in optional title if(sld.title) { this.writeNode("Title", sld.title, root); } // add in optional description if(sld.description) { this.writeNode("Abstract", sld.description, root); } // add in named layers // allow namedLayers to be an array if(sld.namedLayers instanceof Array) { for(var i=0, len=sld.namedLayers.length; i 0) { clone = style.clone(); clone.rules = rulesByZ[zValues[i]]; this.writeNode("FeatureTypeStyle", clone, node); } } } else { this.writeNode("FeatureTypeStyle", style, node); } return node; }, "IsDefault": function(bool) { return this.createElementNSPlus( "sld:IsDefault", {value: (bool) ? "1" : "0"} ); }, "FeatureTypeStyle": function(style) { var node = this.createElementNSPlus("sld:FeatureTypeStyle"); // OpenLayers currently stores no Name, Title, Abstract, // FeatureTypeName, or SemanticTypeIdentifier information // related to FeatureTypeStyle // add in rules for(var i=0, len=style.rules.length; i 0) { this.writeNode( "ogc:PropertyName", {property: item.substring(0, last)}, node ); node.appendChild( this.createTextNode(item.substring(++last)) ); } else { // no ending }, so this is a literal ${ node.appendChild( this.createTextNode("${" + item) ); } } return node; }, "Halo": function(symbolizer) { var node = this.createElementNSPlus("sld:Halo"); if(symbolizer.haloRadius) { this.writeNode("Radius", symbolizer.haloRadius, node); } if(symbolizer.haloColor || symbolizer.haloOpacity) { this.writeNode("Fill", { fillColor: symbolizer.haloColor, fillOpacity: symbolizer.haloOpacity }, node); } return node; }, "Radius": function(value) { return this.createElementNSPlus("sld:Radius", { value: value }); }, "RasterSymbolizer": function(symbolizer) { var node = this.createElementNSPlus("sld:RasterSymbolizer"); if (symbolizer.geometry) { this.writeNode("Geometry", symbolizer.geometry, node); } if (symbolizer.opacity) { this.writeNode("Opacity", symbolizer.opacity, node); } if (symbolizer.colorMap) { this.writeNode("ColorMap", symbolizer.colorMap, node); } return node; }, "Geometry": function(geometry) { var node = this.createElementNSPlus("sld:Geometry"); if (geometry.property) { this.writeNode("ogc:PropertyName", geometry, node); } return node; }, "ColorMap": function(colorMap) { var node = this.createElementNSPlus("sld:ColorMap"); for (var i=0, len=colorMap.length; i