[OpenLayers-Dev] Rule subclasses and 2.6

Tim Schaub tschaub at openplans.org
Sat Apr 5 17:30:16 EDT 2008


Here's the problem.

Currently, you can do:

var popRule = new OpenLayers.Rule.Comparison({
     minScaleDenominator: 50000,
     symbolizer: {fillColor: "red"},
     type: OpenLayers.Rule.Comparison.GREATER_THAN_OR_EQUAL_TO,
     property: "Population",
     value: 10000
});

var catRule = new OpenLayers.Rule.Comparison({
     minScaleDenominator: 100000,
     symbolizer: {fillColor: "blue"},
     type: OpenLayers.Rule.Comparison.EQUAL_TO,
     property: "Category",
     value: "city"
});

var logRule = new OpenLayers.Rule.Logical({
     type: OpenLayers.Rule.Locical.AND,
     rules: [popRule, catRule]
});

Now, when you create a style using the logRule, your expectations are 
likely not to be met.

Logical filters have child filters.  Filters do not have scale 
constraints or symbolizers.

I know you could say that the OpenLayers.Rule.Logical wrapper strips the 
scale constraints and symbolizers from the child rules, but I think this 
defies logic.  I've already been asked if symbolizers from child rules 
extend symbolizers of the parent rule.  This is not convenient, this is 
confusing.

If we want convenience methods (shortcuts to the code I proposed below), 
I suggest we put them elsewhere (on OpenLayers.Rule, OpenLayers.Style, 
or OpenLayers.StyleMap).

Frankly, I'd rather wait until we identify common patterns before 
deciding on what is going to be the most convenient API.  I know that 
Andreas was trying to simplify the style stuff and felt that adding too 
many classes would make it harder to get the code in.  I think we'd all 
rather see it done right.  Convenience can come later*.


Tim

* The most useful shortcuts I see are for adding groups of rules to a 
style map.  The addUniqueValueRules mehtod is an example of this.  Other 
common rule groupings are class breaks, equal interval, proportional 
symbol, etc.  Having methods to quickly produce groups of rules for 
these would vastly improve style creation.  If you have to add one rule 
at a time, you're doing something wrong.

OpenLayers.StyleMap.addRuleGroup({
     intents: ["default"], // this would be the default
     type: OpenLayers.Rule.CLASS_BREAKS,
     property: "population",
     values: [0, 10000, 20000, 30000],
     symbolizers: array // length of values.length -1

});

etc.


