Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 1079 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1079 Rev 1121
Line 1... Line 1...
1
<?php
1
<?php
2
 
-
 
3
/**
2
/**
4
 * Classe unique du web service nasa-srtm qui détermine l'altitude d'un point à partir de ses coordonnees
3
 * Classe unique du web service nasa-srtm qui détermine l'altitude d'un point à partir de ses coordonnees
5
 * Les coordonnees sont definies dans des fichiers au format HGT dans un dossier specifique
4
 * Les coordonnees sont definies dans des fichiers au format HGT dans un dossier specifique
6
 * (dont le chemin est defini dans le fichier de configuration propre au web service).
5
 * (dont le chemin est defini dans le fichier de configuration propre au web service).
7
 * Les ressources utilisees sont les donnees issues du programme SRTM-3 de la NASA qui couvre
6
 * Les ressources utilisees sont les donnees issues du programme SRTM-3 de la NASA qui couvre
Line 9... Line 8...
9
 * Chaque fichier couvre un secteur de 1 degre sur 1 degre et contient un tableau de 1201 lignes
8
 * Chaque fichier couvre un secteur de 1 degre sur 1 degre et contient un tableau de 1201 lignes
10
 * (axe des latitudes) sur 1201 colonnes (axe des longitudes) contenant l'altitude en metres
9
 * (axe des latitudes) sur 1201 colonnes (axe des longitudes) contenant l'altitude en metres
11
 * correspondant a des point precis. L'ecart entre chaque entree des tableaux est constant, ce qui
10
 * correspondant a des point precis. L'ecart entre chaque entree des tableaux est constant, ce qui
12
 * permet de calculer la latitude et la longitude de chaque point. L'altitude du point le plus proche
11
 * permet de calculer la latitude et la longitude de chaque point. L'altitude du point le plus proche
13
 * de celui passe en parametres sera renvoyee au client.
12
 * de celui passe en parametres sera renvoyee au client.
14
 * 
13
 *
15
 * Parametres du web service :
14
 * Parametres du web service :
16
 *   - latitude : latitude du point dont on recherche les coordonnees
15
 *   - latitude : latitude du point dont on recherche les coordonnees
17
 *   - longitude : longitude du point dont on recherche les coordonnees
16
 *   - longitude : longitude du point dont on recherche les coordonnees
18
 * 
17
 *
19
 * @package framework-0.4
18
 * @package framework-0.4
20
 * @author Alexandre GALIBERT <alexandre.galibert@tela-botanica.org>
19
 * @author Alexandre GALIBERT <alexandre.galibert@tela-botanica.org>
21
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
20
 * @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>
22
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
21
 * @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>
23
 * @version $Id$
22
 * @version $Id$
24
 * @copyright 2013 Tela Botanica (accueil@tela-botanica.org)
23
 * @copyright 2013 Tela Botanica (accueil@tela-botanica.org)
25
 *
24
 *
26
 */
25
 */
27
 
-
 
28
 
-
 
