Subversion Repositories eFlore/Applications.cel

Rev

Rev 2022 | Go to most recent revision | Blame | Last modification | View Log | RSS feed

<?php
// declare(encoding='UTF-8');
/**
 * Traitement des observations sauvages pour les migrer vers des champs étendus
 *
 * Description : classe permettant d'affecter des champs étendus aux observations sauvages. Elle permet aussi
 * d'exporter les données à migrer en CSV pour vérifier les informations avant la migration.
 * Utilisation :
 * - Pour migrer : <code>/opt/lamp/bin/php cli.php migration_sauvages -a migrer -v 3</code>
 * - Pour exporter : <code>/opt/lamp/bin/php cli.php migration_sauvages -a exporter -s chemin_vers_fichier_sortie</code>
 *
 * @category   CEL
 * @package    Scripts
 * @subpackage Migration : Sauvages
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
 * @author     Aurelien PERONNET <aurelien@tela-botanica.org>
 * @license    GPL v3 <http://www.gnu.org/licenses/gpl.txt>
 * @license    CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
 */
include_once dirname(__FILE__).'/bibliotheque/Dao.php';

class MigrationSauvages extends Script {
        protected $parametres_autorises = array(
                        '-s' => array(false, true, "Chemin vers le fichier de sortie pour l'export"));


        public function executer() {
                $this->dao = new Dao();
                // Récupération de paramétres
                // Lancement de l'action demandée
                $this->mode_verbeux = $this->getParametre('v');
                $cmd = $this->getParametre('a');
                try {
                        switch ($cmd) {
                                case 'exporter' :
                                        $this->exporterObservationsSauvagesAMigrer();
                                        break;
                                case 'migrer' :
                                        $this->migrerObservationsSauvages();
                                        break;
                                default :
                                        $msg = "Erreur : la commande '$cmd' n'existe pas!\n".
                                                "Commandes existantes : exporter, migrer";
                                        throw new Exception($msg);
                        }
                } catch (Exception $e) {
                        $this->traiterErreur($e->getMessage());
                }
        }

        private function exporterObservationsSauvagesAMigrer() {
                $total = $this->dao->obtenirNbObservationsSauvages();
                $pas_liste_obs = 5000;
                echo " Traitement des $total observations par paquet de $pas_liste_obs \n";

                $fichier = $this->getParametre('s');

                $fp = fopen($fichier, 'w');
                $ecrireEntete = true;
                for ($i = 0; $i <= $total; $i += $pas_liste_obs) {
                        $liste_observations = $this->dao->obtenirObservationsSauvages($i, $pas_liste_obs);
                        foreach ($liste_observations as $observation) {
                                if ($this->doitMigrerObservation($observation)) {
                                        $champs_etendus = $this->convertirChampsObsSauvagesEnChampsEtendus($observation);
                                        $champs_etendus_fixes = array(
                                                'latitudeDebutRue', 'longitudeDebutRue', 'latitudeFinRue', 'longitudeFinRue',
                                                'adresse', 'coteRue');
                                        foreach ($champs_etendus_fixes as $cle) {
                                                $observation[$cle] = '';
                                                foreach ($champs_etendus as $champs) {
                                                        if ($champs['cle'] == $cle) {
                                                                $observation[$cle] = $champs['valeur'];
                                                        }
                                                }
                                        }
                                }
                                if ($ecrireEntete) {
                                        fputcsv($fp, array_keys($observation));
                                        $ecrireEntete = false;
                                }
                                fputcsv($fp, array_values($observation));
                                $this->afficherAvancement("\tObs traitées : ", 1);
                        }
                }
                fclose($fp);
                echo "\nFin de l'export\n";
        }

