Subversion Repositories eFlore/Applications.moissonnage

Rev

Rev 34 | 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 celui utilise par l'application Carnet En Ligne
7
 * (http://www.tela-botanica.org/page:cel)
8
 *
9
 * On passera en parametre lors de la creation d'une instance un objet contenant la liste des criteres
10
 * qui vont restreindre le nombre de resultats a renvoyer
11
 *
12
 * Les deux operations suivantes peuvent etre utilisees dans les services :
13
 *   - recupererStations : va rechercher dans la base de donnees tous les points d'observations
14
 *     correspondant aux criteres de recherche demandes. La precision des lieux d'observation est
15
 *     soit un point precis, soit ramenee au niveau de la commune dans laquelle l'observation a ete faite
16
 *     En fonction du niveau de zoom et du nombre de resultats trouves, la presentation se fera
17
 *     soit par les points localisant les stations pour des niveaux de zoom eleves ou pour un nombre
18
 *     de stations inferieur a un seuil, ou par des mailles de 64*64 pixels dans le cas contraire
19
 *
20
 *   - recupererObservations : va rechercher dans la base de donnees les donnees sur des observations
21
 *     a partir des coordonnees longitude et latitude d'une station (+ des parametres additionnels)
22
 *
23
 * Les donnees seront renvoyees au format JSON
24
 *
34 alex 25
 * @package framework-0.4
26 alex 26
 * @author Alexandre GALIBERT <alexandre.galibert@tela-botanica.org>
27
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
28
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
29
 * @version $Id$
30
 * @copyright 2013 Tela Botanica (accueil@tela-botanica.org)
31
 *
32
 */
33
 
34
 
34 alex 35
final class FloradataFormateur extends Formateur {
26 alex 36
 
34 alex 37
	final protected function construireRequeteStations() {
38
		$condition = "(longitude IS NULL OR latitude IS NULL OR (longitude=0 AND latitude=0) ".
39
		"OR longitude>180 OR latitude>90 OR mots_cles_texte LIKE '%sensible%')";
26 alex 40
		$requete =
31 alex 41
			"SELECT COUNT(id_observation) AS observations, ce_zone_geo, zone_geo, station, ".
34 alex 42
			"IF({$condition}, wgs84_latitude, latitude) AS latitude, IF({$condition}, wgs84_longitude, longitude) ".
43
			"AS longitude, IF({$condition}, 'COMMUNE', 'STATION') AS type_site, 'floradata' AS source ".
31 alex 44
			"FROM cel_obs  LEFT JOIN cel_zones_geo cz ON ce_zone_geo=id_zone_geo ".
45
			"WHERE transmission=1 ".
26 alex 46
			$this->construireWhereDepartement().' '.
47
			$this->construireWhereAuteur().' '.
31 alex 48
			$this->construireWhereDate().' '.
26 alex 49
			$this->construireWhereReferentiel().' '.
50
			$this->construireWhereTaxon().' '.
51
			$this->construireWhereCoordonneesBbox().' '.
34 alex 52
			"GROUP BY IF({$condition},wgs84_longitude,longitude), IF({$condition},wgs84_latitude,latitude)";
26 alex 53
		return $requete;
54
	}
55
 
34 alex 56
	final protected function construireRequeteObservations() {
26 alex 57
		$requete =
34 alex 58
			"SELECT id_observation AS id_obs, nom_sel_nn AS nn, nom_referentiel, lieudit, milieu, ".
59
			"(DATE(IF(date_observation != '0000-00-00 00:00:00', date_observation, date_transmission))) AS date, ".
60
			"CONCAT(prenom_utilisateur, ' ', nom_utilisateur) AS observateur, ce_utilisateur AS observateurId, ".
61
			"IF(nom_sel IS NULL, 'A identifier',nom_sel) AS nomSci, 'floradata' AS projet ".
26 alex 62
			"FROM cel_obs WHERE transmission=1 ".
63
			$this->construireWhereAuteur().' '.
64
			$this->construireWhereReferentiel().' '.
31 alex 65
			$this->construireWhereDate().' '.
26 alex 66
			$this->construireWhereTaxon().' '.
67
			$this->construireWhereCoordonneesPoint().' '.
34 alex 68
			"ORDER BY IF(nom_sel IS NULL, 'A identifier',nom_sel), date, observateur";
26 alex 69
		return $requete;
70
	}
71
 
34 alex 72
	final protected function construireRequeteWfs() {
73
		$condition = "(longitude IS NULL OR latitude IS NULL OR (longitude=0 AND latitude=0) ".
74
			"OR longitude>180 OR latitude>90 OR mots_cles_texte LIKE '%sensible%')";
75
		$requete =
76
		"SELECT nom_sel AS taxon, ce_zone_geo, zone_geo, station, 'floradata' AS source, ".
77
		"IF({$condition}, wgs84_latitude, latitude) AS latitude, IF({$condition}, wgs84_longitude, longitude) ".
43 alex 78
		"AS longitude, IF({$condition}, 'commune', 'station') AS type_site, ".
79
		"CONCAT(prenom_utilisateur, ' ', nom_utilisateur) AS auteur ".
34 alex 80
		"FROM cel_obs  LEFT JOIN cel_zones_geo cz ON ce_zone_geo=id_zone_geo ".
81
		"WHERE transmission=1 ".
82
		$this->construireWhereCoordonneesBbox().' '.
83
		$this->construireWhereNomScientifique().' '.
84
		"ORDER BY IF({$condition},wgs84_longitude,longitude), IF({$condition},wgs84_latitude,latitude)";
85
		return $requete;
86
	}
87
 
88
	private function construireWhereTaxon() {
26 alex 89
		$sql = '';
90
		if (isset($this->criteresRecherche->taxon)) {
31 alex 91
			$taxons = $this->criteresRecherche->taxon;
92
			$criteres = array();
93
			foreach ($taxons as $taxon) {
34 alex 94
				if ($taxon['rang'] == Config::get('rang.famille')) {
31 alex 95
					$criteres[] = "famille=".$this->getBdd()->proteger($taxon['nom']);
34 alex 96
				} elseif ($taxon['rang'] == Config::get('rang.genre')) {
97
					$criteres[] = "nom_sel LIKE ".$this->getBdd()->proteger($taxon['nom']." %");
31 alex 98
				} else {
34 alex 99
					$sousTaxons = $this->concatenerSynonymesEtSousEspeces($taxon);
100
					$criteres[] = "nt IN (".implode(',', $sousTaxons).")";
31 alex 101
				}
26 alex 102
			}
31 alex 103
			$sql = "AND (".implode(' OR ',array_unique($criteres)).")";
26 alex 104
		}
105
		return $sql;
106
	}
34 alex 107
 
108
	private function concatenerSynonymesEtSousEspeces($taxon) {
31 alex 109
		$referentiel = new Referentiel($this->criteresRecherche->referentiel, $taxon);
34 alex 110
		$sousTaxons = $referentiel->recupererSynonymesEtSousEspeces();
31 alex 111
		$criteres = array();
112
		foreach ($sousTaxons as $sousTaxon) {
34 alex 113
			$criteres[] = "nt=".$sousTaxon['nt'];
31 alex 114
		}
34 alex 115
		return array_unique($criteres);
31 alex 116
	}
117
 
26 alex 118
	private function construireWhereReferentiel() {
119
		$sql = '';
120
		if (isset($this->criteresRecherche->referentiel) && !isset($this->criteresRecherche->taxon)) {
121
			$referentiel = current(explode('_', $this->criteresRecherche->referentiel));
122
			$sql = "AND nom_referentiel LIKE ".$this->getBdd()->proteger($referentiel."%");
123
		}
124
		return $sql;
125
	}
126
 
127
	private function construireWhereDepartement() {
128
		$sql = '';
129
		if (isset($this->criteresRecherche->departement)) {
130
			$valeurs_a_proteger = $this->criteresRecherche->departement;
131
			foreach ($valeurs_a_proteger as $valeur) {
132
				$valeurs_protegees[] = "ce_zone_geo LIKE " . $this->getBdd()->proteger('INSEE-C:' . $valeur . '%');
133
			}
134
			$valeurs = implode(' OR ', $valeurs_protegees);
135
			$sql = "AND ($valeurs)";
136
		}
137
		return $sql;
138
	}
139
 
140
	private function construireWhereAuteur() {
141
		$sql = '';
142
		if (isset($this->criteresRecherche->auteur)) {
143
			$utilisateur = $this->getBdd()->proteger($this->criteresRecherche->auteur);
144
			$sql = "AND courriel_utilisateur = $utilisateur";
145
		}
146
		return $sql;
147
	}
148
 
31 alex 149
	private function construireWhereDate() {
150
		$sql = '';
151
		if (isset($this->criteresRecherche->nbJours)) {
152
			$nbJours = $this->criteresRecherche->nbJours;
34 alex 153
			$sql = "AND (Datediff(Curdate(), date_transmission)<={$nbJours})";
31 alex 154
		} else {
155
			$sql = $this->construireWhereDateDebutEtFin();
156
		}
157
		return $sql;
158
	}
159
 
160
	private function construireWhereDateDebutEtFin() {
161
		$sql = '';
162
		$dateDebut = isset($this->criteresRecherche->dateDebut) ? $this->criteresRecherche->dateDebut : null;
163
		$dateFin   = isset($this->criteresRecherche->dateFin) ? $this->criteresRecherche->dateFin : null;
164
		if (!is_null($dateDebut) || !is_null($dateFin)) {
165
			$dateFin = !is_null($dateFin) ? $dateFin : date('Y-m-d');
166
			$condition = '';
167
			if ($dateDebut == $dateFin) {
34 alex 168
				$condition = "DATE(date_observation)=".$this->getBdd()->proteger($dateDebut);
31 alex 169
			} elseif (is_null($dateFin)) {
34 alex 170
				$condition = "DATE(date_observation)>=".$this->getBdd()->proteger($dateDebut);
31 alex 171
			} elseif (is_null($dateDebut)) {
34 alex 172
				$condition = "DATE(date_observation)<=".$this->getBdd()->proteger($dateFin);
31 alex 173
			} else {
34 alex 174
				$condition = "DATE(date_observation) BETWEEN ".$this->getBdd()->proteger($dateDebut)." ".
31 alex 175
						"AND ".$this->getBdd()->proteger($dateFin);
176
			}
177
			$sql = "AND ($condition)";
178
		}
179
		return $sql;
180
	}
181
 
26 alex 182
	private function construireWhereCoordonneesBbox() {
34 alex 183
		$sql = '';
184
		if (isset($this->criteresRecherche->bbox)) {
185
			$sql = "AND (".
186
				"(".$this->genererCritereWhereBbox('').") OR (".
187
					"(longitude IS NULL OR latitude IS NULL OR (longitude=0 AND latitude=0) ".
188
					"OR longitude>180 OR latitude>90 OR mots_cles_texte LIKE '%sensible%') AND ".
189
					$this->genererCritereWhereBbox('wgs84_').
26 alex 190
				")".
191
			")";
34 alex 192
		}
26 alex 193
		return $sql;
194
	}
195
 
34 alex 196
	private function genererCritereWhereBbox($suffixe) {
197
		$bboxRecherche = $this->criteresRecherche->bbox;
198
		$conditions = array();
199
		$sql = '';
200
		foreach ($bboxRecherche as $bbox) {
201
			$conditions[] = "({$suffixe}latitude BETWEEN ".$bbox['sud']." AND ".$bbox['nord']." ".
202
				"AND {$suffixe}longitude BETWEEN ".$bbox['ouest']." AND ".$bbox['est'].")";
203
		}
204
		if (count($conditions) > 0) {
205
			$sql = '('.implode(' OR ', $conditions).')';
206
		}
207
		return $sql;
208
	}
209
 
210
	private function construireWhereNomScientifique() {
211
		$sql = '';
212
		if (isset($this->criteresRecherche->filtre)) {
213
			$filtre = $this->criteresRecherche->filtre;
214
			$valeur = "'{$filtre['valeur']}".($filtre['operateur'] == 'LIKE' ? "%" : "")."'";
215
			switch ($filtre['champ']) {
216
				case "taxon" : $sql = "AND nom_sel {$filtre['operateur']} {$valeur}"; break;
217
			}
218
		}
219
		return $sql;
220
	}
221
 
26 alex 222
	private function construireWhereCoordonneesPoint() {
34 alex 223
		$sql = '';
224
		$conditions = array();
225
		foreach ($this->criteresRecherche->stations as $station) {
226
			if ($station[0] == $this->nomSource) {
227
				$longitude = str_replace(",", ".", strval($station[3]));
228
				$latitude  = str_replace(",", ".", strval($station[2]));
229
				if ($station[1] == 'station') {
230
					$conditions[] = "(longitude=".$longitude." AND latitude=".$latitude." ".
231
						"AND (mots_cles_texte IS NULL OR mots_cles_texte NOT LIKE '%sensible%'))";
232
				} else {
233
					$commune = $this->obtenirCoordonneesCommune($longitude, $latitude);
234
					$conditions[] =
235
					"(".
236
						"((longitude IS NULL OR latitude IS NULL) OR (longitude=0 AND latitude=0) ".
237
						"OR longitude>180 OR latitude>90 OR mots_cles_texte LIKE '%sensible%') ".
238
						"AND ce_zone_geo=".$this->getBdd()->proteger($commune['id_zone_geo']).
239
					")";
240
				}
241
			}
26 alex 242
		}
34 alex 243
		if (count($conditions) > 0) {
244
			$sql = "AND (".implode(" OR ", $conditions).")";
245
		}
246
		return $sql;
26 alex 247
	}
248
 
34 alex 249
	private function obtenirCoordonneesCommune($longitude, $latitude) {
250
		$requete = "SELECT id_zone_geo, nom FROM cel_zones_geo WHERE wgs84_longitude=$longitude ".
251
			"AND wgs84_latitude=$latitude";
26 alex 252
		$commune = $this->getBdd()->recuperer($requete);
253
		if ($commune === false) {
254
			$commune = null;
255
		}
256
		return $commune;
257
	}
258
 
34 alex 259
	final protected function obtenirNomsStationsSurPoint() {
26 alex 260
		// verifier si les coordonnees du point de requetage correspondent a une commune
34 alex 261
		$coordonnees = $this->recupererCoordonneesPremiereStation();
262
		$station = $this->obtenirCoordonneesCommune($coordonnees[0], $coordonnees[1]);
26 alex 263
		if (is_null($station)) {
264
			$requete = 'SELECT DISTINCT lieudit AS nom FROM cel_obs WHERE longitude='.
34 alex 265
				$coordonnees[0].' AND latitude='.$coordonnees[1];
26 alex 266
			$station = $this->getBdd()->recuperer($requete);
267
		}
268
		$nomStation = '';
269
		if ($station !== false) {
270
			$nomStation = trim($station['nom']);
271
		}
272
		return $nomStation;
273
	}
274
 
34 alex 275
	private function recupererCoordonneesPremiereStation() {
276
		$coordonnees = null;
277
		foreach ($this->criteresRecherche->stations as $station) {
278
			if ($station[0] == $this->nomSource) {
279
				$longitude = str_replace(",", ".", strval($station[3]));
280
				$latitude  = str_replace(",", ".", strval($station[2]));
281
				$coordonnees = array($longitude, $latitude);
282
			}
283
		}
284
		return $coordonnees;
285
	}
286
 
26 alex 287
}
288
 
289
?>