diff --git a/backend/src/Controller/SpotScoreController.php b/backend/src/Controller/SpotScoreController.php index 70f15ae..2d240f8 100644 --- a/backend/src/Controller/SpotScoreController.php +++ b/backend/src/Controller/SpotScoreController.php @@ -107,7 +107,10 @@ class SpotScoreController extends AbstractController JOIN sargassum_observation o ON o.id = f.source_observation_id WHERE f.source_observation_id = ( SELECT o2.id FROM sargassum_observation o2 - INNER JOIN sargassum_forecast ff ON ff.source_observation_id = o2.id + INNER JOIN sargassum_forecast ff ON ff.source_observation_id = o2.id, + coastal_point cp3 + WHERE cp3.id = :spotId + AND ST_Distance(o2.geometry::geography, cp3.geometry::geography) < 300000 ORDER BY o2.detected_at DESC LIMIT 1 ) ORDER BY f.time_horizon ASC', @@ -226,7 +229,10 @@ class SpotScoreController extends AbstractController FROM sargassum_observation o WHERE o.id = ( SELECT o2.id FROM sargassum_observation o2 - INNER JOIN sargassum_forecast ff ON ff.source_observation_id = o2.id + INNER JOIN sargassum_forecast ff ON ff.source_observation_id = o2.id, + coastal_point cp3 + WHERE cp3.id = :spotId + AND ST_Distance(o2.geometry::geography, cp3.geometry::geography) < 300000 ORDER BY o2.detected_at DESC LIMIT 1 ) ) dump diff --git a/backend/src/Service/Forecast/ImpactScoreService.php b/backend/src/Service/Forecast/ImpactScoreService.php index 783d104..d6c6ee4 100644 --- a/backend/src/Service/Forecast/ImpactScoreService.php +++ b/backend/src/Service/Forecast/ImpactScoreService.php @@ -267,6 +267,25 @@ class ImpactScoreService /** @param array{score: int, level: string, distance: float|null, density: float, trend: string, etaHours: int|null} $data */ private function persistScore(CoastalPoint $spot, array $data): void { + // "L'observation la plus proche gagne" : ne pas écraser un score avec une distance + // plus grande que le score actuel, sauf si celui-ci a plus de 6h (stale). + if ($data['distance'] !== null) { + $current = $this->connection->fetchAssociative( + 'SELECT distance_to_nearest_sargassum AS dist, timestamp + FROM impact_score WHERE coastal_point_id = :id ORDER BY timestamp DESC LIMIT 1', + ['id' => (string) $spot->getId()] + ); + if ($current !== false && $current['dist'] !== null) { + $ageSeconds = (new \DateTimeImmutable())->getTimestamp() + - (new \DateTimeImmutable($current['timestamp']))->getTimestamp(); + $isStale = $ageSeconds > 21_600; // 6h + $isCloser = $data['distance'] < (float) $current['dist']; + if (!$isStale && !$isCloser) { + return; // garder le score de l'observation plus proche + } + } + } + $s = new ImpactScore(); $s->setCoastalPoint($spot); $s->setScore($data['score']);