17
17
from .element import Element , Figure , JavascriptLink , CssLink , MacroElement
18
18
from .map import Layer , Icon , Marker , Popup
19
19
20
+
20
21
class WmsTileLayer (Layer ):
21
22
def __init__ (self , url , name = None ,
22
23
format = None , layers = None , transparent = True ,
@@ -49,6 +50,7 @@ def __init__(self, url, name=None,
49
50
{% endmacro %}
50
51
""" ) # noqa
51
52
53
+
52
54
class RegularPolygonMarker (Marker ):
53
55
def __init__ (self , location , color = 'black' , opacity = 1 , weight = 2 ,
54
56
fill_color = 'blue' , fill_opacity = 1 ,
@@ -128,6 +130,7 @@ def render(self, **kwargs):
128
130
JavascriptLink ("https://cdnjs.cloudflare.com/ajax/libs/leaflet-dvf/0.2/leaflet-dvf.markers.min.js" ), # noqa
129
131
name = 'dvf_js' )
130
132
133
+
131
134
class Vega (Element ):
132
135
def __init__ (self , data , width = None , height = None ,
133
136
left = "0%" , top = "0%" , position = 'relative' ):
@@ -137,13 +140,16 @@ def __init__(self, data, width=None, height=None,
137
140
"""
138
141
super (Vega , self ).__init__ ()
139
142
self ._name = 'Vega'
140
- self .data = data .to_json () if hasattr (data ,'to_json' ) else data
141
- if isinstance (self .data ,text_type ) or isinstance (data ,binary_type ):
143
+ self .data = data .to_json () if hasattr (data , 'to_json' ) else data
144
+ # FIXME:
145
+ if isinstance (self .data , text_type ) or isinstance (data , binary_type ):
142
146
self .data = json .loads (self .data )
143
147
144
148
# Size Parameters.
145
- self .width = _parse_size (self .data .get ('width' ,'100%' ) if width is None else width )
146
- self .height = _parse_size (self .data .get ('height' ,'100%' ) if height is None else height )
149
+ self .width = _parse_size (self .data .get ('width' , '100%' ) if
150
+ width is None else width )
151
+ self .height = _parse_size (self .data .get ('height' , '100%' ) if
152
+ height is None else height )
147
153
self .left = _parse_size (left )
148
154
self .top = _parse_size (top )
149
155
self .position = position
@@ -191,6 +197,7 @@ def render(self, **kwargs):
191
197
vg.parse.spec(spec, function(chart) { chart({el:div}).update(); });}""" ), # noqa
192
198
name = 'vega_parse' )
193
199
200
+
194
201
class GeoJson (MacroElement ):
195
202
def __init__ (self , data , style_function = None ):
196
203
"""
@@ -220,20 +227,22 @@ def __init__(self, data, style_function=None):
220
227
>>> # Providing string.
221
228
>>> GeoJson(open('foo.json').read())
222
229
223
- >>> # Providing a style_function that put all states in green, but Alabama in blue.
224
- >>> style_function=lambda x: {'fillColor': '#0000ff' if x['properties']['name']=='Alabama' else '#00ff00'}
230
+ >>> # Provide a style_function that color all states green but Alabama.
231
+ >>> style_function = lambda x: {'fillColor': '#0000ff' if
232
+ ... x['properties']['name']=='Alabama' else
233
+ ... '#00ff00'}
225
234
>>> GeoJson(geojson, style_function=style_function)
226
235
"""
227
236
super (GeoJson , self ).__init__ ()
228
237
self ._name = 'GeoJson'
229
- if hasattr (data ,'read' ):
238
+ if hasattr (data , 'read' ):
230
239
self .embed = True
231
240
self .data = json .load (data )
232
- elif isinstance (data ,dict ):
241
+ elif isinstance (data , dict ):
233
242
self .embed = True
234
243
self .data = data
235
244
elif isinstance (data , text_type ) or isinstance (data , binary_type ):
236
- if data .lstrip ()[0 ] in '[{' : # This is a GeoJSON inline string
245
+ if data .lstrip ()[0 ] in '[{' : # This is a GeoJSON inline string
237
246
self .embed = True
238
247
self .data = json .loads (data )
239
248
else : # This is a filename
@@ -242,18 +251,19 @@ def __init__(self, data, style_function=None):
242
251
elif data .__class__ .__name__ in ['GeoDataFrame' , 'GeoSeries' ]:
243
252
self .embed = True
244
253
if hasattr (data , '__geo_interface__' ):
245
- # We have a GeoPandas 0.2 object
246
- self .data = json .loads (json .dumps (data .to_crs (epsg = '4326' ).__geo_interface__ ))
254
+ # We have a GeoPandas 0.2 object.
255
+ self .data = json .loads (json .dumps (data .to_crs (epsg = '4326' ).__geo_interface__ )) # noqa
247
256
elif hasattr (data , 'columns' ):
248
257
# We have a GeoDataFrame 0.1
249
258
self .data = json .loads (data .to_crs (epsg = '4326' ).to_json ())
250
259
else :
251
- raise ValueError ('Unable to transform this object to a GeoJSON.' )
260
+ msg = 'Unable to transform this object to a GeoJSON.'
261
+ raise ValueError (msg )
252
262
else :
253
263
raise ValueError ('Unhandled object {!r}.' .format (data ))
254
264
255
265
if style_function is None :
256
- style_function = lambda x : {}
266
+ def style_function ( x ): return {}
257
267
self .style_function = style_function
258
268
259
269
self ._template = Template (u"""
@@ -268,14 +278,13 @@ def __init__(self, data, style_function=None):
268
278
def style_data (self ):
269
279
if 'features' not in self .data .keys ():
270
280
# Catch case when GeoJSON is just a single Feature or a geometry.
271
- if not (isinstance (self .data , dict ) and 'geometry' in self .data .keys ()):
281
+ if not (isinstance (self .data , dict ) and 'geometry' in self .data .keys ()): # noqa
272
282
# Catch case when GeoJSON is just a geometry.
273
- self .data = {'type' : 'Feature' , 'geometry' : self .data }
274
- self .data = {'type' : 'FeatureCollection' , 'features' : [self .data ]}
283
+ self .data = {'type' : 'Feature' , 'geometry' : self .data }
284
+ self .data = {'type' : 'FeatureCollection' , 'features' : [self .data ]}
275
285
276
286
for feature in self .data ['features' ]:
277
- feature .setdefault ('properties' ,{}).setdefault ('style' ,{}).update (
278
- self .style_function (feature ))
287
+ feature .setdefault ('properties' , {}).setdefault ('style' , {}).update (self .style_function (feature )) # noqa
279
288
return json .dumps (self .data )
280
289
281
290
def _get_self_bounds (self ):
@@ -287,14 +296,14 @@ def _get_self_bounds(self):
287
296
288
297
if 'features' not in self .data .keys ():
289
298
# Catch case when GeoJSON is just a single Feature or a geometry.
290
- if not (isinstance (self .data , dict ) and 'geometry' in self .data .keys ()):
299
+ if not (isinstance (self .data , dict ) and 'geometry' in self .data .keys ()): # noqa
291
300
# Catch case when GeoJSON is just a geometry.
292
- self .data = {'type' : 'Feature' , 'geometry' : self .data }
293
- self .data = {'type' : 'FeatureCollection' , 'features' : [self .data ]}
301
+ self .data = {'type' : 'Feature' , 'geometry' : self .data }
302
+ self .data = {'type' : 'FeatureCollection' , 'features' : [self .data ]}
294
303
295
- bounds = [[None ,None ],[None ,None ]]
304
+ bounds = [[None , None ], [None , None ]]
296
305
for feature in self .data ['features' ]:
297
- for point in iter_points (feature .get ('geometry' ,{}).get ('coordinates' ,{})):
306
+ for point in iter_points (feature .get ('geometry' , {}).get ('coordinates' , {})): # noqa
298
307
bounds = [
299
308
[
300
309
none_min (bounds [0 ][0 ], point [1 ]),
@@ -307,6 +316,7 @@ def _get_self_bounds(self):
307
316
]
308
317
return bounds
309
318
319
+
310
320
class TopoJson (MacroElement ):
311
321
def __init__ (self , data , object_path ):
312
322
"""
@@ -357,10 +367,10 @@ def _get_self_bounds(self):
357
367
358
368
data = json .loads (self .data )
359
369
360
- xmin ,xmax ,ymin ,ymax = None , None , None , None
370
+ xmin , xmax , ymin , ymax = None , None , None , None
361
371
362
372
for arc in data ['arcs' ]:
363
- x ,y = 0 ,0
373
+ x , y = 0 , 0
364
374
for dx , dy in arc :
365
375
x += dx
366
376
y += dy
@@ -370,16 +380,21 @@ def _get_self_bounds(self):
370
380
ymax = none_max (y , ymax )
371
381
return [
372
382
[
373
- data ['transform' ]['translate' ][0 ] + data ['transform' ]['scale' ][0 ] * xmin ,
374
- data ['transform' ]['translate' ][1 ] + data ['transform' ]['scale' ][1 ] * ymin ,
383
+ data ['transform' ]['translate' ][0 ] +
384
+ data ['transform' ]['scale' ][0 ] * xmin ,
385
+ data ['transform' ]['translate' ][1 ] +
386
+ data ['transform' ]['scale' ][1 ] * ymin ,
375
387
],
376
388
[
377
- data ['transform' ]['translate' ][0 ] + data ['transform' ]['scale' ][0 ] * xmax ,
378
- data ['transform' ]['translate' ][1 ] + data ['transform' ]['scale' ][1 ] * ymax ,
389
+ data ['transform' ]['translate' ][0 ] +
390
+ data ['transform' ]['scale' ][0 ] * xmax ,
391
+ data ['transform' ]['translate' ][1 ] +
392
+ data ['transform' ]['scale' ][1 ] * ymax ,
379
393
]
380
394
381
395
]
382
396
397
+
383
398
class ColorScale (MacroElement ):
384
399
def __init__ (self , color_domain , color_code , caption = "" ):
385
400
"""
@@ -409,6 +424,7 @@ def render(self, **kwargs):
409
424
JavascriptLink ("https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" ), # noqa
410
425
name = 'd3' )
411
426
427
+
412
428
class MarkerCluster (Layer ):
413
429
"""Adds a MarkerCluster layer on the map."""
414
430
def __init__ (self , overlay = True , control = True ):
@@ -533,6 +549,7 @@ def __init__(self, location, radius=500, color='black',
533
549
{% endmacro %}
534
550
""" )
535
551
552
+
536
553
class LatLngPopup (MacroElement ):
537
554
def __init__ (self ):
538
555
"""
@@ -651,6 +668,7 @@ def _get_self_bounds(self):
651
668
]
652
669
return bounds
653
670
671
+
654
672
class MultiPolyLine (MacroElement ):
655
673
def __init__ (self , locations , color = None , weight = None ,
656
674
opacity = None , latlon = True , popup = None ):
@@ -697,6 +715,7 @@ def __init__(self, locations, color=None, weight=None,
697
715
{{this._parent.get_name()}}.addLayer({{this.get_name()}});
698
716
{% endmacro %}
699
717
""" ) # noqa
718
+
700
719
def _get_self_bounds (self ):
701
720
"""Computes the bounds of the object itself (not including it's children)
702
721
in the form [[lat_min, lon_min], [lat_max, lon_max]]
@@ -715,6 +734,7 @@ def _get_self_bounds(self):
715
734
]
716
735
return bounds
717
736
737
+
718
738
class CustomIcon (Icon ):
719
739
def __init__ (self , icon_image , icon_size = None , icon_anchor = None ,
720
740
shadow_image = None , shadow_size = None , shadow_anchor = None ,
0 commit comments