Subversion Repositories eFlore/Projets.eflore-projets

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1062 → Rev 1063

/branches/v5.7-arrayanal/scripts/modules/osm/PolygoneCreateur.php
File deleted
\ No newline at end of file
/branches/v5.7-arrayanal/scripts/modules/osm/PolygoneReparateur.php
File deleted
\ No newline at end of file
/branches/v5.7-arrayanal/scripts/modules/osm/OrdonneurDeChemins.php
File deleted
\ No newline at end of file
/branches/v5.7-arrayanal/scripts/modules/osm/MiseAJour.php
File deleted
\ No newline at end of file
/branches/v5.7-arrayanal/scripts/modules/osm/ParseurOsm.php
File deleted
\ No newline at end of file
/branches/v5.7-arrayanal/scripts/modules/osm/FranceCommunes.php
New file
0,0 → 1,61
<?php
/**
* Création de la table osm_communes.
* /opt/lampp/bin/php cli.php osm -a communes -m manuel
*
*/
class FranceCommunes {
 
private $conteneur;
private $bdd;
private $messages;
private $mode;
 
private $bddOsmNom;
 
public function __construct($conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->bddOsmNom = $this->conteneur->getParametre('bdd_osm_nom');
$this->messages = $this->conteneur->getMessages();
$this->mode = $this->conteneur->getParametre('m');
}
 
public function executer() {
// Lancement de l'action demandée
$cmd = $this->conteneur->getParametre('a');
switch ($cmd) {
case 'cm' :
$this->supprimerTableOsmCommunes();
$this->conteneur->getEfloreCommun()->chargerStructureSql();
$this->creerTableOsmCommunes();
break;
case 'cmCreer' :
$this->creerTableOsmCommunes();
break;
case 'cmSupprimer' :
$this->supprimerTableOsmCommunes();
break;
default :
$this->messages->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
}
 
}
 
private function supprimerTableOsmCommunes() {
$requete = 'DROP TABLE IF EXISTS osm_communes '.
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
 
private function creerTableOsmCommunes() {
$requete = 'INSERT INTO osm_communes '.
"SELECT osm_id, osm_version, osm_timestamp, name, ref_insee, shape, shape_centroid, wikipedia ".
"FROM {$this->bddOsmNom}.multipolygons_ref ".
"WHERE admin_level = 8 ".
"AND (ref_insee IS NOT NULL OR ref_insee != '') ".
"AND CHAR_LENGTH(ref_insee) = 5 ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
}
/branches/v5.7-arrayanal/scripts/modules/osm/ZonesAdmin.php
New file
0,0 → 1,119
<?php
/**
* Création de la table osm_communes.
* /opt/lampp/bin/php cli.php osm -a communes -m manuel
*
*/
class ZonesAdmin {
 
private $conteneur;
private $bdd;
private $messages;
private $mode;
 
private $bddOsmNom;
 
public function __construct($conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->bddOsmNom = $this->conteneur->getParametre('bdd_osm_nom');
$this->messages = $this->conteneur->getMessages();
$this->mode = $this->conteneur->getParametre('m');
}
 
public function executer() {
// Lancement de l'action demandée
$cmd = $this->conteneur->getParametre('a');
switch ($cmd) {
case 'za' :
$this->supprimerTableOsmZonesAdmin();
$this->conteneur->getEfloreCommun()->chargerStructureSql();
$this->creerTableOsmZonesAdmin();
$this->corrigerTableOsmZonesAdmin();
$this->mettreAJourIdZoneGeo();
break;
case 'zaCreer' :
$this->creerTableOsmZonesAdmin();
break;
case 'zaCorriger' :
$this->corrigerTableOsmZonesAdmin();
break;
case 'zaMajIdZG' :
$this->mettreAJourIdZoneGeo();
break;
case 'zaSupprimer' :
$this->supprimerTableOsmZonesAdmin();
break;
default :
$this->messages->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
}
 
}
 
private function supprimerTableOsmZonesAdmin() {
$requete = 'DROP TABLE IF EXISTS osm_zones_admin '.
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
 
private function creerTableOsmZonesAdmin() {
$requete = 'INSERT INTO osm_zones_admin '.
"SELECT if(ref_insee != '' AND admin_level = 8, CONCAT('INSEE-C:',ref_insee), ".
"if(ref_insee != '' AND admin_level = 6, CONCAT('INSEE-D:',ref_insee), ".
"if(ref_insee != '' AND admin_level = 4, CONCAT('INSEE-R:',ref_insee), ".
"if(iso3166_2 != '', CONCAT('ISO-3166-2:',iso3166_2), ".
"if(iso3166_1 != '', CONCAT('ISO-3166-1:',iso3166_1), ".
"CONCAT('OSM-ID:',osm_id)))))), ".
'osm_id, osm_version, osm_timestamp, '.
"if(name_fr != '', name_fr, name), ".
'shape, shape_centroid, Y(shape_centroid), X(shape_centroid), '.
'admin_level, iso3166_1, iso3166_2, ref_insee, ref_nuts, '.
'name, name_fr, name_en, name_es, wikipedia '.
"FROM {$this->bddOsmNom}.multipolygons_ref ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
 
private function corrigerTableOsmZonesAdmin() {
$requete = 'SELECT osm_id, other_tags '.
"FROM {$this->bddOsmNom}.multipolygons_ref ".
"WHERE iso3166_2 IS NULL AND other_tags LIKE '%\"iso3166-2\"%' ".
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recupererTous($requete);
if ($resultat) {
foreach ($resultat as $infos) {
$tags = $this->getTags($infos['other_tags']);
$iso_3166_2 = $this->bdd->proteger($tags['iso3166-2']);
$osm_id = $this->bdd->proteger($infos['osm_id']);
 
$requete = 'UPDATE osm_zones_admin '.
"SET code_iso_3166_2 = $iso_3166_2 ".
"WHERE osm_id = $osm_id ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
}
}
 
private function getTags($tagsInfos) {
$tags = array();
$clesValeurs = explode(',', $tagsInfos);
foreach ($clesValeurs as $cleValeur) {
list($cle, $val) = explode('=>', $cleValeur);
$tags[trim($cle, '"')] = trim($val, '"');
}
return $tags;
}
 
private function mettreAJourIdZoneGeo() {
$requete = 'UPDATE osm_zones_admin '.
"SET id_zone_geo = if(code_insee != '' AND niveau = 8, CONCAT('INSEE-C:',code_insee), ".
"if(code_insee != '' AND niveau = 6, CONCAT('INSEE-D:',code_insee), ".
"if(code_insee != '' AND niveau = 4, CONCAT('INSEE-R:',code_insee), ".
"if(code_iso_3166_2 != '', CONCAT('ISO-3166-2:',code_iso_3166_2), ".
"if(code_iso_3166_1 != '', CONCAT('ISO-3166-1:',code_iso_3166_1), ".
"CONCAT('OSM-ID:',osm_id)))))) ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
}
/branches/v5.7-arrayanal/scripts/modules/osm/config.ini
1,9 → 1,12
; Base de données contenant les infos provenant d'OSM
bdd_osm_nom = "osm"
 
; Ajouter les nouvelles version à la suite dans versions et versionsDonnees.
version = "1.0"
version = "2.0"
dossierSql = "{ref:dossierDonneesEflore}osm/"
 
[fichiers]
structureSql = "osm.sql"
structureSql = "osm_v{ref:version}.sql"
 
[chemins]
structureSql = "{ref:dossierSql}{ref:version}/{ref:fichiers.structureSql}"
/branches/v5.7-arrayanal/scripts/modules/osm/Osm.php
3,35 → 3,8
/**
* Exemple de lancement du script : :
* 1. Création de la base de données :
* /opt/lampp/bin/php cli.php osm -a chargerStructureSql -m manuel -v 3
* /opt/lampp/bin/php cli.php osm -a communes -m manuel -v 3
*
* 2. Analyse du fichir OSM :
* /opt/lampp/bin/php cli.php osm -a analyser -f "../donnees/osm/fr_communes_new.osm" -m manuel -v 3
*
* 3. Traitement de l'ordre :
* /opt/lampp/bin/php cli.php osm -a ordre -m manuel -v 3
*
* 4. Remplissage des polygones :
* /opt/lampp/bin/php cli.php osm -a polygone -m manuel -v 3
*
* Définition des centroïdes pour les polygones déjà complets:
* /opt/lampp/bin/php cli.php osm -a centre -m manuel -v 3
*
* 5. Remise de l'ordre à zéro :
* /opt/lampp/bin/php cli.php osm -a zero -m manuel -v 3
*
* 6. Traitement de l'ordre des polygones incomplets :
* /opt/lampp/bin/php cli.php osm -a ordonnerPolygoneInc -m manuel -v 3
*
* 7. Remplissage des polygones incomplets :
* /opt/lampp/bin/php cli.php osm -a remplirPolygoneInc -m manuel -v 3
*
* 8. Renommage des polygones incomplets :
* /opt/lampp/bin/php cli.php osm -a renommer -m manuel -v 3
*
* 9. Définition des centroïdes :
* /opt/lampp/bin/php cli.php osm -a centre -m manuel -v 3
*
* @category php 5.4
* @package DEL
* @subpackage Scripts
40,13 → 13,11
* @license CeCILL v2 http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt
* @license GNU-GPL http://www.gnu.org/licenses/gpl.html
*/
// TODO : Améliorer la gestion de l'ordre des chemins pour éviter de prendre en compte des chemins inexistants
class Osm extends EfloreScript {
 
const PROJET_NOM = 'osm';
 
protected $parametres_autorises = array(
'-f' => array(true, null, 'Chemin du fichier osm à analyser'),
'-m' => array(false, 'auto', 'Mode «auto» ou «manuel». En manuel, les compteurs dans les boucles sont affichés.'));
 
public function executer() {
59,30 → 30,20
case 'chargerStructureSql' :
$this->chargerStructureSql();
break;
case 'analyser' :
$script = $this->chargerClasse('ParseurOsm');
case 'cm' :
case 'cmCreer' :
case 'cmSupprimer' :
$script = $this->chargerClasse('FranceCommunes');
$script->executer();
break;
case 'ordre' :
$script = $this->chargerClasse('OrdonneurDeChemins');
case 'za' :
case 'zaCreer' :
case 'zaCorriger' :
case 'zaMajIdZG' :
case 'zaSupprimer' :
$script = $this->chargerClasse('ZonesAdmin');
$script->executer();
break;
case 'polygone' :
case 'centre' :
case 'zero' :
$script = $this->chargerClasse('PolygoneCreateur');
$script->executer();
break;
case 'ordonnerPolygoneInc' :
case 'remplirPolygoneInc' :
case 'renommer' :
$script = $this->chargerClasse('PolygoneReparateur');
$script->executer();
break;
case 'maj' :
$script = $this->chargerClasse('MiseAJour');
$script->executer();
break;
default :
throw new Exception("Erreur : la commande '$cmd' n'existe pas!");
}
/branches/v5.7-arrayanal/services/modules/0.1/osm/ZoneAdmin.php
New file
0,0 → 1,150
<?php
// declare(encoding='UTF-8');
/**
* Classe permettant d'obtenir le nom et les codes d'une zone administrative à partir de ces coordonnées (latitude et longitude).
* La latitude et longitude doivent être exprimée par un nombre décimal.
* Ce service fonctionne uniquement pour les zones administratives dont les contours ont été tracés dans OpenStreetMap.
* Source des données : OpenStreetMap <http://wiki.openstreetmap.org>
* Tag:boundary=administrative : <http://wiki.openstreetmap.org/wiki/Tag:boundary%3Dadministrative>
* Paramètres du service :
* - lat : latitude
* - lon : longitude
* Exemple :
* http://localhost/service-test:eflore:0.1/osm/nom-commune?lon=3.83619&lat=44.74231
*
* @category php 5.2
* @package eFlore
* @subpackage Services
* @author Jean-Pascal MILCENT <jpm@tela-botanica.org>
* @author Mohcen BENMOUNAH <mohcen@tela-botanica.org>
* @copyright Copyright (c) 2010, Tela Botanica (accueil@tela-botanica.org)
* @license CECILL v2 <http://www.cecill.info/licences/Licence_CeCILL_V2-fr.txt>
* @license GNU-GPL <http://www.gnu.org/licenses/gpl.html>
*/
class ZoneADmin {
 
const PATTERN_LAT = '/^[0-9]+(?:[.][0-9]+|)$/';
const PATTERN_LON = '/^[-]?[0-9]+(?:[.][0-9]+|)$/';
const MIME_JSON = 'application/json';
 
private $parametres = array();
private $bdd = null;
 
private $lat = null;
private $lon = null;
 
public function __construct(Bdd $bdd) {
$this->bdd = $bdd;
}
 
public function consulter($ressources, $parametres) {
$this->parametres = $parametres;
$this->verifierParametres();
$this->lat = $this->parametres['lat'];
$this->lon = $this->parametres['lon'];
 
$zoneTrouveeInfos = $this->localiserPointLatLon();
$corps = $this->formaterResultats($zoneTrouveeInfos);
 
$resultat = new ResultatService();
$resultat->mime = self::MIME_JSON;
$resultat->corps = $corps;
return $resultat;
}
 
private function verifierParametres() {
extract($this->parametres);
$messages = array();
if (! array_key_exists('lat', $this->parametres)) {
$messages[] = "Vous devez indiquer une latitude en degré décimal à l'aide du paramètres d'url : lat";
} else if (!preg_match(self::PATTERN_LAT, $lat)) {
$messages[] = "La valeur de latitude doit être un nombre décimal positif dont le séparateur décimal est un point. Ex. : 44 ou 43.03";
}
if (! array_key_exists('lon', $this->parametres)) {
$messages[] = "Vous devez indiquer une longitude en degré décimal à l'aide du paramètres d'url : lon";
} else if (!preg_match(self::PATTERN_LON, $lon)) {
$messages[] = "La valeur de longitude doit être un nombre décimal dont le séparateur décimal est un point. Ex. : -4.03 ou 3.256";
}
if (count($messages) != 0) {
$message = implode('<br />', $messages);
$code = RestServeur::HTTP_CODE_MAUVAISE_REQUETE;
throw new Exception($message, $code);
}
}
 
private function formaterResultats($zonesTrouveesInfos) {
$retour = array();
foreach ($zonesTrouveesInfos as $infos) {
$donnees = array();
foreach ($infos as $champ => $valeur) {
if ($valeur != '' && $champ != 'niveau') {
if ($champ == 'wikipedia') {
$valeur = $this->formaterUrlWikipedia($valeur);
}
$donnees[$champ] = $valeur;
}
}
$retour[$infos['niveau']] = $donnees;
}
ksort($retour);
return $retour;
}
 
private function localiserPointLatLon() {
$osmIdsInClause = $this->getOsmIdsDesCentresAProximites();
 
$requete = 'SELECT id_zone_geo AS codeZoneGeo, intitule, code_iso_3166_1 AS codeIso31661, '.
'code_iso_3166_2 AS codeIso31662, code_insee AS codeInsee, code_nuts as codeNuts, '.
'nom_en AS nomEn, nom_es AS nomEs, wikipedia, niveau '.
'FROM osm_zones_admin '.
"WHERE st_within(GEOMFROMTEXT('POINT($this->lon $this->lat)'), polygone) = 1 ".
"AND osm_id IN ($osmIdsInClause) ".
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recupererTous($requete);
if ($resultat === false) {
$msgTpl = "Service '%s' : aucune zone correspondant aux coordonnées : %s, %s.";
$msg = sprintf($msgTpl, get_class($this), $this->lat, $this->lon);
throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
return $resultat;
}
 
private function getOsmIdsDesCentresAProximites() {
$requete = $this->construireRequeteUnion();
$resultats = $this->bdd->recupererTous($requete);
if ($resultats === false) {
$msgTpl = "Service '%s' : aucun centroïde correspondant aux coordonnées : %s, %s.";
$msg = sprintf($msgTpl, get_class($this), $this->lat, $this->lon);
throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
$osmIds = array();
foreach ($resultats as $info) {
$osmIds[] = $info['osm_id'];
}
$osmIdsInClause = implode(',', $this->bdd->proteger($osmIds));
return $osmIdsInClause;
}
 
private function construireRequeteUnion() {
$requeteTpl = 'SELECT osm_id, '.
"(($this->lon - X(centre)) * ($this->lon -X(centre)) + ($this->lat - Y(centre)) * ($this->lat - Y(centre))) AS distance ".
'FROM osm_zones_admin '.
'WHERE niveau = %s '.
'ORDER BY distance ASC '.
"LIMIT %s ";
$niveaux = array(2,3,4,5,6,7,8);
$requetesAUnir = array();
foreach ($niveaux as $niveau) {
$requetesAUnir[] = sprintf($requeteTpl, $niveau, ($niveau * 2));
}
$requete = '('.implode(') UNION (', $requetesAUnir).') -- '.__FILE__.' : '.__LINE__;
return $requete;
}
 
private function formaterUrlWikipedia($infoWikipedia) {
list($lang, $page) = explode(':', $infoWikipedia);
$pageEncode = rawurlencode($page);
$urlTpl = 'https://%s.wikipedia.org/wiki/%s';
return sprintf($urlTpl, $lang, $pageEncode);
}
}
/branches/v5.7-arrayanal/services/modules/0.1/osm/NomCommune.php
4,12 → 4,13
* Classe permettant d'obtenir le nom et le code INSEE d'une commune à partir de ces coordonnées (latitude et longitude).
* La latitude et longitude doivent être exprimée par un nombre décimal.
* Ce service fonctionne uniquement pour les communes de France métropolitaine (Corse comprise) dont les contours ont été tracés dans OpenStreetMap.
* Source des données : OpenStreetMap http://wiki.openstreetmap.org (Projet France limites administratives : http://wiki.openstreetmap.org/wiki/WikiProject_France/Limites_administratives)
* Source des données : OpenStreetMap http://wiki.openstreetmap.org
* Projet France limites administratives : http://wiki.openstreetmap.org/wiki/WikiProject_France/Limites_administratives
* Paramètres du service :
* - lat : latitude
* - lon : longitude
* Exemple :
* http://localhost/cartoOSM/services/0.1/nom-commune?lat=44.71546&lon=3.84216
* http://localhost/service-test:eflore:0.1/osm/nom-commune?lon=3.83619&lat=44.74231
*
* @category php 5.2
* @package carto-osm
28,13 → 29,14
const LAT_MIN = 41.316667;
const LON_MAX = 9.513333;
const LON_MIN = -5.140278;
const NBRE_COMMUNE_PAR_DEFAUT = 10;
const NBRE_COMMUNE_MAX = 100;
const MIME_JSON = 'application/json';
 
private $parametres = array();
private $bdd = null;
 
private $lat = null;
private $lon = null;
 
public function __construct(Bdd $bdd) {
$this->bdd = $bdd;
}
42,9 → 44,12
public function consulter($ressources, $parametres) {
$this->parametres = $parametres;
$this->verifierParametres();
$this->lat = $this->parametres['lat'];
$this->lon = $this->parametres['lon'];
 
$nomINSEEs = $this->trouverCommunesProches();
$corps = $this->formaterResultats($nomINSEEs);
$communesProches = $this->trouverCommunesProches();
$communeTrouveeInfos = $this->localiserPointLatLon($communesProches);
$corps = $this->formaterResultats($communeTrouveeInfos);
 
$resultat = new ResultatService();
$resultat->mime = self::MIME_JSON;
60,9 → 65,9
} else if (!preg_match(self::PATTERN_LAT, $lat)) {
$messages[] = "La valeur de latitude doit être un nombre décimal positif dont le séparateur décimal est un point. Ex. : 44 ou 43.03";
} else if ($lat > self::LAT_MAX) {
$messages[] = "La valeur de latitude indiquée est supérieure à {self::LAT_MAX} qui est le point le plus au Nord de la France métropolitaine.";
$messages[] = "La valeur de latitude indiquée est supérieure à {".self::LAT_MAX."} qui est le point le plus au Nord de la France métropolitaine.";
} else if ($lat < self::LAT_MIN) {
$messages[] = "La valeur de latitude indiquée est infèrieure à {self::LAT_MIN} qui est le point le plus au Sud de la France métropolitaine.";
$messages[] = "La valeur de latitude indiquée est infèrieure à {".self::LAT_MIN."} qui est le point le plus au Sud de la France métropolitaine.";
}
if (! array_key_exists('lon', $this->parametres)) {
$messages[] = "Vous devez indiquer une longitude en degré décimal à l'aide du paramètres d'url : lon";
69,9 → 74,9
} else if (!preg_match(self::PATTERN_LON, $lon)) {
$messages[] = "La valeur de longitude doit être un nombre décimal dont le séparateur décimal est un point. Ex. : -4.03 ou 3.256";
} else if ($lon > self::LON_MAX) {
$messages[] = "La valeur de longitude indiquée est supérieure à {self::LON_MAX} qui est le point le plus à l'Est de la France métropolitaine.";
$messages[] = "La valeur de longitude indiquée est supérieure à {".self::LON_MAX."} qui est le point le plus à l'Est de la France métropolitaine.";
} else if ($lon < self::LON_MIN) {
$messages[] = "La valeur de longitude indiquée est infèrieure à {self::LON_MIN} qui est le point le plus à l'Ouest de la France métropolitaine.";
$messages[] = "La valeur de longitude indiquée est infèrieure à {".self::LON_MIN."} qui est le point le plus à l'Ouest de la France métropolitaine.";
}
if (count($messages) != 0) {
$message = implode('<br />', $messages);
83,118 → 88,58
/**
* requête qui récupère les 20 communes les plus proches du point recherché
* La distance(AB = \sqrt{(x_B-x_A)^2 + (y_B-y_A)^2}) est calculée sans la racine
* (calcul en plus qui change pas le résultat).
* (calcul en plus qui change pas le résultat). La distance n'est donc pas juste mais permet de récupérer
* le bon ordre.
*/
private function trouverCommunesProches() {
$lat = $this->parametres['lat'];
$lon = $this->parametres['lon'];
$requete = 'SELECT '.
" (({$lat} - X(centre)) * ({$lat} -X(centre)) + ({$lon} - Y(centre)) * ({$lon} - Y(centre))) AS distance, ".
" code_insee, nom, ASTEXT(polygon) AS poly ".
$requete = 'SELECT id_osm, '.
"(({$this->lon} - X(centre)) * ({$this->lon} -X(centre)) + ({$this->lat} - Y(centre)) * ({$this->lat} - Y(centre))) AS distance ".
'FROM osm_communes '.
'WHERE note = "Polygone complet" '.
'ORDER BY distance '.
'LIMIT 20';
'ORDER BY distance ASC '.
'LIMIT 20 '.
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recupererTous($requete);
 
if ($resultat == false) {
$message = "Le service '".get_class($this)."' n'a trouvé aucune commune dont le centroïde correspond aux coordonnées : {$this->parametres['lat']}, {$this->parametres['lon']}.";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
$msgTpl = "Service '%s' : aucune commune dont le centroïde correspond aux coordonnées : %s, %s.";
$msg = sprintf($msgTpl, get_class($this), $this->lat, $this->lon);
throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
return $resultat;
}
 
private function formaterResultats($nomINSEEs) {
$communeTrouvee = null;
foreach ($nomINSEEs as $nomINSEE) {
$resultat = $this->localiserPointLatLon($nomINSEE['poly']);
if ($resultat == 1) {
$communeTrouvee = array('nom' => $nomINSEE['nom'], 'codeINSEE' => $nomINSEE['code_insee']);
break;
}
}
if (is_null($communeTrouvee)) {
$message = "Le service '".get_class($this)."' n'a trouvé aucune commune correspondant aux coordonnées : {$this->parametres['lat']}, {$this->parametres['lon']}.";
$code = RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE;
throw new Exception($message, $code);
}
return $communeTrouvee;
private function formaterResultats($communeTrouveeInfos) {
return array(
'nom' => $communeTrouveeInfos['nom'],
'codeINSEE' => $communeTrouveeInfos['code_insee'],
'wikipedia' => $this->formaterUrlWikipedia($communeTrouveeInfos['wikipedia'])
);
}
 
private function localiserPointLatLon($multiPolygone) {
$lat = $this->parametres['lat'];
$lon = $this->parametres['lon'];
$requeteMBR = "SELECT MBRWithin(GEOMFROMTEXT('POINT($lat $lon)'), GEOMFROMTEXT('$multiPolygone'))";
$p = array_values($this->bdd->recuperer($requeteMBR));
 
$counter = 0;
if ($p[0] != 1) {
return 0;
} else {
$x = $lat; //Le point latitude recherché
$y = $lon; //Le point longitude recherché
$str = $this->nettoyerChaineMultipolygone($multiPolygone); // Le multipolygone de la commune
$pb = 0;
$pe = strpos($str, ','); //définition de la position de la première virgule
$xy = substr($str, $pb, $pe - $pb); //extraire X Y d'un point séparé par des virgules
$p = strpos($xy, ' '); //position espace dans un point
$p1x = substr($xy, 0, $p ); //récupère X du point
$p1y = substr($xy, $p + 1 ); //récupère Y du point
$str = $str.$xy; // ajouter le premier point du polygone à la fin du polygone
while ($pe > 0) {
$xy = substr($str, $pb, $pe - $pb ); //extraire le point GPS
$p = strpos($xy, ' '); // trouver la position de l'espace entre les deux points X et Y
$p2x = substr($xy,0, $p ); // extraire le point X
$p2y = substr($xy, $p + 1 ); // extraire le point Y
if ($p1y < $p2y) {
$m = $p1y;
} else {
$m = $p2y;
}
if ($y > $m) {
if ($p1y > $p2y) {
$m = $p1y;
} else {
$m = $p2y;
}
if ($y <= $m) {
if ($p1x > $p2x) {
$m = $p1x;
} else {
$m = $p2x;
}
if ($y <= $m) {
if ($p1x > $p2x) {
$m = $p1x;
} else {
$m = $p2x;
}
if ($x <= $m) {
if ($p1y != $p2y) {
$xinters = ($y - $p1y) * ($p2x - $p1x) / ($p2y - $p1y) + $p1x;
}
if (($p1x = $p2x) || ($x <= $xinters )) {
$counter++;
}
}
}
}
}
$p1x = $p2x;
$p1y = $p2y;
$pb = $pe + 1;
$pe = strpos($str, ',', $pb);
}
return $counter % 2;
private function localiserPointLatLon($communesProches) {
$zonesIds = array();
foreach ($communesProches as $commune) {
$zonesIds[] = $commune['id_osm'];
}
$idsOsmClauseIn = implode(',', $this->bdd->proteger($zonesIds));
$requete = "SELECT id_osm, code_insee, nom, wikipedia ".
'FROM osm_communes '.
"WHERE st_within(GEOMFROMTEXT('POINT($this->lon $this->lat)'), polygone) = 1 ".
"AND id_osm IN ($idsOsmClauseIn) ".
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recuperer($requete);
if ($resultat === false) {
$msgTpl = "Service '%s' : aucune commune correspondant aux coordonnées : %s, %s.";
$msg = sprintf($msgTpl, get_class($this), $this->lat, $this->lon);
throw new Exception($msg, RestServeur::HTTP_CODE_RESSOURCE_INTROUVABLE);
}
return $resultat;
}
 
private function nettoyerChaineMultipolygone($chaine) {
$chaine = str_replace('MULTIPOLYGON(((', '', $chaine);
$chaine = str_replace(')))', '', $chaine);
$chaine .= ',';
return $chaine;
private function formaterUrlWikipedia($infoWikipedia) {
list($lang, $page) = explode(':', $infoWikipedia);
$pageEncode = rawurlencode($page);
$urlTpl = 'https://%s.wikipedia.org/wiki/%s';
return sprintf($urlTpl, $lang, $pageEncode);
}
}
?>
}
/branches/v5.7-arrayanal/services/configurations/config_osm.ini
13,4 → 13,4
url_service="{ref:url_base}service:eflore:0.1/osm"
 
; Noms des services disponibles pour ce projet
servicesDispo = "meta-donnees,aide,nom-commune"
servicesDispo = "meta-donnees,aide,nom-commune,zone-admin"
/branches/v5.7-arrayanal
Property changes:
Modified: svn:mergeinfo
Merged /trunk:r1054-1061