Spaces:
Sleeping
Sleeping
pjgerrits
commited on
Commit
·
db20118
1
Parent(s):
9928153
new survey
Browse files- app copy.py +191 -0
- app.py +29 -26
app copy.py
ADDED
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import folium
|
3 |
+
from folium import LayerControl
|
4 |
+
from folium.plugins import Geocoder, MiniMap
|
5 |
+
from streamlit_folium import st_folium
|
6 |
+
import psycopg2
|
7 |
+
|
8 |
+
st.set_page_config(layout="wide")
|
9 |
+
|
10 |
+
@st.cache_resource
|
11 |
+
def connect_to_db():
|
12 |
+
return psycopg2.connect(
|
13 |
+
dbname="glprui_jloddr",
|
14 |
+
user="glprui_jloddr",
|
15 |
+
password="612ef773",
|
16 |
+
host="db.qgiscloud.com",
|
17 |
+
port="5432",
|
18 |
+
sslmode="prefer"
|
19 |
+
)
|
20 |
+
|
21 |
+
def submit_data(age, gender, transport, multi_transport, time_of_day, day_of_week, description, points):
|
22 |
+
conn = connect_to_db()
|
23 |
+
cursor = conn.cursor()
|
24 |
+
|
25 |
+
try:
|
26 |
+
cursor.execute(
|
27 |
+
"""
|
28 |
+
INSERT INTO public.gettinglost_tracking (Age, Gender, Transport, TimeOfDay, DayOfWeek, Description)
|
29 |
+
VALUES (%s, %s, %s, %s, %s, %s) RETURNING ID;
|
30 |
+
""",
|
31 |
+
(age, gender, transport, time_of_day, day_of_week, description)
|
32 |
+
)
|
33 |
+
|
34 |
+
record_id = cursor.fetchone()[0]
|
35 |
+
|
36 |
+
for pointType, point in points.items():
|
37 |
+
cursor.execute(
|
38 |
+
"""
|
39 |
+
INSERT INTO public.gettinglost_geom (ID, PointType, geom)
|
40 |
+
VALUES (%s, %s, ST_SetSRID(ST_Point(%s, %s), 4326));
|
41 |
+
""",
|
42 |
+
(record_id, pointType, point[1], point[0])
|
43 |
+
)
|
44 |
+
|
45 |
+
conn.commit()
|
46 |
+
st.success("Data recorded successfully!")
|
47 |
+
except Exception as e:
|
48 |
+
conn.rollback()
|
49 |
+
st.error(f"Error: {str(e)}")
|
50 |
+
finally:
|
51 |
+
cursor.close()
|
52 |
+
conn.close()
|
53 |
+
|
54 |
+
def create_map(points, center=None, zoom=10):
|
55 |
+
if center is None:
|
56 |
+
center = [51.5074, -0.1278]
|
57 |
+
m = folium.Map(location=center, zoom_start=zoom, control_scale=True,Tiles=None)
|
58 |
+
Geocoder().add_to(m)
|
59 |
+
MiniMap().add_to(m)
|
60 |
+
basemap_satellite_layer1 = folium.TileLayer(
|
61 |
+
tiles="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
62 |
+
attr="Esri",
|
63 |
+
name="ESRI Satellite",
|
64 |
+
overlay=False,
|
65 |
+
control=True
|
66 |
+
)
|
67 |
+
basemap_satellite_layer1.add_to(m)
|
68 |
+
OpenStreetMap_HOT = folium.TileLayer(
|
69 |
+
tiles="https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
|
70 |
+
attr="Humanitarian OpenStreetMap Team",
|
71 |
+
name="OpenStreetMap_HOT",
|
72 |
+
overlay=False,
|
73 |
+
control=True
|
74 |
+
)
|
75 |
+
OpenStreetMap_HOT.add_to(m)
|
76 |
+
LayerControl().add_to(m)
|
77 |
+
for point_type, coords in points.items():
|
78 |
+
if coords:
|
79 |
+
folium.Marker(
|
80 |
+
location=coords,
|
81 |
+
popup=point_type,
|
82 |
+
icon=folium.Icon(color="red" if point_type == "start" else "blue" if point_type == "end" else "orange")
|
83 |
+
).add_to(m)
|
84 |
+
return m
|
85 |
+
|
86 |
+
# Initialize session state for points if not already done
|
87 |
+
if 'points' not in st.session_state:
|
88 |
+
st.session_state['points'] = {'start': None, 'lost': None, 'end': None}
|
89 |
+
if 'survey' not in st.session_state:
|
90 |
+
st.session_state['survey'] = False
|
91 |
+
if 'point_type' not in st.session_state:
|
92 |
+
st.session_state['point_type'] = 'start'
|
93 |
+
if 'map_center' not in st.session_state:
|
94 |
+
st.session_state['map_center'] = [51.5074, -0.1278]
|
95 |
+
if 'map_zoom' not in st.session_state:
|
96 |
+
st.session_state['map_zoom'] = 10
|
97 |
+
|
98 |
+
# Custom CSS for colored buttons
|
99 |
+
st.markdown(
|
100 |
+
"""
|
101 |
+
<style>
|
102 |
+
.start-button { background-color: red; color: white; border: none; padding: 10px 20px; margin: 5px; border-radius: 5px; cursor: pointer; }
|
103 |
+
.lost-button { background-color: orange; color: white; border: none; padding: 10px 20px; margin: 5px; border-radius: 5px; cursor: pointer; }
|
104 |
+
.end-button { background-color: blue; color: white; border: none; padding: 10px 20px; margin: 5px; border-radius: 5px; cursor: pointer; }
|
105 |
+
.reset-button { background-color: gray; color: white; border: none; padding: 10px 20px; margin: 5px; border-radius: 5px; cursor: pointer; }
|
106 |
+
</style>
|
107 |
+
""",
|
108 |
+
unsafe_allow_html=True,
|
109 |
+
)
|
110 |
+
|
111 |
+
st.sidebar.image("static/UoG_keyline.png")
|
112 |
+
st.title("Step 1 - Add Your :red[Start], :orange[Lost] and :blue[End] Markers on the Map")
|
113 |
+
|
114 |
+
# Custom buttons for selecting point type
|
115 |
+
col1, col2, col3 = st.columns(3)
|
116 |
+
|
117 |
+
with col1:
|
118 |
+
if st.button(":red[Start]", key="start-button", help="Place a marker on the corresponding map location", use_container_width=True):
|
119 |
+
st.session_state['point_type'] = 'start'
|
120 |
+
st.markdown('<div class="start-button">Start Point</div>', unsafe_allow_html=True)
|
121 |
+
|
122 |
+
with col2:
|
123 |
+
if st.button(":orange[Lost]", key="lost-button", help="Place a marker on the corresponding map location", use_container_width=True):
|
124 |
+
st.session_state['point_type'] = 'lost'
|
125 |
+
st.markdown('<div class="lost-button">Lost Point</div>', unsafe_allow_html=True)
|
126 |
+
|
127 |
+
with col3:
|
128 |
+
if st.button(":blue[End]", key="end-button", help="Place a marker on the corresponding map location", use_container_width=True):
|
129 |
+
st.session_state['point_type'] = 'end'
|
130 |
+
st.markdown('<div class="end-button">End Point</div>', unsafe_allow_html=True)
|
131 |
+
|
132 |
+
|
133 |
+
# st.write(f"Selected Point Type: {st.session_state['point_type'].capitalize()}")
|
134 |
+
# Reset button
|
135 |
+
if st.button(":red-background[:x: **Clear Markers**]", key="reset-button", use_container_width=True):
|
136 |
+
st.session_state['points'] = {'start': None, 'lost': None, 'end': None}
|
137 |
+
st.rerun()
|
138 |
+
|
139 |
+
map_placeholder = st.empty()
|
140 |
+
|
141 |
+
with map_placeholder.container():
|
142 |
+
folium_map = create_map(st.session_state['points'], center=st.session_state['map_center'], zoom=st.session_state['map_zoom'])
|
143 |
+
map_output = st_folium(folium_map, width="100%", height=800)
|
144 |
+
|
145 |
+
new_coords = None
|
146 |
+
if map_output and 'last_clicked' in map_output and map_output['last_clicked'] is not None:
|
147 |
+
new_coords = (map_output['last_clicked']['lat'], map_output['last_clicked']['lng'])
|
148 |
+
# Update the map center to the current view, ensuring it's a list
|
149 |
+
st.session_state['map_center'] = [map_output['center']['lat'], map_output['center']['lng']]
|
150 |
+
st.session_state['map_zoom'] = map_output['zoom']
|
151 |
+
|
152 |
+
if new_coords:
|
153 |
+
st.session_state['points'][st.session_state['point_type']] = new_coords
|
154 |
+
map_placeholder.empty()
|
155 |
+
with map_placeholder.container():
|
156 |
+
folium_map = create_map(st.session_state['points'], center=st.session_state['map_center'], zoom=st.session_state['map_zoom'])
|
157 |
+
st_folium(folium_map, width="100%", height=800)
|
158 |
+
|
159 |
+
if all(st.session_state['points'].values()) and not st.session_state['survey']:
|
160 |
+
if st.sidebar.button("**Proceed to Survey** :question:", use_container_width=True, key="sidebar"):
|
161 |
+
st.session_state['survey'] = True
|
162 |
+
if st.button("**Proceed to Survey** :question:", use_container_width=True, key="main"):
|
163 |
+
st.session_state['survey'] = True
|
164 |
+
else:
|
165 |
+
st.sidebar.title("Step 2 - Survey Questions")
|
166 |
+
st.sidebar.warning("Please add your start, lost, and end points before proceeding to the survey questions.")
|
167 |
+
|
168 |
+
|
169 |
+
if st.session_state['survey']:
|
170 |
+
st.sidebar.title("Step 2 - Survey Questions")
|
171 |
+
age = st.sidebar.selectbox("Age", ["18-25","25-35","35-45","45-55","55-65","65+"])
|
172 |
+
gender = st.sidebar.radio("Gender", ["Male", "Female", "Other", "Prefer not to say"])
|
173 |
+
transport = st.sidebar.radio("Mode of Transport", ["Walk", "Car", "Bike", "Train", "Other", "Multi"])
|
174 |
+
multi_transport = st.sidebar.multiselect("If Multi, select modes used", ["Walk", "Car", "Bike", "Train", "Other"]) if transport == "Multi" else []
|
175 |
+
time_of_day = st.sidebar.selectbox("Time of Day", ["Morning", "Afternoon", "Evening", "Night"])
|
176 |
+
day_of_week = st.sidebar.selectbox("Day of the Week", ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"])
|
177 |
+
description = st.sidebar.text_area("Why did you get lost?")
|
178 |
+
|
179 |
+
if st.sidebar.button("Save"):
|
180 |
+
submit_data(age, gender, transport, multi_transport, time_of_day, day_of_week, description, st.session_state['points'])
|
181 |
+
st.session_state['points'] = {'start': None, 'lost': None, 'end': None}
|
182 |
+
st.session_state['survey'] = False
|
183 |
+
st.rerun()
|
184 |
+
|
185 |
+
# st.sidebar.write("Current Points:")
|
186 |
+
# st.sidebar.json(st.session_state['points'])
|
187 |
+
|
188 |
+
st.sidebar.markdown("---")
|
189 |
+
st.sidebar.markdown("For a more detailed survey, click the link or scan the QR code:")
|
190 |
+
st.sidebar.markdown("[https://arcg.is/1GK5jP0](https://arcg.is/1GK5jP0)")
|
191 |
+
st.sidebar.image("static/Getting Lost Survey.png", width=200)
|
app.py
CHANGED
@@ -18,17 +18,18 @@ def connect_to_db():
|
|
18 |
sslmode="prefer"
|
19 |
)
|
20 |
|
21 |
-
def submit_data(age, gender,
|
22 |
conn = connect_to_db()
|
23 |
cursor = conn.cursor()
|
24 |
|
25 |
try:
|
26 |
cursor.execute(
|
27 |
"""
|
28 |
-
INSERT INTO public.gettinglost_tracking (
|
29 |
-
|
|
|
30 |
""",
|
31 |
-
(age, gender,
|
32 |
)
|
33 |
|
34 |
record_id = cursor.fetchone()[0]
|
@@ -54,23 +55,23 @@ def submit_data(age, gender, transport, multi_transport, time_of_day, day_of_wee
|
|
54 |
def create_map(points, center=None, zoom=10):
|
55 |
if center is None:
|
56 |
center = [51.5074, -0.1278]
|
57 |
-
m = folium.Map(location=center, zoom_start=zoom, control_scale=True,
|
58 |
Geocoder().add_to(m)
|
59 |
MiniMap().add_to(m)
|
60 |
basemap_satellite_layer1 = folium.TileLayer(
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
)
|
67 |
basemap_satellite_layer1.add_to(m)
|
68 |
OpenStreetMap_HOT = folium.TileLayer(
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
)
|
75 |
OpenStreetMap_HOT.add_to(m)
|
76 |
LayerControl().add_to(m)
|
@@ -129,8 +130,6 @@ with col3:
|
|
129 |
st.session_state['point_type'] = 'end'
|
130 |
st.markdown('<div class="end-button">End Point</div>', unsafe_allow_html=True)
|
131 |
|
132 |
-
|
133 |
-
# st.write(f"Selected Point Type: {st.session_state['point_type'].capitalize()}")
|
134 |
# Reset button
|
135 |
if st.button(":red-background[:x: **Clear Markers**]", key="reset-button", use_container_width=True):
|
136 |
st.session_state['points'] = {'start': None, 'lost': None, 'end': None}
|
@@ -138,7 +137,6 @@ if st.button(":red-background[:x: **Clear Markers**]", key="reset-button", use_c
|
|
138 |
|
139 |
map_placeholder = st.empty()
|
140 |
|
141 |
-
|
142 |
with map_placeholder.container():
|
143 |
folium_map = create_map(st.session_state['points'], center=st.session_state['map_center'], zoom=st.session_state['map_zoom'])
|
144 |
map_output = st_folium(folium_map, width="100%", height=800)
|
@@ -166,19 +164,24 @@ else:
|
|
166 |
st.sidebar.title("Step 2 - Survey Questions")
|
167 |
st.sidebar.warning("Please add your start, lost, and end points before proceeding to the survey questions.")
|
168 |
|
169 |
-
|
170 |
if st.session_state['survey']:
|
171 |
st.sidebar.title("Step 2 - Survey Questions")
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
-
|
176 |
-
time_of_day = st.sidebar.selectbox("Time of Day", ["
|
177 |
day_of_week = st.sidebar.selectbox("Day of the Week", ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"])
|
178 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
|
180 |
if st.sidebar.button("Save"):
|
181 |
-
submit_data(age, gender,
|
182 |
st.session_state['points'] = {'start': None, 'lost': None, 'end': None}
|
183 |
st.session_state['survey'] = False
|
184 |
st.rerun()
|
|
|
18 |
sslmode="prefer"
|
19 |
)
|
20 |
|
21 |
+
def submit_data(consent, age, gender, other_transport, time_of_day, day_of_week, familiarity, route_guidance, group, navigation_ease, personal_context, lost_factors, open_ended_explanation, points):
|
22 |
conn = connect_to_db()
|
23 |
cursor = conn.cursor()
|
24 |
|
25 |
try:
|
26 |
cursor.execute(
|
27 |
"""
|
28 |
+
INSERT INTO public.gettinglost_tracking (
|
29 |
+
Consent, Age, Gender, OtherTransport, TimeOfDay, DayOfWeek, Familiarity, RouteGuidance, Group, NavigationEase, PersonalContext, LostFactors, OpenEndedExplanation
|
30 |
+
) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING ID;
|
31 |
""",
|
32 |
+
(consent, age, gender, other_transport, time_of_day, day_of_week, familiarity, route_guidance, group, navigation_ease, personal_context, lost_factors, open_ended_explanation)
|
33 |
)
|
34 |
|
35 |
record_id = cursor.fetchone()[0]
|
|
|
55 |
def create_map(points, center=None, zoom=10):
|
56 |
if center is None:
|
57 |
center = [51.5074, -0.1278]
|
58 |
+
m = folium.Map(location=center, zoom_start=zoom, control_scale=True, tiles=None)
|
59 |
Geocoder().add_to(m)
|
60 |
MiniMap().add_to(m)
|
61 |
basemap_satellite_layer1 = folium.TileLayer(
|
62 |
+
tiles="https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
|
63 |
+
attr="Esri",
|
64 |
+
name="ESRI Satellite",
|
65 |
+
overlay=False,
|
66 |
+
control=True
|
67 |
)
|
68 |
basemap_satellite_layer1.add_to(m)
|
69 |
OpenStreetMap_HOT = folium.TileLayer(
|
70 |
+
tiles="https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",
|
71 |
+
attr="Humanitarian OpenStreetMap Team",
|
72 |
+
name="OpenStreetMap_HOT",
|
73 |
+
overlay=False,
|
74 |
+
control=True
|
75 |
)
|
76 |
OpenStreetMap_HOT.add_to(m)
|
77 |
LayerControl().add_to(m)
|
|
|
130 |
st.session_state['point_type'] = 'end'
|
131 |
st.markdown('<div class="end-button">End Point</div>', unsafe_allow_html=True)
|
132 |
|
|
|
|
|
133 |
# Reset button
|
134 |
if st.button(":red-background[:x: **Clear Markers**]", key="reset-button", use_container_width=True):
|
135 |
st.session_state['points'] = {'start': None, 'lost': None, 'end': None}
|
|
|
137 |
|
138 |
map_placeholder = st.empty()
|
139 |
|
|
|
140 |
with map_placeholder.container():
|
141 |
folium_map = create_map(st.session_state['points'], center=st.session_state['map_center'], zoom=st.session_state['map_zoom'])
|
142 |
map_output = st_folium(folium_map, width="100%", height=800)
|
|
|
164 |
st.sidebar.title("Step 2 - Survey Questions")
|
165 |
st.sidebar.warning("Please add your start, lost, and end points before proceeding to the survey questions.")
|
166 |
|
|
|
167 |
if st.session_state['survey']:
|
168 |
st.sidebar.title("Step 2 - Survey Questions")
|
169 |
+
consent = st.sidebar.checkbox("I consent to participate in this survey.")
|
170 |
+
age = st.sidebar.selectbox("Age", ["10-19", "20-29", "30-39", "40-49", "50-59", "60-69", "70+"])
|
171 |
+
gender = st.sidebar.selectbox("Gender", ["Male", "Female", "Other", "Prefer not to say"])
|
172 |
+
other_transport = st.sidebar.multiselect("Did you use any other mode of transport during this journey?", ["Walk", "Car", "Bike", "Train", "Other"])
|
173 |
+
time_of_day = st.sidebar.selectbox("Time of Day (2-hour window)", ["00:00-02:00", "02:00-04:00", "04:00-06:00", "06:00-08:00", "08:00-10:00", "10:00-12:00", "12:00-14:00", "14:00-16:00", "16:00-18:00", "18:00-20:00", "20:00-22:00", "22:00-24:00"])
|
174 |
day_of_week = st.sidebar.selectbox("Day of the Week", ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"])
|
175 |
+
familiarity = st.sidebar.radio("Familiarity (1-5, with 1 being not familiar with the area and 5 being very familiar with the area)", [1, 2, 3, 4, 5])
|
176 |
+
route_guidance = st.sidebar.selectbox("Main method of route guidance", ["GPS/sat nav (e.g. Google maps, Citymapper, etc)", "Paper map", "Someone else’s directions (in group)", "Someone else’s directions (not in group)", "Street signs", "I was just wandering"])
|
177 |
+
group = st.sidebar.radio("Walking in group?", ["Yes", "No"])
|
178 |
+
navigation_ease = st.sidebar.radio("How easy do you typically find navigating whilst walking in cities (independent of this event)? [1-5]", [1, 2, 3, 4, 5])
|
179 |
+
personal_context = st.sidebar.text_area("Personal context regarding why you got lost")
|
180 |
+
lost_factors = st.sidebar.text_area("Ranking important factors for getting lost (e.g. environment, street layout, number of people, busy streets, complex roadsigns)")
|
181 |
+
open_ended_explanation = st.sidebar.text_area("Open-ended explanation of why you got lost")
|
182 |
|
183 |
if st.sidebar.button("Save"):
|
184 |
+
submit_data(consent, age, gender, other_transport, time_of_day, day_of_week, familiarity, route_guidance, group, navigation_ease, personal_context, lost_factors, open_ended_explanation, st.session_state['points'])
|
185 |
st.session_state['points'] = {'start': None, 'lost': None, 'end': None}
|
186 |
st.session_state['survey'] = False
|
187 |
st.rerun()
|