Skip to content

Commit ec58d0d

Browse files
authored
Merge pull request #474 from ocefpaf/text_path
Text path
2 parents 574d020 + 591b83a commit ec58d0d

4 files changed

Lines changed: 225 additions & 1 deletion

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# -*- coding: utf-8 -*-
2+
import folium
3+
from folium import plugins
4+
5+
m = folium.Map([30., 0.], zoom_start=3)
6+
wind_locations = [[59.35560, -31.992190],
7+
[55.178870, -42.89062],
8+
[47.754100, -43.94531],
9+
[38.272690, -37.96875],
10+
[27.059130, -41.13281],
11+
[16.299050, -36.56250],
12+
[8.4071700, -30.23437],
13+
[1.0546300, -22.50000],
14+
[-8.754790, -18.28125],
15+
[-21.61658, -20.03906],
16+
[-31.35364, -24.25781],
17+
[-39.90974, -30.93750],
18+
[-43.83453, -41.13281],
19+
[-47.75410, -49.92187],
20+
[-50.95843, -54.14062],
21+
[-55.97380, -56.60156]]
22+
23+
wind_line = folium.PolyLine(wind_locations,
24+
weight=15,
25+
color='#8EE9FF').add_to(m)
26+
attr = {'fill': '#007DEF', 'font-weight': 'bold', 'font-size': '24'}
27+
plugins.PolyLineTextPath(wind_line,
28+
") ",
29+
repeat=True,
30+
offset=7,
31+
attributes=attr).add_to(m)
32+
33+
danger_line = folium.PolyLine([[-40.311, -31.952],
34+
[-12.086, -18.727]],
35+
weight=10,
36+
color='orange',
37+
opacity=0.8).add_to(m)
38+
attr = {'fill': 'red'}
39+
plugins.PolyLineTextPath(danger_line,
40+
"\u25BA",
41+
repeat=True,
42+
offset=6,
43+
attributes=attr).add_to(m)
44+
45+
plane_line = folium.PolyLine([[-49.38237, -37.26562],
46+
[-1.75754, -14.41406],
47+
[51.61802, -23.20312]],
48+
weight=1, color='black').add_to(m)
49+
attr = {'font-weight': 'bold', 'font-size': '24'}
50+
plugins.PolyLineTextPath(plane_line,
51+
"\u2708 ",
52+
repeat=True,
53+
offset=8,
54+
attributes=attr).add_to(m)
55+
56+
line_to_new_delhi = folium.PolyLine([[46.67959447, 3.33984375],
57+
[46.5588603, 29.53125],
58+
[42.29356419, 51.328125],
59+
[35.74651226, 68.5546875],
60+
[28.65203063, 76.81640625]]).add_to(m)
61+
62+
line_to_hanoi = folium.PolyLine([[28.76765911, 77.60742188],
63+
[27.83907609, 88.72558594],
64+
[25.68113734, 97.3828125],
65+
[21.24842224, 105.77636719]]).add_to(m)
66+
67+
plugins.PolyLineTextPath(line_to_new_delhi,
68+
"To New Delhi",
69+
offset=-5).add_to(m)
70+
plugins.PolyLineTextPath(line_to_hanoi, "To Hanoi", offset=-5).add_to(m)
71+
72+
m.save(outfile='polyline_text.html')

folium/plugins/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from .heat_map import HeatMap
1515
from .image_overlay import ImageOverlay
1616
from .fullscreen import Fullscreen
17+
from .polyline_text_path import PolyLineTextPath
1718

