Weather overlay integration

This note describes how weather overlays are integrated in the UI and what invariants new overlay providers must keep.

Scope

Applies to:

  • RASP

  • EDL

  • XCTherm

  • SkySight

Code entry points:

  • src/PageActions.cpp

  • src/Weather/WeatherUIState.hpp

  • src/Weather/MapOverlay/

  • provider-specific glue in src/Weather/<Provider>/

Ownership model

Weather overlays can be active from two contexts:

  • dedicated weather pages (selected through page layout)

  • map pages that show the weather cursor bar

The per-overlay :cpp:`OverlaySession` tracks ownership with three flags:

Use :cpp:`OverlaySession::HasPageOwnership()` when behavior should apply while either entered or suspended.

Lifecycle in PageActions

The lifecycle is orchestrated in src/PageActions.cpp:

  1. :cpp:`PageActions::ApplyPageOverlay()` selects the overlay for the current :cpp:`PageLayout`.

  2. Provider-specific apply hooks run:

  3. Leaving a page calls :cpp:`LeaveWeatherOverlayPage()` and provider-specific leave hooks.

  4. Entering pan mode calls :cpp:`SuspendWeatherOverlaysForPan()`.

  5. Leaving pan mode calls :cpp:`ResumeWeatherOverlaysAfterPan()`.

For dedicated page entry, first-enter behavior should be explicit and idempotent. Existing providers use :cpp:`EnterPage()` and branch on first_enter.

Per-page cursor state

Each weather map page owns both cursor axes. Entering a configured page restores its selections; Auto values are recalculated from current GPS time/altitude.

SkySight forecast loading

SkySight keeps the selected forecast image visible while it refreshes the catalog or fetches forecast-step metadata. With Auto update enabled, opening a SkySight page downloads missing or newer data automatically. Disabling it keeps automatic page refreshes cache-only; explicitly selecting a forecast time, pressing Set active, or starting a preload can still download data. The dialog timer retries deferred metadata requests without waiting for page activation or map rendering.

Preload Layer and Preload Selected use the shared top-of-map download progress widget. The widget first reports forecast-step discovery, then displays the number of finished forecast files while download and NetCDF decoding proceed. Cached files count as finished. Requests run one at a time; a SkySight API rate limit pauses and requeues the interrupted request, shows a countdown, and resumes automatically.

Preloading includes the available forecasts from the start of the current UTC day onward and excludes earlier days. Full-day layers such as PFD contribute one file per forecast day. Live tile layers are not preloaded, and their outstanding requests are cancelled when the user selects another layer.

The SkySight cursor-bar rows are forecast time and layer. Both selections are stored on the current configured page and restored on page entry. The SkySight weather panel manages the global selected-layer list, automatic updates, offline preloading, and cache usage. Add to list changes the layers available to every map page. Set active assigns the highlighted selected layer to the current page in Auto time mode. More page layouts are managed through Pages setup.

The cache row reports the total size of the SkySight cache folder. Clear downloaded data cancels file downloads and decoding before deleting forecast files, rendered images, live tiles, and temporary files. Provider catalog metadata, credentials, selected layers, page configuration, and persisted API throttle state are preserved.

Threading and async boundaries

Keep this split:

  • UI thread: page transitions, overlay/session state, cursor-bar updates

  • network/asio thread: download and parse work

  • handoff back to UI: UI::Notify callback before UI state or overlay updates

Do not call UI APIs (CommonInterface, ActionInterface, window code) directly from network worker code.

Integration checklist for a new provider

  1. Add a provider state/session member in :cpp:`WeatherUIState`.

  2. Add dedicated-page apply/leave hooks in PageActions.cpp.

  3. Handle pan suspend/resume in :cpp:`SuspendWeatherOverlaysForPan()` and :cpp:`ResumeWeatherOverlaysAfterPan()`.

  4. Define first-enter behavior:

    • auto mode reset/refresh path

    • manual mode preserve path via cursor_initialized

  5. Trigger refresh/download only from well-defined UI events (first enter, auto-no-data, explicit user action). Providers with multi-file preloads must report a stable batch progress total, not only the current queue depth.

  6. Add unit tests for session transitions and reset rules (see test/src/TestWeatherUIState.cpp).

Common pitfalls

  • clearing manual selections when entering a page

  • forgetting to clear suspended_for_pan on pan exit

  • performing UI operations from non-UI threads

  • adding provider logic without tests for enter/leave/suspend/resume

Page placement UX

Weather dialogs provide a Pages setup button that opens Config → Look → Pages, where map overlays (RASP, EDL, XCTherm, SkySight) and the weather cursor bar can be assigned to pages.

Programmatic placement helpers in PageActions / WeatherMapOverlay::PagePlacement still:

  • set bottom = WEATHER_CONTROLS so the shared weather cursor bar is active

  • persist page layout changes to the profile

  • clear provider cursor initialization so first-enter behavior is reapplied consistently

When the page limit (PageSettings::MAX_PAGES) is reached, adding a new page must fail without mutating existing pages.