#!/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()