Ticket #1666 (closed feature: fixed)

Opened 5 years ago

Last modified 4 years ago

One Single, Mother Of All Vector Layers

Reported by: euzuro Owned by: ahocevar
Priority: major Milestone: 2.8 Release
Component: general Version: 2.6
Keywords: Cc:
State: Complete

Description

To solve the "I can't click on vectors if they are not in the topmost layer", maybe we could design a way in which multiple vector layers all share a single SVG/VML/Canvas element.

Complexity level on this one is high, but might be helpful.

Attachments

singleroot.patch Download (17.5 KB) - added by ahocevar 4 years ago.
singleroot.2.patch Download (21.2 KB) - added by ahocevar 4 years ago.
new patch with better design and workarounds for the usual IE annoyances
singleroot.3.patch Download (20.8 KB) - added by ahocevar 4 years ago.
fixed redraw issues in IE - this time in a more elegant way
singleroot.4.patch Download (22.2 KB) - added by ahocevar 4 years ago.
layer visibility issues are fixed now
singleroot.5.patch Download (23.1 KB) - added by ahocevar 4 years ago.
fixed issue with Layer.WFS caused ba Layer.Markers mixin overriding Layer.Vector's display method
singleroot.6.patch Download (27.0 KB) - added by ahocevar 4 years ago.
singleroot.6-with-selectionKey.patch Download (31.3 KB) - added by danring 4 years ago.
added 'selectionKey' option to Control/SelectFeature.js
singleroot.7.patch Download (33.3 KB) - added by ahocevar 4 years ago.
new patch with unit tests
singleroot.7.2.patch Download (33.4 KB) - added by ahocevar 4 years ago.
new patch with unit tests
1666-compat.patch Download (6.4 KB) - added by ahocevar 4 years ago.
Better backwards compatibility

Change History

  Changed 5 years ago by openlayers

This is the first attempt to implement the "One Single, Mother Of All Vector Layers" approach as described in issue #1666. See details on the project page  http://ol.m-click.ws

- the patch is tested with version 2.7 and trunk
- it works fine in our application (no performance issues)
- no BC breaks
- of course needs testing (VML)
- a new "sublayer" switch has to be added to the OL layerswitch control

Please review and comment. (matt)

  Changed 5 years ago by elemoine

Thanks. Is the patch available somewhere?

  Changed 4 years ago by ahocevar

Just a few thoughts here:

One common renderer root for all vector layers would result in vector layers not being part of the layer stack, so moving layers up and down in the layer stack would not work any more. Vector layers would always be on top of other layers.

Since we do feature selection using the SelectFeature control, which already moves the layer passed to it's constructor to the top of all layers, we could modify the SelectFeature control to take an array of vector layers instead of a layer as constructor argument. The control would then work on all these layers.

The challenge here would be that for moving these layers to the top, there has to be a renderer root at the top of all layers, and the root elements of each layer would have to be moved from the layer's renderer root to this common on-top root. Maybe a special layer type would work best for that? And vector layers would have to be modified so their root node could be moved to and from this special layer.

  Changed 4 years ago by ahocevar

The patch singleroot.patch does what I have proposed above. As it turned out, the only class to change was Control.SelectFeature.

This control now takes either one layer or an array of layers as the first constructor argument. It works with all renderers.

Unit tests are still missing, and I also have not visually tested all examples. But everything I tried works fine.

The example from the patch can be tried online at  http://dev.openlayers.org/sandbox/ahocevar/singleroot/openlayers/examples/select-feature-multilayer.html

Changed 4 years ago by ahocevar

Changed 4 years ago by ahocevar

new patch with better design and workarounds for the usual IE annoyances

  Changed 4 years ago by ahocevar

Some progress on this: I tested with different kinds of styles (externalGraphic, rotation, graphicName) and found issues in IE of course. The new patch singleroot.2.patch fixes most of these issues, but there are some left in the select-feature example.

I also did some refactoring to make the modifications cleaner in terms of OO. The SelectFeature control no longer needs to know about renderers, and moving of roots among layers is now handled by the renderer.

Relevant unit tests still pass, although I had to make some minor modifications to the tests because some mockup objects had to be updated.

Changed 4 years ago by ahocevar

fixed redraw issues in IE - this time in a more elegant way

  Changed 4 years ago by ahocevar

  • state changed from Needs Discussion to Needs More Work

singleroot.3.patch finally fixes the issues that broke the select-feature example. I think we're good now for others to test this and give feedback. Unit tests are still missing, will add those soon.

  Changed 4 years ago by tschaub

