Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 155 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
155 jpm 1
<?php
2
// declare(encoding='UTF-8');
3
/**
4
 * Classe permettant d'obtenir le nom et le code INSEE des communes les plus proches d'un point (latitude et longitude).
5
 * La latitude et longitude doivent être exprimée par un nombre décimal.
6
 * Ce service fonctionne uniquement sur les communes des DROM-COM présentent
7
 * sur Wikipedia FR à cette adrese : http://fr.wikipedia.org/
8
 * Source des données : Wikipedia http://fr.wikipedia.org/
9
 * Paramètres du service :
10
 *  - lat : latitude
11
 *  - lon : longitude
12
 * Exemple :
13
 * http://localhost/service:eflore:0.1/wikipedia/nom-commune?lat=44.71546&lon=3.84216
14
 *
15
 * @category	php 5.2
16
 * @package		lion1906
17
 * @author		Mohcen BENMOUNAH <mohcen@tela-botanica.org>
18
 * @author		Jean-Pascal MILCENT <jpm@tela-botanica.org>
19
 * @copyright	Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
20
 * @license		http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt Licence CECILL
21
 * @license		http://www.gnu.org/licenses/gpl.html Licence GNU-GPL
22
 * @version		$Id$
23
 */
24
class NomCommune {
25
 
26
	const PATTERN_LAT = '/^[0-9]+(?:[.][0-9]+|)$/';
27
	const PATTERN_LON = '/^[-]?[0-9]+(?:[.][0-9]+|)$/';
28
	const NBRE_COMMUNE_PAR_DEFAUT = 10;
29
	const NBRE_COMMUNE_MAX = 100;
30
	const MIME_JSON = 'application/json';
31
	private $bdd = null;
32
 
33
	public function __construct(Bdd $bdd) {
34
		$this->bdd = $bdd;
35
	}
36
 
37
	public function consulter($ressources, $parametres) {
38
		$this->parametres = $parametres;
39
		$this->ressources = $ressources;
40
 
41
		$this->definirParametresParDefaut();
42
		$this->verifierParametres();
43
 
44
		$nomINSEEs = $this->trouverCommunesProches();
45
		$corps = $this->formaterResultats($nomINSEEs);
46
 
47
		$resultat = new ResultatService();
48
		$resultat->mime = self::MIME_JSON;
49
		$resultat->corps = $corps;
50
		return $resultat;
51
    }
52
 
53
    private function definirParametresParDefaut() {
54
    	if (array_key_exists('nbre', $this->parametres) === false) {
55
    		$this->parametres['nbre'] = self::NBRE_COMMUNE_PAR_DEFAUT;
56
    	}
57
    }
58
 
59
    private function verifierParametres() {
60
    	extract($this->parametres);
61
    	$messages = array();
62
    	if (! array_key_exists('lat', $this->parametres)) {
63
    		$messages[] = "Vous devez indiquer une latitude en degré décimal à l'aide du paramètres d'url : lat";
64
    	} else if (!preg_match(self::PATTERN_LAT, $lat)) {
65
    		$messages[] = "La valeur de latitude doit être un nombre décimal dont le séparateur décimal est un point. Ex. : 44 ou 43.03";
66
    	}
67
    	if (! array_key_exists('lon', $this->parametres)) {
68
    		$messages[] = "Vous devez indiquer une longitude en degré décimal à l'aide du paramètres d'url : lon";
69
    	} else if (!preg_match(self::PATTERN_LON, $lon)) {
70
    		$messages[] = "La valeur de longitude doit être un nombre décimal dont le séparateur décimal est un point. Ex. : -4.03 ou 3.256";
71
    	}
72
    	if (array_key_exists('nbre', $this->parametres)) {
73
    		if (!preg_match('/^[0-9]+$/', $nbre)) {
74
    			$messages[] = "Le nombre de commune le plus proche à retourner doit être un entier positif. Ex. : 10";
75
	    	} else if ($nbre > self::NBRE_COMMUNE_MAX) {
76
	    		$messages[] = "Le nombre de commune le plus proche à retourner doit être un entier positif inférieur à {self::NBRE_COMMUNE_MAX}. Ex. : 10";
77
	    	}
78
    	}
79
 
80
    	if (count($messages) != 0) {
81
			$message = implode('<br />', $messages);
82
			$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
83
			throw new Exception($message, $code);
84
		}
85
    }
86
 
87
    private function formaterResultats($nomINSEEs) {
88
    	$communes_trouvees = null;
89
    	if (isset($nomINSEEs) && !empty($nomINSEEs)) {
90
    		foreach ($nomINSEEs as $nomINSEE) {
91
    			$communes_trouvees[] = array('nom' => $nomINSEE['nom'], 'codeINSEE' => $nomINSEE['code_insee']);
92
    		}
93
    		if (!is_null($communes_trouvees)) {
94
    			if ($this->parametres['nbre'] == 1 && count($communes_trouvees) == 1) {
95
    				$communes_trouvees = $communes_trouvees[0];
96
    			}
97
    		} else {
98
    			$message = "Le service '".get_class($this)."' n'a trouvé aucune commune correspondant aux coordonnées : {$parametres['lat']}, {$parametres['lon']}.";
99
    			$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
100
    			throw new Exception($message, $code);
101
    		}
102
    	} else {
103
    		$message = "Le service '".get_class($this)."' n'a trouvé aucune commune dont le centroïde correspond aux coordonnées : {$parametres['lat']}, {$parametres['lon']}.";
104
    		$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
105
    		throw new Exception($message, $code);
106
    	}
107
    	return $communes_trouvees;
108
    }
109
 
110
	/**
111
	 * requête qui récupère les 20 communes les plus proches du point recherché
112
	 * La distance(AB = \sqrt{(x_B-x_A)^2 + (y_B-y_A)^2}) est calculée sans la racine
113
	 * (calcul en plus qui change pas le résultat).
114
	*/
115
    private function trouverCommunesProches() {
116
    	$lat = $this->parametres['lat'];
117
    	$lon = $this->parametres['lon'];
118
    	$requete =	"SELECT  (({$lat} - X(centroide)) * ({$lat} - X(centroide)) + ({$lon} - Y(centroide)) * ({$lon} - Y(centroide))) AS distance, ".
119
					"code_insee, nom ".
120
    				'FROM wikipedia_communes_v2011 '.
121
    				'ORDER BY distance '.
122
    				"LIMIT {$this->parametres['nbre']} ";
123
    	$resultat = $this->bdd->recupererTous($requete);
124
    	return $resultat;
125
    }
126
}
127
?>