Agregar un oyente de eventos en un marcador en el folleto

10

Estoy usando el folleto para representar un mapa. Creé un mapa con marcadores y no sé cómo implementar el escucha de eventos 'onClick' en cada marcador.

Mi código

var stops = JSON.parse(json);
var map = new L.Map('map', {
  zoom: 12,
  minZoom: 12,
  center: L.latLng(41.11714, 16.87187)
});
map.addLayer(L.tileLayer('https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}.png?access_token={accessToken}', {
  attribution: 'Map data',
  maxZoom: 18,
  id: 'mapbox.streets',
  accessToken: '-----'
}));
var markersLayer = new L.LayerGroup();
map.addLayer(markersLayer);


//populate map from stops
for (var i in stops) {
  L.marker(L.latLng(stops[i].Position.Lat, stops[i].Position.Lon), {
    title: stops[i].Description
  }).addTo(markersLayer).bindPopup("<b>" + stops[i].Description + "</b>").openPopup();
}

Ejemplo

map.on('click', function(e) {
    alert(e.latlng);
});

El folleto trata con los oyentes de eventos por referencia, por lo que si desea agregar un oyente y luego eliminarlo, defínalo como una función:

function onClick(e) { ... }

map.on('click', onClick);
map.off('click', onClick);
ilias ioannou
fuente
Vea la respuesta de @TimoSperisen a esta pregunta y el violín que publicó Funciona para mí
Mawg dice que reinstale a Mónica el

Respuestas:

14

¡Bienvenido a GIS Stack Exchange!

No debería haber ninguna dificultad especial en adjuntar una devolución de llamada al evento de clic de marcador (s). Simplemente usaría myMarker.on('click', callback)como lo hizo con el mapa. También debería hacerlo para cada marcador al que desee adjuntar una devolución de llamada.

Otra posibilidad sería agregar todos sus marcadores en un Grupo de funciones (por ejemplo, simplemente crear una instancia de markersLayercon en L.featureGroup()lugar de L.layerGroup()), para que pueda adjuntar la devolución de llamada directamente a ese Grupo. Recibirá los eventos de clic de marcadores individuales, y puede acceder a la función de clic individual usando event.layer.

var markersLayer = L.featureGroup().addTo(map);

// populate map from stops…

markersLayer.on("click", function (event) {
    var clickedMarker = event.layer;
    // do some stuff…
});

Demostración: http://jsfiddle.net/ve2huzxw/74/

Pregunta similar hecha por otra persona en el foro de Leaflet: https://groups.google.com/forum/#!topic/leaflet-js/RDTCHuLvMdw

ghybs
fuente
Solo para agregar, event.layer.propertiesle dará acceso a la matriz de todas las propiedades (metadatos) de sus marcadores, según el formato GeoJSON. Entonces puedes asignar event.layer.properties.description = stops[i].Descriptionpor ejemplo.
Nikhil VJ
4

Modifique el bucle de población del mapa para asignar propiedades a su marcador.

//populate map from stops
for (var i in stops) {
  var oneMarker = L.marker(L.latLng(stops[i].Position.Lat, stops[i].Position.Lon), {
    title: stops[i].Description
  }).bindPopup("<b>" + stops[i].Description + "</b>").openPopup();

  oneMarker.properies.name = stops[i].Name;
  oneMarker.properies.description = stops[i].Description;
  oneMarker.properies.othervars = stops[i].othervars;
  oneMarker.addTo(markersLayer);
}

Más tarde, para acceder a estas propiedades (propiedades de características como se llaman) en el evento onclick,

markersLayer.on("click", markerOnClick);

function markerOnClick(e) {
  var attributes = e.layer.properties;
  console.log(attributes.name, attributes.desctiption, attributes.othervars);
  // do some stuff…
}

El properties.varenfoque tiene el beneficio adicional de hacer que su marcador esté en el formato estándar GeoJson. Lo hace compatible si, por ejemplo, necesita exportar los datos como shapefile, importar marcadores desde shapefile, etc.

Nikhil VJ
fuente
1
Estoy tratando de incorporar su sugerencia en mi propia configuración. Pero agregar un oneMarker.properties simple me da un mensaje de error "oneMarker.properties no está definido". Estoy pasando por alto algo obvio? saludos por cierto: escribiste mal propiedades ........ propiedades en tu código de ejemplo
alex
1
ah creo que encontré una solución: tuve que agregar oneMarker.properties = {}; por cierto: ¿es correcto usar var oneMarker o debería ser un nombre dinámico?
alex
@alex es bueno saber sobre el hack de propiedades Sí, está bien usarlo var oneMarker: es un ámbito local dentro del ciclo for, y la línea layer.addTo () le agrega valor. (como: a=3; array1.push[a];agregará valor 3a la matriz, no una referencia a así mismo).
Nikhil VJ
0

Una manera bastante directa y fácil de lograr crear una matriz de marcadores en los que se pueda hacer clic dentro de un objeto de mapa de folleto es manipular la lista de clases del marcador creado agregando un nombre de clase incremental personalizado a cada marcador. Entonces es fácil crear un oyente y saber en qué marcador se hizo clic. Al omitir el activo o no, cada uno tiene un evento de clic recuperable con una ID confiable.

  // creates markers, each with a leaflet supplied class
  if (length === 1) {
    for (i = 0; i < parks.length; ++i) {
      if (parks[i].parksNumber !== parks.parksNumber)
        L.marker([parks[i].latitude, parks[i].longitude], {
          icon: parks[i].iconMarker
        }).addTo(mymap);
    }
  }

  // select all of the leaflet supplied class
  let markers = document.querySelectorAll(".leaflet-marker-icon");

  // loop through those elements and first assign the indexed custom class
  for (i = 0; i < markers.length; ++i) {
    markers[i].classList.add("marker_" + parks[i].parksNumber);

    // then add a click listener to each one
    markers[i].addEventListener("click", e => {

      // pull the class list
      let id = String(e.target.classList);

      // pull your unique ID from the list, be careful cause this list could 
      // change orientation,  if so loop through and find it
      let parksNumber = id.split(" ");
      parksNumber = parksNumber[parksNumber.length - 1].replace("marker_", "");

      // you have your unique identifier to then do what you want with
      search_Number_input.value = parksNumber;
      HandleSearch();
    });
  }
Joel Mason
fuente