Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Leaflet event: how to propagate to overlapping layers

Let's say I have some overlapping layers and each layer has a click event. When I click on the map, I'd like to know which layers are clicked on, though the click event stops after the first layer and does not propagate to its underlying layers. How can I achieve this?

Here's a sample fiddle and its code: https://jsfiddle.net/r0r0xLoc/

<div id="mapid" style="width: 600px; height: 400px;"></div>

<script>
  var mymap = L.map('mapid').setView([51.505, -0.09], 13);

  L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token=pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4NXVycTA2emYycXBndHRqcmZ3N3gifQ.rJcFIG214AriISLbB6B5aw', {
    maxZoom: 18,
    attribution: 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, ' +
      '<a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>, ' +
      'Imagery © <a href="http://mapbox.com">Mapbox</a>',
    id: 'mapbox.streets'
  }).addTo(mymap);

  L.polygon([
    [51.509, -0.08],
    [51.503, -0.06],
    [51.51, -0.047]
  ]).addTo(mymap).on('click', function() {
    console.log('clicked on 1st polygon')
  });

  L.polygon([
    [51.609, -0.1],
    [51.503, -0.06],
    [51.51, -0.047]
  ]).addTo(mymap).on('click', function() {
    console.log('clicked on 2nd polygon')
  });

</script>

If you click on each polygon, you see its related message. If you click on the overlapping part, you only see the message for the second polygon.

like image 837
kaveh Avatar asked Mar 24 '17 18:03

kaveh


2 Answers

You have to listen directly to the map "click" event and to "manually" determine which layers contain the clicked position.

You can use leaflet-pip plugin (point in polygon) for example for this determination:

map.on("click", function (event) {
  var clickedLayers = leafletPip.pointInLayer(event.latlng, geoJSONlayerGroup);
  // Do something with clickedLayers
});

Demo: https://jsfiddle.net/ve2huzxw/526/ (listening to "mousemove" instead of "click")

like image 59
ghybs Avatar answered Oct 26 '22 14:10

ghybs


There is a leaflet plugin for propagating events to the underlying layers: https://github.com/danwild/leaflet-event-forwarder

You can use it in your javascript to enable event-forwarding, e.g.:

const myEventForwarder = new L.eventForwarder({
  map: map,
  events: {click: true, mousemove: false}
});
like image 45
thor Avatar answered Oct 26 '22 15:10

thor