Subversion Repositories eFlore/Projets.eflore-projets

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
460 delphine 1
<?php
2
// Encodage : UTF-8
3
// +-------------------------------------------------------------------------------------------------------------------+
4
/**
5
 * Traitement des fichiers de la banque de données SOPHY pour insertion
6
 *
7
 * Description : classe permettant d'insérer les tableaux phytosociologiques de la banque de données SOPHY
8
 * Utilisation : php script.php insertion -a test
9
 *
10
 * @category		PHP 5.3
11
 * @package		phytosocio
12
 //Auteur original :
13
 * @author		Delphine CAUQUIL <delphine@tela-botanica.org>
14
 * @copyright	Copyright (c) 2009, Tela Botanica (accueil@tela-botanica.org)
15
 * @license		http://www.gnu.org/licenses/gpl.html Licence GNU-GPL-v3
16
 * @license		http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL-v2
17
 * @version		$Id$
18
 */
19
// +-------------------------------------------------------------------------------------------------------------------+
20
class Insertion extends EfloreScript {
21
 
22
	protected $tableauTaxon;
23
	protected $dao;
24
	protected $observations;
25
	// Paramêtres autorisées lors de l'appel au script en ligne de commande
26
	protected $parametres_autorises = array(
27
		'-n' => array(true, true, 'Nom du fichier ou du dossier à traiter'));
28
 
29
	protected $param_bd_pour_stat = array(
30
		'sophy_publication' => array(),
31
		'sophy_tableau' => array('stab_id_publi' => 'nombrePubli'),
32
		'sophy_releve' => array(
33
			'sr_id_publi' => 'nombrePubli',
34
			'sr_id_publi, sr_id_tableau' => 'nombreTableau',
35
			'sr_id_station' => 'nombreStation'),
36
		'sophy_observation' => array(
37
			'so_id_publi' => 'nombrePubli',
38
			'so_id_publi, so_id_tableau' => 'nombreTableau',
39
			'so_id_publi, so_id_tableau, so_id_releve' => 'nombreReleve',
40
			'so_id_taxon' => 'nombreTaxon'),
41
		'sophy_station' => array(),
42
		'sophy_taxon' => array()
43
	);
44
 
45
	// Composition classique d'un titre de tableau de stations ou phytosociologiques
46
	protected $format_titre = array(
47
		'numPubli' => array(0, 4),
48
		'numTableau' => array(4, 3),
49
		'nombreStations' => array(7, 3),
50
		'titrePubli' => array(11, -1),
51
		'typeTableau' => array(79, 1)
52
	);
53
 
54
	// Composition classique d'une station
55
	protected $format_station = array(
56
		'numSource' => array(0, 4),
57
		'posteMeteo' => array(4, 5),
58
		'nomStation' => array(10, 38),
59
		'latitude' => array(49, 7),
60
		'codePays' => array(56, 2),
61
		'longitude' => array(59, 6),
62
		'codeDept' => array(66, 2),
63
		'altitude' => array(69, 4),
64
		'codeCommune' => array(74, 3),
65
		'precisionGeographique' => array(78, 1),
66
		'systemeProjection' => array(79, 1),
67
		'latitude2' => array(80, 8),
68
		'longitude2' => array(88, 8)
69
	);
70
 
71
	// Composition classique d'une ligne de tableau phytosociologique
72
	protected $format_tableau = array(
73
 
74
			'numLigne' => array(0, 3),
75
			'idTaxon' => array(3, 5),
76
			'strate' => array(8, 1),
77
			'codeFlore' => array(9, 1),
78
			'abondance_rem' => array(10, 70)),
79
	2 => array(
80
			'numSource' => array(0, 5),
81
			'posteMeteo' => array(5, 3),
82
			'numLigne' => array(8, 2),
83
			'codeFournier1' => array(10, 5),
84
			'abondance1' => array(15, 1),
85
			'strate1' => array(16, 1),
86
			'codeFournier2' => array(17, 5),
87
			'abondance2' => array(22, 1),
88
			'strate2' => array(23, 1),
89
			'codeFournier3' => array(24, 5),
90
			'abondance3' => array(29, 1),
91
			'strate3' => array(30, 1),
92
			'codeFournier4' => array(31, 5),
93
			'abondance4' => array(36, 1),
94
			'strate4' => array(37, 1),
95
			'codeFournier5' => array(38, 5),
96
			'abondance5' => array(43, 1),
97
			'strate5' => array(44, 1),
98
			'codeFournier6' => array(45, 5),
99
			'abondance6' => array(50, 1),
100
			'strate6' => array(51, 1),
101
			'codeFournier7' => array(52, 5),
102
			'abondance7' => array(57, 1),
103
			'strate7' => array(58, 1),
104
			'codeFournier8' => array(59, 5),
105
			'abondance8' => array(64, 1),
106
			'strate8' => array(65, 1),
107
			'codeFournier9' => array(66, 5),
108
			'abondance9' => array(71, 1),
109
			'strate9' => array(72, 1),
110
			'codeFournier10' => array(73, 5),
111
			'abondance10' => array(78, 1),
112
			'strate10' => array(79, 1)),
113
	6 => array(
114
			'numSource' => array(0, 4),
115
			'posteMeteo' => array(4, 4),
116
			'numLigne' => array(8, 2),
117
			'strate1' => array(10, 1),
118
			'codeFournier1' => array(11, 4),
119
			'abondance1' => array(16, 1),
120
			'strate2' => array(17, 1),
121
			'codeFournier2' => array(18, 4),
122
			'abondance2' => array(23, 1),
123
			'strate3' => array(24, 1),
124
			'codeFournier3' => array(25, 4),
125
			'abondance3' => array(30, 1),
126
			'strate4' => array(31, 1),
127
			'codeFournier4' => array(32, 4),
128
			'abondance4' => array(37, 1),
129
			'strate5' => array(38, 1),
130
			'codeFournier5' => array(39, 4),
131
			'abondance5' => array(44, 1),
132
			'strate6' => array(45, 1),
133
			'codeFournier6' => array(46, 4),
134
			'abondance6' => array(51, 1),
135
			'strate7' => array(52, 1),
136
			'codeFournier7' => array(53, 4),
137
			'abondance7' => array(58, 1),
138
			'strate8' => array(59, 1),
139
			'codeFournier8' => array(60, 4),
140
			'abondance8' => array(65, 1),
141
			'strate9' => array(66, 1),
142
			'codeFournier9' => array(67, 4),
143
			'abondance9' => array(72, 1),
144
			'strate10' => array(73, 1),
145
			'codeFournier10' => array(74, 4),
146
			'abondance10' => array(79, 1)),
147
	7 => array(
148
			'numReleve' => array(2, 3),
149
			'posteMeteo' => array(7, 3),
150
			'codeFournier1' => array(10, 4),
151
			'abondance1' => array(14, 1),
152
			'strate1' => array(15, 1),
153
			'codeFournier2' => array(16, 4),
154
			'abondance2' => array(20, 1),
155
			'strate2' => array(21, 1),
156
			'codeFournier3' => array(22, 4),
157
			'abondance3' => array(26, 1),
158
			'strate3' => array(27, 1),
159
			'codeFournier4' => array(28, 4),
160
			'abondance4' => array(32, 1),
161
			'strate4' => array(33, 1),
162
			'codeFournier5' => array(34, 4),
163
			'abondance5' => array(38, 1),
164
			'strate5' => array(39, 1),
165
			'codeFournier6' => array(40, 4),
166
			'abondance6' => array(44, 1),
167
			'strate6' => array(45, 1),
168
			'codeFournier7' => array(46, 4),
169
			'abondance7' => array(50, 1),
170
			'strate7' => array(51, 1),
171
			'codeFournier8' => array(52, 4),
172
			'abondance8' => array(56, 1),
173
			'strate8' => array(57, 1),
174
			'codeFournier9' => array(58, 4),
175
			'abondance9' => array(62, 1),
176
			'strate9' => array(63, 1),
177
			'codeFournier10' => array(64, 4),
178
			'abondance10' => array(68, 1),
179
			'strate10' => array(69, 1),
180
			'numLigne' => array(71, 2),
181
			'codeCarte' => array(73, 7))
182
	);
183
 
184
// +-------------------------------------------------------------------------------------------------------------------+
185
	public function executer() {
186
		include_once dirname(__FILE__).'/bibliotheque/Dao.php';
187
		Config::charger(dirname(__FILE__).'/sophy.ini');
188
 
189
		$this->dao = new Dao();
190
		// Récupération de paramétres
191
		// Lancement de l'action demandée
192
		$cmd = $this->getParametre('a');
193
		switch ($cmd) {
194
			case 'testDossier' :
195
				$this->executerTestDossier();
196
				break;
197
			case 'chargerStructureSql' :
198
				$this->chargerStructureSql();
199
				break;
200
			case 'supprimerTous' :
201
				$this->supprimerTous();
202
			case 'biblio' :
203
				$this->executerBiblio();
204
				break;
205
			case 'station' :
206
				include_once dirname(__FILE__).'/bibliotheque/gPoint.php';
207
				$this->executerStation();
208
				break;
209
			case 'stationCodeInsee' :
210
				$this->executerStationCodeInsee();
211
				break;
212
			case 'tableau' :
213
				include_once dirname(__FILE__).'/bibliotheque/TaxonDao.php';
214
				$this->tableauTaxon = new TaxonDao();
215
				$this->executerTableau();
216
				break;
217
			case 'stats' :
218
				$this->executerStats();
219
				break;
220
			case 'tapir' :
221
				$info = $this->dao->creerTapir();
222
				$this->traiterErreur($info);
223
				break;
224
			default :
225
				$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
226
		}
227
	}
228
	protected function chargerStructureSql() {
229
		$contenuSql = $this->recupererContenu(Config::get('chemins.structureSql'));
230
		$this->executerScripSql($contenuSql);
231
	}
232
 
233
	protected function executerScripSql($sql) {
234
		$requetes = Outils::extraireRequetes($sql);
235
		foreach ($requetes as $requete) {
236
			$this->getBdd()->requeter($requete);
237
		}
238
	}
239
 
240
	private function supprimerTous() {
241
		$requete = "DROP TABLE IF EXISTS sophy_abondance, `sophy_bdnff`, `sophy_bryophyte`, `sophy_ciff`, ".
242
				"`sophy_ciff_fournier`, `sophy_codefr94`, `sophy_flora_europea`, `sophy_fournier`, `sophy_fournier_bdnff`,".
243
				" `sophy_observation`, `sophy_precision_geo`, `sophy_publication`, `sophy_releve`, `sophy_station`, `sophy_strate`,".
244
				" `sophy_syntri`, `sophy_syntri_fournier`, `sophy_tableau`, `sophy_taxon`";
245
		$this->getBdd()->requeter($requete);
246
	}
247
// +-------------------------------------------------------------------------------------------------------------------+
248
	// vérifie qu'il n'y est pas de fichier en double dans le dossier
249
	// à faire avant d'insérer un nouveau dossier
250
	private function executerTestDossier() {
251
		$nomDossier = Config::get('dossierDonneesSophy').$this->getParametre('n');
252
		if (file_exists($nomDossier) === true) {
253
			if (is_dir($nomDossier)) {
254
				if ($dossierOuvert = opendir($nomDossier) ) {
255
					while ( ($nomFichier = readdir($dossierOuvert)) !== false) {
256
						if ( !is_dir($nomFichier) ) {
257
							if (preg_match('/^[ST]{1,2}(\d{2}1)(\d{2}0)\.*/', $nomFichier, $match)) {
258
								// fichier normal type 001 à 010
259
							} elseif (preg_match('/^([ST]{1,2})(\d{3})(\d{3})\.*/', $nomFichier, $match)) {
260
								if (($match[1]=='ST' || $match[1]=='T') && ($match[3] - $match[2] == 1)) {
261
									// fichier normal type 1000 à 1010
262
								} else {
263
									$this->traiterErreur("Le fichier $nomFichier risque d'être en double.");
264
								}
265
							}
266
						}
267
					}
268
					closedir($dossierOuvert);
269
				} else {
270
					$this->traiterErreur("Le dossier $nomDossier n'a pas pu être ouvert.");
271
				}
272
			} else {
273
				$this->traiterErreur("$nomDossier n'est pas un dossier.");
274
			}
275
		} else {
276
			$this->traiterErreur("Le dossier $nomDossier est introuvable.");
277
		}
278
	}
279
 
280
// +-------------------------------------------------------------------------------------------------------------------+
281
	// Traitement du fichier biblio format csv
282
	// /opt/lampp/bin/php cli.php sophy/insertion -a biblio -n ./../donnees/sophy/BIBLIO.csv
283
	private function executerBiblio() {
284
		// Parcours le fichier .csv et enregistre chaque ligne dans un tableau.
285
		$nomFichier = Config::get('dossierDonneesSophy').'BIBLIO.csv';
286
		if ($nomFichier && file_exists($nomFichier) ){
287
			$extensionFichier = strtolower(strrchr($nomFichier, '.'));
288
			if ($extensionFichier === ".csv"){
289
				$file = new SplFileObject($nomFichier);
290
				$file->setFlags(SplFileObject::SKIP_EMPTY);
291
				$i = 0;
292
				echo "Traitement de la biblio : ";
293
				while (!$file->eof()){
294
					$ligne_csv = $file->fgetcsv();
295
					if (preg_match('/^\d+$/', $ligne_csv[0])){
296
						// récupére les colonnes du csv pour les transformer en table publication
297
						$biblio = $this->transformerBiblio($ligne_csv);
298
						// integre les publications à la bdd
299
						$info = $this->dao->integrerBiblio($biblio);
300
						$this->traiterInfo($info);
301
					}
302
					echo str_repeat(chr(8), ( strlen( $i ) + 1 ))."\t".$i++;
303
				}
304
				echo "\n";
305
			} else {
306
				$this->traiterErreur("Le fichier de références bibliographiques : $nomFichier n'est pas au format csv.");
307
			}
308
		} else {
309
			$this->traiterErreur("Le fichier de références bibliographiques : $nomFichier n'existe pas.");
310
		}
311
	}
312
 
313
	private function transformerBiblio($ligne_csv){
314
		$biblio['id_publi'] = $ligne_csv[0];
315
		$biblio['auteur'] = $ligne_csv[2].' '.$ligne_csv[3];
316
		$biblio['date'] = $ligne_csv[4];
317
		$biblio['titre'] = rtrim($ligne_csv[5].' '.$ligne_csv[6].' '.$ligne_csv[7].' '.$ligne_csv[8].' '.$ligne_csv[9]);
318
		$biblio['revue'] = rtrim($ligne_csv[10].' '.$ligne_csv[11]);
319
		$biblio['volume'] = $ligne_csv[12];
320
		$biblio['tome'] = $ligne_csv[13];
321
		$biblio['fascicule'] = $ligne_csv[14];
322
		$biblio['page_debut'] = $ligne_csv[15];
323
		$biblio['page_fin'] = $ligne_csv[16];
324
		return $biblio;
325
	}
326
 
327
// +-------------------------------------------------------------------------------------------------------------------+
328
	// Traitement des fichiers stations
329
	// /opt/lampp/bin/php cli.php insertion -a station -n ./../doc/donnees/ST/
330
	private function executerStation() {
331
		// transforme les fichiers passés en un tableau
332
		//de la forme [nom du fichier][index des tableaux][numéro de ligne]
333
		$tableaux = $this->ouvrirDossier(Config::get('dossierDonneesSophy').'ST/');
334
		foreach ($tableaux as $fichier) {
335
			foreach ($fichier as $tableau) {
336
				if ($tableau[0] != "") {
337
					// découpe la première ligne du tableau et insére les données dans la table tableau
338
					$titre = $this->analyserTitreStation($tableau['0']);
339
					for ($numReleve = 1; $numReleve < sizeof($tableau); $numReleve++) {
340
						// découpe les autres lignes, insére les données dans la table station et retourne l'id de la station
341
						if (trim($tableau[$numReleve]) == '') {
342
							$id_station = 0;
343
						} else {
344
							$id_station = $this->analyserStation($tableau[$numReleve]);
345
						}
346
						// insére les données tableau et station dans la table relevé
347
						$info = $this->dao->integrerReleve($titre, $numReleve, $id_station);
348
						if ($info != '') {
349
							$this->traiterErreur($info);
350
						}
351
					}
352
				}
353
			}
354
		}
355
	}
356
 
357
	private function analyserTitreStation($titre) {
358
		$titreDecoupe = $this->decouperLigne($titre, $this->format_titre);
359
		$info = $this->dao->integrerTableau($titreDecoupe);
360
		if ($info != '') {
361
			$this->traiterErreur($info);
362
		}
363
		return $titreDecoupe;
364
	}
365
 
366
	private function analyserStation($ligne) {
367
		$ligneDecoupe = $this->decouperLigne($ligne, $this->format_station);
368
		$ligneDecoupe['latitude_wgs'] = null;
369
		$ligneDecoupe['longitude_wgs'] = null;
370
		// vérifie que les zéro du code sont présents
371
		$ligneDecoupe = $this->analyserCodeDeptComm($ligneDecoupe);
372
		// transforme les grades paris en degrés décimaux wms
373
		$ligneDecoupe = $this->analyserCoordGrdParis($ligneDecoupe, $ligne);
374
		// transforme les degrés sexagécimaux en degrés décimaux
375
		$ligneDecoupe = $this->analyserCoordDmsWms($ligneDecoupe);
376
		// transforme les degrés décimaux en UTM
377
		$ligneDecoupe = $this->transformerCoordWmsUtm($ligneDecoupe);
378
		$ligneDecoupe['nomStation'] = utf8_encode($ligneDecoupe['nomStation']);
379
		$retour_requete = $this->dao->integrerStation($ligneDecoupe);
380
		if ($retour_requete['info'] != '') {
381
			$this->traiterErreur($retour_requete['info']);
382
		}
383
		return $retour_requete['id_station'];
384
	}
