A visual catalog, drag-drop verifier, and anonymous contribution flow for India's geo data. Admin boundaries from state to village, plus community-submitted layers under open licences.
Live: https://bharatlas.com
catalog → state · district · subdistrict · block · village (LGD-coded)
verify → drop GeoJSON · KML · KMZ · GPX · TCX · Parquet → render + validate
submit → contribute under an open licence · anonymous · admin-token model
view (/c/<id>) → public page per submission, ▲/▼ vote, JSON-LD indexed
| Path | Contents |
|---|---|
web/ |
Vanilla TypeScript + Vite viewer + Cloudflare Pages Functions (web/functions/). |
web/migrations/ |
D1 SQL migrations: submissions, tokens, ratings, votes, originals. |
web/tests/ |
vitest unit tests for pure functions (validators, tokens, view rendering, votes). |
scripts/fetch.sh |
Pulls parquets + PMTiles from yashveeeeeeer/india-geodata releases. |
scripts/extract_per_state.py |
Slices pan-India parquets into per-state GeoJSON via DuckDB-spatial. |
scripts/upload_r2.sh |
Mirrors sources/ + data/ to Cloudflare R2. |
scripts/admin/cleanup_submission.sh |
Delete community submissions by name pattern (R2 + D1). |
catalog.json |
Curated-layer index used by the viewer. Single source of truth. |
REPORT.md |
Coverage + provenance + caveats per curated layer. |
Large data files (sources/, data/) are not in git — they live in R2. See scripts/fetch.sh to rebuild locally.
| Layer | Tech |
|---|---|
| Frontend | Vanilla TypeScript, Vite, MapLibre GL JS, PMTiles, DuckDB-WASM (lazy) |
| Static hosting | Cloudflare Pages |
| Edge functions | Cloudflare Pages Functions (web/functions/) — submit, vote, sitemap, edge-rendered /c/<id> |
| Storage | Cloudflare R2 (open data, no egress) |
| Submissions DB | Cloudflare D1 (SQLite at the edge) |
| Anti-abuse | Cloudflare Turnstile + per-IP rate limits |
| CI/CD | GitHub Actions — tests + build + auto-deploy on push to main |
# clone + viewer-only dev (no submissions, no D1)
git clone git@github.com:urbanmorph/geodata.git
cd geodata/web
npm install
npm run dev # http://localhost:5173
npm test # 167 vitest testsFor the full submission flow (D1 + R2 + Turnstile + Pages Functions), see docs/full-dev.md (TODO) or read wrangler.toml + .dev.vars.example.
- Branch off
main:git checkout -b feat/short-name - Write a test first if you're adding logic to
web/functions/lib/*. Pure functions are tested via vitest inweb/tests/. - Make sure
npm testandnpm run buildboth pass. - Open a PR against
main. CI runs tests + build automatically. - The maintainer reviews and merges. Merge to main = auto-deploy.
Commit messages: short subject, body explains why not what. Examples in git log.
cd web && npm test167 tests across validators, token generation, vote tally, render-view HTML, etc. See web/tests/.
- v1 — pan-India admin layers, parquet + PMTiles downloads
- v2 — DuckDB-WASM filter & export per state
- v3 — submission flow: drag-drop verify, anonymous token, auto-moderation, /c/[id] view page, mixed catalog, votes
- v4 — public API + MCP server + Claude Code plugin
Report vulnerabilities to sathya@urbanmorph.com instead of opening a public issue. Acknowledgement within 72 hours.
Code: MIT. Data: each layer carries its own open licence — see the per-card line on the catalog. Curated data is sourced under CC0-1.0 / CC-BY-4.0 / GODL-India depending on provider.
The platform doesn't warrant accuracy or fitness for any purpose. Boundaries shown are for reference, not legal authority — refer to LGD, SOI, Bhuvan or the state revenue department for official use. Community submissions are auto-moderated, not editorially curated; verify provenance via the source link on each card. See /about → Use of data.
- yashveeeeeeer/india-geodata — upstream parquet + PMTiles publisher.
- LGD, SOI, Bhuvan — primary government sources.
- geoBoundaries — independent cross-check.
- mdshare — the anonymous-token contribution pattern lineage.
Built by Urban Morph · @sathyasankaran. Drop a ⭐ if you find it useful.
Alpha. The submission flow is live and accepting contributions, but the schema and API may change before v4. Community submissions are permanent under the open licence the contributor selected.