A route planner for Swiss public transport. Give it a departure, an arrival, a day and a time, and it lists every trip worth taking: the fastest ones, and the ones with fewer changes, side by side.
Built with Mohamed Amine Goulahsen in spring 2025 for CS-108, Practice of object-oriented programming, at EPFL.
| Saved to a calendar | Drawn on a map |
|---|---|
![]() |
![]() |
The same trip from EPFL to Gruyères: picked in the app, exported as an iCalendar event, and opened on uMap from its GeoJSON.
- Finds stops as you type. The search ignores accents, ignores case unless you type a capital, takes words in any order, and knows the other names a station goes by.
- Weighs more than speed. Each trip is compared on its departure time, its arrival time and its number of changes, and a trip is only shown when no other one does as well or better on all three.
- Shows every leg. Platforms, walking transfers and changes are listed for the selected trip, and each leg folds out to show its intermediate stops.
- Exports the trip. Calendrier saves it as an
.icsevent, and Carte opens it on a map in the browser.
The timetable is the Swiss public transport timetable flattened into binary files: stations, platforms, routes and transfers, then the trips and connections of each day. The files are memory-mapped, so the app reads only the bytes it needs. The repository holds one week of it, from 26 May to 1 June 2025, in timetable/.
The router implements the connection scan algorithm (CSA). For a destination and a day, it scans every connection of that day once, from the latest departure to the earliest, and builds a profile: for each station, the Pareto front of trips that reach the destination from there. Picking a departure then only means reading that station's front and rebuilding each trip from it.
The criteria of a trip (departure, arrival, changes) and a 32-bit payload used to rebuild it are packed into a single long, and a Pareto front is an array of them. Comparing two trips takes a few bit operations, and a front never needs an object per trip.
The interface is JavaFX. The query, the list of trips and the detail view are tied together by observable values, so changing any field updates the results right away.
You need JDK 22 and the JavaFX SDK 21.
- Open the folder in IntelliJ IDEA (it is an IntelliJ project).
- Add the
libfolder of the JavaFX SDK as a global library namedOpenJFX 21. - Run
ch.epfl.rechor.gui.Main, with the repository root as working directory so it findstimetable/.
The timetable only covers 26 May to 1 June 2025, so set the date to one of those days, or every search comes back empty.
The project, its steps and the timetable files were provided by the CS-108 course staff at EPFL.



