Subversion Repositories eFlore/Applications.moissonnage

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php

/**
 * Exemple lancement:
 * /opt/lampp/bin/php -d memory_limit=3500M ~/web/moissonnage/scripts/cli.php maillage_projet
 *   -a source=nom_source
 * 
 * @author alex
 *
 */

class MaillageProjet extends Script {
        
        
        private $nomProjet = 'maillage_projet';
        private $nomSource = '';
        private $bdd = null;
        private $tableRequetage = '';
        
        private $mailles = array();
        private $points  = array();
        
        
        public function executer() {
                try {
                        $this->initialiserScript();
                        $cmd = $this->getParametre('a');
                        $parametre = explode('=', $cmd);
                        if (count($parametre) != 2 && $parametre[0] != 'source') {
                                throw new Exception("Parametre passé incorrect : attendu source=nom_de_la_source\n");
                        } else {
                                if (!$this->estSourceDisponible($parametre[1])) {
                                        $sourcesDispo = Config::get('sources_disponibles');
                                        $message =
                                                "Erreur lors de l'éxécution du script : la soruce demandée n'est pas disponible.\n".
                                                "Les sources dont le maillage est réalisable sont les suivantes : {$sourcesDispo}.\n";
                                        throw new Exception($message);
                                } else {
                                        $this->nomSource = $parametre[1];
                                        $this->chargerConfigurationSource($parametre[1]);
                                        $this->tableRequetage = $parametre[1].Config::get('suffixe_table_interrogation');
                                        $this->genererMaillage();
                                }
                        }
                } catch(Exception $e) {
                        $this->traiterErreur($e->getMessage());
                }
        }
        
        private function initialiserScript() {
                $fichierIni = $this->getScriptChemin().'maillage_projet.ini';
                if (file_exists($fichierIni)) {
                        Config::charger($fichierIni);
                } else {
                        $m = "Veuillez configurer le projet en créant le fichier '{$this->nomProjet}.ini' ".
                                "dans le dossier du module de script du projet à partir du fichier '{$this->nomProjet}.defaut.ini'.";
                        throw new Exception($m);
                }
        }
        
        private function estSourceDisponible($nomSource) {
                $sourcesDispo = explode(',', Config::get('sources_disponibles'));
                return (in_array($nomSource, $sourcesDispo));
        }
        
        private function chargerConfigurationSource($nomSource) {
                $fichierIni = $this->getScriptChemin()."sources".DIRECTORY_SEPARATOR."{$nomSource}.ini";
                if (file_exists($fichierIni)) {
                        Config::charger($fichierIni);
                } else {
                        $m = "Veuillez configurer les champs specifiques à la source en créant le fichier ".
                                "'{$nomSource}.ini' dans le dossier sources de script du projet {$this->nomProjet}.";
                        throw new Exception($m);
                }
        }
        
        
        private function genererMaillage() {
                if (!$this->estTableCreee()) {
                        $this->creerStructureTable();
                }
                $zoomMinimal = Config::get('zoom_minimal');
                $niveauxZoom = range($zoomMinimal, Config::get('zoom_maximal'), 1);
                foreach ($niveauxZoom as $zoom) {
                        print("Génération des mailles au niveau de zoom {$zoom}...\n");
                        if ($zoom == $zoomMinimal) {
                                $this->initialiserMailles();
                                $this->genererMaillesPourZoomMinimal();
                        } else {
                                $this->mailles->redecouperMailles();
                                $this->ajouterMaillesDansBdd();
                        }
                }
        }
        
        private function estTableCreee() {
                $tables = $this->getBdd()->recupererTous("SHOW TABLES FROM ".Config::get('bdd_nom'));
                $tableInsertion = 'mailles_'.$this->nomSource;
                for ($index = 0; $index < count($tables) && $tables[$index]['Tables_in_tb_eflore'] != $tableInsertion;
                        $index ++);
                return $index < count($tables);
        }
        
