Adding all the villages to the map

#20
by fqa-cyber - opened
Files changed (3) hide show
  1. app.py +35 -1
  2. src/map_utils.py +19 -9
  3. src/utils.py +5 -0
app.py CHANGED
@@ -20,11 +20,12 @@ from src.text_content import (
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
 
@@ -117,6 +118,21 @@ def show_requests(filtered_df):
117
  ),
118
  ))
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
  def display_google_sheet_tables(data_url):
122
  """Display the google sheet tables for requests and interventions"""
@@ -232,6 +248,8 @@ df = parse_gg_sheet(REQUESTS_URL)
232
  df = add_latlng_col(df, process_column=15)
233
  interventions_df = parse_gg_sheet(INTERVENTIONS_URL)
234
  interventions_df = add_latlng_col(interventions_df, process_column=12)
 
 
235
  m = init_map()
236
  fg = folium.FeatureGroup(name="Markers")
237
 
@@ -267,6 +285,15 @@ show_interventions = st.checkbox(
267
  value=True,
268
  )
269
 
 
 
 
 
 
 
 
 
 
270
  # Categories of villages
271
 
272
  st.markdown(
@@ -321,6 +348,13 @@ if show_interventions:
321
  ]
322
  display_interventions(interventions_df)
323
 
 
 
 
 
 
 
 
324
  # Show requests
325
  show_requests(filtered_df)
326
 
 
20
  REVIEW_TEXT,
21
  SLOGAN,
22
  )
23
+ from src.utils import add_latlng_col, init_map, parse_gg_sheet, parse_json_file
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
+ DOUARS_URL = "https://raw.githubusercontent.com/fqa-cyber/nt3awnou/main/regions.json"
29
  api = HfApi(TOKEN)
30
 
31
 
 
118
  ),
119
  ))
120
 
121
+ def display_douars(douar_df):
122
+ for _, row in douar_df.iterrows():
123
+ lat = row['lat']
124
+ lng = row['lng']
125
+ lat_lng = (lat, lng)
126
+ dour_name = row['name'].capitalize()
127
+ maps_url = f"https://maps.google.com/?q={lat_lng}"
128
+ display_text = f'<br><b>⛰️ Douar:</b> {dour_name}<br><a href="{maps_url}" target="_blank" rel="noopener noreferrer"><b>🧭 Google Maps</b></a>'
129
+
130
+ fg.add_child(folium.CircleMarker(
131
+ location=[lat, lng],
132
+ radius=1,
133
+ tooltip = dour_name, # we might remove the tooltip to avoid crowding the map
134
+ popup=folium.Popup(display_text, max_width=200),
135
+ ))
136
 
137
  def display_google_sheet_tables(data_url):
138
  """Display the google sheet tables for requests and interventions"""
 
248
  df = add_latlng_col(df, process_column=15)
249
  interventions_df = parse_gg_sheet(INTERVENTIONS_URL)
250
  interventions_df = add_latlng_col(interventions_df, process_column=12)
251
+ douar_df = parse_json_file(DOUARS_URL)
252
+
253
  m = init_map()
254
  fg = folium.FeatureGroup(name="Markers")
255
 
 
285
  value=True,
286
  )
287
 
288
+ # Selection of all Moroccan Douars
289
+ # Maybe create a two streamlit columns with intervention checkbox | Douar Checkbox
290
+ # We might remove this checkbox and always show it in the map
291
+
292
+ #show_douars = st.checkbox(
293
+ # "Display All the villages | عرض جميع القرى | Afficher tous les villages",
294
+ # value=True,
295
+ #)
296
+
297
  # Categories of villages
298
 
299
  st.markdown(
 
348
  ]
349
  display_interventions(interventions_df)
350
 
351
+ # Displaying douars with checkbox
352
+ #if show_douars:
353
+ # display_douars(douar_df)
354
+
355
+
356
+ # Display automatically the douars without checkbox
357
+ display_douars(douar_df)
358
  # Show requests
