Skip to content

planner: climate tile client library - #2346

Merged
timohueser merged 6 commits into
developfrom
claude/planner-climate-client
Oct 3, 2026
Merged

timohueser merged 6 commits into
developfrom
claude/planner-climate-client

Conversation

@timohueser

@timohueser timohueser commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

Summary

This PR adds the client library for the climate layers (Weather and Wind, issue #2329). It is pure TypeScript. It has no UI wiring and no Svelte components. The layer UI comes in a later PR.

This PR builds on #2345 (spec and bake), which is merged. The new files are all in builder/app/src/lib/planner/layers/. map-style.ts now exports DEM_TILE and DEM_MAX_ZOOM. The terrain source and the terrain helper both use them, so the helper requests only tiles that the hillshade loads.

File Contents
climate.ts Tile decoding for zoom 8 and zoom 9, metadata, cells, weeks, temperature, rain, wind
climate-source.ts Tile cache over an archive, sampleLine
climate-route.ts Travel bearings, the Weather and Wind year-slider rows
climate-terrain.ts Terrain heights for a map tile from the map's Terrarium tiles
tile-archive.ts Opens a TileJSON or a PMTiles archive. Snow and climate both use it; snow-layer.svelte.ts no longer has its own opener. Snow behaviour is unchanged.

data-layer.ts has weekOf, the week of the climate bake: days 7w to 7w + 6 of the date's own year, and week 51 also holds the last one or two days. dateColumn(date, 52) and columnDate(column, year, 52) use it, so the 52-column date bar and the climate lookup always select the same week (4 March 2024 is week 9 in both). The 183-column snow grid still folds 29 February onto 28 February.

Definitions

  • Wet days: 7 × wet_share ÷ 100 (for example, 2.4 of 7).
  • Relative rain: (the rain of the week ÷ the days of the week) ÷ (the total rain ÷ the total days) of the same series. The same function works for the 52 overview means and the 520 detail weeks. In a detail year, week 51 has 8 days, or 9 in a leap year (from first_year). In the overview means, it has the mean over the archive years. Drier is below 1/1.25, wetter is above 1.25.
  • Wind: the rose is turned to "blows towards" (from + 8 sectors). Mode is the centre of the busiest three-sector window. Steadiness is the share of that window (3/16 to 1). When two windows have the same share, the busier centre sector wins.
  • Split wind: the busiest window within ±45° of straight opposite has a share ≥ 0.6 × the main window, and the two windows together hold ≥ 0.65.
  • Head/cross/tail: headwind is wind from within ±45° of straight ahead, tailwind is wind towards within ±45° of the travel direction, and crosswind is the remainder. Partial sectors count, so the chance changes smoothly with the bearing.
  • Route rows: each value is the distance-weighted mean of the samples with data. Samples in the same cell are grouped (the correction is linear), so 1,001 samples take about 2 ms.

Measurements

  • BW archive, 100 km route Stuttgart–Villingen (1,001 samples): 2 overview requests (2 detail requests if read at zoom 9). The overview level has the rose and all week means, so a route reads only zoom 8. Sampling took 2 ms, the weather rows 0.6 ms and the wind row 1.8 ms (Node).
  • Terrain (live planner, Chrome): the first request takes about 40 ms, a cached one about 1–2 ms. Decoding takes 5–7 ms per tile (12 ms for the first). One DEM tile at z − 1 serves four 256 px map tiles at 1:1 pixels. The terrain service sends public, max-age=31536000, immutable. A fetch from a worker (the same path that MapLibre uses) fills the HTTP cache, and a later fetch from the main thread gets the tile in 1.6–3.6 ms.

Thresholds (owner to confirm)

  • BIMODAL_RATIO = 0.6, BIMODAL_SHARE = 0.65: chosen on the BW archive. They mark the Lake Constance shore in 11 of 12 months and the northern Upper Rhine in spring. They mark no month at the Feldberg, on the Swabian Alb or at Stuttgart. This is 18 % of the BW cell-months.
  • WETTER_RATIO = 1.25: in the BW ten-year means, 25 % of the cell weeks are drier and about 17 % are wetter.

Public docs changed: no

Requirements: none

Checks

  • npx vitest run src/lib/planner src/components/planner: 29 files, 182 tests pass. Synthetic tiles built from the spec cover the decoding. The BW figures above came from a one-time run on the local archive; that test is not in the PR.
  • svelte-check: no errors in the new files. The 15 errors that remain are wasm pkg/ modules that are not built in this checkout.
  • obc suites check: OK.
  • npm run test:planner (tests/browser): 1 passed. The request budget is unchanged.
  • Not run: the full workspace.

🤖 Generated with Claude Code

timohueser and others added 2 commits October 3, 2026 23:07
Decode both climate archive levels per specs/planner-climate-tiles.md,
look up cells, sample a route from the overview level, correct
temperatures with the two lapse rates, read terrain heights from the
map's Terrarium tiles, and derive wet days, relative rain, wind mode,
steadiness, split winds and head/cross/tail chances. Pure functions
for the Weather and Wind year-slider rows of a route.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 7ac22147-7f6d-4478-934e-60a5839c2e5f
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

timohueser and others added 4 commits October 3, 2026 23:10
…e local archive test

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Snow opens its archive with openTileArchive. The 52-column date bar and
the climate lookup share weekOf, the week of the climate bake. The route
rows keep their own distance weight, since data-layer no longer has one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@timohueser
timohueser merged commit 20c6246 into develop Oct 3, 2026
28 checks passed
@timohueser
timohueser deleted the claude/planner-climate-client branch October 3, 2026 21:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant