Récupération et traitement des fichiers csv "évolution de la vaccination"

Pour l'évolution de la vaccination, on fait appel à deux fichiers de référence. Par rapport aux fichiers indiquant l'état de la vaccination à ce jour, ils reprennent le même genre d'information (sauf la population estimée), mais la fournissent pour tous les jours depuis le 27 décembre 2020, jusqu'à la veille ou le jeudi précédent.

Ça entraîne des fichiers de référence beaucoup plus gros, et qui s'allongent un peu chaque jour. Par exemple, le fichier de référence qui montre l'évolution de la vaccination par classe d'âge a le contenu suivant :



Pour connaître la date de dernière mise à jour de ce fichier, il faut au moins lire en entier la première classe d'âge. On peut aussi lire tout le fichier et récupérer la date de la dernière ligne. Mais récupérer la totalité d'un fichier de référence juste pour savoir s'il est utile de faire une mise à jour du fichier local est stupide !

Donc, pour déterminer si un fichier local relatif à l'évolution de la vaccination est à jour (ou à peu près), on utilisera la même méthode que pour le fichier local vacsi-totgen.csv

Les fonctions testmaj_a_fra () et testmaj_regdom () permettent de mettre à jours les fichiers csv locaux :
Ce fichiers locaux permettront de réaliser des graphiques d'évolution pour les différentes classes d'âge, les différentes régions, et les différents DOM.

Toutefois, il est également intéressant de voir cette évolution sous la forme de tableaux. Mais dans ce cas, une ligne par jour donnerait des tables inutilement longues et précises. On préfère dans ce cas se limiter à l'affichage pour 3 jours de chaque mois.

Des fichiers se limitant aux jours sélectionnés sont aussi générés.

Le fichier vacsi-a-fra et les fichiers dérivés

Tout d'abord, on cherche à savoir s'il est utile de faire une mise à jour du fichier local vacsi-a-fra.csv (et des fichiers dérivés). Pour cela, on regarde si le fichier local vacsi-tot-a-fra.csv est plus récent que vacsi-a-fra.csv. On ne fera une mise à jour que dans ce cas.
    // fichier qui sert à déterminer si une mise à jour est utile
    $refdate = DIR_CSV."/vacsi-tot-a-fra.csv";

    // fichier à mettre éventuellement à jour
    $chemcsv = DIR_CSV."/vacsi-a-fra.csv";

    // si le fichier est à jour
    if (filemtime ($refdate) <= filemtime ($chemcsv))
        // on n'a rien à faire
        return;
      
Remarque : Dans le pire des cas, depuis la dernière mise à jour des données sur le site web de référence, ni l'utilisateur actuel, ni un utilisateur antérieur aura consulté l'état de la vaccination à ce jour avant de regarder l'évolution de la vaccination. Dans ce cas, le fichier vacsi-a-fra.csv et ses dérivés ne seront pas mis à jour à tort.

Toutefois :
Comme pour les fichiers de référence sur la vaccination à ce jour, les classes d'âge sont presque dans l'ordre mais pas tout à fait. La classe d'âge concernant le 5 à 9 ans est entre la classe d'âge des 40 à 49 ans et celle des 40 à 49 ans.

