Skip to content

Commit ba37029

Browse files
committed
DivIcons
1 parent 9fe7593 commit ba37029

File tree

1 file changed

+92
-48
lines changed

1 file changed

+92
-48
lines changed

folium/features.py

Lines changed: 92 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ def __init__(self, url, name=None,
4848
).addTo({{this._parent.get_name()}});
4949
5050
{% endmacro %}
51-
""")
51+
""") # noqa
5252

5353

5454
class RegularPolygonMarker(MacroElement):
@@ -99,7 +99,7 @@ def render(self, **kwargs):
9999
"if it's not in a Figure.")
100100

101101
figure.header.add_children(
102-
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/leaflet-dvf/0.2/leaflet-dvf.markers.min.js"),
102+
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/leaflet-dvf/0.2/leaflet-dvf.markers.min.js"), # noqa
103103
name='dvf_js')
104104

105105

@@ -145,11 +145,11 @@ def render(self, **kwargs):
145145
""").render(this=self, **kwargs)), name=self.get_name())
146146

147147
figure.header.add_children(
148-
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"),
148+
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"), # noqa
149149
name='d3')
150150

151151
figure.header.add_children(
152-
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/vega/1.4.3/vega.min.js"),
152+
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/vega/1.4.3/vega.min.js"), # noqa
153153
name='vega')
154154

155155
figure.header.add_children(
@@ -158,7 +158,7 @@ def render(self, **kwargs):
158158

159159
figure.script.add_children(
160160
Template("""function vega_parse(spec, div) {
161-
vg.parse.spec(spec, function(chart) { chart({el:div}).update(); });}"""),
161+
vg.parse.spec(spec, function(chart) { chart({el:div}).update(); });}"""), # noqa
162162
name='vega_parse')
163163

164164

