1# -*- coding: utf-8 -*-
2
3from branca.element import MacroElement
4
5from folium.elements import JSCSSMixin
6from folium.folium import Map
7from folium.utilities import get_obj_in_upper_tree, parse_options
8
9from jinja2 import Template
10
11
12class StripePattern(JSCSSMixin, MacroElement):
13    """Fill Pattern for polygon composed of alternating lines.
14
15    Add these to the 'fillPattern' field in GeoJson style functions.
16
17    Parameters
18    ----------
19    angle: float, default 0.5
20        Angle of the line pattern (degrees). Should be between -360 and 360.
21    weight: float, default 4
22        Width of the main lines (pixels).
23    space_weight: float
24        Width of the alternate lines (pixels).
25    color: string with hexadecimal, RGB, or named color, default "#000000"
26        Color of the main lines.
27    space_color: string with hexadecimal, RGB, or named color, default "#ffffff"
28        Color of the alternate lines.
29    opacity: float, default 0.75
30        Opacity of the main lines. Should be between 0 and 1.
31    space_opacity: float, default 0.0
32        Opacity of the alternate lines. Should be between 0 and 1.
33
34    See https://github.com/teastman/Leaflet.pattern for more information.
35    """
36
37    _template = Template(u"""
38        {% macro script(this, kwargs) %}
39            var {{ this.get_name() }} = new L.StripePattern(
40                {{ this.options|tojson }}
41            );
42            {{ this.get_name() }}.addTo({{ this.parent_map.get_name() }});
43        {% endmacro %}
44    """)
45
46    default_js = [
47        ('pattern',
48         'https://teastman.github.io/Leaflet.pattern/leaflet.pattern.js')
49    ]
50
51    def __init__(self, angle=.5, weight=4, space_weight=4,
52                 color="#000000", space_color="#ffffff",
53                 opacity=0.75, space_opacity=0.0, **kwargs):
54        super(StripePattern, self).__init__()
55        self._name = 'StripePattern'
56        self.options = parse_options(
57            angle=angle,
58            weight=weight,
59            space_weight=space_weight,
60            color=color,
61            space_color=space_color,
62            opacity=opacity,
63            space_opacity=space_opacity,
64            **kwargs
65        )
66        self.parent_map = None
67
68    def render(self, **kwargs):
69        self.parent_map = get_obj_in_upper_tree(self, Map)
70        super(StripePattern, self).render(**kwargs)
71
72
73class CirclePattern(JSCSSMixin, MacroElement):
74    """Fill Pattern for polygon composed of repeating circles.
75
76    Add these to the 'fillPattern' field in GeoJson style functions.
77
78    Parameters
79    ----------
80    width: int, default 20
81        Horizontal distance between circles (pixels).
82    height: int, default 20
83        Vertical distance between circles (pixels).
84    radius: int, default 12
85        Radius of each circle (pixels).
86    weight: float, default 2.0
87        Width of outline around each circle (pixels).
88    color: string with hexadecimal, RGB, or named color, default "#3388ff"
89        Color of the circle outline.
90    fill_color: string with hexadecimal, RGB, or named color, default "#3388ff"
91        Color of the circle interior.
92    opacity: float, default 0.75
93        Opacity of the circle outline. Should be between 0 and 1.
94    fill_opacity: float, default 0.5
95        Opacity of the circle interior. Should be between 0 and 1.
96
97    See https://github.com/teastman/Leaflet.pattern for more information.
98    """
99
100    _template = Template(u"""
101        {% macro script(this, kwargs) %}
102            var {{ this.get_name() }}_shape = new L.PatternCircle(
103                {{ this.options_pattern_circle|tojson }}
104            );
105            var {{ this.get_name() }} = new L.Pattern(
106                {{ this.options_pattern|tojson }}
107            );
108            {{ this.get_name() }}.addShape({{ this.get_name() }}_shape);
109            {{ this.get_name() }}.addTo({{ this.parent_map }});
110        {% endmacro %}
111    """)
112
113    default_js = [
114        ('pattern',
115         'https://teastman.github.io/Leaflet.pattern/leaflet.pattern.js')
116    ]
117
118    def __init__(self, width=20, height=20, radius=12, weight=2.0,
119                 color="#3388ff", fill_color="#3388ff",
120                 opacity=0.75, fill_opacity=0.5):
121        super(CirclePattern, self).__init__()
122        self._name = 'CirclePattern'
123        self.options_pattern_circle = parse_options(
124            x=radius + 2 * weight,
125            y=radius + 2 * weight,
126            weight=weight,
127            radius=radius,
128            color=color,
129            fill_color=fill_color,
130            opacity=opacity,
131            fill_opacity=fill_opacity,
132            fill=True,
133        )
134        self.options_pattern = parse_options(
135            width=width,
136            height=height,
137        )
138        self.parent_map = None
139
140    def render(self, **kwargs):
141        self.parent_map = get_obj_in_upper_tree(self, Map).get_name()
142        super(CirclePattern, self).render(**kwargs)
143