/trunk/services/modules/0.1/moissonnage/Cartes.php |
---|
1,5 → 1,35 |
<?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 Cartes { |
const MIME_MAP = "text/html"; |
11,7 → 41,7 |
private $referentiel = ''; |
private $taxon = null; |
private $sources = array(); |
private $format = 'max'; |
private $format = 0; |
private $retour = self::MIME_MAP; |
private $erreurs = array(); |
/trunk/services/modules/0.1/moissonnage/cartes/DonneesFloradata.php |
---|
File deleted |
\ No newline at end of file |
/trunk/services/modules/0.1/moissonnage/cartes/DonneesMoissonnage.php |
---|
File deleted |
\ No newline at end of file |
/trunk/services/modules/0.1/moissonnage/cartes/FormateurSVG.php |
---|
1,5 → 1,19 |
<?php |
/** |
* Classe qui genere la carte SVG pour les parametres de la requete qui a ete utilisee pour appeler |
* 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 FormateurSVG { |
private $documentXML; |
29,22 → 43,8 |
private function chargerSVG($nomFichierSVG) { |
$this->documentXML = new DOMDocument("1.0", "UTF-8"); |
$this->documentXML->load($nomFichierSVG); |
$this->supprimerNoeudsInutiles($this->documentXML->documentElement); |
} |
private function supprimerNoeudsInutiles(& $noeud) { |
$index = 0; |
while ($index < $noeud->childNodes->length) { |
if (get_class($noeud->childNodes->item($index)) != 'DOMElement') { |
$noeud->removeChild($noeud->childNodes->item($index)); |
} else { |
$fils = $noeud->childNodes->item($index); |
$this->supprimerNoeudsInutiles($fils); |
$index ++; |
} |
} |
} |
private function chargerCoordonnees() { |
$viewbox = $this->recupererNoeuds('qgisviewbox'); |
$this->coordonnees = array( |
117,10 → 117,10 |
public function formaterCarte($taxon) { |
$limitesCarte = $this->renvoyerLimitesCarte(); |
$sourceDonnees = new SourceDonnees($limitesCarte, $taxon); |
foreach ($this->sources as $source) { |
$nomClasse = $source == 'floradata' ? 'DonneesFloradata' : 'DonneesMoissonnage'; |
$rechercheBdd = new $nomClasse($limitesCarte, $taxon, $source); |
$stations = $rechercheBdd->recupererStations(); |
$nomMethode = "recupererStations".($source == 'floradata' ? 'Floradata' : 'Moissonnage'); |
$stations = $sourceDonnees->$nomMethode($source); |
$this->ajouterStations($stations, $source); |
} |
$this->supprimerMaillesVides(); |
147,6 → 147,9 |
$index = 0; |
$maille = $grille->item($index); |
foreach ($stations as $station) { |
if (!isset($station['lat']) || !isset($station['lng']) || !isset($station['commune'])) { |
continue; |
} |
$idMaille = $maille->attributes->getNamedItem('id')->value; |
$bbox = explode('_', substr($idMaille, 5)); |
$bbox[0] = floatval($bbox[0]); |
161,9 → 164,8 |
$bbox[1] = floatval($bbox[1]); |
} |
if ($bbox[1] == $station['lat'] && $bbox[0] == $station['lng']) { |
$this->genererTitreMaille($station['nb_observations'], $source, $maille); |
$this->ajouterCommentaire($station, $source, $maille); |
$this->appliquerStyleMaille($source, $maille); |
$maille = $grille->item($index ++); |
} |
if ($index == $grille->length) { |
break; |
184,18 → 186,27 |
} |
private function appliquerStyleMaille($source, & $maille) { |
$style = $maille->hasAttribute('class') ? 'tout' : $source; |
$maille->setAttribute('class', $style); |
if ($maille->hasAttribute('class') && $maille->attributes->getNamedItem('class')->value != $source) { |
$maille->setAttribute('class', 'tout'); |
} elseif (!$maille->hasAttribute('class')) { |
$maille->setAttribute('class', $source); |
} |
} |
private function genererTitreMaille($observations, $source, & $maille) { |
$texte = ''; |
private function ajouterCommentaire($station, $source, & $maille) { |
$commentaires = array(); |
if ($maille->hasAttribute('title')) { |
$texte = $maille->attributes->getNamedItem('title')->value."\n$source : $observations observations"; |
$commentaires = explode("; ", $maille->attributes->getNamedItem('title')->value); |
} |
$commentaire = ucfirst($source)." : {$station['commune']}, "; |
if (strlen($station['date']) == 4) { |
$commentaire .= "en {$station['date']} par {$station['auteur']}"; |
} else { |
$texte = "$source : $observations observations"; |
$date = preg_replace("/(\d{4})-(\d{2})-(\d{2})/", "$3/$2/$1", $station['date']); |
$commentaire .= "le {$date} par {$station['auteur']}"; |
} |
$maille->setAttribute('title', $texte); |
$commentaires[] = trim($commentaire); |
$maille->setAttribute('title', implode('; ', $commentaires)); |
} |
/trunk/services/modules/0.1/moissonnage/cartes/LegendeCartes.php |
---|
1,5 → 1,17 |
<?php |
/** |
* Classe qui fournit une legende recuperee dans une table d'ontologies pour la renvoyer au client |
* |
* @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 LegendeCartes { |
const TYPE_MIME = 'application/json'; |
/trunk/services/modules/0.1/moissonnage/cartes/SourceDonnees.php |
---|
1,13 → 1,17 |
<?php |
abstract class SourceDonnees { |
class SourceDonnees { |
protected $limitesCarte = ''; |
protected $taxon = array(); |
protected $source = ''; |
private $bdd = null; |
private $limitesCarte = ''; |
private $taxon = array(); |
private $nomRang = ''; |
private $taxons = array(); |
private $genres = array(); |
public function __construct($limitesCarte, $taxon, $source) { |
public function __construct($limitesCarte, $taxon) { |
$this->limitesCarte = $limitesCarte; |
foreach ($this->limitesCarte as $bord => $valeur) { |
$this->limitesCarte[$bord] = str_replace(",", ".", round($valeur, 6)); |
14,14 → 18,15 |
} |
$this->bdd = new Bdd(); |
$this->taxon = $taxon; |
$this->source = $source; |
$this->nomRang = $this->obtenirNomRang(); |
if ($this->nomRang == 'espece' || $this->nomRang == 'sous_espece') { |
$this->taxons = $this->recupererSynonymesEtSousEspeces(); |
} elseif ($this->nomRang == 'famille') { |
$this->genres = $this->recupererGenres(); |
} |
} |
abstract public function recupererStations(); |
abstract protected function construireWhereTaxon(); |
protected function obtenirNomRang() { |
private function obtenirNomRang() { |
$nomsRangs = array('famille', 'genre', 'espece', 'sous_espece'); |
$rangs = explode(',', Config::get('rangs')); |
for ($index = 0; $index < count($nomsRangs) && $rangs[$index] != $this->taxon['rang']; $index ++); |
30,7 → 35,6 |
} |
protected function recupererSynonymesEtSousEspeces() { |
$this->bdd->requeter("USE ".Config::get('bdd_nom')); |
$requete = |
"SELECT num_nom, nom_sci, num_taxonomique FROM bdtfx_v1_01 WHERE hierarchie LIKE '%-{$this->taxon['num_nom']}-%' ". |
"OR num_taxonomique = {$this->taxon['num_taxonomique']}"; |
44,6 → 48,114 |
return $this->bdd->recupererTous($requete); |
} |
public function recupererStationsFloradata() { |
$this->bdd->requeter("USE ".Config::get('bdd_nom_floradata')); |
$requete = |
"SELECT DISTINCTROW zone_geo AS commune, Date(date_observation) AS date, Floor(wgs84_latitude*10)/10 AS lat, ". |
"Floor(wgs84_longitude*10)/10 AS lng, courriel_utilisateur AS auteur ". |
"FROM cel_obs LEFT JOIN cel_zones_geo cz ON ce_zone_geo=id_zone_geo ". |
"WHERE ".$this->construireWhereTaxonFloradata()." AND transmission=1 AND ". |
"wgs84_longitude BETWEEN ".$this->limitesCarte['ouest']." AND ".$this->limitesCarte['est']." ". |
"AND wgs84_latitude BETWEEN ".$this->limitesCarte['sud']." AND ".$this->limitesCarte['nord']." ". |
"AND date_observation<>'0000-00-00 00-00-00' ORDER BY lat DESC, lng ASC, commune, date"; |
return $this->bdd->recupererTous($requete); |
} |
private function construireWhereTaxonFloradata() { |
$criteres = array(); |
$nomRang = $this->obtenirNomRang($this->taxon); |
if ($this->nomRang == 'famille') { |
$criteres[] = "famille=".$this->bdd->proteger($this->taxon['nom_sci']); |
} elseif ($this->nomRang == 'genre') { |
$criteres[] = "nom_sel LIKE ".$this->bdd->proteger($this->taxon['nom_sci'].'%'); |
} else { |
$taxons = array($this->taxon['num_taxonomique']); |
foreach ($this->taxons as $sousTaxon) { |
$taxons[] = $sousTaxon['num_taxonomique']; |
} |
$criteres[] = "nt IN (".implode(',', array_unique($taxons)) .")"; |
} |
return "(".implode(' OR ',array_unique($criteres)).")"; |
} |
public function recupererStationsMoissonnage($source) { |
$this->bdd->requeter("USE ".Config::get('bdd_nom')); |
$requete = |
"SELECT DISTINCTROW lieu_commune_code_insee, observation_date AS date, observateur_nom_complet AS auteur ". |
"FROM {$source}_tapir WHERE ".$this->construireWhereTaxonMoissonnage()." ". |
"AND lieu_station_longitude BETWEEN ".$this->limitesCarte['ouest']." AND ".$this->limitesCarte['est']." ". |
"AND lieu_station_latitude BETWEEN ".$this->limitesCarte['sud']." AND ".$this->limitesCarte['nord']." ". |
"AND Length(lieu_commune_code_insee)=5 ORDER BY lieu_commune_code_insee, date"; |
$stations = $this->bdd->recupererTous($requete); |
$this->rechercherInfosCommune($stations); |
return $stations; |
} |
private function construireWhereTaxonMoissonnage() { |
$nomRang = $this->obtenirNomRang(); |
$criteres = array(); |
$criteres[] = "nom_scientifique_complet LIKE ".$this->bdd->proteger($this->taxon['nom_sci']."%"); |
if ($this->nomRang == 'espece' || $this->nomRang == 'sous_espece') { |
foreach ($this->taxons as $sousTaxon) { |
$criteres[] = "nom_scientifique_complet LIKE ".$this->bdd->proteger($sousTaxon['nom_sci']."%"); |
} |
} elseif ($this->nomRang == 'famille') { |
foreach ($this->genres as $genre) { |
$criteres[] = "nom_scientifique_complet LIKE ".$this->bdd->proteger($genre['nom_sci']."%"); |
} |
} |
return "(".implode(' OR ',array_unique($criteres)).")"; |
} |
private function rechercherInfosCommune(& $stations) { |
$codesInsee = array(); |
foreach ($stations as $station) { |
$codeInsee = $station['lieu_commune_code_insee']; |
if (substr($codeInsee, 0, 2) == '20') { |
$codeInsee = '2A'.substr($codeInsee, 2); |
$codeInsee2 = '2B'.substr($codeInsee, 2); |
} |
if (!in_array($codeInsee, $codesInsee)) { |
if (substr($codeInsee, 0, 2) == '20') { |
$codesInsee[] = "'$codeInsee2'"; |
} |
$codesInsee[] = "'$codeInsee'"; |
} |
} |
$requete = |
"SELECT insee, nom AS commune, Floor(latitude_degre*10)/10 AS lat, Floor(longitude_degre*10)/10 AS lng ". |
"FROM lion1906_communes_v2008 WHERE insee IN (".implode(',', array_unique($codesInsee)).") ORDER BY insee"; |
$communes = $this->bdd->recupererTous($requete); |
$indexStation = 0; |
foreach ($communes as $commune) { |
$codeInsee = $commune['insee']; |
if (substr($codeInsee, 0, 2) == '2A' || substr($codeInsee, 0, 2) == '2B') { |
$codeInsee = '20'.substr($codeInsee, 2); |
} |
while ($stations[$indexStation]['lieu_commune_code_insee'] < $codeInsee) { |
$indexStation ++; |
} |
if ($stations[$indexStation]['lieu_commune_code_insee'] == $codeInsee) { |
$stations[$indexStation]['lat'] = $commune['lat']; |
$stations[$indexStation]['lng'] = $commune['lng']; |
$stations[$indexStation]['commune'] = $commune['commune']; |
} |
} |
$lat = array(); |
$lng = array(); |
foreach ($stations as $index => $station) { |
if (!isset($station['lat'])) { |
$station['lat'] = -100; |
$station['lng'] = -100; |
} |
$lat[$index] = $station['lat']; |
$lng[$index] = $station['lng']; |
} |
array_multisort($lat, SORT_DESC, $lng, SORT_ASC, $stations); |
} |
} |
?> |