Subversion Repositories eFlore/Applications.cel

Rev

Rev 3857 | Blame | Compare with Previous | Last modification | View Log | RSS feed

<?php
// declare(encoding='UTF-8');
/**
 * Service renvoyant les observations présentent au sein d'un cercle de rayon donné.
 *
 * @internal   Mininum PHP version : 5.2
 * @category   CEL
 * @package    Services
 * @subpackage Cartes
 * @version    0.1
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
 * @author     Aurelien PERONNET <aurelien@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>
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
 */
class CelRadiusPoints extends Cel {

        private $champs_max = array('id_observation', 'nom_sel', 'latitude', 'longitude', 'COUNT(id_observation) AS nb_obs', 'GROUP_CONCAT(id_observation) as ids_obs');
        private $champs_min = array('latitude', 'longitude');

        private $champs_mode = null;

        /**
         * Méthode appelée avec une requête de type GET.
         */
        public function getRessource() {
                $this->champs_mode = $this->champs_min;
                return $this->getElement(array());
        }

        /**
         * Méthode appelée avec une requête de type GET.
         */
        public function getElement($params) {
                $lat_centre = str_replace(',', '.', round(floatval($_GET['lat']), 3));
                $lon_centre = str_replace(',', '.', round(floatval($_GET['lon']), 3));
                $radius = str_replace(',', '.', floatval($_GET['radius']/1000));
                
 
                if (isset($_GET['format'])) {
                        if ($_GET['format'] == 'max') {
                                $this->champs_mode = $this->champs_max;
                        } else if($_GET['format'] == 'min') {
                                $this->champs_mode = $this->champs_min;
                        }
                }

                $retour = array();

                $retour['points'] = $this->obtenirPointsPourCentreEtRadius($lat_centre, $lon_centre, $radius);
                if (empty($retour['points'])) {
                        $retour['plus_proche'] = $this->obtenirPointPlusProche($lat_centre, $lon_centre);
                }
                $this->envoyerJson($retour);
        }

        public function obtenirPointsPourCentreEtRadius($lat_centre, $lon_centre, $radius) {
                $requete = 'SELECT '.implode(', ', $this->champs_mode).' '.
                        'FROM cel_obs '.
                        'WHERE latitude != 0 AND longitude != 0 '.
                        'AND '.$this->renvoyerDistanceSql($lat_centre, $lon_centre)." < $radius ".
                        'GROUP BY latitude, longitude '.
                        ' -- '.__FILE__.':'.__LINE__;
                $points = Cel::db()->requeter($requete);
                return $points;
        }

        private function renvoyerDistanceSql($lat_centre, $lon_centre) {
                $sous_requete =
                        "( ".
                                "6371 * acos ( ".
                                        "cos ( radians($lat_centre) ) ".
                                        "* cos( radians( latitude ) ) ".
                                        "* cos( radians( longitude ) - radians($lon_centre) ) ".
                                        "+ sin ( radians($lat_centre) ) ".
                                        "* sin( radians( latitude ) ) ".
                                ") ".
                        ") ";
                return $sous_requete;
        }

        public function obtenirPointPlusProche($lat_centre, $lon_centre) {
                // TODO: faire moins moche et plus efficace
                $requete = 'SELECT '.
                        implode(", ", $this->champs_mode).", ".$this->renvoyerDistanceSql($lat_centre, $lon_centre)." AS distance ".
                        'FROM cel_obs '.
                        'WHERE latitude != 0 AND longitude != 0 '.
                        'GROUP BY latitude, longitude '.
                        'ORDER BY distance '.
                        'LIMIT 1 '.
                        ' -- '.__FILE__.':'.__LINE__;
                $point = Cel::db()->requeterLigne($requete);
                return $point;
        }
}