Skip to content

Commit 800736a

Browse files
committed
Add the GeoMan plugin
The GeoMan plugin is like the Draw plugin, with extra functionality, such as support for Polygons with holes.
1 parent eda6118 commit 800736a

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed

folium/plugins/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from folium.plugins.float_image import FloatImage
1212
from folium.plugins.fullscreen import Fullscreen
1313
from folium.plugins.geocoder import Geocoder
14+
from folium.plugins.geoman import GeoMan
1415
from folium.plugins.groupedlayercontrol import GroupedLayerControl
1516
from folium.plugins.heat_map import HeatMap
1617
from folium.plugins.heat_map_withtime import HeatMapWithTime
@@ -49,6 +50,7 @@
4950
"FloatImage",
5051
"Fullscreen",
5152
"Geocoder",
53+
"GeoMan",
5254
"GroupedLayerControl",
5355
"HeatMap",
5456
"HeatMapWithTime",

folium/plugins/geoman.py

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
from branca.element import MacroElement
2+
3+
from folium.elements import JSCSSMixin
4+
from folium.template import Template
5+
from folium.utilities import remove_empty
6+
7+
8+
class GeoMan(JSCSSMixin, MacroElement):
9+
"""
10+
An Open Source Leaflet Plugin for editing polygons
11+
12+
Examples
13+
--------
14+
>>> m = folium.Map()
15+
>>> Geoman().add_to(m)
16+
17+
For more info please check
18+
https://github.com/geoman-io/leaflet-geoman/
19+
20+
"""
21+
22+
_template = Template(
23+
"""
24+
{% macro script(this, kwargs) %}
25+
{%- if this.feature_group %}
26+
var drawnItems_{{ this.get_name() }} =
27+
{{ this.feature_group.get_name() }};
28+
{%- else %}
29+
// FeatureGroup is to store editable layers.
30+
var drawnItems_{{ this.get_name() }} =
31+
new L.featureGroup().addTo(
32+
{{ this._parent.get_name() }}
33+
);
34+
{%- endif %}
35+
/* The global varianble below is needed to prevent streamlit-folium
36+
from barfing :-(
37+
*/
38+
var drawnItems = drawnItems_{{ this.get_name() }};
39+
40+
{{this._parent.get_name()}}.pm.addControls(
41+
{{this.options|tojavascript}}
42+
)
43+
drawnItems_{{ this.get_name() }}.eachLayer(function(layer){
44+
L.PM.reInitLayer(layer);
45+
{%- for event, handler in this.on.items() %}
46+
layer.on(
47+
"{{event}}",
48+
{{handler}}
49+
);
50+
{%- endfor %}
51+
});
52+
53+
{{ this._parent.get_name() }}.on("pm:create", function(e) {
54+
var layer = e.layer,
55+
type = e.layerType;
56+
57+
{%- for event, handler in this.on.items() %}
58+
layer.on(
59+
"{{event}}",
60+
{{handler}}
61+
);
62+
{%- endfor %}
63+
drawnItems_{{ this.get_name() }}.addLayer(layer);
64+
});
65+
{{ this._parent.get_name() }}.on("pm:remove", function(e) {
66+
var layer = e.layer,
67+
type = e.layerType;
68+
drawnItems_{{ this.get_name() }}.removeLayer(layer);
69+
});
70+
71+
{% endmacro %}
72+
"""
73+
)
74+
75+
default_js = [
76+
(
77+
"leaflet_geoman_js",
78+
"https://unpkg.com/@geoman-io/leaflet-geoman-free@latest/dist/leaflet-geoman.js",
79+
)
80+
]
81+
default_css = [
82+
(
83+
"leaflet_geoman_css",
84+
"https://unpkg.com/@geoman-io/leaflet-geoman-free@latest/dist/leaflet-geoman.css",
85+
)
86+
]
87+
88+
def __init__(
89+
self,
90+
position="topleft",
91+
feature_group=None,
92+
on=None,
93+
**kwargs,
94+
):
95+
super().__init__()
96+
self._name = "GeoMan"
97+
self.feature_group = feature_group
98+
self.on = on or {}
99+
self.options = remove_empty(
100+
position=position, layer_group=feature_group, **kwargs
101+
)

tests/plugins/test_geoman.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""
2+
Test GeoMan
3+
----------------
4+
5+
"""
6+
7+
import folium
8+
from folium import plugins
9+
from folium.template import Template
10+
from folium.utilities import normalize
11+
12+
13+
def test_geoman():
14+
m = folium.Map([47, 3], zoom_start=1)
15+
fs = plugins.GeoMan().add_to(m)
16+
17+
out = normalize(m._parent.render())
18+
19+
# verify that the GeoMan plugin was added to
20+
# the map
21+
tmpl = Template(
22+
"""
23+
{{this._parent.get_name()}}.pm.addControls(
24+
{{this.options|tojavascript}}
25+
)
26+
"""
27+
)
28+
29+
assert normalize(tmpl.render(this=fs)) in out

0 commit comments

Comments
 (0)