Subversion Repositories eFlore/Projets.eflore-projets

Compare Revisions

Ignore whitespace Rev 459 → Rev 460

/trunk/scripts/modules/sophy/Export.php
New file
0,0 → 1,224
<?php
// Encodage : UTF-8
// +-------------------------------------------------------------------------------------------------------------------+
/**
* Export des données de SOPHY
*
* Description : classe permettant d'exporter les tableaux phytosociologiques de la banque de données SOPHY
* Utilisation : php script.php export
*
* @category PHP 5.3
* @package phytosocio
//Auteur original :
* @author Delphine CAUQUIL <delphine@tela-botanica.org>
* @copyright Copyright (c) 2009, 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$
*
* /opt/lampp/bin/php -d memory_limit=2048M cli.php sophy/export -a rien -c publication/strate/flore
* -f annee:sup:1990/auteur:like:ma%/departement:in:14,50,61,76,27/nomsci:like:trifolium%/fournier:neg: >log.txt
*
*
*
* export pour le crpf
*
*
* export pour les plantes de la liste rouge des suisses
* /opt/lampp/bin/php -d memory_limit=2048M cli.php sophy/export -a rien -f nomsci:in:"'Adenophora liliifolia (L.) A. DC.','Adenostyles leucophylla (Willd.) Rchb.','Allium angulosum L.','Allium rotundum L.','Anagallis minima (L.) E. H. L. Krause','Anagallis tenella (L.) L.','Anchusa officinalis L.','Andromeda polifolia L.','Androsace brevis (Hegetschw.) Ces.','Anemone baldensis L.','Anemone sylvestris L.','Anogramma leptophylla (L.) Link','Apium repens (Jacq.) Lag.','Aquilegia einseleana F. W. Schultz','Artemisia nivalis Braun-Blanq.','Asperugo procumbens L.','Asplenium adulterinum Milde','Asplenium billotii F. W. Schultz','Asplenium foreziense Magnier','Astragalus australis (L.) Lam.','Barbarea stricta Andrz.','Blackstonia acuminata (W. D. J. Koch & Ziz) Domin','Bromus grossus DC.','Bufonia paniculata Dubois','Campanula excisa Murith','Campanula latifolia L.','Cardamine kitaibelii Bech.','Cardamine matthioli Moretti','Carduus crispus L.','Carex baldensis L.','Carex fimbriata Schkuhr','Carex hartmanii Cajander','Carpesium cernuum L.','Chenopodium ficifolium Sm.','Chenopodium rubrum L.','Clematis alpina (L.) Mill.','Corydalis intermedia (L.) Mérat','Corydalis solida (L.) Clairv.','Crepis pygmaea L.','Crepis terglouensis (Hacq.) A. Kern.','Cuscuta europaea L.','Cytisus decumbens (Durande) Spach','Cytisus emeriflorus Rchb.','Cytisus nigricans L.','Cytisus scoparius (L.) Link','Deschampsia littoralis (Gaudin) Reut.','Dianthus gratianopolitanus Vill.','Dianthus seguieri Vill.','Diphasiastrum complanatum (L.) Holub','Diplotaxis muralis (L.) DC.','Draba fladnizensis Wulfen','Draba hoppeana Rchb.','Draba ladina Braun-Blanq.','Draba siliquosa M. Bieb.','Draba tomentosa Clairv.','Equisetum ramosissimum Desf.','Eriophorum gracile Roth','Erythronium dens-canis L.','Euonymus latifolius (L.) Mill.','Euphrasia christii Gremli','Falcaria vulgaris Bernh.','Fragaria viridis Duchesne','Gagea pratensis (Pers.) Dumort.','Galeopsis pubescens Besser','Gentiana engadinensis (Wettst.) Braun-Blanq. & Sam.','Geranium rivulare Vill.','Gladiolus imbricatus L.','Gladiolus italicus Mill.','Gladiolus palustris Gaudin','Gratiola officinalis L.','Hammarbya paludosa (L.) Kuntze','Helianthemum salicifolium (L.) Mill.','Iberis saxatilis L.','Inula britannica L.','Inula helvetica Weber','Inula spiraeifolia L.','Isopyrum thalictroides L.','Juniperus sabina L.','Knautia godetii Reut.','Lathyrus sphaericus Retz.','Leucanthemum halleri (Vitman) Ducommun','Leucojum aestivum L.','Linaria alpina subsp. petraea (Jord.) Rouy','Lindernia procumbens (Krock.) Borbás','Linnaea borealis L.','Littorella uniflora (L.) Asch.','Minuartia cherlerioides subsp. rionii (Gremli) Friedrich','Myosotis rehsteineri Wartm.','Myrrhis odorata (L.) Scop.','Nigella arvensis L.','Notholaena marantae (L.) Desv.','Ononis rotundifolia L.','Orchis laxiflora Lam.','Orchis papilionacea L.','Orchis provincialis DC.','Orchis spitzelii W. D. J. Koch','Ostrya carpinifolia Scop.','Pedicularis oederi Hornem.','Peucedanum verticillare (L.) Mert. & W. D. J. Koch','Phyteuma humile Gaudin','Pilularia globulifera L.','Pinguicula grandiflora Lam. s.str.','Polygonum minus Huds.','Potentilla alpicola Fauc.','Potentilla caulescens L.','Potentilla grammopetala Moretti','Potentilla inclinata Vill.','Primula daonensis (Leyb.) Leyb.','Primula latifolia Lapeyr.','Pulmonaria helvetica Bolliger','Ranunculus gramineus L.','Ranunculus parnassiifolius L.','Rhodiola rosea L.','Rhynchospora alba (L.) Vahl','Rumex nivalis Hegetschw.','Sagina nodosa (L.) Fenzl','Saponaria lutea L.','Saxifraga adscendens L.','Saxifraga aphylla Sternb.','Saxifraga diapensioides Bellardi','Saxifraga mutata L.','Scorzonera laciniata L. s.str.','Scutellaria alpina L.','Sedum anacampseros L.','Sedum cepaea L.','Sedum rubens L.','Senecio aquaticus Hill','Senecio halleri Dandy','Senecio incanus subsp. insubricus (Chenevard) Braun-Blanq.','Senecio paludosus L.','Silene pusilla Waldst. & Kit.','Silene suecica (Lodd.) Greuter & Burdet','Sisymbrium supinum L.','Teucrium scordium L.','Thlaspi rotundifolium subsp. corymbosum Gremli','Trifolium saxatile All.','Trochiscanthes nodiflora (All.) W. D. J. Koch','Typha minima Hoppe','Valeriana celtica L.','Valeriana supina Ard.','Viola cenisia L.','Viola elatior Fr.','Viola lutea Huds.','Viola persicifolia Schreb.','Viola pinnata L.','Viola pyrenaica DC.','Woodsia alpina (Bolton) Gray'"/departement:in:14,39,25,90,68,74
*
*/
// +-------------------------------------------------------------------------------------------------------------------+
class Export extends EfloreScript {
protected $tableauTaxon;
protected $dao;
protected $observations;
// Paramêtres autorisées lors de l'appel au script en ligne de commande
protected $parametres_autorises = array(
'-n' => array(false, 'export', 'Nom du fichier à créer'),
'-c' => array(false, 'tous', 'Liste des champs à récupérer'),
'-f' => array(false, true, 'Liste des filtres à executer'));
 
// à utiliser dans les valeurs des parametres pour séparer les champs ou filtres
protected $separateur = "/";
// correspondances parametres/champs de la bd
protected $champs_exportes = array(
"code_identifiant" => "CONCAT(o.so_id_publi,'.',o.so_id_tableau,'.',o.so_id_releve,'.',
o.so_num_ligne,'.',o.so_id_taxon,'.',o.so_id_strate) AS code_identifiant",
"numero_publication" => "sp_id_publi AS numero_publication",
"publication" => "CONCAT (sp_auteur, '. ', sp_revue, ' ', sp_volume, ' ', sp_tome, ' ', sp_fascicule, ', ', sp_date,
'. ', sp_titre, ', p.', sp_page_debut, '-', sp_page_fin, '.') AS publication",
"auteur" => "sp_auteur AS auteur",
"annee" => "sp_date AS annee",
"numero_tableau" => "sr_id_tableau AS numero_tableau",
"numero_releve" => "sr_id_releve AS numero_releve",
"nom_station" => "ss_localisation AS nom_station",
"code_insee" => "IF (ss_code_departement != 0,
CONCAT(ss_code_departement, ss_code_insee_commune), ss_code_insee_calculee) AS code_insee",
"code_insee_calcule" => "ss_code_insee_calculee AS code_insee_calcule",
"altitude" => "ss_altitude AS altitude",
"coordonnees_wgs" => "ss_latitude_wgs, ss_longitude_wgs",
"coordonnees_utm" => "ss_utmEasting, ss_utmNorthing, ss_utmZone",
"precision_geographique" => "ss_ce_precision_geographique",
"nom_scientifique" => "st_nom AS nom_scientifique",
"flore" => "st_ce_num_fournier, st_ce_num_floeur, st_ce_num_algues, st_ce_num_characees, st_ce_num_bryo,
st_ce_num_lichen, st_ce_num_syntri, st_ce_num_bdnff, st_ce_num_ciff, st_ce_num_codefr94",
"strate" => "so_id_strate AS strate",
"code_abondance" => "so_ce_abondance AS code_abondance");
protected $autresChamps = array(
"signification_precision" => "spg_num_precision, spg_valeur",
"signification_strate" => "so_id_strate",
"signification_abondance" => "sa_valeur");
protected $filtres_existants = array(
"annee" => "sp_date",
"auteur" => "sp_auteur",
"departement" => "",
"commune" => "",
"precisiongeo" => "ss_ce_precision_geographique",
"nomsci" => "st_nom",
"fournier" => "st_ce_num_fournier",
"floeur" => "st_ce_num_floeur",
"algues" => "st_ce_num_algues",
"characees" => "st_ce_num_characees",
"bryo" => "st_ce_num_bryo",
"lichen" => "st_ce_num_lichen",
"syntri" => "st_ce_num_syntri",
"bdnff" => "st_ce_num_bdnff",
"ciff" => "st_ce_num_ciff",
"codefr" => "st_ce_num_codefr94");
protected $operateurs = array(
"inf" => "<",
"sup" => ">",
"eg" => "=",
"neg" => "!=",
"infeg" => "<=",
"supeg" => ">=",
"in" => " IN ",
"like" => " LIKE ");
// +-------------------------------------------------------------------------------------------------------------------+
public function executer() {
include_once dirname(__FILE__).'/bibliotheque/Dao.php';
Config::charger(dirname(__FILE__).'/sophy.ini');
$this->dao = new Dao();
// Récupération de paramétres
$requete['nomFichier'] = $this->getParametre('n');
$requete['champs'] = $this->formaterChamps($this->getParametre('c'));
$requete['filtres'] = $this->formaterFiltres($this->getParametre('f'));
$donnees = $this->recupererDonnees($requete);
if ($donnees === false) {
$info = "Pas de données";
} else {
$titre = $this->formaterTitre($this->getParametre('c')); //à revoir
$this->exportCSV($requete['nomFichier'], $titre, $donnees);
}
}
protected function formaterFiltres($filtres) {
$where = array();
if ($filtres != '') {
$liste_filtres = explode($this->separateur, $filtres);
foreach ($liste_filtres as $filtre) {
$morceaux_filtre = explode(':', $filtre);
if (isset($this->filtres_existants[$morceaux_filtre[0]])) {
if (isset($this->operateurs[$morceaux_filtre[1]])) {
$where[] = $this->traiterFiltres($morceaux_filtre);
} else {
echo "L'operateur demandé {$morceaux_filtre[1]} n'existe pas. Les opérateurs existants sont :\n".
implode(', ', array_keys($this->operateurs));
}
} else {
echo "Le filtre demandé {$morceaux_filtre[0]} n'existe pas. Les filtres existants sont :\n".
implode(', ', array_keys($this->filtres_existants));
}
}
$where = ' WHERE '.implode(' AND ', $where);
}
return $where;
}
protected function traiterFiltres($morceaux) {
$where = '';
if ($this->operateurs[$morceaux[1]] == ' IN ') {
$where = $this->operateurs[$morceaux[1]].'('.$morceaux[2].')';
} else {
$where= $this->operateurs[$morceaux[1]].$this->getBdd()->proteger($morceaux[2]);
}
switch ($morceaux[0]) {
case 'departement' :
$where = "( ss_code_departement".$where.
" OR substring( `ss_code_insee_calculee`, -5, 2 ) ".$where.") ";
break;
case 'commune' :
$where = "( CONCAT(ss_code_departement, ss_code_insee_commune) ".$where.
" OR `ss_code_insee_calculee` ".$where.") ";
break;
default : $where= $this->filtres_existants[$morceaux[0]].$where;
break;
}
return $where;
}
protected function formaterChamps($champs_demandes) {
$champs_demandes = explode($this->separateur, $champs_demandes);
if ($champs_demandes[0] == 'tous') {
$champs = implode(', ', array_values($this->champs_exportes));
} else {
foreach ($champs_demandes as $champ) {
if (isset($this->champs_exportes[$champ])) {
$champs[] = $this->champs_exportes[$champ];
} else {
echo "Le champ demandé {$champ} n'existe pas. Les champs existants sont :\n".
implode(', ', array_keys($this->champs_exportes));
}
}
$champs = implode(', ', $champs);
}
return $champs;
}
protected function formaterTitre($champs) {
$liste_champs = ($champs == 'tous') ? array_keys($this->champs_exportes) :explode(',', $champs);
foreach ($liste_champs as $champs) {
switch ($champs) {
case "flore" : $titre[] = "fournier"; $titre[] = "floeur"; $titre[] = "algues"; $titre[] = "characees";
$titre[] = "bryo"; $titre[] = "lichen"; $titre[] = "syntri"; $titre[] = "bdnff"; $titre[] = "ciff";
$titre[] = "code france 94"; break;
case "coordonnees_wgs": $titre[] = "latitude (wgs)"; $titre[] = "longitude (wgs)"; break;
case "coordonnees_utm" :
$titre[] = "Easting (utm)"; $titre[] = "Northing (utm)"; $titre[] = "zone utm"; break;
default: $titre[] = $champs; break;
}
}
return $titre;
}
 
