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 22 22 23 23 /** 24 24 * Property: context 25 * {Object} An optional object with properties that the rule and its26 * symbolizers' property values should be evaluatad against. If no27 * context is specified, feature.attributes will be used25 * {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. 28 28 */ 29 29 context: null, 30 30 … … 40 40 41 41 /** 42 42 * Property: symbolizer 43 * {Object} Hash of styles for this rule. Contains hashes of feature44 * s tyles. 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"] 45 45 */ 46 46 symbolizer: null, 47 47 -
lib/OpenLayers/Style.js
old new 41 41 rules: null, 42 42 43 43 /** 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 /** 44 52 * Property: defaultStyle 45 53 * {Object} hash of style properties to use as default for merging 46 54 * rule-based style symbolizers onto. If no rules are defined, … … 116 124 var appliedRules = false; 117 125 for(var i=0; i<rules.length; i++) { 118 126 rule = rules[i]; 119 context = rule.context;120 if (!context) {121 context = feature.attributes || feature.data;122 }123 127 // does the rule apply? 124 128 var applies = rule.evaluate(feature); 125 129 … … 128 132 elseRules.push(rule); 129 133 } else { 130 134 appliedRules = true; 131 this.applySymbolizer(rule, style, feature , context);135 this.applySymbolizer(rule, style, feature); 132 136 } 133 137 } 134 138 } … … 137 141 if(appliedRules == false && elseRules.length > 0) { 138 142 appliedRules = true; 139 143 for(var i=0; i<elseRules.length; i++) { 140 this.applySymbolizer(elseRules[i], style, feature , context);144 this.applySymbolizer(elseRules[i], style, feature); 141 145 } 142 146 } 143 147 … … 158 162 * rule - {OpenLayers.Rule} 159 163 * style - {Object} 160 164 * feature - {<OpenLayer.Feature.Vector>} 161 * context - {Object}162 165 * 163 166 * Returns: 164 167 * {Object} A style with new symbolizer applied. … … 163 166 * Returns: 164 167 * {Object} A style with new symbolizer applied. 165 168 */ 166 applySymbolizer: function(rule, style, feature , context) {169 applySymbolizer: function(rule, style, feature) { 167 170 var symbolizerPrefix = feature.geometry ? 168 171 this.getSymbolizerPrefix(feature.geometry) : 169 172 OpenLayers.Style.SYMBOLIZER_PREFIXES[0]; … … 168 171 this.getSymbolizerPrefix(feature.geometry) : 169 172 OpenLayers.Style.SYMBOLIZER_PREFIXES[0]; 170 173 171 var symbolizer = rule.symbolizer[symbolizerPrefix] ;174 var symbolizer = rule.symbolizer[symbolizerPrefix] || rule.symbolizer; 172 175 176 var context = this.context || feature.attributes || feature.data; 177 173 178 // merge the style with the current style 174 179 return this.createLiterals( 175 180 OpenLayers.Util.extend(style, symbolizer), context); … … 212 217 213 218 // check the default style 214 219 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); 220 221 221 222 // walk through all rules to check for properties in their symbolizer 222 223 var rules = this.rules; 223 var prefixes = OpenLayers.Style.SYMBOLIZER_PREFIXES;224 var symbolizer, value; 224 225 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; 232 236 } 233 237 } 234 238 } … … 236 240 }, 237 241 238 242 /** 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 /** 239 266 * APIMethod: addRules 240 267 * Adds rules to this style. 241 268 * -
lib/OpenLayers/StyleMap.js
old new 110 110 return OpenLayers.Util.extend(defaultSymbolizer, 111 111 this.styles[intent].createSymbolizer(feature)); 112 112 }, 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 }, 113 139 114 140 CLASS_NAME: "OpenLayers.StyleMap" 115 141 }); -
tests/Rule/test_Comparison.html
old new 38 38 } 39 39 40 40 function test_Comparison_evaluate(t) { 41 t.plan( 3);41 t.plan(4); 42 42 43 43 var rule = new OpenLayers.Rule.Comparison({ 44 44 property: "area", … … 62 62 t.eq(result, ruleResults[i], "feature "+i+ 63 63 " evaluates to "+result.toString()+" correctly."); 64 64 } 65 rule.context = { 66 area: 4998 67 } 68 var result = rule.evaluate(); 69 t.eq(result, true, "evaluation against custom rule context works."); 65 70 } 66 71 </script> 67 72 </head> -
tests/test_Style.html
old new 116 116 117 117 function test_Style_context(t) { 118 118 t.plan(1); 119 var context = {120 foo: "bar",121 size: 10};122 119 var rule = new OpenLayers.Rule.Comparison({ 123 120 type: OpenLayers.Rule.Comparison.LESS_THAN, 124 context: context,125 121 property: "size", 126 122 value: 11, 127 symbolizer: {"Point": {externalGraphic: "${ foo}.png"}}});123 symbolizer: {"Point": {externalGraphic: "${img1}"}}}); 128 124 var style = new OpenLayers.Style(); 125 style.context = { 126 "img1": "myImage.png" 127 }; 129 128 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"); 132 154 } 133 155 134 156 function test_Style_destroy(t) {