Christopher Schmidt wrote:
> On Sat, Apr 05, 2008 at 11:13:31AM -0600, Tim Schaub wrote:
>> The OpenLayers.Rule class comes from the sld:Rule element.  A rule in 
>> SLD has optional constraints on scale (sld:MinScaleDenominator and 
>> sld:MaxScaleDenominator), typically has symbolizers (for Point, Line, 
>> Polygon, etc), and optionally has an ogc:Filter element.
> 
> Right.
> 
>> In the Filter Encoding spec (where you find the description of 
>> ogc:Filter elements), there are a number of types of filters.  These 
>> include comparison filters, feature id filters, and logical filters.  In 
>> OpenLayers (currently) the subclasses of OpenLayers.Rule map directly to 
>> these types of ogc:Filter.
> 
> Right.  
> 
>> The problem is not only one of naming.  An sld:Rule *has* an ogc:Filter. 
>>    So a rule can have a feature id filter for example.  In OpenLayers, 
>> an OpenLayers.Rule.FeatureId *is* a rule.
> 
> Sure. It's a combination of the Filter and Rule into a single object for
> convenience, right? There's no replacement for 
> OpenLayers.Rule.FeatureID that wouldn't do the same thing the current
> one does, is there?
> 
>> The difference is that rules have things like scale constraints and 
>> symbolizers.  Filters do not have scale constraints and symbolizers.  A 
>> filter is the child of a rule.  A filter is not a rule.
> 
> Understood. So currently (as far as I understand it), we have Rule,
> which encompasses Rule + Filter, and in the future, we could make the
> seperation into Rule and Filter explicit: So Rule.FeatureID would
> (internally) create a Filter.FeatureID with the properties that are
> specified in the filter.
> 
>> So, OpenLayers.Rule.FeatureId would become OpenLayers.Filter.FeatureId. 
> 
> Sort of, I think? OpenLayers.Rule.FeatureId would become OpenLayers.Rule
> + OpenLayers.Filter.FeatureId?
> 
>>   This filter could be used for more than just styling - it could, for 
>> example, be serialized and used in a WFS query.  This has nothing to do 
>> with styling.
> 
> Agreed. Filters are valuable.
> 
>> So yes, your cambridge example would break in the future.  Instead you 
>> would do something like:
>>
>> var rule = new OpenLayers.Rule({
>>      symbolizer: {"Point": {"fillColor": "fuchsia"}},
>>      filter: new OpenLayers.Filter.Comparison({
>>          type: OpenLayers.Filter.Comparison.GREATER_THAN_OR_EQUAL_TO,
>>          property: "Population",
>>          value: 10000
>>      })
>> });
> 
> Alternatively, we add Filters, and make Rule subclasses a convenience
> method that takes everything but the Rule-specific properties and passes
> them onto the Filter? 
> 
>> var rule = new OpenLayers.Rule({
>>      symbolizer: {"Point": {"fillColor": "fuchsia"}},
>>      filter: new OpenLayers.Filter.Logical({
>>          type: OpenLayers.Filter.Logical.AND,
>>          filters: [
>>              new OpenLayers.Filter.Comparison({
>>                  type: OpenLayers.Filter.Comparison.LESS_THAN,
>>                  property: "Population",
>>                  value: 100000,
>>              }),
>>              new OpenLayers.Filter.Comparison({
>>                  type: OpenLayers.Filter.Comparison.GREATER_THAN,
>>                  property: "Population",
>>                  value: 0,
>>              })
>>          ]
>>      })
>> });
>>
>> The difference is that rules have symbolizers and a filter (optionally). 
>>   Filters do not have symbolizers.  A logical filter has child filters.
> 
> Right. To me, this doesn't indicate that we should get rid of
> Rule.FeatureID: instead, that we should make it a wrapper around
> Rule+Filter. 
> 
>> My question was whether we wanted to
>> 1) change this before 2.6, or
>> 2) change this after 2.6.
> 
> Well, my position is "Neither": A rule is a combination of symbolizer +
> Filters. The only thing is that right now, we define the filter
> properties directly in the creation of the Rule, and we can instead use
> those properties to create Filters in the future.
> 
> It seems like option 1) above sets us back another month in the process,
> because we need to abandon the RC at that point, and move back to step 1
> in the release process: The entire point of an RC is "We think that if
> there are no bugs, we can ship this". Perhaps this concept hasn't been
> made clear enough in our discussions in the past: I had assumed that "no
> non-regression changes after we hit RC" was obvious, but it's possible
> that meaning has not actually been stated.
> 
> So, I'm a big -1 on changing to Rules and Filters before 2.6.
> 
>> If we change after 2.6, then we decide whether to wait for 3.0 or 
>> whether to release with the rule subclasses as not part of the API 
>> (subject to change).
> 
> I'm -0 on removing them from the API, since we then move them out of our
> documentation and examples, and they become for most intents and
> purposes unusable until 2.7. (Not having them in the examples being the
> biggest blocker to people actually using them, I think.) 
> 
> "Wait for 3.0" is a possibility, I guess, but I'd like to understand why
> we can't provide Rule.FeatureId as a convenience method: is there
> something that's likely to confuse users about it? I guess I'm -0 on
> removing Rule subclasses even in 3.0, simply because doing so requires
> an even deeper understanding of the underlying aspects of the building
> blocks than I think we need to force users to have... 
> 
>> I'm happy to write up a patch if we want to do this before 2.6 (which I 
>> do of course*).
> 
> If you had said all this 4 weeks ago, I would have said "write a patch
> for 2.6, but I'd prefer to leave Rule subclasses as convenience
> methods going forward." 
> 
> Today, I'll say "I prefer to leave the Rule subclasses as convenience
> methods going forward; because of that, we can skip the patch."
> 
> If I'm lonely in my position, then I'm willing to accept that we
> should pull Rules from the API for this release, grudgingly. 
> 
>> * In the future, I'm also in favor of branching in advance of a release 
>> so we don't release brand spanking new features with unstable interfaces.
> 
> I understand that this is likely led in large part by the recent style
> work that TOPP has put in, but prior to that, the last commit to rules
> was in early February...  and prior to *that*, the last functional
> change to rules was the initial commit in mid December. At what point
> would branching early have helped? Was it known in December that someone
> was going to be working seriously on SLD Styles/Rules/Filters in April?
> If so, would that have changed our release plan for the features? 
> 
> Maintaining stable APIs hasn't actually been that painful, I don't
> think. There's extra code, yes. But I don't see how that extra code
> hurts the end product. We don't spend much of our time supporting
> deprecated APIs: even ones that don't have direct replacements are
> pretty much abandoned by most users. (How many users still use
> MouseToolbar instead of NavToolbar, despite the fact that the former has
> functionality that the latter doesn't?) Have we really avoided many
> changes because backwards compatibility? Or just made our development
> slightly more complex because of it?  
> 
> Regards,




More information about the Dev mailing list