Subversion Repositories eFlore/Projets.eflore-projets

Compare Revisions

Ignore whitespace Rev 1056 → Rev 1055

/trunk/services/modules/0.1/osm/ZoneAdmin.php
File deleted
\ No newline at end of file
/trunk/services/modules/0.1/osm/NomCommune.php
4,13 → 4,12
* 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/service-test:eflore:0.1/osm/nom-commune?lon=3.83619&lat=44.74231
* http://localhost/cartoOSM/services/0.1/nom-commune?lat=44.71546&lon=3.84216
*
* @category php 5.2
* @package carto-osm
29,14 → 28,13
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;
}
44,12 → 42,9
public function consulter($ressources, $parametres) {
$this->parametres = $parametres;
$this->verifierParametres();
$this->lat = $this->parametres['lat'];
$this->lon = $this->parametres['lon'];
 
$communesProches = $this->trouverCommunesProches();
$communeTrouveeInfos = $this->localiserPointLatLon($communesProches);
$corps = $this->formaterResultats($communeTrouveeInfos);
$nomINSEEs = $this->trouverCommunesProches();
$corps = $this->formaterResultats($nomINSEEs);
 
$resultat = new ResultatService();
$resultat->mime = self::MIME_JSON;
65,9 → 60,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";
74,9 → 69,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);
88,58 → 83,118
/**
* 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). La distance n'est donc pas juste mais permet de récupérer
* le bon ordre.
* (calcul en plus qui change pas le résultat).
*/
private function trouverCommunesProches() {
$requete = 'SELECT id_osm, '.
"(({$this->lon} - X(centre)) * ({$this->lon} -X(centre)) + ({$this->lat} - Y(centre)) * ({$this->lat} - Y(centre))) AS distance ".
$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 ".
'FROM osm_communes '.
'ORDER BY distance ASC '.
'LIMIT 20 '.
' -- '.__FILE__.' : '.__LINE__;
'WHERE note = "Polygone complet" '.
'ORDER BY distance '.
'LIMIT 20';
$resultat = $this->bdd->recupererTous($requete);
 
if ($resultat == false) {
$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);
$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);
}
return $resultat;
}
 
private function formaterResultats($communeTrouveeInfos) {
return array(
'nom' => $communeTrouveeInfos['nom'],
'codeINSEE' => $communeTrouveeInfos['code_insee'],
'wikipedia' => $this->formaterUrlWikipedia($communeTrouveeInfos['wikipedia'])
);
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 localiserPointLatLon($communesProches) {
$zonesIds = array();
foreach ($communesProches as $commune) {
$zonesIds[] = $commune['id_osm'];
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;
}
$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 formaterUrlWikipedia($infoWikipedia) {
list($lang, $page) = explode(':', $infoWikipedia);
$pageEncode = rawurlencode($page);
$urlTpl = 'https://%s.wikipedia.org/wiki/%s';
return sprintf($urlTpl, $lang, $pageEncode);
private function nettoyerChaineMultipolygone($chaine) {
$chaine = str_replace('MULTIPOLYGON(((', '', $chaine);
$chaine = str_replace(')))', '', $chaine);
$chaine .= ',';
return $chaine;
}
}
}
?>
/trunk/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,zone-admin"
servicesDispo = "meta-donnees,aide,nom-commune"
/trunk/scripts/modules/osm/FranceCommunes.php
File deleted
\ No newline at end of file
/trunk/scripts/modules/osm/ZonesAdmin.php
File deleted
\ No newline at end of file
/trunk/scripts/modules/osm/config.ini
1,12 → 1,9
; 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 = "2.0"
version = "1.0"
dossierSql = "{ref:dossierDonneesEflore}osm/"
 
[fichiers]
structureSql = "osm_v{ref:version}.sql"
structureSql = "osm.sql"
 
[chemins]
structureSql = "{ref:dossierSql}{ref:version}/{ref:fichiers.structureSql}"
/trunk/scripts/modules/osm/Osm.php
3,8 → 3,35
/**
* Exemple de lancement du script : :
* 1. Création de la base de données :
* /opt/lampp/bin/php cli.php osm -a communes -m manuel -v 3
* /opt/lampp/bin/php cli.php osm -a chargerStructureSql -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
13,11 → 40,13
* @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() {
30,18 → 59,30
case 'chargerStructureSql' :
$this->chargerStructureSql();
break;
case 'cm' :
case 'cmSupprimer' :
$script = $this->chargerClasse('FranceCommunes');
case 'analyser' :
$script = $this->chargerClasse('ParseurOsm');
$script->executer();
break;
case 'za' :
case 'zaCorriger' :
case 'zaMajIdZG' :
case 'zaSupprimer' :
$script = $this->chargerClasse('ZonesAdmin');
case 'ordre' :
$script = $this->chargerClasse('OrdonneurDeChemins');
$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!");
}