Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
filter-directly-on-map
#28
by
jerpint
- opened
- app.py +19 -11
- 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 |
-
|
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 |
-
|
|
|
|
|
|
|
|
|
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:nt3awnoumorocco@gmail.com">nt3awnoumorocco@gmail.com</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:nt3awnoumorocco@gmail.com">nt3awnoumorocco@gmail.com</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
|