Rev 1034 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*** Classe qui remplit un fond cartographique SVG a partir des observations en base de donnees* pour un taxon de plante. Elle verifie dans un premier temps la validite des parametres saisis,* puis charge le fond cartographique depuis le fichier, recupere dans la base de donnees* les observations sur la France metropolitaine pour le taxon donne et remplit la carte* en changeant le style CSS des mailles en fonction des coordonnees des points d'observation.* Le format et la taille de la carte renvoyee au client est parametrable.** Parametres :* - referentiel : le referentiel taxonomique a interroger pour verifier le taxon. Pour l'instant,* seul bdtfx (Tracheophytes de France metropolirtaine) est utilise par le web service* - num_taxon : le numero taxonomique de la plante dont on veut obtenir la carte de repartition.* Le rang des taxons traites par le web service sont la famille, le genre, l'espece et la sous-espece.* La recherche des observations s'etend en pus sur les sous taxons et les synonymes.* - source : une ou plusieurs sources de donnees a interroger. Si le parametre n'est pas indique,* le web service ira rechercher les observatipons dans toutes les sources de donnees.* - format : la largeur de la carte, exprimee dans une valeur entiere en pixels.* Le ratio largeur:hauteur est conserve lors du redimensionnement de la carte pour le retour* - retour : le type MIME (ou format de fichier) de retour. Sont acceptes par le web service* le PNG (image/png) et le XML (text/html) pour renvoyer le web service** @package framework-0.4* @author Alexandre GALIBERT <alexandre.galibert@tela-botanica.org>* @license GPL v3 <http://www.gnu.org/licenses/gpl.txt>* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt>* @version $Id$* @copyright 2013 Tela Botanica (accueil@tela-botanica.org)**/class MoissonnageCartes {const MIME_MAP = "text/html";const MIME_PNG = "image/png";const METHODE_TELECHARGEMENT = "telecharger";const METHODE_AFFICHAGE = "afficher";private $ressources;private $parametres;private $referentiel = '';private $taxon = null;private $sources = array();private $format = 0;private $retour = self::MIME_MAP;private $methode_livraison = self::METHODE_AFFICHAGE;private $erreurs = array();public function consulter($ressources, $parametres) {$this->parametres = $parametres;$this->ressources = $ressources;$resultat = null;$this->chargerClassesSousDossier();if ($this->analyserRessources() == true) {$resultat = $this->formerLegende();} else {$this->traiterParametres();$resultat = $this->formerCarte();if($this->methode_livraison == self::METHODE_TELECHARGEMENT) {$this->telechargerCarte($resultat->corps);}}return $resultat;}private function analyserRessources() {$ok = false;if (isset($this->ressources[0]) && $this->ressources[0] == 'legende') {$ok = true;}return $ok;}private function formerLegende() {$legende = new LegendeCartes();$resultat = $legende->obtenirLegende();return $resultat;}private function chargerClassesSousDossier() {$this->verifierExistenceDossier("cartes");$nomDossier = dirname(__FILE__).DS."cartes";$dossier = opendir($nomDossier);$fichiersAInclure = array();while ($fichier = readdir($dossier)) {if (filetype($nomDossier.DS.$fichier) == 'file') {$fichiersAInclure[] = $nomDossier.DS.$fichier;}}$fichiersAInclure = array_reverse($fichiersAInclure);foreach ($fichiersAInclure as $fichier) {include_once($fichier);}}private function verifierExistenceDossier($nomDossier) {$dossier = dirname(__FILE__).DS.$nomDossier;if (!file_exists($dossier) || !is_dir($dossier)) {$message = "Problème rencontré lors de la génération de la carte : des ressources "."nécessaires au fonctionnement du service n'ont pas été localisées sur le serveur.\n";throw new Exception($message);}}private function verifierExistenceFichier($nomFichier) {if (!file_exists($nomFichier)) {$message = "Problème rencontré lors de la génération de la carte : des ressources "."nécessaires au fonctionnement du service n'ont pas été localisées sur le serveur.\n";throw new Exception($message);}}private function traiterParametres() {$this->verifierReferentielEtTaxon();$this->verifierParametreSource();$this->verifierParametreFormat();$this->verifierParametreRetour();$this->verifierParametreMethodeLivraison();if (count($this->erreurs) > 0) {$this->renvoyerErreurs();}}private function verifierParametreFormat() {if (!isset($this->parametres['format'])) {$this->erreurs[] = "Le paramètre format (dimensions) de l'image n'a pas été indiqué dans l'URL du service.";} elseif (preg_match('/^[1-9]\d{2}$/', $this->parametres['format']) != 1) {$this->erreurs[] = "La valeur du paramètre format n'est pas acceptée par le service. "."Une largeur valide doit être un nombre entier compris entre 100 et 999.";} else {$this->format = $this->parametres['format'];}}private function verifierParametreRetour() {$typesMime = array(self::MIME_MAP, self::MIME_PNG);if (!isset($this->parametres['retour'])) {$this->erreurs[] = "Le paramètre type de retour de l'image n'a pas été indiqué dans l'URL du service.";} elseif (!in_array($this->parametres['retour'], $typesMime)) {$this->erreurs[] = "Le format de retour ".$this->parametres['retour']." n'est pas acceptée par le service. "." Seuls les types MIME suivants sont gérés : ".implode(',', $typesMime);} else {$this->retour = $this->parametres['retour'];}}private function verifierParametreMethodeLivraison() {$typesMethodeLivraison = array(self::METHODE_AFFICHAGE, self::METHODE_TELECHARGEMENT);if (isset($this->parametres['methode']) && !in_array($this->parametres['methode'], $typesMethodeLivraison)) {$this->erreurs[] = "Le format de methode de livraison ".$this->parametres['methode']." n'est pas acceptée par le service. "." Seuls les methodes suivantes sont gérés : ".implode(',', $typesMethodeLivraison);} elseif(isset($this->parametres['methode']) && in_array($this->parametres['methode'], $typesMethodeLivraison)) {$this->methode_livraison = $this->parametres['methode'];}}private function verifierParametreSource() {$sourcesDisponibles = explode(',', trim(Config::get('sourcesDonnees')));if (isset($this->parametres['source'])) {$sourcesParametre = explode(',', trim($this->parametres['source']));foreach ($sourcesParametre as $source) {if (!in_array($source, $sourcesDisponibles)) {$this->erreurs[] = "La source de données $source n'est pas disponible pour ce service. "."Les sources suivantes sont utilisables : ".implode(',', $sourcesDisponibles).".";} else {$this->sources[] = $source;}}} else {$this->sources = $sourcesDisponibles;}}private function verifierReferentielEtTaxon() {if (!$this->estReferentielDisponible()) {$this->erreurs[] = "Le référentiel ".$this->parametres['referentiel']." n'a pas été trouvé. "."La liste des référentiels disponibles pour ce service sont : ".Config::get('referentielsDispo');} else {$this->referentiel = $this->parametres['referentiel'];$taxon = $this->recupererInformationsTaxon();if (is_null($taxon)) {$this->erreurs[] = "Le taxon d'espèce que vous avez demandé n'a pas été trouvé dans le référentiel.";} else {$this->taxon = $taxon;}}}private function renvoyerErreurs() {$message = "Les erreurs suivantes ont été rencontrées : \n".implode('\n', $this->erreurs);throw new Exception($message, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);}private function estReferentielDisponible() {$referentielsDispo = explode(',', Config::get('referentielsDispo'));$estDisponible = (isset($this->parametres['referentiel'])&& in_array($this->parametres['referentiel'], $referentielsDispo));return $estDisponible;}private function recupererInformationsTaxon() {$taxon = null;if (isset($this->parametres['num_taxon'])) {$numTaxon = $this->parametres['num_taxon'];$nomTable = $this->recupererNomTableReferentiel();$bdd = new Bdd();$requete = "SELECT num_nom, num_nom_retenu, nom_sci, nom_complet, rang, num_taxonomique FROM {$nomTable} "."WHERE num_taxonomique={$numTaxon} ORDER BY If(num_nom=num_nom_retenu,0,1) LIMIT 0,1";$taxon = $bdd->recuperer($requete);if ($taxon === false) {$taxon = null;}}return $taxon;}private function recupererNomTableReferentiel() {$tablesReferentiel = explode(',', Config::get('bdd_table_referentiel'));$nomTable = '';foreach ($tablesReferentiel as $table) {if (strstr($table, $this->referentiel) !== false) {$nomTable = $table;}}return $nomTable;}private function formerCarte() {$suffixe = 'france_moissonnage';// le fichier png avec les départements est illisible en petit format// dans ce cas là un template plus simple est utilisé (sans les départements)if($this->format < 300 && $this->retour == self::MIME_PNG) {$suffixe = $suffixe."_sans_departements";}$nomFichierSVG = Config::get('chemin')."{$suffixe}.svg";$this->verifierExistenceFichier($nomFichierSVG);$formateur = new FormateurSVG($nomFichierSVG, $this->sources, $this->retour, $this->format);$formateur->formaterCarte($this->taxon);$resultat = new ResultatService();$resultat->corps = $formateur->renvoyerCarte();$resultat->mime = $this->retour;return $resultat;}private function telechargerCarte($fichier) {if (function_exists('mb_strlen')) {$taille = mb_strlen($fichier, '8bit');} else {$taille = strlen($fichier);}$extension = ($this->retour == "text/html") ? 'html' : 'png';header('Content-Description: File Transfer');header('Content-Type: application/octet-stream');header('Content-Disposition: attachment; filename="carte.'.$extension.'"');header('Content-Transfer-Encoding: binary');header('Connection: Keep-Alive');header('Expires: 0');header('Cache-Control: must-revalidate, post-check=0, pre-check=0');header('Pragma: public');header('Content-Length: '.$taille);}}?>