Add highlighting capabilities to the renderer

Description

Geotools 1 was handling highlighting with managers and listeners. Renderer in Geotools 2 should provides similar behavior.

Environment

None

Activity

Show:
codehaus
April 10, 2015, 3:28 PM

CodeHaus Comment From: desruisseaux - Time: Thu, 15 Jan 2004 06:03:03 -0600
---------------------
In current version of the software, invoking RenderedLayer.repaint() will not automatically take in account the changes in the rules and filters. This repaint() method is similar to Swing's JComponent.repaint(): it said that the component need to be repainted, but doesn't said why. It may be for an other reason than a rule change, so checking all rules unconditionally would probably be inefficient. The usual course of action (as I see it) is:

  • Some event change RenderedLayer state (for example because a rule changed).

  • Only after the RenderedLayer is updated and ready for a new rendering, the event invokes repaint().

So, updating RenderedLayer state is left to the implementation (current RenderedGeometries are somewhat immutable, but it should be fixable).

I like the idea of defining a new kind of layer interacting with the rendering properties directly, rather than through rules and filters. It would probably be much faster. Furthermore, on a conceptual point of view, it seems more comfortable to me. It seems to me that highlighting a feature should not change fundamentally its styling, since it is only a temporary event due to mouse cursor current position; the feature will retrieve its natural styling as soon as the mouse move away.

A possible approach is to subclass SLDRenderedGeometries (for example SelectableRenderedGeometries) and overrides the paint(Graphics2D, Shape, Style2D) method. If the shape.contains(mousePosition) returns true, then the method invokes super.paint(graphics, shape, highlightStype) where highlightStype is the style to use for rendering highlighted features. Otherwise, the usual super.paint(graphics, shape, stype) is invoked.

This is probably the simplest approach. But checking for shape.contains(mousePosition) for every feature is probably costly. Maybe the cost can been kept reasonable if the number of selectable features is low (unselectable features would still in other RenderedLayers). I need some though in order to figure out how and where a R-Tree could fit in this approach. The problem is that the Shape argument may or may not be one of the Geometries given to the setGeometry method (depending on current map scale and rendering mode). If we need the original Geometry object, some mechanism would be required in order to keep trace of them.

In summary my proposal would be: put the minimum amount of selectable features in SelectableRenderedGeometries layer, try the simple implementation described above (using shape.contains(mousePosition)), benchmark how much time is spent in the contains method and lets try to figure out how we could optimize it. Do you think it could work?

codehaus
April 10, 2015, 3:28 PM

CodeHaus Comment From: - Time: Tue, 20 Jan 2004 11:44:22 -0600
---------------------
I'm glad you think the idea of having a special kind of layer

(with features you can access directly) is a good one. Your

suggestion of overriding SLDRenderedGeometries seems sensible,

although it keeps the highlight mechanism entirely internal to

geotools.

We were thinking of a slightly more general support for

highlighting, where a mouse-over created an event that external

code could respond to, and where the external code was able to

modify the rendering properties of the features in response. What

do you think about this?

The original geotools (geotools 1) had this kind of model, didn't

it? Do you think it would be possible to create this kind of

behaviour in GT2, and do you think it's a good idea?

codehaus
April 10, 2015, 3:28 PM

CodeHaus Comment From: jelliott - Time: Tue, 20 Jan 2004 11:45:27 -0600
---------------------
I wasn't logged in, but it was me that wrote the last message!

codehaus
April 10, 2015, 3:28 PM

CodeHaus Comment From: desruisseaux - Time: Thu, 22 Jan 2004 15:55:57 -0600
---------------------
Yes, the more general model make a lot of sense to me and I would like to go that way. Unfortunately, it is pretty hard for me to give useful advice at this time. I would need to go back in the code now. I would really like to work on this issue with you, but will be unable at this time (I'm stuck in a thesis, unfortunately).

One approach (just some ideas) may be the following:

The SelectableGeometries (or whatever name) layer implements MouseMotionListener;

The mouseMoved(MouseEvent) method find which geometry is selected, and then there is a choice:

  • It invokes a 'geometrySelected(Geometry)' or 'geometryRollOver(Geometry)' method, which the user can overrides

  (it may also be a Feature argument rather than a Geometry one);

  • Or it invokes a list of listeners registered by the user.

The event's source is the SelectableGeometries. This SelectableGeometries layer could have some methods like 'setHighlightColor', or whatever is useful for the task.

The main difficulty I have with this approach is: how to map drawing Shape (which may come from a clipped geometry) to the original Geometry or Feature? Maybe the best way would be to add a 'source' field right into the org.geotools.j2d.geom.Geometry class.

Would it be possible to begin with a simpler implementation (like the one discussed previously) and revisit the event paradigm later? Again, I would like to examine how GO-1 do that.

codehaus
April 10, 2015, 3:28 PM

CodeHaus Comment From: aaime - Time: Sun, 28 Mar 2010 05:03:08 -0500
---------------------
Mass closing all go-1 related issues as the module does not exist anymore

Assignee

Unassigned

Reporter

codehaus

Triage

None

Components

Affects versions

Priority

Medium
Configure