/** * Listet alle Fuellfarben des Plans mit Flaeche, Anzahl Polygone und den * naechstgelegenen Beschriftungen - Grundlage fuer die Farb-zu-Material-Zuordnung. * * Aufruf: node tools/inspect-colors.mjs [minFlaeche] */ import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const data = JSON.parse(fs.readFileSync(path.join(__dirname, 'out', 'plan-raw.json'), 'utf8')); const MIN = parseFloat(process.argv[2] ?? '0.15'); const centroid = (pts) => { let x = 0, z = 0; for (const p of pts) { x += p[0]; z += p[1]; } return [x / pts.length, z / pts.length]; }; const groups = new Map(); for (const s of data.shapes) { if (s.op !== 'f') continue; const g = groups.get(s.hex) ?? { hex: s.hex, n: 0, area: 0, big: [], circles: 0 }; g.n++; g.area += s.area; if (s.circle) g.circles++; if (s.area >= MIN) g.big.push(s); groups.set(s.hex, g); } const rows = [...groups.values()].sort((a, b) => b.area - a.area); for (const g of rows) { if (g.area < 0.2 && g.circles === 0) continue; const near = new Set(); for (const s of g.big.slice(0, 6)) { const [cx, cz] = centroid(s.pts); const cands = data.labels .map((l) => ({ l, d: Math.hypot(l.x - cx, l.z - cz) })) .filter((c) => c.d < 3.5 && !/^-?\d\.\d{2}$/.test(c.l.text)) .sort((a, b) => a.d - b.d) .slice(0, 3); for (const c of cands) near.add(c.l.text); } console.log( g.hex.padEnd(9), ('n=' + g.n).padEnd(7), (g.area.toFixed(1) + ' m2').padStart(9), ('gross=' + g.big.length).padEnd(10), ('kreise=' + g.circles).padEnd(11), [...near].slice(0, 7).join(' / '), ); }