Files
2024-09-29 01:46:07 -04:00

92 lines
3.1 KiB
Python

from branca.element import MacroElement
from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.utilities import parse_options
class GroupedLayerControl(JSCSSMixin, MacroElement):
"""
Create a Layer Control with groups of overlays.
Parameters
----------
groups : dict
A dictionary where the keys are group names and the values are lists
of layer objects.
e.g. {
"Group 1": [layer1, layer2],
"Group 2": [layer3, layer4]
}
exclusive_groups: bool, default True
Whether to use radio buttons (default) or checkboxes.
If you want to use both, use two separate instances of this class.
**kwargs
Additional (possibly inherited) options. See
https://leafletjs.com/reference.html#control-layers
"""
default_js = [
(
"leaflet.groupedlayercontrol.min.js",
"https://cdnjs.cloudflare.com/ajax/libs/leaflet-groupedlayercontrol/0.6.1/leaflet.groupedlayercontrol.min.js", # noqa
),
]
default_css = [
(
"leaflet.groupedlayercontrol.min.css",
"https://cdnjs.cloudflare.com/ajax/libs/leaflet-groupedlayercontrol/0.6.1/leaflet.groupedlayercontrol.min.css", # noqa
)
]
_template = Template(
"""
{% macro script(this,kwargs) %}
L.control.groupedLayers(
null,
{
{%- for group_name, overlays in this.grouped_overlays.items() %}
{{ group_name|tojson }} : {
{%- for overlaykey, val in overlays.items() %}
{{ overlaykey|tojson }} : {{val}},
{%- endfor %}
},
{%- endfor %}
},
{{ this.options|tojson }},
).addTo({{this._parent.get_name()}});
{%- for val in this.layers_untoggle %}
{{ val }}.remove();
{%- endfor %}
{% endmacro %}
"""
)
def __init__(self, groups, exclusive_groups=True, **kwargs):
super().__init__()
self._name = "GroupedLayerControl"
self.options = parse_options(**kwargs)
if exclusive_groups:
self.options["exclusiveGroups"] = list(groups.keys())
self.layers_untoggle = set()
self.grouped_overlays = {}
for group_name, sublist in groups.items():
self.grouped_overlays[group_name] = {}
for element in sublist:
self.grouped_overlays[group_name][
element.layer_name
] = element.get_name()
if not element.show:
self.layers_untoggle.add(element.get_name())
# make sure the elements used in GroupedLayerControl
# don't show up in the regular LayerControl.
element.control = False
if exclusive_groups:
# only enable the first radio button
for element in sublist[1:]:
self.layers_untoggle.add(element.get_name())