Subversion Repositories eFlore/Applications.moissonnage

Rev

Rev 31 | Rev 43 | 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) ".
78
		"AS longitude, IF({$condition}, 'COMMUNE', 'STATION') AS type_site ".
79
		"FROM cel_obs  LEFT JOIN cel_zones_geo cz ON ce_zone_geo=id_zone_geo ".
80
		"WHERE transmission=1 ".
81
		$this->construireWhereCoordonneesBbox().' '.
82
		$this->construireWhereNomScientifique().' '.
83
		"ORDER BY IF({$condition},wgs84_longitude,longitude), IF({$condition},wgs84_latitude,latitude)";
84
		return $requete;
85
	}
86
 
87
	private function construireWhereTaxon() {
26 alex 88
		$sql = '';
89
		if (isset($this->criteresRecherche->taxon)) {
31 alex 90
			$taxons = $this->criteresRecherche->taxon;
91
			$criteres = array();
92
			foreach ($taxons as $taxon) {
34 alex 93
				if ($taxon['rang'] == Config::get('rang.famille')) {
31 alex 94
					$criteres[] = "famille=".$this->getBdd()->proteger($taxon['nom']);
34 alex 95
				} elseif ($taxon['rang'] == Config::get('rang.genre')) {
96
					$criteres[] = "nom_sel LIKE ".$this->getBdd()->proteger($taxon['nom']." %");
31 alex 97
				} else {
34 alex 98
					$sousTaxons = $this->concatenerSynonymesEtSousEspeces($taxon);
99
					$criteres[] = "nt IN (".implode(',', $sousTaxons).")";
31 alex 100
				}
26 alex 101
			}
31 alex 102
			$sql = "AND (".implode(' OR ',array_unique($criteres)).")";
26 alex 103
		}
104
		return $sql;
105
	}
34 alex 106
 
107
	private function concatenerSynonymesEtSousEspeces($taxon) {
31 alex 108
		$referentiel = new Referentiel($this->criteresRecherche->referentiel, $taxon);
34 alex 109
		$sousTaxons = $referentiel->recupererSynonymesEtSousEspeces();
31 alex 110
		$criteres = array();
111
		foreach ($sousTaxons as $sousTaxon) {
34 alex 112
			$criteres[] = "nt=".$sousTaxon['nt'];
31 alex 113
		}
34 alex 114
		return array_unique($criteres);
31 alex 115
	}
116
 
26 alex 117
	private function construireWhereReferentiel() {
118
		$sql = '';
119
		if (isset($this->criteresRecherche->referentiel) && !isset($this->criteresRecherche->taxon)) {
120
			$referentiel = current(explode('_', $this->criteresRecherche->referentiel));
121
			$sql = "AND nom_referentiel LIKE ".$this->getBdd()->proteger($referentiel."%");
122
		}
123
		return $sql;
124
	}
125
 
126
	private function construireWhereDepartement() {
127
		$sql = '';
128
		if (isset($this->criteresRecherche->departement)) {
129
			$valeurs_a_proteger = $this->criteresRecherche->departement;
130
			foreach ($valeurs_a_proteger as $valeur) {
131
				$valeurs_protegees[] = "ce_zone_geo LIKE " . $this->getBdd()->proteger('INSEE-C:' . $valeur . '%');
132
			}
133
			$valeurs = implode(' OR ', $valeurs_protegees);
134
			$sql = "AND ($valeurs)";
135
		}
136
		return $sql;
137
	}
138
 
139
	private function construireWhereAuteur() {
140
		$sql = '';
141
		if (isset($this->criteresRecherche->auteur)) {
142
			$utilisateur = $this->getBdd()->proteger($this->criteresRecherche->auteur);
143
			$sql = "AND courriel_utilisateur = $utilisateur";
144
		}
145
		return $sql;
146
	}
147
 
31 alex 148
	private function construireWhereDate() {
149
		$sql = '';
150
		if (isset($this->criteresRecherche->nbJours)) {
151
			$nbJours = $this->criteresRecherche->nbJours;
34 alex 152
			$sql = "AND (Datediff(Curdate(), date_transmission)<={$nbJours})";
31 alex 153
		} else {
154
			$sql = $this->construireWhereDateDebutEtFin();
155
		}
156
		return $sql;
157
	}
158
 
159
	private function construireWhereDateDebutEtFin() {
160
		$sql = '';
161
		$dateDebut = isset($this->criteresRecherche->dateDebut) ? $this->criteresRecherche->dateDebut : null;
162
		$dateFin   = isset($this->criteresRecherche->dateFin) ? $this->criteresRecherche->dateFin : null;
163
		if (!is_null($dateDebut) || !is_null($dateFin)) {
164
			$dateFin = !is_null($dateFin) ? $dateFin : date('Y-m-d');
165
			$condition = '';
166
			if ($dateDebut == $dateFin) {
34 alex 167
				$condition = "DATE(date_observation)=".$this->getBdd()->proteger($dateDebut);
31 alex 168
			} elseif (is_null($dateFin)) {
34 alex 169
				$condition = "DATE(date_observation)>=".$this->getBdd()->proteger($dateDebut);
31 alex 170
			} elseif (is_null($dateDebut)) {
34 alex 171
				$condition = "DATE(date_observation)<=".$this->getBdd()->proteger($dateFin);
31 alex 172
			} else {
34 alex 173
				$condition = "DATE(date_observation) BETWEEN ".$this->getBdd()->proteger($dateDebut)." ".
31 alex 174
						"AND ".$this->getBdd()->proteger($dateFin);
175
			}
176
			$sql = "AND ($condition)";
177
		}
178
		return $sql;
179
	}
