@@ -276,7 +276,7 @@ def style_data(self):
276276 for feature in self .data ['features' ]:
277277 feature .setdefault ('properties' ,{}).setdefault ('style' ,{}).update (
278278 self .style_function (feature ))
279- return json .dumps (self .data )
279+ return json .dumps (self .data , sort_keys = True )
280280
281281 def _get_self_bounds (self ):
282282 """Computes the bounds of the object itself (not including it's children)
@@ -308,7 +308,7 @@ def _get_self_bounds(self):
308308 return bounds
309309
310310class TopoJson (MacroElement ):
311- def __init__ (self , data , object_path ):
311+ def __init__ (self , data , object_path , style_function = None ):
312312 """
313313 TODO docstring here
314314
@@ -317,26 +317,44 @@ def __init__(self, data, object_path):
317317 self ._name = 'TopoJson'
318318 if 'read' in dir (data ):
319319 self .embed = True
320- self .data = data . read ( )
320+ self .data = json . load ( data )
321321 elif type (data ) is dict :
322322 self .embed = True
323- self .data = json . dumps ( data )
323+ self .data = data
324324 else :
325325 self .embed = False
326326 self .data = data
327327
328328 self .object_path = object_path
329329
330+ if style_function is None :
331+ style_function = lambda x : {}
332+ self .style_function = style_function
333+
330334 self ._template = Template (u"""
331335 {% macro script(this, kwargs) %}
332- var {{this.get_name()}}_data = {{this.data }};
336+ var {{this.get_name()}}_data = {{this.style_data() }};
333337 var {{this.get_name()}} = L.geoJson(topojson.feature(
334338 {{this.get_name()}}_data,
335339 {{this.get_name()}}_data.{{this.object_path}}
336340 )).addTo({{this._parent.get_name()}});
341+ {{this.get_name()}}.setStyle(function(feature) {return feature.properties.style;});
342+
337343 {% endmacro %}
338344 """ )
339345
346+ def style_data (self ):
347+ def recursive_get (data , keys ):
348+ if len (keys ):
349+ return recursive_get (data .get (keys [0 ]), keys [1 :])
350+ else :
351+ return data
352+ geometries = recursive_get (self .data , self .object_path .split ('.' ))['geometries' ]
353+ for feature in geometries :
354+ feature .setdefault ('properties' ,{}).setdefault ('style' ,{}).update (
355+ self .style_function (feature ))
356+ return json .dumps (self .data , sort_keys = True )
357+
340358 def render (self , ** kwargs ):
341359 super (TopoJson , self ).render (** kwargs )
342360
@@ -355,11 +373,9 @@ def _get_self_bounds(self):
355373 if not self .embed :
356374 raise ValueError ('Cannot compute bounds of non-embedded TopoJSON.' )
357375
358- data = json .loads (self .data )
359-
360376 xmin ,xmax ,ymin ,ymax = None , None , None , None
361377
362- for arc in data ['arcs' ]:
378+ for arc in self . data ['arcs' ]:
363379 x ,y = 0 ,0
364380 for dx , dy in arc :
365381 x += dx
@@ -370,12 +386,12 @@ def _get_self_bounds(self):
370386 ymax = none_max (y , ymax )
371387 return [
372388 [
373- data ['transform' ]['translate' ][0 ] + data ['transform' ]['scale' ][0 ] * xmin ,
374- data ['transform' ]['translate' ][1 ] + data ['transform' ]['scale' ][1 ] * ymin ,
389+ self . data ['transform' ]['translate' ][0 ] + self . data ['transform' ]['scale' ][0 ] * xmin ,
390+ self . data ['transform' ]['translate' ][1 ] + self . data ['transform' ]['scale' ][1 ] * ymin ,
375391 ],
376392 [
377- data ['transform' ]['translate' ][0 ] + data ['transform' ]['scale' ][0 ] * xmax ,
378- data ['transform' ]['translate' ][1 ] + data ['transform' ]['scale' ][1 ] * ymax ,
393+ self . data ['transform' ]['translate' ][0 ] + self . data ['transform' ]['scale' ][0 ] * xmax ,
394+ self . data ['transform' ]['translate' ][1 ] + self . data ['transform' ]['scale' ][1 ] * ymax ,
379395 ]
380396
381397 ]
0 commit comments