UPG Neighbor: the ring is a column on every row, with rop3 so other plugins can join their groups to it
This commit is contained in:
parent
d679430a5c
commit
266ddef381
3 changed files with 13 additions and 12 deletions
File diff suppressed because one or more lines are too long
|
|
@ -90,7 +90,7 @@ const groups = src.map((r, i) => {
|
|||
if (!Number.isFinite(lat) || !Number.isFinite(lng)) fail(`no coordinates for ${r.PGID}`)
|
||||
const pop = Number(r.Population) || 0
|
||||
return {
|
||||
i, pgid: r.PGID, name: r.DisplayName || r.Name, iso3: r.ISOAlpha3, country: r.CountryDisplayName || r.CountryName,
|
||||
i, pgid: r.PGID, rop3: r.ROP3Code, name: r.DisplayName || r.Name, iso3: r.ISOAlpha3, country: r.CountryDisplayName || r.CountryName,
|
||||
lat, lng, pop, reached: band[0], evPct: band[1], believers: band[0] ? Math.round(pop * band[1] / 100) : 0,
|
||||
lang: (r.LanguageCode || '').trim(), langName: r.LanguageName || '', family: (r.LanguageFamily || '').trim(),
|
||||
ethne: r.ROP25Code, cluster: r.ROP2Code, clusterName: r.ROP2Name, bloc: r.ROP1Code, blocName: r.ROP1Name,
|
||||
|
|
@ -189,7 +189,10 @@ const ringCount = ringCounts(unreached, (u) => ringOfU.get(u.i)?.[0])
|
|||
const shipped = groups.filter((g) => !g.reached || used.has(g.i))
|
||||
const newIdx = new Map(shipped.map((g, j) => [g.i, j]))
|
||||
const COLS = ['pgid', 'name', 'iso3', 'country', 'lat', 'lng', 'pop', 'reached', 'evPct', 'believers', 'lang', 'langName',
|
||||
'family', 'ethne', 'cluster', 'clusterName', 'bloc', 'blocName', 'religion', 'engaged', 'bible', 'film', 'audio', 'radio']
|
||||
'family', 'ethne', 'cluster', 'clusterName', 'bloc', 'blocName', 'religion', 'engaged', 'bible', 'film', 'audio', 'radio',
|
||||
// rop3 + iso3 is the join key other plugins hold (DX groups: rop3 + country). ring = centered-set ring 1-10
|
||||
// (0 = reached or no relation); ringNb = the shipped row of the reached group that sets it (-1 = none).
|
||||
'rop3', 'ring', 'ringNb']
|
||||
// Repeated strings are dictionary-encoded (the value in the row is an index into dict[col]); this
|
||||
// halves the file. A reader decodes with dict[col][row[j]].
|
||||
const DICT_COLS = ['iso3', 'country', 'lang', 'langName', 'family', 'cluster', 'clusterName', 'bloc', 'blocName', 'religion']
|
||||
|
|
@ -197,6 +200,9 @@ const dict = Object.fromEntries(DICT_COLS.map((c) => [c, []]))
|
|||
const dictIdx = Object.fromEntries(DICT_COLS.map((c) => [c, new Map()]))
|
||||
const enc = (c, v) => { const m = dictIdx[c]; if (!m.has(v)) { m.set(v, dict[c].length); dict[c].push(v) } return m.get(v) }
|
||||
const rows = shipped.map((g) => COLS.map((c) => {
|
||||
const rg = ringOfU.get(g.i)
|
||||
if (c === 'ring') return rg ? rg[0] : 0
|
||||
if (c === 'ringNb') return rg ? newIdx.get(rg[1]) : -1
|
||||
const v = g[c]
|
||||
if (DICT_COLS.includes(c)) return enc(c, v)
|
||||
if (typeof v === 'boolean') return v ? 1 : 0
|
||||
|
|
@ -206,9 +212,6 @@ const rows = shipped.map((g) => COLS.map((c) => {
|
|||
const outLinks = {}
|
||||
for (const [ui, ls] of Object.entries(links)) outLinks[newIdx.get(+ui)] = ls.map(([ri, e, d, same]) => [newIdx.get(ri), e, d, same])
|
||||
|
||||
const outRings = {}
|
||||
for (const [ui, [ring, ri]] of ringOfU) outRings[newIdx.get(ui)] = [ring, newIdx.get(ri)]
|
||||
|
||||
const outBridges = bridges.map((b) => ({
|
||||
lang: b.lang, believers: b.believers, unreachedPop: b.unreachedPop, res: b.res,
|
||||
reached: b.rs.map((g) => newIdx.get(g.i)), unreached: b.us.map((g) => newIdx.get(g.i)),
|
||||
|
|
@ -224,7 +227,7 @@ const out = {
|
|||
e2: 'different language, same ROP2 people cluster, or same LanguageFamily within the same ROP1 affinity bloc',
|
||||
e3: `none of the above, within ${NEAR_KM} km or in the same country`,
|
||||
p: 'P-level of an unreached group = the smallest E-level any reached neighbor reaches it at',
|
||||
rings: 'rings[u] = [ring, reachedRow]. 1-3 same LanguageCode, 4-6 same LanguageName root (text before the comma), 7-9 same LanguageFamily, each x culture same ROP25 / near ROP2 / different; 10 = same country or within 600 km. Closest = lowest ring, then believers / (1 + (km/500)^2). Rule: src/rings.js',
|
||||
rings: 'columns ring + ringNb on every row (ring 0 = reached or none; ringNb -1 = none). 1-3 same LanguageCode, 4-6 same LanguageName root (text before the comma), 7-9 same LanguageFamily, each x culture same ROP25 / near ROP2 / different; 10 = same country or within 600 km. Closest = lowest ring, then believers / (1 + (km/500)^2). Rule: src/rings.js',
|
||||
kept: KEEP, rank: `inside one E-level: stronger match kind first (E-2: people cluster before language family), then estimated believers / (1 + (km/${HALF_KM})^2)`,
|
||||
},
|
||||
believersEst: 'Population x midpoint of the evangelical band: an order of magnitude for sizing an audience, not a count',
|
||||
|
|
@ -242,7 +245,6 @@ const out = {
|
|||
rows,
|
||||
links: outLinks,
|
||||
bridges: outBridges,
|
||||
rings: outRings,
|
||||
}
|
||||
writeFileSync(OUT, JSON.stringify(out) + '\n')
|
||||
const bytes = Buffer.byteLength(JSON.stringify(out))
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export function loadNearData(profileConfig) {
|
|||
}
|
||||
|
||||
function decode(raw) {
|
||||
const { cols, dict, rows, links, bridges, meta, rings = {} } = raw
|
||||
const { cols, dict, rows, links, bridges, meta } = raw
|
||||
const groups = rows.map((r, i) => {
|
||||
const g = { i }
|
||||
cols.forEach((c, j) => { g[c] = dict[c] ? dict[c][r[j]] : r[j] })
|
||||
|
|
@ -39,9 +39,8 @@ function decode(raw) {
|
|||
const unreached = groups.filter((g) => !g.reached)
|
||||
for (const u of unreached) {
|
||||
u.p = pLevel(u)
|
||||
const rg = rings[u.i] // centered-set ring (src/rings.js): 1-10, 0 = none; ringNeighbor = the reached group that sets it
|
||||
u.ring = rg ? rg[0] : 0
|
||||
u.ringNeighbor = rg ? groups[rg[1]] : null
|
||||
// centered-set ring (src/rings.js): u.ring 1-10 arrives as a column (0 = none); ringNeighbor = the reached group that sets it
|
||||
u.ringNeighbor = u.ringNb >= 0 ? groups[u.ringNb] : null
|
||||
}
|
||||
const bridgeList = bridges.map((b) => {
|
||||
const rs = b.reached.map((i) => groups[i]), us = b.unreached.map((i) => groups[i])
|
||||
|
|
|
|||
Loading…
Reference in a new issue