Backend: Add spatial overlap check (>=50% horizontal IoU) to Kombi merge
so words at the same position are deduplicated even when OCR text differs.
Frontend: Add yPct/hPct to WordPosition so each word renders at its actual
vertical position instead of all words collapsing to the cell center Y.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Zwei wesentliche Verbesserungen:
1. Multi-group: Gruppen werden per Best-Fit-Breite den Clustern
zugeordnet statt naiv links-nach-rechts. Damit wird z.B.
"Kokosnuss" dem DE-Spalten-Cluster zugeordnet statt dem
breiteren Box-Cluster.
2. Single-group Fallback: verwendet den BREITESTEN Cluster statt
first-to-last Span. Verhindert dass Streupixel von benachbarten
Seitenbereichen den Text nach links ziehen.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Box-Rahmen werden vom OCR als einzelne Symbole wie "|" oder ">"
erkannt und als eigene Text-Gruppen behandelt. Das verfaelscht die
Cluster-Zuordnung weil diese Artefakte entweder keinen eigenen
Cluster erzeugen oder den falschen Cluster zugewiesen bekommen.
Fix: Gruppen mit max 2 Zeichen ohne Buchstaben/Ziffern werden mit
der benachbarten Gruppe zusammengefuehrt bevor die Cluster-Zuordnung
laeuft.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Wenn mehr Pixel-Cluster als Text-Gruppen existieren (z.B. wegen
Box-Rahmenlinien), werden jetzt die N breitesten Cluster ausgewaehlt
statt naiv clusters[i]→groups[i] zuzuordnen. Text-Cluster sind
breiter als Rahmenlinien-Cluster.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Vorher: wenn Text mehr Wort-Gruppen hatte als Pixel-Cluster gefunden
wurden (z.B. bei Box-Rahmen die Cluster zusammenmergen), wurde die
Zelle komplett uebersprungen → Fallback bei x=0%.
Jetzt: Fallback auf Single-Span Positionierung (first→last Cluster)
statt Skip. Damit wird der Text immer korrekt horizontal platziert.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1. Schriftgroesse basiert jetzt auf Median-Zeilenhoehe statt
individueller Zellhoehe — keine Groessensprunge in Box-Bereichen
2. Sehr schmale Pixel-Cluster (< 0.5% Zellbreite) werden gefiltert,
damit Box-Rahmen nicht als Textposition erkannt werden
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>