1819
__all__ = ['MarkerCluster',
1920
'ScrollZoomToggler',
@@ -22,4 +23,5 @@
2223
'TimestampedGeoJson',
2324
'HeatMap',
2425
'ImageOverlay',
25-
'Fullscreen']
26+
'Fullscreen',
27+
'PolyLineTextPath']
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
PolyLine Text Path
4+
-----------
5+
6+
https://github.com/makinacorpus/Leaflet.TextPath
7+
8+
Shows a text along a PolyLine.
9+
10+
"""
11+
from jinja2 import Template
12+
13+
from branca.element import JavascriptLink, Figure
14+
from folium.features import MacroElement
15+
16+
17+
class PolyLineTextPath(MacroElement):
18+
"""Shows a text along a PolyLine."""
19+
def __init__(self, polyline, text, repeat=False, center=False, below=False,
20+
offset=0, orientation=0, attributes={}):
21+
"""Shows a text along a PolyLine.
22+
23+
Parameters
24+
----------
25+
polyline: folium.features.PolyLine object
26+
The folium.features.PolyLine object to attach the text to.
27+
28+
text: string
29+
The string to be attached to the polyline.
30+
31+
repeat: bool, default False
32+
Specifies if the text should be repeated along the polyline.
33+
34+
center: bool, default False
35+
Centers the text according to the polyline's bounding box
36+
37+
below: bool, default False
38+
Show text below the path
39+
40+
offset: int, default 0
41+
Set an offset to position text relative to the polyline.
42+
43+
orientation: int, default 0
44+
Rotate text to a specified angle.
45+
46+
attributes: dictionary
47+
Object containing the attributes applied to the text tag.
48+
Check valid attributes here:
49+
https://developer.mozilla.org/en-US/docs/Web/SVG/Element/text#Attributes
50+
Example: {'fill': '#007DEF', 'font-weight': 'bold', 'font-size': '24'}
51+
52+
53+
"""
54+
super(PolyLineTextPath, self).__init__()
55+
self._name = 'PolyLineTextPath'
56+
self.polyline = polyline
57+
self.text = text
58+
self.repeat = bool(repeat)
59+
self.center = bool(center)
60+
self.below = bool(below)
61+
self.orientation = orientation
62+
self.offset = offset
63+
self.attributes = attributes
64+
65+
self._template = Template(u"""
66+
{% macro script(this, kwargs) %}
67+
{{this.polyline.get_name()}}.setText("{{this.text}}", {
68+
repeat: {{'true' if this.repeat else 'false'}},
69+
center: {{'true' if this.center else 'false'}},
70+
below: {{'true' if this.below else 'false'}},
71+
offset: {{this.offset}},
72+
orientation: {{this.orientation}},
73+
attributes: {{this.attributes}}
74+
});
75+
{% endmacro %}
76+
""") # noqa
77+
78+
def render(self, **kwargs):
79+
super(PolyLineTextPath, self).render(**kwargs)
80+
81+
figure = self.get_root()
82+
assert isinstance(figure, Figure), ("You cannot render this Element "
83+
"if it's not in a Figure.")
84+
85+
figure.header.add_child(
86+
JavascriptLink("https://rawgit.com/makinacorpus/Leaflet.TextPath/gh-pages/leaflet.textpath.js"), # noqa
87+
name='polylinetextpath')
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Test PolyLineTextPath
4+
---------------
5+
"""
6+
7+
from jinja2 import Template
8+
9+
import folium
10+
from folium import plugins
11+
12+
13+
def test_polyline_text_path():
14+
m = folium.Map([20., 0.], zoom_start=3)
15+
16+
wind_locations = [[59.355600, -31.99219],
17+
[55.178870, -42.89062],
18+
[47.754100, -43.94531],
19+
[38.272690, -37.96875],
20+
[27.059130, -41.13281],
21+
[16.299050, -36.56250],
22+
[8.4071700, -30.23437],
23+
[1.0546300, -22.50000],
24+
[-8.754790, -18.28125],
25+
[-21.61658, -20.03906],
26+
[-31.35364, -24.25781],
27+
[-39.90974, -30.93750],
28+
[-43.83453, -41.13281],
29+
[-47.75410, -49.92187],
30+
[-50.95843, -54.14062],
31+
[-55.97380, -56.60156]]
32+
33+
wind_line = folium.PolyLine(wind_locations, weight=15, color='#8EE9FF')
34+
attr = {'fill': '#007DEF', 'font-weight': 'bold', 'font-size': '24'}
35+
wind_textpath = plugins.PolyLineTextPath(wind_line,
36+
") ",
37+
repeat=True,
38+
offset=7,
39+
attributes=attr)
40+
41+
m.add_child(wind_line)
42+
m.add_child(wind_textpath)
43+
m._repr_html_()
44+
45+
out = m._parent.render()
46+
47+
# We verify that the script import is present.
48+
script = '<script src="https://rawgit.com/makinacorpus/Leaflet.TextPath/gh-pages/leaflet.textpath.js"></script>' # noqa
49+
assert script in out
50+
51+
# We verify that the script part is correct.
52+
tmpl = Template("""
53+
{{this.polyline.get_name()}}.setText("{{this.text}}", {
54+
repeat: {{'true' if this.repeat else 'false'}},
55+
center: {{'true' if this.center else 'false'}},
56+
below: {{'true' if this.below else 'false'}},
57+
offset: {{this.offset}},
58+
orientation: {{this.orientation}},
59+
attributes: {{this.attributes}}
60+
});
61+
""") # noqa
62+
63+
assert tmpl.render(this=wind_textpath) in out

0 commit comments

Comments
 (0)