This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Mirrored from
/mnt/DATA/git/pikebacker/docs/05_routing_and_scoring.md. Origin:repository. Active tasks and changing state belong in Gitea issues; this wiki page is durable project context.
Routing and Scoring Model
Goal
Optimize for a loaded bikepacking trip, not a generic bike route.
Route cost model
A candidate route is scored by segment and by whole-trip logistics.
segment_cost =
distance_cost
+ climb_cost
+ steepness_cost
+ poor_surface_cost
+ traffic_stress_cost
+ access_uncertainty_cost
+ hike_a_bike_risk_cost
+ remoteness_cost
+ weather_sensitivity_cost
- official_cycle_route_bonus
- confirmed_good_segment_bonus
- scenic_bonus
stage_cost =
ride_effort_cost
+ sleep_risk_cost
+ water_gap_cost
+ food_gap_cost
+ daylight_risk_cost
+ weather_risk_cost
+ bailout_gap_cost
+ repair_gap_cost
Segment attributes
Each segment should carry:
- distance meters,
- ascent/descent,
- max grade,
- average grade,
- surface,
- smoothness,
- OSM highway class,
- bicycle/access tags,
- traffic stress proxy,
- cycle route membership,
- protected-area overlap,
- POI distance to next water/food/repair/sleep,
- community report score,
- confidence score.
Bikepacking profiles
Loaded gravel
- Prefer gravel/compact dirt and low-traffic roads.
- Penalize technical MTB trails.
- Penalize grades above 12% more heavily when loaded.
- Penalize unknown surfaces in remote areas.
Hardtail bikepacking
- Allow more rough surfaces.
- Allow singletrack where bicycle access and difficulty are acceptable.
- Penalize sustained paved highways and high traffic.
Road touring
- Prefer paved low-traffic roads and official cycle routes.
- Avoid rough surfaces, tracks, and paths with unknown rideability.
E-bikepacking
- Add range and charging constraints.
- Penalize long remote stretches without accommodation/charging.
- Respect local e-bike access distinctions where available.
Beginner-safe
- Strongly prefer known surfaces and legal certainty.
- Avoid high traffic, remote stretches, long dry gaps, and steep grades.
Confidence model
The app should show both recommendation and confidence.
Example route summary:
Distance: 382 km
Ascent: 5,420 m
Known surface: 88%
Unpaved: 42%
Longest water gap: 36 km
Longest food gap: 58 km
Access confidence: Medium-high
Sleep certainty: 4/5 nights confirmed options
Bailout gap: Max 71 km from train/ferry/bus
Warnings: 2 steep loaded-bike climbs, 1 uncertain access segment
Hike-a-bike risk
Estimate using:
- steep grade,
- poor smoothness,
mtb:scale,sac_scale,- surface type,
- trail width if available,
- rider profile,
- actual ride speed reports,
- user reports.
A route can include hike-a-bike if the profile allows it, but it must be visible.
Critical gap detection
Calculate gaps along the route:
- water gap,
- food gap,
- sleep gap,
- repair gap,
- bailout gap,
- charging gap for e-bike.
Warnings should be generated when a gap exceeds profile thresholds.
Stage planning algorithm
- Generate candidate endpoints every 5–15 km around the daily target window.
- Score each endpoint by sleep options, water/food, daylight fit, safety, and bailout.
- Prefer endpoints with at least one high-confidence sleep option.
- Add Plan B endpoints before and after Plan A.
- Rebalance subsequent stages to avoid one impossible day.
- Surface warnings for stages where no good endpoint exists.
Example thresholds
| Profile | Target km/day | Max grade warning | Max water gap | Max food gap |
|---|---|---|---|---|
| Beginner-safe | 40–70 | 10% | 25 km | 40 km |
| Loaded gravel | 60–100 | 12% | 40 km | 70 km |
| Hardtail remote | 50–90 | 15% | 55 km | 90 km |
| Road touring | 70–130 | 10% | 40 km | 70 km |
| E-bikepacking | 50–100 | 12% | 40 km | 60 km + charging |
Thresholds should be configurable per user.