/opt/lamp/bin/php cli.php code_zone_geo -a tout * - Pour ? : /opt/lamp/bin/php cli.php code_zone_geo -a colonne * - Pour ? : /opt/lamp/bin/php cli.php code_zone_geo -a payssanscorrespondance * - Pour ? : /opt/lamp/bin/php cli.php code_zone_geo -a codeinseesanscorrespondance * * @category CEL * @package Scripts * @subpackage Zones Geo * @author Mathias CHOUET * @author Aurelien PERONNET * @license GPL v3 * @license CECILL v2 * @copyright 1999-2014 Tela Botanica */ 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 commande protected $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() { $this->affecterPaysFranceAuxCommunes(); $liste_coordonnees = $this->dao->rechercherToutSansCorrespondance(); $this->traiterCoordonnees($liste_coordonnees); } protected function calculerToutSansCorrespondanceDepuisLeDebut() { $this->affecterPaysFranceAuxCommunes(); $liste_coordonnees = $this->dao->rechercherSansCorrespondanceDepuisLeDebut(); $this->traiterCoordonnees($liste_coordonnees); } protected function affecterPaysFranceAuxCommunes() { if ($this->mode_verbeux) { echo "-------------------------------------------------------------------\n"; echo " Affectation du pays France aux communes ayant un code INSEE mais pas de pays ... "; } $maj = $this->dao->affecterPaysFranceAuxCommunesRenseignees(); if ($this->mode_verbeux) { echo "OK \n"; echo " ".$maj." commune".($maj > 1 ? 's' : '')." affectée".($maj > 1 ? 's' : '')."\n"; echo "-------------------------------------------------------------------\n"; } } 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 modifier if($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 France if($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ésentes if(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 pays if(!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 pays if(!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; } }