Skip to content

Repository files navigation

transit

Île-de-France & France multimodal transit — journey planning, live network map, and estimated vehicle positions, built entirely from raw open data. No Navitia, Hove.io, or other commercial journey APIs.

Transit demo — click to play video

▶ Watch demo (2½ min) · raw MP4

Rust License: MIT


What it does

  • Multimodal routing — RAPTOR over GTFS static schedules with walk transfers, hub links, and optional OSRM street geometry
  • Realtime overlay — trip delays, cancellations, alerts, and vehicle positions from GTFS-RT and PRIM SIRI Lite (StopMonitoring, EstimatedTimetable, GeneralMessage)
  • Position estimation — when GPS is unavailable, vehicles are interpolated along GTFS shapes using schedule + realtime progress
  • GraphQL API — stops, departures, trip detail, itineraries, live vehicles, subscriptions
  • Web map (WASM + Leaflet) — search stops, plan journeys, view polylines and live vehicles on an IDFM-style map

Data sources include Île-de-France Mobilités (GTFS + PRIM SIRI), SNCF open data, and the transport.data.gouv.fr PAN. Transit data remains under each producer's licence (often ODbL); application code is MIT.


Architecture

Everything is built from first principles on public feeds — no third-party routing SaaS.

  Open data feeds                    Processing pipeline                    Clients
 ┌─────────────────┐               ┌──────────────────────────┐          ┌─────────────┐
 │ IDFM GTFS       │──download──►  │ Parse & pack static    │          │ GraphQL API │
 │ SNCF GTFS       │               │ epoch (ArcSwap swap)   │──RAPTOR──►│ (port 8080) │
 │ PRIM SIRI Lite  │──poll──────►  │ Realtime overlay       │          │             │
 │ GTFS-RT (opt.)  │               │ Vehicle estimation     │          │ WASM map UI │
 └─────────────────┘               └──────────────────────────┘          │ (port 8088) │
                                                                          └─────────────┘
  1. Download / parse GTFS — conditional fetch (ETag/hash), streaming parse, horizon filter for large feeds
  2. Pack static epoch — stops, trips, stop times, shapes, pathways, hub links (grid spatial index)
  3. RAPTOR routing — multimodal legs with walk access/egress and transfer graph
  4. Realtime overlay — concurrent Tokio pollers merge SIRI StopMonitoring / EstimatedTimetable / TripUpdates into the live view
  5. Vehicle estimation — shape-aware interpolation when positions are missing
  6. GraphQL + WASM frontend — API serves queries; Trunk-built map UI talks to the same backend

See also docs/IDFM_DAILY.md, docs/REDIS_CACHE.md, and docs/IDFM_VEHICLE_MONITORING.md.


Prerequisites

Requirement Notes
Rust 1.75+ rustup recommended
RAM 8–16 GB+ IDFM + SNCF together is memory-heavy
Disk ~2 GB+ GTFS zips cached under ./data/
IDFM_PRIM_API_KEY PRIM marketplace key for IDFM realtime SIRI Lite (prim.iledefrance-mobilites.fr); apikey header
PRIM_DATASET_KEY Separate PRIM key for GTFS zip downloads (make sync-idfm, daily_sync.sh); X-API-KEY header — not the same value as IDFM_PRIM_API_KEY
Redis (optional) Response cache for search / vehicles / itineraries
OSRM (optional) Street-level walk geometry; public demo URL in config

Quick start

1. Clone & configure

git clone https://github.com/princefr/transit.git
cd transit

make setup          # wasm target, scripts, .env from .env.example

Edit .env and set API keys (see .env.example):

# PRIM realtime key — SIRI Lite (apikey header)
IDFM_PRIM_API_KEY=your_prim_realtime_api_key_here

# Separate PRIM dataset key for GTFS downloads (X-API-KEY header)
PRIM_DATASET_KEY=your_prim_dataset_api_key_here

PRIM issues separate marketplace keys for realtime and dataset access. This repo uses two env vars because callers send different headers (apikey vs X-API-KEY) and the keys are not interchangeable.

Variable Used for Header Where to get it
IDFM_PRIM_API_KEY PRIM SIRI Lite + optional GTFS-RT apikey prim.iledefrance-mobilites.fr marketplace
PRIM_DATASET_KEY GTFS zip via make sync-idfm / scripts/daily_sync.sh X-API-KEY PRIM Datahub / dataset product (separate key)
DATASETS_API_KEY Legacy fallback for PRIM_DATASET_KEY X-API-KEY Deprecated alias
DATAGOUV_API_KEY Legacy fallback for PRIM_DATASET_KEY X-API-KEY Deprecated alias

2. Pre-download IDFM GTFS (recommended)

The IDFM zip is large (~170 MB). Download before first boot:

make sync-idfm      # → data/idfm/current.zip

3. Build & run the API

make release        # or: cargo build --release
make run            # GraphQL API → http://127.0.0.1:8080

First start also fetches SNCF GTFS into ./data/sncf/. Wait until GET /health reports stopCount > 0.

4. Run the web map

In a second terminal:

make web            # WASM UI → http://127.0.0.1:8088

Open http://127.0.0.1:8088 — search two stops, plan a journey, explore the live map.

5. Smoke test

make smoke          # probes /health and GraphQL against BASE_URL

Endpoints

URL Purpose
http://127.0.0.1:8080/health Process & feed status (JSON)
http://127.0.0.1:8080/graphql GraphQL queries
http://127.0.0.1:8080/graphiql GraphiQL playground
ws://127.0.0.1:8080/ws GraphQL subscriptions
http://127.0.0.1:8088 Map UI (Trunk dev server)

Configuration

  • File: config/default.toml
  • Override: TRANSIT_CONFIG=/path/to.toml
  • Secrets: .env (loaded by make run, scripts/run_server.sh, systemd) — never commit
  • Env overrides: TRANSIT__SERVER__BIND=127.0.0.1:8080 (figment __ nesting)

Key sections: [server], [routing], [graphql], [prim], [[feeds]], optional [redis] and [ban].

Feed downloads can also use per-feed auth in TOML (auth_header + auth_env); see comments in config/default.toml for IDFM_PRIM_API_KEY and PRIM_DATASET_KEY.

# Optional: address autocomplete (Base Adresse Nationale, Île-de-France)
make ban-index

Key features

  • Journeys with scheduled + estimated departure/arrival times and delay badges
  • Live network — vehicles on map, occupancy, trip status
  • French stop search — accent-insensitive, station-biased ranking
  • IDFM loading UX — progress while the large feed parses
  • Multi-feed — namespaced ids (idfm:…, sncf:…), configurable [[feeds]]
  • Docker — docker compose up --build (mounts ./data for GTFS cache)

Development

make test           # unit + integration tests
make gate           # fmt + lib tests + wasm check
make dev            # print two-terminal run instructions
make help           # all make targets

Docker

docker compose up --build -d
BASE_URL=http://127.0.0.1:8080 make smoke

Disclaimer

Best-effort open data — not an official IDFM or SNCF journey planner. No ticketing or fares. Results are indicative; verify before travel.


License

MIT — see LICENSE. Transit data remains under each producer's licence.

About

Île-de-France & France multimodal transit from raw open data — RAPTOR routing, PRIM SIRI realtime, GraphQL API, WASM map. No Navitia.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages