Documentation

Weather Along the Course

RaceCraft shows what the course will actually throw at you: the temperature at the hour you reach each section, and the wind relative to your direction of travel — headwind, tailwind, or crosswind.

That last part is the point. "NW at 20 km/h" tells you nothing until you know which way you are pointing. The same wind is a gift on one side of a ridge and a wall on the other.

What you get

Calculate a plan and a Weather Along the Course panel appears above the segment table, collapsed down to its heading. Expand it for:

  • Per segment: projected arrival time, temperature, conditions, wind speed and the direction it blows from, and what that wind does to you
  • Summary: temperature range across the race, the share of the course spent into a headwind / with a tailwind / in a crosswind, the strongest headwind, the peak gust, and what the wind does to your finish time
  • Pace effect: when wind is feeding the pacing model, each segment also shows the time the wind adds to (or takes off) every kilometre

Everything follows your metric / imperial preference — °C and km/h, or °F and mph.

If weather cannot be shown yet — no race date set, a date beyond the forecast horizon, no GPX route on the plan, the forecast service unreachable, or course weather switched off on the server — a short note appears directly under the panel's heading saying exactly which piece is missing. The note stays visible even while the rest of the panel remains folded down, so it never forces itself open over the pacing numbers above it.

Example

An out-and-back near Cairns on a southerly, run north then back south:

Segment Arrive Temp Conditions Wind Effect on you
Start → CP1 06:48 17°C Mainly clear S 9 km/h Tailwind 9 km/h
CP1 → Finish 07:21 18°C Mainly clear S 9 km/h Headwind 9 km/h

Same wind, opposite effect — which is exactly the information a pacing plan needs, and exactly what a daily forecast summary hides.

It changes your predicted time, not just the display

Wind is not only reported — it feeds the pacing model. Each segment's predicted time is multiplied by a wind_factor alongside terrain and fatigue, so headwind sections come out slower, tailwind sections slightly faster, and the finish time reflects both.

That is switched on by default whenever a race date is set, and controlled by Include Wind Effect and Course Wind Exposure in the Pacing section. The exposure setting matters: a forecast measured over open ground overstates what a runner feels in a forest. See the Wind Model for the physics, the exposure factors, and the limits.

Without running a simulation

Opening a saved plan shows wind effects straight away — no need to hit Run Simulation first. Plans saved before this feature carry no per-segment wind numbers, so on load the planner sends its current pacing settings (base pace, fitness, exposure) with the weather request, and the server estimates each segment's cost from a still-air model of the plan. Estimates are marked as such internally and are replaced by exact numbers the next time you calculate; they are also dropped rather than left on screen if the race date moves out of forecast range.

How it works

  1. The hourly forecast for the route is fetched from Open-Meteo.
  2. The GPX polyline is reduced to legs of at least ~50 m, so a bearing means something even on switchbacks.
  3. Each leg is matched to the forecast hour you are projected to be there, using the plan's own cumulative segment times.
  4. The wind vector is split against the leg's bearing into a head/tail component and a crosswind component — the approach used by WindAhead.
  5. Legs are aggregated back up to race segments, distance-weighted.

Why segments are classified by distance share

An out-and-back segment can be half headwind and half tailwind. Averaging the head component over it gives roughly zero, which would label a genuinely hard section as "light air". So a segment is named after whichever share of its distance dominates, and reports "Mixed" with the split when nothing does.

Limits worth knowing

  • ~16 days ahead. Open-Meteo does not forecast further out. Plan a race further ahead and the panel says so rather than inventing numbers.
  • Past races show recorded weather. A race that has already run is projected onto the ERA5 reanalysis archive instead of a forecast — actual conditions on the day, not an estimate. The archive trails real time by a few days, so a race that finished yesterday shows a "check back soon" note until its data lands.
  • One forecast point. The weather is taken at the route start. For a big mountain course, wind on an exposed ridge will differ from the valley — treat it as a strong hint, not gospel.
  • Forecasts move. Results are cached for three hours, so re-opening a plan close to race day picks up revisions.
  • Weather never blocks a plan. If the lookup fails the panel explains what went wrong — no data for the route and date yet, the plan's own lookup failing, or the network being unreachable — and the rest of the planner is unaffected. The pacing falls back to still air.

Relationship to the weather widget

This is separate from the existing OpenWeatherMap widget, which shows a daily forecast for the start location and still needs OPENWEATHERMAP_API_KEY. Course weather uses Open-Meteo, which needs no API key, and works even when the widget is disabled.

Technical notes

  • Endpoints: POST /api/calculate (returns race_weather with the plan), POST /api/race-weather (standalone, display only; accepts an optional wind block to estimate effects for plans that have not been simulated)
  • Optional env: OPEN_METEO_ENABLED, OPEN_METEO_URL, OPEN_METEO_ARCHIVE_URL, OPEN_METEO_TIMEOUT_SECONDS, OPEN_METEO_CACHE_DIR