Spaces:
Running
Running
Update src/modules/map_dashboard.py
Browse files- src/modules/map_dashboard.py +40 -13
src/modules/map_dashboard.py
CHANGED
|
@@ -14,29 +14,44 @@ COLOR_BLUE_FILL = "#83D6F7" # Remplissage bleu
|
|
| 14 |
COLOR_GREEN_ZONE = "#54BD4B" # Vert Cluster
|
| 15 |
COLOR_YELLOW_LINE = "#FFD700" # Lignes de distance
|
| 16 |
|
|
|
|
| 17 |
# --- 1. FONCTIONS DE GÉOCODAGE (AVEC CACHE) ---
|
| 18 |
@st.cache_data(show_spinner=False)
|
| 19 |
def geocode_addresses(df_clients):
|
| 20 |
"""
|
| 21 |
Récupère les coordonnées lat/lon pour les adresses clients.
|
| 22 |
-
Utilise le cache de Streamlit pour ne pas refaire les appels API.
|
| 23 |
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
geolocator = Nominatim(user_agent="vortex_flux_app")
|
| 25 |
geocoded_data = []
|
| 26 |
-
|
| 27 |
-
# On s'assure d'avoir les colonnes nécessaires
|
| 28 |
-
if 'Adresse' not in df_clients.columns or 'ID_Client' not in df_clients.columns:
|
| 29 |
-
return pd.DataFrame()
|
| 30 |
|
| 31 |
for index, row in df_clients.iterrows():
|
| 32 |
address = row['Adresse']
|
| 33 |
client_id = row['ID_Client']
|
| 34 |
|
| 35 |
-
#
|
|
|
|
|
|
|
| 36 |
try:
|
| 37 |
-
# On ajoute "Sénégal" pour aider le géocodeur si ce n'est pas précisé
|
| 38 |
search_query = f"{address}, Sénégal" if "Sénégal" not in str(address) else address
|
| 39 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
if location:
|
| 42 |
geocoded_data.append({
|
|
@@ -47,13 +62,25 @@ def geocode_addresses(df_clients):
|
|
| 47 |
"lon": location.longitude,
|
| 48 |
"Revenus": row.get('Revenus_Mensuels', 0)
|
| 49 |
})
|
|
|
|
| 50 |
else:
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
except:
|
| 54 |
-
|
| 55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
return pd.DataFrame(geocoded_data)
|
|
|
|
| 57 |
|
| 58 |
# --- 2. FONCTION PRINCIPALE D'AFFICHAGE ---
|
| 59 |
def show_map_dashboard(client, sheet_name):
|
|
|
|
| 14 |
COLOR_GREEN_ZONE = "#54BD4B" # Vert Cluster
|
| 15 |
COLOR_YELLOW_LINE = "#FFD700" # Lignes de distance
|
| 16 |
|
| 17 |
+
|
| 18 |
# --- 1. FONCTIONS DE GÉOCODAGE (AVEC CACHE) ---
|
| 19 |
@st.cache_data(show_spinner=False)
|
| 20 |
def geocode_addresses(df_clients):
|
| 21 |
"""
|
| 22 |
Récupère les coordonnées lat/lon pour les adresses clients.
|
|
|
|
| 23 |
"""
|
| 24 |
+
# DÉBOGAGE : Afficher les colonnes disponibles
|
| 25 |
+
st.write("🔍 Colonnes disponibles:", df_clients.columns.tolist())
|
| 26 |
+
st.write("🔍 Nombre de lignes:", len(df_clients))
|
| 27 |
+
|
| 28 |
+
# Vérification des colonnes
|
| 29 |
+
if 'Adresse' not in df_clients.columns:
|
| 30 |
+
st.error("❌ Colonne 'Adresse' manquante !")
|
| 31 |
+
return pd.DataFrame()
|
| 32 |
+
|
| 33 |
+
if 'ID_Client' not in df_clients.columns:
|
| 34 |
+
st.error("❌ Colonne 'ID_Client' manquante !")
|
| 35 |
+
return pd.DataFrame()
|
| 36 |
+
|
| 37 |
geolocator = Nominatim(user_agent="vortex_flux_app")
|
| 38 |
geocoded_data = []
|
| 39 |
+
errors = []
|
|
|
|
|
|
|
|
|
|
| 40 |
|
| 41 |
for index, row in df_clients.iterrows():
|
| 42 |
address = row['Adresse']
|
| 43 |
client_id = row['ID_Client']
|
| 44 |
|
| 45 |
+
# DÉBOGAGE : Afficher l'adresse traitée
|
| 46 |
+
st.write(f"🔄 Traitement: {client_id} - {address}")
|
| 47 |
+
|
| 48 |
try:
|
|
|
|
| 49 |
search_query = f"{address}, Sénégal" if "Sénégal" not in str(address) else address
|
| 50 |
+
|
| 51 |
+
# IMPORTANT : Respecter le rate limit de Nominatim
|
| 52 |
+
time.sleep(1.5) # Pause de 1.5 sec entre chaque requête
|
| 53 |
+
|
| 54 |
+
location = geolocator.geocode(search_query, timeout=10)
|
| 55 |
|
| 56 |
if location:
|
| 57 |
geocoded_data.append({
|
|
|
|
| 62 |
"lon": location.longitude,
|
| 63 |
"Revenus": row.get('Revenus_Mensuels', 0)
|
| 64 |
})
|
| 65 |
+
st.success(f"✅ {client_id} géocodé: {location.latitude}, {location.longitude}")
|
| 66 |
else:
|
| 67 |
+
errors.append(f"❌ {client_id}: Adresse introuvable")
|
| 68 |
+
|
| 69 |
+
except GeocoderTimedOut:
|
| 70 |
+
errors.append(f"⏱️ {client_id}: Timeout")
|
| 71 |
+
except Exception as e:
|
| 72 |
+
errors.append(f"❌ {client_id}: {str(e)}")
|
| 73 |
+
|
| 74 |
+
# Afficher les erreurs
|
| 75 |
+
if errors:
|
| 76 |
+
st.warning("⚠️ Erreurs de géocodage:")
|
| 77 |
+
for err in errors:
|
| 78 |
+
st.write(err)
|
| 79 |
+
|
| 80 |
+
st.write(f"📊 Résultats: {len(geocoded_data)} adresses géocodées sur {len(df_clients)}")
|
| 81 |
+
|
| 82 |
return pd.DataFrame(geocoded_data)
|
| 83 |
+
|
| 84 |
|
| 85 |
# --- 2. FONCTION PRINCIPALE D'AFFICHAGE ---
|
| 86 |
def show_map_dashboard(client, sheet_name):
|