Rev 1110 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php// declare(encoding='UTF-8');/*** Gère le sous-service Taxons de Cartes.** @see http://www.tela-botanica.org/wikini/eflore/wakka.php?wiki=EfloreApi01Cartes** @package eFlore/services* @author Jean-Pascal MILCENT <jpm@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-2012 Tela Botanica (accueil@tela-botanica.org)*/// TODO : Config et Outils sont des classes statiques qui doivent poser des pb pour les tests...class FranceCartes {private $parametres = array();private $ressources = array();protected $largeurOrig = 600;protected $longeurOrig = 545;protected $largeurDefaut = 600;protected $largeurDemandee = 600;protected $prefixe_id_zone = 'INSEE-D';protected $options_cache = array();const PRESENCE_CHOROLOGIE = '1';public function __construct(Conteneur $conteneur) {$this->Bdd = $conteneur->getBdd();$this->tableOntologie = $conteneur->getParametre('bdd_table_ontologies');$this->config = $conteneur->getParametre('Cartes');$this->convertisseur = $this->config['convertisseur'];$this->tableMeta = $conteneur->getParametre('bdd_table_meta');$this->cheminCartesBase = $this->config['chemin'];$this->options_cache = array('mise_en_cache' => $this->config['cache_miseEnCache'],'stockage_chemin' => $this->config['cache_stockageChemin'],'duree_de_vie' => $this->config['cache_dureeDeVie']);}public function consulter($ressources, $parametres) {$this->parametres = $parametres;$this->ressources = $ressources;$this->chargerMetadonnees();$this->definirVersion();$this->tableChorodep = 'chorodep_v'.str_replace('.', '_', $this->version);if(isset($parametres['retour.format']) && is_numeric($parametres['retour.format'])) {$this->largeurDemandee = intval($parametres['retour.format']);}if(count($ressources) == 0) {$resultat = $this->getCarteTaxonsParZones();} else if($ressources[0] == "legende") {$cache = $this->getCache('global');if($cache != null) {$max = $cache['nb_taxons_max'];} else {$max = $this->getNbMaxTaxonsParZones();}$resultat = $this->getLegendeCarteTaxonsParZones($max);}return $resultat;}private function chargerMetadonnees() {$requete = 'SELECT * '."FROM {$this->tableMeta} "."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;}private function definirVersion() {$this->version = $this->metadonnees[0]['version'];}public function getLegendeCarteTaxonsParZones($nb_max) {// TODO : mettre en config ou en ontologie ?// mais ça fait encore un appel de plus aux ontologies// qui sont déjà bien bien bien bien chargées$this->couleurs_legende_globale = array("#808080", "#EFF8E1", "#F2E2C0", "#C9CC8D", "#C1E587", "#A0FF7D");$couleurs = $this->couleurs_legende_globale;$legende = array("seuil0" => array("code" => "","couleur" => $couleurs[0],"css" => "","nom" => "Non renseignée","description" => "Zone géographique non renseignée."));array_shift($couleurs);$borne_min = 0;$borne_max = 500;for($i = 1; $i <= 5; $i++) {$borne_max = ($i == 5) ? $nb_max : $borne_max;$legende["seuil".$i] = array("code" => "","couleur" => $couleurs[$i-1],"css" => "","nom" => "de ".$borne_min." à ".$borne_max." taxons","description" => "de ".$borne_min." à ".$borne_max." taxons.");$borne_min = $borne_max + 1;$borne_max = ($i == 5) ? $nb_max : ($i * 1200);}return $legende;}private function convertirLegendeVersCss($legende) {$css = "";foreach($legende as $cle => $item) {if($item['css'] != '') {$css .=$item['css']." {"."\n"." fill:".$item['couleur'].";"."\n"."}"."\n\n";}}return $css;}public function getCarteTaxonsParZones() {$this->envoyerCacheSiExiste('global');$taxonsParZones = $this->compterTaxonsParZones();$legende = $this->getLegendeCarteTaxonsParZones($taxonsParZones['max']);$infos_zones = array();$max = 0;foreach($taxonsParZones['nb_taxons_par_zones'] as $id_zone => $nb) {$infos_zones[$id_zone] = "- ".$nb." taxons présents";$legende[$this->getSeuil($nb)]['css'] .= $legende[$this->getSeuil($nb)]['css'] != "" ? ', ' : '' ;$legende[$this->getSeuil($nb)]['css'] .= "#".$this->prefixe_id_zone.$id_zone;$max = $max < $nb ? $nb : $max;}$this->style = $this->convertirLegendeVersCss($legende);$svg = $this->assemblerSvg($this->calculerHauteur($this->largeurDemandee),$this->largeurDemandee,$this->style,$infos_zones);$this->sauverCache(array('style' => $this->style, 'infos_zones' => $infos_zones, 'nb_taxons_max' => $max), 'global');$this->envoyerSvg($svg);}// Fonction bien pourrie pour renvoyer juste un max// mais son résultat est mis en cache donc elle sera appelée environ// une fois par an (et encore si on appelle la légende avant la carte)public function getNbMaxTaxonsParZones() {$taxonsParZones = $this->compterTaxonsParZones();$max = 0;foreach($taxonsParZones as $id_zone => $nb) {$max = $max < $nb ? $nb : $max;}return $max;}public function getSeuil($nb_taxons) {// TODO: factoriser les bornes avec la fonction qui gère la légende$seuil = "";if($nb_taxons <= 1) {$seuil = "1";} elseif (2 <= $nb_taxons && $nb_taxons <= 1200) {$seuil = "2";} elseif (1201 <= $nb_taxons && $nb_taxons <= 2400) {$seuil = "3";} elseif (2401 <= $nb_taxons && $nb_taxons <= 3600) {$seuil = "4";} elseif (3601 <= $nb_taxons) {$seuil = "5";}return "seuil".$seuil;}public function compterTaxonsParZones() {$req = "SELECT * FROM ".$this->tableChorodep;$resultat = $this->Bdd->recupererTous($req);$max = 0;$nb_taxons_par_zones = array();foreach($resultat as $ligne) {$i = 0;for($i < 0; $i <= 100; $i++) {$index = $i < 10 ? "0".$i : $i;if(isset($ligne[$index]) && $ligne[$index] != "" && $ligne[$index] == self::PRESENCE_CHOROLOGIE) {// seules les présences certaines sont prises en compte$nb_taxons_par_zones[$index] = isset($nb_taxons_par_zones[$index]) ? $nb_taxons_par_zones[$index] : 0;$nb_taxons_par_zones[$index] += 1;// calcul du max qui sert à générer la légende$max = $nb_taxons_par_zones[$index] > $max ? $nb_taxons_par_zones[$index] : $max;}}}return array('nb_taxons_par_zones' => $nb_taxons_par_zones, 'max' => $max);}public function sauverCache($a_cacher, $cache_id) {$cache = new CacheSimple($this->options_cache);return $cache->sauver(serialize($a_cacher), $cache_id);}public function getCache($id) {$cache = new CacheSimple($this->options_cache);if(($contenu_cache = $cache->charger($id)) !== false) {$contenu_cache = unserialize($contenu_cache);}return $contenu_cache;}private function calculerHauteur($largeur) {$rapport = $this->longeurOrig/$this->largeurOrig;$hauteur = $rapport * $largeur;return intval($hauteur);}private function envoyerCacheSiExiste($id) {if(($cache = $this->getCache($id))) {$style = $cache['style'];$infos_zones = $cache['infos_zones'];$cache = $this->assemblerSvg($this->calculerHauteur($this->largeurDemandee), $this->largeurDemandee, $style, $infos_zones);$this->envoyerSvg($cache);}}private function assemblerSvg($hauteur, $largeur, $style, $infos_zones) {$tpl_svg = $this->cheminCartesBase.'/france_02.tpl.svg';$donnees = array('hauteur' => $hauteur,'largeur' => $largeur,'css' => $style,'infos_zones' => $infos_zones);$svg = SquelettePhp::analyser($tpl_svg, $donnees);return $svg;}private function envoyerLegende($legende) {header("Content-type: application/json");echo json_encode($legende);exit;}private function envoyerSvg($svg) {header("Content-type: image/svg+xml");echo $svg;exit;}}