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)
|
if (!in_array('PLATCHAUD', array_column($rowHeaders, 'label')) || !in_array('GARNITURE', array_column($rowHeaders, 'label'))) {
|
||||||
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) {
|
|
||||||
throw new Exception("Structure du menu non reconnue (Mots-clés 'PLAT CHAUD' et 'GARNITURE' introuvables).");
|
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
|
// Retrait des labels BIO/HVE et mentions superflues
|
||||||
$textVal = trim(preg_replace('/\b(AB|HVE|MSC|Label Rouge)\b/i', '', $t['text']));
|
$textVal = trim(preg_replace('/\b(AB|HVE|MSC|Label Rouge)\b/i', '', $t['text']));
|
||||||
$textVal = str_replace(['(plat', 'complet)'], '', $textVal);
|
$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;
|
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
|
// 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
|
// empilées vers le haut) sur une hauteur variable d'un menu à l'autre : une
|
||||||
// sert de limite basse : on applique donc la même marge des deux côtés.
|
// fenêtre à tolérance fixe est donc peu fiable. Le plus proche voisin (même
|
||||||
$inPlat = ($t['y'] <= $yPlatTop + 20 && $t['y'] >= $yPlatBot + 20);
|
// principe que pour les colonnes de jour ci-dessous) s'adapte automatiquement.
|
||||||
$inGar = ($t['y'] <= $yGarTop + 20 && $t['y'] >= $yGarBot + 20);
|
$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 ?
|
// Filtre Horizontal : Quel est le jour le plus proche ?
|
||||||
$bestCol = 0;
|
$bestCol = 0;
|
||||||
$minDiff = PHP_FLOAT_MAX;
|
$minDiff = PHP_FLOAT_MAX;
|
||||||
@@ -142,7 +132,7 @@ class NativePdfParser {
|
|||||||
$bestCol = $idx;
|
$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