// Requête de création et d'insertion sur table sophy_tapir
public function recupererDonnees($parametre) {
$bdd = new Bdd();
$requete = "SELECT {$parametre['champs']}
FROM sophy_observation o LEFT JOIN sophy_taxon t ON (o.so_id_taxon = t.st_id_taxon)
LEFT JOIN sophy_releve r ON (r.sr_id_publi = o.so_id_publi AND r.sr_id_tableau = o.so_id_tableau AND r.sr_id_releve = o.so_id_releve )
LEFT JOIN sophy_station s ON (r.sr_id_station = s.ss_id_station)
LEFT JOIN sophy_publication p ON (r.sr_id_publi = p.sp_id_publi)
{$parametre['filtres']}";
//INTO OUTFILE '/home/delphine/web/eflore-projets/scripts/{$parametre['nomFichier']}.csv';";
echo $requete;
$reponse = $bdd->recupererTous($requete);
return $reponse;
}
function exportCSV($nomFichier, $titre, $data) {
$outstream = fopen("./{$nomFichier}.csv", 'w');
fputcsv($outstream, $titre, ';', '"');
function __outputCSV(&$vals, $key, $filehandler) {
fputcsv($filehandler, $vals, ';', '"'); //\t = chr(9)
}
array_walk($data, '__outputCSV', $outstream);
fclose($outstream);
}
}
?>
/trunk/scripts/modules/sophy/Insertionflore.php
New file
0,0 → 1,295
<?php
// Encodage : UTF-8
// +-------------------------------------------------------------------------------------------------------------------+
/**
* Traitement des fichiers de la banque de données SOPHY pour insertion
*
* Description : classe permettant d'insérer les flores nécessaires à l'étude des données issues de SOPHY.
* Avant d'utiliser cette classe nettoyer les fichiers pour ne garder que les lignes à insérer.
* Utilisation : php script.php insertionFlore -a test
*
* @category PHP 5.3
* @package phytosocio
//Auteur original :
* @author Delphine CAUQUIL <delphine@tela-botanica.org>
* @copyright Copyright (c) 2009, 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 Insertionflore extends Script {
protected $dao;
protected $dossier;
protected $flore;
protected $parametres_autorises = array(
'-n' => array(true, true, 'Nom du fichier ou du dossier à traiter'));
public function executer() {
include_once dirname(__FILE__).'/bibliotheque/FloreDao.php';
Config::charger(dirname(__FILE__).'/sophy.ini');
$this->dossier = Config::get('dossierDonneesSophy').'FLORE/';
$this->dao = new FloreDao();
// Récupération de paramètres
// Lancement de l'action demandée
$cmd = $this->getParametre('a');
switch ($cmd) {
case 'florenbi' : // fournier
$this->executerFlorenbi();
break;
case 'bdnff' : // bdnff
$this->executerBdnff();
break;
case 'listepla' : // fournier/bdnff
$this->executerListePla();
break;
case 'floeur' : // flora europea
$this->executerFloeur();
break;
case 'bryo' : // bryophyte
$this->executerBryo();
break;
case 'syntri' : //syntri : numéro complémentaire
$this->executerSyntri();
break;
case 'ciff' : // CIFF CIFF/BDNFF
$this->executerCiff();
break;
case 'donneebb' : // Num_nom num_tax bdnff
$this->executerDonneebb();
break;
case 'codefr' : // CODEFR94
$this->executerCodefr();
break;
default :
$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
}
}
 
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement du fichier flore florenbi qui contient tous codes, numéro et nom fournier
// /opt/lampp/bin/php cli.php sophy/insertionflore -a florenbi -n ./../donnees/sophy/2010-12-02/FLORE/FLORENBI
private function executerFlorenbi() {
$nomFichier = $this->dossier.'FLORENBI';
if (file_exists($nomFichier) === true) {
if ( $fichierOuvert = fopen($nomFichier, 'r') ) {
$nom = '';
while ($ligne = fgets($fichierOuvert)) {
if (preg_match('/^\s{2}[\d\s]{4}\s([\d\s]{3}\d)\s{2}([\d\s]\d\.\d\d\.\d)\s[\d\s]{5}[A-Z\s]\s(\d)\s*(.+)$/', $ligne, $champs)) {
// si le rang taxonomique est inf à 4 (subsp et var)
if ($champs[3] < 4) {
$flore[$champs[1]] = $champs[4];
$nom = trim($champs[4]);
} else {
$flore[$champs[1]] = $nom." ".$champs[4];
}
}
}
$info = $this->dao->integrerFlore($flore, 'fournier');
$this->traiterErreur($info);
}
fclose($fichierOuvert);
} else {
$this->traiterErreur("Le fichier {$fichier} n'existe pas.");
}
}
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement du fichier flore florenbi qui contient tous codes, numéro et nom fournier
// /opt/lampp/bin/php cli.php sophy/insertionflore -a florenbi -n ./../donnees/sophy/2010-12-02/FLORE/FLORENBI
private function executerBdnff() {
$nomFichier = $this->dossier.'bdnffv5.csv';
if (file_exists($nomFichier) === true) {
$this->dao->chargerDonnees($nomFichier, 'sophy_bdnff');
} else {
$this->traiterErreur("Le fichier {$nomFichier} n'existe pas.");
}
}
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement du fichier flore listePla qui contient numéro de fournier, nom de fournier, numéro bdnff, nom bdnff
// /opt/lampp/bin/php -d memory_limit=2048M cli.php insertionFlore -a listepla -n ./../doc/jeux_test/FLORE/LISTEPLA.csv
private function executerListePla() {
// Parcours le fichier .csv et enregistre chaque ligne dans un tableau.
$nomFichier = $this->dossier.'LISTEPLA.csv';
if ($nomFichier && file_exists($nomFichier) ){
$extensionFichier = strtolower(strrchr($nomFichier, '.'));
if ($extensionFichier === ".csv"){
$file = new SplFileObject($nomFichier);
$file->setFlags(SplFileObject::SKIP_EMPTY);
$i = 0;
echo "Traitement de LISTEPLA : ";
while (!$file->eof()){
$flore = $this->transformerFournierBdnff($file->fgetcsv());
echo str_repeat(chr(8), ( strlen( $i ) + 1 ))."\t".$i++;
}
echo "\n";
//$info = $this->dao->integrerFlore($this->flore['bdnff'], 'bdnff');
$info .= $this->dao->integrerFlore($this->flore['correspondance'], 'fournier_bdnff');
$this->traiterErreur($info);
} else {
$this->traiterErreur("Le fichier $nomFichier n'est pas au format csv.");
}
} else {
$this->traiterErreur("Le fichier $nomFichier n'existe pas.");
}
}
private function transformerFournierBdnff($ligne_csv){
//$this->flore['bdnff'][$ligne_csv[5]] = $ligne_csv[6];
$this->flore['correspondance'][$ligne_csv[3]] = $ligne_csv[5];
}
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement du fichier flore floeur.bis qui contient numéro et nom de flora europea
// /opt/lampp/bin/php -d memory_limit=2048M cli.php insertionFlore -a floeur -n ./../doc/jeux_test/FLORE/FLOEUR.BIS
private function executerFloeur() {
$nomFichier = $this->dossier.'FLOEUR.BIS';
if (file_exists($nomFichier) === true) {
if ( $fichierOuvert = fopen($nomFichier, 'r') ) {
$i = 0;
while ($ligne = fgets($fichierOuvert)) {
if (preg_match('/^\s[\d\s]{9}[\d\sA-Z]\s([\d\s]{4}\d)\s(.{71})[\s\d]{2}/', $ligne, $champs)) {
$this->flore[$champs[1]] = trim($champs[2]);
}
}
$info = $this->dao->integrerFlore($this->flore, 'flora_europea');
$this->traiterErreur($info);
}
fclose($fichierOuvert);
} else {
$this->traiterErreur("Le fichier {$nomFichier} n'existe pas.");
}
}
 
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement du fichier flore codebry qui contient numéro et nom des bryophytes
// /opt/lampp/bin/php -d memory_limit=2048M cli.php insertionFlore -a bryo -n ./../doc/jeux_test/FLORE/codebry.txt
private function executerBryo() {
$nomFichier = $this->dossier.'codebry.txt';
if (file_exists($nomFichier) === true) {
if ( $fichierOuvert = fopen($nomFichier, 'r') ) {
$i = 0;
while ($ligne = fgets($fichierOuvert)) {
if (preg_match('/^\s([\d\s]{4})\s[\d\s][\d\s]{4}\s{2}\d\s*(.*)\s[\d\s]{4}/', $ligne, $champs)) {
if ($champs[1] != 0) {
$this->flore[$champs[1]] = trim($champs[2]);
}
}
}
$info = $this->dao->integrerFlore($this->flore, 'bryophyte');
$this->traiterErreur($info);
}
fclose($fichierOuvert);
} else {
$this->traiterErreur("Le fichier {$nomFichier} n'existe pas.");
}
}
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement du fichier flore Syntri qui contient numéro de fournier, numéro syntri, nom syntri
// /opt/lampp/bin/php -d memory_limit=2048M cli.php insertionFlore -a syntri -n ./../doc/jeux_test/FLORE/SYNTRI.TXT
private function executerSyntri() {
$nomFichier = $this->dossier.'SYNTRI.TXT';
if (file_exists($nomFichier) === true) {
if ( $fichierOuvert = fopen($nomFichier, 'r') ) {
$i = 0;
while ($ligne = fgets($fichierOuvert)) {
if (preg_match('/^(\d+)\s{2}\d\s([A-Z,\-\'\.()\s]+[A-Z,\-\'\.()])\s+([\d\s]+)$/', trim($ligne), $champs)) {
$syntri = preg_split('/\s+/', $champs[3]);
if (count($syntri) == 3) {
$num = $syntri[1];
} elseif (count($syntri) == 1){
$num = $syntri[0];
}
if (isset($flore['correspondance'][$num])) {
$flore['syntri'][$num] = $flore['syntri'][$num].$champs[2];
} else {
$flore['correspondance'][$num] = $champs[1];
$flore['syntri'][$num] = $champs[2];
}
$i++;
}
}
$info = $this->dao->integrerFlore($flore['syntri'], 'syntri');
$info .= $this->dao->integrerFlore($flore['correspondance'], 'syntri_fournier');
$this->traiterErreur($info);
}
fclose($fichierOuvert);
} else {
$this->traiterErreur("Le fichier {$nomFichier} n'existe pas.");
}
}
// /opt/lampp/bin/php -d memory_limit=2048M cli.php insertionFlore -a ciff -n ./../doc/jeux_test/FLORE/ciff.txt
private function executerCiff() {
$nomFichier = $this->dossier.'ciff.txt';
if (file_exists($nomFichier) === true) {
if ( $fichierOuvert = fopen($nomFichier, 'r') ) {
$i = 0;
while ($ligne = fgets($fichierOuvert)) {
if (preg_match('/^(\d*)\t([A-Za-z].*)\t(\d*)\t\d*/', $ligne, $champs)) {
$flore['ciff'][$champs[1]] = $champs[2];
if ($champs[3] != '') {
$flore['correspondance'][$champs[1]] = $champs[3];
}
}
}
$info = $this->dao->integrerFlore($flore['ciff'], 'ciff');
$info .= $this->dao->integrerFlore($flore['correspondance'], 'ciff_bdnff');
$this->traiterErreur($info);
}
fclose($fichierOuvert);
} else {
$this->traiterErreur("Le fichier {$nomFichier} n'existe pas.");
}
}
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement du fichier flore donneebb.tri qui contient le numero tax t numero nomenclatural de la bdnff
// num_tax||num_nom||num_nom_retenu||?||nom
// /opt/lampp/bin/php -d memory_limit=2048M cli.php insertionFlore -a donneebb -n ./../doc/jeux_test/FLORE/donneebb.tri
private function executerDonneebb() {
$nomFichier = $this->dossier.'donneebb.tri';
if (file_exists($nomFichier) === true) {
if ( $fichierOuvert = fopen($nomFichier, 'r') ) {
while ($ligne = fgets($fichierOuvert)) {
if (preg_match('/^([\d\s]{4}\d)\|([\d\s]{5})\|([\d\s]{5})\|/', $ligne, $champs)) {
if (!isset($this->flore[$champs[1]])) {
$this->flore[$champs[2]]['num_tax'] = $champs[1];
if (trim($champs[3]) != '') {
$this->flore[$champs[2]]['num_nom_retenu'] = $champs[3];
} else {
$this->flore[$champs[2]]['num_nom_retenu'] = $champs[2];
}
}
}
}
$info = $this->dao->ajouterColonnes($this->flore, 'sophy_bdnff');
$this->traiterErreur($info);
}
fclose($fichierOuvert);
} else {
$this->traiterErreur("Le fichier {$nomFichier} n'existe pas.");
}
}
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement du fichier flore codefr94 qui contient numéro et nom codefr94
// /opt/lampp/bin/php -d memory_limit=2048M cli.php insertionFlore -a ciff -n ./../doc/jeux_test/FLORE/CODEFR94
private function executerCodefr() {
$nomFichier = $this->dossier.'CODEFR94';
if (file_exists($nomFichier) === true) {
if ( $fichierOuvert = fopen($nomFichier, 'r') ) {
$i = 0;
while ($ligne = fgets($fichierOuvert)) {
if (preg_match('/^([\d\s]{5})[\d\s]{7}(.*)/', $ligne, $champs)) {
$flore[$champs[1]] = trim($champs[2]);
}
}
$info = $this->dao->integrerFlore($flore, 'codefr94');
$this->traiterErreur($info);
}
fclose($fichierOuvert);
} else {
$this->traiterErreur("Le fichier {$nomFichier} n'existe pas.");
}
}
}
/trunk/scripts/modules/sophy/insertion.ini
New file
0,0 → 1,20
; +------------------------------------------------------------------------------------------------------+
; Général
; Séparateur de dossier
ds = DIRECTORY_SEPARATOR
 
; +------------------------------------------------------------------------------------------------------+
; Info sur l'application
info.nom = Scripts de gestion de la phytosociologie
; Abréviation de l'application
info.abr = sophy
; Version du Framework nécessaire au fonctionnement de cette application
info.framework.version = 0.2
;Encodage de l'application
appli_encodage = "UTF-8"
version="2010-12-02"
dossierSql = "{ref:dossierDonneesEflore}{ref:info.abr}/{ref:version}/"
[fichiers]
structureSql = "sophy.sql"
[chemins]
structureSql = "{ref:dossierSql}{ref:fichiers.structureSql}"
/trunk/scripts/modules/sophy/bibliotheque/gPoint.php
New file
0,0 → 1,534
<?php
/*------------------------------------------------------------------------------
** File: gPoint.php
** Description: PHP class to convert Latitude & Longitude coordinates into
** UTM & Lambert Conic Conformal Northing/Easting coordinates.
** Version: 1.3
** Author: Brenor Brophy
** Email: brenor dot brophy at gmail dot com
** Homepage: brenorbrophy.com
**------------------------------------------------------------------------------
** COPYRIGHT (c) 2005, 2006, 2007, 2008 BRENOR BROPHY
**
** The source code included in this package is free software; you can
** redistribute it and/or modify it under the terms of the GNU General Public
** License as published by the Free Software Foundation. This license can be
** read at:
**
** http://www.opensource.org/licenses/gpl-license.php
**
** This program is distributed in the hope that it will be useful, but WITHOUT
** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
** FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
**------------------------------------------------------------------------------
**
** Code for datum and UTM conversion was converted from C++ code written by
** Chuck Gantz (chuck dot gantz at globalstar dot com) from
** http://www.gpsy.com/gpsinfo/geotoutm/ This URL has many other references to
** useful information concerning conversion of coordinates.
**
** Rev History
** -----------------------------------------------------------------------------
** 1.0 08/25/2005 Initial Release
** 1.1 05/15/2006 Added software license language to header comments
** Fixed an error in the convertTMtoLL() method. The latitude
** calculation had a bunch of variables without $ symbols.
** Fixed an error in convertLLtoTM() method, The $this-> was
** missing in front of a couple of variables. Thanks to Bob
** Robins of Maryland for catching the bugs.
** 1.2 05/18/2007 Added default of NULL to $LongOrigin arguement in convertTMtoLL()
** and convertLLtoTM() to eliminate warning messages when the
** methods are called without a value for $LongOrigin.
** 1.3 02/21/2008 Fixed a bug in the distanceFrom method, where the input parameters
** were not being converted to radians prior to calculating the
** distance. Thanks to Enrico Benco for finding pointing it out.
*/
define ("meter2nm", (1/1852));
define ("nm2meter", 1852);
 
