From a31295945c309d661e879ba36a6bd1f8afccf662 Mon Sep 17 00:00:00 2001 From: Doxa Maps Date: Sat, 26 Sep 2026 06:55:38 +0000 Subject: [PATCH] India by state: all 36 states, Mizoram and Nagaland included MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The India layer drew on UPG-100's curated partition (34 of 36 units), so Mizoram and Nagaland had figures but no geometry. studio staged the complete ADM1 beside it (data/boundaries/gb-IND-ADM1-full.geojson: gbOpen IND-ADM1-1811400, DataMeet / ECI, CC BY 2.5 IN, with its .meta.json). The curated file is untouched. - connectivity-map.vue fetches boundaries/gb-IND-ADM1-full.geojson. - The crosswalk maps Mizoram -> "Mizoram" and Nagaland -> "Nāgāland" (the boundary file's spelling) instead of null. The generator validates against the full file, and the table's meta names it with its licence. - The regenerated table has 36 areas drawn and none missing, so the legend's "no boundary yet" line no longer shows (it renders only when that list is non-empty). Headless: build and tree OK; both boundary files are staged; the fill expression (maplibre-gl-style-spec) colours 36 of 36 states (Mizoram women 67.6, Nagaland women 49.9). --- data/internet/README.md | 4 +-- data/internet/adm1-crosswalk-IND.json | 8 ++--- data/tables/internet-by-adm1.json | 35 +++++++++---------- .../cities-internet/connectivity-map.vue | 8 +++-- .../scripts/build-adm1-internet.mjs | 12 +++---- 5 files changed, 32 insertions(+), 35 deletions(-) diff --git a/data/internet/README.md b/data/internet/README.md index ae70931f9..fbd4cbe5f 100644 --- a/data/internet/README.md +++ b/data/internet/README.md @@ -18,6 +18,6 @@ re-run the script; never edit the table by hand. not a subscription count (TRAI's "subscribers per 100" is a different measure and can exceed 100). ## adm1-crosswalk-IND.json -Source state names → the `shapeName` of `plugin-designs/my-upg-100-list/data/gb-IND-ADM1.geojson` -(served as `assets/boundaries/gb-IND-ADM1.geojson`). Every source name must appear here, with either +Source state names → the `shapeName` of `data/boundaries/gb-IND-ADM1-full.geojson` (all 36 states, +served as `assets/boundaries/gb-IND-ADM1-full.geojson`; source and licence in its `.meta.json`). Every source name must appear here, with either the boundary name or `null` plus a reason. The build fails on anything else, never guesses. diff --git a/data/internet/adm1-crosswalk-IND.json b/data/internet/adm1-crosswalk-IND.json index 61c0d8139..ba18a5ece 100644 --- a/data/internet/adm1-crosswalk-IND.json +++ b/data/internet/adm1-crosswalk-IND.json @@ -1,5 +1,5 @@ { - "_about": "NFHS-5 state name -> gb-IND-ADM1.geojson shapeName. null = no geometry to draw it on, with the reason. Checked by build-adm1-internet.mjs.", + "_about": "NFHS-5 state name -> gb-IND-ADM1-full.geojson shapeName. null = no geometry to draw it on, with the reason. Checked by build-adm1-internet.mjs.", "map": { "Andaman & Nicobar Islands": { "adm1": "Andaman and Nicobar Islands" @@ -73,15 +73,13 @@ "adm1": "Meghālaya" }, "Mizoram": { - "adm1": null, - "reason": "excluded from the shipped boundary file, which is the UPG-100 partition (my-upg-100-list/data/source-boundaries.mjs: 36 units upstream, 34 on disk)" + "adm1": "Mizoram" }, "NCT Delhi": { "adm1": "Delhi" }, "Nagaland": { - "adm1": null, - "reason": "excluded from the shipped boundary file, which is the UPG-100 partition (my-upg-100-list/data/source-boundaries.mjs: 36 units upstream, 34 on disk)" + "adm1": "Nāgāland" }, "Odisha": { "adm1": "Odisha" diff --git a/data/tables/internet-by-adm1.json b/data/tables/internet-by-adm1.json index ba5703316..0e14f1310 100644 --- a/data/tables/internet-by-adm1.json +++ b/data/tables/internet-by-adm1.json @@ -22,14 +22,11 @@ }, "boundaries": { "IND": { - "file": "boundaries/gb-IND-ADM1.geojson", + "file": "boundaries/gb-IND-ADM1-full.geojson", "key": "shapeName", - "licence": "geoBoundaries gbOpen, India ADM1: CC BY 2.5 IN (datameet)", - "missing": [ - "Mizoram", - "Nagaland" - ], - "missing_reason": "no geometry in the shipped boundary file (the UPG-100 partition: 34 of 36 units)" + "licence": "geoBoundaries gbOpen IND-ADM1-1811400 (DataMeet / ECI): CC BY 2.5 IN", + "missing": [], + "missing_reason": "no feature for it in the boundary file" } }, "national": [ @@ -1595,7 +1592,7 @@ "value": 67.6, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Mizoram", "adm1_name": "Mizoram" }, { @@ -1606,7 +1603,7 @@ "value": 83.8, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Mizoram", "adm1_name": "Mizoram" }, { @@ -1617,7 +1614,7 @@ "value": 48, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Mizoram", "adm1_name": "Mizoram" }, { @@ -1628,7 +1625,7 @@ "value": 79.7, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Mizoram", "adm1_name": "Mizoram" }, { @@ -1639,7 +1636,7 @@ "value": 92.7, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Mizoram", "adm1_name": "Mizoram" }, { @@ -1650,7 +1647,7 @@ "value": 63.9, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Mizoram", "adm1_name": "Mizoram" }, { @@ -1661,7 +1658,7 @@ "value": 49.9, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Nāgāland", "adm1_name": "Nagaland" }, { @@ -1672,7 +1669,7 @@ "value": 66.5, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Nāgāland", "adm1_name": "Nagaland" }, { @@ -1683,7 +1680,7 @@ "value": 40.3, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Nāgāland", "adm1_name": "Nagaland" }, { @@ -1694,7 +1691,7 @@ "value": 64.6, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Nāgāland", "adm1_name": "Nagaland" }, { @@ -1705,7 +1702,7 @@ "value": 81, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Nāgāland", "adm1_name": "Nagaland" }, { @@ -1716,7 +1713,7 @@ "value": 55.2, "source": "nfhs5", "year": "2019-21", - "adm1": null, + "adm1": "Nāgāland", "adm1_name": "Nagaland" }, { diff --git a/plugin-designs/cities-internet/connectivity-map.vue b/plugin-designs/cities-internet/connectivity-map.vue index e2e1f1eec..b9c469c2c 100644 --- a/plugin-designs/cities-internet/connectivity-map.vue +++ b/plugin-designs/cities-internet/connectivity-map.vue @@ -292,7 +292,9 @@ const adm1Fill = (sex) => ['case', ['==', ['typeof', ['get', sex]], 'number'], async function loadAdm1() { const [table, geo] = await Promise.all([ fetch(`${assetsBase.value}/tables/internet-by-adm1.json`).then((r) => { if (!r.ok) throw new Error('internet-by-adm1 ' + r.status); return r.json() }), - fetch(`${assetsBase.value}/boundaries/gb-IND-ADM1.geojson`).then((r) => { if (!r.ok) throw new Error('gb-IND-ADM1 ' + r.status); return r.json() }), + // All 36 states (data/boundaries/gb-IND-ADM1-full.geojson). NOT gb-IND-ADM1.geojson: that one is + // UPG-100's partition, curated to 34 units, and it left Mizoram and Nagaland with no geometry. + fetch(`${assetsBase.value}/boundaries/gb-IND-ADM1-full.geojson`).then((r) => { if (!r.ok) throw new Error('gb-IND-ADM1-full ' + r.status); return r.json() }), ]) const byArea = {} for (const r of table.rows || []) { @@ -318,8 +320,8 @@ function paintAdm1(map, geo) { paint: { 'fill-color': adm1Fill(adm1Sex.value), 'fill-opacity': 0.85 } }, before) map.addLayer({ id: 'ci-adm1-line', type: 'line', source: 'ci-adm1-src', paint: { 'line-color': 'rgba(255,255,255,0.8)', 'line-width': 0.6 } }, before) - // India's national band would sit under its states and show through the two with no geometry - // (Mizoram, Nagaland) as if it were their figure. Take India out of the country layer. + // India's national band would sit under its states and show through any state without a + // feature as if it were that state's figure. Take India out of the country layer. if (map.getLayer('ci-fill')) map.setFilter('ci-fill', ['!=', ['get', 'iso3'], 'IND']) map.on('click', 'ci-adm1-fill', (e) => { if (map.getLayer('ci-pg-dots') && map.queryRenderedFeatures(e.point, { layers: ['ci-pg-dots'] }).length) return diff --git a/plugin-designs/cities-internet/scripts/build-adm1-internet.mjs b/plugin-designs/cities-internet/scripts/build-adm1-internet.mjs index 309802b1b..d466e3922 100644 --- a/plugin-designs/cities-internet/scripts/build-adm1-internet.mjs +++ b/plugin-designs/cities-internet/scripts/build-adm1-internet.mjs @@ -6,7 +6,7 @@ * * READS data/internet/nfhs5-internet-by-state.csv India, NFHS-5 2019–21 (see data/internet/README.md) * data/internet/adm1-crosswalk-IND.json source names -> boundary shapeName (strict) - * plugin-designs/my-upg-100-list/data/gb-IND-ADM1.geojson the boundary file the map draws + * data/boundaries/gb-IND-ADM1-full.geojson the boundary file the map draws (all 36) * WRITES data/tables/internet-by-adm1.json served as assets/tables/internet-by-adm1.json * * THE TABLE IS GENERIC ON PURPOSE (other plugins and go-int reuse it). One row per @@ -26,7 +26,7 @@ import { fileURLToPath } from 'node:url' const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '../../..') const CSV = join(ROOT, 'data/internet/nfhs5-internet-by-state.csv') const CROSSWALK = join(ROOT, 'data/internet/adm1-crosswalk-IND.json') -const BOUNDARY = join(ROOT, 'plugin-designs/my-upg-100-list/data/gb-IND-ADM1.geojson') +const BOUNDARY = join(ROOT, 'data/boundaries/gb-IND-ADM1-full.geojson') const OUT = join(ROOT, 'data/tables/internet-by-adm1.json') const fail = (msg) => { console.error('build-adm1-internet: FAIL — ' + msg); process.exit(1) } @@ -62,7 +62,7 @@ for (const r of src) { if (!sex) fail(`unexpected indicator "${r.indicator}"`) const cw = crosswalk[r.state] if (!cw) fail(`"${r.state}" is not in data/internet/adm1-crosswalk-IND.json`) - if (cw.adm1 && !shapeNames.has(cw.adm1)) fail(`crosswalk maps "${r.state}" to "${cw.adm1}", which is not a shapeName in gb-IND-ADM1.geojson`) + if (cw.adm1 && !shapeNames.has(cw.adm1)) fail(`crosswalk maps "${r.state}" to "${cw.adm1}", which is not a shapeName in gb-IND-ADM1-full.geojson`) if (!cw.adm1 && !cw.reason) fail(`crosswalk entry for "${r.state}" has no adm1 and no reason`) for (const [area, col] of Object.entries(AREAS)) { const raw = String(r[col] ?? '').trim() @@ -101,11 +101,11 @@ const out = { }, boundaries: { IND: { - file: 'boundaries/gb-IND-ADM1.geojson', + file: 'boundaries/gb-IND-ADM1-full.geojson', key: 'shapeName', - licence: 'geoBoundaries gbOpen, India ADM1: CC BY 2.5 IN (datameet)', + licence: 'geoBoundaries gbOpen IND-ADM1-1811400 (DataMeet / ECI): CC BY 2.5 IN', missing: [...missing].sort(), - missing_reason: 'no geometry in the shipped boundary file (the UPG-100 partition: 34 of 36 units)', + missing_reason: 'no feature for it in the boundary file', }, }, national,