I am trying to layer some polygons on a Folium map, however it is taking forever.
What I am doing with my code is creating dataframes while loading parquet files via st.cache
I then iterate through the dataframes and create geojson layers to display.
Here is the code:
@st.cache_data
def get_data_noah(folder):
"""
Load the data in a function so we can cache the files.
Returns:
pd.Dataframe: Returns a data frame.
"""
data_folder = folder
files = [f for f in os.listdir(data_folder) if f.endswith('.parquet')]
gdfs = {}
for file in files:
gdf_name = os.path.splitext(file)[0]
gdf = gpd.read_parquet(os.path.join(data_folder, file))
gdfs[gdf_name] = gdf.set_index(gdf.columns[0])
return gdfs
Create layers and display map:
# Map Data
map_url = 'src/tasks/task-5-web-app-deployment/data/mapping_data.parquet'
df1 = get_map_data(map_url)
noah_folder = 'src/tasks/task-5-web-app-deployment/data/noah'
geodata = get_data_noah(noah_folder)
gdf_StormSurgeAdvisory1_1 = geodata['ss1']
gdf_StormSurgeAdvisory1_2 = geodata['ss2']
gdf_StormSurgeAdvisory1_3 = geodata['ss3']
# Add map.
def map_ph(data, name):
cond = data['Province'] == name
lat = data[cond]['Latitude'].tolist()
lon = data[cond]['Longitude'].tolist()
nam = data[cond]['City'].tolist()
vul = data[cond]['Vulnerability'].tolist()
pop = data[cond]['Population'].tolist()
pov = data[cond]['Poverty_Incidents'].tolist()
hop = data[cond]['Hospital'].tolist()
html = f''' <div style="font-family: monospace;font-size: 1rem;">
<h4 style="font-size:1.05rem;">Vulnerability Info</h4>
<ul style="list-style-type: none;margin: 0;padding: 0;">
<li>City/Town: </li>
<li> <b> %s</b></li>
<li>Vulnerability: <b> %s</b></li>
<li>Population: <b> %s</b></li>
<li>Poverty: <b> %s</b></li>
<li>Hospitals: <b> %s</b></li>
</ul>
</div>
'''
if lat and lon:
map = flm.Map(location=[lat[0], lon[0]], zoom_start=8, scrollWheelZoom=False)
else:
return None
fg = flm.FeatureGroup(name='Philippines Cities')
fg1 = flm.FeatureGroup(name='Storm Surge 4 metres')
fg2 = flm.FeatureGroup(name='Storm Surge 3 metres')
fg3 = flm.FeatureGroup(name='Storm Surge 2 metres')
marker_props = {'low': {'color': 'green', 'size': 10},
'medium': {'color': 'blue', 'size': 10},
'high': {'color': 'red', 'size': 15}}
for lt, ln, nm, vu, po, pv, ho in zip((lat), (lon), (nam), (vul), (pop), (pov), (hop)):
iframe = flm.IFrame(html = html % ((nm), (vu), (po), (pv), int((ho))), height = 210)
popup = flm.Popup(iframe, min_width=200, max_width=650)
props = marker_props[vu]
marker = flm.CircleMarker(location = [lt, ln], popup = popup, fill_color=props['color'], color='None', radius=props['size'], fill_opacity = 0.5)
fg.add_child(marker)
map.add_child(fg)
# loop through the dataframes and create a GeoJSON layer for each row
for df, fg, clr in [(gdf_StormSurgeAdvisory1_1, fg1, 'blue'), (gdf_StormSurgeAdvisory1_2, fg2, 'orange'), (gdf_StormSurgeAdvisory1_3, fg3, 'red')]:
for _, r in df.iterrows():
simple_geo = gpd.GeoSeries(r['geometry']).simplify(tolerance=0.001)
geo_j = simple_geo.to_json()
geo_j = flm.GeoJson(data=geo_j, style_function=lambda x: {'fillColor': clr})
fg.add_child(geo_j)
map.add_child(fg)
fg1.add_to(map)
fg2.add_to(map)
fg3.add_to(map)
flm.LayerControl(collapsed=False).add_to(map)
# map.save('map.html')
st_map = st_folium(map, width=1600)
return st_map