@@ -170,20 +170,21 @@ def __init__(self, data):
170170
Parameters
171171
----------
172172
data: file, dict or str.
173-
The geo-json data you want to plot.
174-
If file, then data will be read in the file and fully embedded in Leaflet's javascript.
175-
If dict, then data will be converted to JSON and embedded in the javascript.
176-
If str, then data will be passed to the javascript as-is.
173+
The GeoJSON data you want to plot.
174+
* If file, then data will be read in the file and fully
175+
embedded in Leaflet's JavaScript.
176+
* If dict, then data will be converted to JSON and embedded
177+
in the JavaScript.
178+
* If str, then data will be passed to the JavaScript as-is.
179+
180+
Examples:
181+
>>> # Providing file.
182+
>>> GeoJson(open('foo.json'))
183+
>>> # Providing dict.
184+
>>> GeoJson(json.load(open('foo.json')))
185+
>>> # Providing string.
186+
>>> GeoJson(open('foo.json').read())
177187
178-
examples :
179-
# providing file
180-
GeoJson(open('foo.json'))
181-
182-
# providing dict
183-
GeoJson(json.load(open('foo.json')))
184-
185-
# providing string
186-
GeoJson(open('foo.json').read())
187188
"""
188189
super(GeoJson, self).__init__()
189190
self._name = 'GeoJson'
@@ -198,7 +199,7 @@ def __init__(self, data):
198199
{% macro script(this, kwargs) %}
199200
var {{this.get_name()}} = L.geoJson({{this.data}}).addTo({{this._parent.get_name()}});
200201
{% endmacro %}
201-
""")
202+
""") # noqa
202203

203204

204205
class TopoJson(MacroElement):
@@ -234,7 +235,7 @@ def render(self, **kwargs):
234235
"if it's not in a Figure.")
235236

236237
figure.header.add_children(
237-
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js"),
238+
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js"), # noqa
238239
name='topojson')
239240

240241

@@ -306,7 +307,7 @@ def render(self, **kwargs):
306307
"if it's not in a Figure.")
307308

308309
figure.header.add_children(
309-
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"),
310+
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"), # noqa
310311
name='d3')
311312

312313

@@ -334,7 +335,7 @@ def render(self, **kwargs):
334335
"if it's not in a Figure.")
335336

336337
figure.header.add_children(
337-
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"),
338+
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"), # noqa
338339
name='d3')
339340

340341

@@ -363,39 +364,73 @@ def render(self, **kwargs):
363364
assert isinstance(figure, Figure), ("You cannot render this Element "
364365
"if it's not in a Figure.")
365366
figure.header.add_children(
366-
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/leaflet.markercluster-src.js"),
367+
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/leaflet.markercluster-src.js"), # noqa
367368
name='marker_cluster_src')
368369

369370
figure.header.add_children(
370-
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/leaflet.markercluster.js"),
371+
JavascriptLink("https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/leaflet.markercluster.js"), # noqa
371372
name='marker_cluster')
372373

373374
figure.header.add_children(
374-
CssLink("https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/MarkerCluster.css"),
375+
CssLink("https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/MarkerCluster.css"), # noqa
375376
name='marker_cluster_css')
376377

377378
figure.header.add_children(
378-
CssLink("https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/MarkerCluster.Default.css"),
379+
CssLink("https://cdnjs.cloudflare.com/ajax/libs/leaflet.markercluster/0.4.0/MarkerCluster.Default.css"), # noqa
379380
name="marker_cluster_default_css")
380381

381382

382-
class DivIcon(MacroElement):
383-
def __init__(self, width=30, height=30):
384-
"""TODO : docstring here"""
383+
class DivIcon(Icon):
384+
def __init__(self, html=None, icon_size=None, icon_anchor=None,
385+
popup_anchor=None, class_name='empty'):
386+
"""
387+
Represents a lightweight icon for markers that uses a simple `div`
388+
element instead of an image.
389+
390+
Parameters
391+
----------
392+
icon_size : tuple of 2 int
393+
Size of the icon image in pixels.
394+
icon_anchor : tuple of 2 int
395+
The coordinates of the "tip" of the icon
396+
(relative to its top left corner).
397+
The icon will be aligned so that this point is at the
398+
marker's geographical location.
399+
popup_anchor : tuple of 2 int
400+
The coordinates of the point from which popups will "open",
401+
relative to the icon anchor.
402+
class_name : string
403+
A custom class name to assign to the icon.
404+
Leaflet defaults is 'leaflet-div-icon' which draws a little white
405+
square with a shadow. We set it 'empty' in folium.
406+
html : string
407+
A custom HTML code to put inside the div element.
408+
409+
For more information see:
410+
http://leafletjs.com/reference.html#divicon
411+
412+
"""
385413
super(DivIcon, self).__init__()
386414
self._name = 'DivIcon'
387-
self.width = width
388-
self.height = height
415+
self.icon_size = icon_size
416+
self.icon_anchor = icon_anchor
417+
self.popup_anchor = popup_anchor
418+
self.html = html
419+
self.className = class_name
389420

390421
self._template = Template(u"""
391422
{% macro script(this, kwargs) %}
423+
392424
var {{this.get_name()}} = L.divIcon({
393-
className: 'leaflet-div-icon',
394-
'iconSize': [{{ this.width }},{{ this.height }}]
425+
{% if this.icon_size %}iconSize: [{{this.icon_size[0]}},{{this.icon_size[1]}}],{% endif %}
426+
{% if this.icon_anchor %}iconAnchor: [{{this.icon_anchor[0]}},{{this.icon_anchor[1]}}],{% endif %}
427+
{% if this.popup_anchor %}popupAnchor: [{{this.popup_anchor[0]}},{{this.popup_anchor[1]}}],{% endif %}
428+
{% if this.className %}className: '{{this.className}}',{% endif %}
429+
{% if this.html %}html: '{{this.html}}',{% endif %}
395430
});
396431
{{this._parent.get_name()}}.setIcon({{this.get_name()}});
397432
{% endmacro %}
398-
""")
433+
""") # noqa
399434

400435

401436
class CircleMarker(MacroElement):
@@ -449,7 +484,7 @@ def __init__(self):
449484
}
450485
{{this._parent.get_name()}}.on('click', latLngPop);
451486
{% endmacro %}
452-
""")
487+
""") # noqa
453488

454489

