diff --git a/folium/__init__.py b/folium/__init__.py index 67489f8c50..249fafa397 100644 --- a/folium/__init__.py +++ b/folium/__init__.py @@ -36,6 +36,7 @@ FitOverlays, Icon, LayerControl, + LayerGroup, Marker, Popup, Tooltip, @@ -88,6 +89,7 @@ "JsCode", "LatLngPopup", "LayerControl", + "LayerGroup", "LinearColormap", "Link", "MacroElement", diff --git a/folium/map.py b/folium/map.py index 011025b6a4..ce2e561a5b 100644 --- a/folium/map.py +++ b/folium/map.py @@ -185,6 +185,57 @@ def __init__( self.options = remove_empty(**kwargs) +class LayerGroup(Layer): + """ + Create a LayerGroup layer ; you can put things in it and handle them + as a single layer. For example, you can add a LayerControl to + tick/untick the whole group. + + LayerGroup is the base class of FeatureGroup in Leaflet. + Unlike FeatureGroup, LayerGroup accepts custom options + that can be used in custom JavaScript code. + + Parameters + ---------- + name : str, default None + The name of the layer group layer. + It will be displayed in the LayerControl. + If None get_name() will be called to get the technical (ugly) name. + overlay : bool, default True + Whether your layer will be an overlay (ticked with a check box in + LayerControls) or a base layer (ticked with a radio button). + control: bool, default True + Whether the layer will be included in LayerControls. + show: bool, default True + Whether the layer will be shown on opening. + **kwargs + Additional (possibly inherited) options. See + https://leafletjs.com/reference.html#layergroup + + """ + + _template = Template(""" + {% macro script(this, kwargs) %} + var {{ this.get_name() }} = L.layerGroup( + {{ this.options|tojavascript }} + ); + {% endmacro %} + """) + + def __init__( + self, + name: Optional[str] = None, + overlay: bool = True, + control: bool = True, + show: bool = True, + **kwargs: TypeJsonValue, + ): + super().__init__(name=name, overlay=overlay, control=control, show=show) + self._name = "LayerGroup" + self.tile_name = name if name is not None else self.get_name() + self.options = remove_empty(**kwargs) + + class LayerControl(MacroElement): """ Creates a LayerControl object to be added on a folium map. diff --git a/tests/test_folium.py b/tests/test_folium.py index e424d277c7..0947da1350 100644 --- a/tests/test_folium.py +++ b/tests/test_folium.py @@ -171,6 +171,26 @@ def test_feature_group(self): bounds = m.get_bounds() assert bounds == [[45, -30], [45, 30]], bounds + def test_layer_group(self): + """Test LayerGroup.""" + + m = folium.Map() + layer_group = folium.LayerGroup( + name="my_layer_group", custom_option="test_value" + ) + layer_group.add_child(folium.Marker([45, -30], popup=folium.Popup("-30"))) + layer_group.add_child(folium.Marker([45, 30], popup=folium.Popup("30"))) + m.add_child(layer_group) + m.add_child(folium.LayerControl()) + + m._repr_html_() + + bounds = m.get_bounds() + assert bounds == [[45, -30], [45, 30]], bounds + html = m._repr_html_() + assert "L.layerGroup" in html + assert "my_layer_group" in html + def test_topo_json_smooth_factor(self): """Test topojson smooth factor method.""" self.m = folium.Map([43, -100], zoom_start=4)