* @author Jean-Pascal MILCENT * @author Aurelien PERONNET * @license GPL v3 * @license CECILL v2 * @copyright 1999-2014 Tela Botanica */ 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; } }