Hi community, a suggestion, there is a basic tutorial missing, how to add a marker to a click on a map event. I have been struggling with this and I cannot find it anywhere. I am still struggling a lot with session state, and I know I am not the only one as I found a person with the exact same problem. Here is what I managed to do, but I have to click two times on the map to get the marker there:
the idea: display a marker on the map once the user clicks on the map
expected behaviour: marker appears where the user clicked, if the user clicks somewhere else, the marker appears over the new click
actual behaviour: user clicks once on the map and nothing happens, then clicks again and marker appears over the previous click, not the last
if 'center' not in st.session_state:
st.session_state.center = [46.903354, 1.888334]
# Initialize session state to store clicked points
if 'location' not in st.session_state:
st.session_state.location = folium.Marker(st.session_state.center)
# Create a Folium map
m = folium.Map(location=[46.903354, 1.888334], zoom_start=6)
fg = folium.FeatureGroup(name="Markers")
fg.add_child(st.session_state.location)
# When the user interacts with the map
map_state_change = st_folium(
m,
feature_group_to_add=fg,
width=620, height=580,
returned_objects=['last_clicked'],
key="folium_map"
)
if map_state_change['last_clicked']:
loc = map_state_change['last_clicked']
st.session_state.location = folium.Marker([loc['lat'], loc['lng']])
fg.clear_layers() # Clear existing markers
fg.add_child(st.session_state.location) # Add the new marker
folium_static(m)
if anyone could point me to a tutorial or indicate how to fix the issue I would really appreciate! thanks!
I managed to add a marker to each click but I have no idea how to make the previous marker dissapear…
import streamlit as st
import folium
from streamlit_folium import folium_static
def get_pos(lat, lng):
return lat, lng
# Create a Folium map
m = folium.Map(location=[46.903354, 1.888334], zoom_start=6)
m.add_child(folium.ClickForMarker())
# When the user interacts with the map
map = st_folium(
m,
width=620, height=580,
key="folium_map"
)
data = None
if map.get("last_clicked"):
data = get_pos(map["last_clicked"]["lat"], map["last_clicked"]["lng"])
if data is not None:
st.write(data)
Also was looking for same solution, finally made it.
Here is the code, which worked for me.
import streamlit as st
import folium
from streamlit_folium import st_folium
# Function to get position from click coordinates
def get_pos(lat, lng):
return lat, lng
# Initialize session state to store marker location
if "marker_location" not in st.session_state:
st.session_state.marker_location = [43.238949, 76.889709] # Default location
st.session_state.zoom = 11 # Default zoom
# Create the base map
m = folium.Map(location=st.session_state.marker_location, zoom_start=st.session_state.zoom)
# Add a marker at the current location in session state
marker = folium.Marker(
location=st.session_state.marker_location,
draggable=False
)
marker.add_to(m)
# Render the map and capture clicks
map = st_folium(m, width=620, height=580, key="folium_map")
# Update marker position immediately after each click
if map.get("last_clicked"):
lat, lng = map["last_clicked"]["lat"], map["last_clicked"]["lng"]
st.session_state.marker_location = [lat, lng] # Update session state with new marker location
st.session_state.zoom = map["zoom"]
# Redraw the map immediately with the new marker location
m = folium.Map(location=st.session_state.marker_location, zoom_start=st.session_state.zoom)
folium.Marker(
location=st.session_state.marker_location,
draggable=False
).add_to(m)
map = st_folium(m, width=620, height=580, key="folium_map")
# Display coordinates
st.write(f"Coordinates: {st.session_state.marker_location}")
1 Like