Read the zone tables from the asset pool, and name zones from their slugs
L62 moved zone-regions.json and groupings.json into data/tables/, so the tree copies them into the asset pool and both plugins read one file. This fetches them rather than importing: a relative import into another plugin's folder is refused, and a per-plugin copy is the drift the single-source move exists to prevent. groupings.label is a definition, not a name, and using it as one would have made the legend unreadable. Measured on the published file, the labels run from 7 to 206 characters and the long ones are the zone's member list — Tibet's names ten provinces and three countries. Exactly one of the fourteen is a plain name. So the tree names a zone from its slug, which is uniform by construction, and the label is carried separately as the definition it actually is, for somewhere with room to say what a zone contains. The tree is built and counted; nothing filters on it yet. Mapping a group to a zone still runs through the older partition, which places 69 groups in the wrong printable zone, and that is the Driver's open question.
This commit is contained in:
parent
48a83929f5
commit
e1d0bc203f
1 changed files with 60 additions and 0 deletions
60
plugin-designs/gospel-internet/src/zoneData.js
Normal file
60
plugin-designs/gospel-internet/src/zoneData.js
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* zoneData.js — fetch the published UPG-100 zone tables and build the legend's tree.
|
||||
*
|
||||
* The tables belong to upg100 and are now published: L62 moved them into data/tables/, so the
|
||||
* tree copies them into the asset pool and both plugins read ONE file. That is why this fetches
|
||||
* rather than imports — a relative import into another plugin's folder is refused by
|
||||
* check:no-cross-plugin-imports, and a per-plugin copy is the drift the single-source move exists
|
||||
* to prevent.
|
||||
*
|
||||
* FETCHED ONCE and shared, like the neighbour table beside it.
|
||||
*
|
||||
* ⚠ THE TREE IS READY; THE FILTER IS NOT. Mapping a GROUP to a zone still runs through
|
||||
* admin-to-list.json, which exp measured as an older partition — 69 groups land in the wrong
|
||||
* printable zone and 436 in Unassigned. That is the Driver's row 87. So this builds and counts
|
||||
* the tree, and the caller must not filter rows on it until the fold lands.
|
||||
*/
|
||||
import { resolveAssetsBase } from '@map/utils/embedBase.js'
|
||||
import { buildZoneTree } from './zoneTree.js'
|
||||
|
||||
let pending = null
|
||||
|
||||
/** { nodes, allZoneIds, definitions } from the published tables. Rejects loudly. */
|
||||
export function loadZoneTree(cfg = {}, counts = {}) {
|
||||
if (!pending) {
|
||||
pending = (async () => {
|
||||
const base = resolveAssetsBase(cfg)
|
||||
const [zr, gr] = await Promise.all([
|
||||
fetch(cfg.zoneRegionsUrl || `${base}/tables/zone-regions.json`).then(okJson),
|
||||
fetch(cfg.groupingsUrl || `${base}/tables/groupings.json`).then(okJson),
|
||||
])
|
||||
// ★ groupings.label IS A DEFINITION, NOT A NAME, and using it as one would make the
|
||||
// legend unreadable. Measured on the published file: the labels run from 7 to 206
|
||||
// characters, and the long ones are the zone's MEMBER LIST — Tibet's reads "Tibet
|
||||
// Autonomous Region + Sichuan Province + Xinjiang Uyghur Autonomous Region + ... +
|
||||
// North Korea". Only one of the fourteen is a plain name.
|
||||
// So the tree's NAME comes from the slug, which is uniform by construction, and the
|
||||
// label is carried separately as the zone's DEFINITION — which is what it actually is,
|
||||
// and useful where there is room to say what a zone contains.
|
||||
const definitions = {}
|
||||
for (const [id, g] of Object.entries(gr || {})) if (g && g.label) definitions[id] = g.label
|
||||
return { zoneRegions: zr || {}, definitions }
|
||||
})()
|
||||
}
|
||||
return pending.then(({ zoneRegions, definitions }) => ({
|
||||
zoneRegions,
|
||||
definitions,
|
||||
// No `labels` passed: buildZoneTree falls back to humanising the slug, which gives every
|
||||
// zone a name of the same shape rather than one name and thirteen member lists.
|
||||
nodes: buildZoneTree(zoneRegions, { counts }),
|
||||
// EVERY zone the data can name, not just the ones filed under a region. The legend renders
|
||||
// the difference as a named bucket; passing only the tree's ids would drop the unfiled ones
|
||||
// with no error and no empty state — just a shorter list.
|
||||
allZoneIds: Object.keys(zoneRegions),
|
||||
}))
|
||||
}
|
||||
|
||||
function okJson(res) {
|
||||
if (!res.ok) throw new Error(`${res.status} ${res.url}`)
|
||||
return res.json()
|
||||
}
|
||||
Loading…
Reference in a new issue