Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
File size: 7,732 Bytes
366b82f d2eac8a 5c8a315 0188ddf 5c8a315 0963bdd 5c8a315 181f4c3 5c8a315 9ff2d70 5c8a315 0188ddf 4008992 18e86d5 927c3de 18e86d5 927c3de 18e86d5 927c3de d2eac8a 9ff2d70 d2eac8a 5c8a315 9ff2d70 df311b6 639a871 df311b6 9ff2d70 df311b6 639a871 9ff2d70 5c8a315 99b0a9f af8a251 5c8a315 af8a251 5c8a315 99b0a9f 639a871 653bd0b 99b0a9f 639a871 5c8a315 639a871 5c8a315 653bd0b 5c8a315 639a871 4008992 639a871 4008992 639a871 5c8a315 927c3de 5c8a315 927c3de 5c8a315 927c3de 5c8a315 927c3de 5c8a315 37c5d6f 5c8a315 37c5d6f 5c8a315 49fc98c 5c8a315 639a871 5c8a315 49fc98c 5c8a315 af37579 639a871 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
import re
from typing import Union
import folium
import pandas as pd
from folium import plugins
import streamlit as st
EPICENTER_LOCATION = [31.12210171476489, -8.42945837915193]
BORDER_COLOR = "black"
# @st.cache_resource
def parse_gg_sheet(url):
print("Parsing Google Sheet:", url)
url = url.replace("edit#gid=", "export?format=csv&gid=")
df = pd.read_csv(url, on_bad_lines="warn")
return df
@st.cache_resource
def parse_json_file(url):
df = pd.read_json(url)
df = pd.json_normalize(df.douars)
return df
def is_request_in_list(request, selection_list, options):
if isinstance(request, float): # Check if the input is a float (like NaN)
return False
if "," in request:
all_requests = [r.strip() for r in request.split(",")]
else:
all_requests = [request]
# If at least one of the requests is not in the options or in the selection list, return True
for r in all_requests:
if r not in options:
return True
if r in selection_list:
return True
return False
def add_latlng_col(df, process_column: Union[str, int]):
"""Add a latlng column to the dataframe"""
if isinstance(process_column, str):
df["latlng"] = df[process_column].apply(parse_latlng)
elif isinstance(process_column, int):
df["latlng"] = df.iloc[:, process_column].apply(parse_latlng)
else:
raise ValueError(f"process_column should be a string or an integer, got {type(process_column)}")
return df
# parse latlng (column 4) to [lat, lng]
def parse_latlng(latlng):
if pd.isna(latlng):
return None
try:
# case where there more than one comma 30,98 , -7,10
if latlng.count(',') > 2:
d1, d2, d3, d4 = latlng.split(",")[:4]
return [float(".".join([d1, d2])), float(".".join([d3, d4]))]
# case of more than one dot 30.98. -7.10
if latlng.count('.') > 2:
d1, d2, d3, d4 = latlng.split(".")[:4]
return [float(".".join([d1, d2])), float(".".join([d3, d4]))]
# case where there is only one comma 30,98 , -7,10
lat, lng = latlng.split(",")[:2]
# remove anything that is not a digit or a dot or a minus sign
lat = re.sub(r"[^\d\.\-]", "", lat)
lng = re.sub(r"[^\d\.\-]", "", lng)
return [float(lat), float(lng)]
except Exception as e:
print(f"Error parsing latlng: {latlng} Reason: {e}")
return None
def add_epicentre_to_map(fg):
# Removed the spinner to not confuse the users as the map is already loaded
icon_epicentre = folium.plugins.BeautifyIcon(
icon='star',
border_color='#b3334f',
background_color='#b3334f',
text_color='white'
)
fg.add_child(folium.Marker(location=EPICENTER_LOCATION,
# popup="Epicenter مركز الزلزال",
tooltip="Epicenter مركز الزلزال",
icon=icon_epicentre))
def add_danger_distances_to_map(map_obj):
Danger_Distances_group = folium.FeatureGroup(name='Danger distances - earthquake magnitude 7 | مسافات الخطر - قوة الزلازل 7').add_to(map_obj)
zones = [
{"radius": 100000, "fill_opacity": 0.1, "weight": 1, "fill_color": "yellow", "tooltip": "50 to 100 km - Moderate risk area | منطقة خطر معتدلة"},
{"radius": 50000, "fill_opacity": 0.1, "weight": 1, "fill_color": "orange", "tooltip": "30 to 50 km - High risk zone | منطقة عالية المخاطر"},
{"radius": 30000, "fill_opacity": 0.2, "weight": 1, "fill_color": "#FF0000", "tooltip": "10 to 30 km - Very high risk zone | منطقة شديدة الخطورة"},
{"radius": 10000, "fill_opacity": 0.2, "weight": 0.2, "fill_color": "#8B0000", "tooltip": "0 to 10km - direct impact zone | منطقة التأثير المباشر"}
]
for zone in zones:
folium.Circle(
location=EPICENTER_LOCATION,
radius=zone["radius"],
color=BORDER_COLOR,
weight=zone["weight"],
fill_opacity=zone["fill_opacity"],
opacity=zone["fill_opacity"], # Assuming border opacity should match fill_opacity
fill_color=zone["fill_color"],
# tooltip=zone["tooltip"],
).add_to(Danger_Distances_group)
def add_village_names(douar_df, map_obj):
village_fgroup = folium.FeatureGroup(name='🔵 All the Villages / Tous les villages / جميع القرى', show=False).add_to(map_obj)
for _, row in douar_df.iterrows():
lat = row['lat']
lng = row['lng']
lat_lng = (lat, lng)
dour_name = row['name'].capitalize()
maps_url = f"https://maps.google.com/?q={lat_lng}"
display_text = f'<br><b>⛰️ Douar:</b> {dour_name}<br><a href="{maps_url}" target="_blank" rel="noopener noreferrer"><b>🧭 Google Maps</b></a>'
folium.CircleMarker(
location=[lat, lng],
radius=0.1,
tooltip = dour_name, # we might remove the tooltip to avoid crowding the map
popup=folium.Popup(display_text, max_width=200),
color= "#0046C8",
opacity = 0.7
).add_to(village_fgroup)
def init_intervention_fgs(m):
intervention_fgs = {}
fg_done = folium.FeatureGroup(name="Done ✅", show=True).add_to(m)
fg_planned = folium.FeatureGroup(name="Planned ⏳", show=True).add_to(m)
fg_partial = folium.FeatureGroup(name="Partial 📝", show=True).add_to(m)
intervention_fgs["Done ✅"] = fg_done
intervention_fgs["Planned ⌛"] = fg_planned
intervention_fgs["Partial 📝"] = fg_partial
return intervention_fgs
def init_emergency_fgs(m):
emergency_fgs = {}
fg_high = folium.FeatureGroup(name="High 🔴", show=True).add_to(m)
fg_medium = folium.FeatureGroup(name="Medium 🟠", show=True).add_to(m)
fg_low = folium.FeatureGroup(name="Low 🟡", show=True).add_to(m)
emergency_fgs["High"] = fg_high
emergency_fgs["Medium"] = fg_medium
emergency_fgs["Low"] = fg_low
return emergency_fgs
def init_map():
m = folium.Map(
location=[31.228674, -7.992047],
zoom_start=8.5,
min_zoom=8.5,
max_lat=35.628674,
min_lat=29.628674,
max_lon=-4.992047,
min_lon=-10.992047,
max_bounds=True,
)
# Add a search bar to the map
geocoder = plugins.Geocoder(
collapsed=False,
position="topright",
placeholder="Search | البحث",
)
m.add_child(geocoder)
# Add Fullscreen button to the map
fullscreen = plugins.Fullscreen(
position="topright",
title="Expand me | تكبير الخريطة",
title_cancel="Exit me | تصغير الخريطة",
force_separate_button=True,
)
m.add_child(fullscreen)
# Satellite View from Mapbox
tileurl = "https://marocmap.ikiker.com/maroc/{z}/{x}/{y}.png"
folium.TileLayer(
tiles=tileurl,
attr="Maroc Map",
name="Maroc Map",
overlay=False,
control=False,
).add_to(m)
# Add danger zones
add_epicentre_to_map(m)
add_danger_distances_to_map(m)
emergency_fgs = init_emergency_fgs(m)
intervention_fgs = init_intervention_fgs(m)
# Add a LayerControl to the map to toggle between layers (Satellite View and Default One)
folium.LayerControl().add_to(m)
# Add detect location button
plugins.LocateControl(
position="topleft",
drawCircle=False,
flyTo=True,
strings={"title": "My location | موقعي", "popup": "My location | موقعي"},
).add_to(m)
return m, emergency_fgs, intervention_fgs
|