Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding event handler to feature in OpenLayers 3?

I am using the following code to add a feature to a vector layer in OpenLayers 3 (OL3):

marker = new ol.Feature({
    geometry: new ol.geom.Point([longitude, latitude]),
    name: "Location Marker"
});
markerStyle = new ol.style.Style({
  image: new ol.style.Icon({
    anchor: [0.5, 1.0],
    anchorXUnits: "fraction",
    anchorYUnits: "fraction",
    src: "Content/Images/OpenLayers/marker_trans.png"
  }),
  zIndex: 100000
});
marker.setStyle(markerStyle);
marker.on("click", function(e) {
  // do something
}, marker);
map.getSource().addFeature(marker);

The marker displays as expected, but the click event never fires. What am I doing wrong?

I should note that there is already a handler associated with "click" at the map level, i.e.

map.on("click", function(e) {
  // do something
}, marker);
like image 297
ProfNimrod Avatar asked Oct 15 '14 20:10

ProfNimrod


People also ask

How do you add event handler?

Right-click the control for which you want to handle the notification event. On the shortcut menu, choose Add Event Handler to display the Event Handler Wizard. Select the event in the Message type box to add to the class selected in the Class list box.

What is an event how event handler is added?

Events are signals fired inside the browser window that notify of changes in the browser or operating system environment. Programmers can create event handler code that will run when an event fires, allowing web pages to respond appropriately to change.

How do I select a feature in Openlayers?

When using Single-click or Click you can hold the Shift key to toggle the feature in the selection. Note: when Single-click is used double-clicks won't select features. This in contrast to Click , where a double-click will both select the feature and zoom the map (because of the DoubleClickZoom interaction).

What is event handler and event listener?

Note: Event handlers are sometimes called event listeners — they are pretty much interchangeable for our purposes, although strictly speaking, they work together. The listener listens out for the event happening, and the handler is the code that is run in response to it happening.


2 Answers

First: Features don't fire clicks! For information on the events features do fire, check http://openlayers.org/en/master/apidoc/ol.Feature.html.

For checking if a feature did get clicked, there is the .forEachFeatureAtPixel(pixel, callback) function of ol.Map. ( http://openlayers.org/en/master/apidoc/ol.Map.html#forEachFeatureAtPixel ) The callback is executed on every feature at the pixel. The callback gets passed 2 arguments: the feature and the layer the feature is in.

Good to know is the .getEventPixel(event) function, if you don't work with openlayers event handlers but with handlers on the viewport. If your using openlayers eventhandler, the event has a property .pixel. (http://openlayers.org/en/master/apidoc/ol.Map.html#getEventPixel) The methods .getEventCoordinate(event) and .getCoordinateFromPixels(pixels) might be useful, too.

So you would add it like this to your map.on("click", ... :

map.on("click", function(e) {
    map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
        //do something
    })
});

Same thing with jQuery:

$(map.getViewport()).on("click", function(e) {
    map.forEachFeatureAtPixel(map.getEventPixel(e), function (feature, layer) {
        //do something
    });
});

Same thing with pure JS:

map.getViewport().addEventListener("click", function(e) {
    map.forEachFeatureAtPixel(map.getEventPixel(e), function (feature, layer) {
        //do something
    });
});

You might also want to check this example, there are two uses of this function, first with openlayers events, the second with jQuery events: http://openlayers.org/en/master/examples/icon.js

Note

There is also the possibility to do this with an ol.interaction.Select (http://openlayers.org/en/master/apidoc/ol.interaction.Select.html?unstable=true), but this is a little bit overpowered for this case. And it has some unintuitive caveats caused by openlayers internally moving the selected features to another so called unmanaged layer.

Anyhow this works by adding a listener to the collection belonging to the interaction. The collection can be retrieved with .getFeatures().

interaction.getFeatures().on("add", function (e) { 
    // do something. e.element is the feature which was added
});
like image 173
Simon Zyx Avatar answered Oct 02 '22 18:10

Simon Zyx


If you just want a click on a map, this will work for you.

  var map = new ol.Map({
    target: 'map',
    layers: [
      new ol.layer.Tile({
        source: new ol.source.MapQuest({layer: 'sat'})
      })
    ],
    view: new ol.View({
      center: ol.proj.transform([37.41, 8.82], 'EPSG:4326', 'EPSG:3857'),
      zoom: 4
    })
  });

map.on("click", function(evt) {
    var coord = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');
    var lon = coord[0];
    var lat = coord[1];
    alert(lon);
    alert(lat);
});
like image 31
Costales Avatar answered Oct 02 '22 18:10

Costales