Subversion Repositories eFlore/Applications.cel

Rev

Rev 584 | Rev 694 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php
// declare(encoding='UTF-8');
/**
 * Service fournissant une carte dynamique des obsertions publiques du CEL.
 * Encodage en entrée : utf8
 * Encodage en sortie : utf8
 *
 * Cas d'utilisation :
 * /CelWidgetMap/Carte/Utilisateur : carte des observations publiques d'un utilisateur.
 * /CelWidgetMap/Carte/Utilisateur/Projet : carte des observations publiques d'un utilisateur pour un projet.
 * /CelWidgetMap/Carte/Utilisateur/Projet/dept : carte des observations publiques d'un utilisateur pour un projet sur un département.
 * /CelWidgetMap/Carte/Utilisateur/Projet/dept/num_taxon : carte des observations publiques d'un utilisateur pour un projet sur un département pour un taxon.
 *
 * Carte = Type de carte. Valeurs possible : defaut,
 * Utilisateur = identifiant (= courriel) de l'utilisateur ou * pour tous les utilisateurs.
 * Projet = mot-clé du projet
 *
 * @author Jean-Pascal MILCENT <jpm@clapas.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 © 2010, Jean-Pascal MILCENT
 */
// TODO : supprimer le TRIM quand les obs seront reliées correctements aux localisations (sur le code INSEE par exemple)
class CelWidgetMap extends Cel {
        
        /**
         * Méthode appelée avec une requête de type GET.
         */
        public function getElement($params) {
                $retour = null;
                $parametres = $this->traiterParametres(array('carte'), $params, false);
                extract($parametres);
                
                if (isset($carte)) {
                        $methode = $this->traiterNomMethodeGet($carte);
                        if (method_exists($this, $methode)) {
                                array_shift($params);
                                $retour = $this->$methode($params);
                        } else {
                                $this->messages[] = "Ce type de carte '$methode' n'est pas disponible.";
                        }
                } else {
                        $this->messages[] = "Vous devez indiquer le type de carte.";
                }

                if (is_null($retour)) {
                        $info = 'Un problème est survenu : '.print_r($this->messages, true);
                        $this->envoyer($info);
                } else if ($retour['type'] == 'json') {
                        $this->envoyerJson($retour['variable_js'], $retour['donnees']);
                }  else if ($retour['type'] == 'jsonp') {
                        $this->envoyerJsonp($retour['donnees']);
                } else {
                        $this->envoyer($retour, null, null, true);
                }
        }

        /**
         * Données de la carte par défaut
         */
        public function getCarteDefautJson($params) {
                $json = null;
                $parametres = $this->traiterParametres(array('utilisateur', 'projet', 'dept', 'num_taxon'), $params, false);
                extract($parametres);
                $dept = $this->traiterValeursMultiples($dept);
                
                $requete =  'SELECT sector, x_utm, y_utm '.
                    'FROM cel_inventory AS i '.
                    '   LEFT JOIN locations AS l '.
                    "       ON (l.name = i.location AND l.code = TRIM(LEADING '0' FROM i.id_location)) ".
                    "WHERE transmission = '1' ".
                    (isset($utilisateur) ? " AND identifiant = '$utilisateur' " : '' ).
                    (isset($dept) ? " AND l.code IN ($dept) " : '').
                    (isset($num_taxon) ? " AND num_taxon = '$num_taxon' " : '' ).
                    (isset($projet) ? ' AND ('.$this->getSqlWhereProjet($projet).') ' : '' );
                    $resultats = $this->executerRequete($requete);
                
                // Traitement des résultats
                $mm = null;
                $points = array();
                foreach ($resultats as $enrg) {
                        if ($enrg['x_utm'] != null && $enrg['y_utm'] != null) {
                                $convertisseur = new gPoint();
                                $convertisseur->setUTM($enrg['x_utm'], $enrg['y_utm'], $enrg['sector']);
                                $convertisseur->convertTMtoLL();
                                $enrg['coord_x'] = $convertisseur->Lat();
                                $enrg['coord_y'] = $convertisseur->Long();
                                $enrg['id'] = 'UTM:'.$enrg['x_utm'].'-'.$enrg['y_utm'].'-'.$enrg['sector'];
                                
                                $id = $enrg['coord_x'].'-'.$enrg['coord_y'];
                                if (!isset($points[$id])) {
                                        $points[$id] = $enrg;
                                        $points[$id]['nbre'] = 1;
                                } else {
                                        $points[$id]['nbre']++;
                                }
        
                                // Détermination x et y min et max
                                if (is_null($mm)) {
                                        $mm = array('min_x' => $enrg['coord_x'],
                                                'max_x' => $enrg['coord_x'],
                                                'min_y' => $enrg['coord_y'],
                                                'max_y' => $enrg['coord_y']);
                                } else {
                                        $mm['min_x'] = ($mm['min_x'] > $enrg['coord_x']) ? $enrg['coord_x'] : $mm['min_x'];
                                        $mm['min_y'] = ($mm['min_y'] > $enrg['coord_y']) ? $enrg['coord_y'] : $mm['min_y'];
                                        $mm['max_x'] = ($mm['max_x'] < $enrg['coord_x']) ? $enrg['coord_x'] : $mm['max_x'];
                                        $mm['max_y'] = ($mm['max_y'] < $enrg['coord_y']) ? $enrg['coord_y'] : $mm['max_y'];
                                }
                        }
                }
                $points = array_values($points);

                // Création des infos du widget
                $json['type'] = (isset($this->formatRetour)) ? $this->formatRetour : 'json';
                $json['variable_js'] = 'obs';
                
                $json['donnees']['points'] = $points;
                $json['donnees']['nombre'] = count($points);
                $json['donnees']['centre_x'] = $mm['min_x'].'-'.$mm['max_x'];
                $json['donnees']['centre_y'] = $mm['min_y'].'-'.$mm['max_y'];


                //echo '<pre>'.print_r($json, true).'</pre>';
                return $json;
        }
        
