Subversion Repositories eFlore/Applications.cel

Rev

Rev 3857 | 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
2462 jpm 9
 * @subpackage Cartes
2461 jpm 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
 
2535 aurelien 20
	private $champs_max = array('id_observation', 'nom_sel', 'latitude', 'longitude', 'COUNT(id_observation) AS nb_obs', 'GROUP_CONCAT(id_observation) as ids_obs');
2461 jpm 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));
2535 aurelien 40
 
41
 
42
		if (isset($_GET['format'])) {
43
			if ($_GET['format'] == 'max') {
44
				$this->champs_mode = $this->champs_max;
45
			} else if($_GET['format'] == 'min') {
46
				$this->champs_mode = $this->champs_min;
47
			}
48
		}
2461 jpm 49
 
2452 aurelien 50
		$retour = array();
2461 jpm 51
 
2452 aurelien 52
		$retour['points'] = $this->obtenirPointsPourCentreEtRadius($lat_centre, $lon_centre, $radius);
2461 jpm 53
		if (empty($retour['points'])) {
2452 aurelien 54
			$retour['plus_proche'] = $this->obtenirPointPlusProche($lat_centre, $lon_centre);
55
		}
2461 jpm 56
		$this->envoyerJson($retour);
2452 aurelien 57
	}
58
 
59
	public function obtenirPointsPourCentreEtRadius($lat_centre, $lon_centre, $radius) {
2461 jpm 60
		$requete = 'SELECT '.implode(', ', $this->champs_mode).' '.
61
			'FROM cel_obs '.
62
			'WHERE latitude != 0 AND longitude != 0 '.
63
			'AND '.$this->renvoyerDistanceSql($lat_centre, $lon_centre)." < $radius ".
64
			'GROUP BY latitude, longitude '.
65
			' -- '.__FILE__.':'.__LINE__;
2452 aurelien 66
		$points = Cel::db()->requeter($requete);
67
		return $points;
68
	}
2461 jpm 69
 
2454 aurelien 70
	private function renvoyerDistanceSql($lat_centre, $lon_centre) {
2461 jpm 71
		$sous_requete =
72
			"( ".
73
				"6371 * acos ( ".
74
					"cos ( radians($lat_centre) ) ".
75
					"* cos( radians( latitude ) ) ".
76
					"* cos( radians( longitude ) - radians($lon_centre) ) ".
77
					"+ sin ( radians($lat_centre) ) ".
78
					"* sin( radians( latitude ) ) ".
79
				") ".
80
			") ";
2454 aurelien 81
		return $sous_requete;
82
	}
2461 jpm 83
 
2452 aurelien 84
	public function obtenirPointPlusProche($lat_centre, $lon_centre) {
2455 aurelien 85
		// TODO: faire moins moche et plus efficace
2461 jpm 86
		$requete = 'SELECT '.
87
			implode(", ", $this->champs_mode).", ".$this->renvoyerDistanceSql($lat_centre, $lon_centre)." AS distance ".
88
			'FROM cel_obs '.
89
			'WHERE latitude != 0 AND longitude != 0 '.
90
			'GROUP BY latitude, longitude '.
91
			'ORDER BY distance '.
92
			'LIMIT 1 '.
93
			' -- '.__FILE__.':'.__LINE__;
94
		$point = Cel::db()->requeterLigne($requete);
2452 aurelien 95
		return $point;
96
	}
97
}