OpenLayers OpenLayers

Ticket #1297: 1297-r5851-A1.patch

File 1297-r5851-A1.patch, 9.9 kB (added by ahocevar, 1 year ago)

New patch with additional tests for minScale/maxScale, plus introduced ElseFilter in Format.SLD. With the corrected rule processing logic, the ElseFilter is crucial. Also renamed minScale and maxScale rule properties to minScaleDenominator and maxScaleDenominator for clarity and destinction from layer.maxScale and layer.minScale

  • examples/tasmania/sld-tasmania.xml

    old new  
    5151            </sld:Stroke> 
    5252          </sld:PolygonSymbolizer> 
    5353        </sld:Rule> 
     54        <sld:Rule> 
     55          <sld:Name>testRuleNameElse</sld:Name> 
     56          <sld:Title>title</sld:Title> 
     57          <sld:Abstract>Abstract</sld:Abstract> 
     58          <ogc:ElseFilter/> 
     59        </sld:Rule> 
    5460      </sld:FeatureTypeStyle> 
    5561    </sld:UserStyle> 
    5662 
     
    113119            </sld:Stroke> 
    114120          </sld:PolygonSymbolizer> 
    115121        </sld:Rule> 
    116  
     122        <sld:Rule> 
     123          <sld:Name>testRuleNameHoverElse</sld:Name> 
     124          <sld:Title>title</sld:Title> 
     125          <sld:Abstract>Abstract</sld:Abstract> 
     126          <ogc:ElseFilter/> 
     127        </sld:Rule> 
    117128      </sld:FeatureTypeStyle> 
    118129    </sld:UserStyle> 
    119130 
  • lib/OpenLayers/Format/SLD.js

    old new  
    176176        ); 
    177177 
    178178        if (ruleNodes.length > 0) { 
    179             var rules = userStyle.rules; 
    180             var ruleName; 
     179            var rule, ruleName; 
    181180            for (var i=0; i<ruleNodes.length; i++) { 
    182181                ruleName = this.parseProperty(ruleNodes[i], this.sldns, "Name"); 
    183                 rules.push(this.parseRule(ruleNodes[i], ruleName)); 
     182                var rule = (this.parseRule(ruleNodes[i], ruleName)); 
     183                if (rule instanceof OpenLayers.Rule) { 
     184                    // ElseFilter - insert at beginning 
     185                    userStyle.rules = [rule].concat(userStyle.rules); 
     186                } else { 
     187                    userStyle.rules.push(rule); 
     188                } 
    184189            } 
    185190        } 
    186191 
     
    206211        if (filter && filter.length > 0) { 
    207212            var rule = this.parseFilter(filter[0]); 
    208213        } else { 
    209             // rule applies to all features 
     214            // rule applies to all features (ElseFilter) 
    210215            var rule = new OpenLayers.Rule(); 
    211216        } 
    212217        rule.name = name; 
     
    218223            xmlNode, this.sldns, "MinScaleDenominator" 
    219224        ); 
    220225        if (minScale && minScale.length > 0) { 
    221             rule.minScale = parseFloat(this.getChildValue(minScale[0])); 
     226            rule.minScaleDenominator =  
     227                parseFloat(this.getChildValue(minScale[0])); 
    222228        } 
    223229         
    224230        // MaxScaleDenominator 
     
    226232            xmlNode, this.sldns, "MaxScaleDenominator" 
    227233        ); 
    228234        if (maxScale && maxScale.length > 0) { 
    229             rule.maxScale = parseFloat(this.getChildValue(maxScale[0])); 
     235            rule.maxScaleDenominator = 
     236                parseFloat(this.getChildValue(maxScale[0])); 
    230237        } 
    231238         
    232239        // STYLES 
  • lib/OpenLayers/Rule.js

    old new  
    2828    symbolizer: null, 
    2929     
    3030    /** 
    31      * APIProperty: minScale 
     31     * APIProperty: minScaleDenominator 
    3232     * {Number} or {String} minimum scale at which to draw the feature. 
    3333     * In the case of a String, this can be a combination of text and 
    3434     * propertyNames in the form "literal ${propertyName}" 
     
    3333     * In the case of a String, this can be a combination of text and 
    3434     * propertyNames in the form "literal ${propertyName}" 
    3535     */ 
    36     minScale: null, 
     36    minScaleDenominator: null, 
    3737 
    3838    /** 
    39      * APIProperty: maxScale 
     39     * APIProperty: maxScaleDenominator 
    4040     * {Number} or {String} maximum scale at which to draw the feature. 
    4141     * In the case of a String, this can be a combination of text and 
    4242     * propertyNames in the form "literal ${propertyName}" 
     
    4141     * In the case of a String, this can be a combination of text and 
    4242     * propertyNames in the form "literal ${propertyName}" 
    4343     */ 
    44     maxScale: null, 
     44    maxScaleDenominator: null, 
    4545 
    4646    /**  
    4747     * Constructor: OpenLayers.Rule 
  • lib/OpenLayers/Style.js

    old new  
    113113        } 
    114114        var style = OpenLayers.Util.extend({}, baseStyle); 
    115115         
    116         var draw = true; 
     116        var draw = this.rules.length == 0 ? true : false; 
    117117 
     118        var rule; 
    118119        for (var i=0; i<this.rules.length; i++) { 
     120            rule = this.rules[i]; 
    119121            // does the rule apply?         
    120             var applies = this.rules[i].evaluate(feature); 
     122            var applies = rule.evaluate(feature); 
     123             
     124            if (rule.minScaleDenominator || rule.maxScaleDenominator) { 
     125                var scale = feature.layer.map.getScale(); 
     126            } 
     127             
     128            // check if within minScale/maxScale bounds 
     129            if (rule.minScaleDenominator) { 
     130                applies = scale >= OpenLayers.Style.createLiteral( 
     131                        rule.minScaleDenominator, feature); 
     132            } 
     133            if (applies && rule.maxScaleDenominator) { 
     134                applies = scale < OpenLayers.Style.createLiteral( 
     135                        rule.maxScaleDenominator, feature); 
     136            } 
     137 
    121138            if (applies) { 
    122                 // check if within minScale/maxScale bounds 
    123                 var scale = feature.layer.map.getScale(); 
    124                 if (this.rules[i].minScale) { 
    125                     draw = scale > OpenLayers.Style.createLiteral( 
    126                             this.rules[i].minScale, feature); 
    127                 } 
    128                 if (draw && this.rules[i].maxScale) { 
    129                     draw = scale < OpenLayers.Style.createLiteral( 
    130                             this.rules[i].maxScale, feature); 
    131                 } 
    132                  
     139                draw = true; 
     140 
    133141                // determine which symbolizer (Point, Line, Polygon) to use 
    134142                var symbolizerPrefix = feature.geometry ? 
    135143                        this.getSymbolizerPrefix(feature.geometry) : 
     
    135143                        this.getSymbolizerPrefix(feature.geometry) : 
    136144                        OpenLayers.Style.SYMBOLIZER_PREFIXES[0]; 
    137145 
    138                 // now merge the style with the current style 
     146                // merge the style with the current style 
    139147                var symbolizer = this.rules[i].symbolizer[symbolizerPrefix]; 
    140148                OpenLayers.Util.extend(style, symbolizer); 
    141149            } 
  • tests/test_Style.html

    old new  
    1515    } 
    1616     
    1717    function test_Style_create(t) { 
    18         t.plan(5); 
     18        t.plan(10); 
    1919         
    2020        var map = new OpenLayers.Map("map"); 
    2121         
     
    2727         
    2828        var style = new OpenLayers.Style(baseStyle); 
    2929         
    30         var rule = new OpenLayers.Rule.FeatureId({ 
     30        var rule1 = new OpenLayers.Rule.FeatureId({ 
    3131                fids: ["1"], 
    3232                symbolizer: {"Point": {fillColor: "green"}}, 
    33                 maxScale: 2000000}); 
    34         style.addRules([rule]); 
     33                maxScaleDenominator: 500000}); 
     34        var rule2 = new OpenLayers.Rule.FeatureId({ 
     35                fids: ["1"], 
     36                symbolizer: {"Point": {fillColor: "yellow"}}, 
     37                minScaleDenominator: 500000, 
     38                maxScaleDenominator: 1000000}); 
     39        var rule3 = new OpenLayers.Rule.FeatureId({ 
     40                fids: ["1"], 
     41                symbolizer: {"Point": {fillColor: "red"}}, 
     42                minScaleDenominator: 1000000, 
     43                maxScaleDenominator: 2500000}); 
     44        style.addRules([rule1, rule2, rule3]); 
    3545         
    3646        var feature = new OpenLayers.Feature.Vector( 
    3747                new OpenLayers.Geometry.Point(3,5), 
     
    4555        map.addLayer(layer); 
    4656        map.setBaseLayer(layer); 
    4757 
    48         map.setCenter(new OpenLayers.LonLat(3,5), 8); 
    49         // at this scale, the feature should be visible 
     58        map.setCenter(new OpenLayers.LonLat(3,5), 10); 
     59        // at this scale, the feature should be green 
    5060        var createdStyle = style.createStyle(feature); 
    5161        t.eq(createdStyle.externalGraphic, "barbar.png", "Calculated property style correctly."); 
    5262        t.eq(createdStyle.display, "", "Feature is visible at scale "+map.getScale()); 
     63        t.eq(createdStyle.fillColor, "green", "Point symbolizer from rule applied correctly."); 
     64 
     65        map.setCenter(new OpenLayers.LonLat(3,5), 9); 
     66        // at this scale, the feature should be red 
     67        createdStyle = style.createStyle(feature); 
     68        t.eq(createdStyle.display, "", "Feature is visible at scale "+map.getScale()); 
     69        t.eq(createdStyle.fillColor, "yellow", "Point symbolizer from rule applied correctly."); 
     70 
     71        map.setCenter(new OpenLayers.LonLat(3,5), 8); 
     72        // at this scale, the feature should be yellow 
     73        createdStyle = style.createStyle(feature); 
     74        t.eq(createdStyle.display, "", "Feature is visible at scale "+map.getScale()); 
     75        t.eq(createdStyle.fillColor, "red", "Point symbolizer from rule applied correctly."); 
    5376 
    5477        map.setCenter(new OpenLayers.LonLat(3,5), 7); 
    5578        // at this scale, the feature should be invisible 
     
    5578        // at this scale, the feature should be invisible 
    5679        createdStyle = style.createStyle(feature); 
    5780        t.eq(createdStyle.display, "none", "Feature is invisible at scale "+map.getScale()); 
    58         t.eq(createdStyle.fillColor, "green", "Point symbolizer from rule for fid=\"1\" applied correctly."); 
     81        t.eq(createdStyle.fillColor, baseStyle.fillColor, "Point symbolizer from base style applied correctly."); 
    5982         
    6083        feature.fid = "2"; 
    6184        // now the rule should not apply