About the Project — PulseMap Agent
Inspiration
During fast-moving events—accidents, flash floods, outages—critical info gets scattered across group chats, social media, and rumor. PulseMap Agent was inspired by a simple idea: put everything that matters on one live map, blending community reports with trusted hazard feeds so people nearby can react quickly and help each other.
What I Learned
- Agentic decision-making with LangGraph: How to model a small team of tools (add report, find nearby, classify, fetch feeds) as a state graph so decisions are predictable, not “random LLM magic.”
- Maps + AI: How to connect AI reasoning to geospatial context—coordinates, bounding boxes, and census tract polygons—so the UI feels local and situational.
- Session-aware UX: Using a lightweight SQLite-backed memory and stable IDs (
rid) so Verify / Clear is per-device and never double-nags a user. - Feed normalization: Merging USGS, NWS, NASA EONET, and FIRMS into a single update shape that’s easy for the frontend to render.
- Frontend polish: Custom markers, nearby pop-ups (≤5 within 2 miles), smooth exit animations, and avoiding race conditions in polygon overlays.
How I Built It
Stack overview
- Backend: FastAPI, LangGraph, LangChain tools, Python, SQLite (reports + reactions), simple file storage for photos.
- Frontend: React + TypeScript + Vite, TailwindCSS,
@vis.gl/react-google-maps(Google Maps JS API). - Feeds/APIs: USGS Earthquakes, NWS Alerts, NASA EONET, NASA FIRMS.
Core flow
- A person adds a report (text + optional photo) at a selected point on the map.
- The incident recognizer classifies it (e.g., accident, missing item) and sets severity.
- The report is stored with a stable
ridand rendered instantly on the map + sidebar. - When another user opens the app nearby, a modal surfaces up to 5 reports within 2 miles with Verify / Clear / Skip.
- Reactions update live and are tied to the user’s session to avoid duplicates.
- Official feeds are polled on the backend and merged into
/updates/localso the user sees one coherent picture. - Census zones (tract polygons) tint based on the highest severity inside, giving quick area context.
Mental model (simple)
- One orchestrator (LangGraph) that calls small tools at the right time.
- One map that shows both community and official signals.
- One tap for the community to say “I saw it” or “It’s clear.”
Challenges I Faced
- Respecting user location exactly: Ensuring the agent never shifts coordinates, even when the text implies a different place. Fixed by always passing explicit lat/lon through the tool payloads.
- Stable identifiers: Some early reports lacked a stable
rid, which broke reactions. Solved by stampingridon read/write and backfilling older rows. - Polygon flicker on zoom: GeoJSON fetches were racing with map events. Fixed with AbortController, request IDs, and immediate clears when zoom < min.
- Photo flow: Handling upload URLs, missing thumbnails, and graceful fallbacks without blocking the user path.
- Balancing AI flexibility and determinism: LangGraph nodes + clear tool contracts reduce “hallucinations” and keep actions traceable.
Why it matters
PulseMap Agent turns the crowd + official data into a single situational awareness layer—fast, transparent, and respectful. It makes it easy to add what you see and confirm what’s true, helping neighborhoods stay resilient when it counts.
What’s Next
- Local News ingest (RSS/scrape → summarize & geotag)
- Lightweight moderation / abuse prevention
- PWA + optional push-style nudges (opt-in)
- Broader datasets (road closures, utility outages) and accessibility polish
Built With
- fastapi
- google-maps
- langchain
- langgraph
- lucide
- nasa-eonet
- nasa-firms
- nws
- python
- react
- sqlite
- typescript
- usgs
Log in or sign up for Devpost to join the conversation.