OpenLayers OpenLayers

Ticket #1120 (closed task: fixed)

Opened 9 months ago

Last modified 5 months ago

users should be able to customize the select style per feature

Reported by: tschaub Assigned to:
Priority: minor Milestone: 2.6 Release
Component: general Version: 2.5
Keywords: Cc:
State: Complete

Description

Currently, a select control has one select style. If an application designer wants to have the selected style be different for different features, they should be able to do this. I'd like to rework how we store styles - until then, it would be nice to support custom select styles for features.

Attachments

selectStyle.patch (0.6 kB) - added by tschaub on 10/31/07 19:35:28.
allow for a selectStyle to be set on a feature
stylemap.diff (33.6 kB) - added by ahocevar on 02/08/08 19:58:25.
stylemap_new.patch (27.5 kB) - added by crschmidt on 02/08/08 23:20:11.
with fixed examples
stylemap.2.patch (31.9 kB) - added by tschaub on 02/09/08 14:55:17.
applied with fewer triggerEvents
stylemap.patch (34.0 kB) - added by ahocevar on 02/11/08 13:12:37.
This time I made sure that the patch is correct. Tests pass in IE6 and FF2, visual tests reveiled no errors.

Change History

10/31/07 19:35:28 changed by tschaub

  • attachment selectStyle.patch added.

allow for a selectStyle to be set on a feature

(in reply to: ↑ description ; follow-up: ↓ 2 ) 11/02/07 16:19:18 changed by ahocevar

Replying to tschaub:

I'd like to rework how we store styles - until then, it would be nice to support custom select styles for features.

Tim, for a more elegant way of storing styles, you might like the style framework I created for sld rendering (sandbox/ahocevar/sldRenderer). Since we were talking about it at the FOSS4G code sprint, there have been major improvements.

Although primarily created for sld rendering, it was designed open enough to work completely independent of any sld use cases. It provides a style class (OpenLayers.Style) with a defaultStyle and a defaultSelectStyle property. The minimum requirement for styling vector layers or features is to set those two properties.

In combination with the rules framework (OpenLayers.Rule and subclasses), styling can also be done dependant of map scale (using the minScaleDenominator and maxScaleDenominator properties) and attributive filters known from the OGC filter specification. Rules are no longer stored as Javascript eval snippets, they are now cleanly kept in classes that also allow for hierarchically stacked rule constructs.

(in reply to: ↑ 1 ) 11/02/07 17:13:16 changed by tschaub

Replying to ahocevar:

Replying to tschaub:

I'd like to rework how we store styles - until then, it would be nice to support custom select styles for features.

Tim, for a more elegant way of storing styles, you might like the style framework I created for sld rendering (sandbox/ahocevar/sldRenderer). Since we were talking about it at the FOSS4G code sprint, there have been major improvements.

Andreas, I totally agree. I regret not having had the chance to look it over yet. I'll make a point of doing that next week (thought it was going to be today).

12/15/07 13:50:23 changed by crschmidt

  • state set to Needs Discussion.

With the Style stuff in place, this is possible by using rules: I'm interested in seeing anything that we can't accomplish via the rules framework brought to the forefront.

01/22/08 17:19:17 changed by crschmidt

  • state changed from Needs Discussion to Needs More Work.

01/22/08 17:31:59 changed by ahocevar

  • type changed from feature to task.

01/26/08 11:28:18 changed by ahocevar

  • state changed from Needs More Work to Needs Discussion.

Here are some ideas on a StyleMap object that would satisfy the requirement and others as well.

This is what tschaub proposed in #1297:

At some point, I'd like to see features get a style map with keys that mapped to arrays of styles. I'm sure this will get crschmidt's hackles up, but I'd rather have simple constructors and complex objects than just simple objects (I'm talking here about a more complex style class that has a nice simple constructor for people who only want orange lines).

I agree with this in principle, although I would see the StyleMap object's purpose to manage styles, not arrays of styles. The reason is that the array of styles resulting from applying a SLD UserStyle will differ on a per-feature and per-render base, depending on the fules for feature properties and map scale. But the result would be the same. A yet-to-define method in the StyleMap object before rendering a feature will return an array of styles, which is the symbolizers for which style rules applied to:

!StyleMap.getStyle = function(/*Feature.Vector*/ feature, /*String*/renderIntent) {
    return /*Array*/ styles
}

This method would look up the appropriate style for the passed renderIntent (e.g. "select"), and call the Style's creatStyle method with the {extend: false} option (see the latest patch for #1297), and return the resulting styles array.

The constructor for the StyleMap object could have a simple signature for users who do not care about fancy style processing, with just a style hash as parameter. This would then be mapped to the "default" renderIntent key. A more sophisticated signature of the constructor would allow to pass a hash map of style hashes, keyed by renderIntent. Similar constructor signatures could take a single Style object as "default" renderIntent, and a hash of Style objects.

The nice thing about this would be that all methods for translating between the different style specifications could be encapsulated in the StyleMap class.

So all style information a feature or layer needs would then in a single object.

Does this make sense?

01/26/08 11:34:54 changed by ahocevar

Another idea:

The StyleMap object could also be used to store what is currently called originalStyle (used in Control.SelectFeature): When the getStyle method is called, the passed renderIntent will be stored in the object. Subsequent calls of getStyle without a renderIntent parameter will use this renderIntent, until it is called again with a new renderIntent.

The layer.drawFeature method would call it without renderIntent by default, to preserve the current style when called by moveTo. The layer.drawFeature method would have a renderIntent parameter, which will be passed through when called from other methods, e.g. Control.SelectFeature.select/unselect.

01/27/08 16:46:12 changed by elemoine

ahocevar, all this StyleMap-based design sounds very valuable to me!

02/08/08 17:34:55 changed by ahocevar

  • state changed from Needs Discussion to Review.

The stylemap.diff patch creates a new object, OpenLayers.StyleMap, which is now used as a container for styles on vector layers. It basically has the features described in the discussion above.

02/08/08 19:58:25 changed by ahocevar

  • attachment stylemap.diff added.

02/08/08 23:20:11 changed by crschmidt

  • attachment stylemap_new.patch added.

with fixed examples

02/09/08 14:55:17 changed by tschaub

  • attachment stylemap.2.patch added.

applied with fewer triggerEvents

02/10/08 15:28:18 changed by elemoine

Thanks for this excellent work Andreas. My review comments below.

StyleMap

  • I'd like that the return value of createSymbolizer() be commented

Layer.Vector

  • Shouldn't styleMap be an API property?

Feature.Vector

  • Can application code change a feature's renderIntent value before calling layer.drawFeature(feature)? If so, shouldn't renderIntent be an API property?

Control.SelectFeature

  • If application code can indeed change a feature's renderIntent I'm a bit concerned with having unselect() use "default" as the render intent. Actually, I realize than the renderIntent property of Feature.Vector is not an API property, it just reflects the current rendered style of the feature. Maybe this could be made more explicit.

examples/openmnnd.html

  • You changed the value of OpenLayers.ProxyHost. Was it on purpose?

examples/sld.html

  • The waterStyle var is no longer used so it can be removed
  • I played with this example but I guess it's broken: the default rendering is not as expected and nothing happens when changing the styler

examples/select-feature.html

  • I know you haven't modified that file, but I noticed that this example is broken: feature selection does no longer change the rendering style

examples/modify-feature.html

  • Same comment as for the select-feature.html example

02/11/08 08:50:12 changed by ahocevar

  • state changed from Review to Needs More Work.

Eric, thank you for the review! There is a problem with the patches here. For unknown reasons, I am unable to create a diff between the sandbox where this was developed and the trunk. Everything works in the sandbox. I will try to create a correct patch.

There are no APIProperties because we are close to a release. We decided to let things settle down and define APIProperties later.

The proxy path was modified by crschmidt, I think both locations should work.

The comment to the createSymbolizer() method will be added.

02/11/08 09:13:24 changed by crschmidt

The proxypath modification was a mistake; it should be removed from the patch. I accidentally left it in from testing.

02/11/08 10:08:56 changed by ahocevar

  • state changed from Needs More Work to Review.

02/11/08 13:12:37 changed by ahocevar

  • attachment stylemap.patch added.

This time I made sure that the patch is correct. Tests pass in IE6 and FF2, visual tests reveiled no errors.

02/12/08 13:53:39 changed by tschaub

  • state changed from Review to Commit.

Andreas, thanks for the work on this. I think it looks in good shape now. Please commit. I look forward to adding a few convenience methods and getting folks to start taking advantage of this functionality. Regarding API property, it will likely make sense to add it later - but the idea is that people won't have to touch it.

02/12/08 18:05:47 changed by ahocevar

  • status changed from new to closed.
  • state changed from Commit to Complete.
  • resolution set to fixed.

(In [6240]) "users should be able to customize the select style per feature": Created a StyleMap class which stores all styles that are needed for a layer. Controls that need to render features differently can now just give a render intent (e.g. "default", "select" or "temporary") to the layer's drawFeature method, instead of having extra style informations like Control.SelectFeature.selectStyle. Existing application that set layer.style or feature.style are still supported, but both of these style properties are now null by default. r=crschmidt,elemoine,tschaub (closes #1120)