0

I can specify event callbacks in an OpenLayers layer:

var vectorA=new OpenLayers.Layer.Vector("A");
vectorA.events.on({
  "featureselected": callback
});

and I can specify event callbacks in a control's constructor:

highlightControl = new OpenLayers.Control.SelectFeature(vectorA, {
  renderIntent: "temporary",
  hover: true,
  highlightOnly: true,
  eventListeners: {
    featurehighlighted: hoverFeatureCallback,
    featureunhighlighted: unhoverFeatureCallback
  }
});

Can I mix them properly?

Basically, one layer needs both select and hover events, so I'd have two controls, one that hovers, and give each their own callbacks (like the second example above.)

AND I have multiple layers that need select events, so in that case I'd define the events in the layers themselves, like the first example. However, I can't use the first example with hover and select because, in OL's infinite wisdom, hover events are really just select events.

How can I have two layers respond to hover events and one of them also respond to select events?

2

To combine hover and click in OpenLayers 2.x, it is sufficient to override the clickFeature method of OpenLayers.Control.SelectFeature. The default implementation does nothing on hover but is still called on click:

clickFeature: function (feature) {
  if (!this.hover) {
    ...
  }
}

This code demonstrates that it is possible to handle the feature click by overriding clickFeature:

var highlightCtrl = new OpenLayers.Control.SelectFeature([vectors, vectors2], 
{
  hover: true,
  onSelect: function (e) { ... process feature hover ...  }, 
  clickFeature: function (e) { alert("clicked feature: " + e.id); } 
});
0

I've found a solution. To enable hovering and selecting on multiple layers, each handled differently, you need to:

  1. Create both layers without any event handlers:

    var vectors = new OpenLayers.Layer.Vector("vector"),
        vectors2 = new OpenLayers.Layer.Vector("vector");
    
  2. register select and unselect events on both layers:

    vectors.events.register("featureselected", null, function(feature){
        console.log("v1 featureSelected");
    });
    vectors.events.register("featureunselected", null, function(feature){
        console.log("v1 featureunselected");
    });
    vectors2.events.register("featureselected", null, function(feature){
        console.log("v2 featureSelected");
    });
    vectors2.events.register("featureunselected", null, function(feature){
        console.log("v2 featureunselected");
    });
    
  3. Create select and highlight controls:

    var highlightCtrl = new OpenLayers.Control.SelectFeature([vectors, vectors2], {
        hover: true,
        highlightOnly: true,
        renderIntent: "temporary",
    });
    var selectCtrl = new OpenLayers.Control.SelectFeature([vectors, vectors2],
        {clickout: true}
    );
    
  4. Attach the hover/unhover events to the highlight control: (these take events, not features, but you can get the feature with event.feature)

    highlightCtrl.events.register("featurehighlighted", null, function(event){
        console.log(e);
    });
    highlightCtrl.events.register("featureunhighlighted", null, function(event){
        console.log(e);
    })
    
  5. Finally, you can tell which layer has triggered the highlight event with

    event.feature.layer
    

I dislike this solution since I'd like to implement code in pieces and merge it all together later, and this requires setting up the layers completely before being able to add/attach events, but there you go.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.