Skip to content

Instantly share code, notes, and snippets.

@kenji4569
Last active January 5, 2024 05:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kenji4569/b14ba47b1ec58fb2426fcc12f1bd777a to your computer and use it in GitHub Desktop.
Save kenji4569/b14ba47b1ec58fb2426fcc12f1bd777a to your computer and use it in GitHub Desktop.
"""
streamlit-folium-example-app
Run the following commands to launch the app:
$ pip install streamlit streamlit-folium
$ streamlit run streamlit-folium-example-app.py
"""
import time
import folium
import streamlit as st
from folium.features import Icon, Marker, PolyLine
from streamlit_folium import st_folium
#############
# Constants #
#############
# (lat, lng)
HANEDA_T1 = (35.5492863, 139.7844030)
TOKYO = (35.681093, 139.767043)
DEGREE_FORMAT = "%.5f"
DEGREE_STEP = 0.001
##############
# Init State #
##############
if not st.session_state.get("initialized"):
initial_waypoints = [HANEDA_T1, TOKYO]
for i, waypoint in enumerate(initial_waypoints):
st.session_state["waypoint_{0}_lat".format(i)] = waypoint[0]
st.session_state["waypoint_{0}_lng".format(i)] = waypoint[1]
st.session_state.initialized = True
##############################
# Build Variables From State #
##############################
waypoints = []
i = 0
while True:
waypoint_lat = st.session_state.get("waypoint_{0}_lat".format(i))
waypoint_lng = st.session_state.get("waypoint_{0}_lng".format(i))
if not waypoint_lat or not waypoint_lng:
break
waypoint = (waypoint_lat, waypoint_lng)
waypoints.append(waypoint)
i += 1
##########
# Inputs #
##########
with st.sidebar:
for i, waypoint in enumerate(waypoints):
st.write("Waypoint {0}".format(i))
col1, col2 = st.columns(2)
with col1:
st.number_input(
"lat",
value=waypoint[0],
key="waypoint_{0}_lat".format(i),
format=DEGREE_FORMAT,
step=DEGREE_STEP,
)
with col2:
st.number_input(
"lng",
value=waypoint[1],
key="waypoint_{0}_lng".format(i),
format=DEGREE_FORMAT,
step=DEGREE_STEP,
)
st.write("# streamlit-folium example app")
col1, col2 = st.columns(2)
with col1:
def on_remove_last_waypoint():
last_index = len(waypoints) - 1
if last_index < 0:
return
st.session_state["waypoint_{0}_lat".format(last_index)] = None
st.session_state["waypoint_{0}_lng".format(last_index)] = None
st.button("Remove last waypoint", on_click=on_remove_last_waypoint)
with col2:
def on_clear_waypoints():
i = 0
while True:
waypoint_lat = st.session_state.get("waypoint_{0}_lat".format(i))
waypoint_lng = st.session_state.get("waypoint_{0}_lng".format(i))
if not waypoint_lat or not waypoint_lng:
break
st.session_state["waypoint_{0}_lat".format(i)] = None
st.session_state["waypoint_{0}_lng".format(i)] = None
i += 1
st.button("Clear waypoints", on_click=on_clear_waypoints)
###########
# Outputs #
###########
st.write("Click the map to add a waypoint:")
@st.cache_data(max_entries=3)
def create_folium_map(waypoints):
m = folium.Map(location=TOKYO, zoom_start=11)
m.add_child(folium.LatLngPopup())
for i, waypoint in enumerate(waypoints):
Marker(
location=waypoint,
popup="Waypoint {0}".format(i),
icon=Icon(color="red" if i == 0 else "blue"),
).add_to(m)
if len(waypoints) < 2:
return m
with st.spinner("Wait for it..."):
# Request something to visualize
time.sleep(1)
for i in range(0, len(waypoints) - 1):
PolyLine(
[waypoints[i], waypoints[i + 1]],
color="blue",
weight=2.5,
opacity=1,
).add_to(m)
return m
st_map = st_folium(create_folium_map(waypoints))
if st_map.get("last_clicked"):
last_clicked = st_map["last_clicked"]
last_index = len(waypoints) - 1
st.session_state["waypoint_{0}_lat".format(last_index + 1)] = last_clicked["lat"]
st.session_state["waypoint_{0}_lng".format(last_index + 1)] = last_clicked["lng"]
st_map["last_clicked"] = None
st.rerun()
#########
# Debug #
#########
with st.expander("waypoints"):
st.write(waypoints)
with st.expander("session_state"):
st.write(st.session_state)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment