doxa-maps/library/scripts/people-groups/build-points.mjs
Doxa Maps bfc99ff827 library/ keeps the reason and drops the speaker: no comment quotes or cites the Driver
Every reference to the Driver in library/ is reworded: the engineering reason
stays, the speaker and the quote go, and a decision still open reads
"provisional, pending a product decision". Comments only: each changed file
is identical after stripping comments (JavaScript, template and CSS, including
CSS comments inside the style strings shadow-DOM components inject).

Those style-string comments do ship, so several bundles change by exactly
those comment bytes.
2026-09-29 05:26:25 +00:00

55 lines
2.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env node
/**
* build-points.mjs — the COMPACT point file All People Groups renders from.
*
* node library/scripts/people-groups/build-points.mjs
* reads data/people-groups/people-groups-slim.json (12,379 rows × 22 keys, ~7.5 MB)
* writes data/people-groups/people-groups-points.json (only the 10 fields the map uses)
*
* WHY. The map downloaded and parsed the whole slim file — every column, as one object per row — to
* draw ten fields. That, plus waiting on the live prayer API before drawing anything, is most of why
* the map seemed not to load at all, or took a very long time. This file keeps the same rows and
* values in column order, with the repetitive strings (country, religion, evangelical level,
* language) stored once in dictionaries and referenced by index, and coordinates at 3 decimals
* (~100 m, far below a pin's size at any zoom this map shows).
*
* Deterministic: same input, byte-identical output. Re-run after refreshing the slim file.
*/
import { readFileSync, writeFileSync } from 'node:fs'
import { resolve, dirname } from 'node:path'
import { fileURLToPath } from 'node:url'
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '../../..')
const SRC = resolve(ROOT, 'data/people-groups/people-groups-slim.json')
const OUT = resolve(ROOT, 'data/people-groups/people-groups-points.json')
const slim = JSON.parse(readFileSync(SRC, 'utf8'))
const dicts = { country: [], religion: [], evangelical: [], language: [] }
const idx = { country: new Map(), religion: new Map(), evangelical: new Map(), language: new Map() }
const ref = (k, v) => { const s = String(v || ''); let i = idx[k].get(s); if (i === undefined) { i = dicts[k].length; dicts[k].push(s); idx[k].set(s, i) } return i }
const r3 = (x) => Math.round(Number(x) * 1000) / 1000
const rows = []
for (const r of slim.rows || []) {
const lat = Number(r.Lat), lng = Number(r.Long)
if (!Number.isFinite(lat) || !Number.isFinite(lng) || (lat === 0 && lng === 0)) continue
rows.push([
r3(lng), r3(lat),
r.GSEC === '' || r.GSEC == null ? null : Number(r.GSEC),
String(r.ROP3Code || ''),
String(r.Name || ''),
ref('country', r.CountryName),
Number(r.Population) || 0,
ref('language', r.LanguageName),
ref('religion', r.ReligionName),
ref('evangelical', r.EvangelicalLevel),
])
}
const out = {
meta: { ...(slim.meta || {}), derivedFrom: 'people-groups-slim.json via library/scripts/people-groups/build-points.mjs', rows: rows.length },
cols: ['lng', 'lat', 'gsec', 'rop3', 'name', 'country', 'population', 'language', 'religion', 'evangelical'],
dicts,
rows,
}
writeFileSync(OUT, JSON.stringify(out))
console.log(`people-groups-points.json: ${rows.length} rows, ${(JSON.stringify(out).length / 1e6).toFixed(2)} MB`)