472 lines
No EOL
17 KiB
Python
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() |