0

I have three layer groups. How to use .on (click) for all layer groups without repeating the code? Do I really need to use .on(click) for each layer group? It seems to be unnecessary lots of code.

When using this below I only get the on click window for the last layer group (area_skrym) and no info for the first two. Script load the same data and use the same info when you click on the map, but I can not get it to work with below JavaScript code.

var area_size = new L.layerGroup();
var area_weight = new L.layerGroup();
var area_skrym = new L.layerGroup();

$.getJSON("/geojson/area_polyg.geojson", function(json) {

var vectorGrid_size =  L.vectorGrid.slicer(json, {
                  maxZoom: 20,
                  zIndex: 5,
                  rendererFactory: L.svg.tile,
                  vectorTileLayerStyles: {
                      sliced: function(properties, zoom){
                      var avl = properties.Total
                      if (avl <= 500){
                        return{
                      weight: 1,
                      color: 'white',
                      opacity: 0,
                      fill: true,
                      fillColor: '#4575b4',
                      stroke: true,
                      fillOpacity: 0.6
                      }
                      } else if (avl >= 500 && avl <= 1500){
                        return {
                      weight: 1,
                      color: 'white',
                      opacity: 0,
                      fill: true,
                      fillColor: '#91bfdb',
                      stroke: true,
                      fillOpacity: 0.6
                      }
                      } else if (avl >= 1501 && avl <= 3000){
                        return {
                      weight: 1,
                      color: 'white',
                      opacity: 0,
                      fill: true,
                      fillColor: '#e0f3f8',
                      stroke: true,
                      fillOpacity: 0.6
                      }
                      } else if (avl >= 3001 && avl <= 4500){
                        return {
                      weight: 1,
                      color: 'white',
                      opacity: 0,
                      fill: true,
                      fillColor: '#ffffbf',
                      stroke: true,
                      fillOpacity: 0.6
                      }
                      } else if (avl >= 4501 && avl <= 6000){
                        return {
                      weight: 1,
                      color: 'white',
                      opacity: 0,
                      fill: true,
                      fillColor: '#fee090',
                      stroke: true,
                      fillOpacity: 0.6
                      }
                      } else if (avl >= 6001 && avl <= 7500){
                        return {
                      weight: 1,
                      color: 'white',
                      opacity: 0,
                      fill: true,
                      fillColor: '#fc8d59',
                      stroke: true,
                      fillOpacity: 0.6
                      }
                      } else {
                      return {
                      weight: 1,
                      color: 'white',
                      opacity: 0,
                      fill: true,
                      fillColor: '#d73027',
                      stroke: true,
                      fillOpacity: 0.6
                      }
                    }
                     }},
                     interactive: true,
                   })

var vectorGrid_weight =  L.vectorGrid.slicer(json, {
                  maxZoom: 20,
                  zIndex: 5,
                  rendererFactory: L.svg.tile,
                  vectorTileLayerStyles: {
                      sliced: function(properties, zoom){
                      var gods = properties.1_gods
                      if (gods === 'Yes'){
                        return{
                      weight: 1,
                      color: '#e41a1c',
                      opacity: 1,
                      fill: true,
                      fillColor: '#e41a1c',
                      stroke: true,
                      fillOpacity: 0.6
                      }
                      } else {
                      return {
                      weight: 0,
                      color: 'white',
                      opacity: 0,
                      fill: false,
                      fillColor: '#ffffff',
                      stroke: false,
                      fillOpacity: 0
                      }
                    }
                     }},
                     interactive: true,
                   })

    var vectorGrid_skrym =  L.vectorGrid.slicer(json, {
                  maxZoom: 20,
                  zIndex: 5,
                  rendererFactory: L.svg.tile,
                  vectorTileLayerStyles: {
                      sliced: function(properties, zoom){
                      var skrym = properties.size
                      if (skrym === 'Yes'){
                        return{
                      weight: 1,
                      color: '#377eb8',
                      opacity: 1,
                      fill: true,
                      fillColor: '#377eb8',
                      stroke: true,
                      fillOpacity: 0.6
                      }
                      } else {
                      return {
                      weight: 0,
                      color: 'white',
                      opacity: 0,
                      fill: false,
                      fillColor: '#ffffff',
                      stroke: false,
                      fillOpacity: 0
                      }
                    }
                     }},
                     interactive: true,
                   })

 .on('click', function(e) {
  var properties = e.layer.properties;
  L.popup()
    .setContent(
      "<b>Size</b>: " + properties.size +
      "<br><b>Number</b>: " + properties.code +
      "<br><b>Name</b>: " + properties.name +
      "<br><b>Total</b>: " + properties.Total + '.pieces' + 
      "<br><a href='" + 'mailto:' + properties.email + "'>Contact email</a>" + 
      "<br><b>Date</b>: " + properties.date)
    .setLatLng(e.latlng)
    .openOn(map);
                    })

vectorGrid_size.addTo(area_size)

vectorGrid_weight.addTo(area_weight)

vectorGrid_skrym.addTo(area_skrym)

            }) 
1

There are a few approaches to this. The most basic is to define an event handler and reuse that when defining events, e.g.:

function handleClickOnSomething(ev) {
  var properties = ev.target.properties;
  L.popup().setContent(properties.something).setLatLng(...).openOn(map);
}

vectorGrid_size.on('click', handleClickOnSomething);      
vectorGrid_weight.on('click', handleClickOnSomething);    
vectorGrid_skrym.on('click', handleClickOnSomething);

This kind of refactoring is applicable elsewhere - just look for places where defining a thing once and referencing it several times will make the code architecture simpler.

Another approach is to leverage Leaflet's L.FeatureGroups. From the Leaflet reference:

Extended LayerGroup that makes it easier to do the same thing to all its member layers: [...] Events are propagated to the FeatureGroup, so if the group has an event handler, it will handle events from any of the layers. This includes mouse events and custom events.

So you can do something like:

var group = L.featureGroup();

vectorGrid_size.addTo(group);
vectorGrid_weight.addTo(group);
vectorGrid_skrym.addTo(group);

group.on('click', function(ev) { /* ... */ });

group.addTo(map);

Just be aware of the difference between ev.target, ev.sourceTarget and ev.propagatedFrom in that context - check the Leaflet reference for details.

  • It worked but I needed to change "ev" to "e" like e.layer.properties and function handleClickSomething(e) { or I got an error that properties is not defined... – QGIS-user Apr 1 at 16:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.