Closed patrontheo closed 9 months ago
@randyzwitch Any pointers to where I could have a look, and maybe try to do a PR ? (not sure I have the required skills though)
Unfortunately, with both this one and the other issue you opened, it's not immediately obvious to me without digging into the code what the issue is (I'm surprisingly uninformed about folium 🥲)
Best thing to do is just try and see where it gets you
Ok, thanks for the answer! I'll try to give it a shot when I have a bit of time
@patrontheo One clarification that might be helpful -- the purpose of feature_group_to_add
is explicitly only for cases where you want to dynamically update a feature group while interacting with your app. If you don't need that, you can just add it directly to the map, and don't pass anything to feature_group_to_add
.
Maybe that's obvious, and you did say "dynamic feature group", but just wanted to make sure that's clear.
@blackary yes, basically in my app I have a table on the left and a map on the right, and based on which row of the table is selected, I display different polygons on the map. So to avoid a reload of the map at each row selection, I would like to use the feature_group_to_add
. As I display different things (parcles boundaries, building boundaries, and other layers), it is useful to select which layers to display or not, so to have a layer control also on dynamically added feature groups.
The possibility of giving a list of feature groups instead of a single one is more of a feature request that I think could be nice to have :), but of course I know that you've other things to do, so nothing urgent there ;)
The possibility of giving a list of feature groups instead of a single one
I would guess that's easier to add than you might expect, probably would just be on the Python code side? If I'm thinking about it correctly, you would do something like test the feature group variable usingisinstance(list)
, then write the logic to add the feature groups to the existing object in the proper field.
Yeah, I tried that and it works, partially.. Actually it led me to a new issue: if you remove a dynamic feature group (setting feature_group_to_add
to None
), it is not removed from the map.
I think it comes from here, where the removeLayer
mewthod is called only if the feature group is not None
.
Here is some sample code to show that (basically clicking the button "Remove Feature Group" will not work):
import folium
import geopandas as gpd
import shapely
import streamlit as st
from streamlit_folium import st_folium
st.set_page_config(layout='wide', initial_sidebar_state='collapsed')
st.write('<style>div.block-container{padding-top:2rem;}</style>', unsafe_allow_html=True) # remove padding top
START_LOCATION = [37.7944347109497, -122.398077892527]
START_ZOOM = 17
if not 'feature_group' in st.session_state:
st.session_state['feature_group'] = None
wkt1 = "POLYGON ((-122.399077892527 37.7934347109497, -122.398922660838 37.7934544916178, -122.398980265018 37.7937266504805, -122.399133972495 37.7937070646238, -122.399077892527 37.7934347109497))"
polygon_1 = shapely.wkt.loads(wkt1)
gdf1 = gpd.GeoDataFrame(geometry=[polygon_1]).set_crs(epsg=4326)
style_parcels1 = {'fillColor': '#1100f8', 'color': '#1100f8', 'fillOpacity': 0.13, 'weight': 2 }
polygon_folium1 = folium.GeoJson(data=gdf1, style_function=lambda x: style_parcels1)
map = folium.Map(
location=START_LOCATION, zoom_start=START_ZOOM, tiles="OpenStreetMap", max_zoom=21
)
fg1 = folium.FeatureGroup(name="Parcels")
fg1.add_child(polygon_folium1)
def add_fg_to_ss(fg):
st.session_state["feature_group"] = fg
def remove_fg_from_ss():
st.session_state["feature_group"] = None
b1 = st.button("Add Feature Group", on_click=add_fg_to_ss, args=(fg1,))
b2 = st.button("Remove Feature Group", on_click=remove_fg_from_ss)
st_folium(
map,
width=800,
height=450,
returned_objects=[],
feature_group_to_add=st.session_state['feature_group'],
debug=False,
)
Should I open a new issue for this one ?
For giving a list of feature groups, it kind of work, but with the current implementation in index.tsx, the code only removes one layer, and would need to be modified to remove a list of layers when the feature group list is updated. Perhaps something like the following could work:
if (Array.isArray(window.feature_group)) {
window.feature_group.forEach((group) => {
window.map.removeLayer(group)
})
}
Maybe I'll have more time later to try to implement it, but I'm not sure.
Should I open a new issue for this one ?
In general, the answer is almost always yes, open a new issue. Or if they all are related to the same functionality, just write up one meta-issue describing the desired implementation/result behavior
@randyzwitch I submitted a PR. However for the original topic of this issue, which is making Layercontrol available for dynamically added feature groups, I don't think I have the technical knowledge to do it. Perhaps with some pointers I can dig a bit but I'm not sure where to look at for now.
Actually I think I got it, I'll try to add some tests and submit a PR later
Hello,
folium.LayerControl()
does not work when adding a feature group dynamically with st_folium(). Also, it would be super useful to be able to add a list of feature groups to be added dynamically (instead of a single one), as in the following:Each one of the provided feature group should be 'tickable' in the layer control.
Here is a sample code for you to see that
folium.LayerControl()
does not work.As you can see, the layer control does not appear. Thank you