/*------------------------------------------------------------------------------
** class gPoint ... for Geographic Point
**
** This class encapsulates the methods for representing a geographic point on the
** earth in three different coordinate systema. Lat/Long, UTM and Lambert Conic
** Conformal.
*/
class gPoint
{
/* Reference ellipsoids derived from Peter H. Dana's website-
** http://www.colorado.edu/geography/gcraft/notes/datum/datum_f.html
** email: pdana@pdana.com, web page: www.pdana.com
**
** Source:
** Defense Mapping Agency. 1987b. DMA Technical Report: Supplement to Department
** of Defense World Geodetic System 1984 Technical Report. Part I and II.
** Washington, DC: Defense Mapping Agency
*/
var $ellipsoid = array(//Ellipsoid name, Equatorial Radius, square of eccentricity
"Airy" =>array (6377563, 0.00667054),
"Australian National" =>array (6378160, 0.006694542),
"Bessel 1841" =>array (6377397, 0.006674372),
"Bessel 1841 Nambia" =>array (6377484, 0.006674372),
"Clarke 1866" =>array (6378206, 0.006768658),
"Clarke 1880" =>array (6378249, 0.006803511),
"Everest" =>array (6377276, 0.006637847),
"Fischer 1960 Mercury" =>array (6378166, 0.006693422),
"Fischer 1968" =>array (6378150, 0.006693422),
"GRS 1967" =>array (6378160, 0.006694605),
"GRS 1980" =>array (6378137, 0.00669438),
"Helmert 1906" =>array (6378200, 0.006693422),
"Hough" =>array (6378270, 0.00672267),
"International" =>array (6378388, 0.00672267),
"Krassovsky" =>array (6378245, 0.006693422),
"Modified Airy" =>array (6377340, 0.00667054),
"Modified Everest" =>array (6377304, 0.006637847),
"Modified Fischer 1960" =>array (6378155, 0.006693422),
"South American 1969" =>array (6378160, 0.006694542),
"WGS 60" =>array (6378165, 0.006693422),
"WGS 66" =>array (6378145, 0.006694542),
"WGS 72" =>array (6378135, 0.006694318),
"WGS 84" =>array (6378137, 0.00669438));
 
// Properties
var $a; // Equatorial Radius
var $e2; // Square of eccentricity
var $datum; // Selected datum
var $Xp, $Yp; // X,Y pixel location
var $lat, $long; // Latitude & Longitude of the point
var $utmNorthing, $utmEasting, $utmZone; // UTM Coordinates of the point
var $lccNorthing, $lccEasting; // Lambert coordinates of the point
var $falseNorthing, $falseEasting; // Origin coordinates for Lambert Projection
var $latOfOrigin; // For Lambert Projection
var $longOfOrigin; // For Lambert Projection
var $firstStdParallel; // For lambert Projection
var $secondStdParallel; // For lambert Projection
 
// constructor
function gPoint($datum='WGS 84') // Default datum is WGS 84
{
$this->a = $this->ellipsoid[$datum][0]; // Set datum Equatorial Radius
$this->e2 = $this->ellipsoid[$datum][1]; // Set datum Square of eccentricity
$this->datum = $datum; // Save the datum
}
//
// Set/Get X & Y pixel of the point (used if it is being drawn on an image)
//
function setXY($x, $y)
{
$this->Xp = $x; $this->Yp = $y;
}
function Xp() { return $this->Xp; }
function Yp() { return $this->Yp; }
//
// Set/Get/Output Longitude & Latitude of the point
//
function setLongLat($long, $lat)
{
$this->long = $long; $this->lat = $lat;
}
function Lat() { return $this->lat; }
function Long() { return $this->long; }
function printLatLong() { printf("Latitude: %1.5f Longitude: %1.5f",$this->lat, $this->long); }
//
// Set/Get/Output Universal Transverse Mercator Coordinates
//
function setUTM($easting, $northing, $zone='') // Zone is optional
{
$this->utmNorthing = $northing;
$this->utmEasting = $easting;
$this->utmZone = $zone;
}
function N() { return $this->utmNorthing; }
function E() { return $this->utmEasting; }
function Z() { return $this->utmZone; }
function printUTM() { print( "Northing: ".(int)$this->utmNorthing.", Easting: ".(int)$this->utmEasting.", Zone: ".$this->utmZone); }
//
// Set/Get/Output Lambert Conic Conformal Coordinates
//
function setLambert($easting, $northing)
{
$this->lccNorthing = $northing;
$this->lccEasting = $easting;
}
function lccN() { return $this->lccNorthing; }
function lccE() { return $this->lccEasting; }
function printLambert() { print( "Northing: ".(int)$this->lccNorthing.", Easting: ".(int)$this->lccEasting); }
 
//------------------------------------------------------------------------------
//
// Convert Longitude/Latitude to UTM
//
// Equations from USGS Bulletin 1532
// East Longitudes are positive, West longitudes are negative.
// North latitudes are positive, South latitudes are negative
// Lat and Long are in decimal degrees
// Written by Chuck Gantz- chuck dot gantz at globalstar dot com, converted to PHP by
// Brenor Brophy, brenor dot brophy at gmail dot com
//
// UTM coordinates are useful when dealing with paper maps. Basically the
// map will can cover a single UTM zone which is 6 degrees on longitude.
// So you really don't care about an object crossing two zones. You just get a
// second map of the other zone. However, if you happen to live in a place that
// straddles two zones (For example the Santa Babara area in CA straddles zone 10
// and zone 11) Then it can become a real pain having to have two maps all the time.
// So relatively small parts of the world (like say California) create their own
// version of UTM coordinates that are adjusted to conver the whole area of interest
// on a single map. These are called state grids. The projection system is the
// usually same as UTM (i.e. Transverse Mercator), but the central meridian
// aka Longitude of Origin is selected to suit the logitude of the area being
// mapped (like being moved to the central meridian of the area) and the grid
// may cover more than the 6 degrees of lingitude found on a UTM map. Areas
// that are wide rather than long - think Montana as an example. May still
// have to have a couple of maps to cover the whole state because TM projection
// looses accuracy as you move further away from the Longitude of Origin, 15 degrees
// is usually the limit.
//
// Now, in the case where we want to generate electronic maps that may be
// placed pretty much anywhere on the globe we really don't to deal with the
// issue of UTM zones in our coordinate system. We would really just like a
// grid that is fully contigious over the area of the map we are drawing. Similiar
// to the state grid, but local to the area we are interested in. I call this
// Local Transverse Mercator and I have modified the function below to also
// make this conversion. If you pass a Longitude value to the function as $LongOrigin
// then that is the Longitude of Origin that will be used for the projection.
// Easting coordinates will be returned (in meters) relative to that line of
// longitude - So an Easting coordinate for a point located East of the longitude
// of origin will be a positive value in meters, an Easting coordinate for a point
// West of the longitude of Origin will have a negative value in meters. Northings
// will always be returned in meters from the equator same as the UTM system. The
// UTMZone value will be valid for Long/Lat given - thought it is not meaningful
// in the context of Local TM. If a NULL value is passed for $LongOrigin
// then the standard UTM coordinates are calculated.
//
function convertLLtoTM($LongOrigin = NULL)
{
$k0 = 0.9996;
$falseEasting = 0.0;
 
//Make sure the longitude is between -180.00 .. 179.9
$LongTemp = ($this->long+180)-(integer)(($this->long+180)/360)*360-180; // -180.00 .. 179.9;
$LatRad = deg2rad($this->lat);
$LongRad = deg2rad($LongTemp);
 
if (!$LongOrigin)
{ // Do a standard UTM conversion - so findout what zone the point is in
$ZoneNumber = (integer)(($LongTemp + 180)/6) + 1;
// Special zone for South Norway
if( $this->lat >= 56.0 && $this->lat < 64.0 && $LongTemp >= 3.0 && $LongTemp < 12.0 ) // Fixed 1.1
$ZoneNumber = 32;
// Special zones for Svalbard
if( $this->lat >= 72.0 && $this->lat < 84.0 )
{
if( $LongTemp >= 0.0 && $LongTemp < 9.0 ) $ZoneNumber = 31;
else if( $LongTemp >= 9.0 && $LongTemp < 21.0 ) $ZoneNumber = 33;
else if( $LongTemp >= 21.0 && $LongTemp < 33.0 ) $ZoneNumber = 35;
else if( $LongTemp >= 33.0 && $LongTemp < 42.0 ) $ZoneNumber = 37;
}
$LongOrigin = ($ZoneNumber - 1)*6 - 180 + 3; //+3 puts origin in middle of zone
//compute the UTM Zone from the latitude and longitude
$this->utmZone = sprintf("%d%s", $ZoneNumber, $this->UTMLetterDesignator());
// We also need to set the false Easting value adjust the UTM easting coordinate
$falseEasting = 500000.0;
}
$LongOriginRad = deg2rad($LongOrigin);
 
$eccPrimeSquared = ($this->e2)/(1-$this->e2);
 
$N = $this->a/sqrt(1-$this->e2*sin($LatRad)*sin($LatRad));
$T = tan($LatRad)*tan($LatRad);
$C = $eccPrimeSquared*cos($LatRad)*cos($LatRad);
$A = cos($LatRad)*($LongRad-$LongOriginRad);
 
$M = $this->a*((1 - $this->e2/4 - 3*$this->e2*$this->e2/64 - 5*$this->e2*$this->e2*$this->e2/256)*$LatRad
- (3*$this->e2/8 + 3*$this->e2*$this->e2/32 + 45*$this->e2*$this->e2*$this->e2/1024)*sin(2*$LatRad)
+ (15*$this->e2*$this->e2/256 + 45*$this->e2*$this->e2*$this->e2/1024)*sin(4*$LatRad)
- (35*$this->e2*$this->e2*$this->e2/3072)*sin(6*$LatRad));
$this->utmEasting = ($k0*$N*($A+(1-$T+$C)*$A*$A*$A/6
+ (5-18*$T+$T*$T+72*$C-58*$eccPrimeSquared)*$A*$A*$A*$A*$A/120)
+ $falseEasting);
 
$this->utmNorthing = ($k0*($M+$N*tan($LatRad)*($A*$A/2+(5-$T+9*$C+4*$C*$C)*$A*$A*$A*$A/24
+ (61-58*$T+$T*$T+600*$C-330*$eccPrimeSquared)*$A*$A*$A*$A*$A*$A/720)));
if($this->lat < 0)
$this->utmNorthing += 10000000.0; //10000000 meter offset for southern hemisphere
}
//
// This routine determines the correct UTM letter designator for the given latitude
// returns 'Z' if latitude is outside the UTM limits of 84N to 80S
// Written by Chuck Gantz- chuck dot gantz at globalstar dot com, converted to PHP by
// Brenor Brophy, brenor dot brophy at gmail dot com
//
function UTMLetterDesignator()
{
if((84 >= $this->lat) && ($this->lat >= 72)) $LetterDesignator = 'X';
else if((72 > $this->lat) && ($this->lat >= 64)) $LetterDesignator = 'W';
else if((64 > $this->lat) && ($this->lat >= 56)) $LetterDesignator = 'V';
else if((56 > $this->lat) && ($this->lat >= 48)) $LetterDesignator = 'U';
else if((48 > $this->lat) && ($this->lat >= 40)) $LetterDesignator = 'T';
else if((40 > $this->lat) && ($this->lat >= 32)) $LetterDesignator = 'S';
else if((32 > $this->lat) && ($this->lat >= 24)) $LetterDesignator = 'R';
else if((24 > $this->lat) && ($this->lat >= 16)) $LetterDesignator = 'Q';
else if((16 > $this->lat) && ($this->lat >= 8)) $LetterDesignator = 'P';
else if(( 8 > $this->lat) && ($this->lat >= 0)) $LetterDesignator = 'N';
else if(( 0 > $this->lat) && ($this->lat >= -8)) $LetterDesignator = 'M';
else if((-8 > $this->lat) && ($this->lat >= -16)) $LetterDesignator = 'L';
else if((-16 > $this->lat) && ($this->lat >= -24)) $LetterDesignator = 'K';
else if((-24 > $this->lat) && ($this->lat >= -32)) $LetterDesignator = 'J';
else if((-32 > $this->lat) && ($this->lat >= -40)) $LetterDesignator = 'H';
else if((-40 > $this->lat) && ($this->lat >= -48)) $LetterDesignator = 'G';
else if((-48 > $this->lat) && ($this->lat >= -56)) $LetterDesignator = 'F';
else if((-56 > $this->lat) && ($this->lat >= -64)) $LetterDesignator = 'E';
else if((-64 > $this->lat) && ($this->lat >= -72)) $LetterDesignator = 'D';
else if((-72 > $this->lat) && ($this->lat >= -80)) $LetterDesignator = 'C';
else $LetterDesignator = 'Z'; //This is here as an error flag to show that the Latitude is outside the UTM limits
 
return($LetterDesignator);
}
 
//------------------------------------------------------------------------------
//
// Convert UTM to Longitude/Latitude
//
// Equations from USGS Bulletin 1532
// East Longitudes are positive, West longitudes are negative.
// North latitudes are positive, South latitudes are negative
// Lat and Long are in decimal degrees.
// Written by Chuck Gantz- chuck dot gantz at globalstar dot com, converted to PHP by
// Brenor Brophy, brenor dot brophy at gmail dot com
//
// If a value is passed for $LongOrigin then the function assumes that
// a Local (to the Longitude of Origin passed in) Transverse Mercator
// coordinates is to be converted - not a UTM coordinate. This is the
// complementary function to the previous one. The function cannot
// tell if a set of Northing/Easting coordinates are in the North
// or South hemesphere - they just give distance from the equator not
// direction - so only northern hemesphere lat/long coordinates are returned.
// If you live south of the equator there is a note later in the code
// explaining how to have it just return southern hemesphere lat/longs.
//
function convertTMtoLL($LongOrigin = NULL)
{
$k0 = 0.9996;
$e1 = (1-sqrt(1-$this->e2))/(1+sqrt(1-$this->e2));
$falseEasting = 0.0;
$y = $this->utmNorthing;
 
if (!$LongOrigin)
{ // It is a UTM coordinate we want to convert
sscanf($this->utmZone,"%d%s",$ZoneNumber,$ZoneLetter);
if($ZoneLetter >= 'N')
$NorthernHemisphere = 1;//point is in northern hemisphere
else
{
$NorthernHemisphere = 0;//point is in southern hemisphere
$y -= 10000000.0;//remove 10,000,000 meter offset used for southern hemisphere
}
$LongOrigin = ($ZoneNumber - 1)*6 - 180 + 3; //+3 puts origin in middle of zone
$falseEasting = 500000.0;
}
 
// $y -= 10000000.0; // Uncomment line to make LOCAL coordinates return southern hemesphere Lat/Long
$x = $this->utmEasting - $falseEasting; //remove 500,000 meter offset for longitude
 
$eccPrimeSquared = ($this->e2)/(1-$this->e2);
 
$M = $y / $k0;
$mu = $M/($this->a*(1-$this->e2/4-3*$this->e2*$this->e2/64-5*$this->e2*$this->e2*$this->e2/256));
 
$phi1Rad = $mu + (3*$e1/2-27*$e1*$e1*$e1/32)*sin(2*$mu)
+ (21*$e1*$e1/16-55*$e1*$e1*$e1*$e1/32)*sin(4*$mu)
+(151*$e1*$e1*$e1/96)*sin(6*$mu);
$phi1 = rad2deg($phi1Rad);
 
$N1 = $this->a/sqrt(1-$this->e2*sin($phi1Rad)*sin($phi1Rad));
$T1 = tan($phi1Rad)*tan($phi1Rad);
$C1 = $eccPrimeSquared*cos($phi1Rad)*cos($phi1Rad);
$R1 = $this->a*(1-$this->e2)/pow(1-$this->e2*sin($phi1Rad)*sin($phi1Rad), 1.5);
$D = $x/($N1*$k0);
 
$tlat = $phi1Rad - ($N1*tan($phi1Rad)/$R1)*($D*$D/2-(5+3*$T1+10*$C1-4*$C1*$C1-9*$eccPrimeSquared)*$D*$D*$D*$D/24
+(61+90*$T1+298*$C1+45*$T1*$T1-252*$eccPrimeSquared-3*$C1*$C1)*$D*$D*$D*$D*$D*$D/720); // fixed in 1.1
$this->lat = rad2deg($tlat);
 
$tlong = ($D-(1+2*$T1+$C1)*$D*$D*$D/6+(5-2*$C1+28*$T1-3*$C1*$C1+8*$eccPrimeSquared+24*$T1*$T1)
*$D*$D*$D*$D*$D/120)/cos($phi1Rad);
$this->long = $LongOrigin + rad2deg($tlong);
}
 
//------------------------------------------------------------------------------
// Configure a Lambert Conic Conformal Projection
//
// falseEasting & falseNorthing are just an offset in meters added to the final
// coordinate calculated.
//
// longOfOrigin & LatOfOrigin are the "center" latitiude and longitude of the
// area being projected. All coordinates will be calculated in meters relative
// to this point on the earth.
//
// firstStdParallel & secondStdParallel are the two lines of longitude (that
// is they run east-west) that define where the "cone" intersects the earth.
// Simply put they should bracket the area being projected.
//
// google is your friend to find out more
//
function configLambertProjection ($falseEasting, $falseNorthing,
$longOfOrigin, $latOfOrigin,
$firstStdParallel, $secondStdParallel)
{
$this->falseEasting = $falseEasting;
$this->falseNorthing = $falseNorthing;
$this->longOfOrigin = $longOfOrigin;
$this->latOfOrigin = $latOfOrigin;
$this->firstStdParallel = $firstStdParallel;
$this->secondStdParallel = $secondStdParallel;
}
 
//------------------------------------------------------------------------------
//
// Convert Longitude/Latitude to Lambert Conic Easting/Northing
//
// This routine will convert a Latitude/Longitude coordinate to an Northing/
// Easting coordinate on a Lambert Conic Projection. The configLambertProjection()
// function should have been called prior to this one to setup the specific
// parameters for the projection. The Northing/Easting parameters calculated are
// in meters (because the datum used is in meters) and are relative to the
// falseNorthing/falseEasting coordinate. Which in turn is relative to the
// Lat/Long of origin The formula were obtained from URL:
// http://www.ihsenergy.com/epsg/guid7_2.html.
// Code was written by Brenor Brophy, brenor dot brophy at gmail dot com
//
function convertLLtoLCC()
{
$e = sqrt($this->e2);
 
$phi = deg2rad($this->lat); // Latitude to convert
$phi1 = deg2rad($this->firstStdParallel); // Latitude of 1st std parallel
$phi2 = deg2rad($this->secondStdParallel); // Latitude of 2nd std parallel
$lamda = deg2rad($this->long); // Lonitude to convert
$phio = deg2rad($this->latOfOrigin); // Latitude of Origin
$lamdao = deg2rad($this->longOfOrigin); // Longitude of Origin
 
$m1 = cos($phi1) / sqrt(( 1 - $this->e2*sin($phi1)*sin($phi1)));
$m2 = cos($phi2) / sqrt(( 1 - $this->e2*sin($phi2)*sin($phi2)));
$t1 = tan((pi()/4)-($phi1/2)) / pow(( ( 1 - $e*sin($phi1) ) / ( 1 + $e*sin($phi1) )),$e/2);
$t2 = tan((pi()/4)-($phi2/2)) / pow(( ( 1 - $e*sin($phi2) ) / ( 1 + $e*sin($phi2) )),$e/2);
$to = tan((pi()/4)-($phio/2)) / pow(( ( 1 - $e*sin($phio) ) / ( 1 + $e*sin($phio) )),$e/2);
$t = tan((pi()/4)-($phi /2)) / pow(( ( 1 - $e*sin($phi ) ) / ( 1 + $e*sin($phi ) )),$e/2);
$n = (log($m1)-log($m2)) / (log($t1)-log($t2));
$F = $m1/($n*pow($t1,$n));
$rf = $this->a*$F*pow($to,$n);
$r = $this->a*$F*pow($t,$n);
$theta = $n*($lamda - $lamdao);
 
$this->lccEasting = $this->falseEasting + $r*sin($theta);
$this->lccNorthing = $this->falseNorthing + $rf - $r*cos($theta);
}
//------------------------------------------------------------------------------
//
// Convert Easting/Northing on a Lambert Conic projection to Longitude/Latitude
//
// This routine will convert a Lambert Northing/Easting coordinate to an
// Latitude/Longitude coordinate. The configLambertProjection() function should
// have been called prior to this one to setup the specific parameters for the
// projection. The Northing/Easting parameters are in meters (because the datum
// used is in meters) and are relative to the falseNorthing/falseEasting
// coordinate. Which in turn is relative to the Lat/Long of origin The formula
// were obtained from URL http://www.ihsenergy.com/epsg/guid7_2.html. Code
// was written by Brenor Brophy, brenor dot brophy at gmail dot com
//
function convertLCCtoLL()
{
$e = sqrt($this->e2);
 
$phi1 = deg2rad($this->firstStdParallel); // Latitude of 1st std parallel
$phi2 = deg2rad($this->secondStdParallel); // Latitude of 2nd std parallel
$phio = deg2rad($this->latOfOrigin); // Latitude of Origin
$lamdao = deg2rad($this->longOfOrigin); // Longitude of Origin
$E = $this->lccEasting;
$N = $this->lccNorthing;
$Ef = $this->falseEasting;
$Nf = $this->falseNorthing;
 
$m1 = cos($phi1) / sqrt(( 1 - $this->e2*sin($phi1)*sin($phi1)));
$m2 = cos($phi2) / sqrt(( 1 - $this->e2*sin($phi2)*sin($phi2)));
$t1 = tan((pi()/4)-($phi1/2)) / pow(( ( 1 - $e*sin($phi1) ) / ( 1 + $e*sin($phi1) )),$e/2);
$t2 = tan((pi()/4)-($phi2/2)) / pow(( ( 1 - $e*sin($phi2) ) / ( 1 + $e*sin($phi2) )),$e/2);
$to = tan((pi()/4)-($phio/2)) / pow(( ( 1 - $e*sin($phio) ) / ( 1 + $e*sin($phio) )),$e/2);
$n = (log($m1)-log($m2)) / (log($t1)-log($t2));
$F = $m1/($n*pow($t1,$n));
$rf = $this->a*$F*pow($to,$n);
$r_ = sqrt( pow(($E-$Ef),2) + pow(($rf-($N-$Nf)),2) );
$t_ = pow($r_/($this->a*$F),(1/$n));
$theta_ = atan(($E-$Ef)/($rf-($N-$Nf)));
 
$lamda = $theta_/$n + $lamdao;
$phi0 = (pi()/2) - 2*atan($t_);
$phi1 = (pi()/2) - 2*atan($t_*pow(((1-$e*sin($phi0))/(1+$e*sin($phi0))),$e/2));
$phi2 = (pi()/2) - 2*atan($t_*pow(((1-$e*sin($phi1))/(1+$e*sin($phi1))),$e/2));
$phi = (pi()/2) - 2*atan($t_*pow(((1-$e*sin($phi2))/(1+$e*sin($phi2))),$e/2));
$this->lat = rad2deg($phi);
$this->long = rad2deg($lamda);
}
 
//------------------------------------------------------------------------------
// This is a useful function that returns the Great Circle distance from the
// gPoint to another Long/Lat coordinate
//
// Result is returned as meters
//
function distanceFrom($lon1, $lat1)
{
$lon1 = deg2rad($lon1); $lat1 = deg2rad($lat1); // Added in 1.3
$lon2 = deg2rad($this->Long()); $lat2 = deg2rad($this->Lat());
$theta = $lon2 - $lon1;
$dist = acos(sin($lat1) * sin($lat2) + cos($lat1) * cos($lat2) * cos($theta));
 
// Alternative formula supposed to be more accurate for short distances
// $dist = 2*asin(sqrt( pow(sin(($lat1-$lat2)/2),2) + cos($lat1)*cos($lat2)*pow(sin(($lon1-$lon2)/2),2)));
return ( $dist * 6366710 ); // from http://williams.best.vwh.net/avform.htm#GCF
}
 
//------------------------------------------------------------------------------
// This function also calculates the distance between two points. In this case
// it just uses Pythagoras's theorm using TM coordinates.
//
function distanceFromTM(&$pt)
{
$E1 = $pt->E(); $N1 = $pt->N();
$E2 = $this->E(); $N2 = $this->N();
$dist = sqrt(pow(($E1-$E2),2)+pow(($N1-$N2),2));
return $dist;
}
 
//------------------------------------------------------------------------------
// This function geo-references a geoPoint to a given map. This means that it
// calculates the x,y pixel coordinate that coresponds to the Lat/Long value of
// the geoPoint. The calculation is done using the Transverse Mercator(TM)
// coordinates of the gPoint with respect to the TM coordinates of the center
// point of the map. So this only makes sense if you are using Local TM
// projection.
//
// $rX & $rY are the pixel coordinates that corespond to the Northing/Easting
// ($rE/$rN) coordinate it is to this coordinate that the point will be
// geo-referenced. The $LongOrigin is needed to make sure the Easting/Northing
// coordinates of the point are correctly converted.
//
function gRef($rX, $rY, $rE, $rN, $Scale, $LongOrigin)
{
$this->convertLLtoTM($LongOrigin);
$x = (($this->E() - $rE) / $Scale) // The easting in meters times the scale to get pixels
// is relative to the center of the image so adjust to
+ ($rX); // the left coordinate.
$y = $rY - // Adjust to bottom coordinate.
(($rN - $this->N()) / $Scale); // The northing in meters
// relative to the equator. Subtract center point northing
// to get relative to image center and convert meters to pixels
$this->setXY((int)$x,(int)$y); // Save the geo-referenced result.
}
} // end of class gPoint
 
?>
/trunk/scripts/modules/sophy/bibliotheque/Dao.php
New file
0,0 → 1,175
<?php
class Dao extends Bdd {
 
// +-------------------------------------------------------------------------------------------------------------------+
// Requête d'intégration sur table sophy_publication
public function integrerBiblio($biblio){
$biblio = array_map(array($this, 'proteger'), $biblio);
$requete = 'INSERT INTO sophy_publication VALUES ('.implode(', ', $biblio).');';
$resultat = $this->requeter($requete);
if ($resultat === false) {
$info = $biblio['id_publi']." n'est pas intégrée.\n";
} else {
$info = $biblio['id_publi']." est intégrée.\n";
}
return $info;
}
// +-------------------------------------------------------------------------------------------------------------------+
// Requête d'intégration sur table sophy_tableau
public function integrerTableau($titre) {
$titre = array_map(array($this, 'proteger'), $titre);
$requete_integre_tableau = 'INSERT INTO sophy_tableau VALUES ('.implode(', ', $titre).');';
$reponse_requete_int_tab = $this->requeter($requete_integre_tableau);
if ($reponse_requete_int_tab === false) {
$info = "tableau ".$titre['numPubli']."-".$titre['numTableau']." non intégrée.";
} else {
$info = '';
}
return $info;
}
// +-------------------------------------------------------------------------------------------------------------------+
// Requêtes sur table sophy_station
// Requête d'intégration qui retourne l'id de la dernière station insérée (rechercheIdStation)
public function integrerStation($station) {
$station = array_map(array($this, 'proteger'), $station);
$reponse['id_station'] = null;
$requete_integre_station = 'INSERT INTO sophy_station (`ss_num_source`, `ss_poste_meteo`, `ss_localisation`,
`ss_latitude`, `ss_pays`, `ss_longitude`,`ss_code_departement`, `ss_altitude`, `ss_code_insee_commune`,
`ss_ce_precision_geographique`, `ss_systeme_projection`, `ss_latitude_dms`, `ss_longitude_dms`, `ss_latitude_wgs`,
`ss_longitude_wgs`, `ss_utmNorthing`, `ss_utmEasting`, `ss_utmZone`) VALUES
('.implode(', ', $station).');';
$reponse_requete_int_stat = $this->requeter($requete_integre_station);
if ($reponse_requete_int_stat === false) {
$reponse['info'] = "station ".$station['numSource']." non intégrée. $requete_integre_station";
} else {
$reponse['id_station'] = $this->rechercheIdStation();
$reponse['info'] = '';
}
return $reponse;
}
// Retourne le dernier identifiant de la table station
public function rechercheIdStation() {
$requete_select_id = "SELECT MAX(ss_id_station) as idMax FROM sophy_station;";
$resultat_requete_id = $this->recuperer($requete_select_id);
return $resultat_requete_id['idMax'];
}
public function rechercherCoordonneesWgs() {
$requete = "SELECT `ss_longitude_wgs` as longitude, `ss_latitude_wgs` as latitude
FROM `sophy_station`
GROUP BY `longitude` , `latitude`";
/* Les stations restantes avec coordonnées sans code insee
SELECT COUNT( * ) AS `Lignes` , `ss_longitude_wgs` , `ss_latitude_wgs`
FROM `sophy_station`
WHERE `ss_latitude_wgs` != ''
AND `ss_code_insee_calculee` =0
GROUP BY `ss_longitude_wgs` , `ss_latitude_wgs`
ORDER BY `Lignes` DESC
*/
$resultat = $this->recupererTous($requete);
return $resultat;
}
public function creerColonneCodeInseeCalculee() {
$create = "ALTER TABLE `sophy_station` ADD `ss_code_insee_calculee` VARCHAR( 5 ) NOT NULL ,
ADD INDEX ( `ss_code_insee_calculee` )";
$this->requeter($create);
}
public function ajouterCodeInseeCalculee($latitude, $longitude, $code_insee) {
$insert = "UPDATE `sophy_station` SET `ss_code_insee_calculee` = '$code_insee' ".
"WHERE ss_latitude_wgs = '$latitude' AND ss_longitude_wgs = '$longitude'";
$this->requeter($insert);
}
// +-------------------------------------------------------------------------------------------------------------------+
// Requête d'intégration sur table sophy_releve
public function integrerReleve($titre, $numReleve, $idStation) {
$requete_integre_releve = "INSERT INTO sophy_releve VALUES (".$titre['numPubli'].", ".
$titre['numTableau'].", ".$numReleve.", ".$idStation.");";
$reponse_requete_int_tab = $this->requeter($requete_integre_releve);
if ($reponse_requete_int_tab === false) {
$info = "releve ".$titre['numPubli']."-".$titre['numTableau']."-".$numReleve." non intégrée.";
echo $requete_integre_releve."\n";
} else {
$info = '';
}
return $info;
}
// +-------------------------------------------------------------------------------------------------------------------+
// Requête d'intégration sur table sophy_observation
public function integrerObservation($observations) {
$requete = "INSERT INTO `sophy_observation` (`so_id_publi`, `so_id_tableau`, `so_id_releve`, `so_num_ligne`,".
" `so_id_taxon`, `so_id_strate`, `so_ce_abondance`) VALUES ";
foreach ($observations as $plante) {
if (isset($plante)) {
foreach ($plante as $observation) {
$observation = array_map(array($this, 'proteger'), $observation);
$requete .= " (".implode(', ', $observation)." ),";
}
}
}
$requete = substr($requete,0,-1).";";
$resultat = $this->requeter($requete);
if ($resultat === false) {
echo $requete."\n";
$info = " n'est pas intégrée.\n";
} else {
$info = '';
}
return $info;
}
// +-------------------------------------------------------------------------------------------------------------------+
// Requête pour calculer les statistiques sur toutes les tables
public function getNombreLigne($tables) {
$requete = null;
foreach ($tables as $nomTable => $colonnes) {
$requete = "SELECT COUNT(*) as nombreTotal";
foreach ($colonnes as $recherche => $nom) {
$requete .= ", count(distinct {$recherche}) as {$nom}";
}
$requete .= " FROM {$nomTable}; ";
$resultat[$nomTable] = $this->recupererTous($requete);
}
return $resultat;
}
// +-------------------------------------------------------------------------------------------------------------------+
// Requête de création et d'insertion sur table sophy_tapir
public function creerTapir() {
$info = 'Créé';
$requete = "DROP TABLE IF EXISTS `sophy_tapir`;
CREATE table `sophy_tapir` AS
SELECT CONCAT(_utf8'urn:lsid:tela-botanica.org:sophy:',o.so_id_publi,'.',
o.so_id_tableau,'.',o.so_id_releve,'.',o.so_num_ligne,'.',
o.so_id_taxon,'.',o.so_id_strate) AS `guid`,
CONCAT(o.so_id_publi,'.',o.so_id_tableau,'.',o.so_id_releve,'.',
o.so_num_ligne,'.',o.so_id_taxon,'.',o.so_id_strate) AS `observation_id`,
p.sp_date AS observation_date,
t.st_nom AS nom_scientifique_complet,
CONCAT(s.ss_code_departement,s.ss_code_insee_commune) AS lieu_commune_code_insee,
s.ss_localisation AS `lieu_station_nom`,
s.ss_latitude_wgs AS `lieu_station_latitude`,
s.ss_longitude_wgs AS `lieu_station_longitude`,
s.ss_utmEasting AS `lieu_station_utm_est`,
s.ss_utmNorthing AS `lieu_station_utm_nord`,
s.ss_utmZone AS `lieu_station_utm_zone`,
p.sp_auteur AS observateur_nom_complet
FROM sophy_observation o LEFT JOIN sophy_taxon t ON (o.so_id_taxon = t.st_id_taxon)
LEFT JOIN sophy_releve r ON (r.sr_id_publi = o.so_id_publi AND r.sr_id_tableau = o.so_id_tableau AND r.sr_id_releve = o.so_id_releve )
LEFT JOIN sophy_station s ON (r.sr_id_station = s.ss_id_station)
LEFT JOIN sophy_publication p ON (r.sr_id_publi = p.sp_id_publi);";
$reponse = $this->requeter($requete);
if ($reponse === false) {
$info = "Erreur";
}
return $info;
}
}
?>
/trunk/scripts/modules/sophy/bibliotheque/FloreDao.php
New file
0,0 → 1,74
<?php
class FloreDao extends Bdd {
 
public function integrerFlore($flore, $nom_flore){
$flore = array_map(array($this, 'proteger'), $flore);
$requete = "INSERT INTO sophy_{$nom_flore} VALUES ";
$i = 0; $j = 1000; $info = '';
foreach ($flore as $num => $nom) {
if ($i < $j) {
$requete .= " ({$num}, {$nom}), ";
} else {
$requete = substr($requete,0,-2).";";
$resultat = $this->requeter($requete);
if ($resultat === false) {
$info .= $nom_flore.$j." n'est pas intégrée.\n";
} else {
$info .= $nom_flore.$j." est intégrée.\n";
}
$j += 1000;
$requete = "INSERT INTO sophy_{$nom_flore} VALUES ({$num}, {$nom}), ";
}
$i++;
}
$requete = substr($requete,0,-2).";";
$resultat = $this->requeter($requete);
if ($resultat === false) {
$info .= $nom_flore.$i." n'est pas intégrée.\n";
//echo $requete."\n";
} else {
$info .= $nom_flore.$i." est intégrée.\n";
}
return $info;
}
public function chargerDonnees($fichier, $table) {
$requete = "LOAD DATA INFILE '$fichier' ".
"REPLACE INTO TABLE $table ".
"CHARACTER SET utf8 ".
"FIELDS
TERMINATED BY ','";
$this->requeter($requete);
}
public function ajouterColonnes($donnees, $table) {
$this->preparerTable($table, 'sb_num_nom_retenu');
$this->preparerTable($table, 'sb_num_tax');
$this->lancerRequeteModification($table, $donnees);
}
private function preparerTable($table, $colonne) {
$requete = "SHOW COLUMNS FROM {$table} LIKE '{$colonne}' ";
$resultat = $this->recuperer($requete);
if ($resultat === false) {
$requete = "ALTER TABLE {$table} ".
"ADD {$colonne} INT(5) ";
$this->requeter($requete);
}
}
private function lancerRequeteModification($table, $flore) {
foreach ($flore as $num_nom => $info) {
$requete = "UPDATE {$table} ".
"SET sb_num_nom_retenu = {$info['num_nom_retenu']} ".
", sb_num_tax = {$info['num_tax']} ".
"WHERE sb_id_num_bdnff = $num_nom ";//echo $requete."\n";
$res = $this->requeter($requete);
if ($res === false) {
$this->traiterErreur("erreur d'insertion pour le tuple %s", array($id));
}
}
}
}
?>
/trunk/scripts/modules/sophy/bibliotheque/TaxonDao.php
New file
0,0 → 1,279
<?php
class TaxonDao extends Bdd {
// tableau de la forme $taxons[num][flore][id]
// $taxons[num][flore][nom]
protected $taxons = array();
private $id = 0;
private $flores = array('syntri', 'ciff', 'codefr94', 'bdnff', 'bryo', 'floeur', 'algues', 'characees', 'lichen', 'fournier');
private $table_flores = array('bdnff', 'fournier', 'ciff', 'syntri', 'codefr94', 'bryo', 'floeur');
public function __construct() {
Bdd::__construct();
$this->id = $this->chargerId() + 1;
$this->taxons = $this->chargerTaxon();
}
// recherche si un taxon existe sinon le crée et renvoie son id
public function getId($num_taxon, $flore = 'ind', $nom = null, $flore_supp = null, $num_supp = null, $remarques = '') {
$idTaxon = null; $nom_supp = $nom;
if ($nom == null && $remarques != '') {
$nom = "rem:".$flore_supp.$num_supp.'/'.$remarques;
}
 
if (isset($this->taxons['ind'][$nom]['id'])) {
$idTaxon = $this->taxons['ind'][$nom]['id'];
} elseif (isset($this->taxons[$flore][$num_taxon]['id']) && $nom == null) {
$idTaxon = $this->taxons[$flore][$num_taxon]['id'];
} else {
$idTaxon = $this->ajouterTaxon($num_taxon, $flore, $nom_supp, $flore_supp, $num_supp, $remarques);
}
return $idTaxon;
}
 
// renvoie un nom d'apres son id
public function getNom($id) {
foreach ($this->taxons['ind'] as $nom=>$param) {
if ($param['id'] === $id) {
if (preg_match('/rem:[a-z]+\d+\/(.*)/', $nom, $match)) {
$nom = $match[1];
}
return $nom;
}
}
return '';
}
// Ajoute taxon avec pour clé le numéro taxon, le nom ou la remarque
public function ajouterTaxon($num_taxon, $flore, $nom, $flore_supp, $num_supp, $remarques) {
if ($nom != null) {
$cle = 'ind';
$num = $nom;
} elseif ($remarques != '') {
$cle = 'ind';
$num = "rem:".$flore_supp.$num_supp.'/'.$remarques;
} else {
$cle = $flore;
$num = $num_taxon;
}
$this->taxons[$cle][$num]['id'] = $this->id;
foreach ($this->flores as $nom_flore) {
if ($nom_flore == $flore) {
$this->taxons[$cle][$num][$nom_flore] = $num_taxon;
} elseif ($nom_flore == $flore_supp) {
$this->taxons[$cle][$num][$nom_flore] = $num_supp;
} else {
$this->taxons[$cle][$num][$nom_flore] = 'NULL';
}
}
$this->taxons[$cle][$num]['nom'] = $this->ajouterNomTaxon($num_taxon, $flore, $nom, $flore_supp, $num_supp);
$this->taxons[$cle][$num]['remarques'] = $remarques;
$this->id++;
return $this->taxons[$cle][$num]['id'];
}
public function ajouterNomTaxon($num_taxon, $flore, $nom_supp, $flore_supp, $num_supp) {
$nom = '';
$nomCherche = false;
foreach ($this->table_flores as $nom_flore) {
if ($nomCherche == false) {
if ($nom_flore == $flore) {
$nom = $this->rechercherNomTaxon($nom_flore, $num_taxon);
if ($nom != false) {
$nomCherche = true;
}
} elseif ($nom_flore == $flore_supp) {
$nom = $this->rechercherNomTaxon($nom_flore, $num_supp);
if ($nom != false) {
$nomCherche = true;
}
}
}
}
if ($nom == false && $nom_supp != null) {
$nom = $nom_supp;
} elseif ($nom == '' && $nom_supp != null) {
$nom = $nom_supp;
}
return $nom;
}
public function rechercherNomTaxon($nom_flore, $num_taxon) {
$requete2 = null;
switch ($nom_flore) {
case 'bdnff' :
$requete = "SELECT sb_nom_complet AS nom FROM sophy_bdnff
WHERE sb_num_tax = {$num_taxon} AND sb_id_num_bdnff = sb_num_nom_retenu; ";
break;
case 'fournier' :
$requete = "SELECT sb_nom_complet AS nom FROM sophy_bdnff, sophy_fournier_bdnff
WHERE sfb_id_num_fournier = {$num_taxon} AND sb_num_tax = sfb_id_num_bdnff AND sb_id_num_bdnff = sb_num_nom_retenu;";
$requete2 = "SELECT sf_nom_fournier AS nom FROM sophy_fournier WHERE sf_id_num_fournier = {$num_taxon};";
break;
case 'ciff' :
$requete = "SELECT sb_nom_complet AS nom
FROM sophy_bdnff, sophy_ciff_bdnff
WHERE scb_id_num_ciff = {$num_taxon} AND scb_id_num_bdnff = sb_id_num_bdnff;";
$requete2 = "SELECT sci_nom_ciff AS nom FROM sophy_ciff WHERE sci_id_num_ciff = {$num_taxon};";
break;
case 'syntri' :
$requete = "SELECT sb_nom_complet AS nom
FROM sophy_bdnff, sophy_syntri_fournier, sophy_fournier_bdnff
WHERE ssf_id_num_syntri = {$num_taxon} AND ssf_id_num_fournier = sfb_id_num_fournier
AND sb_num_tax = sfb_id_num_bdnff AND sb_id_num_bdnff = sb_num_nom_retenu;";
$requete2 = "SELECT ssyn_nom_supp AS nom FROM sophy_syntri WHERE ssyn_id_num_supp = {$num_taxon};";
break;
case 'codefr94' :
$requete = "SELECT sc_nom_codefr AS nom FROM sophy_codefr94 WHERE sc_id_num_codefr = {$num_taxon};";
break;
case 'bryo' :
$requete = "SELECT sbr_nom_bryo AS nom FROM sophy_bryophyte WHERE sbr_id_num_bryo = {$num_taxon};";
break;
case 'floeur' :
$requete = "SELECT sfe_nom_floeur AS nom FROM sophy_flora_europea WHERE sfe_id_num_floeur = {$num_taxon};";
break;
}
$resultat_requete = $this->recuperer($requete);
if ($resultat_requete['nom'] == false && $requete2 != null) {
$resultat_requete = $this->recuperer($requete2);
}
return $resultat_requete['nom'];
}
// recherche le dernier id de la base
public function chargerId() {
$id = 0;
$requete_select_id = "SELECT MAX(st_id_taxon) AS idMax FROM sophy_taxon;";
$resultat_requete_id = $this->recuperer($requete_select_id);
if ($resultat_requete_id['idMax'] != false) {
$id = $resultat_requete_id['idMax'];
}
return $id;
}
// Regarde si il y a des taxons dans la base, retourne le tableau de valeur et vide la base
public function chargerTaxon() {
$resultat = null;
$retour = null;
$requete_select = "SELECT * FROM sophy_taxon;";
$resultat = $this->recupererTous($requete_select);
if ($resultat != false) {
foreach ($resultat as $result) {
if ($result['st_nom_supp'] != null) {
$retour['ind'][$result['st_nom_supp']]['id'] = $result['st_id_taxon'];
foreach ($this->flores as $nom_flore) {
$retour['ind'][$result['st_nom_supp']][$nom_flore] = $result["st_ce_num_".$nom_flore];
}
$retour['ind'][$result['st_nom_supp']]['remarques'] = $result['st_nom_supp'];
} elseif ($result['st_remarques'] != null) {
$nom = $result['st_remarques'];
$retour['ind'][$nom]['id'] = $result['st_id_taxon'];
foreach ($this->flores as $nom_flore) {
$retour['ind'][$result['st_nom_supp']][$nom_flore] = $result["st_ce_num_".$nom_flore];
}
$retour['ind'][$nom]['remarques'] = $result['st_nom_supp'];
} elseif ($result['st_ce_num_syntri'] != null) {
$retour['syntri'][$result['st_ce_num_syntri']]['id'] = $result['st_id_taxon'];
$retour['syntri'][$result['st_ce_num_syntri']]['num_supp'] = $result['st_num_supp'];
} elseif ($result['st_ce_num_floeur'] != null) {
$retour['floeur'][$result['st_ce_num_floeur']]['id'] = $result['st_id_taxon'];
} elseif ($result['st_ce_num_bdnff'] != null) {
$retour['bdnff'][$result['st_ce_num_bdnff']]['id'] = $result['st_id_taxon'];
} elseif ($result['st_ce_num_codefr94'] != null) {
$retour['codefr94'][$result['st_ce_num_codefr94']]['id'] = $result['st_id_taxon'];
} elseif ($result['st_ce_num_bryo'] != null) {
$retour['bryo'][$result['st_ce_num_bryo']]['id'] = $result['st_id_taxon'];
} elseif ($result['st_ce_num_ciff'] != null) {
$retour['ciff'][$result['st_ce_num_ciff']]['id'] = $result['st_id_taxon'];
} elseif ($result['st_ce_num_fournier'] != null) {
$retour['fournier'][$result['st_ce_num_fournier']]['id'] = $result['st_id_taxon'];
}
}
}
$requete = "TRUNCATE TABLE `sophy_taxon`; ";
$res = $this->requeter($requete);
return $retour;
}
// +-------------------------------------------------------------------------------------------------------------------+
// Requête sur table sophy_taxon et toutes les tables flore de sophy
public function integrerTaxons() {
foreach ($this->taxons as $flore=>$taxons) {
switch ($flore) {
case 'ind' :
// insertion par 1000 pour éviter que la requête soit trop lourde
$i = 0; $j = 1000;
$requete = "INSERT INTO `sophy_taxon` (`st_id_taxon`, `st_nom`, `st_nom_supp`,";
foreach ($this->flores as $nom_flore) {
$requete .= "st_ce_num_{$nom_flore}, ";
}
$requete .= " st_remarques) VALUES ";
foreach ($taxons as $taxon=>$valeur) {
if (!isset($valeur['remarques'])){
$valeur['remarques'] = 'NULL';
$taxon = $this->proteger($taxon);
} elseif (substr_compare($taxon, 'rem:', 0, 4) == 0){
$valeur['remarques'] = $this->proteger($taxon);
$taxon = 'NULL';
} else {
$taxon = $this->proteger($taxon);
$valeur['remarques'] = $this->proteger($valeur['remarques']);
}
if ($i < $j) {
$requete .= " (".$valeur['id'].", ".$this->proteger($valeur['nom']).", ".$taxon.", ";
foreach ($this->flores as $nom_flore) {
$requete .= $valeur[$nom_flore].", ";
}
$requete .= " ".$valeur['remarques']."),";
} elseif ($i == $j) {$j += 1000;
$requete = substr($requete,0,-1).";";
$resultat = $this->requeter($requete);
if ($resultat == false) {
echo $flore.' : '.$i;
}
$requete = "INSERT INTO `sophy_taxon` (`st_id_taxon`, `st_nom`, `st_nom_supp`,";
foreach ($this->flores as $nom_flore) {
$requete .= "st_ce_num_{$nom_flore}, ";
}
$requete .= " st_remarques) VALUES (".$valeur['id'].", ".$this->proteger($valeur['nom']).
", ".$taxon.", ";
foreach ($this->flores as $nom_flore) {
$requete .= $valeur[$nom_flore].", ";
}
$requete .= " ".$valeur['remarques']."),";
}
$i++;
}
$requete = substr($requete,0,-1).";";
break;
case 'syntri' :
$i = 0;
$requete = "INSERT INTO `sophy_taxon` (`st_id_taxon`, ";
foreach ($this->flores as $nom_flore) {
$requete .= "st_ce_num_{$nom_flore}, ";
}
$requete .= "`st_nom`) VALUES ";
foreach ($taxons as $taxon=>$valeur) {
$requete .= " (".$valeur['id'].", ";
foreach ($this->flores as $nom_flore) {
$requete .= $valeur[$nom_flore].", ";
}
$requete .= $this->proteger($valeur['nom'])."), ";
}
$requete = substr($requete,0,-2).";";
break;
default:
$requete = "INSERT INTO `sophy_taxon` (`st_id_taxon`, `st_nom`, st_ce_num_{$flore}) VALUES ";
foreach ($taxons as $numTaxon=>$valeur) {
$requete .= " (".$valeur['id'].", ".$this->proteger($valeur['nom']).", ".$numTaxon."),";
}
$requete = substr($requete,0,-1).";";
break;
}
$resultat = $this->requeter($requete);
if ($resultat == false) {
echo " - flore : ".$flore;
}
}
}
}
?>
/trunk/scripts/modules/sophy/Insertion.php
New file
0,0 → 1,906
<?php
// Encodage : UTF-8
// +-------------------------------------------------------------------------------------------------------------------+
/**
* Traitement des fichiers de la banque de données SOPHY pour insertion
*
* Description : classe permettant d'insérer les tableaux phytosociologiques de la banque de données SOPHY
* Utilisation : php script.php insertion -a test
*
* @category PHP 5.3
* @package phytosocio
//Auteur original :
* @author Delphine CAUQUIL <delphine@tela-botanica.org>
* @copyright Copyright (c) 2009, 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 Insertion extends EfloreScript {
protected $tableauTaxon;
protected $dao;
protected $observations;
// 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'));
 
protected $param_bd_pour_stat = array(
'sophy_publication' => array(),
'sophy_tableau' => array('stab_id_publi' => 'nombrePubli'),
'sophy_releve' => array(
'sr_id_publi' => 'nombrePubli',
'sr_id_publi, sr_id_tableau' => 'nombreTableau',
'sr_id_station' => 'nombreStation'),
'sophy_observation' => array(
'so_id_publi' => 'nombrePubli',
'so_id_publi, so_id_tableau' => 'nombreTableau',
'so_id_publi, so_id_tableau, so_id_releve' => 'nombreReleve',
'so_id_taxon' => 'nombreTaxon'),
'sophy_station' => array(),
'sophy_taxon' => array()
);
 
// Composition classique d'un titre de tableau de stations ou phytosociologiques
protected $format_titre = array(
'numPubli' => array(0, 4),
'numTableau' => array(4, 3),
'nombreStations' => array(7, 3),
'titrePubli' => array(11, -1),
'typeTableau' => array(79, 1)
);
 
// Composition classique d'une station
protected $format_station = array(
'numSource' => array(0, 4),
'posteMeteo' => array(4, 5),
'nomStation' => array(10, 38),
'latitude' => array(49, 7),
'codePays' => array(56, 2),
'longitude' => array(59, 6),
'codeDept' => array(66, 2),
'altitude' => array(69, 4),
'codeCommune' => array(74, 3),
'precisionGeographique' => array(78, 1),
'systemeProjection' => array(79, 1),
'latitude2' => array(80, 8),
'longitude2' => array(88, 8)
);
 
// Composition classique d'une ligne de tableau phytosociologique
protected $format_tableau = array(
0 => array(
'numLigne' => array(0, 3),
'idTaxon' => array(3, 5),
'strate' => array(8, 1),
'codeFlore' => array(9, 1),
'abondance_rem' => array(10, 70)),
2 => array(
'numSource' => array(0, 5),
'posteMeteo' => array(5, 3),
'numLigne' => array(8, 2),
'codeFournier1' => array(10, 5),
'abondance1' => array(15, 1),
'strate1' => array(16, 1),
'codeFournier2' => array(17, 5),
'abondance2' => array(22, 1),
'strate2' => array(23, 1),
'codeFournier3' => array(24, 5),
'abondance3' => array(29, 1),
'strate3' => array(30, 1),
'codeFournier4' => array(31, 5),
'abondance4' => array(36, 1),
'strate4' => array(37, 1),
'codeFournier5' => array(38, 5),
'abondance5' => array(43, 1),
'strate5' => array(44, 1),
'codeFournier6' => array(45, 5),
'abondance6' => array(50, 1),
'strate6' => array(51, 1),
'codeFournier7' => array(52, 5),
'abondance7' => array(57, 1),
'strate7' => array(58, 1),
'codeFournier8' => array(59, 5),
'abondance8' => array(64, 1),
'strate8' => array(65, 1),
'codeFournier9' => array(66, 5),
'abondance9' => array(71, 1),
'strate9' => array(72, 1),
'codeFournier10' => array(73, 5),
'abondance10' => array(78, 1),
'strate10' => array(79, 1)),
6 => array(
'numSource' => array(0, 4),
'posteMeteo' => array(4, 4),
'numLigne' => array(8, 2),
'strate1' => array(10, 1),
'codeFournier1' => array(11, 4),
'abondance1' => array(16, 1),
'strate2' => array(17, 1),
'codeFournier2' => array(18, 4),
'abondance2' => array(23, 1),
'strate3' => array(24, 1),
'codeFournier3' => array(25, 4),
'abondance3' => array(30, 1),
'strate4' => array(31, 1),
'codeFournier4' => array(32, 4),
'abondance4' => array(37, 1),
'strate5' => array(38, 1),
'codeFournier5' => array(39, 4),
'abondance5' => array(44, 1),
'strate6' => array(45, 1),
'codeFournier6' => array(46, 4),
'abondance6' => array(51, 1),
'strate7' => array(52, 1),
'codeFournier7' => array(53, 4),
'abondance7' => array(58, 1),
'strate8' => array(59, 1),
'codeFournier8' => array(60, 4),
'abondance8' => array(65, 1),
'strate9' => array(66, 1),
'codeFournier9' => array(67, 4),
'abondance9' => array(72, 1),
'strate10' => array(73, 1),
'codeFournier10' => array(74, 4),
'abondance10' => array(79, 1)),
7 => array(
'numReleve' => array(2, 3),
'posteMeteo' => array(7, 3),
'codeFournier1' => array(10, 4),
'abondance1' => array(14, 1),
'strate1' => array(15, 1),
'codeFournier2' => array(16, 4),
'abondance2' => array(20, 1),
'strate2' => array(21, 1),
'codeFournier3' => array(22, 4),
'abondance3' => array(26, 1),
'strate3' => array(27, 1),
'codeFournier4' => array(28, 4),
'abondance4' => array(32, 1),
'strate4' => array(33, 1),
'codeFournier5' => array(34, 4),
'abondance5' => array(38, 1),
'strate5' => array(39, 1),
'codeFournier6' => array(40, 4),
'abondance6' => array(44, 1),
'strate6' => array(45, 1),
'codeFournier7' => array(46, 4),
'abondance7' => array(50, 1),
'strate7' => array(51, 1),
'codeFournier8' => array(52, 4),
'abondance8' => array(56, 1),
'strate8' => array(57, 1),
'codeFournier9' => array(58, 4),
'abondance9' => array(62, 1),
'strate9' => array(63, 1),
'codeFournier10' => array(64, 4),
'abondance10' => array(68, 1),
'strate10' => array(69, 1),
'numLigne' => array(71, 2),
'codeCarte' => array(73, 7))
);
 
// +-------------------------------------------------------------------------------------------------------------------+
public function executer() {
include_once dirname(__FILE__).'/bibliotheque/Dao.php';
Config::charger(dirname(__FILE__).'/sophy.ini');
$this->dao = new Dao();
// Récupération de paramétres
// Lancement de l'action demandée
$cmd = $this->getParametre('a');
switch ($cmd) {
case 'testDossier' :
$this->executerTestDossier();
break;
case 'chargerStructureSql' :
$this->chargerStructureSql();
break;
case 'supprimerTous' :
$this->supprimerTous();
case 'biblio' :
$this->executerBiblio();
break;
case 'station' :
include_once dirname(__FILE__).'/bibliotheque/gPoint.php';
$this->executerStation();
break;
case 'stationCodeInsee' :
$this->executerStationCodeInsee();
break;
case 'tableau' :
include_once dirname(__FILE__).'/bibliotheque/TaxonDao.php';
$this->tableauTaxon = new TaxonDao();
$this->executerTableau();
break;
case 'stats' :
$this->executerStats();
break;
case 'tapir' :
$info = $this->dao->creerTapir();
$this->traiterErreur($info);
break;
default :
$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
}
}
protected function chargerStructureSql() {
$contenuSql = $this->recupererContenu(Config::get('chemins.structureSql'));
$this->executerScripSql($contenuSql);
}
protected function executerScripSql($sql) {
$requetes = Outils::extraireRequetes($sql);
foreach ($requetes as $requete) {
$this->getBdd()->requeter($requete);
}
}
private function supprimerTous() {
$requete = "DROP TABLE IF EXISTS sophy_abondance, `sophy_bdnff`, `sophy_bryophyte`, `sophy_ciff`, ".
"`sophy_ciff_fournier`, `sophy_codefr94`, `sophy_flora_europea`, `sophy_fournier`, `sophy_fournier_bdnff`,".
" `sophy_observation`, `sophy_precision_geo`, `sophy_publication`, `sophy_releve`, `sophy_station`, `sophy_strate`,".
" `sophy_syntri`, `sophy_syntri_fournier`, `sophy_tableau`, `sophy_taxon`";
$this->getBdd()->requeter($requete);
}
// +-------------------------------------------------------------------------------------------------------------------+
// vérifie qu'il n'y est pas de fichier en double dans le dossier
// à faire avant d'insérer un nouveau dossier
private function executerTestDossier() {
$nomDossier = Config::get('dossierDonneesSophy').$this->getParametre('n');
if (file_exists($nomDossier) === true) {
if (is_dir($nomDossier)) {
if ($dossierOuvert = opendir($nomDossier) ) {
while ( ($nomFichier = readdir($dossierOuvert)) !== false) {
if ( !is_dir($nomFichier) ) {
if (preg_match('/^[ST]{1,2}(\d{2}1)(\d{2}0)\.*/', $nomFichier, $match)) {
// fichier normal type 001 à 010
} elseif (preg_match('/^([ST]{1,2})(\d{3})(\d{3})\.*/', $nomFichier, $match)) {
if (($match[1]=='ST' || $match[1]=='T') && ($match[3] - $match[2] == 1)) {
// fichier normal type 1000 à 1010
} else {
$this->traiterErreur("Le fichier $nomFichier risque d'être en double.");
}
}
}
}
closedir($dossierOuvert);
} else {
$this->traiterErreur("Le dossier $nomDossier n'a pas pu être ouvert.");
}
} else {
$this->traiterErreur("$nomDossier n'est pas un dossier.");
}
} else {
$this->traiterErreur("Le dossier $nomDossier est introuvable.");
}
}
 
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement du fichier biblio format csv
// /opt/lampp/bin/php cli.php sophy/insertion -a biblio -n ./../donnees/sophy/BIBLIO.csv
private function executerBiblio() {
// Parcours le fichier .csv et enregistre chaque ligne dans un tableau.
$nomFichier = Config::get('dossierDonneesSophy').'BIBLIO.csv';
if ($nomFichier && file_exists($nomFichier) ){
$extensionFichier = strtolower(strrchr($nomFichier, '.'));
if ($extensionFichier === ".csv"){
$file = new SplFileObject($nomFichier);
$file->setFlags(SplFileObject::SKIP_EMPTY);
$i = 0;
echo "Traitement de la biblio : ";
while (!$file->eof()){
$ligne_csv = $file->fgetcsv();
if (preg_match('/^\d+$/', $ligne_csv[0])){
// récupére les colonnes du csv pour les transformer en table publication
$biblio = $this->transformerBiblio($ligne_csv);
// integre les publications à la bdd
$info = $this->dao->integrerBiblio($biblio);
$this->traiterInfo($info);
}
echo str_repeat(chr(8), ( strlen( $i ) + 1 ))."\t".$i++;
}
echo "\n";
} else {
$this->traiterErreur("Le fichier de références bibliographiques : $nomFichier n'est pas au format csv.");
}
} else {
$this->traiterErreur("Le fichier de références bibliographiques : $nomFichier n'existe pas.");
}
}
 