385
	private function executerStationCodeInsee() {
386
		$this->dao->creerColonneCodeInseeCalculee();
387
		$liste_coordonnees = $this->dao->rechercherCoordonneesWgs();
388
		foreach ($liste_coordonnees as $coordonnees) {
389
			$code_insee = $this->chercherCodeCommune($coordonnees['latitude'], $coordonnees['longitude']);
390
			if ($code_insee != "") {
391
				$this->dao->ajouterCodeInseeCalculee($coordonnees['latitude'], $coordonnees['longitude'], $code_insee);
392
			}
393
		}
394
	}
395
 
396
	private function chercherCodeCommune($latitude, $longitude) {
397
		$code_insee = '';
398
		if ($this->testerCoordonneesWgsFrance($latitude, $longitude)) {
399
			$url_service = "www.tela-botanica.org/service:eflore:0.1/osm/nom-commune".
400
						"?lat={$latitude}&lon={$longitude}";
401
			$url_service = str_replace(',', '.', $url_service);
402
			$ch = curl_init($url_service);
403
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
404
			$reponse = curl_exec($ch);
405
			$reponse = json_decode($reponse);
406
			if (isset($reponse->codeINSEE)) {
407
				$code_insee = $reponse->codeINSEE;
408
			}
409
			curl_close($ch);
410
		}
411
		return $code_insee;
412
	}
413
 
414
	private function testerCoordonneesWgsFrance($latitude, $longitude) {
415
		$coord_france = false;
416
		if ($latitude != '' && $longitude != '') {
417
			if ($latitude < 51.071667 && $latitude > 41.316667) {
418
				if ($longitude < 9.513333 && $longitude > -5.140278) {
419
					$coord_france = true;
420
				}
421
			}
422
		}
423
		return $coord_france;
424
	}
425
	private function analyserCodeDeptComm($ligneDecoupe) {
426
		if (preg_match('/^\d{2}$/', $ligneDecoupe['codeDept'])) {
427
		} elseif (preg_match('/^\s{0,1}\d{1,2}\s{0,1}$/',$ligneDecoupe['codeDept'])) {
428
			$ligneDecoupe['codeDept'] = str_replace(' ', '0', $ligneDecoupe['codeDept']);
429
		} else {
430
			$ligneDecoupe['codeDept'] = null;
431
		}
432
		if (preg_match('/^\d{3}$/', $ligneDecoupe['codeCommune'])) {
433
		} elseif (preg_match('/^\s{0,2}\d{1,2,3}\s{0,2}$/', $ligneDecoupe['codeCommune'])) {
434
			$ligneDecoupe['codeCommune'] = str_replace(' ', '0', $ligneDecoupe['codeCommune']);
435
		} elseif ($ligneDecoupe['codeDept'] == null) {
436
			$ligneDecoupe['codeCommune'] = null;
437
		} else {
438
			$ligneDecoupe['codeCommune'] = '000';
439
		}
440
		return $ligneDecoupe;
441
	}
442
	private function analyserCoordGrdParis($ligneDecoupe, $ligne) {
443
		if (preg_match('/[\s0]0\.000/', $ligneDecoupe['latitude'], $match)) {
444
			$ligneDecoupe['latitude'] = null;
445
			$ligneDecoupe['longitude'] = null;
446
		} elseif (preg_match('/\d{1,2}\.\d{2,3}/', $ligneDecoupe['latitude'], $match)) {// format souhaité
447
			$ligneDecoupe['latitude_wgs'] = round($ligneDecoupe['latitude']*0.9, 7);
448
			$ligneDecoupe['longitude_wgs'] = round($ligneDecoupe['longitude']*0.9+2.3372291, 7);
449
		} elseif (preg_match('/(\d{2})[\d\s,](\d{3})/', $ligneDecoupe['latitude'], $match)) {//erreur de saisie
450
			$ligneDecoupe['latitude'] = $match[1].'.'.$match[2];
451
			$ligneDecoupe['latitude_wgs'] = round($ligneDecoupe['latitude']*0.9, 7);
452
			$ligneDecoupe['longitude_wgs'] = round($ligneDecoupe['longitude']*0.9 + 2.3372291, 7);
453
		} elseif (preg_match('/^[a-zA-Z\s]*[a-zA-Z][a-zA-Z\s]*$/', $ligneDecoupe['latitude'])) {// lat absente + nom long
454
			$ligneDecoupe['nomStation'] = rtrim(substr($ligne, 10, 48));
455
			$ligneDecoupe['latitude'] = null;
456
			$ligneDecoupe['longitude'] = null;
457
		} elseif (preg_match('/.[AO].123/', $ligneDecoupe['latitude'], $match)) {
458
			$ligneDecoupe['latitude'] = null;
459
			$ligneDecoupe['longitude'] = null;
460
		}  elseif ($ligneDecoupe['latitude'] != null) {
461
			$ligneDecoupe['latitude'] = null;
462
			$ligneDecoupe['longitude'] = null;
463
		}
464
		return $ligneDecoupe;
465
	}
466
	private function analyserCoordDmsWms($ligneDecoupe) {
467
		if (preg_match('/(\d{1,2})\.(\d{2})\.(\d{2})/', $ligneDecoupe['latitude2'], $match)) {
468
			$ligneDecoupe['latitude_wgs'] = round($match[1]+($match[2]/60)+($match[3]/3600), 7);
469
		}
470
		if (preg_match('/(-{0,1})(\d{1,2})\.(\d{2})\.(\d{2})/', $ligneDecoupe['longitude2'], $match)) {
471
			$ligneDecoupe['longitude_wgs'] = round($match[2]+($match[3]/60)+($match[4]/3600), 7);
472
			if ($match[1] == '-') {
473
				$ligneDecoupe['longitude_wgs'] = -$ligneDecoupe['longitude_wgs'];
474
			}
475
		}
476
		return $ligneDecoupe;
477
	}
478
	private function transformerCoordWmsUtm($ligneDecoupe) {
479
		$ligneDecoupe['utmNorthing'] = null;
480
		$ligneDecoupe['utmEasting'] = null;
481
		$ligneDecoupe['utmZone'] = null;
482
		if ($ligneDecoupe['longitude_wgs'] != null && $ligneDecoupe['latitude_wgs'] != null) {
483
			$convertisseur = new gPoint();
484
			$convertisseur->setLongLat($ligneDecoupe['longitude_wgs'], $ligneDecoupe['latitude_wgs']);
485
			$convertisseur->convertLLtoTM();
486
			$ligneDecoupe['utmNorthing'] = round($convertisseur->N(), 2);
487
			$ligneDecoupe['utmEasting'] = round($convertisseur->E(), 2);
488
			$ligneDecoupe['utmZone'] = $convertisseur->Z();
489
 
490
		}
491
		return $ligneDecoupe;
492
	}
493
 
494
// +-------------------------------------------------------------------------------------------------------------------+
495
	// Traitement des fichiers tableaux
496
	// /opt/lampp/bin/php cli.php insertion -a tableau -n ./../doc/donnees/T/
497
	private function executerTableau() {
498
		$tableaux = $this->ouvrirDossier(Config::get('dossierDonneesSophy').'T/');
499
		$observations = array();
500
		foreach ($tableaux as $fichier) {
501
			foreach ($fichier as $tableau) {
502
				if ($tableau[0] != "") {
503
					$this->observations = array();
504
					$titre = $this->decouperLigne($tableau[0], $this->format_titre);
505
					$this->analyserTableau($tableau, $titre);
506
					/*$info = $this->dao->integrerObservation($this->observations, $titre);
507
					if ($info != '') {
508
						$this->traiterErreur($info);
509
					}*/
510
				}
511
			}
512
		} $this->tableauTaxon->integrerTaxons();
513
	}
514
 
515
	private function analyserTableau($tableau, $titre) {
516
		if ($titre['typeTableau'] == ' ') {
517
			$titre['typeTableau'] = 0;
518
		}
519
		switch ($titre['typeTableau']) {
520
			case 0 :
521
				for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
522
					$ligneDecoupe = $this->decouperLigne($tableau[$numeroLigne], $this->format_tableau['0']);
523
					if (trim($ligneDecoupe['idTaxon']) == '' && trim($ligneDecoupe['abondance_rem']) == '' &&
524
					preg_match('/^\s+\*N\s*\*\s*$/', $ligneDecoupe['indetermine'])) {
525
						for ($nombreReleve = 1; $nombreReleve <= $titre['nombreStations']; $nombreReleve ++) {
526
							$this->observations[$numeroLigne][$nombreReleve]['sc_id_publi'] = $titre['numPubli'];
527
							$this->observations[$numeroLigne][$nombreReleve]['sc_id_tableau'] = $titre['numTableau'];
528
							$this->observations[$numeroLigne][$nombreReleve]['sc_id_releve'] = $nombreReleve;
529
							$this->observations[$numeroLigne][$nombreReleve]['sc_num_ligne'] = $ligneDecoupe['numLigne'];
530
							$this->observations[$numeroLigne][$nombreReleve]['sc_id_taxon'] = 0;
531
							$this->observations[$numeroLigne][$nombreReleve]['sc_id_strate'] = 0;
532
							$this->observations[$numeroLigne][$nombreReleve]['sc_ce_abondance'] = '?';
533
						}
534
					} else {
535
						$this->creerObservType0($titre, $ligneDecoupe, $numeroLigne);
536
					}
537
				}
538
				for ($nombreReleve = 1; $nombreReleve <= $titre['nombreStations']; $nombreReleve ++) {
539
					$j = false;
540
					for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
541
						if (isset($this->observations[$numeroLigne][$nombreReleve])) {
542
							$j = true;
543
						}
544
					}
545
					if ($j == false) {
546
						$this->observations[0][$nombreReleve]['sc_id_publi'] = $titre['numPubli'];
547
						$this->observations[0][$nombreReleve]['sc_id_tableau'] = $titre['numTableau'];
548
						$this->observations[0][$nombreReleve]['sc_id_releve'] = $nombreReleve;
549
						$this->observations[0][$nombreReleve]['sc_num_ligne'] = 0;
550
						$this->observations[0][$nombreReleve]['sc_id_taxon'] = 0;
551
						$this->observations[0][$nombreReleve]['sc_id_strate'] = 0;
552
						$this->observations[0][$nombreReleve]['sc_ce_abondance'] = '?';
553
					}
554
				}
555
				break;
556
			case 2 :
557
				$numSource = 0; $numReleve = 0;
558
				for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
559
					$ligneDecoupe = $this->decouperLigne($tableau[$numeroLigne], $this->format_tableau['2']);
560
					if ($ligneDecoupe['numSource'] != $numSource) {
561
						// $numSource correspond au numero à la station par l'auteur,
562
						// $numReleve correspond à l'id de la station
563
						$numSource = $ligneDecoupe['numSource'];
564
						$numReleve ++;
565
					}
566
					if (strlen(trim($tableau[$numeroLigne])) < 10) {
567
						$this->observations[$numeroLigne][1]['sc_id_publi'] = $titre['numPubli'];
568
						$this->observations[$numeroLigne][1]['sc_id_tableau'] = $titre['numTableau'];
569
						$this->observations[$numeroLigne][1]['sc_id_releve'] = $numReleve;
570
						$this->observations[$numeroLigne][1]['sc_num_ligne'] = 0;
571
						$this->observations[$numeroLigne][1]['sc_id_taxon'] = 0;
572
						$this->observations[$numeroLigne][1]['sc_id_strate'] = 0;
573
						$this->observations[$numeroLigne][1]['sc_ce_abondance'] = '?';
574
					} else {
575
						$this->creerObservType2($titre, $ligneDecoupe, $numReleve, $numeroLigne);
576
					}
577
				}
578
				break;
579
			case 6 :
580
				$numSource = 0; $numReleve = 0;
581
				for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
582
					$ligneDecoupe = $this->decouperLigne($tableau[$numeroLigne], $this->format_tableau['6']);
583
					$num = (preg_match('/[\dA-Z]+\s+[\dA-Z]+/', $ligneDecoupe['numSource'].$ligneDecoupe['posteMeteo']))
584
							? ltrim($ligneDecoupe['numSource'])
585
							: $ligneDecoupe['numSource'].$ligneDecoupe['posteMeteo'];
586
					if ($num !== $numSource) {
587
						$numSource = $num;
588
						$numReleve ++;
589
					}
590
					$this->creerObservType2($titre, $ligneDecoupe, $numReleve, $numeroLigne);
591
				}
592
				break;
593
			case 7 :
594
				$numSource = 0; $numReleve = 0;
595
				for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
596
					$ligneDecoupe = $this->decouperLigne($tableau[$numeroLigne], $this->format_tableau['7']);
597
					if (trim($ligneDecoupe['numReleve']) !== $numSource) {
598
						$numSource = trim($ligneDecoupe['numReleve']);
599
						$numReleve ++;
600
					}
601
					$this->creerObservType2($titre, $ligneDecoupe, $numReleve, $numeroLigne);
602
				}
603
				break;
604
			default :
605
				for ($numeroLigne = 1; $numeroLigne < sizeof($tableau); $numeroLigne++) {
606
					$ligneDecoupe = $this->decouperLigne($tableau[$numeroLigne], $this->format_tableau['0']);
607
					$this->creerObservType0($titre, $ligneDecoupe);
608
				}
609
				break;
610
		}
611
		return $ligneDecoupe;
612
	}
613
	// crée des observations au format de la table à partir d'un tableau de type standard (0)
614
	private function creerObservType0($titre, $ligneDecoupe, $numeroLigne) {
615
		$observation = null;
616
		// Retourne l'id du taxon dans la bd sophy
617
		$idTaxon = $this->identifierTaxon($titre['nombreStations'], $ligneDecoupe, $numeroLigne);
618
		// découpe le champs abondance_rem ou indetermine selon le nombre de relevés
619
		$remAbondance = substr(
620
			($ligneDecoupe['abondance_rem'] != null) ? $ligneDecoupe['abondance_rem'] : $ligneDecoupe['indetermine'],
621
			0, $titre['nombreStations']);
622
		// si aucun relevé ne contient d'abondance pour un taxon, ajout d'une abondance ? pour ce taxon
623
		if (trim($remAbondance) == '') {
624
			$remAbondance = '?';
625
		}
626
		for ($numReleve = 1; $numReleve <= $titre['nombreStations']; $numReleve++) {
627
			if ($remAbondance === '?' && $numeroLigne === 1) {
628
				$abondance = '?';
629
			} else {
630
				$abondance = substr($remAbondance, ($numReleve-1), 1);
631
			}
632
			if ($abondance != '' && $abondance != ' ') {
633
				$this->observations[$numeroLigne][$numReleve]['sc_id_publi'] = $titre['numPubli'];
634
				$this->observations[$numeroLigne][$numReleve]['sc_id_tableau'] = $titre['numTableau'];
635
				$this->observations[$numeroLigne][$numReleve]['sc_id_releve'] = $numReleve;
636
				$this->observations[$numeroLigne][$numReleve]['sc_num_ligne'] = $numeroLigne;
637
				$this->observations[$numeroLigne][$numReleve]['sc_id_taxon'] = $idTaxon;
638
				if ($ligneDecoupe['strate'] != null) {
639
					$this->observations[$numeroLigne][$numReleve]['sc_id_strate'] = $ligneDecoupe['strate'];
640
				} else {
641
					$this->observations[$numeroLigne][$numReleve]['sc_id_strate'] = 0;
642
				}
643
				$this->observations[$numeroLigne][$numReleve]['sc_ce_abondance'] = $abondance;
644
			}
645
		}
646
	}
647
	// crée des observations au format de la table à partir d'un tableau de type 2, 6 ou 7 (10 plantes en lignes)
648
	private function creerObservType2($titre, $ligneDecoupe, $numReleve, $numeroLigne) {
649
		$observation = null;
650
		for ($i = 1; $i < 11; $i++) {
651
			// si le numéro de taxon et l'abondance ne sont pas nulls
652
			if ((($ligneDecoupe['abondance'.$i] == '' || $ligneDecoupe['abondance'.$i] == '0') &&
653
			(trim($ligneDecoupe['codeFournier'.$i]) == '' || $ligneDecoupe['codeFournier'.$i] == '0'))) {
654
			} else {
655
				$positionTaxon = $ligneDecoupe['numLigne']*10 + $i - 10;
656
				$this->observations[$numeroLigne][$positionTaxon]['sc_id_publi'] = $titre['numPubli'];
657
				$this->observations[$numeroLigne][$positionTaxon]['sc_id_tableau'] = $titre['numTableau'];
658
				$this->observations[$numeroLigne][$positionTaxon]['sc_id_releve'] = $numReleve;
659
				$this->observations[$numeroLigne][$positionTaxon]['sc_num_ligne'] = $positionTaxon;
660
				$idTaxon = str_replace(' ', '0', $ligneDecoupe['codeFournier'.$i]);
661
				$this->observations[$numeroLigne][$positionTaxon]['sc_id_taxon'] =
662
					$this->identifierTaxon2($idTaxon, $titre['typeTableau']);
663
				if ($ligneDecoupe['strate'.$i] != null) {
664
					$this->observations[$numeroLigne][$positionTaxon]['sc_id_strate'] = $ligneDecoupe['strate'.$i];
665
				} else {
666
					$this->observations[$numeroLigne][$positionTaxon]['sc_id_strate'] = 0;
667
				}
668
				if ($ligneDecoupe['abondance'.$i] == '' || $ligneDecoupe['abondance'.$i] == '0') {
669
					$this->observations[$numeroLigne][$positionTaxon]['sc_ce_abondance'] = '?';
670
				} else {
671
					$this->observations[$numeroLigne][$positionTaxon]['sc_ce_abondance'] = $ligneDecoupe['abondance'.$i];
672
				}
673
			}
674
		}
675
	}
676
 
677
	private function identifierTaxon2($idTaxon, $typeTableau) {
678
		$id = 0;
679
		if ($typeTableau == 2 && $idTaxon == 75000) {
680
			$id = $this->tableauTaxon->getId(75000, 'algues');
681
		} elseif ($typeTableau == 2 && $idTaxon == 85000) {
682
			$id = $this->tableauTaxon->getId(85000, 'characees');
683
		} elseif ($typeTableau == 2 && $idTaxon == 90000) {
684
			$id = $this->tableauTaxon->getId(90000, 'bryo');
685
		} elseif ($typeTableau == 2 && $idTaxon == 95000) {
686
			$id = $this->tableauTaxon->getId(95000, 'lichen');
687
		} elseif ($typeTableau == 2 && $idTaxon >= 90000) {
688
			$idTaxon -= 90000;
689
			$id = $this->tableauTaxon->getId($idTaxon, 'bryo');
690
		} elseif ($typeTableau == 2 && $idTaxon >= 20000) {
691
			$idTaxon -= 20000;
692
			$id = $this->tableauTaxon->getId($idTaxon, 'floeur');
693
		} else {
694
			if ($typeTableau == 2 && ($idTaxon != '00000' && $idTaxon != '')) {
695
				$idTaxon = (substr($idTaxon, 0, 2) - 1)*600 +
696
					(substr($idTaxon, 2, 2) - 11)*10 + (substr($idTaxon, 4, 1) + 1);
697
			} elseif ($idTaxon != '00000' && $idTaxon != '') {
698
				$idTaxon = ltrim($idTaxon, "0");
699
			} else {
700
				$idTaxon = 0;
701
			}
702
			$id = $this->tableauTaxon->getId($idTaxon, 'fournier');
703
		}
704
		return $id;
705
	}
706
 
707
	// fonctions nécessaires pour les tableaux de type standard (0)
708
	private function identifierTaxon($nombreReleves, $ligneDecoupe, $numeroLigne) {
709
		// decoupe le champs remarque
710
		if ($ligneDecoupe['abondance_rem'] != null) {
711
			$rem = trim(substr($ligneDecoupe['abondance_rem'], (int) ltrim($nombreReleves), strlen($ligneDecoupe['abondance_rem'])));
712
		} else {
713
			$rem = substr($ligneDecoupe['indetermine'], (int) ltrim($nombreReleves), strlen($ligneDecoupe['indetermine']));
714
		}
715
		$remAnalyse = $this->analyserRemarque($rem, $numeroLigne);
716
		$id = 0;
717
		if ($ligneDecoupe['idTaxon'] != null) {
718
			$idTaxon = str_replace(' ', '0', $ligneDecoupe['idTaxon']);
719
			switch ($idTaxon) { // probleme code dans les 80000 attentes reponses brisse
720
				case 0 : $id = $this->recupererId($remAnalyse, 00000); break;
721
				case 00000 : $id = $this->recupererId($remAnalyse, $idTaxon); break;
722
				case 20000 : $id = $this->recupererId($remAnalyse, $idTaxon, 'floeur'); break;
723
				case 75000 : $id = $this->recupererId($remAnalyse, $idTaxon, 'algues'); break;
724
				case 85000 : $id = $this->recupererId($remAnalyse, $idTaxon, 'characees'); break;
725
				case 90000 : $id = $this->recupererId($remAnalyse, $idTaxon, 'bryo'); break;
726
				case 95000 : $id = $this->recupererId($remAnalyse, $idTaxon, 'lichen'); break;
727
				default :
728
					if ($idTaxon < 1100) {
729
						$id = $this->recupererId($remAnalyse, 0);
730
					}elseif ($idTaxon < 20000) {
731
						// transformer code fournier en numéro fournier
732
						$numeroFournier = (substr($idTaxon, 0, 2) - 1)*600 + (substr($idTaxon, 2, 2) - 11)*10 +
733
						(substr($idTaxon, 4, 1) + 1);
734
						$id = $this->recupererId($remAnalyse, $numeroFournier, 'fournier'); break;
735
					} elseif ($idTaxon < 90000) {
736
						$idTaxon -= 20000;
737
						$id = $this->recupererId($remAnalyse, $idTaxon, 'floeur'); break;
738
					} else {
739
						$idTaxon -= 90000;
740
						$id = $this->recupererId($remAnalyse, $idTaxon, 'bryo'); break;
741
					}
742
					break;
743
			}
744
		} else {
745
			$id = $this->recupererId($remAnalyse, 0);
746
		}
747
		return $id;
748
	}
749
 
750
	private function recupererId($remAnalyse, $idTaxon, $flore = 'ind') {
751
		if ($remAnalyse['presence'] == true) {
752
			$id = $this->tableauTaxon->getId($remAnalyse['num'], $remAnalyse['flore'], $remAnalyse['nom'],
753
			$flore, $idTaxon, $remAnalyse['remarques']);
754
		} else {
755
			$id = $this->tableauTaxon->getId($idTaxon, $flore);
756
		}
757
		return $id;
758
	}
759
 
760
	private function analyserRemarque($rem, $numeroLigne) {
761
		$taxon['presence'] = false;
762
		if ($rem != '') {
763
			$taxon['flore'] = 'ind';
764
			$taxon['num'] = 0;
765
			$taxon['nom'] = null;
766
			$taxon['remarques'] = null;
767
			$remAsterique = preg_split('/\*/', $rem);
768
			// recuperer le numero et/ou le nom qui sont en remarque
769
			foreach ($remAsterique as $morceauRem) {
770
				if ($morceauRem == 'N000000') {
771
				} elseif (preg_match('/^[A-Z]{1,2}\s{5,6}$/', $morceauRem)) {
772
				} elseif (preg_match('/^[\s0]*$/', $morceauRem)) {
773
				} elseif (preg_match('/^([A-Z]{1,2})([0\s]{5,6})$/', $morceauRem)) {
774
				} elseif (preg_match('/^[\d\s]{5}\d$/', $morceauRem)) {
775
					$taxon['num'] = ltrim(str_replace(' ', '0', $morceauRem), '0');
776
					$taxon['flore'] = 'syntri';
777
					$taxon['presence'] = true;
778
				} elseif (preg_match('/^\s*(\d[\d\s]+\d)\s*$/', $morceauRem, $match)) {
779
					$taxon['num'] = ltrim(str_replace(' ', '0', $match[1]), '0');
780
					$taxon['flore'] = 'syntri';
781
					$taxon['presence'] = true;
782
				} elseif (preg_match('/^\s*[A-Za-z][a-z\s\.()]+$/', $morceauRem)) {
783
					$taxon['nom'] = $morceauRem;
784
					$taxon['presence'] = true;
785
				} elseif (preg_match('/^\s*("\s*[\s"]*)([A-Za-z][A-Za-z\s\.()]+)$/', $morceauRem, $match)) {
786
					foreach ($this->observations[$numeroLigne-1] as $obsPrec) {
787
						$idPrec = $obsPrec['sc_id_taxon'];
788
					}
789
					$nombreQuote = substr_count($match[1], '"');
790
					$nomPrec = preg_split('/\s/', $this->tableauTaxon->getNom($idPrec)); $nom = '';
791
					if (preg_match('/^(x|var|ssp)/', $match[2])) {
792
					} elseif ($nombreQuote == 2 || $nombreQuote == 4) {
793
						$nombreQuote = $nombreQuote/2;
794
					}
795
					for ($i = 0; $i < $nombreQuote; $i++) {
796
						if ($i < count($nomPrec)) {
797
							$nom .= $nomPrec[$i]." ";
798
						}
799
					}
800
					$taxon['nom'] = $nom.$match[2];
801
					$taxon['remarques'] = $morceauRem;
802
					$taxon['presence'] = true;
803
				} elseif (preg_match('/^([A-Z]{1,2})([\d\s]{4,5}\d)$/', $morceauRem, $match) ||
804
				preg_match('/^(\s{1,2})([\d\s]{4,5}\d)$/', $morceauRem, $match)) {
805
					switch (trim($match[1])) {
806
						case 'S' : $taxon['flore'] = 'syntri'; break;
807
						case 'CI' : $taxon['flore'] = 'ciff'; break;
808
						case 'C' : $taxon['flore'] = 'codefr94'; break;
809
						case 'BD' : $taxon['flore'] = 'bdnff'; break;
810
						case 'N' : $taxon['flore'] = 'syntri'; break;
811
						case '' : $taxon['flore'] = 'syntri'; break;
812
						default : $taxon['flore'] = 'ind'; break;
813
					}
814
					$taxon['num'] = ltrim(str_replace(' ', '0', $match[2]), '0');
815
					$taxon['presence'] = true;
816
				} else {
817
					$morceauRem = trim($morceauRem);
818
					if ($morceauRem != '' && $morceauRem != null) {
819
						$taxon['remarques'] = $morceauRem;
820
						$taxon['presence'] = true;
821
					}
822
				}
823
			}
824
		}
825
		return $taxon;
826
	}
827
 
828
	// +-------------------------------------------------------------------------------------------------------------------+
829
	// Fonction Statistiques
830
	private function executerStats() {
831
		$nombreTotalLignesTable = $this->dao->getNombreLigne($this->param_bd_pour_stat);
832
		print_r($nombreTotalLignesTable);
833
	}
834
 
835
	// +-------------------------------------------------------------------------------------------------------------------+
836
	// Fonction générale
837
	private function ouvrirDossier($nomDossier) {
838
		$tableaux = null;
839
		if (file_exists($nomDossier) === true) {
840
			if (is_dir($nomDossier)) {
841
				if ($dossierOuvert = opendir($nomDossier) ) {
842
					while ( ($nomFichier = readdir($dossierOuvert)) !== false) {
843
						if ( !is_dir($nomFichier) ) {
844
							$nomFichier = $nomDossier.$nomFichier;
845
							$tableaux[$nomFichier] = $this->ouvrirFichier($nomFichier);
846
						}
847
					}
848
					closedir($dossierOuvert);
849
				} else {
850
					$this->traiterErreur("Le dossier $nomDossier n'a pas pu être ouvert.");
851
				}
852
			} else {
853
				$tableaux[$nomDossier] = $this->ouvrirFichier($nomDossier);
854
			}
855
		} else {
856
			$this->traiterErreur("Le dossier $nomDossier est introuvable.");
857
		}
858
		return $tableaux;
859
	}
860
 
861
	// Prend en entree un fichier et retourne un tableau de Tableau phytosocio ou stations
862
	private function ouvrirFichier($nomFichier) {
863
		$tableauxDecoupes = null;
864
		$clefTableau = 0;
865
		$clefLigne = 0;
866
		if (file_exists($nomFichier) === true) {
867
			if ( $fichierOuvert = fopen($nomFichier, 'r') ) {
868
				while ($ligne = fgets($fichierOuvert)) {
869
					if (preg_match('/^.*9{10}.*$/', $ligne)) {
870
						$clefTableau ++ ;
871
						$clefLigne = 0;
872
					} else {
873
						$tableauxDecoupes[$clefTableau][$clefLigne] = rtrim($ligne, " \t");
874
						$clefLigne ++;
875
					}
876
				}
877
				fclose($fichierOuvert);
878
			} else {
879
				$this->traiterErreur("Le fichier $nomFichier n'a pas pu être ouvert.");
880
			}
881
		} else {
882
			$this->traiterErreur("Le fichier $nomFichier est introuvable.");
883
		}
884
		return $tableauxDecoupes;
885
	}
886
 
887
	// utilise les tableaux format_titre ou format_station pour découper les lignes
888
	private function decouperLigne($ligne, $format) {
889
		$ligne = rtrim($ligne);
890
		$taille = strlen($ligne);
891
		foreach ($format as $param => $position) {
892
			// si la taille de la ligne est inférieure à la taille du champs que l'on veut récupérer
893
			if ($taille < ($position[0]+$position[1])) {
894
				// on met à null sauf dans certains formats
895
				$ligneDecoupe[$param] = null;
896
				if (isset($format['numLigne'])) {
897
					$ligneDecoupe['indetermine'] = rtrim(substr($ligne, $position[0], $taille));
898
				}
899
			} else {
900
				$ligneDecoupe[$param] = trim(substr($ligne, $position[0], $position[1]));
901
			}
902
		}
903
		return $ligneDecoupe;
904
	}
905
}
906
?>