Weather map layers: NWS warning polygons, n0q radar with valid time/legend/loop, wind at incident (#237) #277

Merged
logan merged 2 commits from feat/237-weather-map into main 2026-10-05 03:53:35 -04:00
Owner

Part 2 of 2 for #237 (backend landed in #263).

Map

  • Weather Warnings overlay (layer key wx, saved in the view hash like the others): NWS alert polygons coloured by event (NWS hazard-map colours), outline dash by kind (warning solid / watch dashed / advisory dotted), popup with event, headline, onset/ends/expires, issuing office, zone-assembly note, and National Weather Service credit + fetch time. Polls GET /weather/alerts every 2 min while on and visible, refetches on pan and on return to a hidden tab.
  • Never a silently empty layer: a status chip always says what it shows (N in view / none in view / loading). Feed problems use the 511 FeedProblem wording (could not reach server, NWS feed error, showing data from N min ago). Zone-only alerts are listed in that chip, not dropped.
  • Radar: IEM nexrad-n0r -> n0q. Valid-time badge from IEM's n0q_0.json, flagged STALE past 15 min (or when the time can't be read); dBZ legend; optional 1 h loop off by default. Still refreshed in place, never remounted (the #321-325 workaround kept; layers now sit in a FeatureGroup).

Verified first-hand 2026-10-05: nexrad-n0q-900913/{z}/{x}/{y}.png (ACAO *), -m05m..-m55m exist (-m60m 404s), data/gis/images/4326/USCOMP/n0q_0.json -> meta.valid (n0q_k = k x 5 min earlier), ramp from GIS/rasters.php?rid=2: every opaque pixel of 5 live tiles matched it exactly.

Live wall

  • sampleRadarDbz reads the same n0q tile with that ramp; "approx." label kept.
  • Incident panel: "inside " chips (pure pointInPolygon, holes respected); wind arrow + speed/gust + station/obs time on fire and hazmat-tagged incidents (GET /weather/wind).
  • Region Feeds: NWS row with fetch time or error.

Not touched: LiveView.tsx (#238), backend, discord files (#225).

Checks: tsc --noEmit exit 0 (fresh scratch copy). Ad-hoc node checks on the pure helpers (ramp, pixel lookup, tile URLs, meta parse, point-in-polygon incl. holes/multipolygon, wantsWind, hash round-trip): all passed. Not run in a browser.

Closes #237

🤖 Generated with Claude Code

Part 2 of 2 for #237 (backend landed in #263). **Map** - **Weather Warnings** overlay (layer key `wx`, saved in the view hash like the others): NWS alert polygons coloured by event (NWS hazard-map colours), outline dash by kind (warning solid / watch dashed / advisory dotted), popup with event, headline, onset/ends/expires, issuing office, zone-assembly note, and National Weather Service credit + fetch time. Polls `GET /weather/alerts` every 2 min while on and visible, refetches on pan and on return to a hidden tab. - Never a silently empty layer: a status chip always says what it shows (N in view / none in view / loading). Feed problems use the 511 FeedProblem wording (`could not reach server`, `NWS feed error, showing data from N min ago`). Zone-only alerts are listed in that chip, not dropped. - **Radar**: IEM `nexrad-n0r` -> `n0q`. Valid-time badge from IEM's `n0q_0.json`, flagged **STALE** past 15 min (or when the time can't be read); dBZ legend; optional 1 h loop off by default. Still refreshed in place, never remounted (the #321-325 workaround kept; layers now sit in a FeatureGroup). **Verified first-hand 2026-10-05**: `nexrad-n0q-900913/{z}/{x}/{y}.png` (ACAO *), `-m05m`..`-m55m` exist (`-m60m` 404s), `data/gis/images/4326/USCOMP/n0q_0.json` -> `meta.valid` (n0q_k = k x 5 min earlier), ramp from `GIS/rasters.php?rid=2`: every opaque pixel of 5 live tiles matched it exactly. **Live wall** - `sampleRadarDbz` reads the same n0q tile with that ramp; "approx." label kept. - Incident panel: "inside <warning>" chips (pure `pointInPolygon`, holes respected); wind arrow + speed/gust + station/obs time on fire and hazmat-tagged incidents (`GET /weather/wind`). - Region Feeds: NWS row with fetch time or error. **Not touched**: LiveView.tsx (#238), backend, discord files (#225). **Checks**: `tsc --noEmit` exit 0 (fresh scratch copy). Ad-hoc node checks on the pure helpers (ramp, pixel lookup, tile URLs, meta parse, point-in-polygon incl. holes/multipolygon, wantsWind, hash round-trip): all passed. Not run in a browser. Closes #237 🤖 Generated with [Claude Code](https://claude.com/claude-code)
logan added 1 commit 2026-10-05 03:46:37 -04:00
- Weather Warnings overlay (layer key `wx`, saved in the view hash): NWS alert
  polygons coloured by event (NWS hazard-map colours), outline dash by kind,
  popup with event/headline/expiry/office and National Weather Service credit.
  Polls GET /weather/alerts every 2 min while on and visible, refetches on pan.
  A status chip always says what the layer shows; feed errors use the 511
  FeedProblem wording; zone-only alerts are listed, never dropped.
- Radar: IEM nexrad-n0r -> n0q. Valid-time badge from IEM's n0q_0.json,
  STALE past 15 min or when the time can't be read; dBZ legend; optional 1 h
  loop (nexrad-n0q-900913-m05m..m55m), off by default. Still refreshed in
  place, never remounted.
- liveWall: sampleRadarDbz reads the n0q tile with IEM's published 255-colour
  ramp (verified against live tiles); pointInPolygon/alertsAt, wxStyle,
  wantsWind helpers.
- Wall incident panel: "inside <warning>" chips, wind arrow + speed/gust +
  station/obs time on fire/hazmat incidents; region Feeds gains an NWS row.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
logan added 1 commit 2026-10-05 03:51:27 -04:00
The 1 h loop set MapView state every 600 ms, re-rendering the whole map
component and rebuilding (setIcon) every marker icon on each tick. The
frame now lives in a small external store that only the radar frames and
the valid-time badge subscribe to.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
logan merged commit cde86a8ff9 into main 2026-10-05 03:53:35 -04:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/server-26#277