private function transformerBiblio($ligne_csv){
$biblio['id_publi'] = $ligne_csv[0];
$biblio['auteur'] = $ligne_csv[2].' '.$ligne_csv[3];
$biblio['date'] = $ligne_csv[4];
$biblio['titre'] = rtrim($ligne_csv[5].' '.$ligne_csv[6].' '.$ligne_csv[7].' '.$ligne_csv[8].' '.$ligne_csv[9]);
$biblio['revue'] = rtrim($ligne_csv[10].' '.$ligne_csv[11]);
$biblio['volume'] = $ligne_csv[12];
$biblio['tome'] = $ligne_csv[13];
$biblio['fascicule'] = $ligne_csv[14];
$biblio['page_debut'] = $ligne_csv[15];
$biblio['page_fin'] = $ligne_csv[16];
return $biblio;
}
 
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement des fichiers stations
// /opt/lampp/bin/php cli.php insertion -a station -n ./../doc/donnees/ST/
private function executerStation() {
// transforme les fichiers passés en un tableau
//de la forme [nom du fichier][index des tableaux][numéro de ligne]
$tableaux = $this->ouvrirDossier(Config::get('dossierDonneesSophy').'ST/');
foreach ($tableaux as $fichier) {
foreach ($fichier as $tableau) {
if ($tableau[0] != "") {
// découpe la première ligne du tableau et insére les données dans la table tableau
$titre = $this->analyserTitreStation($tableau['0']);
for ($numReleve = 1; $numReleve < sizeof($tableau); $numReleve++) {
// découpe les autres lignes, insére les données dans la table station et retourne l'id de la station
if (trim($tableau[$numReleve]) == '') {
$id_station = 0;
} else {
$id_station = $this->analyserStation($tableau[$numReleve]);
}
// insére les données tableau et station dans la table relevé
$info = $this->dao->integrerReleve($titre, $numReleve, $id_station);
if ($info != '') {
$this->traiterErreur($info);
}
}
}
}
}
}
 
private function analyserTitreStation($titre) {
$titreDecoupe = $this->decouperLigne($titre, $this->format_titre);
$info = $this->dao->integrerTableau($titreDecoupe);
if ($info != '') {
$this->traiterErreur($info);
}
return $titreDecoupe;
}
 
private function analyserStation($ligne) {
$ligneDecoupe = $this->decouperLigne($ligne, $this->format_station);
$ligneDecoupe['latitude_wgs'] = null;
$ligneDecoupe['longitude_wgs'] = null;
// vérifie que les zéro du code sont présents
$ligneDecoupe = $this->analyserCodeDeptComm($ligneDecoupe);
// transforme les grades paris en degrés décimaux wms
$ligneDecoupe = $this->analyserCoordGrdParis($ligneDecoupe, $ligne);
// transforme les degrés sexagécimaux en degrés décimaux
$ligneDecoupe = $this->analyserCoordDmsWms($ligneDecoupe);
// transforme les degrés décimaux en UTM
$ligneDecoupe = $this->transformerCoordWmsUtm($ligneDecoupe);
$ligneDecoupe['nomStation'] = utf8_encode($ligneDecoupe['nomStation']);
$retour_requete = $this->dao->integrerStation($ligneDecoupe);
if ($retour_requete['info'] != '') {
$this->traiterErreur($retour_requete['info']);
}
return $retour_requete['id_station'];
}
private function executerStationCodeInsee() {
$this->dao->creerColonneCodeInseeCalculee();
$liste_coordonnees = $this->dao->rechercherCoordonneesWgs();
foreach ($liste_coordonnees as $coordonnees) {
$code_insee = $this->chercherCodeCommune($coordonnees['latitude'], $coordonnees['longitude']);
if ($code_insee != "") {
$this->dao->ajouterCodeInseeCalculee($coordonnees['latitude'], $coordonnees['longitude'], $code_insee);
}
}
}
private function chercherCodeCommune($latitude, $longitude) {
$code_insee = '';
if ($this->testerCoordonneesWgsFrance($latitude, $longitude)) {
$url_service = "www.tela-botanica.org/service:eflore:0.1/osm/nom-commune".
"?lat={$latitude}&lon={$longitude}";
$url_service = str_replace(',', '.', $url_service);
$ch = curl_init($url_service);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$reponse = curl_exec($ch);
$reponse = json_decode($reponse);
if (isset($reponse->codeINSEE)) {
$code_insee = $reponse->codeINSEE;
}
curl_close($ch);
}
return $code_insee;
}
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;
}
private function analyserCodeDeptComm($ligneDecoupe) {
if (preg_match('/^\d{2}$/', $ligneDecoupe['codeDept'])) {
} elseif (preg_match('/^\s{0,1}\d{1,2}\s{0,1}$/',$ligneDecoupe['codeDept'])) {
$ligneDecoupe['codeDept'] = str_replace(' ', '0', $ligneDecoupe['codeDept']);
} else {
$ligneDecoupe['codeDept'] = null;
}
if (preg_match('/^\d{3}$/', $ligneDecoupe['codeCommune'])) {
} elseif (preg_match('/^\s{0,2}\d{1,2,3}\s{0,2}$/', $ligneDecoupe['codeCommune'])) {
$ligneDecoupe['codeCommune'] = str_replace(' ', '0', $ligneDecoupe['codeCommune']);
} elseif ($ligneDecoupe['codeDept'] == null) {
$ligneDecoupe['codeCommune'] = null;
} else {
$ligneDecoupe['codeCommune'] = '000';
}
return $ligneDecoupe;
}
private function analyserCoordGrdParis($ligneDecoupe, $ligne) {
if (preg_match('/[\s0]0\.000/', $ligneDecoupe['latitude'], $match)) {
$ligneDecoupe['latitude'] = null;
$ligneDecoupe['longitude'] = null;
} elseif (preg_match('/\d{1,2}\.\d{2,3}/', $ligneDecoupe['latitude'], $match)) {// format souhaité
$ligneDecoupe['latitude_wgs'] = round($ligneDecoupe['latitude']*0.9, 7);
$ligneDecoupe['longitude_wgs'] = round($ligneDecoupe['longitude']*0.9+2.3372291, 7);
} elseif (preg_match('/(\d{2})[\d\s,](\d{3})/', $ligneDecoupe['latitude'], $match)) {//erreur de saisie
$ligneDecoupe['latitude'] = $match[1].'.'.$match[2];
$ligneDecoupe['latitude_wgs'] = round($ligneDecoupe['latitude']*0.9, 7);
$ligneDecoupe['longitude_wgs'] = round($ligneDecoupe['longitude']*0.9 + 2.3372291, 7);
} elseif (preg_match('/^[a-zA-Z\s]*[a-zA-Z][a-zA-Z\s]*$/', $ligneDecoupe['latitude'])) {// lat absente + nom long
$ligneDecoupe['nomStation'] = rtrim(substr($ligne, 10, 48));
$ligneDecoupe['latitude'] = null;
$ligneDecoupe['longitude'] = null;
} elseif (preg_match('/.[AO].123/', $ligneDecoupe['latitude'], $match)) {
$ligneDecoupe['latitude'] = null;
$ligneDecoupe['longitude'] = null;
} elseif ($ligneDecoupe['latitude'] != null) {
$ligneDecoupe['latitude'] = null;
$ligneDecoupe['longitude'] = null;
}
return $ligneDecoupe;
}
private function analyserCoordDmsWms($ligneDecoupe) {
if (preg_match('/(\d{1,2})\.(\d{2})\.(\d{2})/', $ligneDecoupe['latitude2'], $match)) {
$ligneDecoupe['latitude_wgs'] = round($match[1]+($match[2]/60)+($match[3]/3600), 7);
}
if (preg_match('/(-{0,1})(\d{1,2})\.(\d{2})\.(\d{2})/', $ligneDecoupe['longitude2'], $match)) {
$ligneDecoupe['longitude_wgs'] = round($match[2]+($match[3]/60)+($match[4]/3600), 7);
if ($match[1] == '-') {
$ligneDecoupe['longitude_wgs'] = -$ligneDecoupe['longitude_wgs'];
}
}
return $ligneDecoupe;
}
private function transformerCoordWmsUtm($ligneDecoupe) {
$ligneDecoupe['utmNorthing'] = null;
$ligneDecoupe['utmEasting'] = null;
$ligneDecoupe['utmZone'] = null;
if ($ligneDecoupe['longitude_wgs'] != null && $ligneDecoupe['latitude_wgs'] != null) {
$convertisseur = new gPoint();
$convertisseur->setLongLat($ligneDecoupe['longitude_wgs'], $ligneDecoupe['latitude_wgs']);
$convertisseur->convertLLtoTM();
$ligneDecoupe['utmNorthing'] = round($convertisseur->N(), 2);
$ligneDecoupe['utmEasting'] = round($convertisseur->E(), 2);
$ligneDecoupe['utmZone'] = $convertisseur->Z();
}
return $ligneDecoupe;
}
 
