Subversion Repositories eFlore/Applications.cel

Compare Revisions

No changes between revisions

Ignore whitespace Rev 2532 → Rev 2533

/trunk/scripts/modules/code_zone_geo/CodeZoneGeo.php
New file
0,0 → 1,295
<?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 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() {
$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 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;
}
}
/trunk/scripts/modules/code_zone_geo/code_zone_geo.sh
New file
0,0 → 1,12
#!/bin/bash
#
# /usr/local/sbin/code_zone_geo.sh : traitement du calcul des codes INSEE et pays du cel
# Aurélien Peronnet [11 avril 2013]
#
while true
do
logger "Lancement script cel::code_zone_geo"
sudo -u apitela /usr/local/bin/php-cli-56 -f /home/apitela/www/scripts/cel/cli.php code_zone_geo -a toutsanscorrespondance -v 0
logger "Arret script cel::code_zone_geo"
sleep 86400
done
Property changes:
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:executable
+*
\ No newline at end of property
/trunk/scripts/modules/code_zone_geo/bibliotheque/Dao.php
New file
0,0 → 1,185
<?php
class Dao extends Bdd {
 
private $temps_derniere_requete = 0;
 
public function rechercherCoordonnees($conditions = array()) {
if(!empty($conditions)) {
$where = 'WHERE '.implode(' AND ', $conditions);
}
$requete = "SELECT longitude, latitude ".
"FROM cel_obs ".
$where.
"GROUP BY longitude , latitude ";
$resultat = $this->recupererTous($requete);
$this->reinitialiserTempsDerniereRequete();
return $resultat;
}
 
public function rechercherCoordonneesFrancaisesSansCorrespondances() {
$conditions = array(
$this->getConditionCoordonneesValides(),
$this->getConditionInfosGeoIncompletes(),
$this->getConditionlimiteeALaFrance(),
$this->getConditionModifObsRecente()
);
return $this->rechercherCoordonnees($conditions);
}
public function rechercherCoordonneesFrancaisesSansCorrespondanceDepuisLeDebut() {
$conditions = array(
$this->getConditionCoordonneesValides(),
$this->getConditionInfosGeoIncompletes(),
$this->getConditionlimiteeALaFrance()
);
return $this->rechercherCoordonnees($conditions);
}
public function rechercherPaysSansCorrespondance() {
$conditions = array(
$this->getConditionCoordonneesValides(),
$this->getConditionSansPays(),
$this->getConditionModifObsRecente()
);
return $this->rechercherCoordonnees($conditions);
}
public function rechercherPaysSansCorrespondanceDepuisLeDebut() {
$conditions = array(
$this->getConditionCoordonneesValides(),
$this->getConditionSansPays()
);
return $this->rechercherCoordonnees($conditions);
}
public function rechercherToutSansCorrespondance() {
$conditions = array(
$this->getConditionCoordonneesValides(),
'('.
$this->getConditionInfosGeoIncompletes().' OR '.
$this->getConditionSansPays().
') ',
$this->getConditionModifObsRecente()
);
return $this->rechercherCoordonnees($conditions);
}
public function rechercherSansCorrespondanceDepuisLeDebut() {
$conditions = array(
$this->getConditionCoordonneesValides(),
'('.
$this->getConditionInfosGeoIncompletes().' OR '.
$this->getConditionSansPays().
') '
);
return $this->rechercherCoordonnees($conditions);
}
private function getConditionModifObsRecente() {
$condition = 'DATE_ADD(date_modification, INTERVAL 25 HOUR) >= CURDATE() ';
return $condition;
}
private function getConditionInfosGeoIncompletes() {
$condition = '('.
'ce_zone_geo IS NULL OR ce_zone_geo = "" OR '.
'zone_geo IS NULL OR zone_geo = "" '.
') ';
return $condition;
}
private function getConditionlimiteeALaFrance() {
$condition = '('.
'(latitude <= 51.071667 AND latitude >= 41.316667) AND '.
'(longitude <= 9.513333 AND longitude >= -5.140278) '.
') ';
return $condition;
}
private function getConditionSansPays() {
$condition = '(pays IS NULL OR pays = "XX" OR pays = "")';
return $condition;
}
private function getConditionCoordonneesValides() {
$condition = '(latitude IS NOT NULL AND longitude IS NOT NULL '.
' AND latitude != 0 AND latitude != "" '.
' AND longitude != 0 AND longitude != "" ) ';
return $condition;
}
 
public function creerColonneCodeInseeCalcule() {
$create = 'ALTER TABLE cel_obs '.
'ADD code_insee_calcule VARCHAR(5) NOT NULL ';
$this->requeter($create);
$this->reinitialiserTempsDerniereRequete();
}
 
public function ajouterCodeInseeCalcule($latitude, $longitude, $code_insee) {
$insert = 'UPDATE cel_obs '.
"SET ".
"code_insee_calcule = ".$this->proteger($code_insee)." ".
"WHERE latitude = ".$this->proteger($latitude)." ".
" AND longitude = ".$this->proteger($longitude)." ";
$this->requeter($insert);
$this->reinitialiserTempsDerniereRequete();
}
 
public function modifierCodeInseeEtZoneGeo($coordonnees) {
$codeP = $this->proteger($coordonnees['code_insee']);
$codeInseeP = $this->proteger('INSEE-C:'.$coordonnees['code_insee']);
$nomP = $this->proteger($coordonnees['nom']);
$update = "UPDATE cel_obs ".
"SET ".
"pays = 'FR', ".
"code_insee_calcule = ".$codeP.", ".
"ce_zone_geo = ".$codeInseeP.", ".
"zone_geo = IF(zone_geo = '' OR zone_geo = NULL, ".$nomP.", zone_geo) ".
"WHERE ".
" latitude = ".$this->proteger($coordonnees['latitude'])." ".
" AND longitude = ".$this->proteger($coordonnees['longitude'])." ";
$this->requeter($update);
$this->reinitialiserTempsDerniereRequete();
}
public function modifierPays($coordonnees) {
$codePaysP = $this->proteger($coordonnees['code_pays']);
$nomP = $this->proteger($coordonnees['nom']);
$update = "UPDATE cel_obs ".
"SET ".
"pays = ".$codePaysP.", ".
"zone_geo = IF(zone_geo = '' OR zone_geo = NULL, ".$nomP.", zone_geo) ".
"WHERE ".
" latitude = ".$this->proteger($coordonnees['latitude'])." ".
" AND longitude = ".$this->proteger($coordonnees['longitude'])." ";
$this->requeter($update);
$this->reinitialiserTempsDerniereRequete();
}
 
// Il peut se passer assez de temps sans qu'aucune requete ne soit effectuée
// (cas d'un grand nombre d'enregistrements à la suite pour lesquels on ne trouve
// aucun département). Pour éviter cela on teste régulièrement la connection
public function testerActiviteConnection() {
$temps_courant = microtime(true);
$temps_depuis_derniere_requete = $temps_courant - $this->temps_derniere_requete;
if($temps_depuis_derniere_requete >= 18) {
$this->ping();
$this->reinitialiserTempsDerniereRequete();
}
}
 
private function reinitialiserTempsDerniereRequete() {
$this->temps_derniere_requete = microtime(true);
}
}
/trunk/scripts/modules/code_insee_commune/CodeInseeCommune.php
File deleted
\ No newline at end of file
/trunk/scripts/modules/code_insee_commune/code_insee_commune.sh
File deleted
/trunk/scripts/modules/code_insee_commune/bibliotheque/Dao.php
File deleted
\ No newline at end of file
/trunk/scripts/configurations/config.defaut.ini
61,4 → 61,5
 
+------------------------------------------------------------------------------------------------------+
; Url de base du service fournissant les zones geographiques
urlZoneGeoTpl = "http://api.tela-botanica.org/service:eflore:0.1/{projet}/nom-commune?lat={latitude}&lon={longitude}";
urlZoneGeoTpl = "http://api.tela-botanica.org/service:eflore:0.1/{projet}/nom-commune?lat={latitude}&lon={longitude}";
urlPaysTpl = "http://api.tela-botanica.org/service:eflore:0.1/osm/zone-admin?lat={latitude}&lon={longitude}";