kredd25 Claude Opus 4.6 (1M context) commited on
Commit
7548c06
·
1 Parent(s): 6638035

✨ feat(disaster): add NASA EONET layer with scorch effects

Browse files

Add disaster feature slice with NASA EONET v3 proxy (wildfires, storms,
volcanoes, floods, earthquakes). Disasters render as stacked scorch
marks (char + flame + ignition core). Flood zones now use 3-layer ink
bleed (halo + fill + edge). Add Playwright capture scripts for
Chicago, New Orleans, and showcase comparisons.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

surgeink/api/disasters.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import httpx
2
+ from fastapi import APIRouter, Query
3
+
4
+ from surgeink.cache.redis_cache import cache_get_json, cache_set_json
5
+
6
+ router = APIRouter()
7
+
8
+ EONET_BASE = "https://eonet.gsfc.nasa.gov/api/v3/events/geojson"
9
+ CACHE_TTL = 600 # 10 minutes
10
+
11
+
12
+ @router.get("/disasters")
13
+ async def get_disasters(
14
+ categories: str = Query(
15
+ "wildfires,severeStorms,volcanoes,floods,earthquakes",
16
+ description="Comma-separated EONET category IDs",
17
+ ),
18
+ limit: int = Query(200, ge=1, le=1000),
19
+ days: int = Query(30, ge=1, le=365),
20
+ status: str = Query("open", description="open or closed"),
21
+ ):
22
+ cache_key = f"disasters:{categories}:{limit}:{days}:{status}"
23
+ cached = await cache_get_json(cache_key)
24
+ if cached is not None:
25
+ return cached
26
+
27
+ params = {
28
+ "status": status,
29
+ "limit": limit,
30
+ "days": days,
31
+ }
32
+ if categories:
33
+ params["category"] = categories
34
+
35
+ async with httpx.AsyncClient(timeout=20.0) as client:
36
+ resp = await client.get(EONET_BASE, params=params)
37
+ resp.raise_for_status()
38
+
39
+ data = resp.json()
40
+ await cache_set_json(cache_key, data, CACHE_TTL)
41
+ return data
surgeink/api/router.py CHANGED
@@ -1,6 +1,6 @@
1
  from fastapi import APIRouter
2
 
3
- from surgeink.api import geocode, forecast, layers, risk, tiles, predict, interpret, fema
4
 
5
  router = APIRouter(prefix="/api/v1")
6
 
@@ -12,3 +12,4 @@ router.include_router(tiles.router, tags=["tiles"])
12
  router.include_router(predict.router, tags=["predict"])
13
  router.include_router(interpret.router, tags=["interpret"])
14
  router.include_router(fema.router, tags=["fema"])
 
 
1
  from fastapi import APIRouter
2
 
3
+ from surgeink.api import geocode, forecast, layers, risk, tiles, predict, interpret, fema, disasters
4
 
5
  router = APIRouter(prefix="/api/v1")
6
 
 
12
  router.include_router(predict.router, tags=["predict"])
13
  router.include_router(interpret.router, tags=["interpret"])
14
  router.include_router(fema.router, tags=["fema"])
15
+ router.include_router(disasters.router, tags=["disasters"])