Subversion Repositories eFlore/Applications.moissonnage

Rev

Rev 31 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

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