feat(storm-intel): real storm polygon data via Iowa Environmental Mesonet IEM SBW archive
api/storm-polygons.js — Vercel proxy that fetches historical NWS storm-based warnings (severe thunderstorm + tornado) from IEM for WFO FWD (Fort Worth), covering Collin County / Plano TX. Filters to local bounding box, derives severity from polygon area (area2163 km²), estimates impacted homes from density, derives area name from centroid. Cached 12h on Vercel edge. useStormEvents.js — switched to real IEM data (USE_MOCK=false). Fetches full 36-month dataset once on mount; all range/type/severity filtering stays client-side in useMemo for instant UI response. Falls back to MOCK_STORM_EVENTS when /api routes are unavailable (local vite dev).
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
import { useState, useEffect, useMemo } from 'react';
|
||||
import { MOCK_STORM_EVENTS } from '../data/mockStore';
|
||||
|
||||
const USE_MOCK = true;
|
||||
// false = use real IEM/NWS data via /api/storm-polygons (falls back to mock if unreachable)
|
||||
const USE_MOCK = false;
|
||||
|
||||
const DATE_RANGE_DAYS = { '1m': 30, '3m': 90, '6m': 180, '12m': 365, '18m': 548, '24m': 730, '36m': 1095 };
|
||||
|
||||
@@ -38,10 +39,17 @@ export function useStormEvents({
|
||||
await new Promise(r => setTimeout(r, 450));
|
||||
data = MOCK_STORM_EVENTS;
|
||||
} else {
|
||||
const days = DATE_RANGE_DAYS[dateRange] ?? 365;
|
||||
const res = await fetch(`/api/storm-events?days=${days}&county=Collin`);
|
||||
if (!res.ok) throw new Error(`Storm events error: ${res.status}`);
|
||||
data = await res.json();
|
||||
try {
|
||||
// Always fetch full 36-month window so range changes are instant client-side.
|
||||
// Falls back to MOCK_STORM_EVENTS when /api routes aren't available (local vite dev).
|
||||
const res = await fetch('/api/storm-polygons?months=36');
|
||||
if (!res.ok) throw new Error(`${res.status}`);
|
||||
const json = await res.json();
|
||||
if (!Array.isArray(json) || json.length === 0) throw new Error('empty');
|
||||
data = json;
|
||||
} catch {
|
||||
data = MOCK_STORM_EVENTS;
|
||||
}
|
||||
}
|
||||
if (!cancelled) setAllEvents(Array.isArray(data) ? data : []);
|
||||
} catch (e) {
|
||||
@@ -53,7 +61,9 @@ export function useStormEvents({
|
||||
|
||||
load();
|
||||
return () => { cancelled = true; };
|
||||
}, [dateRange]);
|
||||
// Run once — 36mo dataset is fetched in full; all filtering is client-side in useMemo below
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
const events = useMemo(() => {
|
||||
let filtered = allEvents.filter(e => {
|
||||
|
||||
Reference in New Issue
Block a user