        private function creerStructureTable() {
                $tableInsertion = 'mailles_'.$this->nomSource;
                print("Table {$tableInsertion} non trouvée dans la base de données, création de sa structure...\n");
                $requete =
                                "CREATE TABLE {$tableInsertion} (".
                                "code_maille VARCHAR(25) NOT NULL PRIMARY KEY,".
                                "zoom TINYINT UNSIGNED NOT NULL,".
                                "position_latitude SMALLINT UNSIGNED NOT NULL,".
                                "position_longitude SMALLINT UNSIGNED NOT NULL,".
                                "limite_sud DECIMAL(9,6) NOT NULL,".
                                "limite_est DECIMAL(9,6) NOT NULL,".
                                "limite_nord DECIMAL(9,6) NOT NULL,".
                                "limite_ouest DECIMAL(9,6) NOT NULL,".
                                "nombre_sites MEDIUMINT UNSIGNED NOT NULL,".
                                "nombre_observations MEDIUMINT UNSIGNED NOT NULL".
                        ") ENGINE=MyISAM, CHARACTER SET utf8";
                $this->getBdd()->requeter($requete);
                $requete = "ALTER TABLE {$tableInsertion} ADD INDEX bbox(zoom, limite_sud, ".
                        "limite_nord, limite_ouest, limite_est)";
                $this->getBdd()->requeter($requete);
        }
        
        private function initialiserMailles() {
                $limitesEspaceMaillage = $this->recupererExtremesCoordonnees();
                $this->recupererIndexMailles($limitesEspaceMaillage, Config::get('zoom_minimal'));
        }
        
        private function recupererExtremesCoordonnees() {
                $champLongitude = Config::get('tbl.champ_longitude');
                $champLatitude = Config::get('tbl.champ_latitude');
                $requete = "SELECT Min({$champLongitude}) AS lng_min, Max({$champLongitude}) AS lng_max, ".
                        "Min({$champLatitude}) AS lat_min, Max({$champLatitude}) AS lat_max FROM {$this->tableRequetage}";
                $limites = $this->getBdd()->recuperer($requete);
                return $limites;
        }
        
        private function getBdd() {
                if (is_null($this->bdd)) {
                        $this->bdd = new Bdd();
                }
                return $this->bdd;
        }
        
        private function recupererIndexMailles($limites, $zoom) {
                $bbox = array(
                        'sud'   => $limites['lat_min'],
                        'ouest' => $limites['lng_min'],
                        'est'   => $limites['lng_max'],
                        'nord'  => $limites['lat_max']
                );
                $this->mailles = new Maillage($bbox, $zoom);
                $this->mailles->genererMaillesVides();
        }
        
        private function genererMaillesPourZoomMinimal() {
                $this->points = $this->recupererPoints();
                $this->mailles->ajouterPoints($this->points);
                $this->ajouterMaillesDansBdd();
        }
        
        private function recupererPoints() {
                print("Récupération des points dans la base de données...\n");
                $champLongitude = Config::get('tbl.champ_longitude');
                $champLatitude  = Config::get('tbl.champ_latitude');
                $id = Config::get('tbl.champ_id');
                $requete = "SELECT COUNT({$id}) AS observations, {$champLatitude} AS latitude, {$champLongitude} ".
                        "AS longitude FROM {$this->tableRequetage} GROUP BY {$champLongitude},{$champLatitude}";
                $points = $this->getBdd()->recupererTous($requete);
                return $points;
                print("Points chargés\n");
        }
        
        private function ajouterMaillesDansBdd() {
                $aInserer = $this->mailles->formaterPourInsertionBdd();
                $champsTable = Config::get('champs_table_mailles');
                $tableInsertion = 'mailles_'.$this->nomSource;
                $ordresInsertion = [];
                $this->getBdd()->requeter("DELETE FROM {$tableInsertion} WHERE zoom={$aInserer[0]['zoom']}");
                foreach ($aInserer as $ligne) {
                        $codeMaille = $this->nomSource.'.'.$ligne['zoom'].'-'.$ligne['indexLat'].'-'.$ligne['indexLng'];
                        $sql = "('{$codeMaille}',{$ligne['zoom']},{$ligne['indexLng']},{$ligne['indexLat']},".
                                "{$ligne['ouest']},{$ligne['sud']},{$ligne['est']},{$ligne['nord']},".
                                "{$ligne['points']},{$ligne['observations']})";
                        $ordresInsertion[] = $sql;
                }
                $requete = "INSERT INTO {$tableInsertion} ({$champsTable}) VALUES ".implode(',', $ordresInsertion);
                $this->getBdd()->requeter($requete);
        }
        
}

?>