Aller au contenu principal

GFMs Transport

Les Gap Filling Modules Transport calculent les émissions de gaz à effet de serre liées au transport des produits alimentaires de l'origine à la destination. Ces deux modules fonctionnent ensemble : transportation_mode_distance_gfm calcule les distances et les options d'itinéraire, tandis que transportation_decision_gfm sélectionne le mode de transport optimal et génère les flux d'émissions.

Référence rapide

PropriétéTransportModeDistanceGFMTransportDecisionGFM
S'exécute surFoodProductFlowNode, FlowNodeNoeuds avec attribut transport
DépendancesOriginGFM, MatchProductNameGFM, UnitWeightConversionGFM, ConservationGFMTransportModeDistanceGFM
Entrée cléLocalisation d'origine, localisation de destinationDistances de transport, périssabilité du produit
SortieDistances et valeurs CO2 par mode de transportMode de transport optimal, noeuds de flux de transport
Interface de programmation externeEcoTransitAucune

Conditions d'exécution

TransportModeDistanceGFM se déclenche lorsque :

  1. Un FoodProductFlowNode a une localisation d'origine valide
  2. Le noeud parent a une localisation de destination valide
  3. Le produit n'est pas marqué comme subdivision
  4. Aucun mode de transport n'a déjà été spécifié

TransportDecisionGFM se déclenche lorsque :

  1. Les distances de transport ont été calculées par TransportModeDistanceGFM
  2. Au moins une distance de transport valide existe (non nulle)
  3. Le noeud a un noeud enfant pour le produit pré-transporté

Sortie clé

Les modules ajoutent plusieurs composantes au graphe de calcul :

  • Pré-acheminement : Transport routier de l'origine au port/aéroport de départ
  • Transport principal : Transport primaire via le mode sélectionné (route, mer, air, rail)
  • Post-acheminement : Transport routier du port/aéroport d'arrivée à la destination
  • Refroidissement/Congélation : Émissions supplémentaires pour le transport à température contrôlée
  • Infrastructure : Émissions d'infrastructure de transport par tonne-kilomètre

Méthodologie scientifique

Le modèle de transport calcule les émissions en utilisant une approche à trois étapes avec EcoTransit pour la planification d'itinéraire et les facteurs d'émission.

Options de modes de transport

ModeCode EcoTransitVitesse de déplacementTemps de chargementPrix par kmPrix de chargement
Routeroad45 km/h3 heures0,0497 $/km84,62 $
Mersea26 km/h48 heures0,0062 $/km119,66 $
Airair500 km/h6 heures0,0062 $/km2 085,00 $
Railrail40 km/h24 heures0,0186 $/km99,58 $

Méthodologie de calcul des distances

Le modèle de transport utilise une approche hiérarchique pour calculer les distances :

Intégration EcoTransit

Pour chaque mode de transport, le système interroge EcoTransit en utilisant la méthodologie CCWG-Tradelane (Clean Cargo Working Group) :

ECOTRANSIT_CALCULATION_METHOD = "ccwg-tradelane"
ECOTRANSIT_CALCULATION_YEAR = 2024

