Rev 742 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?phpclass Altitude {private $parametres = array();private $ressources = array();private $coordonnees = null;private $fichierSrtm = '';const LONGUEUR_COTE = 1201;const OFFSET = 2;public function consulter($ressources, $parametres) {$this->ressources = $ressources;$this->parametres = $parametres;$retour = null;try {$this->traiterCoordonnees();$this->rechercherFichierSrtm();$this->recupererAltitude();$retour = $this->coordonnees;} catch (Exception $erreur) {$retour = $erreur->getMessage();}return $retour;}private function traiterCoordonnees() {if ($this->estParametreExistant('latitude') && $this->estParametreExistant('longitude')) {$longitude = $this->parametres['longitude'];$latitude = $this->parametres['latitude'];if ($this->estUnFloat($longitude) && $this->estUnFloat($latitude)) {$this->verifierValiditeCoordonnees($longitude, $latitude);} else {$message = "La valeur des coordonnées longitude ou latitude n'est pas correcte. "." Elle doit être pour les deux paramètres une valeur décimale.";throw new Exception($message, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);}} else {$message = "Tous les paramètres passés dans l'URL ne correspondent pas à ceux attendus. "."Le web service nécessite de lui fournir une longitude et une latitude pour son bon fonctionnement.";throw new Exception($message, RestServeur::HTTP_CODE_CONTENU_REQUIS);}}private function estParametreExistant($nomParametre) {return in_array($nomParametre, array_keys($this->parametres));}private function estUnFloat($variable) {return (preg_match("/^(-)?\d+(\.\d+)?$/", $variable) == 1);}private function verifierValiditeCoordonnees($longitude, $latitude) {$longitude = floatval($longitude);$latitude = floatval($latitude);$longitudeMax = Config::get("limite_longitude");$latitudeMax = Config::get("limite_latitude");if (abs($longitude) > $longitudeMax || abs($latitude) > $latitudeMax) {$message = "Les coordonnées passées en paramètres désignent un point qui se trouve "."en dehors des limites du monde. Elles doivent être comprises entre -{$longitudeMax} "."et $longitudeMax sur l'axe des longitudes, et entre -{$latitudeMax} et {$latitudeMax} "."sur l'axe des latitudes.";throw new Exception($message, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);} else {$this->coordonnees = new StdClass();$this->coordonnees->longitude = $longitude;$this->coordonnees->latitude = $latitude;}}private function rechercherFichierSrtm() {$nomFichierSrtm = $this->construireNomFichierSrtm();if (!file_exists($nomFichierSrtm)) {$message = "Erreur interne : certaines ressources demandées n'ont pas pu être trouvées sur le serveur.";throw new Exception($message, restServeur::HTTP_CODE_ERREUR);} else {$this->fichierSrtm = $nomFichierSrtm;}}private function construireNomFichierSrtm() {$latitudeEntier = abs(floor($this->coordonnees->latitude));if ($latitudeEntier < 10) {$latitudeEntier = "0".$latitudeEntier;}$suffixeLatitude = $this->coordonnees->latitude < 0 ? "S" : "N";$longitudeEntier = abs(floor($this->coordonnees->longitude));if ($longitudeEntier < 10) {$longitudeEntier = "00".$longitudeEntier;} elseif ($longitudeEntier < 100) {$longitudeEntier = "0".$longitudeEntier;}$suffixeLongitude = $this->coordonnees->longitude < 0 ? "W" : "E";$dossierSrtm = Config::get('dossier_srtm').DS;$nomFichierSrtm = $dossierSrtm.$suffixeLatitude.$latitudeEntier.$suffixeLongitude.$longitudeEntier.".hgt.zip";return $nomFichierSrtm;}private function recupererAltitude() {$zip = zip_open($this->fichierSrtm);$fichier = zip_read($zip);$donnees = zip_entry_read($fichier, zip_entry_filesize($fichier));zip_close($zip);$xDepart = floor($this->coordonnees->longitude);$yDepart = floor($this->coordonnees->latitude);$longitude = $this->coordonnees->longitude;$latitude = $this->coordonnees->latitude;$positionX = (self::LONGUEUR_COTE-1) * ($longitude - $xDepart);$positionY = (self::LONGUEUR_COTE-1) * (1 - $latitude + $yDepart);$positionX = ($positionX + 0.5 > ceil($positionX)) ? ceil($positionX) : floor($positionX);$positionY = ($positionY + 0.5 > ceil($positionY)) ? ceil($positionY) : floor($positionY);$binaire = substr($donnees, ($positionY * self::LONGUEUR_COTE + $positionX) * self::OFFSET, self::OFFSET);$this->coordonnees->altitude = current(unpack("n*", $binaire));if (!$this->coordonnees->altitude) {$this->coordonnees->altitude = 0;}}}?>