Skip to content

Repository files navigation

Prahari — land-change monitoring from satellite embeddings

CI

Live demo → (runs entirely in your browser — the offline build with the baked snapshot)

Prahari (प्रहरी, sentinel) finds where the ground changed across an Indian region — new construction, land clearing, encroachment — without downloading any satellite imagery. It works on open geo-embedding vectors instead: each 2560 m grid cell has a 1024-dimensional embedding per annual Sentinel-2 snapshot, and a cell whose embedding moved far between 2024 and 2025 changed on the ground. Change detection is one cosine distance per cell; similarity search (cosine again) then sweeps the region for look-alikes of anything you find. No labels, no training, no GPUs.

The UI borrows the look of a Survey of India toposheet, and has day and night themes:

Prahari Register of Changes — 192 cells over the Bengaluru North-East quadrant, flagged cells marked for inspection

Selecting a flagged cell opens its record, and find similar ranks every other cell in the quadrant by cosine similarity and marks the top matches on the plate — useful for finding more of whatever you just spotted (more new construction, more cleared land):

Selecting the top-ranked change and sweeping the quadrant for its nearest neighbours in embedding space

How it works

The pilot AOI is the Bengaluru North-East quadrant: 192 cells of 2560 m (MajorTOM grid), June 2024 vs June 2025, from LGND's open Clay v1.5 Sentinel-2 embeddings (CC-BY 4.0, 15.2B embeddings covering the whole Sentinel-2 archive).

flowchart LR
  SC[(Source Coop\nClay v1.5 parquet)] -->|pipeline/ingest.py| DB[(embeddings.duckdb)]
  DB -->|pipeline/analyze.py\ncosine Δ + kNN| DB
  DB --> API[FastAPI gateway\n/api/v1]
  DB -->|pipeline/export_dashboard.py| SNAP[baked snapshot\ndata.ts]
  API --> UI[React dashboard]
  SNAP -.offline fallback.-> UI
Loading
  • Change detection — cosine distance between a cell's 2024 and 2025 embeddings; cells beyond +2σ of the AOI mean are flagged for inspection.
  • Similarity search — cosine similarity between one cell and every other cell in the same snapshot, served live by the API.
  • Alert workflow — flagged cells can be acknowledged; the state is persisted server-side in SQLite.
  • Offline fallback — the frontend uses the live API when it can reach one and otherwise falls back to a baked data snapshot (the footer shows LIVE API or OFFLINE SNAPSHOT), so npm run build produces a single self-contained dist/index.html that works with no server at all.

API

One FastAPI gateway (server/main.py), service-per-module, OpenAPI docs at /docs:

Endpoint Service
GET /api/v1/aois geo — areas of interest
GET /api/v1/aois/{id}/dashboard analytics — KPIs, cells, distribution
GET /api/v1/aois/{id}/cells/{cid}/similar?k= vector — similarity search
GET /api/v1/aois/{id}/alerts · POST …/alerts/{cid}/ack alerts — flag lifecycle

Layout

├─ pipeline/               batch data plane
│  ├─ ingest.py            pull embeddings for an AOI → embeddings.duckdb
│  ├─ analyze.py           change detection + similarity search
│  └─ export_dashboard.py  bake dashboard snapshot → webapp/land-watch/src/data.ts
├─ embeddings.duckdb       local embedding store (Bengaluru pilot AOI, ships with repo)
├─ server/                 Python platform — one FastAPI gateway, service-per-module
│  ├─ main.py              gateway: mounts every service under /api/v1
│  ├─ platform/            shared kernel: DuckDB store (→ pgvector seam), alerts repo
│  └─ services/            geo · analytics · vector · alerts
├─ webapp/                 micro frontends — one app per product
│  └─ land-watch/          Register of Changes console (React 19 + TS + Vite)
├─ tests/                  pytest: export math + API contract (vitest suite lives in the webapp)
└─ ARCHITECTURE.md         service boundaries; when each piece becomes its own deployment

Run it

Prerequisites: uv and Node 20+. The embedding store ships with the repo, so no ingest is needed to get started.

uv sync                                       # Python deps
uv run python -m pipeline.export_dashboard    # bake the frontend snapshot

uv run uvicorn server.main:app --reload       # API at :8000 (docs at /docs)

cd webapp/land-watch
npm install
npm run dev                                   # dashboard at :5173, proxies /api → :8000

To re-pull embeddings from source (needs internet, ~2 min): uv run python -m pipeline.ingest.

Test & build

uv run pytest                            # export math + API contract
cd webapp/land-watch && npm test         # components + interactions
cd webapp/land-watch && npm run build    # typecheck + single-file offline bundle

Status & background

This is a proof of concept for a startup idea I was exploring: a geo-embeddings analytics platform hosted in India, built around the 2021 geospatial data-residency rules and the private national EO constellation now under construction. The research ended up talking me out of the original pitch (the market is smaller than it looks and the regulatory moat is weaker than it reads), but all the notes are in the repo:

  • NOTES.md — the concept, the landscape (LGND, Google AlphaEarth), and why a plain vector-DB product no longer makes sense
  • RESEARCH.md — viability research with sources. Short version: not viable as originally pitched, possibly viable as something narrower
  • ARCHITECTURE.md — where the service boundaries would be if this grew into a real platform, and what has to happen before each one gets split out

Everything runs locally: DuckDB for the vectors, SQLite for workflow state. The Postgres + pgvector migration path is written down in ARCHITECTURE.md instead of built.

Data & licences

  • Code: MIT.
  • Embeddings: Clay v1.5 Sentinel-2 L2A, published openly by LGND on Source Cooperative under CC-BY 4.0 — this covers embeddings.duckdb and the data derived from it.
  • Type: IBM Plex (embedded subsets), SIL Open Font License.

About

Land-change monitoring over India from open Clay/Sentinel-2 geo-embeddings — change detection + similarity search, DuckDB + FastAPI + React

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages