55import json
66
77from branca .element import Element , Figure
8- from branca .utilities import image_to_url
98
109from folium .map import Layer
10+ from folium .utilities import image_to_url , mercator_transform
1111
1212from jinja2 import Template
1313
1414
15- def mercator_transform (data , lat_bounds , origin = 'upper' , height_out = None ):
16- """
17- Transforms an image computed in (longitude,latitude) coordinates into
18- the a Mercator projection image.
19-
20- Parameters
21- ----------
22-
23- data: numpy array or equivalent list-like object.
24- Must be NxM (mono), NxMx3 (RGB) or NxMx4 (RGBA)
25-
26- lat_bounds : length 2 tuple
27- Minimal and maximal value of the latitude of the image.
28- Bounds must be between -85.051128779806589 and 85.051128779806589
29- otherwise they will be clipped to that values.
30-
31- origin : ['upper' | 'lower'], optional, default 'upper'
32- Place the [0,0] index of the array in the upper left or lower left
33- corner of the axes.
34-
35- height_out : int, default None
36- The expected height of the output.
37- If None, the height of the input is used.
38-
39- See https://en.wikipedia.org/wiki/Web_Mercator for more details.
40-
41- """
42- import numpy as np
43-
44- def mercator (x ):
45- return np .arcsinh (np .tan (x * np .pi / 180. ))* 180. / np .pi
46-
47- array = np .atleast_3d (data ).copy ()
48- height , width , nblayers = array .shape
49-
50- lat_min = max (lat_bounds [0 ], - 85.051128779806589 )
51- lat_max = min (lat_bounds [1 ], 85.051128779806589 )
52- if height_out is None :
53- height_out = height
54-
55- # Eventually flip the image
56- if origin == 'upper' :
57- array = array [::- 1 , :, :]
58-
59- lats = (lat_min + np .linspace (0.5 / height , 1. - 0.5 / height , height ) *
60- (lat_max - lat_min ))
61- latslats = (mercator (lat_min ) +
62- np .linspace (0.5 / height_out , 1. - 0.5 / height_out , height_out ) *
63- (mercator (lat_max )- mercator (lat_min )))
64-
65- out = np .zeros ((height_out , width , nblayers ))
66- for i in range (width ):
67- for j in range (nblayers ):
68- out [:, i , j ] = np .interp (latslats , mercator (lats ), array [:, i , j ])
69-
70- # Eventually flip the image.
71- if origin == 'upper' :
72- out = out [::- 1 , :, :]
73- return out
74-
7515
7616class ImageOverlay (Layer ):
7717 """
@@ -91,47 +31,56 @@ class ImageOverlay(Layer):
9131 Image bounds on the map in the form [[lat_min, lon_min],
9232 [lat_max, lon_max]]
9333 opacity: float, default Leaflet's default (1.0)
94- attr : string, default Leaflet's default ("" )
95- origin : ['upper' | 'lower'], optional, default 'upper'
34+ alt : string, default Leaflet's default ('' )
35+ origin: ['upper' | 'lower'], optional, default 'upper'
9636 Place the [0,0] index of the array in the upper left or
9737 lower left corner of the axes.
98- colormap : callable, used only for `mono` image.
38+ colormap: callable, used only for `mono` image.
9939 Function of the form [x -> (r,g,b)] or [x -> (r,g,b,a)]
10040 for transforming a mono image into RGB.
10141 It must output iterables of length 3 or 4,
10242 with values between 0 and 1.
103- Hint : you can use colormaps from `matplotlib.cm`.
104- mercator_project : bool, default False.
43+ Hint: you can use colormaps from `matplotlib.cm`.
44+ mercator_project: bool, default False.
10545 Used only for array-like image. Transforms the data to
10646 project (longitude, latitude) coordinates to the
10747 Mercator projection.
10848 Beware that this will only work if `image` is an array-like
10949 object.
50+ pixelated: bool, default True
51+ Sharp sharp/crips (True) or aliased corners (False).
52+
53+ See http://leafletjs.com/reference-1.2.0.html#imageoverlay for more options.
11054
11155 """
112- def __init__ (self , image , bounds , opacity = 1. , attr = None ,
113- origin = 'upper' , colormap = None , mercator_project = False ,
114- overlay = True , control = True , pixelated = True ):
115- super (ImageOverlay , self ).__init__ (overlay = overlay , control = control )
56+ def __init__ (self , image , bounds , origin = 'upper' , colormap = None ,
57+ mercator_project = False , overlay = True , control = True ,
58+ pixelated = True , name = None , ** kwargs ):
59+ super (ImageOverlay , self ).__init__ (overlay = overlay , control = control , name = name ) # noqa
60+
61+ options = {
62+ 'opacity' : kwargs .pop ('opacity' , 1. ),
63+ 'alt' : kwargs .pop ('alt' , '' ),
64+ 'interactive' : kwargs .pop ('interactive' , False ),
65+ 'crossOrigin' : kwargs .pop ('cross_origin' , False ),
66+ 'errorOverlayUrl' : kwargs .pop ('error_overlay_url' , '' ),
67+ 'zIndex' : kwargs .pop ('zindex' , 1 ),
68+ 'className' : kwargs .pop ('class_name' , '' ),
69+ }
11670 self ._name = 'ImageOverlay'
117- self .overlay = overlay
11871 self .pixelated = pixelated
11972
12073 if mercator_project :
121- image = mercator_transform (image ,
122- [bounds [0 ][0 ], bounds [1 ][0 ]],
123- origin = origin )
74+ image = mercator_transform (
75+ image ,
76+ [bounds [0 ][0 ],
77+ bounds [1 ][0 ]],
78+ origin = origin )
12479
12580 self .url = image_to_url (image , origin = origin , colormap = colormap )
12681
12782 self .bounds = json .loads (json .dumps (bounds ))
128- options = {
129- 'opacity' : opacity ,
130- 'attribution' : attr ,
131- }
132- self .options = json .dumps ({key : val for key , val
133- in options .items () if val },
134- sort_keys = True )
83+ self .options = json .dumps (options , sort_keys = True , indent = 2 )
13584 self ._template = Template (u"""
13685 {% macro script(this, kwargs) %}
13786 var {{this.get_name()}} = L.imageOverlay(
@@ -160,7 +109,7 @@ def render(self, **kwargs):
160109 </style>"""
161110
162111 if self .pixelated :
163- figure .header .add_child (Element (pixelated ), name = 'leaflet-image-layer' )
112+ figure .header .add_child (Element (pixelated ), name = 'leaflet-image-layer' ) # noqa
164113
165114 def _get_self_bounds (self ):
166115 """
0 commit comments