py_atmo_data_wrapper/demos/demo_emission_functions.py
2025-07-14 17:56:57 +02:00

472 lines
No EOL
17 KiB
Python

#!/usr/bin/env python3
"""
Script de démonstration des fonctionnalités de la classe EmissionData
================================================================
Ce script illustre l'utilisation de toutes les méthodes disponibles
dans la classe EmissionData pour analyser les données d'émissions.
Fonctionnalités testées:
- Analyse des émissions par polluant
- Calcul de densités d'émission par km²
- Calcul d'émissions par habitant
- Analyse des secteurs d'émission
- Gestion des coordonnées géographiques
- Utilisation des méthodes héritées de la classe de base
"""
import json
from pathlib import Path
from atmo_wrapper import AtmoDataWrapper
from atmo_data_wrapper import EmissionData, AtmoDataCollection, Coordinates
from atmo_data_wrapper import SECTEURS_EMISSIONS
def demo_basic_properties():
"""Démonstration des propriétés de base d'un objet EmissionData"""
print("=" * 60)
print("DÉMONSTRATION DES PROPRIÉTÉS DE BASE")
print("=" * 60)
# Exemple de données d'émission simulées
sample_emission = {
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [6.1667, 49.1333] # Nancy
},
"properties": {
"aasqa": "90",
"source": "ATMO Grand Est",
"date_maj": "2024-01-15",
"lib_zone": "Nancy Métropole",
"code": "54395",
"name": "Nancy",
"population": 104885,
"superficie": 15.01,
"nox": 125.5,
"pm10": 45.2,
"pm25": 28.7,
"ges": 850.3,
"code_pcaet": "01"
}
}
emission = EmissionData(sample_emission)
print(f"Code zone: {emission.code}")
print(f"Nom: {emission.name}")
print(f"Population: {emission.population:,} habitants")
print(f"Superficie: {emission.superficie} km²")
print(f"AASQA: {emission.get_aasqa_name()}")
print(f"Source: {emission.get_source()}")
print(f"Date de mise à jour: {emission.date_maj}")
print(f"Zone: {emission.lib_zone}")
print(f"Secteur: {emission.get_secteur_name()}")
if emission.has_coordinates():
print(f"Coordonnées: {emission.coordinates}")
else:
print("Pas de coordonnées disponibles")
print(f"Représentation: {emission}")
print()
def demo_emission_analysis():
"""Démonstration de l'analyse des émissions"""
print("=" * 60)
print("ANALYSE DES ÉMISSIONS PAR POLLUANT")
print("=" * 60)
# Exemple avec plusieurs zones d'émission
emission_samples = [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [6.1667, 49.1333]},
"properties": {
"aasqa": "90", "name": "Nancy", "population": 104885, "superficie": 15.01,
"nox": 125.5, "pm10": 45.2, "pm25": 28.7, "ges": 850.3, "code_pcaet": "01"
}
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [7.7500, 48.5833]},
"properties": {
"aasqa": "90", "name": "Strasbourg", "population": 280966, "superficie": 78.26,
"nox": 285.7, "pm10": 92.1, "pm25": 58.4, "ges": 1850.9, "code_pcaet": "02"
}
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [6.2000, 49.2500]},
"properties": {
"aasqa": "90", "name": "Metz", "population": 116429, "superficie": 41.94,
"nox": 155.8, "pm10": 52.3, "pm25": 35.1, "ges": 950.7, "code_pcaet": "03"
}
}
]
for i, emission_data in enumerate(emission_samples, 1):
emission = EmissionData(emission_data)
print(f"{i}. {emission.name}")
print(f" Population: {emission.population:,} hab, Superficie: {emission.superficie} km²")
# Émissions totales
total_emissions = emission.get_total_emissions()
print(f" Émissions totales:")
for polluant, valeur in total_emissions.items():
print(f" - {polluant}: {valeur:.1f} tonnes/an")
print()
def demo_density_calculations():
"""Démonstration des calculs de densité d'émission"""
print("=" * 60)
print("CALCULS DE DENSITÉ D'ÉMISSION (tonnes/km²)")
print("=" * 60)
emission_data = {
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [2.3522, 48.8566]},
"properties": {
"aasqa": "18", "name": "Paris", "population": 2161000, "superficie": 105.4,
"nox": 1250.5, "pm10": 425.2, "pm25": 280.7, "ges": 8500.3, "code_pcaet": "01"
}
}
emission = EmissionData(emission_data)
print(f"Zone: {emission.name}")
print(f"Superficie: {emission.superficie} km²")
print()
print("Densités d'émission par km²:")
pollutants = ['nox', 'pm10', 'pm25', 'ges']
for pollutant in pollutants:
density = emission.get_emission_density(pollutant)
polluant_name = pollutant.upper().replace('GES', 'GES (CO2 eq)')
print(f" - {polluant_name}: {density:.2f} tonnes/km²")
print()
def demo_per_capita_calculations():
"""Démonstration des calculs d'émission par habitant"""
print("=" * 60)
print("CALCULS D'ÉMISSION PAR HABITANT (tonnes/hab/an)")
print("=" * 60)
emission_data = {
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [3.0573, 50.6292]},
"properties": {
"aasqa": "59", "name": "Lille Métropole", "population": 1182127, "superficie": 611.0,
"nox": 1580.3, "pm10": 520.7, "pm25": 315.8, "ges": 11250.5, "code_pcaet": "02"
}
}
emission = EmissionData(emission_data)
print(f"Zone: {emission.name}")
print(f"Population: {emission.population:,} habitants")
print()
print("Émissions par habitant (en tonnes/habitant/an):")
pollutants = ['nox', 'pm10', 'pm25', 'ges']
for pollutant in pollutants:
per_capita = emission.get_emission_per_capita(pollutant)
polluant_name = pollutant.upper().replace('GES', 'GES (CO2 eq)')
# Convertir en kg/hab/an pour plus de lisibilité
per_capita_kg = per_capita * 1000
print(f" - {polluant_name}: {per_capita:.6f} t/hab/an ({per_capita_kg:.2f} kg/hab/an)")
print()
def demo_secteur_analysis():
"""Démonstration de l'analyse par secteur d'émission"""
print("=" * 60)
print("ANALYSE PAR SECTEUR D'ÉMISSION")
print("=" * 60)
# Simulation de différents secteurs d'émission
secteurs_samples = [
{"code_pcaet": "01", "name": "Transport routier", "nox": 850.5, "pm10": 45.2},
{"code_pcaet": "02", "name": "Industrie manufacturière", "nox": 320.8, "pm10": 85.7},
{"code_pcaet": "03", "name": "Résidentiel", "nox": 125.3, "pm10": 95.4},
{"code_pcaet": "04", "name": "Agriculture", "nox": 85.2, "pm10": 125.8},
{"code_pcaet": "05", "name": "Tertiaire", "nox": 65.7, "pm10": 25.3}
]
print("Émissions par secteur:")
print()
for i, secteur_data in enumerate(secteurs_samples, 1):
emission_data = {
"type": "Feature",
"properties": {
"aasqa": "25", "name": f"Zone {i}", "population": 50000, "superficie": 25.0,
"nox": secteur_data["nox"], "pm10": secteur_data["pm10"], "pm25": 15.0, "ges": 500.0,
"code_pcaet": secteur_data["code_pcaet"]
}
}
emission = EmissionData(emission_data)
print(f"{i}. Secteur: {emission.get_secteur_name()}")
print(f" Code PCAET: {emission.code_pcaet}")
print(f" Émissions NOx: {emission.nox:.1f} t/an")
print(f" Émissions PM10: {emission.pm10:.1f} t/an")
print()
def demo_coordinate_functions():
"""Démonstration des fonctions de coordonnées géographiques"""
print("=" * 60)
print("FONCTIONS DE COORDONNÉES GÉOGRAPHIQUES")
print("=" * 60)
# Créer des émissions avec coordonnées
emission_lille = EmissionData({
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [3.0573, 50.6292]},
"properties": {
"aasqa": "59", "name": "Lille", "population": 233897, "superficie": 34.8,
"nox": 285.5, "pm10": 85.2, "pm25": 55.7, "ges": 1250.3, "code_pcaet": "01"
}
})
emission_nancy = EmissionData({
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [6.1667, 49.1333]},
"properties": {
"aasqa": "90", "name": "Nancy", "population": 104885, "superficie": 15.01,
"nox": 125.5, "pm10": 45.2, "pm25": 28.7, "ges": 850.3, "code_pcaet": "01"
}
})
print(f"Émission 1: {emission_lille.name}")
print(f" Coordonnées: {emission_lille.coordinates}")
print(f" A des coordonnées: {emission_lille.has_coordinates()}")
print()
print(f"Émission 2: {emission_nancy.name}")
print(f" Coordonnées: {emission_nancy.coordinates}")
print(f" A des coordonnées: {emission_nancy.has_coordinates()}")
print()
# Calcul de distance
if emission_lille.has_coordinates() and emission_nancy.has_coordinates():
distance = emission_lille.coordinates.distance_to(emission_nancy.coordinates)
print(f"Distance entre {emission_lille.name} et {emission_nancy.name}: {distance:.1f} km")
print()
def demo_inherited_methods():
"""Démonstration des méthodes héritées de la classe de base"""
print("=" * 60)
print("MÉTHODES HÉRITÉES DE LA CLASSE DE BASE")
print("=" * 60)
emission_data = {
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [4.8357, 45.7640]},
"properties": {
"aasqa": "84", "name": "Lyon Métropole", "population": 1398892, "superficie": 533.68,
"nox": 1850.7, "pm10": 625.4, "pm25": 385.2, "ges": 13250.8, "code_pcaet": "02",
"source": "ATMO Auvergne-Rhône-Alpes", "date_maj": "2024-01-15"
}
}
emission = EmissionData(emission_data)
print(f"Zone: {emission.name}")
print(f"AASQA: {emission.get_aasqa_name()}")
print(f"Source: {emission.get_source()}")
print()
# Test des fonctions de couleur et emoji (niveau fictif pour démonstration)
print("Fonctions de couleur et emoji (exemple avec niveau 3):")
test_level = 3
couleur_hex, couleur_rgb = emission.get_color_by_level(test_level)
emoji_round = emission.get_emoji_by_level(test_level, "round")
emoji_square = emission.get_emoji_by_level(test_level, "square")
print(f" - Couleur hex: {couleur_hex}")
print(f" - Couleur RGB: {couleur_rgb}")
print(f" - Emoji rond: {emoji_round}")
print(f" - Emoji carré: {emoji_square}")
print()
def demo_comparative_analysis():
"""Démonstration d'une analyse comparative entre plusieurs zones"""
print("=" * 60)
print("ANALYSE COMPARATIVE ENTRE ZONES")
print("=" * 60)
zones_data = [
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [2.3522, 48.8566]},
"properties": {
"aasqa": "18", "name": "Paris", "population": 2161000, "superficie": 105.4,
"nox": 1250.5, "pm10": 425.2, "pm25": 280.7, "ges": 8500.3, "code_pcaet": "01"
}
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [4.8357, 45.7640]},
"properties": {
"aasqa": "84", "name": "Lyon", "population": 1398892, "superficie": 533.68,
"nox": 1850.7, "pm10": 625.4, "pm25": 385.2, "ges": 13250.8, "code_pcaet": "02"
}
},
{
"type": "Feature",
"geometry": {"type": "Point", "coordinates": [5.3698, 43.2965]},
"properties": {
"aasqa": "13", "name": "Marseille", "population": 868277, "superficie": 240.62,
"nox": 980.3, "pm10": 385.7, "pm25": 245.8, "ges": 7250.5, "code_pcaet": "01"
}
}
]
emissions = [EmissionData(zone) for zone in zones_data]
print("Comparaison des émissions par habitant (kg/hab/an):")
print("-" * 55)
print(f"{'Zone':<15} {'NOx':<8} {'PM10':<8} {'PM2.5':<8} {'GES':<10}")
print("-" * 55)
for emission in emissions:
nox_per_cap = emission.get_emission_per_capita('nox') * 1000 # Conversion en kg
pm10_per_cap = emission.get_emission_per_capita('pm10') * 1000
pm25_per_cap = emission.get_emission_per_capita('pm25') * 1000
ges_per_cap = emission.get_emission_per_capita('ges') * 1000
print(f"{emission.name:<15} {nox_per_cap:<8.1f} {pm10_per_cap:<8.1f} {pm25_per_cap:<8.1f} {ges_per_cap:<10.1f}")
print()
print("Comparaison des densités d'émission (tonnes/km²):")
print("-" * 55)
print(f"{'Zone':<15} {'NOx':<8} {'PM10':<8} {'PM2.5':<8} {'GES':<10}")
print("-" * 55)
for emission in emissions:
nox_density = emission.get_emission_density('nox')
pm10_density = emission.get_emission_density('pm10')
pm25_density = emission.get_emission_density('pm25')
ges_density = emission.get_emission_density('ges')
print(f"{emission.name:<15} {nox_density:<8.1f} {pm10_density:<8.1f} {pm25_density:<8.1f} {ges_density:<10.1f}")
print()
def demo_edge_cases():
"""Démonstration de la gestion des cas particuliers"""
print("=" * 60)
print("GESTION DES CAS PARTICULIERS")
print("=" * 60)
# Cas 1: Données manquantes
print("1. Zone sans coordonnées:")
emission_no_coords = EmissionData({
"type": "Feature",
"properties": {
"aasqa": "99", "name": "Zone sans coordonnées", "population": 10000, "superficie": 20.0,
"nox": 50.0, "pm10": 20.0, "pm25": 15.0, "ges": 300.0, "code_pcaet": "01"
}
})
print(f" A des coordonnées: {emission_no_coords.has_coordinates()}")
print(f" Coordonnées: {emission_no_coords.coordinates}")
print()
# Cas 2: Population nulle (division par zéro)
print("2. Zone sans population:")
emission_no_pop = EmissionData({
"type": "Feature",
"properties": {
"aasqa": "99", "name": "Zone industrielle", "population": 0, "superficie": 5.0,
"nox": 150.0, "pm10": 25.0, "pm25": 18.0, "ges": 800.0, "code_pcaet": "02"
}
})
nox_per_cap = emission_no_pop.get_emission_per_capita('nox')
print(f" Émission NOx par habitant: {nox_per_cap} (population = 0)")
print()
# Cas 3: Superficie nulle
print("3. Zone sans superficie:")
emission_no_area = EmissionData({
"type": "Feature",
"properties": {
"aasqa": "99", "name": "Point source", "population": 100, "superficie": 0,
"nox": 25.0, "pm10": 8.0, "pm25": 5.0, "ges": 150.0, "code_pcaet": "02"
}
})
nox_density = emission_no_area.get_emission_density('nox')
print(f" Densité NOx: {nox_density} (superficie = 0)")
print()
# Cas 4: Secteur inconnu
print("4. Secteur d'émission non référencé:")
emission_unknown_sector = EmissionData({
"type": "Feature",
"properties": {
"aasqa": "99", "name": "Zone test", "population": 5000, "superficie": 10.0,
"nox": 35.0, "pm10": 12.0, "pm25": 8.0, "ges": 200.0, "code_pcaet": "99"
}
})
print(f" Code secteur: {emission_unknown_sector.code_pcaet}")
print(f" Nom secteur: {emission_unknown_sector.get_secteur_name()}")
print()
def main():
"""Fonction principale de démonstration"""
print("SCRIPT DE DÉMONSTRATION - CLASSE EMISSIONDATA")
print("=" * 60)
print("Ce script teste toutes les fonctionnalités de la classe EmissionData")
print("pour l'analyse des données d'émissions atmosphériques.")
print()
try:
# Exécution de toutes les démonstrations
demo_basic_properties()
demo_emission_analysis()
demo_density_calculations()
demo_per_capita_calculations()
demo_secteur_analysis()
demo_coordinate_functions()
demo_inherited_methods()
demo_comparative_analysis()
demo_edge_cases()
print("=" * 60)
print("RÉCAPITULATIF DES MÉTHODES TESTÉES")
print("=" * 60)
print("Méthodes spécifiques à EmissionData:")
print("✓ get_emission_density(pollutant)")
print("✓ get_emission_per_capita(pollutant)")
print("✓ get_total_emissions()")
print("✓ get_secteur_name()")
print()
print("Méthodes héritées de AtmoDataBase:")
print("✓ get_aasqa_name()")
print("✓ get_source()")
print("✓ has_coordinates()")
print("✓ get_emoji_by_level(level, style)")
print("✓ get_color_by_level(level)")
print()
print("Propriétés testées:")
print("✓ Coordonnées géographiques et distance")
print("✓ Émissions par polluant (nox, pm10, pm25, ges)")
print("✓ Données démographiques (population, superficie)")
print("✓ Secteurs d'émission (code_pcaet)")
print("✓ Gestion des cas particuliers (données manquantes)")
print()
print("✅ TOUTES LES FONCTIONNALITÉS ONT ÉTÉ TESTÉES AVEC SUCCÈS")
except Exception as e:
print(f"❌ ERREUR lors de l'exécution: {e}")
raise
if __name__ == "__main__":
main()