Looping and adding layers to map using folium in python

41 Views Asked by At

I'm creating a folium map using python and adding layers of basic polygons, using the code below. There are only two layers of polygons and each layer must have a different color for the polygons. I can get the result I want, but in an inefficient way. I would like to loop through code rather than assign each layer with an independent piece of code. When I try to loop the code, I do not get the result I want and don't understand why this happens.

Code for the base map:

start_coords = [-26.043555, 28.019104]
base_map = folium.Map(location = start_coords, zoom_start = 13, tile='openstreetmap')

Now I add the two layers of polygons. Block 1 below adds the first layer, with color '#002EFF'

BLOCK 1

buildingcategory = df['Building Category'].unique()[0]
lgd_txt = '<span style="color: {col};">{txt}</span>'
color=color_dict[buildingcategory]
feature_group = FeatureGroup(name=lgd_txt.format(txt=buildingcategory , col=color))
polygons = df[df['Building Category'] == buildingcategory]['Shape Geometry'].to_list()
u = shapely.ops.unary_union(polygons)
highlight_function = lambda x: {'fillColor': color, 'color': 'black', 'weight': 2, 'dashArray': '5, 5', 'fillOpacity': 0.05}
style_function = lambda x: {'fillColor': color, 'color': color, 'weight': 3}
feature_group.add_child(folium.GeoJson(json.dumps(shapely.geometry.mapping(u)), style_function=style_function, highlight_function=highlight_function, overlay=False))
base_map.add_child(feature_group) 

Block 2 below adds the second layer with color '#2ECAD9' BLOCK 2

buildingcategory = df['Building Category'].unique()[1]
lgd_txt = '<span style="color: {col};">{txt}</span>'
color2=color_dict[buildingcategory]
feature_group = FeatureGroup(name=lgd_txt.format(txt=buildingcategory , col=color))
polygons = df[df['Building Category'] == buildingcategory]['Shape Geometry'].to_list()
u = shapely.ops.unary_union(polygons)
highlight_function = lambda x: {'fillColor': color2, 'color': 'black', 'weight': 2, 'dashArray': '5, 5', 'fillOpacity': 0.05}
style_function = lambda x: {'fillColor': color2, 'color': color2, 'weight': 3}
feature_group.add_child(folium.GeoJson(json.dumps(shapely.geometry.mapping(u)), style_function=style_function, highlight_function=highlight_function, overlay=False))
base_map.add_child(feature_group) 

It works as expected with the code above. However, if I change the name of 'color2' to 'color' in block 2 and re-run the code above, the polygons for both layers are the same color of '#2ECAD9' (the color specified in block 2) instead of being the two different colors per layer. My question is why does this happen if I re-assign the value to that 'color' variable and the code is run sequentially? And is there a way of converting this to a generic block where I can loop through the list of values in df['Building Category'].unique()?

I ask as I would like to rather write a generic block of code and loop through it instead of splitting into block 1 and block 2 above. I started off using a generic block of code and looped through it for both values of df['Building Category'].unique() but that did not give me what I wanted, hence the two separate code blocks above. I've tried changing the color and feature_group variables into a dictionary, but it still doesn't work as expected. I've also tried keeping the 'color' variable name constant and changing the name of the feature_group (to feature_group in block 1 and feature_group2 in block 2) but that does not work (all approaches return the correct polygons and layers, but the color for both layers is the same - it's '#2ECAD9'). It seems the only way to get it to work as I want is to change the 'color' variable name in each block of code. So if I were to add a third layer, I would have to use 'color3' as the variable name.

0

There are 0 best solutions below