        /**
         * Données de la carte par défaut
         */
        public function getCartePreciseJson($params) {
                $json = null;
                $parametres = $this->traiterParametres(array('cle', 'utilisateur', 'projet', 'dept', 'num_taxon'), $params, false);
                extract($parametres);
                $dept = $this->traiterValeursMultiples($dept);
                
                // Vérification que la clé passée dans l'url est correspond à celle attendue
                if ($cle == $this->config['jrest_admin']['cleCarto']) {
                        $requete =  'SELECT sector, x_utm, y_utm, coord_x, coord_y, ref_geo '.
                            'FROM cel_inventory AS i '.
                            '   LEFT JOIN locations AS l '.
                            "       ON (l.name = i.location AND l.code = TRIM(LEADING '0' FROM i.id_location)) ".
                            "WHERE transmission = '1' ".
                            (isset($utilisateur) ? " AND identifiant = '$utilisateur' " : '' ).
                            (isset($dept) ? " AND l.code IN ($dept) " : '').
                            (isset($num_taxon) ? " AND num_taxon = '$num_taxon' " : '' ).
                            (isset($projet) ? ' AND ('.$this->getSqlWhereProjet($projet).') ' : '' );
                            $resultats = $this->executerRequete($requete);
                        
                        // Traitement des résultats
                        $mm = array('min_x' => 0,'max_x' => 0,'min_y' => 0,'max_y' => 0);
                        $points = array();
                        foreach ($resultats as $enrg) {
                                $enrg['id'] = 'LngLat:'.$enrg['coord_y'].'-'.$enrg['coord_x'];
                                if ($enrg['coord_x'] == '' && $enrg['coord_y'] == '' && $enrg['x_utm'] != '' && $enrg['y_utm'] != '') {
                                        $enrg['id'] = 'UTM:'.$enrg['x_utm'].'-'.$enrg['y_utm'].'-'.$enrg['sector'];
                                        
                                        $convertisseur = new gPoint();
                                        $convertisseur->setUTM($enrg['x_utm'], $enrg['y_utm'], $enrg['sector']);
                                        $convertisseur->convertTMtoLL();
                                        $enrg['coord_x'] = $convertisseur->Lat();
                                        $enrg['coord_y'] = $convertisseur->Long();
                                }
        
        
                                $id = $enrg['coord_x'].'-'.$enrg['coord_y'];
                                if (!isset($points[$id])) {
                                        $points[$id] = $enrg;
                                        $points[$id]['nbre'] = 1;
                                } else {
                                        $points[$id]['nbre']++;
                                }
        
                                // Détermination x et y min et max
                                $mm['min_x'] = ($mm['min_x'] > $enrg['coord_x']) ? $enrg['coord_x'] : $mm['min_x'];
                                $mm['min_y'] = ($mm['min_y'] > $enrg['coord_y']) ? $enrg['coord_y'] : $mm['min_y'];
                                $mm['max_x'] = ($mm['max_x'] < $enrg['coord_x']) ? $enrg['coord_x'] : $mm['max_x'];
                                $mm['max_y'] = ($mm['max_y'] < $enrg['coord_y']) ? $enrg['coord_y'] : $mm['max_y'];
                        }
                        $points = array_values($points);
        
                        // Création des infos du widget
                        $json['type'] = 'json';
                        $json['variable_js'] = 'obs';
                        $json['donnees']['points'] = $points;
                        $json['donnees']['nombre'] = count($points);
                        $json['donnees']['centre_x'] = $mm['min_x'].'-'.$mm['max_x'];
                        $json['donnees']['centre_y'] = $mm['min_y'].'-'.$mm['max_y'];
                }

                //echo '<pre>'.print_r($json, true).'</pre>';
                return $json;
        }
        
