Subversion Repositories eFlore/Applications.moissonnage

Rev

Blame | Last modification | View Log | RSS feed

<?php

/**
 * Recuperer les stations ou se sont realisees des observations effectuees
 * par les utilisateurs du Carnet En Ligne (http://tela-botanica.org/page:cel
 * 
 * @author Alexandre GALIBERT
 * @copyright 2013 Tela Botanica (accueil@tela-botanica.org)
 *
 */



class Stations {
        
        private $zoom = null;
        private $bbox = null;
        
        private $utilisateur = '';
        private $departement = '';
        private $taxon = null;
        private $referentiel = '';
        private $sousTaxons = array();
        
        private $bdd;
        
        
        public function __construct() {}
        
        public function consulter($ressources, $parametres) {
                extract($parametres);
                $zoomMaxMaillage = Config::get('zoom_maximal_maillage');
                $seuilMaillage   = Config::get('seuil_maillage');
                $this->utilisateur = $utilisateur != '*' ? $utilisateur : '';
                $this->departement = $dept != '*' ? $dept : '';
                
                // recuperation, traitement de tous les parametres et vertification du zoom
                // et des coordonnees des limites de l'espace de recherche (parametre bbox)
                $statutParametresEspace = $this->traiterParametresEspace($parametres);
                if ($statutParametresEspace == false) {
                        $message = "Recherche des stations impossible : parametres de l'espace de recherche incorrects";
                        return new Exception($message, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
                }
         
                // recherche du taxon dans les referentiels bdtfx et bdtxa et verification de sa validite
                if ($referentiel != '*') {
                        $this->referentiel = $this->verifierExistenceReferentiel($referentiel);
                        if (is_null($this->referentiel)) {
                                $message = "Recherche des stations impossible : referentiel inconnu\n"
                                        + "Voici les referentiels disponibles : "
                                        + implode(', ', Referentiel::listeReferentielsDisponibles());
                                return new Exception($message, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
                        }
                }
                
                if ($num_taxon != '*') {
                        $this->traiterParametresTaxon($num_taxon);
                        if (is_null($this->taxon)) {
                                $message = "Recherche des stations impossible : taxon non trouve dans les referentiels";
                                return new Exception($message, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);
                        }
                        // recuperer les sous-taxons
                        $referentiel = new Referentiel($this->referentiel);
                        $this->sousTaxons = $referentiel->recupererSousTaxons();
                }
                        
                // recuperer les informations sur les stations repondant a ces parametres
                $stations = $this->recupererStations();
                if (count($stations) > $seuilMaillage && intval($this->zoom)<= $zoomMaxMaillage) {
                        // partitionnement des donnees en mailles
                        $maillage = new Maillage($this->bbox, $this->zoom);
                        $maillage->genererMaillesVides();
                        $maillage->ajouterPoints($stations);
                        $stations = $maillage->resumePourReponseAJAX();
                }
                
                // mettre en forme les informations au format JSON
                $formateurJSON = new FormateurJson();
                $donneesFormatees = $formateurJSON->formaterStations($stations);
                return $donneesFormatees;
        }
        
        
        
        //-------------------------------------------------------------------------------
        //    Recuperation et verification des parametres
        //-------------------------------------------------------------------------------
        
        private function traiterParametresEspace($parametres) {
                $this->zoom = $this->verifierZoom($parametres['zoom']);
                $this->bbox = $this->verifierCoordonneesBbox($parametres['bbox']);
                return (!is_null($this->zoom) && !is_null($this->bbox));
        }
        
        private function traiterParametresTaxon($numeroTaxon) {
                if ($numeroTaxon != '*') {
                        if ($this->referentiel != '') {
                                $referentiel = new Referentiel($this->referentiel);
                                $this->taxon = $referentiel->recupererTaxon($numeroTaxon);
                        } else {
                                $this->taxon = $this->verifierExistenceTaxon($numeroTaxon);
                        }
                }
        }
        
        private function verifierZoom($niveauZoom) {
                $zoom = intval($niveauZoom);
                $limitesZoom = array(
                        'min' => intval(Config::get('carte.zoom_minimal')),
                        'max' => intval(Config::get('carte.zoom_maximal'))
                );
                if ($zoom < $limitesZoom['min'] || $zoom > $limitesZoom['max']) {
                        return null;
                }
                return $zoom;
        }
        
        private function verifierCoordonneesBbox($limitesBbox) {
                $coordonnees = explode(',', $limitesBbox);
                if (count($coordonnees) != 4) {
                        return null;
                }
                
                // index du tableau des coordonnees : ouest/sud/est/nord
                $nomsIndexBbox = array("ouest", "sud", "est", "nord");
                $bbox = array();
                for ($i = 0; $i < count($coordonnees); $i ++) {
                        $bbox[$nomsIndexBbox[$i]] = $coordonnees[$i];
                }
                
                // verifier que les coordonnees de chaque bord de la bbox sont valides
                $limites = array(
                        'ouest' => floatval(Config::get('carte.limite_ouest')),
                        'est'   => floatval(Config::get('carte.limite_est')),
                        'sud'   => floatval(Config::get('carte.limite_sud')),
                        'nord'  => floatval(Config::get('carte.limite_nord'))
                );

                if (floatval($bbox['ouest']) >= $limites['ouest']  && floatval($bbox['ouest']) <= $limites['est']
                        && floatval($bbox['est']) >= $limites['ouest'] && floatval($bbox['est']) <= $limites['est']
                        && floatval($bbox['nord']) >= $limites['sud']  && floatval($bbox['nord']) <= $limites['nord']
                        && floatval($bbox['sud']) >= $limites['sud']   && floatval($bbox['sud']) <= $limites['nord']) {
                        return $bbox;
                }
                return null;
        }
        
        private function verifierExistenceReferentiel($referentiel) {
                if ($referentiel == '*') {
                        return '';
                }
                $listeReferentiels = Referentiel::listeReferentielsDisponibles();
                foreach ($listeReferentiels as $nomReferentiel) {
                        if (strstr($nomReferentiel, $referentiel) !== false) {
                                $this->referentiel = $nomReferentiel;
                                break;
                        }
                }
                return null;
        }
        
        private function verifierExistenceTaxon($numTaxon) {
                $listeReferentiels = Referentiel::listeReferentielsDisponibles();
                // tester chaque referentiel jusqu'a trouver un taxon correspondant
                // a tous les criteres demandes dans les masques
                foreach ($listeReferentiels as $nomReferentiel) {
                        $referentiel = new Referentiel($nomReferentiel);
                        $taxon = $referentiel->recupererTaxon($numTaxon);
                        if (!is_null($taxon)) {
                                $this->referentiel = $nomReferentiel;
                                return $taxon;
                        }
                }
                return null;
        }
                
        
        
        //-------------------------------------------------------------------------------
        //    Recuperation des donnees dans la base de donnees
        //    et mise sous forme d'objet geographique en fonction du niveau de zoom
        //-------------------------------------------------------------------------------
        
        private function recupererStations() {
                $this->getBdd()->requeter("USE tb_cel");
                $selectTypeSite = "If((longitude IS NULL AND latitude IS NULL) OR (longitude=0 AND latitude=0)"
                        . " OR (longitude=999.99999 AND latitude=999.99999), 'COMMUNE', 'STATION')";
                $requete = 'SELECT 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->construireWhereUtilisateur()
                        . $this->construireWhereTaxon() . $this->construireWhereCoordonnees()
                        . " GROUP BY longitude, latitude, wgs84_longitude, wgs84_latitude";
                return $this->getBdd()->recupererTous($requete);
                /*
                
                // requete n°1 : recuperer dans la base cel les informations sur les stations
                // dans l'espace de recherche dont la precision de la localisation est au niveau de la commune
                $requete = 'SELECT id_zone_geo AS "ce_zone_geo", nom AS "zone_geo", \'\' AS "nom",'
                        . ' wgs84_latitude AS "latitude", wgs84_longitude AS "longitude", \'COMMUNE\' AS "type_site"'
                        . ' FROM cel_zones_geo WHERE 1 ' . $this->construireWhereDepartement('id')
                        . $this->construireWhereCoordonnees('wgs84_') . ' AND id_zone_geo IN('
                        . 'SELECT ce_zone_geo FROM cel_obs WHERE transmission=1' . $this->construireWhereTaxon()  . ')';
                $stations = $this->getBdd()->recupererTous($requete);
                // requete 2 : recuperer la liste des stations ayant des observations publiques
                // dans l'espace de recherche dont la precision de la localisation est au lieu-dit
                $requete = 'SELECT ce_zone_geo, zone_geo, station AS "nom", latitude, longitude, \'STATION\''
                        . ' AS "type_site" FROM cel_obs WHERE transmission=1' 
                        . $this->construireWhereTaxon() . $this->construireWhereCoordonnees()
                        . $this->construireWhereDepartement('ce') . ' GROUP BY longitude, latitude';
                return array_merge($stations, $this->getBdd()->recupererTous($requete));*/
        }
        
        private function getBdd() {
                if (!isset($this->bdd)) {
                        $this->bdd = new Bdd();
                }
                return $this->bdd;
        }
        
        private function construireWhereTaxon() {
                $sql = '';
                if (!is_null($this->taxon)) {
                        $criteres = "nom_ret LIKE '" . addslashes($this->taxon['nom']) . "%'";
                        foreach ($this->sousTaxons as $sousTaxon) {
                                $criteres .= " OR nom_ret LIKE '" . addslashes($sousTaxon['nom']) . "%'";
                        }
                        $sql = " AND ($criteres)";
                }
                return $sql;
        }
        
        private function construireWhereDepartement() {
                $sql = '';
                if (strlen(trim($this->departement)) > 0) {
                        $valeurs_a_proteger = explode(',',trim($this->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 construireWhereUtilisateur() {
                $sql = '';
                if ($this->utilisateur != '') {
                        $utilisateur = $this->getBdd()->proteger($this->utilisateur);
                        $sql = " AND courriel_utilisateur = $utilisateur ";
                }
                return $sql;
        }

        private function construireWhereCoordonnees() {
                $sql = " AND ((longitude BETWEEN " . $this->bbox['ouest'] . " AND " . $this->bbox['est']
                        . " AND latitude BETWEEN " . $this->bbox['sud'] . " AND " . $this->bbox['nord']
                        . " AND wgs84_longitude IS NULL AND wgs84_latitude IS NULL) OR (wgs84_longitude BETWEEN "
                        . $this->bbox['ouest'] . " AND " . $this->bbox['est'] . " AND wgs84_latitude BETWEEN "
                        . $this->bbox['sud'] . " AND " . $this->bbox['nord'] . "))";
                /*$sql = " AND {$suffixeChamp}latitude BETWEEN " . $this->bbox['sud'] . " AND "
                        . $this->bbox['nord'] . " AND ";
                if ($this->bbox['ouest'] > $this->bbox['est']) {
                        $sql .= "({$suffixeChamp}longitude >= " . $this->bbox['ouest']
                                . " OR {$suffixeChamp}longitude <= " . $this->bbox['est'] . ")";
                } else {
                        $sql .= "{$suffixeChamp}longitude BETWEEN " . $this->bbox['ouest'] . " AND "
                                . $this->bbox['est'];
                }*/
                return $sql;
        }
        
}

?>