180
 
26 alex 181
	private function construireWhereCoordonneesBbox() {
34 alex 182
		$sql = '';
183
		if (isset($this->criteresRecherche->bbox)) {
184
			$sql = "AND (".
185
				"(".$this->genererCritereWhereBbox('').") OR (".
186
					"(longitude IS NULL OR latitude IS NULL OR (longitude=0 AND latitude=0) ".
187
					"OR longitude>180 OR latitude>90 OR mots_cles_texte LIKE '%sensible%') AND ".
188
					$this->genererCritereWhereBbox('wgs84_').
26 alex 189
				")".
190
			")";
34 alex 191
		}
26 alex 192
		return $sql;
193
	}
194
 
34 alex 195
	private function genererCritereWhereBbox($suffixe) {
196
		$bboxRecherche = $this->criteresRecherche->bbox;
197
		$conditions = array();
198
		$sql = '';
199
		foreach ($bboxRecherche as $bbox) {
200
			$conditions[] = "({$suffixe}latitude BETWEEN ".$bbox['sud']." AND ".$bbox['nord']." ".
201
				"AND {$suffixe}longitude BETWEEN ".$bbox['ouest']." AND ".$bbox['est'].")";
202
		}
203
		if (count($conditions) > 0) {
204
			$sql = '('.implode(' OR ', $conditions).')';
205
		}
206
		return $sql;
207
	}
208
 
209
	private function construireWhereNomScientifique() {
210
		$sql = '';
211
		if (isset($this->criteresRecherche->filtre)) {
212
			$filtre = $this->criteresRecherche->filtre;
213
			$valeur = "'{$filtre['valeur']}".($filtre['operateur'] == 'LIKE' ? "%" : "")."'";
214
			switch ($filtre['champ']) {
215
				case "taxon" : $sql = "AND nom_sel {$filtre['operateur']} {$valeur}"; break;
216
			}
217
		}
218
		return $sql;
219
	}
220
 
26 alex 221
	private function construireWhereCoordonneesPoint() {
34 alex 222
		$sql = '';
223
		$conditions = array();
224
		foreach ($this->criteresRecherche->stations as $station) {
225
			if ($station[0] == $this->nomSource) {
226
				$longitude = str_replace(",", ".", strval($station[3]));
227
				$latitude  = str_replace(",", ".", strval($station[2]));
228
				if ($station[1] == 'station') {
229
					$conditions[] = "(longitude=".$longitude." AND latitude=".$latitude." ".
230
						"AND (mots_cles_texte IS NULL OR mots_cles_texte NOT LIKE '%sensible%'))";
231
				} else {
232
					$commune = $this->obtenirCoordonneesCommune($longitude, $latitude);
233
					$conditions[] =
234
					"(".
235
						"((longitude IS NULL OR latitude IS NULL) OR (longitude=0 AND latitude=0) ".
236
						"OR longitude>180 OR latitude>90 OR mots_cles_texte LIKE '%sensible%') ".
237
						"AND ce_zone_geo=".$this->getBdd()->proteger($commune['id_zone_geo']).
238
					")";
239
				}
240
			}
26 alex 241
		}
34 alex 242
		if (count($conditions) > 0) {
243
			$sql = "AND (".implode(" OR ", $conditions).")";
244
		}
245
		return $sql;
26 alex 246
	}
247
 
34 alex 248
	private function obtenirCoordonneesCommune($longitude, $latitude) {
249
		$requete = "SELECT id_zone_geo, nom FROM cel_zones_geo WHERE wgs84_longitude=$longitude ".
250
			"AND wgs84_latitude=$latitude";
26 alex 251
		$commune = $this->getBdd()->recuperer($requete);
252
		if ($commune === false) {
253
			$commune = null;
254
		}
255
		return $commune;
256
	}
257
 
34 alex 258
	final protected function obtenirNomsStationsSurPoint() {
26 alex 259
		// verifier si les coordonnees du point de requetage correspondent a une commune
34 alex 260
		$coordonnees = $this->recupererCoordonneesPremiereStation();
261
		$station = $this->obtenirCoordonneesCommune($coordonnees[0], $coordonnees[1]);
26 alex 262
		if (is_null($station)) {
263
			$requete = 'SELECT DISTINCT lieudit AS nom FROM cel_obs WHERE longitude='.
34 alex 264
				$coordonnees[0].' AND latitude='.$coordonnees[1];
26 alex 265
			$station = $this->getBdd()->recuperer($requete);
266
		}
267
		$nomStation = '';
268
		if ($station !== false) {
269
			$nomStation = trim($station['nom']);
270
		}
271
		return $nomStation;
272
	}
273
 
34 alex 274
	private function recupererCoordonneesPremiereStation() {
275
		$coordonnees = null;
276
		foreach ($this->criteresRecherche->stations as $station) {
277
			if ($station[0] == $this->nomSource) {
278
				$longitude = str_replace(",", ".", strval($station[3]));
279
				$latitude  = str_replace(",", ".", strval($station[2]));
280
				$coordonnees = array($longitude, $latitude);
281
			}
282
		}
283
		return $coordonnees;
284
	}
285
 
26 alex 286
}
287
 
288
?>