Skip to content

Commit 087d73b

Browse files
authored
Merge pull request #1760 from Conengmo/draggable-layer-control
Draggable layer control
2 parents 14c9d26 + 8f14c1f commit 087d73b

File tree

2 files changed

+65
-6
lines changed

2 files changed

+65
-6
lines changed

folium/map.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,9 @@ class LayerControl(MacroElement):
144144
autoZIndex : bool, default True
145145
If true the control assigns zIndexes in increasing order to all of
146146
its layers so that the order is preserved when switching them on/off.
147+
draggable: bool, default False
148+
By default the layer control has a fixed position. Set this argument
149+
to True to allow dragging the control around.
147150
**kwargs
148151
Additional (possibly inherited) options. See
149152
https://leafletjs.com/reference.html#control-layers
@@ -153,7 +156,7 @@ class LayerControl(MacroElement):
153156
_template = Template(
154157
"""
155158
{% macro script(this,kwargs) %}
156-
var {{ this.get_name() }} = {
159+
var {{ this.get_name() }}_layers = {
157160
base_layers : {
158161
{%- for key, val in this.base_layers.items() %}
159162
{{ key|tojson }} : {{val}},
@@ -165,12 +168,16 @@ class LayerControl(MacroElement):
165168
{%- endfor %}
166169
},
167170
};
168-
L.control.layers(
169-
{{ this.get_name() }}.base_layers,
170-
{{ this.get_name() }}.overlays,
171+
let {{ this.get_name() }} = L.control.layers(
172+
{{ this.get_name() }}_layers.base_layers,
173+
{{ this.get_name() }}_layers.overlays,
171174
{{ this.options|tojson }}
172175
).addTo({{this._parent.get_name()}});
173176
177+
{%- if this.draggable %}
178+
new L.Draggable({{ this.get_name() }}.getContainer()).enable();
179+
{%- endif %}
180+
174181
{% endmacro %}
175182
"""
176183
)
@@ -180,13 +187,15 @@ def __init__(
180187
position: str = "topright",
181188
collapsed: bool = True,
182189
autoZIndex: bool = True,
190+
draggable: bool = False,
183191
**kwargs: TypeJsonValue,
184192
):
185193
super().__init__()
186194
self._name = "LayerControl"
187195
self.options = parse_options(
188196
position=position, collapsed=collapsed, autoZIndex=autoZIndex, **kwargs
189197
)
198+
self.draggable = draggable
190199
self.base_layers: OrderedDict[str, str] = OrderedDict()
191200
self.overlays: OrderedDict[str, str] = OrderedDict()
192201

tests/test_map.py

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
import numpy as np
99
import pytest
1010

11-
from folium import Map
12-
from folium.map import CustomPane, Icon, Marker, Popup
11+
from folium import GeoJson, Map, TileLayer
12+
from folium.map import CustomPane, Icon, LayerControl, Marker, Popup
1313
from folium.utilities import normalize
1414

1515
tmpl = """
@@ -19,6 +19,56 @@
1919
""".format
2020

2121

22+
def test_layer_control_initialization():
23+
layer_control = LayerControl()
24+
assert layer_control._name == "LayerControl"
25+
assert layer_control.options["position"] == "topright"
26+
assert layer_control.options["collapsed"] is True
27+
assert layer_control.options["autoZIndex"] is True
28+
assert layer_control.draggable is False
29+
assert layer_control.base_layers == {}
30+
assert layer_control.overlays == {}
31+
32+
33+
def test_layer_control_reset():
34+
layer_control = LayerControl()
35+
layer_control.base_layers = {"Layer1": "layer1"}
36+
layer_control.overlays = {"Layer2": "layer2"}
37+
layer_control.reset()
38+
assert layer_control.base_layers == {}
39+
assert layer_control.overlays == {}
40+
41+
42+
def test_layer_control_render():
43+
m = Map(tiles=None)
44+
layer1 = TileLayer().add_to(m)
45+
layer2 = Marker([0, 0]).add_to(m)
46+
layer3 = GeoJson({}).add_to(m)
47+
layer1.control = True
48+
layer2.control = False
49+
layer3.control = True
50+
layer1.layer_name = "Layer1"
51+
layer2.layer_name = "Layer2"
52+
layer3.layer_name = "Layer3"
53+
layer1.get_name = lambda: "layer1"
54+
layer2.get_name = lambda: "layer2"
55+
layer3.get_name = lambda: "layer3"
56+
57+
layer_control = LayerControl().add_to(m)
58+
layer_control.render()
59+
60+
assert layer_control.base_layers == {"Layer1": "layer1"}
61+
assert layer_control.overlays == {"Layer3": "layer3"}
62+
63+
64+
def test_layer_control_draggable():
65+
m = Map(tiles=None)
66+
layer_control = LayerControl(draggable=True).add_to(m)
67+
expected = f"new L.Draggable({ layer_control.get_name() }.getContainer()).enable();"
68+
rendered = m.get_root().render()
69+
assert normalize(expected) in normalize(rendered)
70+
71+
2272
def test_popup_ascii():
2373
popup = Popup("Some text.")
2474
_id = list(popup.html._children.keys())[0]

0 commit comments

Comments
 (0)