Paramètres de requête :

  • Coordonnées de départ (centroïde d'origine ou localisation précise)
  • Coordonnées de destination (centroïde de destination ou localisation précise)
  • Mode de transport (route, mer, air, rail)
  • Poids de la cargaison : 1 tonne (émissions normalisées par tonne)

Résolution de localisation avec GADM

Les localisations sont résolues en utilisant GADM (Global Administrative Areas Database) :

  1. GADM Niveau 1-2 (Pays/Région) : Utilise les coordonnées du centroïde pour les requêtes EcoTransit
  2. GADM Niveau 3+ (Détaillé) : Revient au centroïde de la région parente de niveau 2
  3. Stratégie de mise en cache : Les résultats région-à-région sont mis en cache ; pays-à-pays sert de repli
# Format de clé de cache
request_key = f"{start_location_gadm_term.xid}_{end_location_gadm_term.xid}_{mode.value}"

Estimation des distances de pré/post-acheminement

Pour le transport maritime et aérien, les distances de pré- et post-acheminement (transport routier vers/depuis les ports) sont estimées en utilisant :

# Pour le transport dans la même région (origine et destination dans la même région GADM)
estimated_distance = ribbon_factor * direct_distance

# Pour des régions différentes
estimated_distance = max(
sqrt(region_area_km2) * scaling_factor, # Estimation basée sur la surface
distance_from_centroid_to_port # Estimation basée sur le centroïde
) * ribbon_factor

Facteurs d'échelle par mode de transport :

ModeFacteur d'échelle pré/post-acheminementDescription
Mer0,29042sqrt(surface)/2,43
Air0,11782sqrt(surface)/5,99
Route (même région)0,56905Pour le transport local

Facteur ruban (Indice de détour) :

Le facteur ruban de 1,417 convertit les distances en ligne droite en distances routières réalistes, basé sur la recherche de Ballou et al. (2002).

Calcul des émissions de CO2

Les émissions de CO2 sont extraites directement des réponses EcoTransit en tonnes CO2eq par tonne de cargaison :

# Pour chaque segment de transport
co2_value = section["emissions"]["co2Equivalents"][mode]["_value_1"]
distance = section["emissions"]["distances"][mode]["tankToWheel"]

# Le CO2 de pré/post-acheminement est mis à l'échelle en fonction de la distance estimée
scaled_co2 = ecotransit_co2 * (estimated_distance / ecotransit_distance)

Sélection du mode de transport

Le TransportDecisionGFM sélectionne le mode optimal en :

  1. Filtrage par périssabilité : Exclure les modes où le temps de trajet dépasse le temps de stockage du produit
  2. Calcul du coût total : Additionner les coûts de distance et les coûts de chargement pour chaque mode
  3. Sélection du moins cher : Choisir le mode avec le coût total le plus bas
# Calcul du temps de trajet total
travel_time = distance / travel_speed + loading_time

# Calcul du coût total
total_cost = (distance_price * distance) + loading_price

Contraintes de périssabilité

Les produits avec des contraintes de temps de stockage (réfrigérés, congelés) sont filtrés vers les modes capables de livrer dans la fenêtre de stockage :

# Vérifier si le mode est qualifié
storage_time_hours = product.storage_time * time_conversion_factor
if travel_time < storage_time_hours:
qualifying_modes.append(mode)

Si aucun mode ne répond à la contrainte de stockage, le mode le plus rapide est sélectionné comme repli.


Détails d'implémentation

Distances de transport par défaut

Lorsque l'origine ne peut être déterminée (code FAO de production inconnu), des distances par défaut basées sur l'Argentine vers l'Allemagne via le Portugal sont utilisées :

TransportDistance (km)CO2 (t/t)
Pré-acheminement (centroïde Argentine vers port)666,020,0952
Transport principal (port Argentine vers port Portugal)11 428,680,1202
Post-acheminement (port Portugal vers centroïde Allemagne)2 569,740,1908
Total14 664,440,4062

Gestion des produits non alimentaires

Les produits non alimentaires (identifiés par les termes FoodEx2 EAT-0002 et EAT-0000) sont exclus des calculs de transport.

Transport sur même localisation

Lorsque l'origine et la destination sont dans la même région GADM :

  1. Appliquer un décalage de 50 km aux coordonnées d'origine et de destination
  2. Forcer le mode de transport routier
  3. Calculer la distance en utilisant le facteur ruban
if start_location_gadm_term == end_location_gadm_term:
start_location = add_offset_to_endpoint(start_lon, start_lat, -50_000)
end_location = add_offset_to_endpoint(end_lon, end_lat, 50_000)
pre_defined_mode = ServiceTransportModeEnum.GROUND

Mutations du graphe

Le TransportDecisionGFM crée la structure de graphe suivante :

FoodProductFlowNode (ingrédient)
|
+-- FoodProcessingActivityNode (activité de transport)
|
+-- FoodProductFlowNode (produit pré-transporté)
| |
| +-- [noeuds enfants originaux]
|
+-- PracticeFlowNode (Pré-acheminement)
| +-- TransportActivityNode
| +-- FlowNode (Consommation de carburant)
| +-- PracticeFlowNode (Infrastructure)
|
+-- PracticeFlowNode (Transport principal)
| +-- TransportActivityNode
| +-- FlowNode (Consommation de carburant)
| +-- PracticeFlowNode (Infrastructure)
|
+-- PracticeFlowNode (Post-acheminement)
| +-- TransportActivityNode
| +-- FlowNode (Consommation de carburant)
| +-- PracticeFlowNode (Infrastructure)
|
+-- PracticeFlowNode (Refroidissement/Congélation) [optionnel]

Refroidissement et congélation pendant le transport

Pour les produits marqués comme réfrigérés (J0131) ou congelés (J0136), des émissions de refroidissement supplémentaires sont ajoutées :

# Calculer le temps de trajet pour le mode sélectionné
travel_time_hours = total_distance / travel_speed + loading_time

# Créer un noeud de flux de refroidissement/congélation avec une quantité en kg*heure
cooling_flow_node.amount = travel_time_hours # en unité kg*heure

Référence complète du code

Structure de requête EcoTransit

complex_transport_request = {
"cargo": Cargo(weight=1, unit="ton"),
"transportDate": None, # Dates omises pour éviter les variations temporelles
"accountingVariant": AccountingVariantParameters(
variant="ccwg-tradelane",
year=2024,
),
"section": {
"route": {
"departure": RequestStation(
wgs84=Wgs84Coordinates(departure_longitude, departure_latitude)
),
"destination": RequestStation(
wgs84=Wgs84Coordinates(destination_longitude, destination_latitude)
),
},
"carriage": {
"preCarriage": PreOrPostCarriageParameters(road=RoadParameters()),
"mainCarriage": CarriageParameters(mode_params),
"postCarriage": PreOrPostCarriageParameters(road=RoadParameters()),
},
},
"output": Output(split=OutputSplit(), createKml=False),
}

Traitement de la réponse

La réponse EcoTransit est réduite aux données essentielles pour la mise en cache :

def strip_ecotransit_response(mode: str, response: dict) -> dict:
return {
"mainhaul": {
mode: [
{
"co2eq_value": section["emissions"]["co2Equivalents"][mode]["_value_1"],
"distance": section["emissions"]["distances"][mode]["tankToWheel"],
}
for section in mainhaul_sections
]
},
"mainhaul_start_location": response["mainhaul"][0]["route"]["startLocation"]["wgs84"],
"mainhaul_end_location": response["mainhaul"][-1]["route"]["endLocation"]["wgs84"],
"preCarriage": {ServiceTransportModeEnum.GROUND: [...]},
"postCarriage": {ServiceTransportModeEnum.GROUND: [...]},
}

Calcul des coûts

async def get_minimal_cost_transportation_mode(
transport_modes_distances: TransportModesDistancesProp,
qualified_travel_modes: list,
) -> ServiceTransportModeEnum:
mile_to_km_constant = 0.621371192

# Prix par mile convertis en km
distance_prices = {
ServiceTransportModeEnum.AIR: 0.01 * mile_to_km_constant,
ServiceTransportModeEnum.GROUND: 0.08 * mile_to_km_constant,
ServiceTransportModeEnum.SEA: 0.01 * mile_to_km_constant,
ServiceTransportModeEnum.TRAIN: 0.03 * mile_to_km_constant,
}
loading_prices = {
ServiceTransportModeEnum.AIR: 2085.0,
ServiceTransportModeEnum.GROUND: 84.62,
ServiceTransportModeEnum.SEA: 119.6646,
ServiceTransportModeEnum.TRAIN: 99.578,
}

total_prices = {}
for mode in qualified_travel_modes:
total_price = 0

# Ajouter les coûts de pré/post-acheminement (toujours route)
for carriage in ("pre_carriage", "post_carriage"):
if getattr(distances[mode], carriage).value > 0:
total_price += (
distance_prices[ServiceTransportModeEnum.GROUND]
* getattr(distances[mode], carriage).value
+ loading_prices[ServiceTransportModeEnum.GROUND]
)

# Ajouter le coût du transport principal
total_price += (
distance_prices[mode] * distances[mode].main_carriage.value
+ loading_prices[mode]
)
total_prices[mode] = total_price

return min(total_prices, key=total_prices.get)

Calcul du temps de trajet

@staticmethod
def get_travel_time(distance: float, mode: str) -> float:
travel_speed = { # km/h
ServiceTransportModeEnum.AIR: 500,
ServiceTransportModeEnum.GROUND: 45,
ServiceTransportModeEnum.SEA: 26,
ServiceTransportModeEnum.TRAIN: 40,
}
travel_loading_time = { # heures
ServiceTransportModeEnum.AIR: 6,
ServiceTransportModeEnum.GROUND: 3,
ServiceTransportModeEnum.SEA: 48,
ServiceTransportModeEnum.TRAIN: 24,
}

return distance / travel_speed[mode] + travel_loading_time[mode]

Sources de données

Interface de programmation EcoTransit

EcoTransit World fournit des calculs d'émissions de transport de fret :

  • Méthodologie : Cadre GLEC (Global Logistics Emissions Council)
  • Variante de calcul : CCWG-Tradelane (Clean Cargo Working Group)
  • Couverture : Routes de fret mondiales pour la route, le rail, la mer et l'air
  • Année des données : 2024 (configurable)

La méthodologie CCWG ajoute un facteur de correction de 15 % aux distances maritimes, car la distance de la route la plus courte sous-estime généralement les distances réelles parcourues.

Base de données géographique GADM

GADM fournit les limites géographiques et les centroïdes :

  • Centroïdes de pays pour le niveau 1
  • Centroïdes régionaux pour le niveau 2
  • Repli du niveau 3+ vers le parent de niveau 2

Codes FAO pour les cas spéciaux

Code FAODescriptionComportement de transport
100000Production localePas d'émissions de transport
200000Production par défautDistances par défaut utilisées
300000Production de poisson inconnueDistances par défaut utilisées
400000Échec de correspondance de productionDistances par défaut utilisées

Exemple de calcul

Scénario : 1 kg d'oranges d'Espagne (Valence) vers la Suisse (Zurich)

Étape 1 : Résoudre les localisations

  • Origine : Espagne, région de Valence (GADM : ES.17_1)
    • Centroïde : -0,4, 39,5
  • Destination : Suisse, Zurich (GADM : CH.26_1)
    • Centroïde : 8,5, 47,4

Étape 2 : Interroger EcoTransit

Requêtes effectuées pour les modes route, mer et air :

Réponse route :

{
"mainhaul": {
"road": [
{"distance": 1284.3, "co2eq_value": 0.1156}
]
}
}

Réponse mer :

{
"mainhaul": {
"sea": [
{"distance": 2156.7, "co2eq_value": 0.0345}
]
},
"preCarriage": {"road": [{"distance": 312.4, "co2eq_value": 0.0281}]},
"postCarriage": {"road": [{"distance": 428.6, "co2eq_value": 0.0386}]}
}

Étape 3 : Calculer les options de transport

ModePré-acheminementTransport principalPost-acheminementDistance totaleCO2 total
Route0 km1 284,3 km0 km1 284,3 km0,1156 t
Mer312,4 km2 156,7 km428,6 km2 897,7 km0,1012 t

Étape 4 : Calculer les coûts

Route :

Coût = (1284,3 * 0,0497) + 84,62 = 148,45 $

Mer :

Pré-acheminement : (312,4 * 0,0497) + 84,62 = 100,14 $
Transport principal : (2156,7 * 0,0062) + 119,66 = 133,03 $
Post-acheminement : (428,6 * 0,0497) + 84,62 = 105,92 $
Total : 339,09 $

Étape 5 : Sélectionner le mode

La route est sélectionnée comme l'option viable la moins chère (148,45 $ vs 339,09 $).

Étape 6 : Créer les noeuds du graphe

  1. Noeud d'activité de transport créé
  2. Noeud de flux de transport principal : 1 284,3 km de transport routier
  3. Noeud de consommation de carburant : 0,1156 t CO2eq
  4. Noeud d'infrastructure : 1,0 tonne-km

Sortie finale

Le module ajoute des émissions de 0,1156 kg CO2eq par kg d'oranges pour le transport.


Stratégie de mise en cache

Niveaux de cache

  1. Cache région-à-région : Réponses EcoTransit complètes mises en cache par paires de termes GADM
  2. Repli pays-à-pays : Utilisé en cas d'absence dans le cache de région
  3. Cache de réponse réduite : Données minimales pour des recherches rapides (chargées au démarrage)
# Cache de réponse complète (non chargé au démarrage)
await cache.set(request_key, response_data, load_on_boot=False)

# Cache de réponse réduite (chargé au démarrage)
await cache.set(request_key + "_stripped", stripped_data, load_on_boot=True)

Calcul en arrière-plan

En cas d'absence dans le cache :

  1. Tâche en arrière-plan démarrée pour le calcul région-à-région
  2. Vérification de la présence dans le cache pays-à-pays
  3. Utilisation du repli pays si disponible, sinon attente du calcul de région
# Démarrer le calcul en arrière-plan
region_calc_task = asyncio.create_task(
get_transport_mode_responses_cached(origin, destination, mode, cache_only=False)
)

# Vérifier le repli pays
country_result = await get_transport_mode_responses_cached(
origin_country, destination_country, mode, cache_only=True
)

Limitations connues

Couverture géographique

  • Dépend de la couverture de la base de données d'itinéraires EcoTransit
  • Certaines localisations éloignées peuvent ne pas avoir de routes valides
  • Les routes maritimes nécessitent des connexions portuaires valides

Couverture des modes

  • Rail : Actuellement fonctionnel mais moins priorisé dans le modèle de coûts
  • Voies navigables intérieures : Disponibles dans EcoTransit mais pas encore implémentées
  • Ferry : Traité comme transport routier (pas de distinction)

Hypothèses du modèle

  • Date de transport non spécifiée pour éviter les variations temporelles des facteurs d'émission
  • Facteur de charge supposé à 60 % (par défaut EcoTransit)
  • Tout pré/post-acheminement supposé être du transport routier
  • Même mix d'infrastructure utilisé mondialement

Contraintes de périssabilité

  • S'applique uniquement lorsqu'un tag de temps de stockage est présent sur le produit
  • Le mode le plus rapide est sélectionné en repli lorsqu'aucun mode ne répond aux contraintes
  • Peut résulter en transport aérien pour les articles hautement périssables

Fraîcheur des données

  • Facteurs d'émission EcoTransit mis à jour annuellement
  • Les limites GADM peuvent ne pas refléter les changements administratifs récents
  • Les prix de transport dans le modèle de coûts peuvent ne pas refléter les taux actuels du marché

Références

  1. EcoTransit World. Environmental methodology and data update. https://www.ecotransit.org/

  2. Smart Freight Centre (2019). Global Logistics Emissions Council Framework for Logistics Emissions Accounting and Reporting. https://www.smartfreightcentre.org/en/our-programs/global-logistics-emissions-council/

  3. Clean Cargo Working Group. Container shipping methodology for calculating emissions. https://www.smartfreightcentre.org/en/our-programs/clean-cargo-1/

  4. Ballou, R.H., Rahardja, H., & Sakai, N. (2002). Selected country circuity factors for road travel distance estimation. Transportation Research Part A, 36(9), 843-848.

  5. Base de données GADM. Global Administrative Areas. https://gadm.org/

  6. FAO. Statistiques commerciales de l'Organisation des Nations Unies pour l'alimentation et l'agriculture. https://www.fao.org/faostat/