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;
}
}