fix(food): affectation plat/garniture par plus proche voisin vertical
Deploy HouseHub / deploy (push) Successful in 1s
Deploy HouseHub / deploy (push) Successful in 1s
La fenêtre à tolérance fixe (+/-20) pour distinguer Plat Chaud et Garniture ratait des lignes selon le nombre de lignes du plat (le débordement du texte au-dessus de son label varie d'une semaine à l'autre). Remplacé par une affectation "rangée la plus proche" pour chaque texte, sur le même principe déjà utilisé pour les colonnes de jour : robuste quelle que soit la hauteur du bloc. Corrige aussi la perte du caractère "œ" (ex: "bœuf" -> "buf") dans le nettoyage du texte, la plage Unicode À-ÿ ne le couvrant pas. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3a64934eb5
commit
bfa70402a9
1 file changed
+17
-27
@@ -87,25 +87,7 @@ class NativePdfParser {
|
||||
}
|
||||
}
|
||||
|
||||
// Tri de haut en bas (Y du PDF est décroissant du haut vers le bas)
|
||||
usort($rowHeaders, fn($a, $b) => $b['y'] <=> $a['y']);
|
||||
|
||||
$yPlatTop = null; $yPlatBot = null;
|
||||
$yGarTop = null; $yGarBot = null;
|
||||
|
||||
for ($i = 0; $i < count($rowHeaders); $i++) {
|
||||
if ($rowHeaders[$i]['label'] === 'PLATCHAUD') {
|
||||
$yPlatTop = $rowHeaders[$i]['y'];
|
||||
// La limite basse est le label suivant, ou -50 unités
|
||||
$yPlatBot = $rowHeaders[$i+1]['y'] ?? ($yPlatTop - 50);
|
||||
}
|
||||
if ($rowHeaders[$i]['label'] === 'GARNITURE') {
|
||||
$yGarTop = $rowHeaders[$i]['y'];
|
||||
$yGarBot = $rowHeaders[$i+1]['y'] ?? ($yGarTop - 50);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$yPlatTop || !$yGarTop) {
|
||||
if (!in_array('PLATCHAUD', array_column($rowHeaders, 'label')) || !in_array('GARNITURE', array_column($rowHeaders, 'label'))) {
|
||||
throw new Exception("Structure du menu non reconnue (Mots-clés 'PLAT CHAUD' et 'GARNITURE' introuvables).");
|
||||
}
|
||||
|
||||
@@ -120,18 +102,26 @@ class NativePdfParser {
|
||||
// Retrait des labels BIO/HVE et mentions superflues
|
||||
$textVal = trim(preg_replace('/\b(AB|HVE|MSC|Label Rouge)\b/i', '', $t['text']));
|
||||
$textVal = str_replace(['(plat', 'complet)'], '', $textVal);
|
||||
$textVal = trim(preg_replace('/[^a-zA-ZÀ-ÿ0-9\s&\-]/u', '', $textVal));
|
||||
$textVal = trim(preg_replace('/[^a-zA-ZÀ-ÿŒœÆæ0-9\s&\-]/u', '', $textVal));
|
||||
|
||||
if (strlen($textVal) < 3) continue;
|
||||
|
||||
// Filtre Vertical : Est-on dans la tranche Plat Chaud ou Garniture ? (Tolérance +/- 5 unités)
|
||||
// Filtre Vertical : de quelle rangée (en-tête) ce texte est-il le plus proche ?
|
||||
// Le texte d'une rangée déborde souvent au-dessus de son propre label (lignes
|
||||
// empilées vers le haut), y compris pour le label de la rangée suivante qui
|
||||
// sert de limite basse : on applique donc la même marge des deux côtés.
|
||||
$inPlat = ($t['y'] <= $yPlatTop + 20 && $t['y'] >= $yPlatBot + 20);
|
||||
$inGar = ($t['y'] <= $yGarTop + 20 && $t['y'] >= $yGarBot + 20);
|
||||
// empilées vers le haut) sur une hauteur variable d'un menu à l'autre : une
|
||||
// fenêtre à tolérance fixe est donc peu fiable. Le plus proche voisin (même
|
||||
// principe que pour les colonnes de jour ci-dessous) s'adapte automatiquement.
|
||||
$bestRow = null;
|
||||
$minRowDiff = PHP_FLOAT_MAX;
|
||||
foreach ($rowHeaders as $rh) {
|
||||
$diff = abs($t['y'] - $rh['y']);
|
||||
if ($diff < $minRowDiff) {
|
||||
$minRowDiff = $diff;
|
||||
$bestRow = $rh['label'];
|
||||
}
|
||||
}
|
||||
|
||||
if ($inPlat || $inGar) {
|
||||
if ($bestRow === 'PLATCHAUD' || $bestRow === 'GARNITURE') {
|
||||
// Filtre Horizontal : Quel est le jour le plus proche ?
|
||||
$bestCol = 0;
|
||||
$minDiff = PHP_FLOAT_MAX;
|
||||
@@ -142,7 +132,7 @@ class NativePdfParser {
|
||||
$bestCol = $idx;
|
||||
}
|
||||
}
|
||||
$days[$bestCol][] = ['text' => $textVal, 'y' => $t['y'], 'type' => $inPlat ? 'plat' : 'gar'];
|
||||
$days[$bestCol][] = ['text' => $textVal, 'y' => $t['y'], 'type' => $bestRow === 'PLATCHAUD' ? 'plat' : 'gar'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user