Inspiration
Puget Sound's kelp and eelgrass meadows have been quietly disappearing for decades — taking juvenile Chinook salmon habitat with them, and by extension, food for the Southern Resident Orca population already on the endangered species list. Washington state set a bold goal: restore 10,000 acres of kelp and eelgrass by 2040. The Estuary and Salmon Restoration Program has invested $165M since 2006. But when we looked at how restoration sites get prioritized, we found a gap: decisions are made by committee, reading project proposals, without a continuous satellite view of where degradation is actually happening. 340 miles of Puget Sound shoreline. No real-time alerts. No 30-year change baseline feeding into grant decisions. That gap — between the data that exists and the decisions being made — is what KelpWatch is built to close.
What It Does
KelpWatch gives Puget Sound eyes on every inch of shoreline, all the time — backed by 30 years of NASA Landsat satellite data. One data layer serves every stakeholder:
WDFW biologists get continuous NDWI monitoring and satellite-derived ROI scores for ESRP grant applications Tribal nations get independent satellite verification of kelp and eelgrass health in their treaty waters — Swinomish, Lummi, Tulalip, Puyallup, Nisqually, Suquamish Nonprofits and NGOs see which sites need volunteer restoration efforts most urgently Legislators and citizens can verify whether Washington is on track for its 2040 goal
The system has five core capabilities:
30-year satellite map — Landsat 8/9 + TM5 NDWI change detection, 30m resolution, 6 Puget Sound counties, 1995 → today Early warning alerts — when NDWI drops 10% in any monitored bay, automatic notification fires to the relevant WDFW regional biologist and tribal natural resources department Tribal co-management layer — treaty territory overlays with per-nation NDWI health, 30-year trend, and treaty rights context ESRP grant ranker — paste any 2026 grant applications, get satellite-derived ROI scores and Fund/Review/Deprioritize recommendations in seconds AI decision agent — ask any restoration question in plain language; the agent cites real NDWI numbers, degradation percentages, and salmon recovery co-benefits
How We Built It
Satellite pipeline: We used the Google Earth Engine Python API to query Landsat Collection 2 Tier 1 Level 2 imagery across six Puget Sound county bounding boxes. For each county, we computed NDWI (Normalized Difference Water Index) across four time periods — 1995–97 (Landsat TM5), 1999–2001 (Landsat ETM7), 2009–11 (Landsat ETM7), and 2022–24 (Landsat LC8/9) — using reduceRegion with a mean reducer at 30m scale. This gives us a real satellite-derived degradation percentage for every county going back 30 years. The NDWI formula used: NDWI=Green−NIRGreen+NIR\text{NDWI} = \frac{\text{Green} - \text{NIR}}{\text{Green} + \text{NIR}}NDWI=Green+NIRGreen−NIR More negative NDWI = more degraded aquatic vegetation. Backend: FastAPI with two key routes beyond the GEE tile endpoints: /api/counties returns satellite-derived degradation rankings, and /api/agent routes to either Groq (llama-3.3-70b-versatile) or OpenAI (GPT-4o-mini) depending on the LLM_PROVIDER env variable. County data is precomputed in a background thread on startup and cached in memory — so by the time a user opens the dashboard, real satellite data is ready. We also built a smart response cache: 16 WDFW-aligned questions are pre-answered using real satellite data on startup. Fuzzy key matching on incoming queries returns cached responses instantly, with a progress bar showing whether the response came from cache or live LLM inference. Frontend: Leaflet.js with ESRI World Imagery satellite basemap. GEE tile URLs are fetched from the backend and rendered as map tile layers. The dashboard polls /api/status every 5 seconds and auto-updates when real satellite data becomes available, replacing fallback estimates with live county NDWI values.
Challenges
GEE authentication at hackathon speed was the first wall. Service account JSON key creation is blocked by default on new Google Cloud projects under the "Secure by Default" org policy introduced in 2024. We worked around it using earthengine authenticate --auth_mode=localhost, which stores credentials locally and initializes via ee.Initialize() without a JSON key. Python 3.14 / httpx compatibility — both the openai and groq SDKs fail with a proxies keyword argument error on Python 3.14. Fix: pin httpx==0.27.2 and build a fresh venv using Python 3.13 explicitly. GEE computation latency — a full 6-county, 4-period NDWI computation takes 45–90 seconds. We solved this with a startup background thread that precomputes and caches county data, a /api/status polling endpoint, and a frontend progress bar that buffers agent queries until satellite data is ready. The demo never blocks. Framing for non-technical judges — the hardest challenge wasn't technical. It was learning to lead with the human story (kelp → salmon → orca → treaty rights → 2040 goal) rather than the architecture. Satellite data and AI agents are only compelling when the human stakes are visible first.
What We Learned
Thirty years of NASA satellite data is sitting in Google Earth Engine, publicly accessible, free to query. The gap isn't data — it's the layer that turns raw spectral indices into decisions. Building that layer in a single weekend showed us how much is already possible with public infrastructure, and how much of the environmental decision-making process still runs on PDFs and committee meetings. We also learned that tribal treaty rights are a powerful lens for environmental data. The Boldt Decision (U.S. v. Washington, 1974) gives tribal nations co-management authority over fisheries — which means kelp and eelgrass health in treaty waters is not just an ecological question, it's a legal one. Giving tribes independent satellite verification of habitat health in their ceded waters is a concrete, actionable use of this technology.
Built With
- chart.js
- esri-world-imagery
- fastapi
- google-earth-engine
- groq
- javascript
- landsat-c02
- leaflet.js
- llama-3.3-70b
- ndwi
- openai
- python
- remote-sensing
- uvicorn
Log in or sign up for Devpost to join the conversation.