0

I have a couple of layers and i want to add click event on a specific layer of the map.

E.g. If clicking on parcels, do different ajax request than clicking on buildings.

How can i do it?

    var wmsLayer = new ol.layer.Image({
  source: wmsSource
});
var map = new ol.Map({
  target: 'map',
  layers: [baseLayer, wmsLayer],
  view: new ol.View({
    center: ol.proj.fromLonLat([33.33386, 35.14710]),
    zoom: 14
  })
});

map.on('click', function (evt) {
  map.forEachLayerAtPixel(evt.pixel, function (layer) {
    if (layer==='web:Parcels') {
      console.log('parcels clicked');
    }
  });
});
  • What do you want to get from the layer? Generally, you can just loop over the layers, until you find your desired layer, but some functions (like map.forEachFeatureAtPixel) have a layerfilter-option – Rob Mar 27 at 8:41
  • @Rob i'll click on the layer and get the degrees. It's important to click on the specific layer to request data from the server related to that layer. – csandreas1 Mar 27 at 8:53
  • How do you get the data from your server? Anyways, you can do forEachLayerAtPixel inside your click listener, and use the layerFilter-option there. You can get the Pixel from your evt. (openlayers.org/en/latest/apidoc/…) – Rob Mar 27 at 8:58
  • @Rob i get the degrees on map click (should be on layer click) and i query data on the related layer table where ST_CONTAINS(p.geom,ST_GeomFromText('POINT(33.3293679356575 35.144125764150516)')) something like that – csandreas1 Mar 27 at 9:53
  • 1
    Since all layers of your map are in the same coordinate reference system, you will get the same (map) coordinates on every layer. However, you can convert map coordinates to geographic coordinates ('degrees') via ol.proj.toLonLat(evt.coordinate), or to any desired coordinateReferenceSystem via proj4 – Rob Mar 27 at 10:09
2

You can add and retrieve extra attributes on a layer and aren't limited by key names. Here's a sample for OpenStreetMaps:

var baseLayer = new ol.layer.Tile({
        id: 'base_osm',
        title: 'OpenStreetMap',
        group: 'base',
        whatever: 'Testing 123',
        visible: true,
        source: new ol.source.OSM(),
})

map.on('singleclick', function (evt) {
    map.forEachLayerAtPixel(evt.pixel, function(layer) {
        console.log(evt.pixel);
        console.log(layer);
        var id = layer.get('title');
        console.log(id);
        var title = layer.get('title');
        console.log(title);
        var whatever = layer.get('whatever');
        console.log(whatever);
    });
});

See https://openlayers.org/en/latest/apidoc/module-ol_layer_Base-BaseLayer.html#get for the API Doc on this.

That should plug right into a WMS example and a working fiddle is at https://jsfiddle.net/ategenkamp/Lhekcvna/3/ as well based on https://openlayers.org/en/v4.6.5/examples/wms-tiled.html

Let me know if that helps!

  • Hi, firstly, you have to close the function like that });. Secondly, i am getting the following error: IntermediateCanvas.js:117 Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. Also you need map click event – csandreas1 Mar 28 at 13:49
  • I missed the }) from in copy/paste from the fiddle. That also has the click/singleclick event, which I added here. It was meant to be snippets like your original code but the fiddle puts it all together if needed. The jsfiddle also has crossOrigin: 'anonymous', which you'll need in your source to fix the cross-origin data message. There's a lot of stuff on CORS here if the server you get data from still has an issue. I'm fighting with that myself for some of our sources myself! – Andrew T Mar 28 at 15:58
  • So if one layer is above the other, and click on it, the click event will be triggered twice :/ – csandreas1 Mar 29 at 8:03
  • The click event runs once but it loops through all visible layers and can run different code for each layer which seemed to be what you wanted in the original question. – Andrew T Mar 30 at 19:44
  • The click event only runs once. It loops through each visible layer. You can run different code per layer which seems to answer your original question. – Andrew T Mar 30 at 20:18

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.