Subversion Repositories eFlore/Applications.moissonnage

Rev

Rev 31 | Go to most recent revision | 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, ".
68
		"lieu_station_longitude AS longitude, 'STATION' AS type_site, lieu_commune_code_insee AS code_insee, ".
69
		"'{$this->nomSource}' AS source FROM {$this->nomSource}_tapir WHERE 1 ".
70
		$this->construireWhereCoordonneesBbox().' '.
71
		$this->construireWhereNomScientifique().' '.
72
		"ORDER BY lieu_station_longitude, lieu_station_latitude";
73
		return $requete;
74
	}
75
 
76
	private function construireWhereTaxon() {
26 alex 77
		$sql = '';
78
		if (isset($this->criteresRecherche->taxon)) {
31 alex 79
			$taxons = $this->criteresRecherche->taxon;
80
			$criteres = array();
81
			foreach ($taxons as $taxon) {
82
				$criteres[] = "nom_scientifique_complet LIKE ".$this->getBdd()->proteger($taxon['nom']."%");
34 alex 83
				if ($taxon['rang'] >= Config::get('rang.espece')) {
84
					$criteres = array_merge($criteres, $this->concatenerSynonymesEtSousEspeces($taxon));
85
				} elseif ($taxon['rang'] == Config::get('rang.famille')) {
86
					$criteres = array_merge($criteres, $this->concatenerTaxonsGenres($taxon));
31 alex 87
				}
26 alex 88
			}
31 alex 89
			$sql = "AND (".implode(' OR ',array_unique($criteres)).")";
26 alex 90
		}
91
		return $sql;
92
	}
93
 
34 alex 94
	private function concatenerSynonymesEtSousEspeces($taxon) {
31 alex 95
		$referentiel = new Referentiel($this->criteresRecherche->referentiel, $taxon);
34 alex 96
		$sousTaxons = $referentiel->recupererSynonymesEtSousEspeces();
31 alex 97
		$criteres = array();
98
		foreach ($sousTaxons as $sousTaxon) {
99
			$criteres[] = "nom_scientifique_complet LIKE ".$this->getBdd()->proteger($sousTaxon['nom']."%");
100
		}
101
		return $criteres;
102
	}
103
 
34 alex 104
	private function concatenerTaxonsGenres($taxon) {
31 alex 105
		$referentiel = new Referentiel($this->criteresRecherche->referentiel, $taxon);
34 alex 106
		$sousTaxons = $referentiel->recupererGenres();
31 alex 107
		$criteres = array();
108
		foreach ($sousTaxons as $sousTaxon) {
109
			$criteres[] = "nom_scientifique_complet LIKE ".$this->getBdd()->proteger($sousTaxon['nom']."%");
110
		}
111
		return $criteres;
112
	}
113
 
34 alex 114
	private function construireWhereReferentiel() {
26 alex 115
		$sql = '';
34 alex 116
		if (isset($this->criteresRecherche->referentiel)) {
117
			$referentielSource = Config::get('referentiel_source');
118
			if (strstr($this->criteresRecherche->referentiel, $referentielSource) === false) {
119
				$sql = "AND 0";
120
			}
121
		}
26 alex 122
		return $sql;
123
	}
124
 
34 alex 125
	private function construireWhereDepartement() {
26 alex 126
		$sql = '';
31 alex 127
		if (isset($this->criteresRecherche->departement)) {
128
			$valeurs_a_proteger = $this->criteresRecherche->departement;
129
			foreach ($valeurs_a_proteger as $valeur) {
130
				$aProteger = $this->getBdd()->proteger($valeur . '%');
131
				$valeurs_protegees[] = "lieu_commune_code_insee LIKE {$aProteger}";
132
			}
133
			$valeurs = implode(' OR ', $valeurs_protegees);
134
			$sql = "AND ($valeurs)";
135
		}
26 alex 136
		return $sql;
137
	}
138
 
34 alex 139
	private function construireWhereAuteur() {
26 alex 140
		$sql = '';
141
		if (isset($this->criteresRecherche->auteur)) {
142
			$auteur = $this->getBdd()->proteger($this->criteresRecherche->auteur);
143
			$sql = "AND observateur_nom_complet = $auteur";
144
		}
145
		return $sql;
146
	}
31 alex 147
 
34 alex 148
	private function construireWhereDate() {
31 alex 149
		$sql = '';
150
		$dateDebut = isset($this->criteresRecherche->dateDebut) ? $this->criteresRecherche->dateDebut : null;
151
		$dateFin   = isset($this->criteresRecherche->dateFin) ? $this->criteresRecherche->dateFin : null;
152
		if (!is_null($dateDebut) || !is_null($dateFin)) {
153
			$dateDebut = !is_null($dateDebut) ? substr($dateDebut, 0, 4) : null;
154
			$dateFin   = !is_null($dateFin)   ? substr($dateFin, 0, 4)   : date('Y');
155
			$condition = '';
156
			if ($dateDebut == $dateFin) {
157
				$condition = "observation_date=".$dateDebut;
158
			} elseif (is_null($dateFin)) {
159
				$condition = "observation_date>=".$dateDebut;
160
			} elseif (is_null($dateDebut)) {
161
				$condition = "observation_date<=".$dateFin;
162
			} else {
163
				$condition = "observation_date BETWEEN ".$dateDebut." AND ".$dateFin;
164
			}
165
			$sql = "AND ($condition)";
166
		}
167
		return $sql;
168
	}
