Blame | 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 partage en commun avec l'application EFlore** 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 SophyFormateur {private $criteresRecherche;private $bdd;public function __construct($criteresRecherche) {$this->criteresRecherche = $criteresRecherche;}public function recupererStations() {$stations = array();$nombreStations = $this->obtenirNombreStationsDansBbox();$seuilMaillage = Config::get('seuil_maillage');$nombreParametresNonSpatiaux = $this->calculerNombreCriteresNonSpatiaux();if ($nombreStations >= $seuilMaillage && $nombreParametresNonSpatiaux == 0) {// pas besoin de rechercher les stations correspondant a ces criteres// recuperer les mailles se trouvant dans l'espace de recherche demande$stations = $this->recupererMaillesDansBbox();} else {$requeteSql = $this->construireRequeteStations();$stations = $this->getBdd()->recupererTous($requeteSql);$zoom = $this->criteresRecherche->zoom;$zoomMaxMaillage = Config::get('zoom_maximal_maillage');if ($zoom <= $zoomMaxMaillage && count($stations) >= $seuilMaillage) {// generer un maillage a partir des stations recuperees dans la base de donnees$maillage = new Maillage($this->criteresRecherche->bbox, $zoom, 'sophy');$maillage->genererMaillesVides();$maillage->ajouterPoints($stations);$stations = $maillage->formaterSortie();}}// mettre en forme les informations au format JSON$formateurJSON = new FormateurJson('sophy');$donneesFormatees = $formateurJSON->formaterStations($stations);return $donneesFormatees;}public function recupererObservations() {$requeteSql = $this->construireRequeteObservations();$observations = $this->getBdd()->recupererTous($requeteSql);$this->recupererNumeroNomenclaturauxTaxons($observations);$nomStation = $this->obtenirNomsStationsSurPoint();$formateurJSON = new FormateurJson('sophy');$donneesFormatees = $formateurJSON->formaterObservations($observations, $nomStation);return $donneesFormatees;}private function calculerNombreCriteresNonSpatiaux() {$nombreParametresNonSpatiaux = 0;$criteresSpatiaux = array('zoom', 'bbox', 'longitude', 'latitude');foreach ($this->criteresRecherche as $nomCritere => $valeur) {if (!in_array($nomCritere, $criteresSpatiaux)) {$nombreParametresNonSpatiaux ++;}}return $nombreParametresNonSpatiaux;}// ------------------------------------------------------------------------ //// 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() {$requete ="SELECT DISTINCT lieu_station_nom AS nom, lieu_station_latitude AS latitude, "."lieu_station_longitude AS longitude, 'STATION' AS type_site "."FROM sophy_tapir WHERE 1 ".$this->construireWhereDepartement().' '.$this->construireWhereAuteur().' '.$this->construireWhereReferentiel().' '.$this->construireWhereTaxon().' '.$this->construireWhereCoordonneesBbox().' '."GROUP BY lieu_station_latitude, lieu_station_longitude";return $requete;}private function construireRequeteObservations() {$requete ="SELECT observation_id AS id_obs, nom_scientifique_complet AS nomSci, "."observation_date AS date, lieu_station_nom AS lieu, observateur_nom_complet AS observateur "."FROM sophy_tapir WHERE 1 ".$this->construireWhereAuteur().' '.$this->construireWhereReferentiel().' '.$this->construireWhereTaxon().' '.$this->construireWhereCoordonneesPoint().' '."ORDER BY nom_scientifique_complet, date, observateur";return $requete;}private function construireWhereTaxon() {$sql = '';if (isset($this->criteresRecherche->taxon)) {$taxon = $this->criteresRecherche->taxon;$criteres = "nom_scientifique_complet LIKE ".$this->getBdd()->proteger($taxon['nom']."%");$referentiel = new Referentiel($this->criteresRecherche->referentiel, $this->criteresRecherche->taxon);$sousTaxons = $referentiel->recupererSousTaxons();foreach ($sousTaxons as $sousTaxon) {$criteres .= " OR nom_scientifique_complet LIKE ".$this->getBdd()->proteger($taxon['nom']."%");}$sql = "AND ($criteres)";}return $sql;}// TODO : completer le corps des methodes construire where pour referentiel et departementprivate function construireWhereReferentiel() {$sql = '';return $sql;}private function construireWhereDepartement() {$sql = '';return $sql;}private function construireWhereAuteur() {$sql = '';if (isset($this->criteresRecherche->auteur)) {$auteur = $this->getBdd()->proteger($this->criteresRecherche->auteur);$sql = "AND observateur_nom_complet = $auteur";}return $sql;}private function construireWhereCoordonneesBbox() {$bbox = $this->criteresRecherche->bbox;$sql = "AND lieu_station_longitude BETWEEN ".$bbox['ouest']." AND ".$bbox['est']." "."AND lieu_station_latitude BETWEEN ".$bbox['sud']." AND ".$bbox['nord'];return $sql;}private function construireWhereCoordonneesPoint() {$sql = "AND lieu_station_latitude=".$this->criteresRecherche->latitude." "."AND lieu_station_longitude=".$this->criteresRecherche->longitude;return $sql;}private function obtenirNomsStationsSurPoint() {$requete = "SELECT DISTINCTROW lieu_station_nom FROM sophy_tapir WHERE 1 ".$this->construireWhereTaxon().' '.$this->construireWhereCoordonneesPoint();$stations = $this->getBdd()->recupererTous($requete);$nomsStations = array();foreach ($stations as $station) {$nomsStations[] = $station['lieu_station_nom'];}return implode(', ', $nomsStations);}private function obtenirNombreStationsDansBbox() {$bbox = $this->criteresRecherche->bbox;$zoom = $this->criteresRecherche->zoom;$requete ="SELECT zoom, Sum(nombre_sites) AS total_points FROM mailles_sophy "."WHERE zoom=".$zoom." AND limite_sud<=".$bbox['nord']." AND limite_nord>=".$bbox['sud']." "."AND limite_ouest<=".$bbox['est']." AND limite_est>=".$bbox['ouest']." GROUP BY zoom";$resultat = $this->getBdd()->recuperer($requete);return $resultat['total_points'];}private function recupererMaillesDansBbox() {$bbox = $this->criteresRecherche->bbox;$zoom = $this->criteresRecherche->zoom;$requete ="SELECT zoom, position_latitude, position_longitude, limite_sud AS sud, limite_ouest AS ouest, "."limite_nord AS nord, limite_est AS est, nombre_sites AS points, 'MAILLE' AS type_site "."FROM mailles_sophy WHERE zoom=".$zoom." AND limite_sud<=".$bbox['nord']." "."AND limite_nord>=".$bbox['sud']." AND limite_ouest<=". $bbox['est']." "."AND limite_est>=".$bbox['ouest'];return $this->getBdd()->recupererTous($requete);}private function recupererNumeroNomenclaturauxTaxons(& $observations) {for ($index = 0; $index < count($observations); $index ++) {$taxon = isset($this->criteresRecherche->taxon) ? $this->criteresRecherche->taxon : null;if (is_null($taxon) && strlen(trim($observations[$index]['nomSci'])) > 0) {if (isset($this->criteresRecherche->taxon)) {$taxon = $this->rechercherTaxonDansReferentiel($observations[$index]['nomSci'],$this->criteresRecherche->referentiel);} else {$taxon = $this->obtenirNumeroTaxon($observations[$index]['nomSci']);}}if (!is_null($taxon)) {$observations[$index]['nn'] = $taxon['nn'];$observations[$index]['num_referentiel'] = $taxon['referentiel'];} else {$observations[$index]['nn'] = '';}}}private function rechercherTaxonDansReferentiel($nomScientifique, $nomReferentiel) {$referentiel = new Referentiel($nomReferentiel);$taxon = $referentiel->obtenirNumeroNomenclatural($nomScientifique);return $taxon;}private function obtenirNumeroTaxon($nomScientifique) {$taxonTrouve = null;$listeReferentiels = Referentiel::recupererListeReferentielsDisponibles();foreach ($listeReferentiels as $nomReferentiel) {$taxon = $this->rechercherTaxonDansReferentiel($nomScientifique, $nomReferentiel);if (!is_null($taxon)) {$taxonTrouve = $taxon;break;}}return $taxonTrouve;}}?>