diff --git a/backend/src/Controller/ForecastController.php b/backend/src/Controller/ForecastController.php new file mode 100644 index 0000000..faa55aa --- /dev/null +++ b/backend/src/Controller/ForecastController.php @@ -0,0 +1,95 @@ +query->get('bbox'); + if ($bboxParam !== null) { + $parts = array_map('floatval', explode(',', $bboxParam)); + if (count($parts) === 4) { + [$minLon, $minLat, $maxLon, $maxLat] = $parts; + $sql .= ' AND ST_Intersects(f.geometry, ST_MakeEnvelope(:minLon, :minLat, :maxLon, :maxLat, 4326))'; + $params['minLon'] = $minLon; + $params['minLat'] = $minLat; + $params['maxLon'] = $maxLon; + $params['maxLat'] = $maxLat; + } + } + + $horizonParam = $request->query->get('horizon'); + if ($horizonParam !== null && in_array((int) $horizonParam, [6, 12, 24, 48], true)) { + $sql .= ' AND f.time_horizon = :horizon'; + $params['horizon'] = (int) $horizonParam; + } + + $sql .= ' ORDER BY f.valid_at DESC LIMIT 50'; + + $rows = $this->connection->fetchAllAssociative($sql, $params); + + foreach ($rows as &$row) { + $row['geometry'] = $row['geometry'] ? json_decode($row['geometry'], true) : null; + } + + return $this->json(['items' => $rows, 'total' => count($rows)]); + } + + /** + * GET /api/forecasts/{id} + */ + #[Route('/{id}', name: 'item', methods: ['GET'])] + public function item(string $id): JsonResponse + { + $row = $this->connection->fetchAssociative( + 'SELECT f.id, f.time_horizon AS "timeHorizon", f.valid_at AS "validAt", + f.computed_at AS "computedAt", f.model_version AS "modelVersion", + f.confidence, f.source_observation_id AS "sourceObservationId", + ST_AsGeoJSON(f.geometry)::json AS geometry + FROM sargassum_forecast f WHERE f.id = :id', + ['id' => $id] + ); + + if ($row === false) { + return $this->json(['error' => 'Forecast not found'], 404); + } + + $row['geometry'] = $row['geometry'] ? json_decode($row['geometry'], true) : null; + + return $this->json($row); + } +} diff --git a/backend/src/Entity/SargassumForecast.php b/backend/src/Entity/SargassumForecast.php index 2fd16f0..7bf6971 100644 --- a/backend/src/Entity/SargassumForecast.php +++ b/backend/src/Entity/SargassumForecast.php @@ -2,9 +2,6 @@ namespace App\Entity; -use ApiPlatform\Metadata\ApiResource; -use ApiPlatform\Metadata\Get; -use ApiPlatform\Metadata\GetCollection; use App\Repository\SargassumForecastRepository; use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Types\UuidType; @@ -13,13 +10,7 @@ use Symfony\Component\Uid\Uuid; #[ORM\Entity(repositoryClass: SargassumForecastRepository::class)] #[ORM\Index(columns: ['valid_at'], name: 'idx_forecast_valid_at')] #[ORM\Index(columns: ['time_horizon'], name: 'idx_forecast_horizon')] -#[ApiResource( - shortName: 'Forecast', - operations: [ - new GetCollection(), - new Get(), - ] -)] +// Routes gérées par ForecastController (filtres bbox + horizon) class SargassumForecast { #[ORM\Id]