OpenLayers OpenLayers

Ticket #533: sld.diff

File sld.diff, 97.8 kB (added by ahocevar, 9 months ago)

patch with tests and examples

  • tests/list-tests.html

    old new  
    2222    <li>test_Format.html</li> 
    2323    <li>Format/test_XML.html</li> 
    2424    <li>Format/test_KML.html</li> 
     25    <li>Format/test_SLD.html</li> 
    2526    <li>Format/test_GeoRSS.html</li> 
    2627    <li>Format/test_JSON.html</li> 
    2728    <li>Format/test_GeoJSON.html</li> 
  • tests/Format/test_SLD.html

    old new  
     1<html>  
     2<head>  
     3    <script src="../../lib/OpenLayers.js"></script>  
     4    <script type="text/javascript"> 
     5 
     6    var test_content = '<sld:StyledLayerDescriptor xmlns:sld="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:gml="http://www.opengis.net/gml"><sld:NamedLayer><sld:Name>TestLayer</sld:Name><sld:UserStyle><sld:Name>foo</sld:Name><sld:FeatureTypeStyle><sld:Rule><sld:Name>bar</sld:Name><ogc:Filter></ogc:Filter><sld:PolygonSymbolizer><sld:Fill><sld:CssParameter name="fill"><ogc:Literal>blue</ogc:Literal></sld:CssParameter></sld:Fill></sld:PolygonSymbolizer></sld:Rule></sld:FeatureTypeStyle></sld:UserStyle></sld:NamedLayer></sld:StyledLayerDescriptor>'; 
     7 
     8    function test_Format_SLD_constructor(t) {  
     9        t.plan(3);  
     10          
     11        var options = {'foo': 'bar'};  
     12        var format = new OpenLayers.Format.SLD(options);  
     13        t.ok(format instanceof OpenLayers.Format.SLD,  
     14             "new OpenLayers.Format.SLD returns object" );  
     15        t.eq(format.foo, "bar", "constructor sets options correctly");  
     16        t.eq(typeof format.read, "function", "format has a read function");  
     17    } 
     18 
     19    function test_Format_SLD_read(t) { 
     20        t.plan(5); 
     21        var format = new OpenLayers.Format.SLD(); 
     22        var styles = format.read(this.test_content); 
     23         
     24        var testLayer = format.content.namedLayer.TestLayer; 
     25         
     26        t.ok(testLayer.foo != undefined, "SLD correctly reads a UserStyle named \"foo\""); 
     27        t.eq(testLayer.foo.rules.length, 1, "The number of rules for the UserStyle is correct"); 
     28        t.eq(testLayer.foo.rules[0].name, "bar", "The first rule's name is \"bar\""); 
     29        t.eq(testLayer.foo.rules[0].symbolizer.Polygon.fillColor, "blue", "The fillColor for the Polygon symbolizer is correct"); 
     30        t.eq(testLayer.foo.name, styles[0].name, "The content hash of the Format contains the correct rules."); 
     31    } 
     32 
     33    </script>  
     34</head>  
     35<body>  
     36</body>  
     37</html>  
  • lib/OpenLayers/Format/SLD.js

    old new  
     1/* Copyright (c) 2006 MetaCarta, Inc., published under a modified BSD license. 
     2 * See http://svn.openlayers.org/trunk/openlayers/repository-license.txt  
     3 * for the full text of the license. */ 
     4 
     5/** 
     6 * @requires OpenLayers/Format/XML.js 
     7 * @requires OpenLayers/Style.js 
     8 * @requires OpenLayers/Rule.js 
     9 * @requires OpenLayers/Rule/FeatureId.js 
     10 * @requires OpenLayers/Rule/Logical.js 
     11 * @requires OpenLayers/Rule/Comparison.js 
     12 * 
     13 * Class: OpenLayers.Format.SLD 
     14 * Read/Wite SLD. Create a new instance with the <OpenLayers.Format.SLD> 
     15 *     constructor. 
     16 *  
     17 * Inherits from: 
     18 *  - <OpenLayers.Format.XML> 
     19 */ 
     20OpenLayers.Format.SLD = OpenLayers.Class(OpenLayers.Format.XML, { 
     21     
     22    /** 
     23     * APIProperty: sldns 
     24     * Namespace used for sld. 
     25     */ 
     26    sldns: "http://www.opengis.net/sld", 
     27     
     28    /** 
     29     * APIProperty: ogcns 
     30     * Namespace used for ogc. 
     31     */ 
     32    ogcns: "http://www.opengis.net/ogc", 
     33     
     34    /** 
     35     * APIProperty: gmlns 
     36     * Namespace used for gml. 
     37     */ 
     38    gmlns: "http://www.opengis.net/gml", 
     39     
     40    /** 
     41     * APIProperty: defaultStyle. 
     42     * {Object} 
     43     * A simple style, preset with the SLD defaults 
     44     */ 
     45    defaultStyle: { 
     46            fillColor: "#808080", 
     47            fillOpacity: 1, 
     48            strokeColor: "#000000", 
     49            strokeOpacity: 1, 
     50            strokeWidth: 1, 
     51            pointRadius: 6 
     52    }, 
     53     
     54    /** 
     55     * APIProperty: content 
     56     * {Object} containing 
     57     *     - namedLayer - {Object} hash of userStyles, keyed by sld:NamedLayer/Name, 
     58     *                    each again keyed by sld:UserStyle/Name. Each entry of namedLayer 
     59     *                    is a style map for a layer, with the userStyle names as style keys. 
     60     *     - userStyles - {Array(<OpenLayers.Style>)} 
     61     */ 
     62    content: { 
     63            namedLayer: null, 
     64            userStyles: null 
     65    }, 
     66     
     67    /** 
     68     * APIProperty: overrideDefaultStyleKey 
     69     * {Boolean} if true, userStyles with sld:IsDefault==1 will be stored with 
     70     * key "default" instead of the sld:UserStyle/Name in the style map. 
     71     */ 
     72    overrideDefaultStyleKey: true, 
     73 
     74 
     75    /** 
     76     * Constructor: OpenLayers.Format.SLD 
     77     * Create a new parser for SLD 
     78     * 
     79     * Parameters: 
     80     * options - {Object} An optional object whose properties will be set on 
     81     *                    this instance. 
     82     */ 
     83    initialize: function(options) { 
     84        OpenLayers.Format.XML.prototype.initialize.apply(this, [options]); 
     85    }, 
     86 
     87    /** 
     88     * APIMethod: read 
     89     * Read data from a string, and return a list of features.  
     90     *  
     91     * Parameters: 
     92     * data - {String} or {XMLNode} data to read/parse. 
     93     * 
     94     * Returns: 
     95     * {Array(<OpenLayers.Style>)} 
     96     */ 
     97    read: function(data) { 
     98        if (typeof data == "string") {  
     99            data = OpenLayers.Format.XML.prototype.read.apply(this, [data]); 
     100        } 
     101         
     102        var userStyles = this.getElementsByTagNameNS(data, this.sldns, 
     103                "UserStyle"); 
     104        if (userStyles.length == 0) { 
     105            return {}; 
     106        } 
     107 
     108        this.content.namedLayer = {}; 
     109        var styles = []; 
     110 
     111        for (var i=0; i<userStyles.length; i++) { 
     112            var styleName = this.parseProperty(userStyles[i], this.sldns, "Name"); 
     113            var style = this.parseUserStyle(userStyles[i], styleName); 
     114 
     115            if (this.overrideDefaultStyleKey && style.isDefault == true) { 
     116                styleName = "default"; 
     117            } 
     118 
     119            var namedLayer = this.content.namedLayer; 
     120            if (!namedLayer[style.layerName]) { 
     121                namedLayer[style.layerName] = {}; 
     122            } 
     123            namedLayer[style.layerName][styleName] = style; 
     124            styles.push(style); 
     125        } 
     126         
     127        this.content.userStyles = styles; 
     128         
     129        return styles; 
     130    }, 
     131 
     132    /** 
     133     * Method: parseUserStyle 
     134     * parses a sld userStyle for rules 
     135     *  
     136     * Parameters: 
     137     * xmlNode - {<DOMElement>} xml node to read the style from 
     138     * name - {<String>} name of the style 
     139     *  
     140     * Returns: 
     141     * {<OpenLayers.Style>} 
     142     */ 
     143    parseUserStyle: function(xmlNode, name) { 
     144        var userStyle = new OpenLayers.Style(this.defaultStyle, {name: name}); 
     145         
     146        userStyle.isDefault = this.parseProperty(xmlNode, this.sldns, 
     147                "IsDefault") == 1 ? true : false; 
     148         
     149        // get the name of the layer if we have a NamedLayer 
     150        var namedLayerNode = xmlNode.parentNode; 
     151        var nameNodes = this.getElementsByTagNameNS(namedLayerNode, this.sldns, "Name"); 
     152        if (namedLayerNode.nodeName.indexOf("NamedLayer") != -1 && 
     153                nameNodes && 
     154                nameNodes.length > 0 && 
     155                nameNodes[0].parentNode == namedLayerNode) { 
     156            userStyle.layerName = this.getChildValue(nameNodes[0]); 
     157        } 
     158          
     159        var ruleNodes = this.getElementsByTagNameNS(xmlNode, this.sldns, 
     160                "Rule"); 
     161        if (ruleNodes.length == 0) { return []; } 
     162 
     163        var rules = userStyle.rules; 
     164        for (var i=0; i<ruleNodes.length; i++) { 
     165            var name = this.parseProperty(ruleNodes[i], this.sldns, "Name"); 
     166            rules.push(this.parseRule(ruleNodes[i], name)); 
     167        } 
     168 
     169        return userStyle; 
     170    },         
     171     
     172    /** 
     173     * Method: parseRule 
     174     * This function is the core of the SLD parsing code in OpenLayers. 
     175     * It creates the rule with its constraints and symbolizers. 
     176     * 
     177     * Parameters: 
     178     * xmlNode - {<DOMElement>} 
     179     *  
     180     * Returns: 
     181     * {Object} Hash of rule properties 
     182     */ 
     183    parseRule: function(xmlNode, name) { 
     184 
     185        // FILTERS 
     186         
     187        var filter = this.getElementsByTagNameNS(xmlNode, this.ogcns, "Filter"); 
     188        if (filter && filter.length > 0) { 
     189            var rule = this.parseFilter(filter[0]); 
     190        } else { 
     191            // rule applies to all features 
     192            var rule = new OpenLayers.Rule(); 
     193        } 
     194        rule.name = name; 
     195         
     196        // SCALE DENOMINATORS 
     197         
     198        // MinScaleDenominator 
     199        var minScale = this.getElementsByTagNameNS(xmlNode, 
     200                this.sldns, "MinScaleDenominator"); 
     201        if (minScale && minScale.length > 0) { 
     202            rule.minScale = parseFloat( 
     203                    this.getChildValue(minScale[0])); 
     204        } 
     205         
     206        // MaxScaleDenominator 
     207        var maxScale = this.getElementsByTagNameNS(xmlNode, 
     208                this.sldns, "MaxScaleDenominator"); 
     209        if (maxScale && maxScale.length > 0) { 
     210            rule.maxScale = parseFloat( 
     211                    this.getChildValue(maxScale[0])); 
     212        } 
     213         
     214        // STYLES 
     215         
     216        // walk through all symbolizers 
     217        var prefixes = OpenLayers.Style.SYMBOLIZER_PREFIXES; 
     218        for (var s=0; s<prefixes.length; s++) { 
     219             
     220            // symbolizer type 
     221            var symbolizer = this.getElementsByTagNameNS(xmlNode, this.sldns, 
     222                    prefixes[s]+"Symbolizer"); 
     223             
     224            if (symbolizer && symbolizer.length > 0) { 
     225             
     226                var style = {}; 
     227             
     228                // externalGraphic 
     229                var graphic = this.getElementsByTagNameNS(symbolizer[0], 
     230                        this.sldns, "Graphic"); 
     231                if (graphic && graphic.length > 0) { 
     232                    style.externalGraphic = this.parseProperty(graphic[0], 
     233                            this.sldns, "OnlineResource", "xlink:href"); 
     234                    style.pointRadius = this.parseProperty(graphic[0], 
     235                            this.sldns, "Size"); 
     236                    style.graphicOpacity = this.parseProperty(graphic[0], 
     237                            this.sldns, "Opacity"); 
     238                } 
     239                 
     240                // fill 
     241                var fill = this.getElementsByTagNameNS(symbolizer[0], 
     242                        this.sldns, "Fill"); 
     243                if (fill && fill.length > 0) { 
     244                    style.fillColor = this.parseProperty(fill[0], this.sldns, 
     245                            "CssParameter", "name", "fill"); 
     246                    style.fillOpacity = this.parseProperty(fill[0], 
     247                            this.sldns, "CssParameter", "name", 
     248                            "fill-opacity") || 1; 
     249                } 
     250             
     251                // stroke 
     252                var stroke = this.getElementsByTagNameNS(symbolizer[0], 
     253                        this.sldns, "Stroke"); 
     254                if (stroke && stroke.length > 0) { 
     255                    style.strokeColor = this.parseProperty(stroke[0], 
     256                            this.sldns, "CssParameter", "name", "stroke"); 
     257                    style.strokeOpacity = this.parseProperty(stroke[0], 
     258                            this.sldns, "CssParameter", "name", 
     259                            "stroke-opacity") || 1; 
     260                    style.strokeWidth = this.parseProperty(stroke[0], 
     261                            this.sldns, "CssParameter", "name", 
     262                            "stroke-width"); 
     263                    style.strokeLinecap = this.parseProperty(stroke[0], 
     264                            this.sldns, "CssParameter", "name", 
     265                            "stroke-linecap"); 
     266                } 
     267                 
     268                // set the [point|line|polygon]Symbolizer property of the rule 
     269                rule.symbolizer[prefixes[s]] = style; 
     270            } 
     271        } 
     272 
     273        return rule; 
     274    }, 
     275     
     276    /** 
     277     * Method: parseFilter 
     278     * Parses ogc fiters. 
     279     * 
     280     * Parameters: 
     281     * xmlNode - {<DOMElement>} 
     282     *  
     283     * Returns: 
     284     * {<OpenLayers.Rule>} rule representing the filter 
     285     */ 
     286    parseFilter: function(xmlNode) { 
     287        // ogc:FeatureId filter 
     288        var filter = this.getNodeOrChildrenByTagName(xmlNode, "FeatureId"); 
     289        if (filter) { 
     290            var rule = new OpenLayers.Rule.FeatureId(); 
     291            for (var i=0; i<filter.length; i++) { 
     292                rule.fids.push(filter[i].getAttribute("fid")); 
     293            } 
     294            return rule; 
     295        } 
     296         
     297        // ogc:And filter 
     298        filter = this.getNodeOrChildrenByTagName(xmlNode, "And"); 
     299        if (filter) { 
     300            var rule = new OpenLayers.Rule.Logical( 
     301                    {type: OpenLayers.Rule.Logical.AND}); 
     302            var filters = filter[0].childNodes;  
     303            for (var i=0; i<filters.length; i++) { 
     304                if (filters[i].nodeType == 1) { 
     305                    rule.children.push(this.parseFilter(filters[i])); 
     306                } 
     307            } 
     308            return rule; 
     309        } 
     310 
     311        // ogc:Or filter 
     312        filter = this.getNodeOrChildrenByTagName(xmlNode, "Or"); 
     313        if (filter) { 
     314            var rule = new OpenLayers.Rule.Logical( 
     315                    {type: OpenLayers.Rule.Logical.OR}) 
     316            var filters = filter[0].childNodes;  
     317            for (var i=0; i<filters.length; i++) { 
     318                if (filters[i].nodeType == 1) { 
     319                    rule.children.push(this.parseFilter(filters[i])); 
     320                } 
     321            } 
     322            return rule; 
     323        } 
     324 
     325        // ogc:Not filter 
     326        filter = this.getNodeOrChildrenByTagName(xmlNode, "Not"); 
     327        if (filter) { 
     328            var rule = new OpenLayers.Rule.Logical( 
     329                    {type: OpenLayers.Rule.Logical.NOT}); 
     330            rule.children.push(this.parseFilter(filter[0])); 
     331            return rule; 
     332        } 
     333         
     334        // Comparison filters 
     335        for (var type in this.TYPES) { 
     336            var filter = this.getNodeOrChildrenByTagName(xmlNode, type); 
     337            if (filter) { 
     338                filter = filter[0]; 
     339                var rule = new OpenLayers.Rule.Comparison({ 
     340                        type: OpenLayers.Rule.Comparison[this.TYPES[type]], 
     341                        property: this.parseProperty( 
     342                                filter, this.ogcns, "PropertyName")}); 
     343                // ogc:PropertyIsBetween 
     344                if (this.TYPES[type] == "BETWEEN") { 
     345                    rule.lowerBoundary = this.parseProperty( 
     346                            filter, this.ogcns, "LowerBoundary"); 
     347                    rule.upperBoudary = this.parseProperty( 
     348                            filter, this.ogcns, "UpperBoundary"); 
     349                } else { 
     350                    rule.value = this.parseProperty( 
     351                            filter, this.ogcns, "Literal"); 
     352                    // ogc:PropertyIsLike 
     353                    if (this.TYPES[type] == "LIKE") { 
     354                        var wildCard = filter.getAttribute("wildCard"); 
     355                        var singleChar = filter.getAttribute("singleChar"); 
     356                        var escape = filter.getAttribute("escape"); 
     357                        rule.value2regex(wildCard, singleChar, escape); 
     358                    } 
     359                } 
     360                return rule; 
     361            } 
     362        } 
     363         
     364        // if we get here, the filter was empty 
     365        return new OpenLayers.Rule(); 
     366    }, 
     367     
     368    /** 
     369     * Method: getNodeOrChildrenByTagName 
     370     * Convenience method to get a node or its child nodes, but only 
     371     * those matching a tag name. 
     372     *  
     373     * Returns: 
     374     * {Array(<DOMElement>)} or null if no matching content is found 
     375     */ 
     376    getNodeOrChildrenByTagName: function(xmlNode, tagName) { 
     377        var nodeName = (xmlNode.prefix) ? 
     378               xmlNode.nodeName.split(":")[1] : 
     379               xmlNode.nodeName; 
     380 
     381        if (nodeName == tagName) { 
     382            return [xmlNode]; 
     383        } else { 
     384            var nodelist = this.getElementsByTagNameNS( 
     385                    xmlNode, this.ogcns, tagName); 
     386        } 
     387 
     388        // make a new list which only contains matching child nodes 
     389        if (nodelist.length > 0) { 
     390            var node; 
     391            var list = []; 
     392            for (var i=0; i<nodelist.length; i++) { 
     393                node = nodelist[i]; 
     394                if (node.parentNode == xmlNode) { 
     395                    list.push(node); 
     396                } 
     397            } 
     398            return list.length > 0 ? list : null; 
     399        } 
     400         
     401        return null; 
     402    }, 
     403     
     404    /** 
     405     * Method: parseProperty 
     406     * Convenience method to parse the different kinds of properties 
     407     * found in the sld and ogc namespace. 
     408     * Parses an ogc node that can either contain a value directly, 
     409     * or inside a <Literal> property. The parsing can also be limited 
     410     * to nodes with certain attribute names and/or values 
     411     * 
     412     * Parameters: 
     413     * xmlNode        - {<DOMElement>} 
     414     * namespace      - {String} namespace of the node to find 
     415     * propertyName   - {String} name of the property to parse 
     416     * attributeName  - {String} optional name of the property to match 
     417     * attributeValue - {String} optional value of the specified attribute 
     418     *  
     419     * Returns: 
     420     * {String} The value for the requested property 
     421     */     
     422    parseProperty: function(xmlNode, namespace, propertyName, attributeName, 
     423                                                              attributeValue) { 
     424        var result = null; 
     425        var propertyNodeList = this.getElementsByTagNameNS( 
     426                xmlNode, namespace, propertyName); 
     427                 
     428        if (propertyNodeList && propertyNodeList.length > 0) { 
     429            var propertyNode = attributeName ? 
     430                    this.getNodeWithAttribute(propertyNodeList,  
     431                            attributeName) : 
     432                    propertyNodeList[0]; 
     433 
     434            // strip namespace from attribute name for Opera browsers 
     435            if (window.opera && attributeName) { 
     436                var nsDelimiterPos = attributeName.indexOf(":"); 
     437                if (nsDelimiterPos != -1) { 
     438                    attributeName = attributeName.substring(++nsDelimiterPos); 
     439                } 
     440            } 
     441             
     442            // get the property value from the node matching attributeName 
     443            // and attributeValue, eg.: 
     444            // <CssParameter name="stroke"> 
     445            //     <ogc:Literal>red</ogc:Literal> 
     446            // </CssParameter> 
     447            // or: 
     448            // <CssParameter name="stroke">red</CssParameter> 
     449            if (attributeName && attributeValue) { 
     450                propertyNode = this.getNodeWithAttribute(propertyNodeList, 
     451                        attributeName, attributeValue); 
     452                result = this.parseParameter(propertyNode); 
     453            } 
     454 
     455            // get the attribute value and use it as result, eg.: 
     456            // <sld:OnlineResource xlink:href="../img/marker.png"/> 
     457            if (attributeName && !attributeValue) { 
     458                var propertyNode = this.getNodeWithAttribute(propertyNodeList, 
     459                        attributeName); 
     460                result = propertyNode.getAttribute(attributeName);                 
     461            } 
     462             
     463            // get the property value directly or from an ogc:propertyName, 
     464            // ogc:Literal or any other property at the level of the property 
     465            // node, eg.: 
     466            // <sld:Opacity>0.5</sld:Opacity> 
     467            if (!attributeName) { 
     468                var result = this.parseParameter(propertyNode); 
     469            } 
     470        } 
     471         
     472        // adjust the result to be a trimmed string or a number 
     473        if (result) { 
     474            result = OpenLayers.String.trim(result); 
     475            if (!isNaN(result)) { 
     476                result = parseFloat(result); 
     477            } 
     478        } 
     479         
     480        return result; 
     481    }, 
     482     
     483    /** 
     484     * Method: parseParameter 
     485     * parses a property for propertyNames, Literals and textContent and 
     486     * creates the according value string. 
     487     *  
     488     * Parameters: 
     489     * xmlNode - {<DOMElement>} 
     490     *  
     491     * Returns: 
     492     * {String} a string holding a value suitable for OpenLayers.Style.value 
     493     */ 
     494    parseParameter: function(xmlNode) { 
     495        if (!xmlNode) { 
     496            return null; 
     497        } 
     498        var childNodes = xmlNode.childNodes; 
     499        if (!childNodes) { 
     500            return null; 
     501        } 
     502 
     503        var value = new Array(childNodes.length); 
     504        for (var i=0; i<childNodes.length; i++) { 
     505            if (childNodes[i].nodeName.indexOf("Literal") != -1) { 
     506                value[i] = this.getChildValue(childNodes[i]); 
     507            } else 
     508            if (childNodes[i].nodeName.indexOf("propertyName") != -1) { 
     509                value[i] = "${" + this.getChildValue(childNodes[i]) + "}"; 
     510            } else 
     511            if (childNodes[i].nodeType == 3) { 
     512                value[i] = childNodes[i].text || childNodes[i].textContent; 
     513            } 
     514        } 
     515        return value.join(""); 
     516    }, 
     517         
     518    /** 
     519     * Method: getNodeWithAttribute 
     520     * Walks through a list of xml nodes and returns the fist node that has an 
     521     * attribute with the name and optional value specified. 
     522     *  
     523     * Parameters: 
     524     * xmlNodeList    - {Array(<DOMElement>)} list to search 
     525     * attributeName  - {String} name of the attribute to match 
     526     * attributeValue - {String} optional value of the attribute 
     527     */ 
     528    getNodeWithAttribute: function(xmlNodeList, attributeName, attributeValue) { 
     529        for (var i=0; i<xmlNodeList.length; i++) { 
     530            var currentAttributeValue = 
     531                    xmlNodeList[i].getAttribute(attributeName); 
     532            if (currentAttributeValue) { 
     533                if (!attributeValue) { 
     534                    return xmlNodeList[i]; 
     535                } else if (currentAttributeValue == attributeValue) { 
     536                    return xmlNodeList[i]; 
     537                } 
     538            } 
     539        } 
     540    }, 
     541     
     542    /** 
     543     * Constant: TYPES 
     544     * {Object} Mapping between SLD rule names and rule type constants. 
     545     *  
     546     */ 
     547    TYPES: {'PropertyIsEqualTo': 'EQUAL_TO', 
     548            'PropertyIsNotEqualTo': 'NOT_EQUAL_TO', 
     549            'PropertyIsLessThan': 'LESS_THAN', 
     550            'PropertyIsGreaterThan': 'GREATER_THAN', 
     551            'PropertyIsLessThanOrEqualTo': 'LESS_THAN_OR_EQUAL_TO', 
     552            'PropertyIsGreaterThanOrEqualTo': 'GREATER_THAN_OR_EQUAL_TO', 
     553            'PropertyIsBetween': 'BETWEEN', 
     554            'PropertyIsLike': 'LIKE'}, 
     555 
     556    CLASS_NAME: "OpenLayers.Format.SLD"  
     557}); 
  • lib/OpenLayers.js

    old new  
    176176            "OpenLayers/Format/GeoRSS.js", 
    177177            "OpenLayers/Format/WFS.js", 
    178178            "OpenLayers/Format/WKT.js", 
     179            "OpenLayers/Format/SLD.js", 
    179180            "OpenLayers/Format/Text.js", 
    180181            "OpenLayers/Format/JSON.js", 
    181182            "OpenLayers/Format/GeoJSON.js", 
  • examples/sld.html

    old new  
     1<html xmlns="http://www.w3.org/1999/xhtml"> 
     2  <head> 
     3    <style type="text/css"> 
     4        #map { 
     5            width: 800px; 
     6            height: 475px; 
     7            border: 1px solid black; 
     8        } 
     9    </style> 
     10    <script src="../lib/Firebug/firebug.js"></script> 
     11    <script src="../lib/OpenLayers.js"></script> 
     12    <script type="text/javascript"> 
     13        var lon = 5; 
     14        var lat = 40; 
     15        var zoom = 5; 
     16        var map, layer, gmlLayers, styles, waterStyle, hover; 
     17 
     18        function load(){ 
     19           OpenLayers.loadURL("tasmania/sld-tasmania.xml", "", null, init); 
     20        } 
     21         
     22        function init(req){ 
     23            map = new OpenLayers.Map('map'); 
     24            layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",  
     25                    "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} ); 
     26            map.addLayer(layer);            
     27                  map.zoomToExtent(new OpenLayers.Bounds(143,-39,150,-45)); 
     28 
     29            sld = new OpenLayers.Format.SLD(); 
     30            sld.read(req.responseText); 
     31             
     32            styles = sld.content.namedLayer; 
     33             
     34            waterStyle = styles["WaterBodies"]; 
     35             
     36            gmlLayers = [ 
     37                    // use the sld UserStyle named "Default Styler" 
     38                    new OpenLayers.Layer.GML("StateBoundaries", 
     39                            "tasmania/TasmaniaStateBoundaries.xml", { 
     40                            style: waterStyle["default"]}), 
     41                    new OpenLayers.Layer.GML("Roads", 
     42                            "tasmania/TasmaniaRoads.xml", { 
     43                            style: waterStyle["default"]}), 
     44                    new OpenLayers.Layer.GML("WaterBodies", 
     45                            "tasmania/TasmaniaWaterBodies.xml", { 
     46                            style: waterStyle["default"]}), 
     47                    new OpenLayers.Layer.GML("Cities", 
     48                            "tasmania/TasmaniaCities.xml", { 
     49                            style: waterStyle["default"]})]; 
     50  
     51            // add the first layer with the style passed to the constructor 
     52            map.addLayer(gmlLayers[0]); 
     53            // add the other layers after setting the style using the 
     54            // setStyle() method, which will pick the correct default style 
     55            // from the styles hash we got back from 
     56            // OpenLayers.Format.SLD.read() 
     57            for (var i=1; i<gmlLayers.length; i++) { 
     58                gmlLayers[i].style = styles[gmlLayers[i].name]["default"]; 
     59                      map.addLayer(gmlLayers[i]); 
     60                gmlLayers[i].redraw(); 
     61            } 
     62             
     63            // SLD can also be used for the SelectFeature control 
     64            waterStyle["Hover Styler"].defaultStyle = 
     65                    OpenLayers.Feature.Vector.style["select"]; 
     66            hover = new OpenLayers.Control.SelectFeature(gmlLayers[2], { 
     67                    selectStyle: waterStyle["Hover Styler"], 
     68                    hover: true, 
     69                    select: select 
     70                }); 
     71            map.addControl(hover); 
     72            hover.activate(); 
     73        } 
     74 
     75        // replaces OpenLayers.Control.Select.select 
     76        var select = function(feature) { 
     77            // store layer style 
     78            var style = feature.layer.style; 
     79            // set temporary layer style for hover rendering 
     80            feature.layer.style = hover.selectStyle; 
     81            OpenLayers.Control.SelectFeature.prototype.select.apply(hover, arguments); 
     82            // restore layer style 
     83            feature.layer.style = style; 
     84        } 
     85         
     86        // set a new style when the radio button changes 
     87        function setStyle(styleName) { 
     88            // change the style of the features of the WaterBodies layer 
     89            var features = gmlLayers[2].features; 
     90            for (var i=0; i<features.length; i++) { 
     91                features[i].style = waterStyle[styleName]; 
     92            } 
     93            gmlLayers[2].redraw(); 
     94        } 
     95    </script> 
     96  </head> 
     97  <body onload="load()"> 
     98    <div id="map"></div> 
     99    <p>This example uses a <a target="_blank" href="xml/sld-tasmania.xml">SLD 
     100    file</a> to style the vector features. The style to be used is either 
     101    determined by the NamedLayer and IsDefault properties in the sld file, or 
     102    can directly be applied by addressing a style from the styles 
     103    hash with the UserStyle name from the sld file as key. Select a new style for the WaterBodies layer below:<p> 
     104    <form> 
     105      <input type="radio" name="style" onclick="setStyle(this.value)" checked="checked" value="default">Default Styler (zoom in to see more features)</input><br/> 
     106      <input type="radio" name="style" onclick="setStyle(this.value)" value="Styler Test PropertyIsEqualTo">Styler Test PropertyIsEqualTo</input><br/> 
     107      <input type="radio" name="style" onclick="setStyle(this.value)" value="Styler Test Not FeatureId">Styler Test Not FeatureId</input><br/> 
     108      <input type="radio" name="style" onclick="setStyle(this.value)" value="Styler Test WATER_TYPE">Styler Test WATER_TYPE</input><br/> 
     109      <input type="radio" name="style" onclick="setStyle(this.value)" value="Styler Test PropertyIsGreaterThanOrEqualTo">Styler Test PropertyIsGreaterThanOrEqualTo</input><br/> 
     110      <input type="radio" name="style" onclick="setStyle(this.value)" value="Styler Test PropertyIsLessThanOrEqualTo">Styler Test PropertyIsLessThanOrEqualTo</input><br/> 
     111      <input type="radio" name="style" onclick="setStyle(this.value)" value="Styler Test PropertyIsGreaterThan">Styler Test PropertyIsGreaterThan</input><br/> 
     112      <input type="radio" name="style" onclick="setStyle(this.value)" value="Styler Test PropertyIsLessThan">Styler Test PropertyIsLessThan</input><br/> 
     113      <input type="radio" name="style" onclick="setStyle(this.value)" value="Styler Test PropertyIsLike">Styler Test PropertyIsLike</input><br/> 
     114    </form> 
     115  </body> 
     116</html> 
  • examples/tasmania/TasmaniaRoads.xml

    old new  
     1<?xml version="1.0" encoding="UTF-8"?> 
     2<wfs:FeatureCollection xmlns:wfs="http://www.opengis.net/wfs" xmlns:topp="http://www.openplans.org/topp" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.openplans.org/topp http://192.168.0.100:8080/geoserver-1.4.0-RC3/wfs/DescribeFeatureType?typeName=topp:tasmania_roads http://www.opengis.net/wfs http://192.168.0.100:8080/geoserver-1.4.0-RC3/schemas/wfs/1.0.0/WFS-basic.xsd"> 
     3  <gml:boundedBy> 
     4    <gml:Box srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     5      <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">145.19754,-43.423512 148.27298,-40.852802</gml:coordinates> 
     6    </gml:Box> 
     7  </gml:boundedBy> 
     8  <gml:featureMember> 
     9    <topp:tasmania_roads fid="tasmania_roads.1"> 
     10      <topp:the_geom> 
     11        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     12          <gml:lineStringMember> 
     13            <gml:LineString> 
     14              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">146.468582,-41.241478 146.574768,-41.251186 146.640411,-41.255154 146.766129,-41.332348 146.794189,-41.34417 146.822174,-41.362988 146.863434,-41.380234 146.899521,-41.379452 146.929504,-41.378227 147.008041,-41.356079 147.098343,-41.362919</gml:coordinates> 
     15            </gml:LineString> 
     16          </gml:lineStringMember> 
     17        </gml:MultiLineString> 
     18      </topp:the_geom> 
     19      <topp:TYPE>alley</topp:TYPE> 
     20    </topp:tasmania_roads> 
     21  </gml:featureMember> 
     22  <gml:featureMember> 
     23    <topp:tasmania_roads fid="tasmania_roads.2"> 
     24      <topp:the_geom> 
     25        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     26          <gml:lineStringMember> 
     27            <gml:LineString> 
     28              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">147.098343,-41.362919 147.17305,-41.452778 147.213867,-41.503773 147.234894,-41.546661 147.251129,-41.573826 147.264664,-41.602474 147.284485,-41.617554 147.300583,-41.637878</gml:coordinates> 
     29            </gml:LineString> 
     30          </gml:lineStringMember> 
     31        </gml:MultiLineString> 
     32      </topp:the_geom> 
     33      <topp:TYPE>highway</topp:TYPE> 
     34    </topp:tasmania_roads> 
     35  </gml:featureMember> 
     36  <gml:featureMember> 
     37    <topp:tasmania_roads fid="tasmania_roads.3"> 
     38      <topp:the_geom> 
     39        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     40          <gml:lineStringMember> 
     41            <gml:LineString> 
     42              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">147.300583,-41.637878 147.225815,-41.626938 147.183319,-41.619236 147.082367,-41.577755 147.031326,-41.565205 146.961487,-41.564186 146.924545,-41.568565 146.876328,-41.569614 146.783722,-41.56073 146.684937,-41.536232 146.614258,-41.478153 146.619995,-41.423958 146.582581,-41.365482 146.52478,-41.29541 146.477493,-41.277622 146.468582,-41.241478</gml:coordinates> 
     43            </gml:LineString> 
     44          </gml:lineStringMember> 
     45        </gml:MultiLineString> 
     46      </topp:the_geom> 
     47      <topp:TYPE>lane</topp:TYPE> 
     48    </topp:tasmania_roads> 
     49  </gml:featureMember> 
     50  <gml:featureMember> 
     51    <topp:tasmania_roads fid="tasmania_roads.4"> 
     52      <topp:the_geom> 
     53        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     54          <gml:lineStringMember> 
     55            <gml:LineString> 
     56              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">147.522247,-41.859921 147.551865,-41.927834 147.597321,-42.017418 147.578644,-42.113216 147.541656,-42.217743 147.468674,-42.22662</gml:coordinates> 
     57            </gml:LineString> 
     58          </gml:lineStringMember> 
     59        </gml:MultiLineString> 
     60      </topp:the_geom> 
     61      <topp:TYPE>highway</topp:TYPE> 
     62    </topp:tasmania_roads> 
     63  </gml:featureMember> 
     64  <gml:featureMember> 
     65    <topp:tasmania_roads fid="tasmania_roads.5"> 
     66      <topp:the_geom> 
     67        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     68          <gml:lineStringMember> 
     69            <gml:LineString> 
     70              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">146.103699,-41.171677 146.303619,-41.237202 146.362228,-41.236279 146.39418,-41.245384 146.443726,-41.244308 146.468582,-41.241478</gml:coordinates> 
     71            </gml:LineString> 
     72          </gml:lineStringMember> 
     73        </gml:MultiLineString> 
     74      </topp:the_geom> 
     75      <topp:TYPE>gravel</topp:TYPE> 
     76    </topp:tasmania_roads> 
     77  </gml:featureMember> 
     78  <gml:featureMember> 
     79    <topp:tasmania_roads fid="tasmania_roads.6"> 
     80      <topp:the_geom> 
     81        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     82          <gml:lineStringMember> 
     83            <gml:LineString> 
     84              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">145.856018,-41.08007 145.944839,-41.119896 146.037994,-41.150059 146.103699,-41.171677</gml:coordinates> 
     85            </gml:LineString> 
     86          </gml:lineStringMember> 
     87        </gml:MultiLineString> 
     88      </topp:the_geom> 
     89      <topp:TYPE>road</topp:TYPE> 
     90    </topp:tasmania_roads> 
     91  </gml:featureMember> 
     92  <gml:featureMember> 
     93    <topp:tasmania_roads fid="tasmania_roads.7"> 
     94      <topp:the_geom> 
     95        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     96          <gml:lineStringMember> 
     97            <gml:LineString> 
     98              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">147.468674,-42.22662 147.474945,-42.292259 147.467697,-42.301292 147.451828,-42.341656 147.424545,-42.378723 147.366013,-42.412552 147.345779,-42.432449 147.289322,-42.476475 147.264511,-42.503899 147.259918,-42.547539 147.249405,-42.614006 147.278351,-42.693249 147.284271,-42.757759 147.256744,-42.778393</gml:coordinates> 
     99            </gml:LineString> 
     100          </gml:lineStringMember> 
     101        </gml:MultiLineString> 
     102      </topp:the_geom> 
     103      <topp:TYPE>highway</topp:TYPE> 
     104    </topp:tasmania_roads> 
     105  </gml:featureMember> 
     106  <gml:featureMember> 
     107    <topp:tasmania_roads fid="tasmania_roads.8"> 
     108      <topp:the_geom> 
     109        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     110          <gml:lineStringMember> 
     111            <gml:LineString> 
     112              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">148.249252,-41.860851 148.234436,-41.901783 148.192123,-41.93721 148.155762,-41.953667 148.127731,-41.994537 148.053131,-42.100563</gml:coordinates> 
     113            </gml:LineString> 
     114          </gml:lineStringMember> 
     115        </gml:MultiLineString> 
     116      </topp:the_geom> 
     117      <topp:TYPE>road</topp:TYPE> 
     118    </topp:tasmania_roads> 
     119  </gml:featureMember> 
     120  <gml:featureMember> 
     121    <topp:tasmania_roads fid="tasmania_roads.9"> 
     122      <topp:the_geom> 
     123        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     124          <gml:lineStringMember> 
     125            <gml:LineString> 
     126              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">145.19754,-40.878323 145.246674,-40.86021 145.293289,-40.852802 145.465225,-40.897865 145.538498,-40.936264 145.554062,-40.939201 145.602112,-40.962936 145.646362,-40.98243 145.683838,-40.989883 145.710587,-40.996201 145.744293,-41.007545 145.801956,-41.041782 145.856018,-41.08007</gml:coordinates> 
     127            </gml:LineString> 
     128          </gml:lineStringMember> 
     129        </gml:MultiLineString> 
     130      </topp:the_geom> 
     131      <topp:TYPE>logging</topp:TYPE> 
     132    </topp:tasmania_roads> 
     133  </gml:featureMember> 
     134  <gml:featureMember> 
     135    <topp:tasmania_roads fid="tasmania_roads.10"> 
     136      <topp:the_geom> 
     137        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     138          <gml:lineStringMember> 
     139            <gml:LineString> 
     140              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">147.360001,-42.91993 147.348816,-42.93726 147.285049,-42.979027 147.220886,-42.995876 147.164429,-43.027004 147.068237,-43.06319 146.96463,-43.116447 146.949554,-43.17004 146.95369,-43.209591 146.964127,-43.224545 146.975723,-43.250484 146.980759,-43.2701 146.982605,-43.287716 146.970871,-43.31691 146.940521,-43.33812 146.943054,-43.362263 146.952194,-43.39278 146.955429,-43.423512</gml:coordinates> 
     141            </gml:LineString> 
     142          </gml:lineStringMember> 
     143        </gml:MultiLineString> 
     144      </topp:the_geom> 
     145      <topp:TYPE>road</topp:TYPE> 
     146    </topp:tasmania_roads> 
     147  </gml:featureMember> 
     148  <gml:featureMember> 
     149    <topp:tasmania_roads fid="tasmania_roads.11"> 
     150      <topp:the_geom> 
     151        <gml:MultiLineString srsName="http://www.opengis.net/gml/srs/epsg.xml#4326"> 
     152          <gml:lineStringMember> 
     153            <gml:LineString> 
     154              <gml:coordinates xmlns:gml="http://www.opengis.net/gml" decimal="." cs="," ts=" ">147.300583,-41.637878 147.372009,-41.695503 147.402588,-41.725574 147.444061,-41.749676 147.490433,-41.782482 147.506866,-41.795624 147.522919,-41.835609 147.522247,-41.859921</gml:coordinates> 
     155            </gml:LineString> 
     156          </gml:lineStringMember> 
     157        </gml:MultiLineString> 
     158      </topp:the_geom> 
     159      <topp:TYPE>highway</topp:TYPE> 
     160    </topp:tasmania_roads> 
     161  </gml:featureMember> 
     162  <gml:featureMember> 
     163    <topp:tasmania_roa