Add village status selection and description to the markers, change marker color if village was visited but is in critical condition

#15
by loubnabnl HF staff - opened
Files changed (2) hide show
  1. app.py +106 -32
  2. src/map_utils.py +1 -0
app.py CHANGED
@@ -7,7 +7,6 @@ import pandas as pd
7
  import streamlit as st
8
  from huggingface_hub import HfApi
9
  from streamlit_folium import st_folium
10
- from src.utils import add_latlng_col
11
 
12
  from src.text_content import (
13
  COLOR_MAPPING,
@@ -21,18 +20,21 @@ from src.text_content import (
21
  REVIEW_TEXT,
22
  SLOGAN,
23
  )
24
- from src.utils import init_map, parse_gg_sheet
25
 
26
  TOKEN = os.environ.get("HF_TOKEN", None)
27
  REQUESTS_URL = "https://docs.google.com/spreadsheets/d/1gYoBBiBo1L18IVakHkf3t1fOGvHWb23loadyFZUeHJs/edit#gid=966953708"
28
- INTERVENTIONS_URL = (
29
- "https://docs.google.com/spreadsheets/d/1eXOTqunOWWP8FRdENPs4cU9ulISm4XZWYJJNR1-SrwY/edit#gid=2089222765"
30
- )
31
  api = HfApi(TOKEN)
32
 
33
 
34
  # Initialize Streamlit Config
35
- st.set_page_config(layout="wide", initial_sidebar_state="collapsed", page_icon="🤝", page_title="Nt3awnou نتعاونو")
 
 
 
 
 
36
 
37
  # Initialize States
38
  if "sleep_time" not in st.session_state:
@@ -42,7 +44,9 @@ if "auto_refresh" not in st.session_state:
42
 
43
  auto_refresh = st.sidebar.checkbox("Auto Refresh?", st.session_state.auto_refresh)
44
  if auto_refresh:
45
- number = st.sidebar.number_input("Refresh rate in seconds", value=st.session_state.sleep_time)
 
 
46
  st.session_state.sleep_time = number
47
 
48
 
@@ -50,21 +54,34 @@ if auto_refresh:
50
  def display_interventions(interventions_df, m):
51
  """Display NGO interventions on the map"""
52
  for index, row in interventions_df.iterrows():
53
- status = (
54
- "Done ✅"
55
- if row[interventions_df.columns[5]] != "Intervention prévue dans le futur / Planned future intervention"
56
- else "Planned "
57
- )
58
- color_mk = (
59
- "green"
60
- if row[interventions_df.columns[5]] != "Intervention prévue dans le futur / Planned future intervention"
61
- else "pink"
62
- )
 
 
 
 
 
 
 
 
 
 
 
 
63
  intervention_type = row[interventions_df.columns[6]].split("/")[0].strip()
64
  org = row[interventions_df.columns[1]]
65
  city = row[interventions_df.columns[9]]
66
  date = row[interventions_df.columns[4]]
67
- intervention_info = f"<b>Status:</b> {status}<br><b>Org:</b> {org}<br><b>Intervention:</b> {intervention_type}<br><b>📅 Date:</b> {date}"
 
68
  if row["latlng"] is None:
69
  continue
70
  folium.Marker(
@@ -94,7 +111,9 @@ def show_requests(filtered_df, m):
94
  if not pd.isna(row[" لأي جماعة / قيادة / دوار تنتمون ؟"])
95
  else None,
96
  popup=folium.Popup(display_text, max_width=300),
97
- icon=folium.Icon(color=COLOR_MAPPING.get(request_type, "blue"), icon=icon_name),
 
 
98
  ).add_to(m)
99
 
100
 
@@ -146,10 +165,14 @@ def display_dataframe(df, drop_cols, data_url, search_id=True, status=False):
146
  if status:
147
  target = "Pouvez-vous nous préciser si vous êtes déjà intervenus ou si vous prévoyez de le faire | Tell us if you already made the intervention, or if you're planning to do it"
148
  if selected_status == "Done / تم":
149
- display_df = display_df[display_df[target] == "Intervention déjà passée / Past intevention"]
 
 
150
 
151
  elif selected_status == "Planned / مخطط لها":
152
- display_df = display_df[display_df[target] != "Intervention déjà passée / Past intevention"]
 
 
153
 
154
  st.dataframe(display_df, height=500)
155
  st.markdown(
@@ -175,7 +198,9 @@ def id_review_submission():
175
  st.subheader("🔍 Review of requests")
176
  st.markdown(REVIEW_TEXT)
177
 
178
- id_to_review = st.number_input("Enter id / أدخل الرقم", min_value=0, max_value=len(df), value=0, step=1)
 
 
179
  reason_for_review = st.text_area("Explain why / أدخل سبب المراجعة")
180
  if st.button("Submit / أرسل"):
181
  if reason_for_review == "":
@@ -190,7 +215,9 @@ def id_review_submission():
190
  repo_id="nt3awnou/review_requests",
191
  repo_type="dataset",
192
  )
193
- st.success("Submitted at https://huggingface.co/datasets/nt3awnou/review_requests/ تم الإرسال")
 
 
194
 
195
 
196
  # Logo and Title
@@ -215,14 +242,10 @@ options = [
215
  ]
216
  selected_options = []
217
 
218
- # with tab_en:
219
- # st.markdown("👉 **Choose request type**")
220
- # with tab_ar:
221
- # st.markdown("👉 **اختر نوع الطلب**")
222
- # with tab_fr:
223
- # st.markdown("👉 **Choisissez le type de demande**")
224
 
225
- st.markdown("👉 **Choose request type | Choissisez le type de demande | اختر نوع الطلب**")
 
 
226
  col1, col2, col3, col4, col5 = st.columns([2, 3, 2, 3, 4])
227
  cols = [col1, col2, col3, col4, col5]
228
 
@@ -241,8 +264,58 @@ show_interventions = st.checkbox(
241
  value=True,
242
  )
243
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  if show_interventions:
245
- # print(interventions_df.columns)
 
 
 
 
246
  display_interventions(interventions_df, m)
247
 
248
  # Show requests
@@ -269,6 +342,7 @@ drop_cols = [
269
  "GeoCode",
270
  "GeoAddress",
271
  "Status",
 
272
  ]
273
  display_dataframe(filtered_df, drop_cols, REQUESTS_URL, search_id=True)
274
 
@@ -277,7 +351,7 @@ st.divider()
277
  st.subheader("📝 **Table of interventions / جدول التدخلات**")
278
  display_dataframe(
279
  interventions_df,
280
- [], # We show NGOs contact information
281
  INTERVENTIONS_URL,
282
  search_id=False,
283
  status=True,
 
7
  import streamlit as st
8
  from huggingface_hub import HfApi
9
  from streamlit_folium import st_folium
 
10
 
11
  from src.text_content import (
12
  COLOR_MAPPING,
 
20
  REVIEW_TEXT,
21
  SLOGAN,
22
  )
23
+ from src.utils import add_latlng_col, init_map, parse_gg_sheet
24
 
25
  TOKEN = os.environ.get("HF_TOKEN", None)
26
  REQUESTS_URL = "https://docs.google.com/spreadsheets/d/1gYoBBiBo1L18IVakHkf3t1fOGvHWb23loadyFZUeHJs/edit#gid=966953708"
27
+ INTERVENTIONS_URL = "https://docs.google.com/spreadsheets/d/1eXOTqunOWWP8FRdENPs4cU9ulISm4XZWYJJNR1-SrwY/edit#gid=2089222765"
 
 
28
  api = HfApi(TOKEN)
29
 
30
 
31
  # Initialize Streamlit Config
32
+ st.set_page_config(
33
+ layout="wide",
34
+ initial_sidebar_state="collapsed",
35
+ page_icon="🤝",
36
+ page_title="Nt3awnou نتعاونو",
37
+ )
38
 
39
  # Initialize States
40
  if "sleep_time" not in st.session_state:
 
44
 
45
  auto_refresh = st.sidebar.checkbox("Auto Refresh?", st.session_state.auto_refresh)
46
  if auto_refresh:
47
+ number = st.sidebar.number_input(
48
+ "Refresh rate in seconds", value=st.session_state.sleep_time
49
+ )
50
  st.session_state.sleep_time = number
51
 
52
 
 
54
  def display_interventions(interventions_df, m):
55
  """Display NGO interventions on the map"""
56
  for index, row in interventions_df.iterrows():
57
+ village_status = row[interventions_df.columns[7]]
58
+ if (
59
+ row[interventions_df.columns[5]]
60
+ == "Intervention prévue dans le futur / Planned future intervention"
61
+ ):
62
+ # future intervention
63
+ color_mk = "pink"
64
+ status = "Planned "
65
+ elif (
66
+ row[interventions_df.columns[5]]
67
+ != "Intervention prévue dans le futur / Planned future intervention"
68
+ and village_status
69
+ != "Critique, Besoin d'aide en urgence / Critical, in urgent need of help"
70
+ ):
71
+ # past intervention and village not in a critical condition
72
+ color_mk = "green"
73
+ status = "Done ✅"
74
+
75
+ else:
76
+ color_mk = "darkgreen"
77
+ status = "Partial ⚠️"
78
+
79
  intervention_type = row[interventions_df.columns[6]].split("/")[0].strip()
80
  org = row[interventions_df.columns[1]]
81
  city = row[interventions_df.columns[9]]
82
  date = row[interventions_df.columns[4]]
83
+ population = row[interventions_df.columns[11]]
84
+ intervention_info = f"<b>Intervention Status:</b> {status}<br><b>Village Status:</b> {village_status.split('/')[0]}<br><b>Org:</b> {org}<br><b>Intervention:</b> {intervention_type}<br><b>Population:</b> {population}<br><b>📅 Date:</b> {date}"
85
  if row["latlng"] is None:
86
  continue
87
  folium.Marker(
 
111
  if not pd.isna(row[" لأي جماعة / قيادة / دوار تنتمون ؟"])
112
  else None,
113
  popup=folium.Popup(display_text, max_width=300),
114
+ icon=folium.Icon(
115
+ color=COLOR_MAPPING.get(request_type, "blue"), icon=icon_name
116
+ ),
117
  ).add_to(m)
118
 
119
 
 
165
  if status:
166
  target = "Pouvez-vous nous préciser si vous êtes déjà intervenus ou si vous prévoyez de le faire | Tell us if you already made the intervention, or if you're planning to do it"
167
  if selected_status == "Done / تم":
168
+ display_df = display_df[
169
+ display_df[target] == "Intervention déjà passée / Past intevention"
170
+ ]
171
 
172
  elif selected_status == "Planned / مخطط لها":
173
+ display_df = display_df[
174
+ display_df[target] != "Intervention déjà passée / Past intevention"
175
+ ]
176
 
177
  st.dataframe(display_df, height=500)
178
  st.markdown(
 
198
  st.subheader("🔍 Review of requests")
199
  st.markdown(REVIEW_TEXT)
200
 
201
+ id_to_review = st.number_input(
202
+ "Enter id / أدخل الرقم", min_value=0, max_value=len(df), value=0, step=1
203
+ )
204
  reason_for_review = st.text_area("Explain why / أدخل سبب المراجعة")
205
  if st.button("Submit / أرسل"):
206
  if reason_for_review == "":
 
215
  repo_id="nt3awnou/review_requests",
216
  repo_type="dataset",
217
  )
218
+ st.success(
219
+ "Submitted at https://huggingface.co/datasets/nt3awnou/review_requests/ تم الإرسال"
220
+ )
221
 
222
 
223
  # Logo and Title
 
242
  ]
243
  selected_options = []
244
 
 
 
 
 
 
 
245
 
246
+ st.markdown(
247
+ "👉 **Choose request type | Choissisez le type de demande | اختر نوع الطلب**"
248
+ )
249
  col1, col2, col3, col4, col5 = st.columns([2, 3, 2, 3, 4])
250
  cols = [col1, col2, col3, col4, col5]
251
 
 
264
  value=True,
265
  )
