OpenLayers 3 hover to highlight only one specified object per time

孤街醉人 提交于 2021-02-07 10:28:19

问题


Original issue:

OpenLayers 3 (tested also newest 3.14.1) should have some sense in the way it selects features that overlap each other. When multi=false it selects only one feature, but picks it quite randomly. When you hover over certain features from different directions, different feature is selected.

I have tried to tangle this by setting z-index to features to tell Openlayers the desired order. Indexing is set to order point > line > polygon but still I am not getting point selected first on hover.

Z-Index is applied to layer with:

rendererOptions: { zIndexing: true }

on layer and

zIndex: x

in style for different feature types.

What happened first:

Z-indexing did not work so I was not able to tangle the situation for select. I kept multi=true and filtered results manually from list.

I had a function getSelectedRemovableFeature(event.selected) that took event.selected and returned only one feature out of it.

So, my selection had a code like follows:

 var selectionInteraction = new ol.interaction.Select({
                               layers: [layersModule.getTargetLayer()],
                               condition: ol.events.condition.click,
                               multi: true
                            });  

and more..

selectionInteraction.on('select', function(event) {

                var selectedFeature = null;

                selectedFeature = getSelectedRemovableFeature(event.selected);

                if(selectedFeature){
                   .. some logic..
                   layersModule.getTargetLayer().getSource().removeFeature(selectedFeature);
                }
         });

Then I got stucked:

I had

var hoverInteraction = new ol.interaction.Select({
                       layers: [layersModule.getTargetLayer()],
                       condition: ol.events.condition.pointerMove,
                       multi: true
                       });

..and..

hoverInteraction.on('select', function(event) {

            var selectedFeature = null;

            selectedFeature = getSelectedRemovableFeature(event.selected);

            // here I didn't know what to do..
            }
     });

I had there a logic like this:

  selectControl = new OpenLayers.Control.SelectFeature(vectorLayer);
  ...
  map.addControls([selectControl]);
 selectControl.activate();

  // unselect any specific feature...
  selectControl.unselect(vectorLayer.features[0]);

(https://gis.stackexchange.com/questions/41017/how-can-i-unselect-a-feature-in-openlayers)

.. but when it was there, no selections were removed, it worked like same as without this part.

Back to the origins:

Now I realized, that tangling with the hoverSelection data is of no use, because new multi=true type event is thrown there before I could calculate how to select one only and show that. I believe that is the case, because nothing changes even I manually filter the results and remove features.

In short finally:

How to determine explicit order where the hover / select selection goes?


回答1:


Hit detection of features on a map works in opposite rendering order. By default, points are rendered last, so they get hit detected (and selected) first. When no zIndex is set on any style, the rendering order is polygons, lines, points, texts.

When you set zIndex on an ol.style.Style, you override this fixed rendering order, allowing you to e.g. render polygons on top of points.

Within these four groups (polygons, lines, points, texts), you can control the rendering order by setting a renderOrder function on your ol.layer.Vector. That is an array sort function called with two features:

new ol.layer.Vector({
  renderOrder: function(a, b) {
    if (a.get('importance') < b.get('importance')) {
      return -1;
    } else if (b.get('importance') > a.get('importance')) {
      return 1;
    }
    return 0;
  }
});

The above assumes that your features have a numeric 'importance' property. Now when you hit detect (select) features of the same geometry type (e.g. points), those with a higher 'importance' value will be selected first, because they are rendered last.

Also note that there are no rendererOptions like you state in your question.




回答2:


I noticed that from some reason the draw styles included heavily z-indexing and what made this problem to occur was the following:

Reason:

From some historical reason selected style was forced on top by zIndex: 100. Normal selection had zIndex: 1.

That caused a problem: when you had point and line on top of each other and you select line, it's zIndex rose up to 100. That broke the natural highlight order, because 100 is far more than 1. Thus natural order, which @ahocevar pointed out, gets broken and highlighting becomes dependent of direction where you come near to the feature on map.

Solution:

I put selected and default style both to zIndex: 1 and everything seemed to work ok event with that.

I will need to check still the reason of selected style on zIndex so high, but if there is no reason to continue its usage, this thing solves the problem.

Side note:

Answer is a community wiki, because half of solution is from comment of another user.



来源:https://stackoverflow.com/questions/35722225/openlayers-3-hover-to-highlight-only-one-specified-object-per-time

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!