OpenLayers OpenLayers

Ticket #1373: 1373-r6361-A0.patch

File 1373-r6361-A0.patch, 13.4 kB (added by ahocevar, 11 months ago)
  • examples/styles-unique.html

    old new  
     1<html xmlns="http://www.w3.org/1999/xhtml"> 
     2  <head> 
     3    <title>OpenLayers Styles Unique Value Styles Example</title> 
     4    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" /> 
     5    <style type="text/css"> 
     6        #map { 
     7            width: 800px; 
     8            height: 400px; 
     9            border: 1px solid black; 
     10        } 
     11    </style> 
     12    <script src="../lib/OpenLayers.js"></script> 
     13    <script type="text/javascript"> 
     14        var map, layer; 
     15 
     16        function init(){ 
     17            map = new OpenLayers.Map('map', {maxResolution:'auto'}); 
     18            var wms = new OpenLayers.Layer.WMS( "OpenLayers WMS", 
     19                "http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} ); 
     20            map.addLayer(wms); 
     21            map.setCenter(new OpenLayers.LonLat(0, 0), 0); 
     22             
     23            // create 20 random features with a random type attribute. The 
     24            // type attribute is a value between 0 and 2. 
     25            var features = new Array(20); 
     26            for (var i=0; i<20; i++) { 
     27                features[i] = new OpenLayers.Feature.Vector( 
     28                    new OpenLayers.Geometry.Point(Math.random()*360-180, Math.random()*180-90), 
     29                    {type: parseInt(Math.random()*3)} 
     30                ); 
     31            } 
     32             
     33            // create a styleMap with a custom default symbolizer 
     34            var styleMap = new OpenLayers.StyleMap({ 
     35                fillOpacity: 1, 
     36                pointRadius: 10 
     37            }); 
     38             
     39            // create a lookup table with different symbolizers for 0, 1 and 2 
     40            var lookup = { 
     41                0: {externalGraphic: "../img/marker-blue.png"}, 
     42                1: {externalGraphic: "../img/marker-green.png"}, 
     43                2: {externalGraphic: "../img/marker-gold.png"} 
     44            } 
     45             
     46            // add rules from the above lookup table, with the keyes mapped to 
     47            // the "type" property of the features, for the "default" intent 
     48            styleMap.addUniqueValueRules("default", "type", lookup); 
     49             
     50            layer = new OpenLayers.Layer.Vector('Points', { 
     51                styleMap: styleMap 
     52            }); 
     53             
     54            layer.addFeatures(features); 
     55            map.addLayer(layer); 
     56        } 
     57    </script> 
     58  </head> 
     59  <body onload="init()"> 
     60    <h1 id="title">Unique Value Styles Example</h1> 
     61 
     62    <div id="tags"></div> 
     63 
     64    <p id="shortdesc"> 
     65      Shows how to create a style based on unique feature attribute values. 
     66    </p> 
     67 
     68    <div id="map"></div> 
     69 
     70    <div id="docs"></div> 
     71  </body> 
     72</html> 
  • lib/OpenLayers/Rule.js

    old new  
    2222     
    2323    /** 
    2424     * Property: context 
    25      * {Object} An optional object with properties that the rule and its 
    26      * symbolizers' property values should be evaluatad against. If no 
    27      * context is specified, feature.attributes will be used 
     25     * {Object} An optional object with properties that the rule should be 
     26     * evaluatad against. If no context is specified, feature.attributes will 
     27     * be used. 
    2828     */ 
    2929    context: null, 
    3030 
     
    4040     
    4141    /** 
    4242     * Property: symbolizer 
    43      * {Object} Hash of styles for this rule. Contains hashes of feature 
    44      * styles. Keys are one or more of ["Point", "Line", "Polygon"] 
     43     * {Object} Symbolizer or hash of symbolizers for this rule. If hash of 
     44     * symbolizers, keys are one or more of ["Point", "Line", "Polygon"] 
    4545     */ 
    4646    symbolizer: null, 
    4747     
  • lib/OpenLayers/Style.js

    old new  
    4141    rules: null, 
    4242     
    4343    /** 
     44     * Property: context 
     45     * {Object} An optional object with properties that symbolizers' property 
     46     * values should be evaluatad against. If no context is specified, 
     47     * feature.attributes will be used 
     48     */ 
     49    context: null, 
     50 
     51    /** 
    4452     * Property: defaultStyle 
    4553     * {Object} hash of style properties to use as default for merging 
    4654     * rule-based style symbolizers onto. If no rules are defined, 
     
    116124        var appliedRules = false; 
    117125        for(var i=0; i<rules.length; i++) { 
    118126            rule = rules[i]; 
    119             context = rule.context; 
    120             if (!context) { 
    121                 context = feature.attributes || feature.data; 
    122             } 
    123127            // does the rule apply? 
    124128            var applies = rule.evaluate(feature); 
    125129             
     
    128132                    elseRules.push(rule); 
    129133                } else { 
    130134                    appliedRules = true; 
    131                     this.applySymbolizer(rule, style, feature, context); 
     135                    this.applySymbolizer(rule, style, feature); 
    132136                } 
    133137            } 
    134138        } 
     
    137141        if(appliedRules == false && elseRules.length > 0) { 
    138142            appliedRules = true; 
    139143            for(var i=0; i<elseRules.length; i++) { 
    140                 this.applySymbolizer(elseRules[i], style, feature, context); 
     144                this.applySymbolizer(elseRules[i], style, feature); 
    141145            } 
    142146        } 
    143147 
     
    158162     * rule - {OpenLayers.Rule} 
    159163     * style - {Object} 
    160164     * feature - {<OpenLayer.Feature.Vector>} 
    161      * context - {Object} 
    162165     * 
    163166     * Returns: 
    164167     * {Object} A style with new symbolizer applied. 
     
    163166     * Returns: 
    164167     * {Object} A style with new symbolizer applied. 
    165168     */ 
    166     applySymbolizer: function(rule, style, feature, context) { 
     169    applySymbolizer: function(rule, style, feature) { 
    167170        var symbolizerPrefix = feature.geometry ? 
    168171                this.getSymbolizerPrefix(feature.geometry) : 
    169172                OpenLayers.Style.SYMBOLIZER_PREFIXES[0]; 
     
    168171                this.getSymbolizerPrefix(feature.geometry) : 
    169172                OpenLayers.Style.SYMBOLIZER_PREFIXES[0]; 
    170173 
    171         var symbolizer = rule.symbolizer[symbolizerPrefix]
     174        var symbolizer = rule.symbolizer[symbolizerPrefix] || rule.symbolizer
    172175 
     176        var context = this.context || feature.attributes || feature.data; 
     177         
    173178        // merge the style with the current style 
    174179        return this.createLiterals( 
    175180                OpenLayers.Util.extend(style, symbolizer), context); 
     
    212217 
    213218        // check the default style 
    214219        var style = this.defaultStyle; 
    215         for (var i in style) { 
    216             if (typeof style[i] == "string" && style[i].match(/\$\{\w+\}/)) {   
    217                 propertyStyles[i] = true; 
    218             } 
    219         } 
     220        this.addPropertyStyles(propertyStyles, style); 
    220221 
    221222        // walk through all rules to check for properties in their symbolizer 
    222223        var rules = this.rules; 
    223         var prefixes = OpenLayers.Style.SYMBOLIZER_PREFIXES
     224        var symbolizer, value
    224225        for (var i=0; i<rules.length; i++) { 
    225             for (var s=0; s<prefixes.length; s++) { 
    226                 style = rules[i].symbolizer[prefixes[s]]; 
    227                 for (var j in style) { 
    228                     if (typeof style[j] == "string" && 
    229                             style[j].match(/\$\{\w+\}/)) { 
    230                         propertyStyles[j] = true; 
    231                     } 
     226            var symbolizer = rules[i].symbolizer; 
     227            for (var key in symbolizer) { 
     228                value = symbolizer[key]; 
     229                if (typeof value == "object") { 
     230                    // symbolizer key is "Point", "Line" or "Polygon" 
     231                    this.addPropertyStyles(propertyStyles, value); 
     232                } else { 
     233                    // symbolizer is a hash of style properties 
     234                    this.addPropertyStyles(propertyStyles, symbolizer); 
     235                    break; 
    232236                } 
    233237            } 
    234238        } 
     
    236240    }, 
    237241     
    238242    /** 
     243     * Method: addPropertyStyles 
     244     *  
     245     * Parameters: 
     246     * propertyStyles - {Object} hash to add new property styles to. Will be 
     247     *                  modified inline 
     248     * context        - {Object} look inside this hash for property styles 
     249     *  
     250     * Returns: 
     251     * {Object} propertyStyles hash 
     252     */ 
     253    addPropertyStyles: function(propertyStyles, context) { 
     254        var property; 
     255        for (var key in context) { 
     256            property = context[key]; 
     257            if (typeof property == "string" && 
     258                    property.match(/\$\{\w+\}/)) { 
     259                propertyStyles[key] = true; 
     260            } 
     261        } 
     262        return propertyStyles; 
     263    }, 
     264     
     265    /** 
    239266     * APIMethod: addRules 
    240267     * Adds rules to this style. 
    241268     *  
  • lib/OpenLayers/StyleMap.js

    old new  
    110110        return OpenLayers.Util.extend(defaultSymbolizer, 
    111111            this.styles[intent].createSymbolizer(feature)); 
    112112    }, 
     113     
     114    /** 
     115     * Method: addUniqueValueRules 
     116     * Convenience method to create comparison rules for unique values of a 
     117     * property. The rules will be added to the style object for a specified 
     118     * rendering intent. This method is a shortcut for creating something like 
     119     * the "unique value legends" familiar from well known desktop GIS systems 
     120     *  
     121     * Parameters: 
     122     * renderIntent - {String} rendering intent to add the rules to 
     123     * property     - {String} values of feature attributes to create the 
     124     *                rules for 
     125     * symbolizers  - {Object} Hash of symbolizers, keyed by the desired 
     126     *                property values  
     127     */ 
     128    addUniqueValueRules: function(renderIntent, property, symbolizers) { 
     129        var rules = []; 
     130        for (var value in symbolizers) { 
     131            rules.push(new OpenLayers.Rule.Comparison({ 
     132                type: OpenLayers.Rule.Comparison.EQUAL_TO, 
     133                property: property, 
     134                value: value, 
     135                symbolizer: symbolizers[value]})); 
     136        } 
     137        this.styles[renderIntent].addRules(rules); 
     138    }, 
    113139 
    114140    CLASS_NAME: "OpenLayers.StyleMap" 
    115141}); 
  • tests/Rule/test_Comparison.html

    old new  
    3838    } 
    3939     
    4040    function test_Comparison_evaluate(t) { 
    41         t.plan(3); 
     41        t.plan(4); 
    4242         
    4343        var rule = new OpenLayers.Rule.Comparison({ 
    4444                property: "area", 
     
    6262            t.eq(result, ruleResults[i], "feature "+i+ 
    6363                    " evaluates to "+result.toString()+" correctly."); 
    6464        } 
     65        rule.context = { 
     66            area: 4998 
     67        } 
     68        var result = rule.evaluate(); 
     69        t.eq(result, true, "evaluation against custom rule context works."); 
    6570    } 
    6671    </script>  
    6772</head>  
  • tests/test_Style.html

    old new  
    116116     
    117117    function test_Style_context(t) { 
    118118        t.plan(1); 
    119         var context = { 
    120             foo: "bar", 
    121             size: 10}; 
    122119        var rule = new OpenLayers.Rule.Comparison({ 
    123120            type: OpenLayers.Rule.Comparison.LESS_THAN, 
    124             context: context, 
    125121            property: "size", 
    126122            value: 11, 
    127             symbolizer: {"Point": {externalGraphic: "${foo}.png"}}}); 
     123            symbolizer: {"Point": {externalGraphic: "${img1}"}}}); 
    128124        var style = new OpenLayers.Style(); 
     125        style.context = { 
     126            "img1": "myImage.png" 
     127        }; 
    129128        style.addRules([rule]); 
    130         var styleHash = style.createSymbolizer(new OpenLayers.Feature.Vector()); 
    131         t.eq(styleHash.externalGraphic, "bar.png", "correctly evaluated rule against a custom context"); 
     129        var feature = new OpenLayers.Feature.Vector(); 
     130        feature.attributes = {size: 10}; 
     131        var styleHash = style.createSymbolizer(feature); 
     132        t.eq(styleHash.externalGraphic, "myImage.png", "correctly evaluated rule and calculated property styles from a custom context"); 
     133    } 
     134     
     135    function test_Style_findPropertyStyles(t) { 
     136        t.plan(4); 
     137        var rule1 = new OpenLayers.Rule({symbolizer: { 
     138            pointRadius: 3, 
     139            externalGraphic: "${foo}.bar" 
     140        }}); 
     141        var rule2 = new OpenLayers.Rule({symbolizer: {"Point": { 
     142            strokeWidth: "${foo}" 
     143        }}}); 
     144        var style = new OpenLayers.Style({ 
     145            strokeOpacity: 1, 
     146            strokeColor: "${foo}" 
     147        }); 
     148        style.addRules([rule1, rule2]); 
     149        var propertyStyles = style.findPropertyStyles(); 
     150        t.ok(propertyStyles.externalGraphic, "detected externalGraphic from rule correctly"); 
     151        t.ok(propertyStyles.strokeWidth, "detected strokeWidth from Point symbolizer correctly"); 
     152        t.ok(propertyStyles.strokeColor, "detected strokeColor from style correctly"); 
     153        t.eq(typeof propertyStyles.pointRadius, "undefined", "correctly detected pointRadius as non-property style"); 
    132154    } 
    133155 
    134156    function test_Style_destroy(t) {