29
class Altitude {
26
class Altitude {
30
	
27
 
31
	private $parametres = array();
28
	private $parametres = array();
32
	private $ressources = array();
29
	private $ressources = array();
33
	private $coordonnees = null;
30
	private $coordonnees = null;
34
	private $fichierSrtm = '';
31
	private $fichierSrtm = '';
35
	
32
 
36
	const LONGUEUR_COTE = 1201;
33
	const LONGUEUR_COTE = 1201;
37
	const OFFSET = 2;
34
	const OFFSET = 2;
38
	
35
 
39
	
36
 
40
	public function consulter($ressources, $parametres) {
37
	public function consulter($ressources, $parametres) {
41
		$this->ressources = $ressources;
38
		$this->ressources = $ressources;
42
		$this->parametres = $parametres;
39
		$this->parametres = $parametres;
43
		$retour = null;
40
		$retour = null;
44
		try {
41
		try {
Line 49... Line 46...
49
		} catch (Exception $erreur) {
46
		} catch (Exception $erreur) {
50
			$retour = $erreur->getMessage();
47
			$retour = $erreur->getMessage();
51
		}
48
		}
52
		return $retour;
49
		return $retour;
53
	}
50
	}
54
	
51
 
55
	private function traiterCoordonnees() {
52
	private function traiterCoordonnees() {
56
		if ($this->estParametreExistant('lat') && $this->estParametreExistant('lon')) {
53
		if ($this->estParametreExistant('lat') && $this->estParametreExistant('lon')) {
57
			$longitude = $this->parametres['lon'];
54
			$longitude = $this->parametres['lon'];
58
			$latitude  = $this->parametres['lat'];
55
			$latitude  = $this->parametres['lat'];
59
			if ($this->estUnFloat($longitude) && $this->estUnFloat($latitude)) {
56
			if ($this->estUnFloat($longitude) && $this->estUnFloat($latitude)) {
Line 67... Line 64...
67
			$message = "Tous les paramètres passés dans l'URL ne correspondent pas à ceux attendus. ".
64
			$message = "Tous les paramètres passés dans l'URL ne correspondent pas à ceux attendus. ".
68
			"Le web service nécessite de lui fournir une longitude et une latitude pour son bon fonctionnement.";
65
			"Le web service nécessite de lui fournir une longitude et une latitude pour son bon fonctionnement.";
69
			throw new Exception($message, RestServeur::HTTP_CODE_CONTENU_REQUIS);
66
			throw new Exception($message, RestServeur::HTTP_CODE_CONTENU_REQUIS);
70
		}
67
		}
71
	}
68
	}
72
	
69
 
73
	private function estParametreExistant($nomParametre) {
70
	private function estParametreExistant($nomParametre) {
74
		return in_array($nomParametre, array_keys($this->parametres));
71
		return in_array($nomParametre, array_keys($this->parametres));
75
	}
72
	}
76
	
73
 
77
	private function estUnFloat($variable) {
74
	private function estUnFloat($variable) {
78
		return (preg_match("/^(-)?\d+(\.\d+)?$/", $variable) == 1);
75
		return (preg_match("/^(-)?\d+(\.\d+)?$/", $variable) == 1);
79
	}
76
	}
80
	
77
 
81
	private function verifierValiditeCoordonnees($longitude, $latitude) {
78
	private function verifierValiditeCoordonnees($longitude, $latitude) {
82
		$longitude = floatval($longitude);
79
		$longitude = floatval($longitude);
83
		$latitude  = floatval($latitude);
80
		$latitude  = floatval($latitude);
84
		$longitudeMax = Config::get("limite_longitude");
81
		$longitudeMax = Config::get("limite_longitude");
85
		$latitudeMax  = Config::get("limite_latitude");
82
		$latitudeMax  = Config::get("limite_latitude");
Line 93... Line 90...
93
			$this->coordonnees = new StdClass();
90
			$this->coordonnees = new StdClass();
94
			$this->coordonnees->longitude = $longitude;
91
			$this->coordonnees->longitude = $longitude;
95
			$this->coordonnees->latitude  = $latitude;
92
			$this->coordonnees->latitude  = $latitude;
96
		}
93
		}
97
	}
94
	}
98
	
95
 
99
	private function rechercherFichierSrtm() {
96
	private function rechercherFichierSrtm() {
100
		$nomFichierSrtm = $this->construireNomFichierSrtm();
97
		$nomFichierSrtm = $this->construireNomFichierSrtm();
101
		if (!file_exists($nomFichierSrtm)) {
98
		if (!file_exists($nomFichierSrtm)) {
102
			$message = "Erreur interne : certaines ressources demandées n'ont pas pu être trouvées sur le serveur.";
99
			$message = "Erreur interne : la ressource « $nomFichierSrtm » demandée n'a pas pu être trouvée sur le serveur.";
103
			throw new Exception($message, restServeur::HTTP_CODE_ERREUR);
100
			throw new Exception($message, restServeur::HTTP_CODE_ERREUR);
104
		} else {
101
		} else {
105
			$this->fichierSrtm = $nomFichierSrtm;
102
			$this->fichierSrtm = $nomFichierSrtm;
106
		}
103
		}
107
	}
104
	}
108
	
105
 
109
	private function construireNomFichierSrtm() {
106
	private function construireNomFichierSrtm() {
110
		$latitudeEntier = abs(floor($this->coordonnees->latitude));
107
		$latitudeEntier = abs(floor($this->coordonnees->latitude));
111
		if ($latitudeEntier < 10) {
108
		if ($latitudeEntier < 10) {
112
			$latitudeEntier = "0".$latitudeEntier;
109
			$latitudeEntier = "0".$latitudeEntier;
113
		}
110
		}
Line 121... Line 118...
121
		$suffixeLongitude = $this->coordonnees->longitude < 0 ? "W" : "E";
118
		$suffixeLongitude = $this->coordonnees->longitude < 0 ? "W" : "E";
122
		$dossierSrtm = Config::get('dossier_srtm').DS;
119
		$dossierSrtm = Config::get('dossier_srtm').DS;
123
		$nomFichierSrtm = $dossierSrtm.$suffixeLatitude.$latitudeEntier.$suffixeLongitude.$longitudeEntier.".hgt.zip";
120
		$nomFichierSrtm = $dossierSrtm.$suffixeLatitude.$latitudeEntier.$suffixeLongitude.$longitudeEntier.".hgt.zip";
124
		return $nomFichierSrtm;
121
		return $nomFichierSrtm;
125
	}
122
	}
126
	
123
 
127
	private function recupererAltitude() {
124
	private function recupererAltitude() {
128
		$zip = zip_open($this->fichierSrtm);
125
		$zip = zip_open($this->fichierSrtm);
129
		$fichier = zip_read($zip);
126
		$fichier = zip_read($zip);
130
		$donnees = zip_entry_read($fichier, zip_entry_filesize($fichier));
127
		$donnees = zip_entry_read($fichier, zip_entry_filesize($fichier));
131
		zip_close($zip);
128
		zip_close($zip);
132
				
129
 
133
		$xDepart = floor($this->coordonnees->longitude);
130
		$xDepart = floor($this->coordonnees->longitude);
134
		$yDepart = floor($this->coordonnees->latitude);
131
		$yDepart = floor($this->coordonnees->latitude);
135
		$longitude = $this->coordonnees->longitude;
132
		$longitude = $this->coordonnees->longitude;
136
		$latitude = $this->coordonnees->latitude;
133
		$latitude = $this->coordonnees->latitude;
137
		$positionX = (self::LONGUEUR_COTE-1) * ($longitude - $xDepart);
134
		$positionX = (self::LONGUEUR_COTE-1) * ($longitude - $xDepart);
138
		$positionY = (self::LONGUEUR_COTE-1) * (1 - $latitude + $yDepart);
135
		$positionY = (self::LONGUEUR_COTE-1) * (1 - $latitude + $yDepart);
139
		$positionX = ($positionX + 0.5 > ceil($positionX)) ? ceil($positionX) : floor($positionX);
136
		$positionX = ($positionX + 0.5 > ceil($positionX)) ? ceil($positionX) : floor($positionX);
140
		$positionY = ($positionY + 0.5 > ceil($positionY)) ? ceil($positionY) : floor($positionY);
137
		$positionY = ($positionY + 0.5 > ceil($positionY)) ? ceil($positionY) : floor($positionY);
141
		
138
 
142
		$binaire = substr($donnees, ($positionY * self::LONGUEUR_COTE + $positionX) * self::OFFSET, self::OFFSET);
139
		$binaire = substr($donnees, ($positionY * self::LONGUEUR_COTE + $positionX) * self::OFFSET, self::OFFSET);
143
		$this->coordonnees->altitude = current(unpack("n*", $binaire));
140
		$this->coordonnees->altitude = current(unpack("n*", $binaire));
144
		if (!$this->coordonnees->altitude) {
141
		if (!$this->coordonnees->altitude) {
145
			$this->coordonnees->altitude = 0;
142
			$this->coordonnees->altitude = 0;
146
		}
143
		}
147
	}
144
	}
148
	
-
 
149
}
-
 
Line 150... Line -...
150
 
-
 
151
?>
145
 
-
 
146
}
152
147