Rev 402 | Rev 418 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*** Classe Graphiques.php permet d'afficher des graphiques en svg remplis avec des données écologiques* fin d'url possibles :* graphiques/#typegraphique/#bdnt.nn:#num_nomen --> renvoie une graphique avec les données connues** Encodage en entrée : utf8* Encodage en sortie : utf8* @package eflore-projets* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>* @author Mathilde SALTHUN-LASSALLE <mathilde@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 1.0* @copyright 1999-2011 Tela Botanica (accueil@tela-botanica.org)*/class Graphiques {private $parametres = array();private $ressources = array();private $metadonnees;private $version;private $Bdd;private $nomGraphique = array();private $table = "";private $requete_condition = "";private $requete_champs;private $config;private $convertisseur;private $cheminGraphBase;private $serviceNom = 'Graphiques';private $valeurs_en_pourcentage ;private $dom;private $largeurSVG="500";private $graduations_id = array ("zero" => 0 ,"un"=> 0.1, "deux" => 0.2 , "trois" => 0.3, "quatre" => 0.4,"cinq" => 0.5, "six" => 0.6 ,"sept" => 0.7, "huit" => 0.8, "neuf" => 0.9,"dix" => 1 );public function consulter($ressources, $parametres) {$this->ressources = $ressources;$this->parametres = $parametres;$this->initialiserConfiguration();$resultats = '';$this->table = Config::get('bdd_table')."_v".$this->version;$this->traiterRessources();$requete = $this->assemblerLaRequete();$resultat = $this->Bdd->recupererTous($requete);$versionResultat = $this->obtenirResultat($resultat);return $versionResultat;}//+--------------------------initialisation de paramètres -------------------------------------------+public function initialiserConfiguration() {$conteneur = new Conteneur();$this->Bdd = $conteneur->getBdd();$this->config = $conteneur->getParametre('Graphiques');$this->convertisseur = $this->config['convertisseur'];$this->cheminGraphBase = $this->config['chemin'];$cacheOptions = array('mise_en_cache' => $this->config['cache']['miseEnCache'],'stockage_chemin' => $this->config['cache']['stockageChemin'],'duree_de_vie' => $this->config['cache']['dureeDeVie']);$this->cache = $conteneur->getCacheSimple($cacheOptions);$this->chargerVersions();$this->definirVersion();$this->definirFormat();}//on n'affiche qu'une version de graphique à la fois ( la dernière ou celle demandée )private function definirVersion() {if( (!isset($this->parametres['version.projet']) ) || ((isset($this->parametres['version.projet']) )&&(($this->parametres['version.projet'] == '+') || ($this->parametres['version.projet'] == '')))){$this->version = $this->metadonnees[0]['version'];} else {$this->version = $this->parametres['version.projet'];}}private function definirFormat() {if (isset($this->parametres['retour.format']) ){if (preg_match("/^[0-9]+$/", $this->parametres['retour.format'])){$this->largeurSVG= $this->parametres['retour.format'];}else {$erreur = "Erreur : Entrez la largeur voulue (en pixels) pour le paramètre retour.format.";$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;throw new Exception($erreur, $code);}}if (!isset($this->parametres['retour']) ){$this->parametres['retour'] = 'image/svg+xml';}else {if (( $this->parametres['retour'] != 'image/svg+xml')&& ( $this->parametres['retour'] != 'image/png')){$erreur = "Erreur : choisissez le format de retour pour le paramètre retour : image/svg%2Bxml ou image/png.";$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;throw new Exception($erreur, $code);}}}private function chargerVersions() {$requete = "SELECT version "."FROM ".Config::get('bdd_table_meta')." "."ORDER BY date_creation DESC ";$resultats = $this->Bdd->recupererTous($requete);if (!is_array($resultats) || count($resultats) <= 0) {$message = "Les méta-données n'ont pu être chargée pour la ressource demandée";$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;throw new Exception($message, $code);}$this->metadonnees = $resultats;}//+--------------------------traitement ressources ou paramètres -------------------------------------------+public function traiterRessources() {$this->traiterRessources_NomService();$this->traiterRessources_TypeGraphique();}public function traiterRessources_TypeGraphique(){if (isset($this->ressources) && !empty($this->ressources[1])) {if(preg_match('/^(.+)\.nn:([0-9]+)$/', $this->ressources[1], $retour)==1){switch ($retour[1]) {case 'bdtfx' :$this->requete_condition[]= "num_nomen = ".$retour[2]." AND BDNT = 'BDTFX' ";break;case 'bdafx' :$this->requete_condition[] = "num_nomen = ".$retour[2]." AND BDNT = 'BDAFX' ";break;case 'bdbfx' :$this->requete_condition[] = "num_nomen = ".$retour[2]." AND BDNT = 'BDBFX' ";break;default :$e = 'Erreur dans l\'url de votre requête : </br> La ressource " '.$retour[1].' " n\'existe pas.';throw new Exception( $e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);break;}}else {$e = 'Erreur dans l\'url de votre requête : </br> La ressource n\'existe pas.';throw new Exception( $e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);}} else {throw new Exception( "Erreur dans l\'url de votre requête :"."preciser le référentiel et le numéro nomenclatural sous la forme {bdnt}.nn:{nn}.",RestServeur::HTTP_CODE_MAUVAISE_REQUETE);}}public function traiterRessources_NomService(){if (isset($this->ressources) && !empty($this->ressources[0])) {switch ($this->ressources[0]) {case 'climat' :$this->requete_champs = ' ve_lumiere , ve_temperature, ve_continentalite, ve_humidite_atmos' ;$this->nomGraphique= 'climat';break;case 'sol' :$this->requete_champs = ' ve_humidite_edaph , ve_reaction_sol, ve_nutriments_sol, ve_salinite,'.'ve_texture_sol, ve_mat_org_sol' ;$this->nomGraphique = 'sol';break;default :$e = 'Erreur dans l\'url de votre requête : </br> La ressource " '.$retour[1].' " n\'existe pas.';throw new Exception($e, RestServeur::HTTP_CODE_MAUVAISE_REQUETE);break;}}else {throw new Exception("Erreur dans l\'url de votre requête :"."</br> precisez le graphique -> \"sol\" ou \"climat\".", RestServeur::HTTP_CODE_MAUVAISE_REQUETE);}}//+-------------------------- formatage du résultat -------------------------------------------+public function obtenirResultat($resultat) {if ($resultat == ""){$message = 'La requête SQL formée comporte une erreur!';$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;throw new Exception($message, $code);}elseif ($resultat) {if ((count($this->ressources)) != 0) {$this->traiterValeursEcologiques($resultat[0]);$i = 0;$svg = $this->genererSVG();$resultat = new ResultatService();$resultat->corps = ($this->parametres['retour'] == 'image/png') ? $this->convertirEnPNG($svg) : $svg;$resultat->mime = $this->parametres['retour'];}} else {$message = 'Les données recherchées sont introuvables.';$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;throw new Exception($message, $code);}return $resultat;}public function traiterValeursEcologiques($valeurs){//humidite edaphique sur echelle de 12foreach($valeurs as $cle => $val){if ($cle == 've_humidite_edaph'){$this->valeurs_en_pourcentage[$cle] = round($val/12,1);}else{//salinite commence à 0if($val == 0){$this->valeurs_en_pourcentage[$cle] = 0;}else{$this->valeurs_en_pourcentage[$cle] = round($val/9,1);}}}}public function genererSVG(){$this->dom = new DOMDocument('1.0', 'UTF-8');//verifie que le xml est bien formé$this->dom->validateOnParse = true;$fichierSvg = $this->cheminGraphBase."".$this->nomGraphique.".svg";$res=$this->dom->load($fichierSvg);$this->changerValeursSVG();$svg = $this->dom->saveXML();return $svg;}public function changerValeursSVG(){foreach ($this->valeurs_en_pourcentage as $cle => $val){$grad_id = array_search($val,$this->graduations_id);$Dompath = new DOMXPath($this->dom);$element = $Dompath->query("//*[@id='".$grad_id."']")->item(0);$pos_x = $element->getAttribute('x1');$curseur = $Dompath->query("//*[@id='".$cle."']")->item(0);$curseur->setAttribute('cx', $pos_x);$svg = $this->dom->getElementsByTagName("svg")->item(0);$svg->setAttribute('width',$this->largeurSVG);}}private function convertirEnPNG($svg) {$png = null;if (isset($this->convertisseur)) {if ($this->convertisseur == 'imagick') {if (extension_loaded('imagick')) {$png = $this->convertirEnPNGAvecImageMagick($svg);} else {$message = "Impossible de générer l'image sur le serveur. Extension ImageMagick absente.";$code = RestServeur::HTTP_CODE_ERREUR;throw new Exception($message, $code);}} else if ($this->convertisseur == 'rsvg') {$png = $this->convertirEnPNGAvecRsvg($svg);} else {$message = "Le convertisseur indiqué '{$this->convertisseur}' ne fait pas partie de la liste "."des convertisseurs disponibles : imagick, rsvg.";$code = RestServeur::HTTP_CODE_ERREUR;throw new Exception($message, $code);}} else {$message = "Veuillez indiquer le convertisseur de svg à utiliser pour le service.";$code = RestServeur::HTTP_CODE_ERREUR;throw new Exception($message, $code);}return $png;}private function convertirEnPNGAvecImageMagick($svg) {$convertisseur = new Imagick();$convertisseur->setBackgroundColor(new ImagickPixel('transparent'));$convertisseur->readImageBlob($svg);$convertisseur->setImageFormat('png32');$convertisseur->resizeImage($this->largeurSVG, 0 , imagick::FILTER_LANCZOS, 0, true);$png = $convertisseur->getImageBlob();$convertisseur->clear();$convertisseur->destroy();return $png;}private function convertirEnPNGAvecRsvg($svg) {$idFichier = $this->getIdFichier();$fichierPng = $this->config['cache']['stockageChemin']."".$idFichier.'.png';$fichierSvg = $this->config['cache']['stockageChemin']."".$idFichier.'.svg';file_put_contents($fichierSvg, $svg);$commande = "rsvg-convert $fichierSvg -d 75 -p 75 -o $fichierPng";$rsvg = exec($commande);$this->indexerFichierPng($fichierPng);$png = file_get_contents($fichierPng);return $png;}private function indexerFichierPng($fichierPng) {$img = imagecreatefrompng($fichierPng);imagetruecolortopalette($img, false, 32);imagepng($img, $fichierPng, 9, PNG_ALL_FILTERS);}private function getIdFichier(){$idfichier = str_replace(".","-",$this->ressources[1]);$idfichier = str_replace(':','-',$idfichier);return $idfichier;}//+--------------------------FONCTIONS D'ASSEMBLAGE DE LA REQUETE-------------------------------------------+public function assemblerLaRequete() {$requete = ' SELECT '.$this->requete_champs.' FROM '.$this->table.' '.$this->retournerRequeteCondition();return $requete;}public function retournerRequeteCondition() {$condition = '';if ($this->requete_condition !== "") {$condition = ' WHERE '.implode(' AND ', $this->requete_condition);}return $condition;}}?>