src/Controller/MeteoController.php line 586

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Service\MeteoFranceService;
  4. use App\DTO\StationMeteoDTO;
  5. use App\Form\StationMeteoType
  6. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  7. use Symfony\Component\HttpFoundation\JsonResponse;
  8. use Symfony\Component\HttpFoundation\Response;
  9. use Symfony\Component\Routing\Annotation\Route;
  10. use Doctrine\ORM\EntityManagerInterface;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use App\Entity\Pluviometrie;
  13. use App\Entity\StationsMeteo;
  14. set_time_limit(36000);
  15. class MeteoController extends AbstractController {
  16. //    private HttpClientInterface $client;
  17. //    private CacheInterface $cache;
  18. //    private string $apiKey;
  19. //    private string $tokenUrl;
  20. //    private string $apiUrl;
  21.     
  22.     public function __construct(private MeteoFranceService $meteoServiceStationMeteoType $stationMeteoType){//, HttpClientInterface $client, CacheInterface $cache, string $apiKey, string $meteoFranceTokenUrl, string $meteoFranceApiUrl) {
  23.         $this->stationMeteoType $stationMeteoType;
  24.     }
  25.     #[Route(path'/meteo/stations/tous'name'meteo_stations_tous')]
  26.     public function getAllStationsData(EntityManagerInterface $em\App\Repository\PluvioDatabaseRepository $pluvioRepo,
  27.             Request $req): Response {
  28.         // Liste des départements (exemple de 5 départements, tu peux en ajouter plus)
  29.         $departements = ['974','976','984''985','986','987','988'];
  30.             //'17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32',
  31.             //'33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57',
  32.             //'58','59','60','61','62','63','64','65','66','67','68','69','70','71','72','73','74','75','76','77','78','79','80','81','82',
  33.             //'83','84','85','86','87','88','89','90','91','92','93','94','95','971','972','973',
  34.          //,   ,
  35.             //'11','12','13','14','15','16',
  36.            // '01','02']; '05','06','07','08','09','10'// Remplace par la liste complète des départements
  37.         
  38.         //[
  39.             //'75','92', '69','91','13','31','44',           
  40.             //'33'//,'35','51','06','67','38','73','63','76',
  41.              //    '26','53','45','59','16','84','79','2A','37','64','34','85','49','74','29','56','95','14','25','10',
  42.              //    '86','42','77','87','54','71','39','50','60','17','22','72','41','83','90','28','52','12','05','89',
  43.              //    '18','01','04','19','40','48','47','88','57','03','30','27','46','08','58','65','15','81','36','2B',
  44.              // '66','62','82','43','61','02','24','55','11','32','07','70','09','23'
  45.             //'78'//'93'//,'93',,  '21'// 
  46.           //  ];
  47.         
  48.         
  49.         $stationsData = [];
  50.         $commandeArray = []; // Initialisation pour éviter l'erreur Undefined variable
  51.         $columnDataArray = []; // Initialisation pour stocker les données des colonnes
  52.         // Boucle pour récupérer les données pour chaque département
  53. //        foreach ($departements as $departement) {
  54. //            try {
  55. //                $stations = $this->meteoService->getStationsByDepartment($departement);
  56. //
  57. //                // Ajouter le numéro du département à chaque station
  58. //                foreach ($stations as &$station) {
  59. //                    $station['departement'] = $departement;
  60. //                }
  61. //
  62. //                $stationsData[$departement] = $stations;
  63. //            } catch (\Exception $e) {
  64. //                $stationsData[$departement] = ['error' => $e->getMessage()];
  65. //            }
  66. //            
  67. //                // Pause pour respecter la limite de 50 requêtes par minute
  68. //               usleep(1300000); // 1,2 secondes = 1 200 000 microsecondes
  69. //            
  70. //        }
  71. //
  72. //        dump($stationsData);
  73. //
  74. //        foreach ($stationsData as $listeStationsDdepartement) {
  75.             
  76.             //$listeStationsDdepartement = $em->getRepository(StationsMeteo::class)->findAll();
  77.             $listeStationsDdepartement $em->getRepository(StationsMeteo::class)
  78.     ->createQueryBuilder('s')
  79.     ->where('s.departement > :min')
  80.     ->andWhere('s.departement < :max')
  81.     ->setParameter('min'39)
  82.     ->setParameter('max'41)
  83.     ->getQuery()
  84.     ->getResult();
  85.             // Pour chaque station, on réalise une commande
  86.             foreach ($listeStationsDdepartement as $station) {
  87.                 dump($station);
  88.             //    if ($station['typePoste'] < 2) {
  89.                     $stationId $station->getIdStation();
  90.                      dump($stationId);
  91.                     $AnneesEtudiees = [];
  92.                     foreach (range(20202024) as $annee) {
  93.                         $AnneesEtudiees[$annee] = [
  94.                             'dateDeb' => "{$annee}-01-01T00%3A00%3A00Z",
  95.                             'dateFin' => "{$annee}-12-31T00%3A00%3A00Z",
  96.                         ];
  97.                     }
  98.                     foreach ($AnneesEtudiees as $annee => $AnneeEtudiee) {
  99.                         //check si déjà commandé ?
  100.                         $dejaCommandee null;
  101.                         $stationEntity $em->getRepository(StationsMeteo::class)->findOneBy(['IdStation' => $stationId]);
  102.                         if ($stationEntity) {
  103.                             $dejaCommandee $em->getRepository(Pluviometrie::class)->findOneBy([
  104.                                 'idStation' => $stationEntity,
  105.                                 'annee' => $annee
  106.                             ]);
  107.                         }
  108.                         if (!$dejaCommandee) {
  109.                             $commande $this->meteoService->getStationData($stationId$AnneeEtudiee);
  110.                             $commandeArray[$stationId][$annee] = $commande;
  111.                             // Pause pour respecter la limite de 50 requêtes par minute
  112.                             usleep(1300000); // 1,2 secondes = 1 200 000 microsecondes
  113.                         }
  114.                     }
  115.                     //$nomDesStations[] = $station['nom'];
  116.                     $stationDB $em->getRepository(StationsMeteo::class)->findOneBy(['IdStation' => $stationId]);
  117.                     if (!$stationDB) {
  118.                         // Si la station n'existe pas, alors crée-la
  119.                         //saisie dans la bdd
  120.                         $stationDB = new \App\Entity\StationsMeteo();
  121.                         $stationDB->setNomStation($station['nom']);
  122.                         $stationDB->setTypeStation($station['typePoste']);
  123.                         $stationDB->setDepartement($station['departement']);
  124.                         $stationDB->setIdStation($station['id']);
  125.                         dump($stationDB);
  126.                         $em->persist($stationDB);
  127.                         $em->flush();
  128.                     }
  129.             //    }
  130.             }
  131.        // }
  132.         dump($commandeArray);
  133.         $erreur500 null;
  134.         $extractedData null;
  135.         // Récupération des fichiers à partir des commandes
  136.         foreach ($commandeArray as $stationId => $anneesData) {
  137.             dump($anneesData);
  138.             $erreur null;
  139.             
  140.             foreach ($anneesData as $AnneeEtudiee => $commandeAnnee) {
  141.                 $commandeId $commandeAnnee['elaboreProduitAvecDemandeResponse']['return'];
  142.                 dump($commandeId);
  143.                 $csvString $this->meteoService->getFichier($commandeId);
  144.                 // Pause pour respecter la limite de 50 requêtes par minute
  145.                 usleep(1300000); // 1,2 secondes = 1 200 000 microsecondes  
  146.                 
  147.                 if ($csvString == 'Erreur 500'){
  148.                     $erreur500[$commandeId] = $stationId;                    
  149.                     $erreur 1;
  150.                 } else {
  151.                                    // Diviser la chaîne en lignes
  152.                     $lines explode("\n"$csvString);
  153.                     // Tableau pour stocker les données extraites
  154.                     $extractedData = [];
  155.                     foreach ($lines as $index => $line) {
  156.                         // Ignorer la première ligne (en-tête)
  157.                         if ($index === 0) {
  158.                             continue;
  159.                         }
  160.                         // Diviser chaque ligne en colonnes par le séparateur ;
  161.                         $columns explode(";"$line);
  162.                         // Vérifier qu'il y a suffisamment de colonnes
  163.                         if (count($columns) > 2) {
  164.                             // Extraire ce qui se situe entre le 3ème et 4ème point-virgule
  165.                             $data $columns[2]; // Récupère la valeur de l'élément à l'index 2 (entre 3ème et 4ème point-virgule)
  166.                             // Remplacer les virgules par des points
  167.                             $data str_replace(",""."$data);
  168.                             $extractedData[] = $data;
  169.                         }
  170.                     }
  171.                     // Création de l'entité Pluviometrie
  172.                     $entity = new \App\Entity\Pluviometrie();
  173.                     $entity->setRainData($extractedData);
  174.                     dump($stationId);
  175.                     // Vérifie si tu récupères bien l'entité StationsMeteo avant de l'assigner
  176.                     $station $em->getRepository(StationsMeteo::class)->findOneBy(['IdStation' => $stationId]);
  177.                     if ($station) {
  178.                         $entity->setIdStation($station); // Assigner l'entité StationMeteo
  179.                     } else {
  180.                         // Gérer le cas où la station n'existe pas
  181.                         throw new \Exception("Station not found");
  182.                     }
  183.                     // Lier l'année à Pluviometrie
  184.                     $entity->setAnnee($AnneeEtudiee);
  185.                     // Persister l'entité
  186.                     $em->persist($entity);
  187.                     
  188.                 }
  189.             }
  190.             
  191.             if (!$erreur){
  192.                 $em->flush();
  193.             }
  194.             
  195.         }
  196. // Flush une seule fois après avoir traité toutes les données
  197.         
  198. $query $em->createQueryBuilder()
  199.     ->select('s.id')  // On récupère uniquement l'ID de la station météo
  200.     ->from(\App\Entity\Pluviometrie::class, 'p')
  201.     ->join('p.idStation''s')  // Jointure avec StationsMeteo
  202.     ->getQuery();
  203. $idStations $query->getResult();
  204.     dump($idStations); //die();
  205.     
  206.     // Extraction des ID des stations météorologiques
  207.     $idStation = [];
  208.     foreach ($idStations as $idStation) {
  209.         
  210.             $idStationArray[] = $idStation['id'];
  211.         
  212.     }
  213. dump($idStationArray);
  214.     // Supprimer les doublons d'ID
  215.     $listeUniqueIdStation array_unique($idStationArray);
  216. dump($listeUniqueIdStation); 
  217.     // Récupérer toutes les stations correspondantes
  218.     $stationDBAll $em->getRepository(\App\Entity\StationsMeteo::class)
  219.                        ->findBy(['id' => $listeUniqueIdStation], ['departement' => 'ASC']);
  220. dump($stationDBAll); //die();
  221.     return $this->render('meteoFrance.html.twig', ['stationDBAll' => $stationDBAll]);
  222.     }
  223.     #[Route(path'/meteo/listeStation'name'listeStation')]
  224.     public function listeStation(EntityManagerInterface $em\App\Repository\PluvioDatabaseRepository $pluvioRepo,
  225.             Request $req): Response {
  226. $stationDBAll $em->getRepository(StationsMeteo::class)->findAll();
  227. return $this->render('meteoFrance.html.twig', ['stationDBAll' => $stationDBAll]);
  228.     }
  229.     
  230.     
  231.     #[Route(path'/meteo/station/{stationId}'name'meteo_station_data')]
  232.     public function getStationData(string $stationId): JsonResponse {
  233.         try {
  234.             // Récupérer les données pour la station spécifiée et la période
  235.             $data $this->meteoService->getStationData($stationId);
  236.             return new JsonResponse($data); // Retourner les données au format JSON
  237.         } catch (\Exception $e) {
  238.             return new JsonResponse(['error' => $e->getMessage()]);
  239.         }
  240.     }
  241.     #[Route(path'/meteo/commande/{commandeId}'name'meteo_commande')]
  242.     public function getFichier(string $commandeId): Response {
  243.         // Récupérer les données pour la station spécifiée et la période
  244.         $data $this->meteoService->getFichier($commandeId);
  245.         return new Response(
  246.                 $data,
  247.                 Response::HTTP_OK,
  248.                 ['Content-Type' => 'text/plain']
  249.         );
  250.     }
  251.     
  252.     
  253.     #[Route(path'/meteo/stations/{departmentId}/precipitation'name'meteo_stations'methods: ['GET'])]
  254.     public function getStations(string $departmentId) {
  255.         // Récupérer les données pour le département spécifié
  256.         $data $this->meteoService->getStationsByDepartment($departmentId);
  257.         dump($data);
  258.         // Retourner les données sous forme de réponse JSON
  259.         return new JsonResponse($data);
  260.     }
  261.     #[Route(path'/meteo/commande/tous'name'commande_tous')]
  262.     public function getCommandeData(): JsonResponse {
  263.         // Liste des départements (exemple de 5 départements, tu peux en ajouter plus)
  264.         $departements = ['01''02']; // Remplace par la liste complète des départements
  265.         $stationsData = [];
  266.         // Boucle pour récupérer les données pour chaque département
  267.         foreach ($departements as $departement) {
  268.             //           try {
  269.             dump($departement);
  270.             $stationsData[$departement] = $this->meteoService->getStationsByDepartment($departement);
  271.             //           } catch (\Exception $e) {
  272.             //               $stationsData[$departement] = ['error' => $e->getMessage()];
  273.             //           }
  274.         }
  275.         dump($stationsData);
  276.         // Pour chaque station, on réalise une commande
  277.         //$commandeArray = $this->meteoService->getStationData($stationId);
  278.         // Pour chaque commande, on obtient un fichier
  279.         //$fichier = $this->meteoService->getFichier($commandeId);
  280.         return $this->render('meteoFrance.html.twig');
  281.     }
  282.     
  283. //    #[Route(path: '/meteo/testToken', name: 'testToken')]
  284. //    public function gettestToken(string $tokenUrl): Response {
  285. //
  286. //        // Récupérer les données pour la station spécifiée et la période
  287. //        $tokenUrl = $this->meteoService->getrefreshToken();
  288. //        return new Response(
  289. //                $tokenUrl,
  290. //                Response::HTTP_OK,
  291. //                ['Content-Type' => 'text/plain']
  292. //        );
  293. //    }
  294.     
  295. #[Route(path'/meteo/listeDesStations'name'listeDesStations')]
  296. public function listeDesStations(EntityManagerInterface $em\App\Repository\PluvioDatabaseRepository $pluvioRepoRequest $req): Response 
  297. {
  298.     // Récupération de toutes les données de pluviométrie
  299.     //$pluviometrieAll = $em->getRepository(\App\Entity\Pluviometrie::class)->findAll();
  300.     
  301. $query $em->createQueryBuilder()
  302.     ->select('s.id')  // On récupère uniquement l'ID de la station météo
  303.     ->from(\App\Entity\Pluviometrie::class, 'p')
  304.     ->join('p.idStation''s')  // Jointure avec StationsMeteo
  305.     ->getQuery();
  306. $idStations $query->getResult();
  307.     dump($idStations); //die();
  308.     
  309.     // Extraction des ID des stations météorologiques
  310.     $idStation = [];
  311.     foreach ($idStations as $idStation) {
  312.         
  313.             $idStationArray[] = $idStation['id'];
  314.         
  315.     }
  316. dump($idStationArray);
  317.     // Supprimer les doublons d'ID
  318.     $listeUniqueIdStation array_unique($idStationArray);
  319. dump($listeUniqueIdStation); 
  320.     // Récupérer toutes les stations correspondantes
  321.     $stationDBAll $em->getRepository(\App\Entity\StationsMeteo::class)
  322.                        ->findBy(['id' => $listeUniqueIdStation], ['departement' => 'ASC']);
  323. dump($stationDBAll); //die();
  324.     return $this->render('meteoFrance.html.twig', ['stationDBAll' => $stationDBAll]);
  325. }
  326.     #[Route(path'/chart'name'chart')]
  327.     public function index(Request $request): Response
  328.     {    
  329.         // Créer une instance du DTO pour passer au formulaire
  330.         $stationMeteoDTO = new StationMeteoDTO();
  331.         
  332.         // Créer le formulaire avec l'objet DTO
  333.         $form $this->createForm(StationMeteoType::class, $stationMeteoDTO);
  334.         // Gérer la soumission du formulaire
  335.         $form->handleRequest($request);
  336.         if ($form->isSubmitted() && $form->isValid()) {
  337.             // Récupérer les données du formulaire
  338.             $data $form->getData();
  339.             dump($data);
  340.             // Tu as directement accès à l'objet StationMeteoDTO ici
  341.             $apikey $data->getApikey();  // Accès via la méthode getter
  342.             $stationAPI $data->getStationAPI();  // Accès via la méthode getter
  343.             // Appeler le service pour obtenir les données météo
  344.           //  try {
  345.                // $result = $this->météoService->getStationDataHoraire($data['stationId'], $AnneeEtudiee, $data['apiKey']);
  346.         $stationsData = [];
  347.         $commandeArray = []; // Initialisation pour éviter l'erreur Undefined variable
  348.         $columnDataArray = []; // Initialisation pour stocker les données des colonnes  
  349.                     $AnneesEtudiees = [];
  350.                     foreach (range(20182024) as $annee) {
  351.                         $AnneesEtudiees[$annee] = [
  352.                             'dateDeb' => "{$annee}-01-01T00%3A00%3A00Z",
  353.                             'dateFin' => "{$annee}-12-31T00%3A00%3A00Z",
  354.                         ];
  355.                     }
  356.                     foreach ($AnneesEtudiees as $annee => $AnneeEtudiee) {
  357.                             $commande $this->meteoService->getStationDataHoraire($stationAPI$AnneeEtudiee$apikey);
  358.                             $commandeArray[$stationAPI][$annee] = $commande;
  359.                             // Pause pour respecter la limite de 50 requêtes par minute
  360.                             usleep(1300000); // 1,2 secondes = 1 200 000 microsecondes
  361.                         }
  362.         dump($commandeArray);
  363.         $erreur500 null;
  364.         $extractedData = [];
  365.         // Récupération des fichiers à partir des commandes
  366.         foreach ($commandeArray as $stationAPI => $anneesData) {
  367.             dump($anneesData);
  368.             $erreur null;
  369.             foreach ($anneesData as $AnneeEtudiee => $commandeAnnee) {
  370.                 $commandeId $commandeAnnee['elaboreProduitAvecDemandeResponse']['return'];
  371. //                dump($commandeId);
  372.                 $csvString $this->meteoService->getFichier($commandeId$apikey);
  373.                // dump($csvString);
  374.                 // Pause pour respecter la limite de 50 requêtes par minute
  375.                 usleep(1300000); // 1,2 secondes = 1 200 000 microsecondes  
  376.                 if ($csvString == 'Erreur 500'){
  377.                     $erreur500[$commandeId] = $stationId;                    
  378.                     $erreur 1;
  379.                 } else {
  380.                                    // Diviser la chaîne en lignes
  381.                     $lines explode("\n"$csvString);
  382.                     // Tableau pour stocker les données extraites
  383.                     $data = [];
  384.                     foreach ($lines as $index => $line) {
  385.                         // Ignorer la première ligne (en-tête)
  386.                         if ($index === 0) {
  387.                             continue;
  388.                         }
  389.                         // Diviser chaque ligne en colonnes par le séparateur ;
  390.                         $columns explode(";"$line);
  391.                         // Vérifier qu'il y a suffisamment de colonnes
  392.                         if (count($columns) > 2) {
  393.                             // Extraire ce qui se situe entre le 3ème et 4ème point-virgule
  394.                             $data['date'] = str_replace(",""."$columns[1]);
  395.                             $data['temperature'] = str_replace(",""."$columns[10]);
  396.                             $data['vitesse'] = str_replace(",""."$columns[48]);
  397.                             $data['direction'] = str_replace(",""."$columns[50]);
  398.                             $extractedData[] = $data;
  399.                             $extractedDataParAn[$AnneeEtudiee][] = $data;
  400.                         }
  401.                     }                    
  402.                 }
  403.             }                     
  404.         }
  405. //        dump($extractedDataParAn);
  406.         $directions = ['N''NNE''NE''ENE''E''ESE''SE''SSE',
  407.             'S''SSW''SW''WSW''W''WNW''NW''NNW'];
  408.         $classesVitesse = [
  409.             '<1' => [01],
  410.             '1–5' => [15],
  411.             '5–10' => [510],
  412.             '10–15' => [1015],
  413.             '>15' => [15INF],
  414.         ];
  415.         $roseDesVents = [];
  416.         foreach ($directions as $dir) {
  417.             foreach ($classesVitesse as $classe => $_) {
  418.                 $roseDesVents[$dir][$classe] = 0;
  419.             }
  420.             $roseDesVents[$dir]['Total'] = 0;
  421.         }
  422.         function getWindDirection16($deg) {
  423.             $dirs = ['N''NNE''NE''ENE''E''ESE''SE''SSE',
  424.                 'S''SSW''SW''WSW''W''WNW''NW''NNW'];
  425.             $index = (int) round($deg 22.5) % 16;
  426.             return $dirs[$index];
  427.         }
  428.         function getVitesseClasse($vitesse$classesVitesse) {
  429.             foreach ($classesVitesse as $label => [$min$max]) {
  430.                 if ($vitesse >= $min && $vitesse $max) {
  431.                     return $label;
  432.                 }
  433.             }
  434.             return '>10'// fallback
  435.         }
  436.         $totalObservations 0;
  437.         foreach ($extractedData as $data) {
  438.             $direction floatval($data['direction']);
  439.             $vitesse floatval($data['vitesse']);
  440.             if ($vitesse || $direction || $direction 360)
  441.                 continue;
  442.             $dirName getWindDirection16($direction);
  443.             $classeVitesse getVitesseClasse($vitesse$classesVitesse);
  444.             $roseDesVents[$dirName][$classeVitesse]++;
  445.             $roseDesVents[$dirName]['Total']++;
  446.             $totalObservations++;
  447.         }
  448.         // Convertir en % de fréquence
  449.         foreach ($roseDesVents as $dir => $classes) {
  450.             foreach ($classesVitesse as $classe => $_) {
  451.                 $count $roseDesVents[$dir][$classe];
  452.                 $roseDesVents[$dir][$classe] = round(($count $totalObservations) * 1002);
  453.             }
  454.             // Total (par direction, toutes vitesses confondues)
  455.             $countTotal $roseDesVents[$dir]['Total'];
  456.             $roseDesVents[$dir]['Total'] = round(($countTotal $totalObservations) * 1002);
  457.         }
  458.         $stationKey $this->getKeyById($stationAPI);
  459.         $summerData = [];
  460.                 $winterData = [];
  461.                 foreach ($extractedData as $data) {
  462.                     // Récupérer l'année, le mois et le jour de la date
  463.                     $date $data['date'];  // Assurez-vous que la date est au format AAAAMMJJHH
  464.                     $year substr($date04); // AAAA
  465.                     $month substr($date42); // MM
  466.                     $day substr($date62);   // JJ
  467.                     // Vérifier si la date correspond à l'été (juin, juillet, août)
  468.                     if (in_array($month, ['06''07''08'])) {
  469.                         $summerData[] = $data;
  470.                     }
  471.                     // Vérifier si la date correspond à l'hiver (décembre, janvier, février)
  472.                     elseif (in_array($month, ['12''01''02'])) {
  473.                         $winterData[] = $data;
  474.                     }
  475.                 }
  476. // Traiter les données d'été et d'hiver de la même manière que pour les données globales
  477.                 $summerRoseDesVents $this->processWindData($summerData$classesVitesse);
  478.                 $winterRoseDesVents $this->processWindData($winterData$classesVitesse);
  479. //                dump($summerRoseDesVents);
  480. //                dump($roseDesVents);
  481. // Passer les données au template
  482.         return $this->render('chart.html.twig', [
  483.                             'roseDesVents' => $roseDesVents,
  484.                             'summerRoseDesVents' => $summerRoseDesVents,
  485.                             'winterRoseDesVents' => $winterRoseDesVents,
  486.                             'directions' => $directions,
  487.                             'stationKey' => $stationKey,
  488.             'form' => $form->createView(),
  489.         ]);
  490. //            } catch (\Exception $e) {
  491. //                // Gérer les erreurs
  492. //                $this->addFlash('error', 'Erreur : ' . $e->getMessage());
  493. //            }
  494.         }
  495.         // Rendre la vue du formulaire
  496.         return $this->render('formulaireWindrose.html.twig', [
  497.             'form' => $form->createView(),
  498.         ]);
  499.         
  500.         
  501.     }
  502.     // Méthode pour obtenir la clé en fonction de l'ID
  503.     public function getKeyById($id)
  504.     {
  505.         // Récupérer le tableau des stations et IDs à partir de StationMeteoType
  506.         $choices $this->stationMeteoType->getStationAPIChoices();
  507.         // Rechercher la clé correspondant à l'ID
  508.         $key array_search($id$choices);
  509.         // Si l'ID est trouvé, retourne la clé, sinon retourne null
  510.         return $key !== false $key null;
  511.     }
  512.     
  513.     
  514.     private function processWindData(array $data, array $classesVitesse)
  515. {
  516.     $roseDesVents = [];
  517.     foreach ($data as $dataPoint) {
  518.         $direction floatval($dataPoint['direction']);
  519.         $vitesse floatval($dataPoint['vitesse']);
  520.     
  521.         if ($vitesse || $direction || $direction 360) {
  522.             continue;
  523. }
  524.         $dirName getWindDirection16($direction);
  525.         $classeVitesse getVitesseClasse($vitesse$classesVitesse);
  526.         if (!isset($roseDesVents[$dirName])) {
  527.             $roseDesVents[$dirName] = [];
  528.         }
  529.         if (!isset($roseDesVents[$dirName][$classeVitesse])) {
  530.             $roseDesVents[$dirName][$classeVitesse] = 0;
  531.         }
  532.         $roseDesVents[$dirName][$classeVitesse]++;
  533.     }
  534.     // Convertir en % de fréquence
  535.     $totalObservations array_sum(array_map(function ($direction) {
  536.         return array_sum($direction);
  537.     }, $roseDesVents));
  538.     //dump($roseDesVents);
  539. // S'assurer que chaque direction contient toutes les classes avec une valeur par défaut
  540. foreach ($roseDesVents as $dir => &$classes) {
  541.     foreach ($classesVitesse as $classe => $_) {
  542.         if (!isset($classes[$classe])) {
  543.             $classes[$classe] = 0;
  544.         }
  545.     }
  546. }
  547. // Important : libérer la référence
  548. unset($classes);
  549. // Ensuite, tu peux faire le calcul des pourcentages
  550. foreach ($roseDesVents as $dir => $classes) {
  551.     foreach ($classesVitesse as $classe => $_) {
  552.         $count $roseDesVents[$dir][$classe];
  553.         $roseDesVents[$dir][$classe] = round(($count $totalObservations) * 1002);
  554.     }
  555.     // Pareil pour Total (si tu veux l’inclure dans le tableau final)
  556.     $roseDesVents[$dir]['Total'] = round((array_sum($roseDesVents[$dir]) / 100), 2);
  557. }
  558.     return $roseDesVents;
  559. }
  560.     
  561.     
  562.     
  563. }