Rev 26 | Rev 34 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/**** Classe en charge de recuperer les donnees d'observation ou liees a leur localisation* Le jeu de donnees a interroger est celui utilise par l'application Carnet En Ligne* (http://www.tela-botanica.org/page:cel)** On passera en parametre lors de la creation d'une instance un objet contenant la liste des criteres* qui vont restreindre le nombre de resultats a renvoyer** Les deux operations suivantes peuvent etre utilisees dans les services :* - recupererStations : va rechercher dans la base de donnees tous les points d'observations* correspondant aux criteres de recherche demandes. La precision des lieux d'observation est* soit un point precis, soit ramenee au niveau de la commune dans laquelle l'observation a ete faite* En fonction du niveau de zoom et du nombre de resultats trouves, la presentation se fera* soit par les points localisant les stations pour des niveaux de zoom eleves ou pour un nombre* de stations inferieur a un seuil, ou par des mailles de 64*64 pixels dans le cas contraire** - recupererObservations : va rechercher dans la base de donnees les donnees sur des observations* a partir des coordonnees longitude et latitude d'une station (+ des parametres additionnels)** Les donnees seront renvoyees au format JSON** @package framework-0.3* @author Alexandre GALIBERT <alexandre.galibert@tela-botanica.org>* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>* @version $Id$* @copyright 2013 Tela Botanica (accueil@tela-botanica.org)**/class FloradataFormateur {private $criteresRecherche;private $bdd;public function __construct($criteresRecherche) {$this->criteresRecherche = $criteresRecherche;}public function recupererStations() {$requeteSql = $this->construireRequeteStations();$stations = $this->getBdd()->recupererTous($requeteSql);$zoomMaxMaillage = Config::get('zoom_maximal_maillage');$seuilMaillage = Config::get('seuil_maillage');$zoom = $this->criteresRecherche->zoom;$bbox = $this->criteresRecherche->bbox;// TODO: gérer une notion d'échelle plutot que de zoom (pour les clients SIG)if (count($stations) > $seuilMaillage && intval($zoom)<= $zoomMaxMaillage) {$maillage = new Maillage($bbox, $zoom);$maillage->genererMaillesVides();$maillage->ajouterPoints($stations);$stations = $maillage->formaterSortie();}$formateurJSON = new FormateurJson('floradata');$donneesFormatees = $formateurJSON->formaterStations($stations);return $donneesFormatees;}public function recupererObservations() {$requeteSql = $this->construireRequeteObservations();$observations = $this->getBdd()->recupererTous($requeteSql);$nomSite = $this->obtenirNomStation();$formateurJSON = new FormateurJson('floradata');$donneesFormatees = $formateurJSON->formaterObservations($observations, $nomSite);return $donneesFormatees;}// ------------------------------------------------------------------------ //// Fonctions de construction des criteres de recherches pour la requete SQL //// ------------------------------------------------------------------------ //private function getBdd() {if (!isset($this->bdd)) {$this->bdd = new Bdd();}$this->bdd->requeter("USE ".Config::get('bdd_nom'));return $this->bdd;}private function construireRequeteStations() {$bbox = $this->criteresRecherche->bbox;$selectTypeSite ="IF("."(longitude IS NULL OR latitude IS NULL) "."OR (longitude=0 AND latitude=0) "."OR (mots_cles_texte LIKE '%sensible%') "."OR NOT ("."longitude BETWEEN ".$bbox['ouest']." AND ".$bbox['est']." "."AND latitude BETWEEN ".$bbox['sud']." AND ".$bbox['nord'].")".", 'COMMUNE', 'STATION'".")";$requete ="SELECT COUNT(id_observation) AS observations, ce_zone_geo, zone_geo, station, "."longitude, latitude, nom AS nom_commune,wgs84_longitude AS lng_commune, "."wgs84_latitude AS lat_commune, ".$selectTypeSite." AS type_site "."FROM cel_obs LEFT JOIN cel_zones_geo cz ON ce_zone_geo=id_zone_geo "."WHERE transmission=1 ".$this->construireWhereDepartement().' '.$this->construireWhereAuteur().' '.$this->construireWhereDate().' '.$this->construireWhereReferentiel().' '.$this->construireWhereTaxon().' '.$this->construireWhereCoordonneesBbox().' '."GROUP BY longitude, latitude, wgs84_longitude, wgs84_latitude";return $requete;}private function construireRequeteObservations() {$requete ="SELECT id_observation AS id_obs, nom_ret_nn AS nn, nom_ret AS nomSci, "."Date(date_observation) AS date, milieu AS lieu, nom_referentiel, "."Concat(prenom_utilisateur, ' ', nom_utilisateur) AS observateur, ce_utilisateur AS observateurId "."FROM cel_obs WHERE transmission=1 ".$this->construireWhereAuteur().' '.$this->construireWhereReferentiel().' '.$this->construireWhereDate().' '.$this->construireWhereTaxon().' '.$this->construireWhereCoordonneesPoint().' '."ORDER BY nom_ret, date, observateur";return $requete;}protected function construireWhereTaxon() {$sql = '';if (isset($this->criteresRecherche->taxon)) {$taxons = $this->criteresRecherche->taxon;$criteres = array();foreach ($taxons as $taxon) {$nomRang = $this->getNomRang($taxon);if ($nomRang == 'genre') {$criteres[] = "famille=".$this->getBdd()->proteger($taxon['nom']);} else {$criteres[] = "nom_ret LIKE ".$this->getBdd()->proteger($taxon['nom']."%");if ($nomRang == 'espece') {$criteres = array_merge($criteres, $this->concatenerTaxonsSousEspeces($taxon));}}}$sql = "AND (".implode(' OR ',array_unique($criteres)).")";}return $sql;}protected function getNomRang($taxon) {$nomsRangs = array('famille', 'genre', 'espece', 'sous_espece');for ($index = 0; $index < count($nomsRangs)&& Config::get("rang.".$nomsRangs[$index]) != $taxon['rang']; $index ++);$position = $index == count($nomsRangs) ? count($nomsRangs)-1 : $index;return $nomsRangs[$position];}protected function concatenerTaxonsSousEspeces($taxon) {$referentiel = new Referentiel($this->criteresRecherche->referentiel, $taxon);$sousTaxons = $referentiel->recupererTaxonsSousEspeces();$criteres = array();foreach ($sousTaxons as $sousTaxon) {$criteres[] = "nom_ret LIKE ".$this->getBdd()->proteger($sousTaxon['nom']."%");}return $criteres;}protected function concatenerTaxonsFamilles($taxon) {$referentiel = new Referentiel($this->criteresRecherche->referentiel, $taxon);$sousTaxons = $referentiel->recupererTaxonsFamilles();$criteres = array();foreach ($sousTaxons as $sousTaxon) {$criteres[] = "nom_ret LIKE ".$this->getBdd()->proteger($sousTaxon['nom']."%");}return $criteres;}private function construireWhereReferentiel() {$sql = '';if (isset($this->criteresRecherche->referentiel) && !isset($this->criteresRecherche->taxon)) {$referentiel = current(explode('_', $this->criteresRecherche->referentiel));$sql = "AND nom_referentiel LIKE ".$this->getBdd()->proteger($referentiel."%");}return $sql;}private function construireWhereDepartement() {$sql = '';if (isset($this->criteresRecherche->departement)) {$valeurs_a_proteger = $this->criteresRecherche->departement;foreach ($valeurs_a_proteger as $valeur) {$valeurs_protegees[] = "ce_zone_geo LIKE " . $this->getBdd()->proteger('INSEE-C:' . $valeur . '%');}$valeurs = implode(' OR ', $valeurs_protegees);$sql = "AND ($valeurs)";}return $sql;}private function construireWhereAuteur() {$sql = '';if (isset($this->criteresRecherche->auteur)) {$utilisateur = $this->getBdd()->proteger($this->criteresRecherche->auteur);$sql = "AND courriel_utilisateur = $utilisateur";}return $sql;}private function construireWhereDate() {$sql = '';if (isset($this->criteresRecherche->nbJours)) {$nbJours = $this->criteresRecherche->nbJours;$sql = "AND (Datediff(Curdate(), date_creation)<={$nbJours})";} else {$sql = $this->construireWhereDateDebutEtFin();}return $sql;}private function construireWhereDateDebutEtFin() {$sql = '';$dateDebut = isset($this->criteresRecherche->dateDebut) ? $this->criteresRecherche->dateDebut : null;$dateFin = isset($this->criteresRecherche->dateFin) ? $this->criteresRecherche->dateFin : null;if (!is_null($dateDebut) || !is_null($dateFin)) {$dateFin = !is_null($dateFin) ? $dateFin : date('Y-m-d');$condition = '';if ($dateDebut == $dateFin) {$condition = "Date(date_observation)=".$this->getBdd()->proteger($dateDebut);} elseif (is_null($dateFin)) {$condition = "Date(date_observation)>=".$this->getBdd()->proteger($dateDebut);} elseif (is_null($dateDebut)) {$condition = "Date(date_observation)<=".$this->getBdd()->proteger($dateFin);} else {$condition = "Date(date_observation) BETWEEN ".$this->getBdd()->proteger($dateDebut)." "."AND ".$this->getBdd()->proteger($dateFin);}$sql = "AND ($condition)";}return $sql;}private function construireWhereCoordonneesBbox() {$bbox = $this->criteresRecherche->bbox;$sql ="AND ("."("."latitude BETWEEN ".$bbox['sud']." AND ".$bbox['nord']." "."AND longitude BETWEEN ".$bbox['ouest']." AND ".$bbox['est'].") OR ("."((longitude IS NULL OR latitude IS NULL) OR (longitude=0 AND latitude=0) "."OR (longitude>180 AND latitude>90)) AND "."wgs84_longitude BETWEEN ".$bbox['ouest']." AND ". $bbox['est']." "."AND wgs84_latitude BETWEEN ".$bbox['sud']." AND ".$bbox['nord'].")".")";return $sql;}private function construireWhereCoordonneesPoint() {$longitude = $this->criteresRecherche->longitude;$latitude = $this->criteresRecherche->latitude;$condition = "(longitude=".$longitude." AND latitude=".$latitude." "."AND (mots_cles_texte IS NULL OR mots_cles_texte NOT LIKE '%sensible%'))";if ($this->criteresRecherche->typeSite == 'commune') {$commune = $this->obtenirCoordonneesCommune();$condition .=" OR ("."((longitude IS NULL OR latitude IS NULL) OR (longitude=0 AND latitude=0) "."OR (longitude>180 AND latitude>90)) "."AND ce_zone_geo=".$this->getBdd()->proteger($commune['id_zone_geo']).")";}return "AND ($condition)";}private function obtenirCoordonneesCommune() {$requete = "SELECT id_zone_geo, nom FROM cel_zones_geo WHERE wgs84_longitude=".$this->criteresRecherche->longitude." AND wgs84_latitude=".$this->criteresRecherche->latitude;$commune = $this->getBdd()->recuperer($requete);if ($commune === false) {$commune = null;}return $commune;}private function obtenirNomStation() {// verifier si les coordonnees du point de requetage correspondent a une commune$station = $this->obtenirCoordonneesCommune();if (is_null($station)) {$requete = 'SELECT DISTINCT lieudit AS nom FROM cel_obs WHERE longitude='.$this->criteresRecherche->longitude.' AND latitude='.$this->criteresRecherche->latitude;$station = $this->getBdd()->recuperer($requete);}$nomStation = '';if ($station !== false) {$nomStation = trim($station['nom']);}return $nomStation;}}?>