26 alex 169
 
34 alex 170
	private function construireWhereCoordonneesBbox() {
171
		$sql = '';
172
		if (isset($this->criteresRecherche->bbox)) {
173
			$bboxRecherche = $this->criteresRecherche->bbox;
174
			$conditions = array();
175
			foreach ($bboxRecherche as $bbox) {
176
				$conditions[] = "(lieu_station_longitude BETWEEN ".$bbox['ouest']." AND ".$bbox['est']." ".
177
					"AND lieu_station_latitude BETWEEN ".$bbox['sud']." AND ".$bbox['nord'].")";
178
			}
179
			$sql = 'AND ('.implode(' OR ', $conditions).')';
180
		}
26 alex 181
		return $sql;
182
	}
183
 
34 alex 184
	private function construireWhereNomScientifique() {
185
		$sql = '';
186
		if (isset($this->criteresRecherche->filtre)) {
187
			$filtre = $this->criteresRecherche->filtre;
188
			$valeur = "'{$filtre['valeur']}".($filtre['operateur'] == 'LIKE' ? "%" : "")."'";
189
			switch ($filtre['champ']) {
190
				case "taxon" : $sql = "AND nom_scientifique_complet {$filtre['operateur']} {$valeur}"; break;
191
			}
192
		}
26 alex 193
		return $sql;
194
	}
195
 
34 alex 196
	private function construireWhereCoordonneesPoint() {
197
		$sql = '';
198
		$conditions = array();
199
		foreach ($this->criteresRecherche->stations as $station) {
200
			if ($station[0] == $this->nomSource) {
201
				$longitude = str_replace(",", ".", strval($station[2]));
202
				$latitude  = str_replace(",", ".", strval($station[3]));
203
				$conditions[] = "(lieu_station_latitude={$longitude} AND lieu_station_longitude={$latitude})";
204
			}
205
		}
206
		if (count($conditions) > 0) {
207
			$sql = "AND (".implode(" OR ", $conditions).")";
208
		}
209
		return $sql;
210
	}
211
 
212
	final protected function obtenirNomsStationsSurPoint() {
213
		$requete = "SELECT DISTINCTROW lieu_station_nom FROM {$this->nomSource}_tapir WHERE 1 ".
26 alex 214
			$this->construireWhereTaxon().' '.
215
			$this->construireWhereCoordonneesPoint();
216
		$stations = $this->getBdd()->recupererTous($requete);
217
		$nomsStations = array();
218
		foreach ($stations as $station) {
219
			$nomsStations[] = $station['lieu_station_nom'];
220
		}
221
		return implode(', ', $nomsStations);
222
	}
223
 
34 alex 224
	final protected function obtenirNombreStationsDansBbox() {
26 alex 225
		$bbox = $this->criteresRecherche->bbox;
226
		$zoom = $this->criteresRecherche->zoom;
227
		$requete =
34 alex 228
			"SELECT zoom, Sum(nombre_sites) AS total_points FROM mailles_{$this->nomSource} ".
229
			"WHERE zoom=".$zoom." ".$this->construireWhereMaillesBbox()." GROUP BY zoom";
26 alex 230
		$resultat = $this->getBdd()->recuperer($requete);
231
		return $resultat['total_points'];
232
	}
233
 
34 alex 234
	final protected function recupererMaillesDansBbox() {
26 alex 235
		$bbox = $this->criteresRecherche->bbox;
236
		$zoom = $this->criteresRecherche->zoom;
237
		$requete =
34 alex 238
			"SELECT limite_sud AS sud, limite_ouest AS ouest, limite_est AS est, limite_nord AS nord, ".
239
			"nombre_sites AS stations, nombre_observations AS observations FROM mailles_{$this->nomSource} ".
240
			"WHERE zoom=".$zoom." ".$this->construireWhereMaillesBbox();
241
		$mailles = $this->getBdd()->recupererTous($requete);
31 alex 242
		// placer les totaux des nombres de stations dans des mailles vides
243
		$maillage = new Maillage($this->criteresRecherche->bbox, $zoom, $this->nomSource);
244
		$maillage->genererMaillesVides();
245
		$maillage->ajouterMailles($mailles);
246
		return $maillage->formaterSortie();
26 alex 247
	}
248
 
34 alex 249
	private function construireWhereMaillesBbox() {
250
		$bboxRecherche = $this->criteresRecherche->bbox;
251
		$conditions = array();
252
		$sql = '';
253
		foreach ($bboxRecherche as $bbox) {
254
			$conditions[] = "(limite_sud<=".$bbox['nord']." AND limite_nord>=".$bbox['sud']." ".
255
				"AND limite_ouest<=". $bbox['est']." AND limite_est>=".$bbox['ouest'].")";
256
		}
257
		if (count($conditions) > 0) {
258
			$sql = 'AND ('.implode(' OR ', $conditions).')';
259
		}
260
		return $sql;
261
	}
262
 
26 alex 263
}
264
 
265
?>