From 2f0382e6f60bbb4bf69b5264574ec7ee05e4c4a6 Mon Sep 17 00:00:00 2001 From: ahocevar Date: Thu, 28 Feb 2008 17:57:37 +0000 Subject: [PATCH] * Style and Rule now have separate context properties * new convenience method addUniqueValueRules in OL.!StyleMap. This can actually be used to achieve what I was trying to show in the example of this ticket's description. * some refactoring of OL.Style to remove duplicate code (with tests) * a new example showing how to add a "unique value" legend to a point layer using the new addUniqueValueRules method * Rule.symbolizer can now also be just a symbolizer, instead of a hash of symbolizers keyed by "Point", "Line", "Polygon". This will make things even simpler (as can be seen in the styles-unique.html example) r=tschaub (closes #1373) git-svn-id: http://svn.openlayers.org/trunk/openlayers@6396 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf --- examples/styles-unique.html | 72 +++++++++++++++++++++++++++++++++ lib/OpenLayers/Rule.js | 10 ++--- lib/OpenLayers/Style.js | 71 ++++++++++++++++++++++---------- lib/OpenLayers/StyleMap.js | 26 ++++++++++++ tests/Rule/test_Comparison.html | 7 +++- tests/test_Style.html | 36 +++++++++++++---- 6 files changed, 187 insertions(+), 35 deletions(-) create mode 100644 examples/styles-unique.html diff --git a/examples/styles-unique.html b/examples/styles-unique.html new file mode 100644 index 0000000000..50ecb4f6c7 --- /dev/null +++ b/examples/styles-unique.html @@ -0,0 +1,72 @@ + + + OpenLayers Styles Unique Value Styles Example + + + + + + +

Unique Value Styles Example

+ +
+ +

+ Shows how to create a style based on unique feature attribute values. +

+ +
+ +
+ + diff --git a/lib/OpenLayers/Rule.js b/lib/OpenLayers/Rule.js index 4cb5bb1b7b..439de1be16 100644 --- a/lib/OpenLayers/Rule.js +++ b/lib/OpenLayers/Rule.js @@ -22,9 +22,9 @@ OpenLayers.Rule = OpenLayers.Class({ /** * Property: context - * {Object} An optional object with properties that the rule and its - * symbolizers' property values should be evaluatad against. If no - * context is specified, feature.attributes will be used + * {Object} An optional object with properties that the rule should be + * evaluatad against. If no context is specified, feature.attributes will + * be used. */ context: null, @@ -40,8 +40,8 @@ OpenLayers.Rule = OpenLayers.Class({ /** * Property: symbolizer - * {Object} Hash of styles for this rule. Contains hashes of feature - * styles. Keys are one or more of ["Point", "Line", "Polygon"] + * {Object} Symbolizer or hash of symbolizers for this rule. If hash of + * symbolizers, keys are one or more of ["Point", "Line", "Polygon"] */ symbolizer: null, diff --git a/lib/OpenLayers/Style.js b/lib/OpenLayers/Style.js index 95e7d8dd97..90997575cf 100644 --- a/lib/OpenLayers/Style.js +++ b/lib/OpenLayers/Style.js @@ -40,6 +40,14 @@ OpenLayers.Style = OpenLayers.Class({ */ rules: null, + /** + * Property: context + * {Object} An optional object with properties that symbolizers' property + * values should be evaluatad against. If no context is specified, + * feature.attributes will be used + */ + context: null, + /** * Property: defaultStyle * {Object} hash of style properties to use as default for merging @@ -116,10 +124,6 @@ OpenLayers.Style = OpenLayers.Class({ var appliedRules = false; for(var i=0; i 0) { appliedRules = true; for(var i=0; i} - * context - {Object} * * Returns: * {Object} A style with new symbolizer applied. */ - applySymbolizer: function(rule, style, feature, context) { + applySymbolizer: function(rule, style, feature) { var symbolizerPrefix = feature.geometry ? this.getSymbolizerPrefix(feature.geometry) : OpenLayers.Style.SYMBOLIZER_PREFIXES[0]; - var symbolizer = rule.symbolizer[symbolizerPrefix]; + var symbolizer = rule.symbolizer[symbolizerPrefix] || rule.symbolizer; + var context = this.context || feature.attributes || feature.data; + // merge the style with the current style return this.createLiterals( OpenLayers.Util.extend(style, symbolizer), context); @@ -212,29 +217,51 @@ OpenLayers.Style = OpenLayers.Class({ // check the default style var style = this.defaultStyle; - for (var i in style) { - if (typeof style[i] == "string" && style[i].match(/\$\{\w+\}/)) { - propertyStyles[i] = true; - } - } + this.addPropertyStyles(propertyStyles, style); // walk through all rules to check for properties in their symbolizer var rules = this.rules; - var prefixes = OpenLayers.Style.SYMBOLIZER_PREFIXES; + var symbolizer, value; for (var i=0; i diff --git a/tests/test_Style.html b/tests/test_Style.html index c0a5762ab8..a6541d8a6e 100644 --- a/tests/test_Style.html +++ b/tests/test_Style.html @@ -116,19 +116,41 @@ function test_Style_context(t) { t.plan(1); - var context = { - foo: "bar", - size: 10}; var rule = new OpenLayers.Rule.Comparison({ type: OpenLayers.Rule.Comparison.LESS_THAN, - context: context, property: "size", value: 11, - symbolizer: {"Point": {externalGraphic: "${foo}.png"}}}); + symbolizer: {"Point": {externalGraphic: "${img1}"}}}); var style = new OpenLayers.Style(); + style.context = { + "img1": "myImage.png" + }; style.addRules([rule]); - var styleHash = style.createSymbolizer(new OpenLayers.Feature.Vector()); - t.eq(styleHash.externalGraphic, "bar.png", "correctly evaluated rule against a custom context"); + var feature = new OpenLayers.Feature.Vector(); + feature.attributes = {size: 10}; + var styleHash = style.createSymbolizer(feature); + t.eq(styleHash.externalGraphic, "myImage.png", "correctly evaluated rule and calculated property styles from a custom context"); + } + + function test_Style_findPropertyStyles(t) { + t.plan(4); + var rule1 = new OpenLayers.Rule({symbolizer: { + pointRadius: 3, + externalGraphic: "${foo}.bar" + }}); + var rule2 = new OpenLayers.Rule({symbolizer: {"Point": { + strokeWidth: "${foo}" + }}}); + var style = new OpenLayers.Style({ + strokeOpacity: 1, + strokeColor: "${foo}" + }); + style.addRules([rule1, rule2]); + var propertyStyles = style.findPropertyStyles(); + t.ok(propertyStyles.externalGraphic, "detected externalGraphic from rule correctly"); + t.ok(propertyStyles.strokeWidth, "detected strokeWidth from Point symbolizer correctly"); + t.ok(propertyStyles.strokeColor, "detected strokeColor from style correctly"); + t.eq(typeof propertyStyles.pointRadius, "undefined", "correctly detected pointRadius as non-property style"); } function test_Style_destroy(t) {