        private function migrerObservationsSauvages() {
                if ($this->mode_verbeux) $debut = microtime(true);
                $nb_obs_modifiees = 0;
                $nb_obs_ignorees = 0;
                $total = $this->dao->obtenirNbObservationsSauvages();

                if ($this->mode_verbeux) {
                        echo "-------------------------------------------------------------------\n".
                                " Début de la migration des observations sauvages vers les champs étendus \n".
                                " $total observations concernées\n".
                                "-------------------------------------------------------------------\n";
                }

                $champs_etendus_a_inserer = array();
                $nb_champs_total = 0;
                $nb_champs_etendus_a_inserer = 0;

                $pas_liste_obs = 5000;
                echo " Traitement des observations par paquet de ".$pas_liste_obs." (5 champs étendus ajoutés par observation traitée) \n";

                for ($i = 0; $i <= $total; $i += $pas_liste_obs) {
                        $liste_observations = $this->dao->obtenirObservationsSauvages($i, $pas_liste_obs);
                        $champs_etendus_a_inserer = array();
                        $nb_champs_etendus_a_inserer = 0;
                        foreach ($liste_observations as $observation) {

                                // test si obs candidate est ok, i.e. si elle contient bien un champ station formate comme ceci
                                // coordonnees_debut_de_rue;coordonnees_fin_de_rue;cote_de_la_rue
                                if ($this->doitMigrerObservation($observation)) {
                                        $champs_etendus = $this->convertirChampsObsSauvagesEnChampsEtendus($observation);
                                        $champs_etendus_a_inserer[] = $champs_etendus;
                                        $nb_champs = count($champs_etendus);
                                        $nb_obs_modifiees++;
                                        $nb_champs_etendus_a_inserer += $nb_champs;
                                        $nb_champs_total += $nb_champs;
                                } else {
                                        $nb_obs_ignorees++;
                                }

                                // insertion par paquets de 100 champs ou bien à la fin du parcours de la liste s'il y a moins de
                                // 20 observations à traiter (20 obs * 5 champs = 100 champs)
                                if ($nb_champs_etendus_a_inserer >= 100) {
                                        $this->dao->ajouterChampsEtendusParLots($champs_etendus_a_inserer);
                                        $champs_etendus_a_inserer = array();
                                        $nb_champs_etendus_a_inserer = 0;
                                }
                        }
                        echo " $nb_champs_total champs étendus insérés \n";
                }

                // insertion des champs restants s'il en reste moins de 100 à la fin
                if ($nb_champs_etendus_a_inserer > 0) {
                        $this->dao->ajouterChampsEtendusParLots($champs_etendus_a_inserer);
                        $nb_champs_total += $nb_champs_etendus_a_inserer;
                        echo " $nb_champs_total champs étendus insérés \n";
                }

                if ($this->mode_verbeux) {
                        $fin = microtime(true);
                        $tps_ecoule = $fin - $debut;
                        echo "\n".
                                "-------------------------------------------------------------------\n".
                                "  Fin de la migration des observations sauvages, \n".
                                "  $tps_ecoule secondes écoulées \n".
                                "  $nb_champs_total champs étendus créées \n".
                                "  $nb_obs_modifiees observations modifiées \n".
                                "  $nb_obs_ignorees observations ignorées \n".
                                "-------------------------------------------------------------------\n\n";
                }
        }

        private function doitMigrerObservation($observation) {
                return (!empty($observation['station']) && substr_count($observation['station'], ';') == 2);
        }

        private function convertirChampsObsSauvagesEnChampsEtendus($observation) {
                list($coords_debut_rue, $coords_fin_rue, $cote_rue) = explode(';', $observation['station']);
                $coords_debut_rue = explode(',', $coords_debut_rue);
                $coords_fin_rue = explode(',', $coords_fin_rue);
                $lieu_dit = (trim($observation['lieudit']) == 'non renseigné(e)') ? '' : $observation['lieudit'];
                $id = $observation['id_observation'];

                if (!preg_match('/^(?:2cotes|pair|impair|)$/', $cote_rue)) {
                        $msg = "Obs #$id: erreur champ cote_rue contient : $cote_rue";
                        $this->traiterErreur($msg);
                }
                $testCoords = array(
                        'latitudeDebutRue' => $coords_debut_rue[0],
                        'longitudeDebutRue' => $coords_debut_rue[1],
                        'latitudeDebutRue' => $coords_fin_rue[0],
                        'longitudeDebutRue' => $coords_fin_rue[1]
                );
                foreach ($testCoords as $champ => $coord) {
                        if (!preg_match('/^(?:-|)[0-9]{1,2}[.][0-9]{5}$/', $coord)) {
                                $msg = "Obs #$id: erreur champ $champ contient : $coord";
                                $this->traiterErreur($msg);
                        }
                }

                $champs_etendus = array();
                if (count($coords_debut_rue) == 2) {
                        $champs_etendus[] = array('id_observation' => $id,
                                'cle' => 'latitudeDebutRue',
                                'label' => 'Latitude du début de la rue',
                                'valeur' => $coords_debut_rue[0]);
                        $champs_etendus[] = array('id_observation' => $id,
                                'cle' => 'longitudeDebutRue',
                                'label' => 'Longitude du début de la rue',
                                'valeur' => $coords_debut_rue[1]);
                }
                if (count($coords_fin_rue) == 2) {
                        $champs_etendus[] = array('id_observation' => $id,
                                'cle' => 'latitudeFinRue',
                                'label' => 'Latitude de fin de la rue',
                                'valeur' => $coords_fin_rue[0]);
                        $champs_etendus[] = array('id_observation' => $id,
                                'cle' => 'longitudeFinRue',
                                'label' => 'Longitude de fin de la rue',
                                'valeur' => $coords_fin_rue[1]);
                }
                if ($lieu_dit != '') {
                        $champs_etendus[] = array('id_observation' => $id,
                                'cle' => 'adresse',
                                'label' => 'Adresse',
                                'valeur' => $lieu_dit);
                }
                if (preg_match('/^(?:2cotes|pair|impair)$/', $cote_rue)) {
                        $champs_etendus[] = array('id_observation' => $id,
                                'cle' => 'coteRue',
                                'label' => 'Côté rue',
                                'valeur' => $cote_rue);
                }

                return $champs_etendus;
        }
}