[GIS] Using stopPropagation in OpenLayers 4

openlayers

I'm using OL4 on my project and I have a feature layer where I can click and a popup appears, I also use a draw layer where I can plot a Marker (in the example it's just a point)

My problem is that if I plot the marker above the feature layer, the click propagate through the draw layer till the feature layer and the popup appears, I know it exists the stopPropagation() event but I really don't find the correct place to insert it.

I tried to insert the event on marklayer and map on(click…) but doesn't work.

Here my code:

var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
var overlay = new ol.Overlay({
    element: container,
    autoPan: true,
    autoPanAnimation: {
      duration: 250
    }
});
    closer.onclick = function() {
      overlay.setPosition(undefined);
      closer.blur();
      return false;
    };

// DRAW Layer
var Msource = new ol.source.Vector();
var markLayer = new ol.layer.Vector({
   source: Msource,
   style: new ol.style.Style({
     fill: new ol.style.Fill({
     color: 'rgba(255, 255, 255, 0.2)'
   }),
   stroke: new ol.style.Stroke({
     color: '#328cc1',
     width: 4
   }),
   image: new ol.style.Circle({
     radius: 7,
     fill: new ol.style.Fill({
       color: '#328cc1'
     })
   })
   })
 });


// DRAW Layer
var Msource = new ol.source.Vector();
var markLayer = new ol.layer.Vector({
   source: Msource,
   style: new ol.style.Style({
     fill: new ol.style.Fill({
     color: 'rgba(255, 255, 255, 0.2)'
   }),
   stroke: new ol.style.Stroke({
     color: '#328cc1',
     width: 4
   }),
   image: new ol.style.Circle({
     radius: 7,
     fill: new ol.style.Fill({
       color: '#328cc1'
     })
   })
   })
 });

// MAP
      var map = new ol.Map({
        layers: [
          new ol.layer.Tile({
            source: new ol.source.TileJSON({
              url: 'https://api.tiles.mapbox.com/v3/mapbox.natural-earth-hypso-bathy.json?secure',
              crossOrigin: 'anonymous'
            })
          })
        ],
        overlays: [overlay,markLayer],
        target: 'map',
        view: new ol.View({
          center: [0, 0],
          zoom: 2
        })
      });

// POPUP INTERACTION
map.on('singleclick', function(evt) {
  var coordinate = evt.coordinate;
  var hdms = ol.coordinate.toStringHDMS(ol.proj.transform(
          coordinate, 'EPSG:3857', 'EPSG:4326'));

  content.innerHTML = '<p>You clicked here:</p><code>' + hdms + '</code>';
  overlay.setPosition(coordinate);
});


// MARKER INTERACTION
$("#marker").click(function(e) {
  addMark("Point");
});


var mark;

function addMark(Type) {
  mark = new ol.interaction.Draw({
    source: Msource,
    type: Type
  });

    map.addInteraction(mark);

    mark.on("drawend", function(){          
      //to do stuff
    });

    markLayer.on("change", function(){
      // remove the interaction after you have plotted a marker
      map.removeInteraction(mark);
    });
}

here my CodePen: https://codepen.io/sebalaini/pen/gvPLBJ

On the live system, I have a map layer, feature layer and a drawing layer so not all the map is clickable but, for the purpose of showing my problem, the example is OK, you can see that if you draw a circle you open also the popup

Best Answer

Thanks to @fradal83 that answered in StackOverflow

AFAIK, you cannot use stopPropagation in this context.

One quick and (very) dirty solution could be setting a (global) variable in the drawend callback (eg. skipCoordinatesPopup) and checking it inside the singleclick callback.

Here's the codepen modified https://codepen.io/anon/pen/NyrKBm

map.on('singleclick', function(evt) {
  if(skipCoordinatesPopup) {
    console.log('skip popup while drawing marker');
    return;
  }
  var coordinate = evt.coordinate;
  var hdms = ol.coordinate.toStringHDMS(ol.proj.transform(
          coordinate, 'EPSG:3857', 'EPSG:4326'));

  content.innerHTML = '<p>You clicked here:</p><code>' + hdms + '</code>';
  overlay.setPosition(coordinate);
});
...

map.addInteraction(mark);
skipCoordinatesPopup = true;

Instead, while dealing with controls that relies on the same gesture (click in your example), I suggest you to "activate" and "deactivate" (using the setActive functions or add/removeInteraction) them using a "toggling system", like a radio button or a combobox.

You can find something similar in this example https://openlayers.org/en/latest/examples/draw-freehand.html

Related Question