Rev 2536 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php// declare(encoding='UTF-8');/*** Traitement des codes INSEE et des codes pays de la base de données CEL* Permet d'affecter des codes INSEE et des codes pays aux obs possédant des coordonnées mais pas de commune ou de pays.** Utilisation :* - Pour ? : <code>/opt/lamp/bin/php cli.php code_zone_geo -a tout</code>* - Pour ? : <code>/opt/lamp/bin/php cli.php code_zone_geo -a colonne</code>* - Pour ? : <code>/opt/lamp/bin/php cli.php code_zone_geo -a payssanscorrespondance</code>* - Pour ? : <code>/opt/lamp/bin/php cli.php code_zone_geo -a codeinseesanscorrespondance</code>** @category CEL* @package Scripts* @subpackage Zones Geo* @author Mathias CHOUET <mathias@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 CodeZoneGeo extends Script {protected $tableauTaxon;protected $dao;protected $observations;protected $url_service_geo_tpl;protected $url_service_pays_tpl;protected $mode_verbeux = false;// Paramêtres autorisées lors de l'appel au script en ligne de commandeprotected $parametres_autorises = array('-n' => array(true, true, 'Nom du fichier ou du dossier à traiter'));public function executer() {$this->url_service_geo_tpl = Config::get('urlZoneGeoTpl');$this->url_service_pays_tpl = Config::get('urlPaysTpl');$this->dao = new Dao();// Récupération de paramétres// Lancement de l'action demandée$cmd = $this->getParametre('a');$this->mode_verbeux = $this->getParametre('v');switch ($cmd) {case 'tout' :// à effectuer manuellement au premier lancement du script$this->creerColonne();$this->calculerToutSansCorrespondanceDepuisLeDebut();break;case 'colonne' :$this->creerColonne();break;case 'codeinseesanscorrespondance' :$this->calculerCodesInseeSansCorrespondance();break;case 'codeinseesanscorrespondancedepuisledebut' :$this->calculerCodesInseeSansCorrespondanceDepuisLeDebut();break;case 'payssanscorrespondance' :$this->calculerPaysSansCorrespondance();break;case 'payssanscorrespondancedepuisledebut' :$this->calculerPaysSansCorrespondanceDepuisLeDebut();break;case 'toutsanscorrespondance' :// devrait être être l'option utilisée dans le cron quotidien (avec l'option -v 0)$this->calculerToutSansCorrespondance();break;case 'toutsanscorrespondancedepuisledebut' :$this->calculerToutSansCorrespondanceDepuisLeDebut();break;default :$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));}}protected function creerColonne() {$this->dao->creerColonneCodeInseeCalcule();}protected function calculerCodesInseeSansCorrespondance() {$liste_coordonnees = $this->dao->rechercherCoordonneesFrancaisesSansCorrespondances();$this->traiterCoordonnees($liste_coordonnees);}protected function calculerCodesInseeSansCorrespondanceDepuisLeDebut() {$liste_coordonnees = $this->dao->rechercherCoordonneesFrancaisesSansCorrespondanceDepuisLeDebut();$this->traiterCoordonnees($liste_coordonnees);}protected function calculerPaysSansCorrespondance() {$liste_coordonnees = $this->dao->rechercherPaysSansCorrespondance();$this->traiterCoordonnees($liste_coordonnees);}protected function calculerPaysSansCorrespondanceDepuisLeDebut() {$liste_coordonnees = $this->dao->rechercherPaysSansCorrespondanceDepuisLeDebut();$this->traiterCoordonnees($liste_coordonnees);}protected function calculerToutSansCorrespondance() {$liste_coordonnees = $this->dao->rechercherToutSansCorrespondance();$this->traiterCoordonnees($liste_coordonnees);}protected function calculerToutSansCorrespondanceDepuisLeDebut() {$liste_coordonnees = $this->dao->rechercherSansCorrespondanceDepuisLeDebut();$this->traiterCoordonnees($liste_coordonnees);}private function traiterCoordonnees($liste_coordonnees) {$debut = microtime(true);$nb_coordonnees_modifiees = 0;$nb_coordonnees_ignorees = 0;$total = count($liste_coordonnees);if ($this->mode_verbeux) {echo "-------------------------------------------------------------------\n";echo " Calcul des codes INSEE, du code pays et modification (".count($liste_coordonnees)." coordonnées en tout) ... \n";echo " Enrichissement des champs zone geo et ce_zone_geo vides ... \n";echo "-------------------------------------------------------------------\n";}foreach ($liste_coordonnees as $coordonnees) {$infos_coord = $this->obtenirInfosPourCoordonnees($coordonnees);if ($infos_coord != null) {// Le type renvoyé permet de connaitre ce qu'on peut modifierif($infos_coord['type'] == 'france') {// Cas d'une commune française$coordonnee_a_traiter = array('latitude' => $coordonnees['latitude'],'longitude' => $coordonnees['longitude'],'code_insee' => $infos_coord['code_insee'],'nom' => $infos_coord['nom']);$this->dao->modifierCodeInseeEtZoneGeo($coordonnee_a_traiter);} else if($infos_coord['type'] == 'pays') {// Cas d'un lieu à l'étranger$coordonnee_a_traiter = array('latitude' => $coordonnees['latitude'],'longitude' => $coordonnees['longitude'],'code_pays' => $infos_coord['code_pays'],'nom' => $infos_coord['nom']);$this->dao->modifierPays($coordonnee_a_traiter);}$nb_coordonnees_modifiees++;} else {$nb_coordonnees_ignorees++;}if ($this->mode_verbeux) {$this->afficherAvancement(' Coordonnées traitées ', $nb_coordonnees_modifiees);}}$fin = microtime(true);if ($this->mode_verbeux) {echo "\n";echo "-------------------------------------------------------------------\n";echo " Fin de la mise à jour des codes INSEE calculés, du pays et de l'enrichissement, \n";echo " ".($fin - $debut)." secondes écoulées \n";echo " ".$nb_coordonnees_modifiees." code insee calculés et modifiés \n";echo " ".$nb_coordonnees_ignorees." coordonnées ignorées \n";echo "-------------------------------------------------------------------\n";echo "\n";}}private function obtenirInfosPourCoordonnees($coordonnees) {$infos_coord = null;// Test facile qui permet d'abord de tenter une localisation bien plus rapide si les coordonnées// sont dans la bounding box approximative de la Franceif($this->testerCoordonneesWgsFrance($coordonnees['latitude'], $coordonnees['longitude'])) {$infos_coord = $this->chercherInfosCommune('osm', $coordonnees['latitude'], $coordonnees['longitude']);if ($infos_coord == null) {// Sinon recherche par pays$infos_coord = $this->chercherInfosPays($coordonnees['latitude'], $coordonnees['longitude']);}} else {// Recherche par pays immédiate si en dehors de la bouding box française$infos_coord = $this->chercherInfosPays($coordonnees['latitude'], $coordonnees['longitude']);}return $infos_coord;}private function chercherInfosCommune($projet, $latitude, $longitude) {$noms_params = array('{projet}', '{latitude}', '{longitude}');$valeurs_params = array($projet, $latitude, $longitude);$url_service = str_replace($noms_params, $valeurs_params, $this->url_service_geo_tpl);$url_service = str_replace(',', '.', $url_service);$ch = curl_init($url_service);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);$reponse = curl_exec($ch);$infos_coord = $this->traiterReponseServiceCommune($reponse);curl_close($ch);return $infos_coord;}private function chercherInfosPays($latitude, $longitude) {$noms_params = array('{latitude}', '{longitude}');$valeurs_params = array($latitude, $longitude);$url_service = str_replace($noms_params, $valeurs_params, $this->url_service_pays_tpl);$url_service = str_replace(',', '.', $url_service);$ch = curl_init($url_service);curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);$reponse = curl_exec($ch);$res = json_decode($reponse, true);$retour = null;if(!empty($res)) {// Cas où l'on a recherché des coordonnées en France// On en profite pour remplir plus de données// que le simple pays si elles sont présentesif(isset($res[8]) && isset($res[8]['codeInsee'])) {$retour = array('code_insee' => $res[8]['codeInsee'],'nom' => $res[8]['intitule'],'type' => 'france');} else {// Cas de la recherche en dehors de France// La zone de plus haut niveau est toujours un pays// (car le niveau de zone est limité à 2)$infos_pays = $res[min(array_keys($res))];// La zone de niveau le plus bas est la "localité"// la plus précise qu'on a pu trouver$infos_localite = $res[max(array_keys($res))];// Cas où l'on a trouvé un code paysif(!empty($infos_pays['codeIso31661'])) {$retour = array('code_pays' => $infos_pays['codeIso31661'],'nom' => '');} elseif(!empty($infos_pays['codeIso31662'])) {// Quelquefois la zone de plus haut niveau est une région ou une province// heureusement son code est de forme XX-YY ou XX est le code iso du pays !$retour = array('code_pays' => substr($infos_pays['codeIso31662'], 0, 2),'nom' => '');}// Pas de sens de prendre un nom de localité si on a pas de paysif(!empty($retour['code_pays'])) {// Type sert à savoir quelle fonction de mise à jour on appellera$retour['type'] = 'pays';$retour['nom'] = $infos_localite['intitule'];}}}return $retour;}private function traiterReponseServiceCommune($reponse) {$retour = null;$reponse = json_decode($reponse);// cas du service lion 1906 qui peut renvoyer plusieurs communes (on prend la première)if (is_array($reponse)) {$reponse = $reponse[0];}if (isset($reponse->codeINSEE)) {// Type sert à savoir quelle fonction de mise à jour on appellera$retour = array('code_insee' => $reponse->codeINSEE,'nom' => $reponse->nom,'type' => 'france');}return $retour;}private function testerCoordonneesWgsFrance($latitude, $longitude) {$coord_france = false;if ($latitude != '' && $longitude != '') {if ($latitude < 51.071667 && $latitude > 41.316667) {if ($longitude < 9.513333 && $longitude > -5.140278) {$coord_france = true;}}}return $coord_france;}}