Subversion Repositories eFlore/Applications.moissonnage

Rev

Rev 34 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
26 alex 1
<?php
2
 
3
/**
4
 *
5
 * Classe en charge de recuperer les donnees d'observation ou liees a leur localisation
6
 * Le jeu de donnees a interroger est partage en commun avec l'application EFlore
7
 *
8
 * On passera en parametre lors de la creation d'une instance un objet contenant la liste des criteres
9
 * qui vont restreindre le nombre de resultats a renvoyer
10
 *
11
 * Les deux operations suivantes peuvent etre utilisees dans les services :
12
 *   - recupererStations : va rechercher dans la base de donnees tous les points d'observations
13
 *     correspondant aux criteres de recherche demandes. La precision des lieux d'observation est
14
 *     soit un point precis, soit ramenee au niveau de la commune dans laquelle l'observation a ete faite
15
 *     En fonction du niveau de zoom et du nombre de resultats trouves, la presentation se fera
16
 *     soit par les points localisant les stations pour des niveaux de zoom eleves ou pour un nombre
17
 *     de stations inferieur a un seuil, ou par des mailles de 64*64 pixels dans le cas contraire
18
 *
19
 *   - recupererObservations : va rechercher dans la base de donnees les donnees sur des observations
20
 *     a partir des coordonnees longitude et latitude d'une station (+ des parametres additionnels)
21
 *
22
 * Les donnees seront renvoyees au format JSON
23
 *
34 alex 24
 * @package framework-0.4
26 alex 25
 * @author Alexandre GALIBERT <alexandre.galibert@tela-botanica.org>
26
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
27
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
28
 * @version $Id$
29
 * @copyright 2013 Tela Botanica (accueil@tela-botanica.org)
30
 *
31
 */
32
 
