klydekushy commited on
Commit
d5a050b
·
verified ·
1 Parent(s): 99d9d70

Update src/modules/map_dashboard.py

Browse files
Files changed (1) hide show
  1. src/modules/map_dashboard.py +28 -42
src/modules/map_dashboard.py CHANGED
@@ -41,16 +41,13 @@ COLOR_YELLOW_LINE = "#FFD700" # Lignes de distance
41
  # --- 1. FONCTIONS DE GÉOCODAGE (AVEC CACHE) ---
42
  @st.cache_data(show_spinner=False, ttl=3600)
43
  def geocode_addresses(df_clients):
44
- """Géocodage via Mapbox API - Meilleure couverture mondiale"""
45
 
46
  if 'Adresse' not in df_clients.columns or 'ID_Client' not in df_clients.columns:
47
  return pd.DataFrame()
48
 
49
- # METTEZ VOTRE TOKEN MAPBOX ICI
50
- MAPBOX_TOKEN = "pk.eyJ1Ijoia2x5ZGUwNyIsImEiOiJjbWpwd3B4cWMwYTVqM2ZxeHcwM3FoMHF5In0.mgiTZbug_4eD3cSNgF2t5Q" # Le même que vous avez utilisé pour la carte
51
-
52
- # Bounding Box du Sénégal : [lon_min, lat_min, lon_max, lat_max]
53
- SENEGAL_BBOX = [-17.535, 12.307, -11.355, 16.691]
54
 
55
  geocoded_data = []
56
 
@@ -59,46 +56,31 @@ def geocode_addresses(df_clients):
59
  client_id = row['ID_Client']
60
 
61
  try:
62
- # Encoder l'adresse pour l'URL
63
  import urllib.parse
64
- encoded_address = urllib.parse.quote(address)
65
 
66
- # Appel API Mapbox Geocoding
67
- url = f"https://api.mapbox.com/geocoding/v5/mapbox.places/{encoded_address}.json"
68
  params = {
69
- 'access_token': MAPBOX_TOKEN,
 
 
 
70
  'limit': 1,
71
- 'language': 'fr',
72
- 'country': 'sn', # Limiter au Sénégal uniquement
73
- 'bbox': ','.join(map(str, SENEGAL_BBOX)), # Bounding box Sénégal
74
- 'proximity': '-17.4467,14.6928' # Prioriser autour de Dakar
75
  }
76
 
77
- import requests
78
  response = requests.get(url, params=params, timeout=10)
79
 
80
  if response.status_code == 200:
81
  data = response.json()
82
 
83
- if data['features']:
84
- feature = data['features'][0]
85
- coords = feature['geometry']['coordinates']
86
- lon, lat = coords[0], coords[1]
87
- place_name = feature['place_name']
88
- relevance = feature.get('relevance', 0)
89
-
90
- # Vérifier la pertinence du résultat
91
- if relevance < 0.5:
92
- st.warning(f"⚠️ {client_id}: Résultat peu fiable ({relevance:.2f}) - '{place_name}'")
93
-
94
- # Vérifier que c'est bien au Sénégal
95
- context = feature.get('context', [])
96
- is_senegal = any('Senegal' in str(ctx) or 'Sénégal' in str(ctx) for ctx in context)
97
 
98
- if not is_senegal and 'Senegal' not in place_name and 'Sénégal' not in place_name:
99
- st.error(f"❌ {client_id}: Résultat hors Sénégal - '{place_name}' (IGNORÉ)")
100
- continu
101
-
102
  geocoded_data.append({
103
  "ID": client_id,
104
  "Nom": row.get('Nom_Complet', 'Client Inconnu'),
@@ -108,17 +90,20 @@ def geocode_addresses(df_clients):
108
  "Revenus": row.get('Revenus_Mensuels', 0)
109
  })
110
 
111
- st.success(f"✅ {client_id}: {place_name} (confiance: {relevance:.2f})")
112
  else:
113
  st.error(f"❌ {client_id}: Adresse introuvable - '{address}'")
114
-
115
  elif response.status_code == 401:
116
- st.error(f"❌ Token Mapbox invalide ou expiré")
117
- break
 
 
 
118
  else:
119
- st.error(f"❌ {client_id}: Erreur API {response.status_code}")
120
-
121
- time.sleep(0.3) # Rate limit respectueux
122
 
123
  except Exception as e:
124
  st.error(f"❌ {client_id}: Erreur - {str(e)}")
@@ -325,4 +310,5 @@ def show_map_dashboard(client, sheet_name):
325
  """
326
 
327
  # Afficher la carte
328
- st.components.v1.html(mapbox_html, height=600)
 
 
41
  # --- 1. FONCTIONS DE GÉOCODAGE (AVEC CACHE) ---
42
  @st.cache_data(show_spinner=False, ttl=3600)
43
  def geocode_addresses(df_clients):
44
+ """Géocodage via LocationIQ - Gratuit et précis"""
45
 
46
  if 'Adresse' not in df_clients.columns or 'ID_Client' not in df_clients.columns:
47
  return pd.DataFrame()
48
 
49
+ # METTEZ VOTRE TOKEN LOCATIONIQ ICI
50
+ LOCATIONIQ_TOKEN = "pk.e1561a89e1ed2bc2ddeb3ee53fd88fb8"
 
 
 
51
 
52
  geocoded_data = []
53
 
 
56
  client_id = row['ID_Client']
57
 
58
  try:
 
59
  import urllib.parse
60
+ import requests
61
 
62
+ # URL LocationIQ Geocoding
63
+ url = "https://us1.locationiq.com/v1/search.php"
64
  params = {
65
+ 'key': LOCATIONIQ_TOKEN,
66
+ 'q': address,
67
+ 'format': 'json',
68
+ 'countrycodes': 'sn', # Limiter au Sénégal
69
  'limit': 1,
70
+ 'accept-language': 'fr'
 
 
 
71
  }
72
 
 
73
  response = requests.get(url, params=params, timeout=10)
74
 
75
  if response.status_code == 200:
76
  data = response.json()
77
 
78
+ if data and len(data) > 0:
79
+ result = data[0]
80
+ lat = float(result['lat'])
81
+ lon = float(result['lon'])
82
+ display_name = result['display_name']
 
 
 
 
 
 
 
 
 
83
 
 
 
 
 
84
  geocoded_data.append({
85
  "ID": client_id,
86
  "Nom": row.get('Nom_Complet', 'Client Inconnu'),
 
90
  "Revenus": row.get('Revenus_Mensuels', 0)
91
  })
92
 
93
+ st.success(f"✅ {client_id}: {display_name}")
94
  else:
95
  st.error(f"❌ {client_id}: Adresse introuvable - '{address}'")
96
+
97
  elif response.status_code == 401:
98
+ st.error(f"❌ Token LocationIQ invalide")
99
+ break
100
+ elif response.status_code == 429:
101
+ st.error(f"⚠️ Limite de requêtes atteinte (5000/jour)")
102
+ break
103
  else:
104
+ st.error(f"❌ {client_id}: Erreur {response.status_code}")
105
+
106
+ time.sleep(1.2) # Rate limit: max 2 req/sec (on joue safe avec 1.2s)
107
 
108
  except Exception as e:
109
  st.error(f"❌ {client_id}: Erreur - {str(e)}")
 
310
  """
311
 
312
  # Afficher la carte
313
+ st.components.v1.html(mapbox_html, height=600)
314
+