A full-stack geospatial platform for real-time flood and urban heat risk analysis β powered by terrain modeling, weather history, computer vision, hydraulic simulation, and an AI assistant.
π₯ Watch Demo
| Default View | OSM + Routing |
|---|---|
![]() |
![]() |
| Satellite + Routing | Advanced Mode |
|---|---|
![]() |
![]() |
- πΊοΈ Dual map modes β OpenStreetMap and satellite imagery
- π Waypoint routing β draw a path, get a navigable route
- π Flood risk analysis β per-cell scoring from terrain + rainfall + simulation + street imagery
- π‘οΈ Heat risk analysis β Urban Heat Island scoring from temperature + impervious surfaces + vegetation
- π· Street-level vision β Mapillary images analyzed by SegFormer, Groq vision, or CLIP
- π€ GeoAI Assistant β Groq-powered chatbot with tool-calling for routing, analysis, and weather
- π Advanced mode β elevation profile, risk stats panel, image viewer, trajectory playback
- β‘ Redis caching β weather (1h TTL) and DEM (24h TTL) to avoid redundant API calls
ββββββββββββββββββββββββββββββββββββββββββββββββ
β Frontend (Next.js 14) β
β MapView Β· RiskMap Β· WaypointRouter β
β GeoAssistant Β· ProfileChart Β· RiskStatsPanel β
β Zustand store (useAnalysisStore) β
ββββββββββββββββββββββ¬ββββββββββββββββββββββββββ
β REST / SSE
ββββββββββββββββββββββΌββββββββββββββββββββββββββ
β Backend (FastAPI) β
β β
β /analysis /assistant /weather β
β /routing /mapillary /profile β
β β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β AnalysisPipeline β β
β β Fetch β Process β Simulate β Score β β
β β β GeoJSON Export β β
β βββββββββββββββββββββββββββββββββββββββββββ β
β β
β Providers: Open-Meteo Β· SRTM Β· Mapillary β
β Cache: Redis β
β Simulation: HEC-RAS | NullEngine β
ββββββββββββββββββββββββββββββββββββββββββββββββ
AnalysisPipeline.run() in fusion/pipeline.py β five ordered stages:
All sources fetched in parallel via asyncio.gather:
| Source | Provider | Cache TTL |
|---|---|---|
| Historical weather | Open-Meteo | 1 hour |
| Digital Elevation Model | SRTM | 24 hours |
| Street-level images | Mapillary | none |
Redis caches weather and DEM results. Mapillary failures are silently ignored β the pipeline continues with an empty image list.
| Analyzer | Input | Output |
|---|---|---|
TerrainAnalyzer |
DEM grid | elevation, slope (Β°), flow accumulation (D8) |
WeatherAnalyzer |
Weather history | flood trigger score, heat stress, rainfall totals |
VisionAnalyzer |
Mapillary images | impervious %, vegetation %, shadow %, standing water % |
| Engine | Description |
|---|---|
HEC-RAS |
Full hydraulic simulation β flood_extent_array + flood_depth_array |
NullEngine |
Statistical fallback β produces a weaker extent array; its 25% weight is redistributed to terrain/weather |
Active engine set via SIMULATION_ENGINE=null|hecras in .env.
FloodRiskEngine and HeatRiskEngine each produce a per-cell NumPy score grid [0, 1], a category grid (0=none β¦ 4=extreme), and a components dict for UI explainability.
grid_to_geojson_polygons() converts score/category grids into GeoJSON Polygon features rendered directly on the map.
| Factor | Weight | Notes |
|---|---|---|
| Weather | 35% | Rainfall total + peak intensity |
| Terrain | 30% | Elevation + slope + flow accumulation |
| Simulation | 25% | 0% with NullEngine; redistributed to terrain/weather |
| Vision | 10% | Impervious surface + standing water |
Terrain score (per cell):
terrain = 0.4 Γ (1 β norm_elevation)
+ 0.3 Γ (1 β clip(slope / 30Β°))
+ 0.3 Γ norm(log(flow_accumulation + 1))
Derived display metrics: runoff coefficient (Rational Method), peak flow index, drainage index, high-risk cell %, max flow accumulation.
heat_score = temp_baseline β dominant (15Β°Cβ0, 40Β°Cβ1)
+ heat_stress Γ 0.25
+ impervious Γ 0.25 β Urban Heat Island proxy
β vegetation Γ 0.15 β cooling
β shadow Γ 0.10 β cooling
β elevation_norm Γ 0.05 β lapse rate
Derived display metrics: UHI intensity (Β°C), simplified Steadman heat index, cooling deficit, drought days.
VisionAnalyzer processes each Mapillary image through a fallback chain:
SegFormer (HuggingFace) β Groq Vision β CLIP (local) β Mock
| Model | How it works |
|---|---|
SegFormer nvidia/segformer-b0-finetuned-cityscapes-640-640 |
Pixel-level Cityscapes segmentation via HF Inference API. Decodes base64 PNG masks β computes per-label pixel fractions (vegetation, impervious, water, sky) |
Groq Vision llama-3.2-11b-vision-preview |
Prompts the model to return a JSON object with vegetation_score, impervious_score, shadow_score, standing_water, surface_type |
CLIP openai/clip-vit-base-patch32 |
Zero-shot classification against 5 text labels, run locally via HuggingFace transformers |
| Mock | Seeded random values β used in tests or when all APIs are unavailable |
Set with CV_MODEL=segformer|groq|clip|mock.
The assistant (/api/v1/assistant/chat) is a Groq tool-calling agent backed by llama-3.3-70b-versatile.
Flow:
- Frontend sends
messages[]+tools[]to the backend - Backend proxies to Groq (
/openai/v1/chat/completions) withtool_choice: auto - Groq returns a
tool_useresponse β frontend executes the tool locally - Frontend sends the tool result back as a
toolrole message - Loop repeats until Groq returns a plain text answer
Endpoints:
| Endpoint | Mode |
|---|---|
POST /assistant/chat |
Standard JSON response |
POST /assistant/chat/stream |
SSE streaming (token-by-token) |
Tool examples registered by the frontend:
run_analysisβ triggers the full risk pipeline for a bboxget_weatherβ fetches weather for coordinatesroute_waypointsβ plans a path between waypointsfly_toβ pans the map camera (updatesflyToTargetin Zustand)
All shared UI state lives in useAnalysisStore:
| Slice | Description |
|---|---|
mode |
simple (map only) or advanced (full analysis UI) |
aoi / drawnPath |
Current area of interest or freehand path |
floodLayers / heatLayers |
GeoJSON risk features from last analysis |
activeLayer |
Which risk overlay is visible (flood or heat) |
trajectory / profile |
Elevation profile points for playback |
images |
Mapillary image points for the image viewer |
assistantWaypoints / assistantRoute |
Route generated by the AI assistant |
flyToTarget |
Map camera target set by the assistant |
lastAnalysisDurationSeconds |
Performance display in the stats panel |
| Key pattern | TTL | Data |
|---|---|---|
weather:{lat}:{lon}:{days} |
1 hour | WeatherSummary JSON |
dem:{west}:{south}:{east}:{north} |
24 hours | DEMData JSON |
Coordinates are snapped to 0.01Β° precision to avoid near-duplicate cache misses. If Redis is unavailable, the pipeline falls back to live fetches transparently.
git clone https://github.com/your-org/GeoAI-RiskMapper.git
cd GeoAI-RiskMapper
cp .env.example .env # fill in your keys
docker compose -f infra/docker-compose.yml up --build- Frontend β http://localhost:3000
- Backend API β http://localhost:8000/docs
APP_NAME=GeoAI Risk Engine
DATABASE_URL=postgresql+asyncpg://geoai:geoai@localhost:5432/geoai
REDIS_URL=redis://localhost:6379
MAPILLARY_ACCESS_TOKEN=your_token
GROQ_API_KEY=your_key
GROQ_MODEL=llama-3.3-70b-versatile
HF_API_KEY=your_key
ORS_API_KEY=your_key
GEONAMES_USERNAME=your_username
OPENTOPOGRAPHY_API_KEY=your_key
WEATHER_PROVIDER=open_meteo
DEM_PROVIDER=srtm
ELEVATION_OPENTOPODATA_DATASET=srtm90m
ELEVATION_OPENTOPOGRAPHY_DEMTYPE=SRTMGL1
SIMULATION_ENGINE=null # null | hecras
HECRAS_MCP_URL=http://localhost:8001
CV_MODEL=segformer # segformer | groq | clip | mock# Backend
cd backend && pip install -r requirements.txt
uvicorn app.main:app --reload --port 8000
# Frontend
cd frontend && npm install && npm run dev.
βββ backend/app/
β βββ api/routes/ # FastAPI endpoints
β βββ core/ # Config, DB, Redis
β βββ data_providers/ # SRTM, Open-Meteo, Mapillary
β βββ elevation/ # Multi-provider elevation catalog
β βββ fusion/ # AnalysisPipeline + GeoJSON export
β βββ processing/ # Terrain, Weather, Vision analyzers
β βββ risk_engine/ # FloodRiskEngine, HeatRiskEngine
β βββ simulation/ # HEC-RAS + NullEngine
βββ frontend/src/
β βββ components/ # Map, analysis panels, assistant UI
β βββ store/ # Zustand (useAnalysisStore)
β βββ lib/ # API client
βββ docs/ # Platform screenshots
βββ infra/ # docker-compose.yml, schema.sql
βββ README.md
MIT



