Skip to content

Commit 1d52280

Browse files
committed
Merge pull request #317 from BibMartin/topojsonstyle
Add style_function to TopoJson
2 parents faffad4 + 1cd4beb commit 1d52280

3 files changed

Lines changed: 30 additions & 14 deletions

File tree

folium/features.py

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

310310
class 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
]

folium/folium.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ def choropleth(self, geo_path=None, geo_str=None, data_out='data.json',
610610
}
611611

612612
if topojson:
613-
geo_json = TopoJson(geo_data, topojson)
613+
geo_json = TopoJson(geo_data, topojson, style_function=style_function)
614614
else:
615615
geo_json = GeoJson(geo_data, style_function=style_function)
616616

tests/test_folium.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ def test_geo_json_str(self):
396396

397397
# Verify the geo_json object
398398
obj_temp = jinja2.Template("""
399-
var {{ this.get_name() }} = L.geoJson({{ json.dumps(this.data) }})
399+
var {{ this.get_name() }} = L.geoJson({{ this.style_data() }})
400400
.addTo({{ this._parent.get_name() }});
401401
{{ this.get_name() }}.setStyle(function(feature) {return feature.properties.style;});
402402
""")

0 commit comments

Comments
 (0)