The Flow Map offers a bird’s-eye animated view of every inferred bike trip in the past 24 hours. Bike dots travel along cached road-network polylines between departure and arrival stations, giving you an intuitive feel for where and when riders move through the system. The view is purely observational — pins are non-interactive scenery; the animated bikes are the focus.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/samgutentag/bcycle-map/llms.txt
Use this file to discover all available pages before exploring further.
Route
| Path | Purpose |
|---|---|
/flow | Animated flow map with timeline scrubber |
How Trip Inference Works
BCycle Map doesn’t receive GPS traces. Instead, the poller diffs per-stationnum_bikes_available counts every two minutes and classifies each change as a departure (count decreased) or arrival (count increased). Consecutive departure-arrival pairs are then matched into trips using the pre-computed travel-time matrix.
Two confidence levels exist for inferred trips, exposed as Trip.confidence in the shared types:
High confidence
A clean
0 → 1 → 0 single-rider transition: exactly one bike left the system and exactly one bike returned. The pairing is unambiguous.Low confidence
A greedy best-fit match against the travel-time matrix while multiple bikes were in flight simultaneously. Probable but not certain — treat as an estimate.
GET /api/systems/:id/trips (the R2 parquet archive) for the full 24-hour window. The fetch refreshes every 60 seconds.
Animated Bike Markers
Each trip in the playback window is rendered as a single dot on a<canvas> overlay (via BikeAnimationLayer). A canvas-based approach — rather than individual DOM nodes — keeps animation smooth even when 50+ bikes are in motion on mid-tier hardware.
| Visual element | Behaviour |
|---|---|
| Moving dot | Interpolated along the cached GeoJSON polyline for the station pair |
| Trail ghost | Fades behind the dot over 5 seconds (pool playback mode) |
| Dot disappears | When arrival_ts is reached — the trip is complete |
TRAIL_GHOST_FADE_SEC is 30 seconds — the module-level constant exported from BikeAnimationLayer. The Flow Map currently runs in pool playback mode and passes a shorter ghostFadeSec of 5 seconds (POOL_GHOST_FADE_SEC) to keep the canvas readable when many trips are compressed into the playback window.Station Pins
Station markers on the Flow Map are small static dots — no counts, no teardrops, no popups. This keeps the animated bikes as the visual hero. Pin brightness reflects historical availability at the scrubbed cursor time:| Pin style | State |
|---|---|
| Bright dot | Bikes available at cursor time |
| Dim dot | Station was empty at cursor time |
| Very dim dot | Station was offline (!is_installed || !is_renting) |
getSnapshotAt(cursorTs) — the historical snapshot archive — with a live-data fallback while the archive fetch is in flight.
Pool Playback Mode
Rather than playing the real 24-hour timeline at 1× speed (which would take 24 hours), the Flow Map uses pool scheduling: all trips are packed into 5 concurrent playback lanes and assigned synthetic start/end times. This means you always see a handful of bikes in motion rather than watching an empty canvas for hours between rare trips. The scrubber in pool mode shows:Timeline Scrubber
TheFlowTimelineScrubber docks to the bottom of the screen and exposes the full playback interface.
Play / Pause
Toggle playback with the button or the Space key. The scrubber advances in real time once playing.
Drag to Scrub
Drag the slider handle or click anywhere on the track to jump to a specific moment in the pool window.
Pool Progress Counter
Displays “N / Total trips” so you know how far through the 24-hour archive you are.
Caption Area
Shows loading status (“Loading trips…”), the active trip count, and loop state (“All trips shown — looping…”).
Dynamic Window
On quiet days, the scrubber automatically shrinks from the full 24-hour span to[oldest_trip_departure − 5 min, now]. This is the dynamic window computed by computeDynamicWindow — it prevents a mostly-empty slider when only a handful of trips happened late in the day.
Fog-of-World Overlay
TheFogOfWorldLayer dims map areas outside corridors where trips have been observed. Toggle it with the FogToggle button in the top-left corner of the map. The preference is persisted to localStorage under bcycle-map:flow-fog-enabled (defaults to off so first-time visitors don’t see a blacked-out screen).
How to Use the Flow Map
Navigate to /flow
The map boots on the Positron basemap centred on the active system. Trips for the past 24 hours are fetched in the background.
Press Play
Click the ▶ button (or press Space) to start pool playback. Bike dots appear and travel along their inferred routes.
Watch the counter
The “N / Total” counter at the top-left of the scrubber panel advances as each trip starts. “All trips shown — looping…” indicates the playback has wrapped.
Pause and inspect
Press Space to pause. The caption shows how many trips are currently active on the canvas.
Data Sources
| Source | Endpoint | Used for |
|---|---|---|
| Live snapshot | GET /api/systems/:id/current | Station locations and current pin states |
| Trip archive | GET /api/systems/:id/trips | Full 24-hour trip window, refreshed every 60 s |
| Historical snapshots | GET /api/systems/:id/snapshots | Per-station bike counts at the scrubbed cursor time |
| Route cache | R2 travel-times.json | Cached GeoJSON polylines for trip animation |
| Travel-time matrix | R2 travel-times.json | Station-pair distances used as straight-line fallback |
Related Views
Live Map
Real-time station pins with availability counts and filter chips.
Explore
Analytics dashboard including an activity log of inferred trips.
Route Check
Plan a specific journey and see its travel-time estimate.
Station Details
Historical availability charts for a single station.