359
  show_requests(filtered_df)
360
 
src/map_utils.py CHANGED
@@ -37,17 +37,18 @@ template = """
37
  style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8);
38
  border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'>
39
 
40
- <div class='legend-title'>Legend / مفتاح الخريطة</div>
41
  <div class='legend-scale'>
42
  <ul class='legend-labels'>
43
- <li><span style='background:#CE3C28;opacity:0.7;'></span>Rescue / إغاثة</li>
44
- <li><span style='background:#ED922E;opacity:0.7;'></span>Medical Assistance / مساعدة طبية</li>
45
- <li><span style='background:#FFCA92;opacity:0.7;'></span>Shelter / مأوى</li>
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>
53
  </div>
@@ -87,6 +88,15 @@ template = """
87
  margin-left: 0;
88
  border: 1px solid #999;
89
  }
 
 
 
 
 
 
 
 
 
90
  .maplegend .legend-source {
91
  font-size: 80%;
92
  color: #777;
 
37
  style='position: absolute; z-index:9999; border:2px solid grey; background-color:rgba(255, 255, 255, 0.8);
38
  border-radius:6px; padding: 10px; font-size:14px; right: 20px; bottom: 20px;'>
39
 
40
+ <div class='legend-title'>Legend / Nomenclature / مفتاح الخريطة</div>
41
  <div class='legend-scale'>
42
  <ul class='legend-labels'>
43
+ <li><div class='circle' style='background:#2F7FEC;opacity:0.7;'></div> All the Villages / Tous les villages / جميع القرى</li>
44
+ <li><span style='background:#CE3C28;opacity:0.7;'></span>Rescue / Secours / إغاثة</li>
45
+ <li><span style='background:#ED922E;opacity:0.7;'></span>Medical Assistance / Assistance Médicale / مساعدة طبية</li>
46
+ <li><span style='background:#FFCA92;opacity:0.7;'></span>Shelter / Abris / مأوى</li>
47
+ <li><span style='background:#37A8DA;opacity:0.7;'></span>Food & Water / Nourriture et eau / طعام وماء</li>
48
+ <li><span style='background:#575757;opacity:0.7;'></span>Danger / Danger /مخاطر (تسرب الغاز، تلف في الخدمات العامة...)</li>
49
+ <li><span style='background:#6EAA25;opacity:0.7;'></span>Done / terminée / تم</li>
50
+ <li><span style='background:#023020;opacity:0.7;'></span>Partial / Partiellement terminée / تم جزئيا</li>
51
+ <li><span style='background:#FF91E8;opacity:0.7;'></span>Planned / Prévue / مخطط لها</li>
52
  </ul>
53
  </div>
54
  </div>
 
88
  margin-left: 0;
89
  border: 1px solid #999;
90
  }
91
+ .circle {
92
+ position:relative;
93
+ border-radius: 50%;
94
+ margin-right: 1.2em;
95
+ margin-left: 1em;
96
+ width: 10px;
97
+ height: 10px;
98
+ float:left;
99
+ }
100
  .maplegend .legend-source {
101
  font-size: 80%;
102
  color: #777;
src/utils.py CHANGED
@@ -12,6 +12,11 @@ def parse_gg_sheet(url):
12
  df = pd.read_csv(url, on_bad_lines="warn")
13
  return df
14
 
 
 
 
 
 
15
  # Session for Requests
16
  # session = requests.Session()
17
  # @st.cache_data(persist=True)
 
12
  df = pd.read_csv(url, on_bad_lines="warn")
13
  return df
14
 
15
+ def parse_json_file(url):
16
+ df = pd.read_json(url)
17
+ df = pd.json_normalize(df.douars)
18
+ return df
19
+
20
  # Session for Requests
21
  # session = requests.Session()
22
  # @st.cache_data(persist=True)