Posters drawn at the click use the SPARSE layout, like their stored thumbnails

The bold header on a poster -- the UPG count and population set large, a
bigger map, and no "Jesus' Strategy to Feed the 5000" / "What is a Prayer List"
columns -- is the SPARSE layout, the "thumbnail-worthy" design. The `posters`
script generates with SPARSE=1, so every stored thumbnail has it. But the env
handed to the generator in the browser carried only FORMAT and POSTER_DATE, so
EVERY sheet drawn at the click -- UPG-100 and country alike -- fell back to the
dense layout.

MEASURED on FINAL (two UPG-100 zones, Northwest and South-Central India): the
thumbnail shows the SPARSE header; the print the reader actually gets shows the
small facts table, both vision columns and a smaller map. That is the reported
"the country poster looks worse than the UPG-100 poster" -- the comparison was a
SPARSE thumbnail against a dense sheet.

(a) posterSheets.js passes SPARSE for every POSTER format and NOT for 'packet'.
    That is exactly the split the two build scripts make: `posters` sets
    SPARSE=1, `packets` does not. The renderer's formats are 3x4, 3x3, letter and
    packet, so 'packet' alone keeps the full layout its pages were built around.

(b) check:poster-browser-equiv's poster case now runs the Node side with
    SPARSE=1 as well. It used to compare dense with dense, so it passed while no
    reader ever saw that layout on a card. The packet case stays dense on both
    sides. PASS: country-npl 909026 bytes on each; asia-india-gujarat (packet)
    835047 on each.

The stored UPG-100 thumbnails are untouched by this. What changes is the PRINT,
which now matches them.
This commit is contained in:
Doxa Maps 2026-09-30 02:53:15 +00:00
parent 948012a003
commit 16dca4d266
2 changed files with 16 additions and 2 deletions

View file

@ -121,7 +121,13 @@ const results = []
const series = { totalGroups: tier.reduce((a, x) => a + (x.count || 0), 0), totalLists: tier.length, index: tier.indexOf(c) + 1 }
results.push({ what: `${c.id} (3x3 poster, generateCountrySheet)`,
browser: await generateCountrySheet({ country: c, records: recs, assetsBase, ISO3_NAME, format: '3x3', series, date: DATE }),
node: nodeSheet({ COUNTRIES: '1', FORMAT: '3x3', SHEET: '3x3', ONLY: c.id }, `${c.id}.html`) })
// SPARSE on the Node side because a POSTER is generated with SPARSE=1 -- that is how the `posters`
// script builds every stored thumbnail, and how the browser now draws a poster at the click. This
// gate used to compare the dense layout with the dense layout, so it passed while every stored
// thumbnail showed the SPARSE header and every print showed the dense one: a check that agreed
// with itself and with nothing a reader saw. The packet case above stays dense on both sides,
// because packet pages are built without SPARSE.
node: nodeSheet({ COUNTRIES: '1', FORMAT: '3x3', SHEET: '3x3', SPARSE: '1', ONLY: c.id }, `${c.id}.html`) })
}
for (const r of results) {

View file

@ -130,7 +130,15 @@ export async function generateSheet({
// pinned the FIRST caller's data — its boundaries, its name table — onto every later sheet: a caller
// without adm0 poisoned the cache for one with it. The inputs are the caller's, every time.
const gen = createPosterGenerator({
env: { FORMAT: format, ...(date ? { POSTER_DATE: date } : {}) },
// ★ SPARSE FOR POSTERS, NEVER FOR THE PACKET -- exactly the split the two build scripts make.
// `posters` generates with SPARSE=1 (the "thumbnail-worthy" layout: the bold facts row with the
// UPG count and population set large, a bigger map, and the two vision columns dropped), and
// `packets` does not. This env used to carry FORMAT and POSTER_DATE only, so EVERY sheet drawn
// at the click -- UPG-100 and country alike -- fell back to the small facts table, while the
// stored UPG-100 thumbnails showed the bold row. A reader saw one header on the card and got
// another on the print. 'packet' is the one packet format (FORMATS: 3x4, 3x3, letter, packet),
// so it alone keeps the full layout its packet pages were designed around.
env: { FORMAT: format, ...(format !== 'packet' ? { SPARSE: '1' } : {}), ...(date ? { POSTER_DATE: date } : {}) },
SERIES_DEF, ISO3_NAME, adm0, adm1Ind, adm1Chn, nePlaces: places, series: { totalGroups: 0, totalLists: 0, index: 1, ...series },
})
const fc = zoneFC || { type: 'FeatureCollection', features: [] }