Subversion Repositories eFlore/Projets.communes

Rev

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

<?php
// declare(encoding='UTF-8');
/**
 * Exemple de script utilisable avec le TBFramework.
 * Pour le lancer, taper en ligne de commande, en vous plaçant dans le dossier /framework/exemple/scripts/ :
 * <code>/opt/lampp/bin/php cli.php mon_script -a test</code>
 *
 * @author              Jean-Pascal MILCENT <jpm@tela-botanica.org>
 * @copyright   Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
 * @license     http://www.gnu.org/licenses/gpl.html Licence GNU-GPL-v3
 * @license     http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL-v2
 * @version     $Id$
 */
class NettoyageKml extends Script {
        
        private $fichier_id = '';
        
        private $coordonnees_simples = array();
        
        protected $parametres_autorises = array(
                '-f' => array(true, true, 'Fichier KML à nettoyer.'));
        
        public function executer() {
                // Récupération de paramêtres

                // Lancement de l'action demandée
                $cmd = $this->getParametre('a');
            switch ($cmd) {
                        case 'nettoyer' :
                                $this->executerNettoyage();
                                break;
                        default :
                                $this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
                }
    }

    private function executerNettoyage() {
        $kml = $this->getParametre('f');
        if (file_exists($kml)) {
                $placemarks = $this->analyserFichierKml($kml);
                                
                $nom_kml = basename($kml, '.kml');
                $dossier_kml = dirname($kml);
                $dpt = '00';
                if (preg_match('/^([0-9]{2}|2[AB])/', $nom_kml, $match)) {
                        $dpt = $match[1];
                }
                $fichier_sortie = $dossier_kml.DS.$dpt.'%s.kml';
                $squelette = dirname(__FILE__).DS.'squelettes'.DS.'defaut.tpl.kml';
                
                $num = 1;
                $pas = Config::get('fichierSortie.taille');
                $taille = 0;
                $nbre_placemarks = count($placemarks);
                foreach ($placemarks as $id => $placemark) {
                        $placemarks_portion[] = $placemark;
                        $taille += mb_strlen($placemark);
                        if ($taille > $pas || $id == ($nbre_placemarks - 1)) {
                                $taille = 0;
                                $donnees = array('nom' => $nom_kml, 'placemarks' => $placemarks_portion);
                                
                                $sortie = SquelettePhp::analyser($squelette, $donnees);
                                $suffixe_fichier = ($id == ($nbre_placemarks - 1) && $num == 1) ? '' : '_'.$num++;
                                if (file_put_contents(sprintf($fichier_sortie, $suffixe_fichier), $sortie)) {
                                        @chmod($fichier_sortie, octdec(Config::get('fichierSortie.droits')));
                                } else {
                                        trigger_error("Impossible d'écrire dans le fichier : $fichier_sortie", E_USER_WARNING);
                                }
                                $placemarks_portion = array();
                        }
                }
        }
    }
    
    private function analyserFichierKml($fichier_kml) {
        $placemarks = array();
        $lignesKML = file($fichier_kml, FILE_SKIP_EMPTY_LINES);
        foreach ($lignesKML as $id => $ligne) {
                if (preg_match('/^\s*<Placemark>/', $ligne)) {
                        if (isset($placemark)) {
                                $placemarks[] = $placemark;
                        }
                        $placemark = '';
                }
                
                $this->trouverFichierId($ligne);
                if (isset($placemark)) {
                        $ligne = $this->remplacerChaines($ligne);
                        $placemark .= $this->traiterLigne($ligne);
                        
                }
        }
        return $placemarks;
    }
    private function trouverFichierId($ligne) {
        if (preg_match('/<Document><Folder><name>([^<]+)<\/name>/', $ligne, $match)) {
                $this->fichier_id = $match[1];
        }
    }
    
    private function remplacerChaines($ligne) {
                $ligne = preg_replace("/^\s+(<[\/]?Placemark>)/", "\t\t$1", $ligne);
                $ligne = preg_replace("/^\s+(<name>)/", "\t\t\t$1", $ligne);
                $ligne = preg_replace("/(<ExtendedData>)(<SchemaData)/", "\t\t$1\n\t\t\t\t$2", $ligne);
                $ligne = preg_replace("/(<\/SchemaData>)(<\/ExtendedData>)/", "\t\t\t$1\n\t\t\t$2", $ligne);
            $ligne = preg_replace('/^\t+(<SimpleData name=")CODE_INSEE(">)/', "\t\t\t\t\t$1code_insee$2", $ligne);
            $ligne = preg_replace('/(schemaUrl="#)'.$this->fichier_id.'(")/', "$1commune$2", $ligne);
            return $ligne;
    }
    
    private function traiterLigne($ligne) {
        $ligne_traitee = $ligne;
        if (preg_match('/^\s*(<Polygon><outerBoundaryIs><LinearRing><coordinates>)([^<]+)([^$]+)/', $ligne, $match)) {
                $debut_chaine_polygone = $match[1];
                $coordonnees = $this->traiterCoordonnees($match[2]);
                $fin_chaine_polygone = $match[3];
                $ligne_traitee = "\t\t\t".$debut_chaine_polygone.$coordonnees.$fin_chaine_polygone;
        } else if (preg_match('/^\s*<Style>.*<\/Style>$/u', $ligne)) {
                $url_style = Config::get('urlStyle');
                $ligne_traitee = "\t\t\t<styleUrl>$url_style#commune-limite</styleUrl>\n";
        } else if (preg_match('/^\t+<SimpleData name="Name">/', $ligne)) {
                 // Ne pas prendre en compte cette ligne
        } else {
                        $ligne_traitee = $ligne;
                }
                return $ligne_traitee;
        }
        
        private function traiterCoordonnees($chaine_coordonnees) {
                $coordonnees = explode(' ', $chaine_coordonnees);
                $geo_points = array();
                foreach ($coordonnees as $coord) {
                        list($lon, $lat) = explode(',', $coord);
                        $geo_points[] = new GeoPoint($lat, $lon);
                }
                $reducteur = new PolylineReducer($geo_points);
                $coordonnees_simplifiees = $reducteur->SimplerLine(Config::get('simplification'));
                
                $polygone_points = array();
                foreach ($coordonnees_simplifiees as $geoPoint) {
                        $lat = str_replace(',', '.', $geoPoint->latitude);
                        $lon = str_replace(',', '.', $geoPoint->longitude);
                        $polygone_points[] = $lon.','.$lat;
                }
                
                $this->traiterInfo("Traitement coordonnées (avt/aprs) : %s/%s", array(count($coordonnees), count($coordonnees_simplifiees)));
                return implode(' ', $polygone_points);
        }
}
?>