5.6 Routes Pages
The /routes page is a server-rendered route browser for comparing Atlas GTFS and OSM route definitions.
It is designed around two primary filter dimensions plus free-text route search:
- Atlas Operator (index-style searchable multi-select dropdown)
- Status (
all,matched,unmatched,unmatched_atlas,unmatched_osm)
1. End-to-End Flow
- User submits filters using the top toolbar.
- Flask route
backend/blueprints/routes.py::routes_pagenormalizes query params. - Backend builds a combined route query and applies:
- matched/unmatched status constraints
- optional Atlas operator constraints
- optional route-id search
- Matched pairs are returned once, then unmatched Atlas-only and OSM-only rows are appended into the same paginated result set.
- Results are expanded with route-stop details and route metadata.
- Template
templates/pages/routes.htmlrenders compact route cards. - Each card starts collapsed and can be unfolded to:
- view stops by direction
- view route extent in an embedded Leaflet map
2. Query Semantics
Status
matched=all: include matched pairs, unmatched Atlas routes, and unmatched OSM routes.matched=matched: include only routes present inroutes_matched.matched=unmatched: include both unmatched Atlas routes and unmatched OSM routes.matched=unmatched_atlas: include only Atlas routes without a matched OSM route.matched=unmatched_osm: include only OSM routes without a matched Atlas route.
Atlas Operator
- Matched and unmatched Atlas rows: filter is applied directly through
route_atlas_stops -> atlas_stops. - Unmatched OSM rows are excluded when an Atlas operator filter is active, because they have no Atlas-side operator to match against.
3. Route Card Structure
Each route card keeps a dual-source header:
- Atlas panel (blue)
- OSM panel (green)
Depending on match state, one side can collapse to an Atlas-only or OSM-only summary.
The visible header now surfaces:
- Atlas operator summary
- Atlas
representative_headsignsummary orroute_long_name - OSM GTFS route ID
- OSM operator
Below the header, two native collapsible panels (details/summary) are rendered:
- Stops list
- Route on map
This keeps the default page compact while preserving full route detail on demand.
4. Stops Rendering
Stops are loaded from:
route_atlas_stops+atlas_stopsroute_osm_stops+osm_nodes
Then grouped by direction and UIC:
- Direction groups are sorted with numeric-first ordering.
- Inside each direction, stops are grouped by
uic_ref. - Each group exposes member rows (SLOID or OSM node id) for traceability.
5. Embedded Leaflet Map Rendering
Map previews now use the same map stack as the main page (Leaflet + shared marker helpers):
- each route card exposes a route-scoped filter payload (
station_filter+filter_types=route) - the frontend loads stops via
/api/datawith those route filters - markers/lines are rendered using shared map marker functions (
createAtlasMarker,createOsmMarker) - map bounds are fit to loaded route points after rendering
If no geolocated points are returned, the map panel shows a fallback message.
6. Files and Responsibilities
backend/blueprints/routes.py- parameter normalization
- combined matched/unmatched query construction and pagination
- stop/group assembly
- Atlas and OSM route metadata loading
- route map filter payload assembly
templates/pages/routes.html- one-line filter toolbar (index-style search + Operator dropdown)
- summary + pagination
- route card markup and collapsible panels
static/css/pages/routes.css- one-line toolbar and filter-pill styles
- collapsible panel visuals
- responsive card and embedded map layout
static/js/pages/routes.js- Atlas operator dropdown initialization
- route panel map loading and rendering
- route filter request construction for
/api/data
7. Maintenance Guidelines
- Keep query logic in backend helpers, not in templates.
- Keep card panels collapsed by default to protect performance and readability.
- Keep route-filter payload generation centralized in backend helpers.
- Prefer adding new filters as normalized query params with explicit allowed values.
- Preserve pagination query params when adding links/actions in the template.