javascriptopenlayers

OL4 stopPropagation


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: REMOVED

On the live system, I have a map layer feature layer 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


Solution

  • 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