5
5
import json
6
6
7
7
from branca .element import Element , Figure
8
- from branca .utilities import image_to_url
9
8
10
9
from folium .map import Layer
10
+ from folium .utilities import image_to_url , mercator_transform
11
11
12
12
from jinja2 import Template
13
13
14
14
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
-
75
15
76
16
class ImageOverlay (Layer ):
77
17
"""
@@ -91,47 +31,56 @@ class ImageOverlay(Layer):
91
31
Image bounds on the map in the form [[lat_min, lon_min],
92
32
[lat_max, lon_max]]
93
33
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'
96
36
Place the [0,0] index of the array in the upper left or
97
37
lower left corner of the axes.
98
- colormap : callable, used only for `mono` image.
38
+ colormap: callable, used only for `mono` image.
99
39
Function of the form [x -> (r,g,b)] or [x -> (r,g,b,a)]
100
40
for transforming a mono image into RGB.
101
41
It must output iterables of length 3 or 4,
102
42
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.
105
45
Used only for array-like image. Transforms the data to
106
46
project (longitude, latitude) coordinates to the
107
47
Mercator projection.
108
48
Beware that this will only work if `image` is an array-like
109
49
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.
110
54
111
55
"""
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
+ }
116
70
self ._name = 'ImageOverlay'
117
- self .overlay = overlay
118
71
self .pixelated = pixelated
119
72
120
73
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 )
124
79
125
80
self .url = image_to_url (image , origin = origin , colormap = colormap )
126
81
127
82
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 )
135
84
self ._template = Template (u"""
136
85
{% macro script(this, kwargs) %}
137
86
var {{this.get_name()}} = L.imageOverlay(
@@ -160,7 +109,7 @@ def render(self, **kwargs):
160
109
</style>"""
161
110
162
111
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
164
113
165
114
def _get_self_bounds (self ):
166
115
"""
0 commit comments