34 alex 33
class MoissonnageFormateur extends Formateur {
26 alex 34
 
35
 
34 alex 36
	final protected function construireRequeteStations() {
26 alex 37
		$requete =
31 alex 38
			"SELECT COUNT(guid) AS observations, lieu_station_nom AS nom, lieu_station_latitude AS latitude, ".
34 alex 39
			"lieu_station_longitude AS longitude, 'STATION' AS type_site, lieu_commune_code_insee AS code_insee, ".
40
			"'{$this->nomSource}' AS source FROM {$this->nomSource}_tapir WHERE 1 ".
26 alex 41
			$this->construireWhereDepartement().' '.
42
			$this->construireWhereAuteur().' '.
31 alex 43
			$this->construireWhereDate().' '.
26 alex 44
			$this->construireWhereReferentiel().' '.
45
			$this->construireWhereTaxon().' '.
46
			$this->construireWhereCoordonneesBbox().' '.
31 alex 47
			"GROUP BY lieu_station_longitude, lieu_station_latitude";
26 alex 48
		return $requete;
49
	}
50
 
34 alex 51
	final protected function construireRequeteObservations() {
26 alex 52
		$requete =
53
			"SELECT observation_id AS id_obs, nom_scientifique_complet AS nomSci, ".
34 alex 54
			"observation_date AS date, lieu_station_nom AS lieu, observateur_nom_complet AS observateur, ".
55
			"'{$this->nomSource}' AS projet FROM {$this->nomSource}_tapir WHERE 1 ".
26 alex 56
			$this->construireWhereAuteur().' '.
57
			$this->construireWhereReferentiel().' '.
31 alex 58
			$this->construireWhereDate().' '.
26 alex 59
			$this->construireWhereTaxon().' '.
60
			$this->construireWhereCoordonneesPoint().' '.
61
			"ORDER BY nom_scientifique_complet, date, observateur";
62
		return $requete;
63
	}
64
 
34 alex 65
	final protected function construireRequeteWfs() {
66
		$requete =
67
		"SELECT nom_scientifique_complet AS taxon, lieu_station_nom AS nom, lieu_station_latitude AS latitude, ".
43 alex 68
		"lieu_station_longitude AS longitude, 'station' AS type_site, lieu_commune_code_insee AS code_insee, ".
69
		"'{$this->nomSource}' AS source, observateur_nom_complet AS auteur ".
70
		"FROM {$this->nomSource}_tapir WHERE 1 ".
34 alex 71
		$this->construireWhereCoordonneesBbox().' '.
72
		$this->construireWhereNomScientifique().' '.
73
		"ORDER BY lieu_station_longitude, lieu_station_latitude";
74
		return $requete;
75
	}
76
 
77
	private function construireWhereTaxon() {
26 alex 78
		$sql = '';
79
		if (isset($this->criteresRecherche->taxon)) {
31 alex 80
			$taxons = $this->criteresRecherche->taxon;
81
			$criteres = array();
82
			foreach ($taxons as $taxon) {
83
				$criteres[] = "nom_scientifique_complet LIKE ".$this->getBdd()->proteger($taxon['nom']."%");
34 alex 84
				if ($taxon['rang'] >= Config::get('rang.espece')) {
85
					$criteres = array_merge($criteres, $this->concatenerSynonymesEtSousEspeces($taxon));
86
				} elseif ($taxon['rang'] == Config::get('rang.famille')) {
87
					$criteres = array_merge($criteres, $this->concatenerTaxonsGenres($taxon));
31 alex 88
				}
26 alex 89
			}
31 alex 90
			$sql = "AND (".implode(' OR ',array_unique($criteres)).")";
26 alex 91
		}
92
		return $sql;
93
	}
94
 
34 alex 95
	private function concatenerSynonymesEtSousEspeces($taxon) {
31 alex 96
		$referentiel = new Referentiel($this->criteresRecherche->referentiel, $taxon);
34 alex 97
		$sousTaxons = $referentiel->recupererSynonymesEtSousEspeces();
31 alex 98
		$criteres = array();
99
		foreach ($sousTaxons as $sousTaxon) {
100
			$criteres[] = "nom_scientifique_complet LIKE ".$this->getBdd()->proteger($sousTaxon['nom']."%");
101
		}
102
		return $criteres;
103
	}
104
 
34 alex 105
	private function concatenerTaxonsGenres($taxon) {
31 alex 106
		$referentiel = new Referentiel($this->criteresRecherche->referentiel, $taxon);
34 alex 107
		$sousTaxons = $referentiel->recupererGenres();
31 alex 108
		$criteres = array();
109
		foreach ($sousTaxons as $sousTaxon) {
110
			$criteres[] = "nom_scientifique_complet LIKE ".$this->getBdd()->proteger($sousTaxon['nom']."%");
111
		}
112
		return $criteres;
113
	}
114
 
34 alex 115
	private function construireWhereReferentiel() {
26 alex 116
		$sql = '';
34 alex 117
		if (isset($this->criteresRecherche->referentiel)) {
118
			$referentielSource = Config::get('referentiel_source');
119
			if (strstr($this->criteresRecherche->referentiel, $referentielSource) === false) {
120
				$sql = "AND 0";
121
			}
122
		}
26 alex 123
		return $sql;
124
	}
125
 
34 alex 126
	private function construireWhereDepartement() {
26 alex 127
		$sql = '';
31 alex 128
		if (isset($this->criteresRecherche->departement)) {
129
			$valeurs_a_proteger = $this->criteresRecherche->departement;
130
			foreach ($valeurs_a_proteger as $valeur) {
131
				$aProteger = $this->getBdd()->proteger($valeur . '%');
132
				$valeurs_protegees[] = "lieu_commune_code_insee LIKE {$aProteger}";
133
			}
134
			$valeurs = implode(' OR ', $valeurs_protegees);
135
			$sql = "AND ($valeurs)";
136
		}
26 alex 137
		return $sql;
138
	}
139
 
34 alex 140
	private function construireWhereAuteur() {
26 alex 141
		$sql = '';
142
		if (isset($this->criteresRecherche->auteur)) {
143
			$auteur = $this->getBdd()->proteger($this->criteresRecherche->auteur);
144
			$sql = "AND observateur_nom_complet = $auteur";
145
		}
146
		return $sql;
147
	}
31 alex 148
 
34 alex 149
	private function construireWhereDate() {
31 alex 150
		$sql = '';
151
		$dateDebut = isset($this->criteresRecherche->dateDebut) ? $this->criteresRecherche->dateDebut : null;
152
		$dateFin   = isset($this->criteresRecherche->dateFin) ? $this->criteresRecherche->dateFin : null;
153
		if (!is_null($dateDebut) || !is_null($dateFin)) {
154
			$dateDebut = !is_null($dateDebut) ? substr($dateDebut, 0, 4) : null;
155
			$dateFin   = !is_null($dateFin)   ? substr($dateFin, 0, 4)   : date('Y');
156
			$condition = '';
157
			if ($dateDebut == $dateFin) {
158
				$condition = "observation_date=".$dateDebut;
159
			} elseif (is_null($dateFin)) {
160
				$condition = "observation_date>=".$dateDebut;
161
			} elseif (is_null($dateDebut)) {
162
				$condition = "observation_date<=".$dateFin;
163
			} else {
164
				$condition = "observation_date BETWEEN ".$dateDebut." AND ".$dateFin;
165
			}
166
			$sql = "AND ($condition)";
167
		}
168
		return $sql;
169
	}
26 alex 170
 
34 alex 171
	private function construireWhereCoordonneesBbox() {
172
		$sql = '';
173
		if (isset($this->criteresRecherche->bbox)) {
174
			$bboxRecherche = $this->criteresRecherche->bbox;
175
			$conditions = array();
176
			foreach ($bboxRecherche as $bbox) {
177
				$conditions[] = "(lieu_station_longitude BETWEEN ".$bbox['ouest']." AND ".$bbox['est']." ".
178
					"AND lieu_station_latitude BETWEEN ".$bbox['sud']." AND ".$bbox['nord'].")";
179
			}
180
			$sql = 'AND ('.implode(' OR ', $conditions).')';
181
		}
26 alex 182
		return $sql;
183
	}
184
 
34 alex 185
	private function construireWhereNomScientifique() {
186
		$sql = '';
187
		if (isset($this->criteresRecherche->filtre)) {
188
			$filtre = $this->criteresRecherche->filtre;
189
			$valeur = "'{$filtre['valeur']}".($filtre['operateur'] == 'LIKE' ? "%" : "")."'";
190
			switch ($filtre['champ']) {
191
				case "taxon" : $sql = "AND nom_scientifique_complet {$filtre['operateur']} {$valeur}"; break;
192
			}
193
		}
26 alex 194
		return $sql;
195
	}
196
 
34 alex 197
	private function construireWhereCoordonneesPoint() {
198
		$sql = '';
199
		$conditions = array();
200
		foreach ($this->criteresRecherche->stations as $station) {
201
			if ($station[0] == $this->nomSource) {
202
				$longitude = str_replace(",", ".", strval($station[2]));
203
				$latitude  = str_replace(",", ".", strval($station[3]));
204
				$conditions[] = "(lieu_station_latitude={$longitude} AND lieu_station_longitude={$latitude})";
205
			}
206
		}
207
		if (count($conditions) > 0) {
208
			$sql = "AND (".implode(" OR ", $conditions).")";
209
		}
210
		return $sql;
211
	}
212
 
213
	final protected function obtenirNomsStationsSurPoint() {
214
		$requete = "SELECT DISTINCTROW lieu_station_nom FROM {$this->nomSource}_tapir WHERE 1 ".
26 alex 215
			$this->construireWhereTaxon().' '.
216
			$this->construireWhereCoordonneesPoint();
217
		$stations = $this->getBdd()->recupererTous($requete);
218
		$nomsStations = array();
219
		foreach ($stations as $station) {
220
			$nomsStations[] = $station['lieu_station_nom'];
221
		}
222
		return implode(', ', $nomsStations);
223
	}
224
 
34 alex 225
	final protected function obtenirNombreStationsDansBbox() {
26 alex 226
		$bbox = $this->criteresRecherche->bbox;
227
		$zoom = $this->criteresRecherche->zoom;
228
		$requete =
34 alex 229
			"SELECT zoom, Sum(nombre_sites) AS total_points FROM mailles_{$this->nomSource} ".
230
			"WHERE zoom=".$zoom." ".$this->construireWhereMaillesBbox()." GROUP BY zoom";
26 alex 231
		$resultat = $this->getBdd()->recuperer($requete);
232
		return $resultat['total_points'];
233
	}
234
 
34 alex 235
	final protected function recupererMaillesDansBbox() {
26 alex 236
		$bbox = $this->criteresRecherche->bbox;
237
		$zoom = $this->criteresRecherche->zoom;
238
		$requete =
34 alex 239
			"SELECT limite_sud AS sud, limite_ouest AS ouest, limite_est AS est, limite_nord AS nord, ".
240
			"nombre_sites AS stations, nombre_observations AS observations FROM mailles_{$this->nomSource} ".
241
			"WHERE zoom=".$zoom." ".$this->construireWhereMaillesBbox();
242
		$mailles = $this->getBdd()->recupererTous($requete);
31 alex 243
		// placer les totaux des nombres de stations dans des mailles vides
244
		$maillage = new Maillage($this->criteresRecherche->bbox, $zoom, $this->nomSource);
245
		$maillage->genererMaillesVides();
246
		$maillage->ajouterMailles($mailles);
247
		return $maillage->formaterSortie();
26 alex 248
	}
249
 
34 alex 250
	private function construireWhereMaillesBbox() {
251
		$bboxRecherche = $this->criteresRecherche->bbox;
252
		$conditions = array();
253
		$sql = '';
254
		foreach ($bboxRecherche as $bbox) {
255
			$conditions[] = "(limite_sud<=".$bbox['nord']." AND limite_nord>=".$bbox['sud']." ".
256
				"AND limite_ouest<=". $bbox['est']." AND limite_est>=".$bbox['ouest'].")";
257
		}
258
		if (count($conditions) > 0) {
259
			$sql = 'AND ('.implode(' OR ', $conditions).')';
260
		}
261
		return $sql;
262
	}
263
 
26 alex 264
}
265
 
266
?>