How it works

One bike, one trip, no overage.

àVélo is Québec City’s bike-share. A plan gives you 30 or 45 minutes per ride; every minute past that costs $0.30. Most trips across the city do not fit in one ride, and ordinary navigation apps do not know that. This planner does.

The problem

The limit applies per ride, not per trip. The clock starts when you unlock and stops when you dock. So the question is not “what is the fastest way from A to B” but “where should I dock along the way so that no single ride runs over” — and, if you would rather pay than stop, exactly what that costs.

Measured over 1,000 real trips in this network, riding straight through overruns a 30-minute plan about half the time, at a mean overage of $2.75. See Does it work?

Using the planner

  1. Set where you start and where you are going. Search a place, tap the map, tap a station, or use your location. Pins can be dragged.
  2. Add stops if you are visiting several places, and tick Return to start for a round trip. Each visit means docking the bike; the plan picks the stations.
  3. Choose your bike and your plan — electric or mechanical, 30 or 45 minutes per ride. Availability is live: the counts next to each option are bikes on the street right now.
  4. Read the options. The green route keeps every ride under the limit ($0). The others trade money for time; the chart shows them all at once. Tap one to see it on the map and as a timetable, then open it in Google Maps or Waze, or share the link.

Station colours: green has bikes and docks, red has no bikes to take, amber has no free dock to reset in. With a route selected, only the stations it uses stay on the map.

Why a reset is free

You keep the same bike for the whole trip. A “reset” is docking at a station, waiting for the ride to close, and unlocking the bike again: the clock restarts and nothing is billed. It costs about a minute, so it is only worth doing when the alternative is paying. A transfer station therefore needs a free dock and to be in service — it does not need a spare bike, which is why empty stations still work as reset points.

How long a ride takes

Everything rests on one estimate: the minutes from station A to station B. It is the sum of riding time, expected traffic-light delay, the reset overhead, and a 90-second safety buffer.

Riding time uses real bicycle-network distances (not straight lines — the street distance between every pair of stations is a median 1.27× the crow-flies distance, measured over 49,626 pairs) and the grade. Québec City has 141 m of relief between its lowest and highest stations; the Basse-Ville / Haute-Ville escarpment is a wall in the middle of it. Uphill speed decays exponentially with grade, calibrated so a 5% climb halves a mechanical bike and takes ~22% off an e-bike; downhill helps less than uphill hurts, because you brake. A 90 m climb over 1.4 km costs an electric bike 39% more time than the flat and a mechanical one 145% more.

Traffic lights are an expectation, not a worst case: arriving at a random moment in a 60-second cycle you wait 7.5 s on average, plus stopping and starting a heavy bike — about 12 s per light, one light every 250 m.

Every leg under the limit. The station graph has ~25,000 edges, one for every ride a person might plausibly take. Remove every edge that runs over the limit and the fastest remaining path is plain Dijkstra — the constraint is local to each edge, so nothing cleverer is needed. Recognising that is the point.

The trade-offs. Once you may pay to go over, there are two things to minimise at once, time and money, and there is no single best answer: a 32-minute direct ride costs 60 cents but saves a reset; a two-ride route is free but slower. This is the bi-criteria shortest-path problem. It is solved with Martins’ label-setting algorithm: every station keeps a set of partial routes, and a new one is thrown away if an existing one is at least as fast and at least as cheap. That pruning — Pareto dominance — discards about 98% of everything generated, which is the only reason the search finishes in a couple of hundred milliseconds. What survives at the destination is the frontier: the options you see.

Several stops, round trips

A visit means docking near the place, so a trip through several stops is a chain of independent door-to-door plans. The whole-trip options are the Pareto-optimal combinations of each segment’s options, pruned segment by segment so the work never explodes. A round trip is the same chain with the start appended as the last stop. Each leg has its own colour on the map and in the timetable.

Risk, not just feasibility

The estimate is a mean; the real ride is a distribution around it. A ride estimated at 96% of the limit is under it on paper and a coin flip in practice. The green route therefore refuses any ride above 95% of the limit and resets at a nearby station instead, relaxing that rule only if nothing safer reaches the destination. Every ride is labelled low, medium or high risk so you can see where the margin is thin.

Where the data comes from

  • Stations and availability: àVélo’s public GBFS feed, refreshed every 30 seconds. The same code runs on any GBFS system — Bixi, Citi Bike, Vélib’ — by changing one URL.
  • Street distances and polylines: OSRM with OpenStreetMap’s bicycle and foot profiles, self-hosted on a Québec City extract; every station pair is pre-computed.
  • Elevation: open-meteo, one lookup per station, cached forever.
  • Place search: Google Places, through the API; OpenStreetMap when unavailable.
  • Pricing and limits: verified against àVélo’s published plans — 30 or 45 minutes, $0.30 per extra minute, billed per started minute.

Does it work?

The planner is compared against what a normal app does — nearest station to nearest station, one ride — over 1,000 trips sampled where people actually ride, all costed with the same model so the comparison is about the route chosen, not the estimate. The naive strategy overruns the limit on roughly half of trips; the constrained route on none, for a mean cost of about two minutes. An ablation with the hill model switched off is reported too: for today’s all-electric fleet it changes individual legs but rarely the chosen route, which the project says out loud rather than hides. The full tables are in docs/evaluation.md.

API

Everything the app does is a public JSON endpoint: /route, /route/options, /route/compare, /trip, /stations, /geocode. Parameters include the bike type, the plan (limit=30|45), the accepted risk (max_risk) and geometry=true for street polylines. Interactive documentation lives at /api/docs; the source, the cost-model derivation and the evaluation are on GitHub.

Built by Imran Akki, Université Laval. Not affiliated with àVélo or the RTC.