// +-------------------------------------------------------------------------------------------------------------------+
// Traitement des fichiers tableaux
// /opt/lampp/bin/php cli.php insertion -a tableau -n ./../doc/donnees/T/
private function executerTableau() {
$tableaux = $this->ouvrirDossier(Config::get('dossierDonneesSophy').'T/');
$observations = array();
foreach ($tableaux as $fichier) {
foreach ($fichier as $tableau) {
if ($tableau[0] != "") {
$this->observations = array();
$titre = $this->decouperLigne($tableau[0], $this->format_titre);
$this->analyserTableau($tableau, $titre);
/*$info = $this->dao->integrerObservation($this->observations, $titre);
if ($info != '') {
$this->traiterErreur($info);
}*/
}
}
} $this->tableauTaxon->integrerTaxons();
}
 
private function analyserTableau($tableau, $titre) {
if ($titre['typeTableau'] == ' ') {
$titre['typeTableau'] = 0;
}
switch ($titre['typeTableau']) {
case 0 :
for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
$ligneDecoupe = $this->decouperLigne($tableau[$numeroLigne], $this->format_tableau['0']);
if (trim($ligneDecoupe['idTaxon']) == '' && trim($ligneDecoupe['abondance_rem']) == '' &&
preg_match('/^\s+\*N\s*\*\s*$/', $ligneDecoupe['indetermine'])) {
for ($nombreReleve = 1; $nombreReleve <= $titre['nombreStations']; $nombreReleve ++) {
$this->observations[$numeroLigne][$nombreReleve]['sc_id_publi'] = $titre['numPubli'];
$this->observations[$numeroLigne][$nombreReleve]['sc_id_tableau'] = $titre['numTableau'];
$this->observations[$numeroLigne][$nombreReleve]['sc_id_releve'] = $nombreReleve;
$this->observations[$numeroLigne][$nombreReleve]['sc_num_ligne'] = $ligneDecoupe['numLigne'];
$this->observations[$numeroLigne][$nombreReleve]['sc_id_taxon'] = 0;
$this->observations[$numeroLigne][$nombreReleve]['sc_id_strate'] = 0;
$this->observations[$numeroLigne][$nombreReleve]['sc_ce_abondance'] = '?';
}
} else {
$this->creerObservType0($titre, $ligneDecoupe, $numeroLigne);
}
}
for ($nombreReleve = 1; $nombreReleve <= $titre['nombreStations']; $nombreReleve ++) {
$j = false;
for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
if (isset($this->observations[$numeroLigne][$nombreReleve])) {
$j = true;
}
}
if ($j == false) {
$this->observations[0][$nombreReleve]['sc_id_publi'] = $titre['numPubli'];
$this->observations[0][$nombreReleve]['sc_id_tableau'] = $titre['numTableau'];
$this->observations[0][$nombreReleve]['sc_id_releve'] = $nombreReleve;
$this->observations[0][$nombreReleve]['sc_num_ligne'] = 0;
$this->observations[0][$nombreReleve]['sc_id_taxon'] = 0;
$this->observations[0][$nombreReleve]['sc_id_strate'] = 0;
$this->observations[0][$nombreReleve]['sc_ce_abondance'] = '?';
}
}
break;
case 2 :
$numSource = 0; $numReleve = 0;
for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
$ligneDecoupe = $this->decouperLigne($tableau[$numeroLigne], $this->format_tableau['2']);
if ($ligneDecoupe['numSource'] != $numSource) {
// $numSource correspond au numero à la station par l'auteur,
// $numReleve correspond à l'id de la station
$numSource = $ligneDecoupe['numSource'];
$numReleve ++;
}
if (strlen(trim($tableau[$numeroLigne])) < 10) {
$this->observations[$numeroLigne][1]['sc_id_publi'] = $titre['numPubli'];
$this->observations[$numeroLigne][1]['sc_id_tableau'] = $titre['numTableau'];
$this->observations[$numeroLigne][1]['sc_id_releve'] = $numReleve;
$this->observations[$numeroLigne][1]['sc_num_ligne'] = 0;
$this->observations[$numeroLigne][1]['sc_id_taxon'] = 0;
$this->observations[$numeroLigne][1]['sc_id_strate'] = 0;
$this->observations[$numeroLigne][1]['sc_ce_abondance'] = '?';
} else {
$this->creerObservType2($titre, $ligneDecoupe, $numReleve, $numeroLigne);
}
}
break;
case 6 :
$numSource = 0; $numReleve = 0;
for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
$ligneDecoupe = $this->decouperLigne($tableau[$numeroLigne], $this->format_tableau['6']);
$num = (preg_match('/[\dA-Z]+\s+[\dA-Z]+/', $ligneDecoupe['numSource'].$ligneDecoupe['posteMeteo']))
? ltrim($ligneDecoupe['numSource'])
: $ligneDecoupe['numSource'].$ligneDecoupe['posteMeteo'];
if ($num !== $numSource) {
$numSource = $num;
$numReleve ++;
}
$this->creerObservType2($titre, $ligneDecoupe, $numReleve, $numeroLigne);
}
break;
case 7 :
$numSource = 0; $numReleve = 0;
for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
$ligneDecoupe = $this->decouperLigne($tableau[$numeroLigne], $this->format_tableau['7']);
if (trim($ligneDecoupe['numReleve']) !== $numSource) {
$numSource = trim($ligneDecoupe['numReleve']);
$numReleve ++;
}
$this->creerObservType2($titre, $ligneDecoupe, $numReleve, $numeroLigne);
}
break;
default :
for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
$ligneDecoupe = $this->decouperLigne($tableau[$numeroLigne], $this->format_tableau['0']);
$this->creerObservType0($titre, $ligneDecoupe);
}
break;
}
return $ligneDecoupe;
}
// crée des observations au format de la table à partir d'un tableau de type standard (0)
private function creerObservType0($titre, $ligneDecoupe, $numeroLigne) {
$observation = null;
// Retourne l'id du taxon dans la bd sophy
$idTaxon = $this->identifierTaxon($titre['nombreStations'], $ligneDecoupe, $numeroLigne);
// découpe le champs abondance_rem ou indetermine selon le nombre de relevés
$remAbondance = substr(
($ligneDecoupe['abondance_rem'] != null) ? $ligneDecoupe['abondance_rem'] : $ligneDecoupe['indetermine'],
0, $titre['nombreStations']);
// si aucun relevé ne contient d'abondance pour un taxon, ajout d'une abondance ? pour ce taxon
if (trim($remAbondance) == '') {
$remAbondance = '?';
}
for ($numReleve = 1; $numReleve <= $titre['nombreStations']; $numReleve++) {
if ($remAbondance === '?' && $numeroLigne === 1) {
$abondance = '?';
} else {
$abondance = substr($remAbondance, ($numReleve-1), 1);
}
if ($abondance != '' && $abondance != ' ') {
$this->observations[$numeroLigne][$numReleve]['sc_id_publi'] = $titre['numPubli'];
$this->observations[$numeroLigne][$numReleve]['sc_id_tableau'] = $titre['numTableau'];
$this->observations[$numeroLigne][$numReleve]['sc_id_releve'] = $numReleve;
$this->observations[$numeroLigne][$numReleve]['sc_num_ligne'] = $numeroLigne;
$this->observations[$numeroLigne][$numReleve]['sc_id_taxon'] = $idTaxon;
if ($ligneDecoupe['strate'] != null) {
$this->observations[$numeroLigne][$numReleve]['sc_id_strate'] = $ligneDecoupe['strate'];
} else {
$this->observations[$numeroLigne][$numReleve]['sc_id_strate'] = 0;
}
$this->observations[$numeroLigne][$numReleve]['sc_ce_abondance'] = $abondance;
}
}
}
// crée des observations au format de la table à partir d'un tableau de type 2, 6 ou 7 (10 plantes en lignes)
private function creerObservType2($titre, $ligneDecoupe, $numReleve, $numeroLigne) {
$observation = null;
for ($i = 1; $i < 11; $i++) {
// si le numéro de taxon et l'abondance ne sont pas nulls
if ((($ligneDecoupe['abondance'.$i] == '' || $ligneDecoupe['abondance'.$i] == '0') &&
(trim($ligneDecoupe['codeFournier'.$i]) == '' || $ligneDecoupe['codeFournier'.$i] == '0'))) {
} else {
$positionTaxon = $ligneDecoupe['numLigne']*10 + $i - 10;
$this->observations[$numeroLigne][$positionTaxon]['sc_id_publi'] = $titre['numPubli'];
$this->observations[$numeroLigne][$positionTaxon]['sc_id_tableau'] = $titre['numTableau'];
$this->observations[$numeroLigne][$positionTaxon]['sc_id_releve'] = $numReleve;
$this->observations[$numeroLigne][$positionTaxon]['sc_num_ligne'] = $positionTaxon;
$idTaxon = str_replace(' ', '0', $ligneDecoupe['codeFournier'.$i]);
$this->observations[$numeroLigne][$positionTaxon]['sc_id_taxon'] =
$this->identifierTaxon2($idTaxon, $titre['typeTableau']);
if ($ligneDecoupe['strate'.$i] != null) {
$this->observations[$numeroLigne][$positionTaxon]['sc_id_strate'] = $ligneDecoupe['strate'.$i];
} else {
$this->observations[$numeroLigne][$positionTaxon]['sc_id_strate'] = 0;
}
if ($ligneDecoupe['abondance'.$i] == '' || $ligneDecoupe['abondance'.$i] == '0') {
$this->observations[$numeroLigne][$positionTaxon]['sc_ce_abondance'] = '?';
} else {
$this->observations[$numeroLigne][$positionTaxon]['sc_ce_abondance'] = $ligneDecoupe['abondance'.$i];
}
}
}
}
private function identifierTaxon2($idTaxon, $typeTableau) {
$id = 0;
if ($typeTableau == 2 && $idTaxon == 75000) {
$id = $this->tableauTaxon->getId(75000, 'algues');
} elseif ($typeTableau == 2 && $idTaxon == 85000) {
$id = $this->tableauTaxon->getId(85000, 'characees');
} elseif ($typeTableau == 2 && $idTaxon == 90000) {
$id = $this->tableauTaxon->getId(90000, 'bryo');
} elseif ($typeTableau == 2 && $idTaxon == 95000) {
$id = $this->tableauTaxon->getId(95000, 'lichen');
} elseif ($typeTableau == 2 && $idTaxon >= 90000) {
$idTaxon -= 90000;
$id = $this->tableauTaxon->getId($idTaxon, 'bryo');
} elseif ($typeTableau == 2 && $idTaxon >= 20000) {
$idTaxon -= 20000;
$id = $this->tableauTaxon->getId($idTaxon, 'floeur');
} else {
if ($typeTableau == 2 && ($idTaxon != '00000' && $idTaxon != '')) {
$idTaxon = (substr($idTaxon, 0, 2) - 1)*600 +
(substr($idTaxon, 2, 2) - 11)*10 + (substr($idTaxon, 4, 1) + 1);
} elseif ($idTaxon != '00000' && $idTaxon != '') {
$idTaxon = ltrim($idTaxon, "0");
} else {
$idTaxon = 0;
}
$id = $this->tableauTaxon->getId($idTaxon, 'fournier');
}
return $id;
}
 
// fonctions nécessaires pour les tableaux de type standard (0)
private function identifierTaxon($nombreReleves, $ligneDecoupe, $numeroLigne) {
// decoupe le champs remarque
if ($ligneDecoupe['abondance_rem'] != null) {
$rem = trim(substr($ligneDecoupe['abondance_rem'], (int) ltrim($nombreReleves), strlen($ligneDecoupe['abondance_rem'])));
} else {
$rem = substr($ligneDecoupe['indetermine'], (int) ltrim($nombreReleves), strlen($ligneDecoupe['indetermine']));
}
$remAnalyse = $this->analyserRemarque($rem, $numeroLigne);
$id = 0;
if ($ligneDecoupe['idTaxon'] != null) {
$idTaxon = str_replace(' ', '0', $ligneDecoupe['idTaxon']);
switch ($idTaxon) { // probleme code dans les 80000 attentes reponses brisse
case 0 : $id = $this->recupererId($remAnalyse, 00000); break;
case 00000 : $id = $this->recupererId($remAnalyse, $idTaxon); break;
case 20000 : $id = $this->recupererId($remAnalyse, $idTaxon, 'floeur'); break;
case 75000 : $id = $this->recupererId($remAnalyse, $idTaxon, 'algues'); break;
case 85000 : $id = $this->recupererId($remAnalyse, $idTaxon, 'characees'); break;
case 90000 : $id = $this->recupererId($remAnalyse, $idTaxon, 'bryo'); break;
case 95000 : $id = $this->recupererId($remAnalyse, $idTaxon, 'lichen'); break;
default :
if ($idTaxon < 1100) {
$id = $this->recupererId($remAnalyse, 0);
}elseif ($idTaxon < 20000) {
// transformer code fournier en numéro fournier
$numeroFournier = (substr($idTaxon, 0, 2) - 1)*600 + (substr($idTaxon, 2, 2) - 11)*10 +
(substr($idTaxon, 4, 1) + 1);
$id = $this->recupererId($remAnalyse, $numeroFournier, 'fournier'); break;
} elseif ($idTaxon < 90000) {
$idTaxon -= 20000;
$id = $this->recupererId($remAnalyse, $idTaxon, 'floeur'); break;
} else {
$idTaxon -= 90000;
$id = $this->recupererId($remAnalyse, $idTaxon, 'bryo'); break;
}
break;
}
} else {
$id = $this->recupererId($remAnalyse, 0);
}
return $id;
}
 
private function recupererId($remAnalyse, $idTaxon, $flore = 'ind') {
if ($remAnalyse['presence'] == true) {
$id = $this->tableauTaxon->getId($remAnalyse['num'], $remAnalyse['flore'], $remAnalyse['nom'],
$flore, $idTaxon, $remAnalyse['remarques']);
} else {
$id = $this->tableauTaxon->getId($idTaxon, $flore);
}
return $id;
}
 
private function analyserRemarque($rem, $numeroLigne) {
$taxon['presence'] = false;
if ($rem != '') {
$taxon['flore'] = 'ind';
$taxon['num'] = 0;
$taxon['nom'] = null;
$taxon['remarques'] = null;
$remAsterique = preg_split('/\*/', $rem);
// recuperer le numero et/ou le nom qui sont en remarque
foreach ($remAsterique as $morceauRem) {
if ($morceauRem == 'N000000') {
} elseif (preg_match('/^[A-Z]{1,2}\s{5,6}$/', $morceauRem)) {
} elseif (preg_match('/^[\s0]*$/', $morceauRem)) {
} elseif (preg_match('/^([A-Z]{1,2})([0\s]{5,6})$/', $morceauRem)) {
} elseif (preg_match('/^[\d\s]{5}\d$/', $morceauRem)) {
$taxon['num'] = ltrim(str_replace(' ', '0', $morceauRem), '0');
$taxon['flore'] = 'syntri';
$taxon['presence'] = true;
} elseif (preg_match('/^\s*(\d[\d\s]+\d)\s*$/', $morceauRem, $match)) {
$taxon['num'] = ltrim(str_replace(' ', '0', $match[1]), '0');
$taxon['flore'] = 'syntri';
$taxon['presence'] = true;
} elseif (preg_match('/^\s*[A-Za-z][a-z\s\.()]+$/', $morceauRem)) {
$taxon['nom'] = $morceauRem;
$taxon['presence'] = true;
} elseif (preg_match('/^\s*("\s*[\s"]*)([A-Za-z][A-Za-z\s\.()]+)$/', $morceauRem, $match)) {
foreach ($this->observations[$numeroLigne-1] as $obsPrec) {
$idPrec = $obsPrec['sc_id_taxon'];
}
$nombreQuote = substr_count($match[1], '"');
$nomPrec = preg_split('/\s/', $this->tableauTaxon->getNom($idPrec)); $nom = '';
if (preg_match('/^(x|var|ssp)/', $match[2])) {
} elseif ($nombreQuote == 2 || $nombreQuote == 4) {
$nombreQuote = $nombreQuote/2;
}
for ($i = 0; $i < $nombreQuote; $i++) {
if ($i < count($nomPrec)) {
$nom .= $nomPrec[$i]." ";
}
}
$taxon['nom'] = $nom.$match[2];
$taxon['remarques'] = $morceauRem;
$taxon['presence'] = true;
} elseif (preg_match('/^([A-Z]{1,2})([\d\s]{4,5}\d)$/', $morceauRem, $match) ||
preg_match('/^(\s{1,2})([\d\s]{4,5}\d)$/', $morceauRem, $match)) {
switch (trim($match[1])) {
case 'S' : $taxon['flore'] = 'syntri'; break;
case 'CI' : $taxon['flore'] = 'ciff'; break;
case 'C' : $taxon['flore'] = 'codefr94'; break;
case 'BD' : $taxon['flore'] = 'bdnff'; break;
case 'N' : $taxon['flore'] = 'syntri'; break;
case '' : $taxon['flore'] = 'syntri'; break;
default : $taxon['flore'] = 'ind'; break;
}
$taxon['num'] = ltrim(str_replace(' ', '0', $match[2]), '0');
$taxon['presence'] = true;
} else {
$morceauRem = trim($morceauRem);
if ($morceauRem != '' && $morceauRem != null) {
$taxon['remarques'] = $morceauRem;
$taxon['presence'] = true;
}
}
}
}
return $taxon;
}
 
// +-------------------------------------------------------------------------------------------------------------------+
// Fonction Statistiques
private function executerStats() {
$nombreTotalLignesTable = $this->dao->getNombreLigne($this->param_bd_pour_stat);
print_r($nombreTotalLignesTable);
}
 
// +-------------------------------------------------------------------------------------------------------------------+
// Fonction générale
private function ouvrirDossier($nomDossier) {
$tableaux = null;
if (file_exists($nomDossier) === true) {
if (is_dir($nomDossier)) {
if ($dossierOuvert = opendir($nomDossier) ) {
while ( ($nomFichier = readdir($dossierOuvert)) !== false) {
if ( !is_dir($nomFichier) ) {
$nomFichier = $nomDossier.$nomFichier;
$tableaux[$nomFichier] = $this->ouvrirFichier($nomFichier);
}
}
closedir($dossierOuvert);
} else {
$this->traiterErreur("Le dossier $nomDossier n'a pas pu être ouvert.");
}
} else {
$tableaux[$nomDossier] = $this->ouvrirFichier($nomDossier);
}
} else {
$this->traiterErreur("Le dossier $nomDossier est introuvable.");
}
return $tableaux;
}
 
// Prend en entree un fichier et retourne un tableau de Tableau phytosocio ou stations
private function ouvrirFichier($nomFichier) {
$tableauxDecoupes = null;
$clefTableau = 0;
$clefLigne = 0;
if (file_exists($nomFichier) === true) {
if ( $fichierOuvert = fopen($nomFichier, 'r') ) {
while ($ligne = fgets($fichierOuvert)) {
if (preg_match('/^.*9{10}.*$/', $ligne)) {
$clefTableau ++ ;
$clefLigne = 0;
} else {
$tableauxDecoupes[$clefTableau][$clefLigne] = rtrim($ligne, " \t");
$clefLigne ++;
}
}
fclose($fichierOuvert);
} else {
$this->traiterErreur("Le fichier $nomFichier n'a pas pu être ouvert.");
}
} else {
$this->traiterErreur("Le fichier $nomFichier est introuvable.");
}
return $tableauxDecoupes;
}
// utilise les tableaux format_titre ou format_station pour découper les lignes
private function decouperLigne($ligne, $format) {
$ligne = rtrim($ligne);
$taille = strlen($ligne);
foreach ($format as $param => $position) {
// si la taille de la ligne est inférieure à la taille du champs que l'on veut récupérer
if ($taille < ($position[0]+$position[1])) {
// on met à null sauf dans certains formats
$ligneDecoupe[$param] = null;
if (isset($format['numLigne'])) {
$ligneDecoupe['indetermine'] = rtrim(substr($ligne, $position[0], $taille));
}
} else {
$ligneDecoupe[$param] = trim(substr($ligne, $position[0], $position[1]));
}
}
return $ligneDecoupe;
}
}
?>
/trunk/scripts/modules/sophy/sophy.ini
New file
0,0 → 1,20
; +------------------------------------------------------------------------------------------------------+
; Général
; Séparateur de dossier
ds = DIRECTORY_SEPARATOR
 
; +------------------------------------------------------------------------------------------------------+
; Info sur l'application
info.nom = Scripts de gestion de la phytosociologie
; Abréviation de l'application
info.abr = sophy
; Version du Framework nécessaire au fonctionnement de cette application
info.framework.version = 0.2
;Encodage de l'application
appli_encodage = "UTF-8"
version="2010-12-02"
dossierDonneesSophy = "{ref:dossierDonneesEflore}{ref:info.abr}/{ref:version}/"
[fichiers]
structureSql = "sophy.sql"
[chemins]
structureSql = "{ref:dossierDonneesSophy}{ref:fichiers.structureSql}"