(In [8675]) Reverting changes from r8664 that were inadvertently committed to the trunk. This gets the SelectFeature control tests passing again. (see #1666)

Changed 4 years ago by ahocevar

layer visibility issues are fixed now

  Changed 4 years ago by crschmidt

  • milestone changed from Future to 2.8 Release

  Changed 4 years ago by crschmidt

ahocevar: Is unit testing on this one all that's missing? At this point, I've tested in IE6, IE7, IE8 in default config (yes, really), FF3, FF2, Opera, Safari, all with no problems.

  Changed 4 years ago by ahocevar

crschmidt: If we want to add this functionality to other controls like DragFeature with separate tickets, then unit tests are indeed the only thing that's missing.

Changed 4 years ago by ahocevar

fixed issue with Layer.WFS caused ba Layer.Markers mixin overriding Layer.Vector's display method

  Changed 4 years ago by ahocevar

This needs to be refactored a bit to avoid code duplication if we want the same functionality for other controls (like DragFeature):

Currently, the collectRoots, resetRoots and handleChangeLayer methods are on the control. The same functions, as well as the special layer.getFeatureFromEvent method, would be required for other controls that need to do this trick.

It would be better to create a new layer type (subclass of Layer.Vector, e.g. Layer.Vector.Container) which provides this functionality and listens for changelayer events.

Changed 4 years ago by ahocevar

  Changed 4 years ago by ahocevar

singleroot.6.patch implements the refactoring mentioned in my above comment. It adds a new layer type, OpenLayers.Layer.Vector.RootContainer, which can be used by all controls that need mouse events across multiple vector layers.

Changed 4 years ago by danring

added 'selectionKey' option to Control/SelectFeature.js

follow-up: ↓ 16   Changed 4 years ago by danring

singleroot.6-with-selectionKey.patch adds an option selectionKey to OpenLayers.Control.SelectFeature, which in turn allows multiple SelectFeature controls on a single layer to be distinguishable. Basically, I wanted to have both 'hover' and 'click' controls using SelectFeature, but wanted the callbacks/style to be different.

If selectionKey is specified (non-null) then a layer's selected features are stored in layer.selections[selectionKey] instead of layer.selectedFeatures. If selectionKey is null (the default), layer.selectedFeatures is used (as before).

For the events beforefeatureselected, featureselected, and featureunselected, the callback object has selectionKey as well as feature properties, so that layer callbacks can distinguish events caused by different controls.

I also changed the example to demonstrate the changes.

I'm not sure whether these changes are desired by others or in the right place, so feel free to disregard.

  Changed 4 years ago by ahocevar

  • owner set to ahocevar
  • status changed from new to assigned

in reply to: ↑ 14   Changed 4 years ago by ahocevar

danring, thanks for your efforts. I think your modifications deserve a separate ticket.

Changed 4 years ago by ahocevar

new patch with unit tests

Changed 4 years ago by ahocevar

new patch with unit tests

  Changed 4 years ago by ahocevar

  • owner changed from ahocevar to crschmidt
  • status changed from assigned to new
  • state changed from Needs More Work to Review

New patch with additional unit tests passing in FF3 and IE7. Please review.

  Changed 4 years ago by crschmidt

  • state changed from Review to Commit

Confirmed that:

  • Tests all pass in Safari and FF3 (I"ll trust yon on IE)
  • Example works
  • Also works with Canvas renderer (though the stacking won't neccesarily, but that's not important in my mind)
  • The code looks sound
  • It should be easy to extend for other layer types in the future.

I'd say that all this makes us ready to go. Andreas, this will be a *Great* addition to the library. Thanks for all your hard work.

Please commit.

  Changed 4 years ago by crschmidt

  • owner changed from crschmidt to ahocevar

  Changed 4 years ago by ahocevar

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

(In [9116]) SelectFeature control can now select across multiple vector layers when passed an array of layers instead of a single layer with the constructor. This changeset also introduces a new layer type, Layer.Vector.RootContainer, which will be set as the topmost layer by the SelectFeature control and collect the svg/vml/canvas roots of multiple vector layers. r=crschmidt (closes #1666)

  Changed 4 years ago by ahocevar

  • status changed from closed to reopened
  • resolution fixed deleted

We can do better here in terms of backwards compatibility and only create the root container if the constructor was called with an array of layers.

Changed 4 years ago by ahocevar

Better backwards compatibility

  Changed 4 years ago by ahocevar

  • state changed from Complete to Review

Tests continue to pass, examples work. Please review.

  Changed 4 years ago by crschmidt

  • state changed from Review to Commit

Agreed. Looks good, and this means that we get fewer complaints about 'my half baked hack doesn't work anymore!' :) Thanks, please commit.

  Changed 4 years ago by ahocevar

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

(In [9275]) better backwards compatibility -- only create the root container if Control.SelectFeature constructor was called with an array of layers. r=crschmidt (closes #1666)

  Changed 4 years ago by dvinnenberg

  • status changed from closed to reopened
  • resolution fixed deleted

Potential bug with this fix. If inserting a new layer to the map on the fly the onselect still doesn't fall through. Using the RC2 release of OpenLayers 2.8 I modified the select-feature-multilayer.html example above to insert the second layer from a javascript call on a button click. While the second layer is displayed onselect does not work. If you turn off the first layer with the layer control or raise the second layer up it is selectable.

You can see the modification to the example here:  http://pastebin.com/f4b71cb27

  Changed 4 years ago by crschmidt

  • status changed from reopened to closed
  • resolution set to fixed

This appears to be working as expected. Specifically:

  • Only one selectfeature control can be active at a time.
  • You add a second layer, and create a second select feature control.
  • the new sfc2 is the only one that works.

If you wish to have both layers selectable:

  • deactivate your first sfc
  • Add a new SFC with both layers.

An unsupported way to achieve the same functionality:

        sfc.layers.push(vlayer);
        sfc.layer.layers.push(vlayer);
        sfc.layer.collectRoots();

Since this is not supported by the API, and adding/removing layers to the existing SFC is a reasonable request, the ability to add/remove layers from an SFC could be filed as a feature request.

This ticket is still resolved, so I'm re-closing. Feel free to open new tickets for additional enhancement requests.

Note: See TracTickets for help on using tickets.