// reprojeta-meta-mapa.mjs — reescreve SÓ o `meta` de cada item do // web/atlas/atlas-map.json a partir do pipeline/catalogo.jsonl, sem re-renderizar // os atlas .webp (posições, cores e recortes das peças ficam intactos). // // Use quando as regras de metadados do web/build-atlas.js mudarem e não valer a // pena reconstruir 47 MB de imagem. As regras aqui têm de espelhar as de // summarize()/pickAll() lá — em 2026-09-12 as duas foram escritas juntas. // // node pipeline/reprojeta-meta-mapa.mjs (da raiz do projeto) import fs from 'node:fs'; import readline from 'node:readline'; const MAP = 'web/atlas/atlas-map.json'; const pickAll = (item, field, noUrls) => { const out = []; for (const row of item.full_table || []) { if (row.field !== field) continue; const v = String(row.value ?? '').trim(); if (!v || out.includes(v)) continue; if (noUrls && /^https?:\/\//i.test(v)) continue; out.push(v); } return out; }; const some = (i, f, noUrls) => { const v = pickAll(i, f, noUrls); return v.length ? v : undefined; }; const one = (i, f) => pickAll(i, f)[0] || undefined; const d = JSON.parse(fs.readFileSync(MAP, 'utf8')); const wanted = new Set(Object.keys(d.map)); const extra = new Map(); const rl = readline.createInterface({ input: fs.createReadStream('pipeline/catalogo.jsonl'), crlfDelay: Infinity }); for await (const line of rl) { if (!line.trim()) continue; const o = JSON.parse(line); if (!wanted.has(o.handle)) continue; extra.set(o.handle, { subject: some(o, 'dc.subject'), description: some(o, 'dc.description'), coverage: some(o, 'dc.coverage'), source: one(o, 'dc.source'), publisher: one(o, 'dc.publisher'), relation: some(o, 'dc.relation', true), identifier: some(o, 'dc.identifier', true), }); } let enriched = 0, missing = 0; for (const [h, e] of Object.entries(d.map)) { const add = extra.get(h); if (!add) { missing++; continue; } let touched = false; for (const [k, v] of Object.entries(add)) if (v !== undefined) { e.meta[k] = v; touched = true; } // deriváveis da chave: não repetir (ver build-atlas.js) delete e.meta.handle; delete e.meta.source_url; if (touched) enriched++; } const out = JSON.stringify(d); fs.writeFileSync(MAP, out); console.log(`itens: ${wanted.size} | enriquecidos: ${enriched} | sem registro: ${missing}`); console.log(`atlas-map.json: ${(out.length / 1048576).toFixed(2)} MB`);