Skip to content

feat(renderer): cartographic upgrades — peaks, inland lakes, scope marker, refined colorbar#126

Merged
jacaudi merged 2 commits into
mainfrom
feat/renderer-cartographic-upgrades
May 9, 2026
Merged

feat(renderer): cartographic upgrades — peaks, inland lakes, scope marker, refined colorbar#126
jacaudi merged 2 commits into
mainfrom
feat/renderer-cartographic-upgrades

Conversation

@jacaudi
Copy link
Copy Markdown
Owner

@jacaudi jacaudi commented May 9, 2026

Summary

Iterative session focused on visual quality and geographic anchoring of the rendered radar PNG. The default render is now noticeably more professional and spatially intuitive. Bundles a container-runtime bug fix that was masking missing Cartopy cache layers.

Visual upgrades

  • Scope-style radar marker (open ring + center dot) at the antenna location with haloed station label.
  • Per-station peak markers — KATX gets Mt Baker, Glacier Peak, Mt Rainier, Mt Olympus drawn as brown triangles via a new _PEAKS_BY_STATION registry in basemap.py. Stations without an entry render no markers (opt-in, no warning).
  • Inland lakes layer (ne_10m_lakes_north_america) wired in so Lake Washington, Lake Tahoe, Lake Pontchartrain, etc. render as water. The global ne_10m_lakes shapefile drops every lake smaller than a Great Lake at every resolution.
  • North arrow flipped to point up (was inverted in v2.12.0).
  • Colorbar beefed up: thicker bar, integer ticks every 20 dBZ, inline "dBZ" label to the right of the bar, thin black outline, positioned just above the bottom border.
  • Footer text bumped 8 pt → 12 pt.
  • 15 px white margin frames the radar plot cleanly instead of bleeding to the figure edges.
  • City labels force-clipped to the axes patch so east-edge labels don't leak past the right boundary.

Default render shape

  • Default plot height bumped 1000 → 1100 so southern coverage features (e.g. Mt Rainier at the edge of KATX's view) get breathing room above the bottom border.
  • Y-axis projected limit now scales with the axes pixel aspect ratio so a taller figure actually shows more N-S area instead of just adding whitespace.
  • Projected xlim/ylim locked explicitly so Cartopy's default adjustable="box" doesn't introduce uneven internal padding (previously sides=14 px while top/bottom=26 px).

Refactor: single source of truth for defaults

  • DEFAULT_RANGE_KM, DEFAULT_WIDTH, DEFAULT_HEIGHT consolidated as module-level constants in render.py and consumed by service.RenderRequest and the FastAPI Query defaults. The three layers can no longer drift.
  • Prior drift had the API silently using range_km=230 while the dataclass advertised 150 — found and fixed mid-session.
  • Existing test test_render_options_defaults_match_route_defaults updated to assert against the constants directly.

Container fix bundled

The prewarmed Cartopy cache in scripts/cartopy_cache.py was missing admin_2_counties_lakes, roads, LAND (10m), and (now) lakes_north_america. Without them the unprivileged container uid hit PermissionError trying to download missing layers at request time. The script's docstring already required this list be kept in sync with render.py — it had drifted. Build now reports all layers warmed.

Test plan

  • uv run pytest tests/ — 67 passed
  • Container build succeeds: docker build -t dras-renderer:local .
  • Container renders KATX without PermissionError (was 500ing before the cartopy_cache fix)
  • Visual review of /render/KATX output — peaks visible, Lake Washington rendering as water, equal margins, colorbar legible
  • Deploy to Talos selfhosted ns and confirm in-cluster render matches local

🤖 Generated with Claude Code

jacaudi and others added 2 commits May 8, 2026 18:06
…rker, refined colorbar

User-visible improvements to the default radar PNG, plus a container fix
bundled in.

Visual:
- Scope-style radar marker (open ring + center dot) at the antenna
  location with haloed station label
- Per-station peak markers — KATX gets Mt Baker, Glacier Peak, Mt
  Rainier, Mt Olympus drawn as brown triangles via the
  _PEAKS_BY_STATION registry in basemap.py (other stations render no
  peaks until they're added)
- ne_10m_lakes_north_america layer wired in so Lake Washington, Lake
  Tahoe, etc. render as water; the global lakes layer drops them at
  every resolution because they're not Great-Lakes-class
- North arrow flipped to point up (was inverted)
- Colorbar: thicker bar (4.5% height), integer ticks every 20 dBZ,
  "dBZ" label inline to the right of the bar, thin black outline,
  positioned just above the bottom border
- Footer text bumped 8pt → 12pt
- 15 px white margin frames the radar plot cleanly instead of
  bleeding to the figure edges
- City labels force-clipped to the axes patch so east-edge labels
  don't leak past the right boundary

Defaults:
- Default plot height bumped 1000 → 1100 so southern coverage
  features (e.g. Mt Rainier at the edge of KATX's view) get
  breathing room above the bottom border
- DEFAULT_RANGE_KM, DEFAULT_WIDTH, DEFAULT_HEIGHT consolidated as
  module-level constants in render.py and consumed by
  service.RenderRequest and the FastAPI Query defaults — the three
  layers can no longer drift (prior drift had the API silently using
  range_km=230 while the dataclass said 150)
- Y-axis projected limit scales with the axes pixel aspect ratio so
  a taller figure actually shows more N-S area, not just whitespace
- Projected xlim/ylim locked explicitly so Cartopy's default
  adjustable="box" doesn't introduce uneven internal padding
  (sides were 14 px while top/bottom were 26 px)

Container fix:
- The prewarmed Cartopy cache in scripts/cartopy_cache.py was missing
  admin_2_counties_lakes, roads, LAND (10m), and the newly added
  lakes_north_america. Without them the unprivileged container uid
  hit PermissionError trying to download missing layers at request
  time. The script's docstring already required this list to be kept
  in sync with render.py; it had drifted.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
matplotlib stubs type Colorbar.outline as Spine | None and flag
method calls as "Spine not callable [operator]". At runtime it's
always a Spine on a freshly-constructed colorbar; suppress with a
narrow type: ignore[operator] rather than restructuring runtime code.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@jacaudi jacaudi merged commit 84b5389 into main May 9, 2026
9 checks passed
@jacaudi jacaudi deleted the feat/renderer-cartographic-upgrades branch May 9, 2026 01:17
@wall-e-one
Copy link
Copy Markdown
Contributor

wall-e-one Bot commented May 9, 2026

🎉 This PR is included in version 2.13.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@wall-e-one wall-e-one Bot added the released label May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant