Spaces:
Sleeping
Sleeping
Tracy André
commited on
Commit
·
0a62aa3
1
Parent(s):
7fb73fa
updated
Browse files- analyzer.py +150 -0
analyzer.py
CHANGED
|
@@ -361,3 +361,153 @@ class AgricultureAnalyzer:
|
|
| 361 |
def get_risk_analysis(self):
|
| 362 |
"""Retourne l'analyse des risques"""
|
| 363 |
return self.risk_analysis
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 361 |
def get_risk_analysis(self):
|
| 362 |
"""Retourne l'analyse des risques"""
|
| 363 |
return self.risk_analysis
|
| 364 |
+
|
| 365 |
+
def get_available_parcels(self):
|
| 366 |
+
"""Retourne la liste des parcelles disponibles dans les données"""
|
| 367 |
+
if self.df is None or len(self.df) == 0:
|
| 368 |
+
return []
|
| 369 |
+
|
| 370 |
+
# Créer une liste avec numéro et nom de parcelle si disponible
|
| 371 |
+
parcels_info = []
|
| 372 |
+
|
| 373 |
+
if 'nomparc' in self.df.columns:
|
| 374 |
+
# Grouper par parcelle et prendre le premier nom (en cas de doublons)
|
| 375 |
+
parcels_data = self.df.groupby('numparcell')['nomparc'].first().reset_index()
|
| 376 |
+
for _, row in parcels_data.iterrows():
|
| 377 |
+
parcel_id = str(row['numparcell'])
|
| 378 |
+
parcel_name = str(row['nomparc']) if pd.notna(row['nomparc']) else ""
|
| 379 |
+
if parcel_name and parcel_name != "nan":
|
| 380 |
+
display_name = f"{parcel_id} - {parcel_name}"
|
| 381 |
+
else:
|
| 382 |
+
display_name = parcel_id
|
| 383 |
+
parcels_info.append((display_name, parcel_id))
|
| 384 |
+
else:
|
| 385 |
+
# Seulement les numéros de parcelles
|
| 386 |
+
unique_parcels = sorted(self.df['numparcell'].dropna().unique())
|
| 387 |
+
parcels_info = [(str(p), str(p)) for p in unique_parcels]
|
| 388 |
+
|
| 389 |
+
# Ajouter l'option "Toutes les parcelles" en premier
|
| 390 |
+
parcels_info.insert(0, ("Toutes les parcelles", "ALL"))
|
| 391 |
+
|
| 392 |
+
return parcels_info
|
| 393 |
+
|
| 394 |
+
def filter_data_by_parcel(self, parcel_id):
|
| 395 |
+
"""Filtre les données par parcelle"""
|
| 396 |
+
if self.df is None or parcel_id is None or parcel_id == "ALL":
|
| 397 |
+
return self.df
|
| 398 |
+
|
| 399 |
+
parcel_data = self.df[self.df['numparcell'] == parcel_id].copy()
|
| 400 |
+
return parcel_data
|
| 401 |
+
|
| 402 |
+
def filter_data_by_year_and_parcel(self, year, parcel_id):
|
| 403 |
+
"""Filtre les données par année et parcelle"""
|
| 404 |
+
if self.df is None:
|
| 405 |
+
return None
|
| 406 |
+
|
| 407 |
+
filtered_data = self.df.copy()
|
| 408 |
+
|
| 409 |
+
# Filtrer par année si spécifiée
|
| 410 |
+
if year is not None:
|
| 411 |
+
filtered_data = filtered_data[filtered_data['millesime'] == year]
|
| 412 |
+
|
| 413 |
+
# Filtrer par parcelle si spécifiée (et différente de "ALL")
|
| 414 |
+
if parcel_id is not None and parcel_id != "ALL":
|
| 415 |
+
# Convertir parcel_id en type approprié (gérer string/int)
|
| 416 |
+
try:
|
| 417 |
+
# Essayer de convertir en entier si c'est une chaîne
|
| 418 |
+
if isinstance(parcel_id, str) and parcel_id.isdigit():
|
| 419 |
+
parcel_id_converted = int(parcel_id)
|
| 420 |
+
else:
|
| 421 |
+
parcel_id_converted = parcel_id
|
| 422 |
+
|
| 423 |
+
filtered_data = filtered_data[filtered_data['numparcell'] == parcel_id_converted]
|
| 424 |
+
except (ValueError, TypeError):
|
| 425 |
+
# En cas d'erreur de conversion, essayer tel quel
|
| 426 |
+
filtered_data = filtered_data[filtered_data['numparcell'] == parcel_id]
|
| 427 |
+
|
| 428 |
+
return filtered_data
|
| 429 |
+
|
| 430 |
+
def get_data_table_by_year_and_parcel(self, year, parcel_id=None, max_rows=1000):
|
| 431 |
+
"""Retourne un tableau des données pour une année et optionnellement une parcelle"""
|
| 432 |
+
try:
|
| 433 |
+
filtered_data = self.filter_data_by_year_and_parcel(year, parcel_id)
|
| 434 |
+
|
| 435 |
+
if filtered_data is None or len(filtered_data) == 0:
|
| 436 |
+
if parcel_id and parcel_id != "ALL":
|
| 437 |
+
return None, f"❌ Aucune donnée pour l'année {year} et la parcelle {parcel_id}"
|
| 438 |
+
else:
|
| 439 |
+
return None, f"❌ Aucune donnée pour l'année {year}"
|
| 440 |
+
|
| 441 |
+
# Sélectionner les colonnes les plus importantes pour l'affichage
|
| 442 |
+
display_cols = []
|
| 443 |
+
important_cols = [
|
| 444 |
+
'millesime', 'numparcell', 'nomparc', 'surfparc',
|
| 445 |
+
'libelleusag', 'datedebut', 'datefin', 'libevenem',
|
| 446 |
+
'familleprod', 'produit', 'quantitetot', 'unite'
|
| 447 |
+
]
|
| 448 |
+
|
| 449 |
+
for col in important_cols:
|
| 450 |
+
if col in filtered_data.columns:
|
| 451 |
+
display_cols.append(col)
|
| 452 |
+
|
| 453 |
+
if not display_cols:
|
| 454 |
+
return None, "❌ Aucune colonne importante trouvée"
|
| 455 |
+
|
| 456 |
+
# Préparer les données pour l'affichage
|
| 457 |
+
display_df = filtered_data[display_cols].copy()
|
| 458 |
+
|
| 459 |
+
# Formater les colonnes pour un meilleur affichage
|
| 460 |
+
if 'surfparc' in display_df.columns:
|
| 461 |
+
display_df['surfparc'] = display_df['surfparc'].round(2)
|
| 462 |
+
if 'quantitetot' in display_df.columns:
|
| 463 |
+
display_df['quantitetot'] = pd.to_numeric(display_df['quantitetot'], errors='coerce').round(3)
|
| 464 |
+
|
| 465 |
+
# Trier par date si disponible, sinon par parcelle
|
| 466 |
+
if 'datedebut' in display_df.columns:
|
| 467 |
+
# Convertir les dates pour le tri
|
| 468 |
+
display_df['date_sort'] = pd.to_datetime(display_df['datedebut'], format='%d/%m/%y', errors='coerce')
|
| 469 |
+
display_df = display_df.sort_values(['numparcell', 'date_sort'])
|
| 470 |
+
display_df = display_df.drop('date_sort', axis=1)
|
| 471 |
+
else:
|
| 472 |
+
display_df = display_df.sort_values('numparcell')
|
| 473 |
+
|
| 474 |
+
# Limiter le nombre de lignes pour l'affichage
|
| 475 |
+
if len(display_df) > max_rows:
|
| 476 |
+
display_df = display_df.head(max_rows)
|
| 477 |
+
info_msg = f"📊 Affichage de {max_rows} premières lignes sur {len(filtered_data)} total"
|
| 478 |
+
else:
|
| 479 |
+
info_msg = f"📊 {len(display_df)} enregistrements au total"
|
| 480 |
+
|
| 481 |
+
# Renommer les colonnes pour l'affichage
|
| 482 |
+
column_mapping = {
|
| 483 |
+
'millesime': 'Année',
|
| 484 |
+
'numparcell': 'N° Parcelle',
|
| 485 |
+
'nomparc': 'Nom Parcelle',
|
| 486 |
+
'surfparc': 'Surface (ha)',
|
| 487 |
+
'libelleusag': 'Usage',
|
| 488 |
+
'datedebut': 'Date Début',
|
| 489 |
+
'datefin': 'Date Fin',
|
| 490 |
+
'libevenem': 'Type Intervention',
|
| 491 |
+
'familleprod': 'Famille Produit',
|
| 492 |
+
'produit': 'Produit',
|
| 493 |
+
'quantitetot': 'Quantité',
|
| 494 |
+
'unite': 'Unité'
|
| 495 |
+
}
|
| 496 |
+
|
| 497 |
+
# Appliquer le renommage seulement pour les colonnes présentes
|
| 498 |
+
rename_dict = {k: v for k, v in column_mapping.items() if k in display_df.columns}
|
| 499 |
+
display_df = display_df.rename(columns=rename_dict)
|
| 500 |
+
|
| 501 |
+
# Ajouter l'information sur la sélection
|
| 502 |
+
if year and parcel_id and parcel_id != "ALL":
|
| 503 |
+
info_msg = f"📊 Année {year} - Parcelle {parcel_id}: {len(display_df)} enregistrements"
|
| 504 |
+
elif year:
|
| 505 |
+
info_msg = f"📊 Année {year}: {len(display_df)} enregistrements"
|
| 506 |
+
elif parcel_id and parcel_id != "ALL":
|
| 507 |
+
info_msg = f"📊 Parcelle {parcel_id}: {len(display_df)} enregistrements"
|
| 508 |
+
|
| 509 |
+
return display_df, info_msg
|
| 510 |
+
|
| 511 |
+
except Exception as e:
|
| 512 |
+
print(f"❌ Erreur lors de la création du tableau: {e}")
|
| 513 |
+
return None, f"❌ Erreur lors de la création du tableau: {str(e)[:100]}..."
|