266
 
267
+ # Categories of villages
268
+
269
+ st.markdown(
270
+ "👉 **State of villages visited by NGOs| Etat de villages visités par les ONGs | اختر نوع القرى التي زارتها الجمعيات**",
271
+ unsafe_allow_html=True,
272
+ )
273
+
274
+
275
+ # use checkboxes
276
+ col_1, col_2, col_3 = st.columns([1, 1, 1])
277
+
278
+ critical_villages = col_1.checkbox(
279
+ "🚨 Critical, in urgent need of help / وضع حرج، في حاجة عاجلة للمساعدة",
280
+ value=True,
281
+ )
282
+ partially_satisfied_villages = col_2.checkbox(
283
+ "⚠️ Partially served / مساعدة جزئية، بحاجة للمزيد من التدخلات",
284
+ value=True,
285
+ )
286
+ fully_satisfied_villages = col_3.checkbox(
287
+ "✅ Fully served / تمت المساعدة بشكل كامل",
288
+ value=True,
289
+ )
290
+
291
+ selected_village_types = []
292
+
293
+ if critical_villages:
294
+ selected_village_types.append(
295
+ "🚨 Critical, in urgent need of help / وضع حرج، في حاجة عاجلة للمساعدة"
296
+ )
297
+
298
+ if partially_satisfied_villages:
299
+ selected_village_types.append(
300
+ "⚠️ Partially served / مساعدة جزئية، بحاجة للمزيد من التدخلات"
301
+ )
302
+
303
+ if fully_satisfied_villages:
304
+ selected_village_types.append("✅ Fully served / تمت المساعدة بشكل كامل")
305
+
306
+ status_mapping = {
307
+ "🚨 Critical, in urgent need of help / وضع حرج، في حاجة عاجلة للمساعدة": "Critique, Besoin d'aide en urgence / Critical, in urgent need of help",
308
+ "⚠️ Partially served / مساعدة جزئية، بحاجة للمزيد من التدخلات": "Partiellement satisfait / Partially Served",
309
+ "✅ Fully served / تمت المساعدة بشكل كامل": "Entièrement satisfait / Fully served",
310
+ }
311
+ selected_statuses = [status_mapping[status] for status in selected_village_types]
312
+
313
  if show_interventions:
314
+ interventions_df = interventions_df.loc[
315
+ interventions_df[
316
+ "Etat de la région actuel | Current situation of the area "
317
+ ].isin(selected_statuses)
318
+ ]
319
  display_interventions(interventions_df, m)
320
 
321
  # Show requests
 
342
  "GeoCode",
343
  "GeoAddress",
344
  "Status",
345
+ "id",
346
  ]
347
  display_dataframe(filtered_df, drop_cols, REQUESTS_URL, search_id=True)
348
 
 
351
  st.subheader("📝 **Table of interventions / جدول التدخلات**")
352
  display_dataframe(
353
  interventions_df,
354
+ [], # We show NGOs contact information
355
  INTERVENTIONS_URL,
356
  search_id=False,
357
  status=True,
src/map_utils.py CHANGED
@@ -46,6 +46,7 @@ template = """
46
  <li><span style='background:#37A8DA;opacity:0.7;'></span>Food & Water / طعام وماء</li>
47
  <li><span style='background:#575757;opacity:0.7;'></span>Danger / مخاطر (تسرب الغاز، تلف في الخدمات العامة...)</li>
48
  <li><span style='background:#6EAA25;opacity:0.7;'></span>Done / تم</li>
 
49
  <li><span style='background:#FF91E8;opacity:0.7;'></span>Planned / مخطط لها</li>
50
  </ul>
51
  </div>
 
46
  <li><span style='background:#37A8DA;opacity:0.7;'></span>Food & Water / طعام وماء</li>
47
  <li><span style='background:#575757;opacity:0.7;'></span>Danger / مخاطر (تسرب الغاز، تلف في الخدمات العامة...)</li>
48
  <li><span style='background:#6EAA25;opacity:0.7;'></span>Done / تم</li>
49
+ <li><span style='background:#023020;opacity:0.7;'></span>Partial / تم جزئيا</li>
50
  <li><span style='background:#FF91E8;opacity:0.7;'></span>Planned / مخطط لها</li>
51
  </ul>
52
  </div>