Subversion Repositories eFlore/Applications.cel

Rev

Rev 2455 | Rev 2462 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2452 aurelien 1
<?php
2461 jpm 2
// declare(encoding='UTF-8');
3
/**
4
 * Service renvoyant les observations présentent au sein d'un cercle de rayon donné.
5
 *
6
 * @internal   Mininum PHP version : 5.2
7
 * @category   CEL
8
 * @package    Services
9
 * @subpackage Bibliothèques
10
 * @version    0.1
11
 * @author     Mathias CHOUET <mathias@tela-botanica.org>
12
 * @author     Jean-Pascal MILCENT <jpm@tela-botanica.org>
13
 * @author     Aurelien PERONNET <aurelien@tela-botanica.org>
14
 * @license    GPL v3 <http://www.gnu.org/licenses/gpl.txt>
15
 * @license    CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
16
 * @copyright  1999-2014 Tela Botanica <accueil@tela-botanica.org>
17
 */
2452 aurelien 18
class CelRadiusPoints extends Cel {
2461 jpm 19
 
20
	private $champs = array('id_observation', 'nom_sel', 'latitude', 'longitude', 'COUNT(id_observation) AS nb_obs');
21
	private $champs_min = array('latitude', 'longitude');
22
 
2455 aurelien 23
	private $champs_mode = null;
2461 jpm 24
 
25
	/**
26
	 * Méthode appelée avec une requête de type GET.
27
	 */
2455 aurelien 28
	public function getRessource() {
2461 jpm 29
		$this->champs_mode = $this->champs_min;
30
		return $this->getElement(array());
2452 aurelien 31
	}
32
 
2461 jpm 33
	/**
34
	 * Méthode appelée avec une requête de type GET.
35
	 */
36
	public function getElement($params) {
2453 aurelien 37
		$lat_centre = str_replace(',', '.', round(floatval($_GET['lat']), 3));
38
		$lon_centre = str_replace(',', '.', round(floatval($_GET['lon']), 3));
2452 aurelien 39
		$radius = str_replace(',', '.', floatval($_GET['radius']/1000));
2461 jpm 40
 
2452 aurelien 41
		$retour = array();
2461 jpm 42
 
2452 aurelien 43
		$retour['points'] = $this->obtenirPointsPourCentreEtRadius($lat_centre, $lon_centre, $radius);
2461 jpm 44
		if (empty($retour['points'])) {
2452 aurelien 45
			$retour['plus_proche'] = $this->obtenirPointPlusProche($lat_centre, $lon_centre);
46
		}
2461 jpm 47
		$this->envoyerJson($retour);
2452 aurelien 48
	}
49
 
50
	public function obtenirPointsPourCentreEtRadius($lat_centre, $lon_centre, $radius) {
2461 jpm 51
		$requete = 'SELECT '.implode(', ', $this->champs_mode).' '.
52
			'FROM cel_obs '.
53
			'WHERE latitude != 0 AND longitude != 0 '.
54
			'AND '.$this->renvoyerDistanceSql($lat_centre, $lon_centre)." < $radius ".
55
			'GROUP BY latitude, longitude '.
56
			' -- '.__FILE__.':'.__LINE__;
2452 aurelien 57
		$points = Cel::db()->requeter($requete);
58
		return $points;
59
	}
2461 jpm 60
 
2454 aurelien 61
	private function renvoyerDistanceSql($lat_centre, $lon_centre) {
2461 jpm 62
		$sous_requete =
63
			"( ".
64
				"6371 * acos ( ".
65
					"cos ( radians($lat_centre) ) ".
66
					"* cos( radians( latitude ) ) ".
67
					"* cos( radians( longitude ) - radians($lon_centre) ) ".
68
					"+ sin ( radians($lat_centre) ) ".
69
					"* sin( radians( latitude ) ) ".
70
				") ".
71
			") ";
2454 aurelien 72
		return $sous_requete;
73
	}
2461 jpm 74
 
2452 aurelien 75
	public function obtenirPointPlusProche($lat_centre, $lon_centre) {
2455 aurelien 76
		// TODO: faire moins moche et plus efficace
2461 jpm 77
		$requete = 'SELECT '.
78
			implode(", ", $this->champs_mode).", ".$this->renvoyerDistanceSql($lat_centre, $lon_centre)." AS distance ".
79
			'FROM cel_obs '.
80
			'WHERE latitude != 0 AND longitude != 0 '.
81
			'GROUP BY latitude, longitude '.
82
			'ORDER BY distance '.
83
			'LIMIT 1 '.
84
			' -- '.__FILE__.':'.__LINE__;
85
		$point = Cel::db()->requeterLigne($requete);
2452 aurelien 86
		return $point;
87
	}
88
}