        /**
         * Données pour l'affichage des obs d'une station
         */
        public function getObservations($params) {
                $json = null;
                $parametres = $this->traiterParametres(array('station', 'utilisateur', 'projet', 'dept', 'num_taxon'), $params, false);
                extract($parametres);
                $dept = $this->traiterValeursMultiples($dept);
                
                // Récupération des coordonnées depuis l'id station
                //$this->debug[] = $station;
                list($type, $coord) = explode(':', $station);
                if ($type == 'UTM') {
                        list($x_utm, $y_utm, $secteur) = explode('-', $coord);
                } else if ($type == 'LngLat') {
                        list($coord_y, $coord_x) = explode('-', $coord);
                }
                
                // Récupération du filtre where pour les mots clés "projet"
                if (isset($projet)) {
                        $projet_sql = $this->getSqlWhereProjet($projet);
                }

                $requete =      'SELECT id, identifiant, nom_sel, nom_ret, num_nom_sel, num_nom_ret, num_taxon, famille, '.
                                        '       lieudit, location, date_observation, milieu, commentaire, '.
                                        '       sector, x_utm, y_utm, insee_code '.
                                        'FROM cel_inventory AS i '.
                                        '       LEFT JOIN locations AS l '.
                                        "               ON (l.name = i.location AND l.code = TRIM(LEADING '0' FROM i.id_location)) ".
                                        "WHERE transmission = '1' ".
                                        (($type == 'UTM') ? "   AND (sector = '$secteur' AND x_utm = '$x_utm' AND y_utm = '$y_utm' ) " : '').
                                        (($type == 'LngLat') ? "        AND (coord_x = '$coord_x' AND coord_y = '$coord_y' ) " : '').
                                        (isset($utilisateur) ? " AND identifiant = '$utilisateur' " : '').
                                        (isset($dept) ? " AND l.code IN ($dept) " : '').
                    (isset($num_taxon) ? " AND num_taxon = '$num_taxon' " : '' ).
                    ((isset($projet) && $projet_sql != '') ? " AND ($projet_sql) " : '' ).
                    'ORDER BY nom_sel ASC ';
                    
                //$this->debug[] = $requete;

                $resultats = $this->executerRequete($requete);
                
                // Post-traitement
                if (is_array($resultats)) {
                        $resultats = $this->nettoyerTableau($resultats);
                }
                
                return $resultats;
        }
        
        /**
         * Liste des taxons présents sur la carte
         */
        public function getTaxons($params) {
                $json = null;
                $parametres = $this->traiterParametres(array('utilisateur', 'projet', 'dept', 'num_taxon'), $params, false);
                extract($parametres);
                $dept = $this->traiterValeursMultiples($dept);
                // Récupération du filtre where pour les mots clés "projet"
                if (isset($projet)) {
                        $projet_sql = $this->getSqlWhereProjet($projet);
                }

                $requete =      'SELECT DISTINCT nom_sel, num_nom_sel, nom_ret, num_nom_ret, num_taxon, famille '.
                                        'FROM cel_inventory AS i '.
                                        '       LEFT JOIN locations AS l '.
                                        "               ON (l.name = i.location AND l.code = TRIM(LEADING '0' FROM i.id_location)) ".
                                        "WHERE transmission = '1' ".
                                        (isset($utilisateur) ? " AND identifiant = '$utilisateur' " : '').
                                        (isset($dept) ? " AND l.code IN ($dept) " : '').
                    (isset($num_taxon) ? " AND num_taxon = '$num_taxon' " : '' ).
                    ((isset($projet) && $projet_sql != '') ? " AND ($projet_sql) " : '' ).
                    'ORDER BY nom_ret ASC ';
                //$this->debug[] = $requete;

                $resultats = $this->executerRequete($requete);
                
                // Post-traitement
                if (is_array($resultats)) {
                        $resultats = $this->nettoyerTableau($resultats);
                }
                
                return $resultats;
        }
        
        /**
         * Traitement de $projet pour construction du filtre dans la requête
         */
        private function getSqlWhereProjet($projet) {
                $mot_cle_encode = $this->bdd->quote($this->encoderMotCle($projet));
                
                // Construction de la requête
                $requete =      'SELECT * '.
                                        'FROM cel_mots_cles_obs '.
                                        "WHERE cmc_id_mot_cle_general = $mot_cle_encode ";
                $elements_projet = $this->executerRequete($requete);
                
                $requete_projet = array();
                if ($elements_projet != false && count($elements_projet) > 0) {
                        // Pré-construction du where de la requête
                        $tpl_where = '(mots_cles LIKE "%%%s%%" AND identifiant = %s )';
                        
                        foreach ($elements_projet as $occurence) {
                                $requete_projet[] = sprintf($tpl_where, $occurence['cmc_id_mot_cle_utilisateur'], $this->bdd->quote($occurence['cmc_id_proprietaire']));
                        }
                } else {
                        $this->messages[] = "Aucune observation ne correspond à ce mot clé.";
                }
                
                $sql = implode(" \nOR ", $requete_projet);
                return $sql;
        }       
}