Pour remettre ça dans l'ordre (même si ce n'est pas indispensable), on va recopier les lignes issues du fichier de référence dans 2 fichiers distincts, un pour les deux classes d'âge jusqu'à 9 ans, et l'autre pour toutes les classes d'âge à partir de 10 ans. Pour cela, on teste le premier chiffre de la classe d'âge.
    // comme la classe d'âge 09 est mal placée on commence
    // par créer 2 fichiers qu'on fusionnera juste après
    $nouvcsv1 = DIR_CSV."/vacsi-a-fra.new1";
    $nouvcsv2 = DIR_CSV."/vacsi-a-fra.new2";

    // les ouvrir en écriture
    $descscv1 = fopen ($nouvcsv1, "w");
    $descscv2 = fopen ($nouvcsv2, "w");

    // si les ouvertures se sont bien passées
    if ($descscv1 && $descscv2)
    {
        // lire la première ligne de l'url en oubliant "FR;"
        $ligne_url = substr (fgets ($descurl, LG_MAX_CSV), 3);

        // séparer les différents champs de la ligne
        // on prévoie que des champs supplémentaires pourront apparaitre
        $args = explode (";", trim ($ligne_url), 20);

        // trouver le nombre de doses mémorisées
        $doses = (count ($args) - 2) / 3;

        // tant que la dernière ligne lue fait référence à une classe d'âge
        while ($ligne_url [2] == ";")
        {
            // réordonner le champ date et supprimer les champs inutiles
            $ligne_url = selchamps_evol ($ligne_url, $doses);

            // recopier la ligne dans le bon fichier
            if ($ligne_url [0]  == "0")
                fputs ($descscv1, $ligne_url);
            else
                fputs ($descscv2, $ligne_url);

            // lire la ligne suivante de l'url en oubliant "FR;"
            $ligne_url = substr (fgets ($descurl, LG_MAX_CSV), 3);
        }
      
Il faut à présent mettre le contenu du 2ème fichier dans le premier.
        // remplissage du fichier 2 terminé
        fclose ($descscv2);

        // on va rajouter son contenu au fichier 1
        $descscv2 = fopen ($nouvcsv2, "r");

        // si l'ouverture s'est bien passée
        if ($descscv2)
        {
            // lire la première ligne du fichier 2
            $ligne = fgets ($descscv2, LG_MAX_CSV);

            // tant que non fin du fichier 2
            while ($ligne)
            {
                // recopier la ligne dans le fichier 1
                fputs ($descscv1, $ligne);

                // lire la ligne suivante du fichier 2
                $ligne = fgets ($descscv2, LG_MAX_CSV);
            }

            // terminé avec le fichier 2
            fclose ($descscv2);
        }
        else
            $erreur = "Problème pour terminer le fichier ".basename ($chemcsv);
      
Il reste les données concernant la vaccination tous âges confondus qu'on va rajouter à la fin du fichier en remplaçant la classe d'âge numérotée 0 par "ta".
        // on rajoute les données corespondant à toutes les classes d'âge réunies

        // tant que non fin de fichier csv
        while ($ligne_url)
        {
            // réordonner le champ date, supprimer les champs inutiles
            // et rebaptise la classe d'age générale
            $ligne_url = "ta".substr (selchamps_evol ($ligne_url, $doses), 1);

            // recopier la ligne dans le dernier fichier
            fputs ($descscv1, $ligne_url);

            // lire la ligne suivante de l'url en oubliant "FR;"
            $ligne_url = substr (fgets ($descurl, LG_MAX_CSV), 3);
        }
      
Le remplissage du fichier vacsi-a-fra.csv est terminé.

À présent, à partir de ce fichier, on va créer un fichier par classe d'âge et un fichier tous âges confondus représentant l'évolution de la vaccination tous les 10 jours environ.

On choisira de mémoriser dans les nouveaux fichiers les données des 1er, 11ème et 21ème jours ou, si l'une d'elles venait à être absentes, celle du premier jour qui suit.

L'état de la vaccination pour le jour le plus récent disponible sera aussi recopié dans le fichier s'il ne l'a pas déjà été en sélectionnant un jour sur 10.

Pour ça, on lit ligne par ligne le fichier vacsi-a-fra.csv que l'on vient de créer. A chaque nouvelle ligne, on commence par tester la classe d'âge. Si ce n'est pas la même que pour la ligne précédente, on va créer un nouveau fichier.
    // lire la classe d'âge
    $cl_age = fgets ($descscv, 3);

    // tant que non fin de fichier
    while ($cl_age)
    {
        // si la classe d'âge a changé par rapport à la ligne précédente
        if ($cl_age != $cl_prec)
        {
            // si on remplissait un fichier
            if ($cl_prec)
            {
                (...)

                // fermer le fichier qu'on vient de remplir
                fclose ($descout);
            }

            // nouveau fichier à remplir
            $ficout = DIR_CSV."/vacsi-age-".$cl_age.".csv";
            $descout = fopen ($ficout, "w");

            // si l'ouverture s'est mal passée
            if (! $descout)
                // il pourra y avoir plusieurs erreurs du même type
                $erreur = $erreur."Problème créer le fichier ".basename ($ficout)."<br>\n";

            // mémoriser la nouvelle classe d'âge
            $cl_prec = $cl_age;

            // on commencera à afficher les données début janvier 2020
            $dizaine = 0;
        }
      
Les fichiers créés ont comme nom vacsi-age-??.csv avec la classe d'âge à la place des ??? . Par exemple vacsi-age-24.csv pour la classe d'âge des 18 à 24 ans. Le fichiers de l'évolution tous âges confondus s'appelle vacsi-age-ta.csv

On va recopier certaines lignes du fichier vacsi-a-fra.csv dans le nouveau fichier. Pour qu'une ligne soit choisie, il faut que le chiffre des dizaines du jour du mois ait changé par rapport à la dernière ligne recopiée et que le chiffre des unités du jour du mois ne soit pas 0. On exclue aussi le 31ème jour lorsqu'il existe.

Le passage d'une dizaine de jours à la suivante s'effectue simplement grâce à une addition modulo 3.
        // lire le reste de la ligne
        $ligmemo = fgets ($descscv, LG_MAX_CSV);

        // si on n'a encore rien enregistré pour cette dizaine de jours
        if ($ligmemo [0] == $dizaine  && $ligmemo [1])
        {
            // le faire
            fputs ($descout, $ligmemo);

            // cette ligne ne sera pas réutilisée
            $ligmemo = "";

            // passer à la dizaine de jours suivante
            $dizaine = ($dizaine + 1) % 3;
        }

        // lire la classe d'âge de la ligne suivante
        $cl_age = fgets ($descscv, 3);
      
Enfin, lorsque toutes les dates d'une classe d'âge ont été explorée, on recopie les données concernant le jour le plus récent si elles ne viennent pas de l'être.
    // si la ligne du jour n'a pas été recopiée
    if ($ligmemo)
        // le faire
        fputs ($descout, $ligmemo);
      
Cette dernière opération se fait :

Les fichiers vacsi-reg , vacsi-dom et les fichiers dérivés

Ces fichiers sont réalisés à partir d'un fichier de référence qui a la même structure que le fichier de référence d'évolution de la vaccination pas classe d'âge.

En particulier l'indication du DOM ou de la région figure en début de ligne sous la forme d'un code de 2 chiffres :
Dans les fichiers vacsi-dom.csv et vacsi-reg.csv on va remplacer ces codes numériques par des codes de 3 lettres :
Pour transformer les codes numérique de DOM puis de région en un code de 3 lettres, on procède de manière similaire à ce qui a été fait pour les fichiers vacsi-tot-dom.csv et vacsi-tot-reg.csv

Un tableau est utilisé pour les DOM :
    // code des DOM dans l'ordre de leur numéro du fichier csv de référence
    $liste_codedom = array ("", "gua", "mar", "guy", "reu", "smi", "may", "sba", "sma");
      
et une instruction switch ... case pour les codes de région.

Une fois les fichiers vacsi-dom.csv et vacsi-reg.csv réalisés, on va créer des fichiers de nom vacsi-dom-???.csv et vacsi-reg-???.csv avec le code de région ou de DOM à la place des ???

Pour cela, on va utiliser une fonction appelée 2 fois :
    // 2ème partie : on crée un fichier par région et un fichier par DOM
    //               avec une information tous les 10 jours
    synthese_regdom ($csvreg, "reg");
    synthese_regdom ($csvdom, "dom");
      
Le fonctionnement de synthese_regdom (...) est similaire au traitement qui a été fait pour les classes d'âge. La seule différence est qu'on utilise des codes de 3 caractères au lieu de 2