[GIS] Dynamic legend with multiple layers in leaflet

javascriptleaflet

I have a choropleth map I am putting together with two different layers. each layer has its own symbolization and legend. I have so far been successful in having the legend change when a new layer is turned on, however if a layer is turned off, the legend does not change to match the remaining layer. Additionally, if all layers are turned off, the legend will remain for whatever layer last activated a legend change.

my code that is working for the layer change so far is:

map.on('overlayadd', function (eventLayer) 
{
    if (eventLayer.name === 'Housing'){
        map.removeControl(currentLegend );
        currentLegend = houselegend;
        houselegend.addTo(map);
    }
    else if (eventLayer.name === 'Families') {
        map.removeControl(currentLegend );
        currentLegend = childlegend;
        childlegend.addTo(map);
    }
})

The code I have tried so far to make the legend change when a layer is removed or all layers are removed is:

function legendChange(e) {
    if (map.hasLayer(Families) && !map.hasLayer(Housing)){
        map.removeControl(currentLegend );
        currentLegend = childlegend;
        childlegend.addTo(map);
    }
    else if (map.hasLayer(Housing) && !map.hasLayer(Families)){
        map.removeControl(currentLegend );
        currentLegend = houselegend;
        houselegend.addTo(map);
    }
    else if (!map.hasLayer(Housing) && !map.hasLayer(Families)){
        map.removeControl(currentLegend );
    }
}

The map loads right now, so I'm confident my syntax is close and that the problem is likely with my logic.

Best Answer

I think the first problem is your currentLegend variable. Whenever you add a layer this variable gets overwritten, either with houselegend or childlegend. Let's say you activate Families and then Housing, your currentLegend is now houselegend.

Now you deactive the Families layers, but your Housing legend is removed, and currentLegend is set to houselegend again. You now remove the Housing layer and legend, but it fails because houselegend is already removed, childlegend stays.

The second problem is that the conditions in your if code are mutually exclusive in handling the layer legends. It allows only one legend to be active at a time, whenever a layer is added a legend is removed.

One way to solve and simplify this would be to create a mapping between layers and legends. Add and remove legends according to the layer name taken from the event.

var layerToLegendMapping={
  "Housing": houselegend,
  "Families": childlegend
}
function legendAdd(event) {
  var layername = event.name;
  map.addControl(layerToLegendMapping[layername]);
}
function legendRemove(event) {
  var layername = event.name;
  map.removeControl(layerToLegendMapping[layername]);
}
map.on('overlayadd',legendAdd);
map.on('overlayremove',legendRemove);
Related Question