455490
class ClickForMarker(MacroElement):
@@ -476,7 +511,7 @@ def __init__(self, popup=None):
476511
};
477512
{{this._parent.get_name()}}.on('click', newMarker);
478513
{% endmacro %}
479-
""")
514+
""") # noqa
480515

481516

482517
class PolyLine(MacroElement):
@@ -517,7 +552,7 @@ def __init__(self, locations, color=None, weight=None,
517552
});
518553
{{this._parent.get_name()}}.addLayer({{this.get_name()}});
519554
{% endmacro %}
520-
""")
555+
""") # noqa
521556

522557

523558
class MultiPolyLine(MacroElement):
@@ -558,7 +593,7 @@ def __init__(self, locations, color=None, weight=None,
558593
});
559594
{{this._parent.get_name()}}.addLayer({{this.get_name()}});
560595
{% endmacro %}
561-
""")
596+
""") # noqa
562597

563598

564599
class ImageOverlay(MacroElement):
@@ -572,10 +607,13 @@ def __init__(self, image, bounds, opacity=1., attribution=None,
572607
image: string, file or array-like object
573608
The data you want to draw on the map.
574609
* If string, it will be written directly in the output file.
575-
* If file, it's content will be converted as embeded in the output file.
576-
* If array-like, it will be converted to PNG base64 string and embedded in the output.
610+
* If file, it's content will be converted as embedded in the
611+
output file.
612+
* If array-like, it will be converted to PNG base64 string
613+
and embedded in the output.
577614
bounds: list
578-
Image bounds on the map in the form [[lat_min, lon_min], [lat_max, lon_max]]
615+
Image bounds on the map in the form [[lat_min, lon_min],
616+
[lat_max, lon_max]]
579617
opacity: float, default Leaflet's default (1.0)
580618
attr: string, default Leaflet's default ("")
581619
origin : ['upper' | 'lower'], optional, default 'upper'
@@ -584,11 +622,14 @@ def __init__(self, image, bounds, opacity=1., attribution=None,
584622
colormap : callable, used only for `mono` image.
585623
Function of the form [x -> (r,g,b)] or [x -> (r,g,b,a)]
586624
for transforming a mono image into RGB.
587-
It must output iterables of length 3 or 4, with values between 0. and 1.
625+
It must output iterables of length 3 or 4,
626+
with values between 0 and 1.
588627
Hint : you can use colormaps from `matplotlib.cm`.
589-
mercator_project : bool, default False, used only for array-like image.
590-
Transforms the data to project (longitude, latitude)
591-
coordinates to the Mercator projection.
628+
mercator_project : bool, default False.
629+
Used only for array-like image. Transforms the data to
630+
project (longitude, latitude) coordinates to the
631+
Mercator projection.
632+
592633
"""
593634
super(ImageOverlay, self).__init__()
594635
self._name = 'ImageOverlay'
@@ -627,8 +668,10 @@ def __init__(self, icon_image, icon_size=None, icon_anchor=None,
627668
icon_image : string, file or array-like object
628669
The data you want to use as an icon.
629670
* If string, it will be written directly in the output file.
630-
* If file, it's content will be converted as embedded in the output file.
631-
* If array-like, it will be converted to PNG base64 string and embedded in the output.
671+
* If file, it's content will be converted as embedded in the
672+
output file.
673+
* If array-like, it will be converted to PNG base64 string
674+
and embedded in the output.
632675
icon_size : tuple of 2 int
633676
Size of the icon image in pixels.
634677
icon_anchor : tuple of 2 int
@@ -647,6 +690,7 @@ def __init__(self, icon_image, icon_size=None, icon_anchor=None,
647690
popup_anchor : tuple of 2 int
648691
The coordinates of the point from which popups will "open",
649692
relative to the icon anchor.
693+
650694
"""
651695
super(Icon, self).__init__()
652696
self._name = 'CustomIcon'
@@ -676,4 +720,4 @@ def __init__(self, icon_image, icon_size=None, icon_anchor=None,
676720
});
677721
{{this._parent.get_name()}}.setIcon({{this.get_name()}});
678722
{% endmacro %}
679-
""")
723+
""") # noqa

0 commit comments

Comments
 (0)