Subversion Repositories eFlore/Applications.moissonnage

Rev

Rev 31 | Go to most recent revision | Details | 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
 *
25
 * @package framework-0.3
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
 
35
class FloradataFormateur {
36
 
37
	private $criteresRecherche;
38
	private $bdd;
39
 
40
 
41
	public function __construct($criteresRecherche) {
42
		$this->criteresRecherche = $criteresRecherche;
43
	}
44
 
45
	public function recupererStations() {
46
		// recuperer les informations au niveau de la base de donnees
47
		$requeteSql = $this->construireRequeteStations();
48
		$stations = $this->getBdd()->recupererTous($requeteSql);
49
 
50
		$zoomMaxMaillage = Config::get('zoom_maximal_maillage');
51
		$seuilMaillage   = Config::get('seuil_maillage');
52
		$zoom = $this->criteresRecherche->zoom;
53
		$bbox = $this->criteresRecherche->bbox;
54
		// TODO: gérer une notion d'échelle plutot que de zoom (pour les clients SIG)
55
		if (count($stations) > $seuilMaillage && intval($zoom)<= $zoomMaxMaillage) {
56
			// partitionnement des donnees en mailles
57
			$maillage = new Maillage($bbox, $zoom);
58
			$maillage->genererMaillesVides();
59
			$maillage->ajouterPoints($stations);
60
			$stations = $maillage->formaterSortie();
61
		}
62
 
63
		// mettre en forme les informations au format JSON
64
		$formateurJSON = new FormateurJson('floradata');
65
		$donneesFormatees = $formateurJSON->formaterStations($stations);
66
		return $donneesFormatees;
67
	}
68
 
69
	public function recupererObservations() {
70
		// recuperer les informations sur les stations repondant a ces parametres
71
		$requeteSql = $this->construireRequeteObservations();
72
		$observations = $this->getBdd()->recupererTous($requeteSql);
73
		$nomSite = $this->obtenirNomStation();
74
 
75
		// mettre en forme les informations au format JSON
76
		$formateurJSON = new FormateurJson('floradata');
77
		$donneesFormatees = $formateurJSON->formaterObservations($observations, $nomSite);
78
		return $donneesFormatees;
79
	}
80
 
81
 
82
 
83
	// ------------------------------------------------------------------------ //
84
	// Fonctions de construction des criteres de recherches pour la requete SQL //
85
	// ------------------------------------------------------------------------ //
86
 
87
	private function getBdd() {
88
		if (!isset($this->bdd)) {
89
			$this->bdd = new Bdd();
90
		}
91
		$this->bdd->requeter("USE ".Config::get('bdd_nom'));
92
		return $this->bdd;
93
	}
94
 
95
	private function construireRequeteStations() {
96
		$selectTypeSite =
97
			"IF(".
98
				"(longitude IS NULL OR latitude IS NULL) ".
99
				"OR (longitude=0 AND latitude=0) ".
100
				"OR (longitude=999.99999 AND latitude=999.99999)".
101
				", 'COMMUNE', 'STATION'".
102
			")";
103
		$requete =
104
			'SELECT ce_zone_geo, zone_geo, station, longitude, latitude, nom AS "nom_commune",'.
105
			'wgs84_longitude AS "lng_commune", wgs84_latitude AS "lat_commune", '.
106
			$selectTypeSite.' AS "type_site" '.
107
			'FROM cel_obs  LEFT JOIN cel_zones_geo cz ON ce_zone_geo=id_zone_geo '.
108
			'WHERE transmission=1 '.
109
			$this->construireWhereDepartement().' '.
110
			$this->construireWhereAuteur().' '.
111
			$this->construireWhereReferentiel().' '.
112
			$this->construireWhereTaxon().' '.
113
			$this->construireWhereCoordonneesBbox().' '.
114
			"GROUP BY longitude, latitude, wgs84_longitude, wgs84_latitude";
115
		return $requete;
116
	}
117
 
118
	private function construireRequeteObservations() {
119
		$requete =
120
			"SELECT id_observation AS id_obs, nom_ret_nn AS nn, nom_ret AS nomSci, ".
121
			"Date(date_transmission)  AS date, milieu AS lieu, nom_referentiel, ".
122
			"Concat(prenom_utilisateur, ' ', nom_utilisateur) AS observateur, ce_utilisateur AS observateurId ".
123
			"FROM cel_obs WHERE transmission=1 ".
124
			$this->construireWhereAuteur().' '.
125
			$this->construireWhereReferentiel().' '.
126
			$this->construireWhereTaxon().' '.
127
			$this->construireWhereCoordonneesPoint().' '.
128
			"ORDER BY nom_ret, date, observateur";
129
		return $requete;
130
	}
131
 
132
	private function construireWhereTaxon() {
133
		$sql = '';
134
		if (isset($this->criteresRecherche->taxon)) {
135
			$taxon = $this->criteresRecherche->taxon;
136
			$criteres = "nom_ret LIKE ".$this->getBdd()->proteger($taxon['nom']."%");
137
 
138
			$referentiel = new Referentiel($this->criteresRecherche->referentiel, $this->criteresRecherche->taxon);
139
			$sousTaxons = $referentiel->recupererSousTaxons();
140
			foreach ($sousTaxons as $sousTaxon) {
141
				$criteres .= " OR nom_ret LIKE ".$this->getBdd()->proteger($taxon['nom']."%");
142
			}
143
			$sql = "AND ($criteres)";
144
		}
145
		return $sql;
146
	}
147
 
148
	private function construireWhereReferentiel() {
149
		$sql = '';
150
		if (isset($this->criteresRecherche->referentiel) && !isset($this->criteresRecherche->taxon)) {
151
			$referentiel = current(explode('_', $this->criteresRecherche->referentiel));
152
			$sql = "AND nom_referentiel LIKE ".$this->getBdd()->proteger($referentiel."%");
153
		}
154
		return $sql;
155
	}
156
 
157
	private function construireWhereDepartement() {
158
		$sql = '';
159
		if (isset($this->criteresRecherche->departement)) {
160
			$valeurs_a_proteger = $this->criteresRecherche->departement;
161
			foreach ($valeurs_a_proteger as $valeur) {
162
				$valeurs_protegees[] = "ce_zone_geo LIKE " . $this->getBdd()->proteger('INSEE-C:' . $valeur . '%');
163
			}
164
			$valeurs = implode(' OR ', $valeurs_protegees);
165
			$sql = "AND ($valeurs)";
166
		}
167
		return $sql;
168
	}
169
 
170
	private function construireWhereAuteur() {
171
		$sql = '';
172
		if (isset($this->criteresRecherche->auteur)) {
173
			$utilisateur = $this->getBdd()->proteger($this->criteresRecherche->auteur);
174
			$sql = "AND courriel_utilisateur = $utilisateur";
175
		}
176
		return $sql;
177
	}
178
 
179
	private function construireWhereCoordonneesBbox() {
180
		$bbox = $this->criteresRecherche->bbox;
181
		$sql =
182
			"AND (".
183
				"(".
184
					"longitude BETWEEN ".$bbox['ouest']." AND ".$bbox['est']." ".
185
					"AND latitude BETWEEN ".$bbox['sud']." AND ".$bbox['nord']." ".
186
					"AND (wgs84_longitude IS NULL OR wgs84_latitude IS NULL)".
187
				") OR (".
188
					"wgs84_longitude BETWEEN ".$bbox['ouest']." AND ". $bbox['est']." ".
189
					"AND wgs84_latitude BETWEEN ".$bbox['sud']." AND ".$bbox['nord'].
190
				")".
191
			")";
192
		return $sql;
193
	}
194
 
195
	private function construireWhereCoordonneesPoint() {
196
		$commune = 	$this->obtenirCoordonneesCommune();
197
		$condition = "(longitude=".$this->criteresRecherche->longitude." ".
198
			"AND latitude=".$this->criteresRecherche->latitude.")";
199
		if (!is_null($commune)) {
200
			$condition .= " OR (longitude IS NULL AND latitude IS NULL AND ce_zone_geo=".
201
				$this->getBdd()->proteger($commune['id_zone_geo']).")";
202
		}
203
		return "AND ($condition)";
204
	}
205
 
206
	private function obtenirCoordonneesCommune() {
207
		$requete = "SELECT id_zone_geo, nom FROM cel_zones_geo WHERE wgs84_longitude=".
208
		$this->criteresRecherche->longitude." AND wgs84_latitude=".$this->criteresRecherche->latitude;
209
		$commune = $this->getBdd()->recuperer($requete);
210
		if ($commune === false) {
211
			$commune = null;
212
		}
213
		return $commune;
214
	}
215
 
216
	private function obtenirNomStation() {
217
		// verifier si les coordonnees du point de requetage correspondent a une commune
218
		$station = $this->obtenirCoordonneesCommune();
219
		if (is_null($station)) {
220
			$requete = 'SELECT DISTINCT lieudit AS nom FROM cel_obs WHERE longitude='.
221
				$this->criteresRecherche->longitude.' AND latitude='.$this->criteresRecherche->latitude;
222
			$station = $this->getBdd()->recuperer($requete);
223
		}
224
		$nomStation = '';
225
		if ($station !== false) {
226
			$nomStation = trim($station['nom']);
227
		}
228
		return $nomStation;
229
	}
230
 
231
}
232
 
233
?>