Transportation GFMs
I Gap Filling Module Trasporto calcolano le emissioni di gas serra dal trasporto dei prodotti alimentari dall'origine alla destinazione. Questi due moduli lavorano insieme: transportation_mode_distance_gfm calcola le distanze e le opzioni di percorso, mentre transportation_decision_gfm seleziona la modalita di trasporto ottimale e genera i flussi di emissione.
Riferimento Rapido
| Proprieta | TransportModeDistanceGFM | TransportDecisionGFM |
|---|---|---|
| Eseguito su | FoodProductFlowNode, FlowNode | Nodi con attributo transport |
| Dipendenze | OriginGFM, MatchProductNameGFM, UnitWeightConversionGFM, ConservationGFM | TransportModeDistanceGFM |
| Input Chiave | Localita di origine, localita di destinazione | Distanze di trasporto, deperibilita del prodotto |
| Output | Distanze e valori CO2 per modalita di trasporto | Modalita di trasporto ottimale, nodi di flusso del trasporto |
| Interfaccia di programmazione esterna | EcoTransit | Nessuna |
Quando Vengono Eseguiti
TransportModeDistanceGFM si attiva quando:
- Un
FoodProductFlowNodeha una localita di origine valida - Il nodo genitore ha una localita di destinazione valida
- Il prodotto non e marcato come suddivisione
- Nessuna modalita di trasporto e gia stata specificata
TransportDecisionGFM si attiva quando:
- Le distanze di trasporto sono state calcolate da TransportModeDistanceGFM
- Esiste almeno una distanza di trasporto valida (diversa da zero)
- Il nodo ha un nodo figlio per il prodotto pre-trasportato
Output Chiave
I moduli aggiungono molteplici componenti al grafo di calcolo:
- Pre-trasporto: Trasporto su strada dall'origine al porto/aeroporto di partenza
- Trasporto principale: Trasporto primario tramite modalita selezionata (strada, mare, aria, ferrovia)
- Post-trasporto: Trasporto su strada dal porto/aeroporto di arrivo alla destinazione
- Raffreddamento/Congelamento: Emissioni aggiuntive per trasporto a temperatura controllata
- Infrastruttura: Emissioni dell'infrastruttura di trasporto per tonnellata-chilometro
Metodologia Scientifica
Il modello di trasporto calcola le emissioni usando un approccio di trasporto a tre fasi con EcoTransit per la pianificazione del percorso e i fattori di emissione.
Opzioni di Modalita di Trasporto
| Modalita | Codice EcoTransit | Velocita di Viaggio | Tempo di Carico | Prezzo per km | Prezzo di Carico |
|---|---|---|---|---|---|
| Strada | road | 45 km/h | 3 ore | $0,0497/km | $84,62 |
| Mare | sea | 26 km/h | 48 ore | $0,0062/km | $119,66 |
| Aria | air | 500 km/h | 6 ore | $0,0062/km | $2.085,00 |
| Ferrovia | rail | 40 km/h | 24 ore | $0,0186/km | $99,58 |
Metodologia di Calcolo della Distanza
Il modello di trasporto usa un approccio gerarchico per calcolare le distanze:
Integrazione EcoTransit
Per ogni modalita di trasporto, il sistema interroga EcoTransit usando la metodologia CCWG-Tradelane (Clean Cargo Working Group):
ECOTRANSIT_CALCULATION_METHOD = "ccwg-tradelane"
ECOTRANSIT_CALCULATION_YEAR = 2024
Parametri della Richiesta:
- Coordinate di partenza (centroide dell'origine o posizione precisa)
- Coordinate di destinazione (centroide della destinazione o posizione precisa)
- Modalita di trasporto (strada, mare, aria, ferrovia)
- Peso del carico: 1 tonnellata (emissioni normalizzate per tonnellata)
Risoluzione della Localita con GADM
Le localita sono risolte usando GADM (Database delle Aree Amministrative Globali):
- GADM Livello 1-2 (Paese/Regione): Usa coordinate del centroide per le interrogazioni EcoTransit
- GADM Livello 3+ (Dettagliato): Ritorna al centroide della regione genitore di livello 2
- Strategia di Cache: I risultati regione-a-regione sono memorizzati in cache; paese-a-paese serve come fallback
# Formato della chiave di cache
request_key = f"{start_location_gadm_term.xid}_{end_location_gadm_term.xid}_{mode.value}"
Stima della Distanza di Pre/Post Trasporto
Per il trasporto marittimo e aereo, le distanze di pre e post trasporto (trasporto su strada da/verso i porti) sono stimate usando:
# Per trasporto nella stessa regione (origine e destinazione nella stessa regione GADM)
estimated_distance = ribbon_factor * direct_distance
# Per regioni diverse
estimated_distance = max(
sqrt(region_area_km2) * scaling_factor, # Stima basata sull'area
distance_from_centroid_to_port # Stima basata sul centroide
) * ribbon_factor
Fattori di Scala per Modalita di Trasporto:
| Modalita | Fattore di Scala Pre/Post Trasporto | Descrizione |
|---|---|---|
| Mare | 0,29042 | sqrt(area)/2,43 |
| Aria | 0,11782 | sqrt(area)/5,99 |
| Strada (stessa regione) | 0,56905 | Per trasporto locale |
Fattore di Deviazione (Indice di Deviazione):
Il fattore di deviazione di 1,417 converte le distanze in linea retta in distanze stradali realistiche, basato sulla ricerca di Ballou et al. (2002).
Calcolo delle Emissioni di CO2
Le emissioni di CO2 sono estratte direttamente dalle risposte EcoTransit in tonnellate di CO2eq per tonnellata di carico:
# Per ogni segmento di trasporto
co2_value = section["emissions"]["co2Equivalents"][mode]["_value_1"]
distance = section["emissions"]["distances"][mode]["tankToWheel"]
# La CO2 di pre/post trasporto e scalata in base alla distanza stimata
scaled_co2 = ecotransit_co2 * (estimated_distance / ecotransit_distance)
Selezione della Modalita di Trasporto
Il TransportDecisionGFM seleziona la modalita ottimale tramite:
- Filtro per Deperibilita: Esclude le modalita dove il tempo di viaggio supera il tempo di conservazione del prodotto
- Calcola il Costo Totale: Somma i costi di distanza e i costi di carico per ogni modalita
- Seleziona il Piu Economico: Sceglie la modalita con il costo totale piu basso
# Calcolo del tempo di viaggio totale
travel_time = distance / travel_speed + loading_time
# Calcolo del costo totale
total_cost = (distance_price * distance) + loading_price
Vincoli di Deperibilita
I prodotti con vincoli di tempo di conservazione (refrigerati, congelati) sono filtrati alle modalita che possono consegnare entro la finestra di conservazione:
# Verifica se la modalita e qualificata
storage_time_hours = product.storage_time * time_conversion_factor
if travel_time < storage_time_hours:
qualifying_modes.append(mode)
Se nessuna modalita si qualifica entro il vincolo di conservazione, viene selezionata la modalita piu veloce come fallback.
Dettagli di Implementazione
Distanze di Trasporto Predefinite
Quando l'origine non puo essere determinata (codice FAO produzione sconosciuto), vengono usate distanze predefinite basate sul percorso Argentina-Germania via Portogallo:
| Trasporto | Distanza (km) | CO2 (t/t) |
|---|---|---|
| Pre-trasporto (centroide Argentina a porto) | 666,02 | 0,0952 |
| Trasporto principale (porto Argentina a porto Portogallo) | 11.428,68 | 0,1202 |
| Post-trasporto (porto Portogallo a centroide Germania) | 2.569,74 | 0,1908 |
| Totale | 14.664,44 | 0,4062 |
Gestione dei Prodotti Non Alimentari
I prodotti non alimentari (identificati dai termini FoodEx2 EAT-0002 e EAT-0000) sono esclusi dai calcoli di trasporto.
Trasporto nella Stessa Localita
Quando origine e destinazione sono nella stessa regione GADM:
- Applica un offset di 50km alle coordinate di origine e destinazione
- Forza la modalita di trasporto su strada
- Calcola la distanza usando il fattore di deviazione
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
Modifiche al Grafo
Il TransportDecisionGFM crea la seguente struttura del grafo:
FoodProductFlowNode (ingrediente)
|
+-- FoodProcessingActivityNode (attivita di trasporto)
|
+-- FoodProductFlowNode (prodotto pre-trasportato)
| |
| +-- [nodi figli originali]
|
+-- PracticeFlowNode (Pre-trasporto)
| +-- TransportActivityNode
| +-- FlowNode (Consumo carburante)
| +-- PracticeFlowNode (Infrastruttura)
|
+-- PracticeFlowNode (Trasporto principale)
| +-- TransportActivityNode
| +-- FlowNode (Consumo carburante)
| +-- PracticeFlowNode (Infrastruttura)
|
+-- PracticeFlowNode (Post-trasporto)
| +-- TransportActivityNode
| +-- FlowNode (Consumo carburante)
| +-- PracticeFlowNode (Infrastruttura)
|
+-- PracticeFlowNode (Raffreddamento/Congelamento) [opzionale]
Raffreddamento e Congelamento Durante il Trasporto
Per i prodotti etichettati come refrigerati (J0131) o congelati (J0136), vengono aggiunte emissioni di raffreddamento aggiuntive:
# Calcola il tempo di viaggio per la modalita selezionata
travel_time_hours = total_distance / travel_speed + loading_time
# Crea il nodo di flusso raffreddamento/congelamento con quantita in kg*ora
cooling_flow_node.amount = travel_time_hours # in unita kg*ora
Riferimento Codice Completo
Struttura della Richiesta EcoTransit
complex_transport_request = {
"cargo": Cargo(weight=1, unit="ton"),
"transportDate": None, # Date omesse per evitare variazioni temporali
"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),
}
Elaborazione della Risposta
La risposta EcoTransit viene ridotta ai dati essenziali per la memorizzazione in 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: [...]},
}
Calcolo del Costo
async def get_minimal_cost_transportation_mode(
transport_modes_distances: TransportModesDistancesProp,
qualified_travel_modes: list,
) -> ServiceTransportModeEnum:
mile_to_km_constant = 0.621371192
# Prezzi per miglio convertiti in 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
# Aggiungi costi di pre/post trasporto (sempre su strada)
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]
)
# Aggiungi costo del trasporto principale
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)
Calcolo del Tempo di Viaggio
@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 = { # ore
ServiceTransportModeEnum.AIR: 6,
ServiceTransportModeEnum.GROUND: 3,
ServiceTransportModeEnum.SEA: 48,
ServiceTransportModeEnum.TRAIN: 24,
}
return distance / travel_speed[mode] + travel_loading_time[mode]
Fonti dei Dati
Interfaccia di programmazione EcoTransit
EcoTransit World fornisce calcoli delle emissioni del trasporto merci:
- Metodologia: GLEC Framework (Global Logistics Emissions Council)
- Variante di calcolo: CCWG-Tradelane (Clean Cargo Working Group)
- Copertura: Rotte merci globali per strada, ferrovia, mare e aria
- Anno dei dati: 2024 (configurabile)
La metodologia CCWG aggiunge un fattore di correzione del 15% alle distanze marittime, poiche la distanza del percorso piu breve tipicamente sottostima le distanze effettivamente percorse.
Database Geografico GADM
GADM fornisce confini geografici e centroidi:
- Centroidi dei paesi per il livello 1
- Centroidi regionali per il livello 2
- Fallback dal livello 3+ al genitore di livello 2
Codici FAO per Casi Speciali
| Codice FAO | Descrizione | Comportamento Trasporto |
|---|---|---|
100000 | Produzione locale | Nessuna emissione di trasporto |
200000 | Produzione predefinita | Vengono usate distanze predefinite |
300000 | Produzione pesce sconosciuto | Vengono usate distanze predefinite |
400000 | Abbinamento produzione fallito | Vengono usate distanze predefinite |
Esempio di Calcolo
Scenario: 1 kg di arance dalla Spagna (Valencia) alla Svizzera (Zurigo)
Passo 1: Risolvere le Localita
- Origine: Spagna, regione Valencia (GADM: ES.17_1)
- Centroide: -0,4, 39,5
- Destinazione: Svizzera, Zurigo (GADM: CH.26_1)
- Centroide: 8,5, 47,4
Passo 2: Interrogare EcoTransit
Interrogazioni effettuate per modalita strada, mare e aria:
Risposta Strada:
{
"mainhaul": {
"road": [
{"distance": 1284.3, "co2eq_value": 0.1156}
]
}
}
Risposta Mare:
{
"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}]}
}
Passo 3: Calcolare le Opzioni di Trasporto
| Modalita | Pre-trasporto | Trasporto principale | Post-trasporto | Distanza Totale | CO2 Totale |
|---|---|---|---|---|---|
| Strada | 0 km | 1.284,3 km | 0 km | 1.284,3 km | 0,1156 t |
| Mare | 312,4 km | 2.156,7 km | 428,6 km | 2.897,7 km | 0,1012 t |
Passo 4: Calcolare i Costi
Strada:
Costo = (1284,3 * 0,0497) + 84,62 = $148,45
Mare:
Pre-trasporto: (312,4 * 0,0497) + 84,62 = $100,14
Trasporto principale: (2156,7 * 0,0062) + 119,66 = $133,03
Post-trasporto: (428,6 * 0,0497) + 84,62 = $105,92
Totale: $339,09
Passo 5: Selezionare la Modalita
La strada viene selezionata come l'opzione piu economica e praticabile ($148,45 vs $339,09).
Passo 6: Creare i Nodi del Grafo
- Nodo attivita di trasporto creato
- Nodo di flusso trasporto principale: 1.284,3 km trasporto su strada
- Nodo consumo carburante: 0,1156 t CO2eq
- Nodo infrastruttura: 1,0 tonnellata-km
Output Finale
Il modulo aggiunge emissioni di 0,1156 kg CO2eq per kg di arance per il trasporto.
Strategia di Cache
Livelli di Cache
- Cache regione-a-regione: Risposte EcoTransit complete memorizzate per coppie di termini GADM
- Fallback paese-a-paese: Usato quando si verifica un miss nella cache regionale
- Cache risposta ridotta: Dati minimi per ricerche rapide (caricati all'avvio)
# Cache risposta completa (non caricata all'avvio)
await cache.set(request_key, response_data, load_on_boot=False)
# Cache risposta ridotta (caricata all'avvio)
await cache.set(request_key + "_stripped", stripped_data, load_on_boot=True)
Calcolo in Background
Quando si verifica un miss nella cache:
- Avvia un task in background per il calcolo regione-a-regione
- Verifica se c'e un hit nella cache paese-a-paese
- Usa il fallback del paese se disponibile, altrimenti attendi il calcolo regionale
# Avvia calcolo in background
region_calc_task = asyncio.create_task(
get_transport_mode_responses_cached(origin, destination, mode, cache_only=False)
)
# Verifica fallback del paese
country_result = await get_transport_mode_responses_cached(
origin_country, destination_country, mode, cache_only=True
)
Limitazioni Note
Copertura Geografica
- Dipende dalla copertura del database delle rotte EcoTransit
- Alcune localita remote potrebbero non avere rotte valide
- Le rotte marittime richiedono connessioni portuali valide
Copertura delle Modalita
- Ferrovia: Attualmente funzionale ma meno prioritaria nel modello di costo
- Vie d'acqua interne: Disponibile in EcoTransit ma non ancora implementato
- Traghetto: Gestito come trasporto su strada (nessuna distinzione)
Ipotesi del Modello
- Data di trasporto non specificata per evitare variazioni temporali nei fattori di emissione
- Fattore di carico assunto al 60% (predefinito EcoTransit)
- Tutto il pre/post trasporto assunto come trasporto su strada
- Stesso mix infrastrutturale usato globalmente
Vincoli di Deperibilita
- Si applica solo quando il tag del tempo di conservazione e presente sul prodotto
- La modalita piu veloce selezionata come fallback quando nessuna modalita soddisfa i vincoli
- Puo risultare in trasporto aereo per articoli altamente deperibili
Freschezza dei Dati
- Fattori di emissione EcoTransit aggiornati annualmente
- I confini GADM potrebbero non riflettere recenti cambiamenti amministrativi
- I prezzi di trasporto nel modello di costo potrebbero non riflettere le tariffe di mercato attuali
Riferimenti
-
EcoTransit World. Environmental methodology and data update. https://www.ecotransit.org/
-
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/
-
Clean Cargo Working Group. Container shipping methodology for calculating emissions. https://www.smartfreightcentre.org/en/our-programs/clean-cargo-1/
-
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.
-
GADM Database. Global Administrative Areas. https://gadm.org/
-
FAO. Food and Agriculture Organization trade statistics. https://www.fao.org/faostat/