Quando in un’app di mobilità vengono inseriti partenza e destinazione, tutto sembra semplice: due campi, un tap, qualche istante d’attesa, una lista di soluzioni di viaggio. A quell’attesa diamo poco peso, eppure è lì che si concentra il lavoro più interessante. Dietro due punti su una mappa si nasconde un microcosmo di sistemi, algoritmi e scelte architetturali che in pochi decimi di secondo costruiscono un risultato affidabile e utile.
Il microcosmo nascosto in un calcolo del percorso
Perché non basta saper calcolare un percorso?
Trovare un percorso da A a B, di per sé, non è complesso: è un problema ben studiato e ormai “risolto” dall’industria. La difficoltà nasce in condizioni reali: grandi aree geografiche, più modalità di trasporto da combinare, dati che cambiano di continuo, tempi di risposta bassissimi. Quattro vincoli gestibili uno alla volta, ma che insieme cambiano la natura del problema. Per affrontarli tutti insieme non ci affidiamo ad un unico strumento, ma a più algoritmi di calcolo del percorso (algoritmi proprietari, per il trasporto a chiamata, per il trasporto pubblico, per il carpooling), fusi ad arte. Per semplicità, in questo caso ci concentriamo su OpenTripPlanner (OTP) 2.
OTP 2 è un motore di calcolo del percorso open source e gratuito, mantenuto da oltre dieci anni da una comunità attiva e molto usato nell’ambito del calcolo del percorso per il trasporto pubblico locale. Si tratta, di fatto, del “cervello” che, dati partenza e arrivo, calcola come raggiungere la destinazione combinando mezzi pubblici, camminata, auto ed altri servizi di mobilità, a partire da dati pubblici in formati standard e tenendo conto degli aggiornamenti in tempo reale.
I vantaggi di questo motore sono molteplici:
- Multimodalità integrata: mezzi pubblici, piedi, bici, bike sharing e servizi a domanda in un unico itinerario, non in soluzioni separate.
- Calcolo multi-criterio: gestisce insieme modalità, orari, trasbordi e preferenze, adattandosi a vincoli eterogenei.
- Tempo reale: avvisi e ricalcolo degli itinerari in base a ritardi e posizione dei veicoli.
- Prestazioni e scalabilità: rapido anche su aree molto estese.
- Standard aperti: il supporto nativo a GTFS, GTFS-RT, NeTEx, SIRI, OSM e GBFS, con una comunità attiva alle spalle, riduce il rischio di lock-in.
Su cosa lavora OTP?
Quando riceve una richiesta, il motore lavora su un grafo: la rappresentazione digitale della rete di trasporto, delle strade e delle connessioni tra i punti. E qui torna uno dei vincoli iniziali, i dati che cambiano. Orari, linee e fonti si aggiornano di continuo: il grafo non può essere statico, e ogni variazione deve riflettersi nel sistema senza interrompere il servizio.
La soluzione è una pipeline automatica che lavora in sottofondo tramite un processo che controlla i cambiamenti nelle fonti dati. Quando cambiano i dati statici del pianificato (GTFS o NeTEx) o le informazioni su mappa e altimetria, parte un processo di build che ricostruisce il grafo; il nuovo grafo viene caricato in un nuovo router e rilasciato in produzione al posto del precedente, senza che l’utente se ne accorga. Quando invece il listener intercetta variazioni nei dati in tempo reale (GTFS-RT, SIRI, GTFS-Service Alerts o GBFS), queste vengono integrate direttamente nel router.
Orchestrare, non collegare
Ma un motore, per quanto avanzato, non basta: va integrato in un’architettura più ampia, che ne valorizzi le potenzialità e ne compensi i limiti. Dalla gestione e dall’aggiornamento dei dati di rete in ingresso fino alla pre-elaborazione delle richieste e al post-trattamento dei risultati, così da garantire prestazioni, affidabilità e scalabilità anche sotto carico elevato.
Il punto, quindi, non è aver adottato OTP2, ma come lo abbiamo integrato. La scelta più ovvia, far interrogare il motore di routing direttamente dall’app, è semplice ma fragile: difficile da scalare, complicata da controllare, poco aperta all’evoluzione. Per questo, tra frontend e motore di calcolo del percorso, abbiamo inserito un layer intermedio che orchestra, controlla e ottimizza ogni richiesta. Origine e destinazione non raggiungono mai il motore direttamente: passano prima da questo layer, che verifica se esiste già una risposta simile in cache, instrada al router corretto, applica le logiche custom del caso (ad esempio favorire il percorso più veloce o con meno trasbordi rispetto agli altri) ed ottimizza la chiamata.
Il risultato è un cambio di prospettiva: il routing smette di essere una funzionalità e diventa un servizio condiviso. Non è più l’app a fare routing. È la piattaforma.
Le tecnologie giuste, nei punti giusti
Inserire un layer aggiuntivo non deve però compromettere i tempi di risposta attesi dall’utente finale; per fare ciò è necessario uno stack in cui ogni tecnologia è posizionata dove genera il massimo valore. Il layer di orchestrazione è scritto in Go, scelto per gestire grandi volumi di richieste concorrenti con latenze ridottissime: qui avvengono la gestione delle chiamate, il coordinamento tra servizi e la gestione delle logiche custom. Accanto, Redis alimenta la cache: conserva le risposte più frequenti ed evita di interrogare ogni volta il motore, abbattendo latenza percepita e il carico complessivo. La comunicazione tra servizi viaggia su gRPC, più rapido e strutturato delle classiche API REST, ideale ad alta frequenza di chiamate, con i Protocol Buffers a definire un linguaggio comune, compatto e privo di ambiguità.
Tutto in un colpo d'occhio
Vista dall’alto, l’architettura si legge come due flussi paralleli che si incontrano in un solo punto.
Il flusso di runtime è ciò che accade nei decimi di secondo in cui l’utente attende: nessun servizio parla mai direttamente con il rispettivo motore di calcolo, ma passano da un gateway fino al layer di orchestrazione (otp-api, in Go). Qui la richiesta incontra la cache Redis, le logiche custom e i microservizi di supporto, e solo allora viene instradata verso il router OTP corretto, uno per area o istanza. Il tutto su gRPC e Protocol Buffers, per restare veloce anche sotto carico.
Il flusso di build opera in background: un processo si attiva ogni giorno e verifica le sorgenti dati statiche, GTFS, NeTEx, mappe e altimetrie. Se una di esse risulta modificata, viene avviato il processo otp-builder, che costruisce un nuovo grafo; quest’ultimo viene poi caricato in un nuovo router. I dati in tempo reale (GTFS-RT, SIRI e GBFS) seguono invece un percorso differente: è il router OTP stesso a scaricarli in tempo reale e a integrarli nel grafo direttamente durante l’esecuzione.
I due flussi si toccano in un solo punto: il nuovo router entra in produzione sostituendo il precedente con un hot-swap, senza alcuna interruzione percepita. È qui che si chiude l’intera idea, un sistema che si aggiorna mentre continua a rispondere.
Dove tutto questo prende vita
La teoria è una cosa; è sul campo che un’architettura mostra se regge davvero.
Milano Cortina 2026: la mobilità di un’Olimpiade diffusa. Per i Giochi Olimpici e Paralimpici Invernali abbiamo realizzato la piattaforma di mobilità: un unico ecosistema digitale per utenti accreditati (giornalisti, atleti, delegazioni olimpiche) e per il pubblico generico. La sfida era inedita: le prime “Olimpiadi diffuse”, che superano la singola città ospitante per abbracciare un’area vasta su più regioni. Il grafo è stato esteso a tutto il Nord-Est italiano, integrando oltre dieci operatori di trasporto ed una multimodalità che va da bus, metro, tram e treni fino alle navette private, con dati in tempo reale e una gestione dinamica di alert e modifiche di servizio. Connettere più regioni e farle funzionare come un unico sistema è esattamente il problema per cui un’architettura orchestrata, e non semplicemente collegata, fa la differenza.
L’app Andemo a Venezia: un ecosistema fortemente multimodale. Pochi territori mettono alla prova un motore di mobilità come Venezia, dove la rete non è fatta solo di strade. Lavoriamo con sei operatori e una varietà di mezzi che comprende bus, tram, vaporetti, treni, biciclette, monopattini e auto in sharing, tutti combinabili in un unico percorso. Una rete così eterogenea è il banco di prova ideale per un grafo che deve fondere modalità molto diverse in un risultato coerente.
LinkingSST e gli spostamenti transfrontalieri. L’ultima frontiera è il confine. Nel progetto europeo LinkingSST abilitiamo l’intermodalità tra Italia e Svizzera, integrando i dati di bus, treni, parcheggi e altre forme di mobilità: attraversare un confine internazionale diventa semplice quanto spostarsi nella propria città.