- Hono Worker + MapLibre GL 3D terrain map (satellite + Terrarium DEM, no API key) - Deterministic survey simulator: lawnmower flight + georeferenced detections - Species markers, flight path, timeline scrubber, confidence + type filters - D1 schema + POST /api/ingest for real drone data feeding the same dashboard Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| src | ||
| .gitignore | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| schema.sql | ||
| wrangler.toml | ||
🛰️ CritterScope
Turn a drone survey into georeferenced animal/object detections on a 3D map.
A drone flies a survey → thermal+RGB frames + telemetry → an AI detector emits
warm-blob detections → each is projected onto terrain as (lat, lon, type, confidence, temp, time) → this app plots them on a 3D terrain globe with a
timeline you can replay.
The dashboard runs today off a built-in simulator, so the whole UI is done and
testable before any drone arrives. Real footage feeds the same dashboard via
POST /api/ingest.
Stack
- Cloudflare Worker + Hono (
src/index.js) - MapLibre GL JS — satellite imagery + Terrarium DEM for real 3D terrain (no API key)
- D1 (optional) — stores real surveys/detections; schema in
schema.sql - Deploys to
critterscope.theradicalparty.com
Run locally
npm install
npm run dev # http://localhost:8787
Open / for the dashboard. Point it anywhere:
/?lat=-33.73&lon=150.31&r=1000 # center, radius (m)
/?seed=42 # different simulated survey
Data contract (what the drone pipeline must produce)
GET /api/survey returns:
{
"survey": { "id","name","center_lon","center_lat","radius_m","sensor","drone","started_at","ended_at","simulated" },
"flight": [ { "seq","lon","lat","agl_m","t" } ],
"detections": [ { "id","type","lon","lat","confidence","temp_c","t","frame" } ],
"stats": { "total","counts","area_km2","duration_min" }
}
type ∈ deer | fox | rabbit | boar | kangaroo | person | vehicle | unknown.
Feeding real drone data
wrangler d1 create critterscope, paste the id intowrangler.toml, uncomment the binding.npm run db:initPOST /api/ingestwith{ survey, flight, detections }.- View it at
/?survey=<id>.
The georeferencing step (frame + drone GPS + gimbal angle + terrain → lat/lon) lives in the drone pipeline, not here — this app just needs the resulting detections.
Roadmap
- Drone ingest pipeline (RTMP/SRT frames → YOLO thermal detector → georeferencer)
- Live mode (stream detections during flight, not just post-survey)
- Track clustering (merge repeat sightings of the same animal across passes)