kaveh
Digamos que tengo algunas capas superpuestas y cada capa tiene un evento de clic. Cuando hago clic en el mapa, me gustaría saber en qué capas se hace clic, aunque el evento de clic se detiene después de la primera capa y no se propaga a sus capas subyacentes. ¿Cómo puedo conseguir esto?
Aquí hay un violín de muestra y su código: 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 © <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>
Si hace clic en cada polígono, verá su mensaje relacionado. Si hace clic en la parte superpuesta, solo verá el mensaje del segundo polígono.
Tienes que escuchar directamente el mapa "click"
evento y determinar “manualmente” qué capas contienen la posición en la que se hizo clic.
Puedes usar folleto-pepita complemento (punto en polígono) por ejemplo para esta determinación:
map.on("click", function (event) {
var clickedLayers = leafletPip.pointInLayer(event.latlng, geoJSONlayerGroup);
// Do something with clickedLayers
});
Manifestación: https://jsfiddle.net/ve2huzxw/526/ (escuchar "mousemove"
en vez de "click"
)
-
Al final utilicé el mismo enfoque y escuché hacer clic en eventos en el mapa mismo. no he probado
leaflet-pip
; en su lugar, utilicé turfjs/inside para determinar si la capa contiene el punto en el que se hizo clic. Aún así, creo que es lógico suponer que el evento debería propagarse a todas las capas.– kaveh
28 de marzo de 2017 a las 16:48
-
Solo una nota al margen, esas son excelentes sugerencias. Desafortunadamente, esto no ayuda cuando tus capas son líneas simples.
– Keul
28 de enero de 2019 a las 10:48
Hay un complemento de folleto para propagar eventos a las capas subyacentes: https://github.com/danwild/leaflet-event-forwarder
Puede usarlo en su javascript para habilitar el reenvío de eventos, por ejemplo:
const myEventForwarder = new L.eventForwarder({
map: map,
events: {click: true, mousemove: false}
});
El problema es el orden en que se agregan las capas (geometrías). En mi caso, tenía una matriz de geometrías y lo que hice fue ordenar la matriz de geometrías usando sus límites L.LatLngBounds#contains
por lo que si una geometría contiene otra, debe agregarse más tarde.
var geometries = [layerOne, layerTwo, ...];
geometries
.sort((a, b) => {
// in my case a separate function is required because the geometry could be a Circle, Rectangle, Polygon or Marker
// and the methods to get the corresponding bounds are different.
var boundsA = this.getBoundsFromGeometry(a);
var boundsB = this.getBoundsFromGeometry(b);
// if the second geometry contains the first, the order must be change so the layers don't overlap
return boundsB.contains(boundsA) ? 1 : -1;
})
.forEach(l => this.map.addLayer(l));
Para mi la solución fue usar la opción interactive: false
al crear la capa superior:
var options = {
style: feature => this.__determineStyle(feature),
interactive: false,
};
var overlay = L.geoJson(geoJsonData, options);
overlay.addTo(this.map);