filter-directly-on-map

#28
by jerpint - opened
Files changed (2) hide show
  1. app.py +19 -11
  2. src/utils.py +39 -9
app.py CHANGED
@@ -56,9 +56,9 @@ if auto_refresh:
56
 
57
 
58
  # Streamlit functions
59
- def display_interventions(interventions_df, selected_statuses):
60
  """Display NGO interventions on the map"""
61
- global fg
62
  for index, row in interventions_df.iterrows():
63
  village_status = row[interventions_df.columns[7]]
64
  is_future_intervention = (
@@ -81,7 +81,7 @@ def display_interventions(interventions_df, selected_statuses):
81
 
82
  else:
83
  color_mk = "darkgreen"
84
- status = "Partial ⚠️"
85
 
86
  intervention_type = row[interventions_df.columns[6]]
87
  org = row[interventions_df.columns[1]]
@@ -107,6 +107,7 @@ def display_interventions(interventions_df, selected_statuses):
107
  if row["latlng"] is None:
108
  continue
109
 
 
110
  fg.add_child(
111
  folium.Marker(
112
  location=row["latlng"],
@@ -210,14 +211,16 @@ def show_requests(filtered_df):
210
  )
211
 
212
 
213
- def show_verified_requests(filtered_verified_df):
214
  """Display verified victim requests on the map"""
215
  global fg
 
216
  verified_color_mapping = {
217
  "Low": "beige",
218
  "Medium": "orange",
219
  "High": "red",
220
  }
 
221
  for index, row in filtered_verified_df.iterrows():
222
  long_lat = row["latlng"]
223
  # we display all requests in popup text and use the first one for the icon/color
@@ -250,7 +253,11 @@ def show_verified_requests(filtered_verified_df):
250
  if long_lat is None:
251
  continue
252
  location = row["Location Details"]
253
- fg.add_child(
 
 
 
 
254
  folium.Marker(
255
  location=long_lat,
256
  tooltip=location if not pd.isna(location) else None,
@@ -328,7 +335,7 @@ def display_dataframe(df, drop_cols, data_url, search_id=True, status=False, for
328
  st.markdown(
329
  """
330
  <div style="text-align: left;">
331
- <a href="mailto:[email protected]">[email protected]</a> نحن نخفي معلومات الاتصال لحماية خصوصية الضحايا. إذا كنت جمعية وتريد الاتصال بالضحايا، يرجى الاتصال بنا على
332
  </div>
333
  """,
334
  unsafe_allow_html=True,
@@ -364,7 +371,7 @@ st.markdown(LOGO, unsafe_allow_html=True)
364
  # st.title("Nt3awnou نتعاونو")
365
  st.markdown(SLOGAN, unsafe_allow_html=True)
366
 
367
- m = init_map()
368
  fg = folium.FeatureGroup(name="Markers")
369
 
370
  # Selection of requests
@@ -465,15 +472,16 @@ status_mapping = {
465
  selected_statuses = [status_mapping[status] for status in selected_village_types]
466
 
467
  if show_interventions:
468
- display_interventions(interventions_df, selected_statuses)
469
  display_solved(solved_verified_requests, selected_statuses)
 
 
470
 
471
  # Show requests
472
  if show_unverified:
473
  show_requests(filtered_df)
474
 
475
  # Show verified requests
476
- show_verified_requests(verified_df)
477
 
478
  # Add legend
479
  legend_macro = get_legend_macro(show_unverified)
@@ -491,7 +499,7 @@ with st.expander("💻 For Developers only, embed code for the map | للمطو
491
  st.code(
492
  """
493
  <iframe id="nt3awnou-map"
494
- src="https://nt3awnou-embed-rescue-map.hf.space/?embed=true" width="1200" height="720"
495
  frameborder="0"
496
  width="850"
497
  height="450"
@@ -563,7 +571,7 @@ with tab_fr:
563
  "# Nombre de demandes résolues",
564
  len_solved_verified_requests,
565
  )
566
-
567
 
568
  # Verified Requests table
569
  st.divider()
 
56
 
57
 
58
  # Streamlit functions
59
+ def display_interventions(interventions_df, selected_statuses, map_obj, intervention_fgs):
60
  """Display NGO interventions on the map"""
61
+
62
  for index, row in interventions_df.iterrows():
63
  village_status = row[interventions_df.columns[7]]
64
  is_future_intervention = (
 
81
 
82
  else:
83
  color_mk = "darkgreen"
84
+ status = "Partial 📝"
85
 
86
  intervention_type = row[interventions_df.columns[6]]
87
  org = row[interventions_df.columns[1]]
 
107
  if row["latlng"] is None:
108
  continue
109
 
110
+ fg = intervention_fgs[status]
111
  fg.add_child(
112
  folium.Marker(
113
  location=row["latlng"],
 
211
  )
212
 
213
 
214
+ def show_verified_requests(filtered_verified_df, emergency_fgs):
215
  """Display verified victim requests on the map"""
216
  global fg
217
+
218
  verified_color_mapping = {
219
  "Low": "beige",
220
  "Medium": "orange",
221
  "High": "red",
222
  }
223
+
224
  for index, row in filtered_verified_df.iterrows():
225
  long_lat = row["latlng"]
226
  # we display all requests in popup text and use the first one for the icon/color
 
253
  if long_lat is None:
254
  continue
255
  location = row["Location Details"]
256
+
257
+ # Select the correct feature group
258
+ fg_emergency_group = emergency_fgs[emergency]
259
+
260
+ fg_emergency_group.add_child(
261
  folium.Marker(
262
  location=long_lat,
263
  tooltip=location if not pd.isna(location) else None,
 
335
  st.markdown(
336
  """
337
  <div style="text-align: left;">
338
+ <a href="mailto:[email protected]">[email protected]</a> نحن نخفي معلومات الاتصال لحماية خصوصية الضحايا. إذا كنت جمعية وتريد الاتصال بالضحايا، يرجى الاتصال بنا على
339
  </div>
340
  """,
341
  unsafe_allow_html=True,
 
371
  # st.title("Nt3awnou نتعاونو")
372
  st.markdown(SLOGAN, unsafe_allow_html=True)
373
 
374
+ m, emergency_fgs, intervention_fgs = init_map()
375
  fg = folium.FeatureGroup(name="Markers")
376
 
377
  # Selection of requests
 
472
  selected_statuses = [status_mapping[status] for status in selected_village_types]
473
 
474
  if show_interventions:
 
475
  display_solved(solved_verified_requests, selected_statuses)
476
+ display_interventions(interventions_df, selected_statuses, m, intervention_fgs)
477
+
478
 
479
  # Show requests
480
  if show_unverified:
481
  show_requests(filtered_df)
482
 
483
  # Show verified requests
484
+ show_verified_requests(verified_df, emergency_fgs)
485
 
486
  # Add legend
487
  legend_macro = get_legend_macro(show_unverified)
 
499
  st.code(
500
  """
501
  <iframe id="nt3awnou-map"
502
+ src="https://nt3awnou-embed-rescue-map.hf.space/?embed=true" width="1200" height="720"
503
  frameborder="0"
504
  width="850"
505
  height="450"
 
571
  "# Nombre de demandes résolues",
572
  len_solved_verified_requests,
573
  )
574
+
575
 
576
  # Verified Requests table
577
  st.divider()
src/utils.py CHANGED
@@ -67,7 +67,7 @@ def parse_latlng(latlng):
67
  if latlng.count(',') > 2:
68
  d1, d2, d3, d4 = latlng.split(",")[:4]
69
  return [float(".".join([d1, d2])), float(".".join([d3, d4]))]
70
-
71
  # case of more than one dot 30.98. -7.10
72
  if latlng.count('.') > 2:
73
  d1, d2, d3, d4 = latlng.split(".")[:4]
@@ -79,7 +79,7 @@ def parse_latlng(latlng):
79
  lat = re.sub(r"[^\d\.\-]", "", lat)
80
  lng = re.sub(r"[^\d\.\-]", "", lng)
81
  return [float(lat), float(lng)]
82
-
83
  except Exception as e:
84
  print(f"Error parsing latlng: {latlng} Reason: {e}")
85
  return None
@@ -93,16 +93,16 @@ def add_epicentre_to_map(fg):
93
  text_color='white'
94
  )
95
 
96
- fg.add_child(folium.Marker(location=EPICENTER_LOCATION,
97
- # popup="Epicenter مركز الزلزال",
98
  tooltip="Epicenter مركز الزلزال",
99
  icon=icon_epicentre))
100
-
101
 
102
 
103
  def add_danger_distances_to_map(map_obj):
104
  Danger_Distances_group = folium.FeatureGroup(name='Danger distances - earthquake magnitude 7 | مسافات الخطر - قوة الزلازل 7').add_to(map_obj)
105
-
106
  zones = [
107
  {"radius": 100000, "fill_opacity": 0.1, "weight": 1, "fill_color": "yellow", "tooltip": "50 to 100 km - Moderate risk area | منطقة خطر معتدلة"},
108
  {"radius": 50000, "fill_opacity": 0.1, "weight": 1, "fill_color": "orange", "tooltip": "30 to 50 km - High risk zone | منطقة عالية المخاطر"},
@@ -123,7 +123,7 @@ def add_danger_distances_to_map(map_obj):
123
  ).add_to(Danger_Distances_group)
124
 
125
 
126
- def add_village_names(douar_df, map_obj):
127
  village_fgroup = folium.FeatureGroup(name='🔵 All the Villages / Tous les villages / جميع القرى', show=False).add_to(map_obj)
128
 
129
  for _, row in douar_df.iterrows():
@@ -137,13 +137,41 @@ def add_village_names(douar_df, map_obj):
137
  folium.CircleMarker(
138
  location=[lat, lng],
139
  radius=0.1,
140
- tooltip = dour_name, # we might remove the tooltip to avoid crowding the map
141
  popup=folium.Popup(display_text, max_width=200),
142
  color= "#0046C8",
143
  opacity = 0.7
144
  ).add_to(village_fgroup)
145
 
146
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  def init_map():
148
  m = folium.Map(
149
  location=[31.228674, -7.992047],
@@ -185,6 +213,8 @@ def init_map():
185
  # Add danger zones
186
  add_epicentre_to_map(m)
187
  add_danger_distances_to_map(m)
 
 
188
 
189
  # Add a LayerControl to the map to toggle between layers (Satellite View and Default One)
190
  folium.LayerControl().add_to(m)
@@ -197,4 +227,4 @@ def init_map():
197
  strings={"title": "My location | موقعي", "popup": "My location | موقعي"},
198
  ).add_to(m)
199
 
200
- return m
 
67
  if latlng.count(',') > 2:
68
  d1, d2, d3, d4 = latlng.split(",")[:4]
69
  return [float(".".join([d1, d2])), float(".".join([d3, d4]))]
70
+
71
  # case of more than one dot 30.98. -7.10
72
  if latlng.count('.') > 2:
73
  d1, d2, d3, d4 = latlng.split(".")[:4]
 
79
  lat = re.sub(r"[^\d\.\-]", "", lat)
80
  lng = re.sub(r"[^\d\.\-]", "", lng)
81
  return [float(lat), float(lng)]
82
+
83
  except Exception as e:
84
  print(f"Error parsing latlng: {latlng} Reason: {e}")
85
  return None
 
93
  text_color='white'
94
  )
95
 
96
+ fg.add_child(folium.Marker(location=EPICENTER_LOCATION,
97
+ # popup="Epicenter مركز الزلزال",
98
  tooltip="Epicenter مركز الزلزال",
99
  icon=icon_epicentre))
100
+
101
 
102
 
103
  def add_danger_distances_to_map(map_obj):
104
  Danger_Distances_group = folium.FeatureGroup(name='Danger distances - earthquake magnitude 7 | مسافات الخطر - قوة الزلازل 7').add_to(map_obj)
105
+
106
  zones = [
107
  {"radius": 100000, "fill_opacity": 0.1, "weight": 1, "fill_color": "yellow", "tooltip": "50 to 100 km - Moderate risk area | منطقة خطر معتدلة"},
108
  {"radius": 50000, "fill_opacity": 0.1, "weight": 1, "fill_color": "orange", "tooltip": "30 to 50 km - High risk zone | منطقة عالية المخاطر"},
 
123
  ).add_to(Danger_Distances_group)
124
 
125
 
126
+ def add_village_names(douar_df, map_obj):
127
  village_fgroup = folium.FeatureGroup(name='🔵 All the Villages / Tous les villages / جميع القرى', show=False).add_to(map_obj)
128
 
129
  for _, row in douar_df.iterrows():
 
137
  folium.CircleMarker(
138
  location=[lat, lng],
139
  radius=0.1,
140
+ tooltip = dour_name, # we might remove the tooltip to avoid crowding the map
141
  popup=folium.Popup(display_text, max_width=200),
142
  color= "#0046C8",
143
  opacity = 0.7
144
  ).add_to(village_fgroup)
145
 
146
 
147
+ def init_intervention_fgs(m):
148
+ intervention_fgs = {}
149
+
150
+ fg_done = folium.FeatureGroup(name="Done ✅", show=True).add_to(m)
151
+ fg_planned = folium.FeatureGroup(name="Planned ⏳", show=True).add_to(m)
152
+ fg_partial = folium.FeatureGroup(name="Partial 📝", show=True).add_to(m)
153
+
154
+ intervention_fgs["Done ✅"] = fg_done
155
+ intervention_fgs["Planned ⌛"] = fg_planned
156
+ intervention_fgs["Partial 📝"] = fg_partial
157
+
158
+ return intervention_fgs
159
+
160
+
161
+ def init_emergency_fgs(m):
162
+ emergency_fgs = {}
163
+
164
+ fg_high = folium.FeatureGroup(name="High 🔴", show=True).add_to(m)
165
+ fg_medium = folium.FeatureGroup(name="Medium 🟠", show=True).add_to(m)
166
+ fg_low = folium.FeatureGroup(name="Low 🟡", show=True).add_to(m)
167
+
168
+ emergency_fgs["High"] = fg_high
169
+ emergency_fgs["Medium"] = fg_medium
170
+ emergency_fgs["Low"] = fg_low
171
+
172
+ return emergency_fgs
173
+
174
+
175
  def init_map():
176
  m = folium.Map(
177
  location=[31.228674, -7.992047],
 
213
  # Add danger zones
214
  add_epicentre_to_map(m)
215
  add_danger_distances_to_map(m)
216
+ emergency_fgs = init_emergency_fgs(m)
217
+ intervention_fgs = init_intervention_fgs(m)
218
 
219
  # Add a LayerControl to the map to toggle between layers (Satellite View and Default One)
220
  folium.LayerControl().add_to(m)
 
227
  strings={"title": "My location | موقعي", "popup": "My location | موقعي"},
228
  ).add_to(m)
229
 
230
+ return m, emergency_fgs, intervention_fgs