Subversion Repositories eFlore/Projets.eflore-projets

Compare Revisions

No changes between revisions

Ignore whitespace Rev 1045 → Rev 1046

/trunk/scripts/modules/osm/carto-osm-maj.sh
File deleted
\ No newline at end of file
/trunk/scripts/modules/osm/carto-osm-cron
File deleted
/trunk/scripts/modules/osm/config.cfg
File deleted
\ No newline at end of file
/trunk/scripts/modules/osm/carto-osm
File deleted
/trunk/scripts/modules/osm/config.defaut.cfg
File deleted
\ No newline at end of file
/trunk/scripts/modules/osm/PolygoneCreateur.php
New file
0,0 → 1,144
<?php
/**
* Traitement de l'ordre :
*
* Fonction qui rajoute l'ordre et le sens de chaque way d'une relation dans la table `osm_relation_a_chemins`
*
* Exemple de lancement du script :
* /opt/lampp/bin/php -d memory_limit=8000M cli.php osm -a ordre -m manuel
*
*/
class PolygoneCreateur {
private $conteneur;
private $bdd;
private $messages;
private $mode;
 
public function __construct($conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->messages = $this->conteneur->getMessages();
$this->mode = $this->conteneur->getParametre('m');
}
 
/**
* Fonction qui parcourt tous les ways les noeuds de chaque relation en prenant en considération l'ordre et
* le sens de chaque ways concaténés ensemble (séparés par des virgules). Update du champ polygone de chaque
* relation dans la table `osm_relations`
*/
public function executer() {
// Lancement de l'action demandée
$cmd = $this->conteneur->getParametre('a');
switch ($cmd) {
case 'polygone' :
$this->genererPolygones();
break;
case 'centre' :
$this->mettreAJourCentroide();
break;
case 'zero' :
$this->remettreOrdreAZero();
break;
default :
$msgTpl = "Erreur : la commande '%s' n'est pas prise en compte par la classe %s !";
$msg = sprintf($msgTpl, $cmd, get_class($this));
throw new Exception($msg);
}
print "\n";// Pour ramener à la ligne en fin de script
}
 
private function genererPolygones() {
$relations = $this->getRelations();
foreach ($relations as $relation) {
$chemins = $this->getChemins($relation['id_relation']);
$noeuds = array();
foreach ($chemins as $chemin) {
$noeuds = array_merge($noeuds, $this->getNoeuds($chemin['id_chemin'], $chemin['sens']));
}
$this->creerPolygone($relation, $noeuds);
 
if ($this->mode == 'manuel') {
$this->messages->afficherAvancement("Création du polygone pour la relation : ", 1);
}
}
}
 
private function getRelations() {
$requete = 'SELECT id_relation, nom, code_insee '.
'FROM osm_relations '.
' -- '.__FILE__.' : '.__LINE__;
$relations = $this->bdd->recupererTous($requete);
return $relations;
}
 
private function getChemins($idRelation) {
$requete = 'SELECT id_chemin, sens '.
'FROM osm_relation_a_chemins '.
"WHERE id_relation = $idRelation ".
'ORDER BY ordre '.
' -- '.__FILE__.' : '.__LINE__;
$chemins = $this->bdd->recupererTous($requete);
return $chemins;
}
 
private function getNoeuds($idChemin, $sens) {
$tri = ($sens == 'directe') ? 'ASC' : 'DESC';
$requete = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '.
'FROM osm_chemin_a_noeuds AS WN '.
' INNER JOIN osm_noeuds AS NLL ON (WN.id_noeud = NLL.id_noeud) '.
"WHERE WN.id_chemin = $idChemin ".
"ORDER BY WN.ordre $tri ".
' -- '.__FILE__.' : '.__LINE__;
$noeuds = $this->bdd->recupererTous($requete);
$latLng = array();
foreach ($noeuds as $noeud) {
$latLng[] = $noeud['lat'].' '.$noeud['long'];
}
return $latLng;
}
 
private function creerPolygone($relation, $noeuds) {
$polygone = implode(', ', $noeuds);
$idRelation = $relation['id_relation'];
$nomCommuneP = $this->bdd->proteger($relation['nom']);
$InseeP = $this->bdd->proteger($relation['code_insee']);
$note = ($noeuds[0] == $noeuds[count($noeuds) - 1]) ? 'Polygone complet' : 'Polygone incomplet';
 
$requete = 'REPLACE INTO osm_communes (id_relation, nom, code_insee, polygone, notes ) '.
"VALUES ($idRelation, $nomCommuneP, $InseeP, ".
"POLYFROMTEXT('MULTIPOLYGON ((($polygone)))'), '$note') ".
' -- '.__FILE__.' : '.__LINE__;
unset($polygone);
 
$this->bdd->requeter($requete);
}
 
/**
* Pour chaque commune, renseigne le champe "centre" avec un point centroïde du polygone (si non null).
*/
private function mettreAJourCentroide() {
$requete = 'UPDATE osm_communes '.
'SET centre = CENTROID(polygone) '.
"WHERE polygone IS NOT NULL ".
' -- '.__FILE__.' : '.__LINE__;
$retour = $this->bdd->requeter($requete);
$this->messages->traiterInfo("Nombre de centroïde mis à jour : ".$retour->rowCount());
}
 
/**
* Pour chaque commune, remet à zéro l'ordre des chemins si le polygone est incomplet.
*/
private function remettreOrdreAZero() {
$sousRequeteRelations = 'SELECT DISTINCT id_relation '.
'FROM osm_communes '.
"WHERE notes = 'Polygone incomplet' ";
 
$requete = 'UPDATE osm_relation_a_chemins '.
'SET ordre = NULL '.
"WHERE id_relation IN ($sousRequeteRelations) ".
' -- '.__FILE__.' : '.__LINE__;
$retour = $this->bdd->requeter($requete);
echo $requete;
$this->messages->traiterInfo("Nombre de chemins remis à zéro : ".$retour->rowCount());
}
}
/trunk/scripts/modules/osm/PolygoneReparateur.php
New file
0,0 → 1,300
<?php
/**
* Réparation des polygones incomplets :
*
* Exemple de lancement du script :
* /opt/lampp/bin/php -d memory_limit=8000M cli.php osm -a ordonnerPolygoneInc -m manuel -v 3
*
* /opt/lampp/bin/php -d memory_limit=8000M cli.php osm -a remplirPolygoneInc -m manuel -v 3
*
* /opt/lampp/bin/php -d memory_limit=8000M cli.php osm -a renommer -m manuel -v 3
*
*/
class PolygoneReparateur {
private $conteneur;
private $bdd;
private $messages;
private $mode;
 
public function __construct($conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->messages = $this->conteneur->getMessages();
$this->mode = $this->conteneur->getParametre('m');
}
 
/**
* Fonction qui parcourt tous les ways les noeuds de chaque relation en prenant en considération l'ordre et
* le sens de chaque ways concaténés ensemble (séparés par des virgules). Update du champ polygone de chaque
* relation dans la table `osm_relations`
*/
public function executer() {
// Lancement de l'action demandée
$cmd = $this->conteneur->getParametre('a');
switch ($cmd) {
case 'ordonnerPolygoneInc' :
$this->ordonnerRelationsAuPolygoneIncomplet();
break;
case 'remplirPolygoneInc' :
$this->remplirRelationsAuPolygoneIncomplet();
break;
case 'renommer' :
$this->renommerEnPolygoneIncomplet();
break;
default :
$msgTpl = "Erreur : la commande '%s' n'est pas prise en compte par la classe %s !";
$msg = sprintf($msgTpl, $cmd, get_class($this));
throw new Exception($msg);
}
print "\n";// Pour ramener à la ligne en fin de script
}
 
/**
* Fonction qui récupère les relations des polygones incomplets et appelle pour chaque relation la fonction
* ordonnerPolygoneIncomplet($ordre,$tour,$idRelation,$nombrePolygone)
*/
private function ordonnerRelationsAuPolygoneIncomplet() {
$relations = $this->getRelationsAuPolygoneIncomplet();
foreach ($relations as $relation) {
$idRelation = $relation['id_relation'];
$this->ordonnerCheminsMultiPolygone($idRelation);
 
if ($this->mode == 'manuel') {
$this->messages->afficherAvancement("Réparation du polygone incomplet : ", 1);
}
}
}
 
/**
* Fonction récursive qui exécute la même tâche que la fonction ordonnerWays() pour chaque polygone d'un
* multipolygone et remplie le champ NbPoly dans la table `osm_relation_a_chemins` qui correspond au nombre de polygone fermé
* dans le multipolygone
*/
private function ordonnerCheminsMultiPolygone($idRelation, $numPolygone = 1, $ordre = 1, $tour = 1) {
$chemins = $this->getChemins($idRelation);
$nbreCheminsTotal = count($chemins);
 
// premier élément du tableau
$idPremierChemin = $chemins[0]['id_chemin'];
$idChemin = $idPremierChemin;
 
$this->mettreAJourChemin($idRelation, $idPremierChemin, $ordre, 'directe', $numPolygone);
//selection dernier noeud
$nodes = $this->getNoeuds($idPremierChemin);
$nombreNodes = count($nodes);
$premierNoeud = $nodes[0]['id_noeud'];
$dernierNoeud = $nodes[$nombreNodes - 1]['id_noeud'];
$noeudActuel = $dernierNoeud;
 
//Condition pour laquelle la boucle while continue à tourner; tant que le premier noeud du polygone n'est
//égale au dernier et tant qu'il reste des ways à gérer
while (($premierNoeud != $noeudActuel) && (($ordre % 1000) < $nbreCheminsTotal)) {
//select le way qui possède le dernier noeud du précédent way et écarter l'actuel
$ordre++;
 
$chemins = $this->getCheminsAOrdonner($idRelation, $idChemin, $noeudActuel);
if (isset($chemins[0])) {
$idChemin = $chemins[0]['id_chemin'];
$nodes = $this->getNoeuds($idChemin);
$nombreNodes = count($nodes);
if (strcmp($nodes[0]['id_noeud'], $noeudActuel ) == 0) {
$sens = 'directe';
$noeudActuel = $nodes[$nombreNodes-1]['id_noeud'];
} else {
$sens = 'indirecte';
$noeudActuel = $nodes[0]['id_noeud'];
}
$this->mettreAJourChemin($idRelation, $idChemin, $ordre, $sens, $numPolygone);
}
}
$ordre = 1000 * $tour; //différencier chaque polygone: pour chaque polygone on a un multiple de mille
if ($this->getNombreChemins($idRelation) != 0) {
//appelle de la méthode récursivement
$this->ordonnerCheminsMultiPolygone($idRelation, ++$numPolygone, $ordre, ++$tour);
}
}
 
private function getRelationsAuPolygoneIncomplet() {
$requete = 'SELECT id_relation '.
'FROM osm_communes '.
"WHERE notes = 'Polygone incomplet' ".
' -- '.__FILE__.' : '.__LINE__;
$relations = $this->bdd->recupererTous($requete);
return $relations;
}
 
private function getChemins($idRelation) {
$requete = 'SELECT id_chemin '.
'FROM osm_relation_a_chemins '.
"WHERE id_relation = $idRelation ".
"AND ordre IS NULL ".
' -- '.__FILE__.' : '.__LINE__;
$chemins = $this->bdd->recupererTous($requete);
return $chemins;
}
/**
* Select des ways qui n'ont pas été ordonnés: on obtient à chaque itération les ways qui restent à ordonner
*/
private function getCheminsAOrdonner($idRelation, $idChemin, $idNoeud) {
$requete = 'SELECT cn.id_chemin '.
'FROM osm_relation_a_chemins AS rc '.
' INNER JOIN osm_chemin_a_noeuds AS cn ON (rc.id_chemin = cn.id_chemin) '.
"WHERE cn.id_noeud = $idNoeud ".
"AND cn.id_chemin != $idChemin ".
"AND rc.id_relation = $idRelation ".
"AND rc.ordre IS NULL ".
' -- '.__FILE__.' : '.__LINE__;
$chemins = $this->bdd->recupererTous($requete);
return $chemins;
}
 
private function getNoeuds($idChemin) {
$requete = 'SELECT id_noeud '.
'FROM osm_chemin_a_noeuds '.
"WHERE id_chemin = $idChemin ".
'ORDER BY ordre '.
' -- '.__FILE__.' : '.__LINE__;
$noeuds = $this->bdd->recupererTous($requete);
return $noeuds;
}
 
private function getNombreChemins($idRelation) {
$requete = 'SELECT COUNT(id_chemin) AS nbre '.
'FROM osm_relation_a_chemins '.
"WHERE id_relation = $idRelation ".
'AND ordre = 0 '.
' -- '.__FILE__.' : '.__LINE__;
$infos = $this->bdd->recuperer($requete);
return $infos['nbre'];
}
 
private function mettreAJourChemin($idRelation, $idChemin, $ordre, $sens, $nbrePoly) {
$requete = 'UPDATE osm_relation_a_chemins '.
"SET ordre = '$ordre', sens = '$sens', num_poly = $nbrePoly ".
"WHERE id_relation = $idRelation ".
"AND id_chemin = $idChemin ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
 
/**
* Fonction qui récupère les relations des polygones incomplets et appelle pour chaque relation la fonction
* remplirPolygoneIncomplet($idRelation);
*/
private function remplirRelationsAuPolygoneIncomplet() {
$relations = $this->getRelationsAuPolygoneIncomplet();
foreach ($relations as $relation) {
$this->remplirPolygoneIncomplet($relation['id_relation']);
if ($this->mode == 'manuel') {
$this->messages->afficherAvancement("Création du polygone incomplet : ", 1);
}
}
}
 
/**
* Fonction qui exécute la même tâche que la fonction remplirPolygone() pour chaque polygone d'un multipolygone
* et renvoie un tableau MultiPolygone[] où chaque case contient un polygone fermé. Puis met à jour le polygone
* de la commune.
*/
private function remplirPolygoneIncomplet($idRelation) {
// Tableau multipolygone qui contient tous les polygones d'un multipolygone
$multiPolygone = array();
// Tableau roles qui contient les différents roles des chemins de la relation
$roles = array();
// Sélectionner le nombre de polygones qui existe dans un multipolygone
$nbPoly = $this->getNombrePoly($idRelation);
//boucle for qui parcourt chaque polygone du multipolygone
for ($numPoly = 1; $numPoly <= $nbPoly; $numPoly++) {
$polygone = array();
$chemins = $this->getCheminsParPolygone($idRelation, $numPoly);
foreach ($chemins as $chemin) {
$role = $chemin['role'];
$roles[$role] = (isset($roles[$role])) ? $roles[$role]++ : 1;
$noeuds = $this->getNoeudsPourCheminEtSens($chemin['id_chemin'], $chemin['sens']);
$polygone = array_merge($polygone, $noeuds);
}
$multiPolygone[] = implode(', ', $polygone);
}
$this->mettreAJourMultiPolygone($multiPolygone, $roles, $idRelation, $nbPoly);
}
 
private function getNombrePoly($idRelation) {
$requete = 'SELECT MAX(num_poly) AS num_poly '.
'FROM osm_relation_a_chemins '.
"WHERE id_relation = $idRelation ".
' -- '.__FILE__.' : '.__LINE__;
$resultat = $this->bdd->recuperer($requete);
return $resultat['num_poly'];
}
 
private function getCheminsParPolygone($idRelation, $numPoly) {
$requete = 'SELECT id_chemin, sens, role '.
'FROM osm_relation_a_chemins '.
"WHERE id_relation = $idRelation ".
"AND num_poly = $numPoly ".
'ORDER BY ordre '.
' -- '.__FILE__.' : '.__LINE__;
$chemins = $this->bdd->recupererTous($requete);
return $chemins;
}
 
private function getNoeudsPourCheminEtSens($idChemin, $sens) {
$tri = ($sens == 'directe') ? 'ASC' : 'DESC';
$requete = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '.
'FROM osm_chemin_a_noeuds AS WN '.
' INNER JOIN osm_noeuds AS NLL ON (WN.id_noeud = NLL.id_noeud) '.
"WHERE WN.id_chemin = $idChemin ".
"ORDER BY WN.ordre $tri ".
' -- '.__FILE__.' : '.__LINE__;
$noeuds = $this->bdd->recupererTous($requete);
$latLng = array();
foreach ($noeuds as $noeud) {
$latLng[] = $noeud['lat'].' '.$noeud['long'];
}
return $latLng;
}
 
/**
* Remplie le champ polygone à partir du tableau MultiPolygone
*/
private function mettreAJourMultiPolygone($multiPolygone, $roles, $idRelation, $nbPoly) {
// Présence d'une enclave contenue dans cette entité administrative mais qui appartient à une autre entité administrative
if ((isset($roles['inner']) || isset($roles['enclave']))) {
if ($nbPoly == 2) {
$multiPoly = implode('),(', $multiPolygone);
} else {
$multiPoly = null;
$msgTpl = "La relation '%s' possède plus de 2 polygones de type enclaves.";
$this->messages->traiterErreur($msgTpl, array($idRelation));
}
} else {
// Tous les autres cas
$multiPoly = implode(')),((', $multiPolygone);
}
if (isset($multiPoly)) {
$this->mettreAJourCommune($idRelation, $multiPoly);
}
}
 
private function mettreAJourCommune($idRelation, $multiPoly) {
$requete = 'UPDATE osm_communes '.
"SET polygone = MPOLYFROMTEXT('MULTIPOLYGON((($multiPoly)))'), ".
"notes = 'Polygone complet' ".
"WHERE id_relation = $idRelation ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
 
/**
* Renomme la note des polygones vides d'un polygone complet en polygone incomplet
*/
private function renommerEnPolygoneIncomplet() {
$requete = 'UPDATE osm_communes '.
"SET notes = 'Polygone incomplet' ".
"WHERE ASTEXT(polygone) IS NULL ".
' -- '.__FILE__.' : '.__LINE__;
 
$retour = $this->bdd->requeter($requete);
$this->messages->traiterInfo("Nombre de polygones définis à incomplet : ".$retour->rowCount());
}
}
/trunk/scripts/modules/osm/OrdonneurDeChemins.php
New file
0,0 → 1,170
<?php
/**
* Traitement de l'ordre :
*
* Fonction qui rajoute l'ordre et le sens de chaque way d'une relation dans la table `osm_relation_a_chemins`
*
* Exemple de lancement du script :
* /opt/lampp/bin/php -d memory_limit=8000M cli.php osm -a ordre -m manuel
*
*/
class OrdonneurDeChemins {
private $conteneur;
private $bdd;
private $messages;
private $mode;
 
private $idRelation = null;
private $idChemin = null;
private $idNoeud = null;
private $chemins = array();
private $ordre = 0;
 
public function __construct($conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->messages = $this->conteneur->getMessages();
$this->mode = $this->conteneur->getParametre('m');
}
 
public function executer() {
$relations = $this->getToutesRelationsAChemins();
if ($this->mode == 'manuel') {
$this->messages->traiterInfo("Nombre de relations : %s", array(count($relations)));
}
foreach ($relations as $relation) {
// Traitement de la relation courante
$this->idRelation = $relation['id_relation'];
 
$this->chargerCheminsRelationActuelle();
 
// Selection du premier chemin comme chemin actuel
$this->idChemin = $this->getIdPremierChemin();
$this->mettreAJourChemin('directe', __LINE__);
 
// Selection du dernier noeud comme noeud actuel
$idDernierNoeud = $this->getIdDernierNoeud();
if ($idDernierNoeud) {
$this->idNoeud = $idDernierNoeud;
$this->ordonnerChemins();
}
 
// Affichage de l'avancement
if ($this->mode == 'manuel') {
$this->messages->afficherAvancement("Ordone les chemins de la relation : ", 1);
}
}
}
 
private function getToutesRelationsAChemins() {
$requete = 'SELECT DISTINCT id_relation '.
'FROM osm_relation_a_chemins '.
' -- '.__FILE__.' : '.__LINE__;
$relations = $this->bdd->recupererTous($requete);
return $relations;
}
 
private function chargerDonneesRelationActuelle() {
$requete = 'SELECT cn.id_chemin, cn.id_noeud, cn.ordre '.
'FROM osm_relation_a_chemins AS rc '.
' LEFT JOIN osm_chemin_a_noeuds AS cn ON (rc.id_chemin = cn.id_chemin) '.
"WHERE rc.id_relation = {$this->idRelation} ".
"ODER BY cn.ordre ASC ".
' -- '.__FILE__.' : '.__LINE__;
$infos = $this->bdd->recupererTous($requete);
foreach ($infos as $info) {
$this->infosRel[$this->idRelation][$info['id_chemin']]['noeuds'][$info['id_noeud']] = $info['ordre'];
}
$this->chemins = ($chemins) ? $chemins : array();
$this->ordre = 0;
}
 
private function chargerCheminsRelationActuelle() {
$requete = 'SELECT id_chemin '.
'FROM osm_relation_a_chemins '.
"WHERE id_relation = {$this->idRelation} ".
' -- '.__FILE__.' : '.__LINE__;
$chemins = $this->bdd->recupererTous($requete);
$this->chemins = ($chemins) ? $chemins : array();
$this->ordre = 0;
}
 
private function getIdPremierChemin() {
return isset($this->chemins[0]) ? $this->chemins[0]['id_chemin'] : null;
}
 
private function mettreAJourChemin($sens, $ligne, $fichier = __FILE__) {
$ordre = $this->ordre++;
$requete = 'UPDATE osm_relation_a_chemins '.
"SET ordre = '$ordre', sens = '$sens' ".
"WHERE id_relation = {$this->idRelation} ".
"AND id_chemin = {$this->idChemin} ".
" -- $fichier : $ligne";
$retour = $this->bdd->requeter($requete);
return $retour;
}
 
private function getIdDernierNoeud() {
$requete = 'SELECT id_noeud '.
'FROM osm_chemin_a_noeuds '.
"WHERE id_chemin = {$this->idChemin} ".
'ORDER BY ordre DESC '.
'LIMIT 0,1 '.
' -- '.__FILE__.' : '.__LINE__;
$noeud = $this->bdd->recuperer($requete);
$idDernierNoeud = ($noeud) ? $noeud['id_noeud'] : false;
return $idDernierNoeud;
}
 
private function ordonnerChemins() {
foreach ($this->chemins as $chemin) {
// Selection du chemin qui possède le dernier noeud du précédent chemin et écarter l'actuel
$idCheminSuivant = $this->getIdCheminSuivant();
if ($idCheminSuivant) {
$this->idChemin = $idCheminSuivant;
$this->comparerNoeuds();
} else {
$msg = "Impossible de trouver le chemin suivant pour la relation : %s";
$this->messages->traiterAvertissement($msg, array($this->idRelation));
}
}
}
 
private function getIdCheminSuivant() {
$requete = 'SELECT wn.id_chemin '.
'FROM osm_relation_a_chemins AS rw '.
' LEFT JOIN osm_chemin_a_noeuds AS wn ON (rw.id_chemin = wn.id_chemin) '.
"WHERE wn.id_noeud = {$this->idNoeud} ".
" AND wn.id_chemin != {$this->idChemin} ".
" AND rw.id_relation = {$this->idRelation} ".
" LIMIT 0,1 ".
' -- '.__FILE__.' : '.__LINE__;
$chemins = $this->bdd->recuperer($requete);
$idCheminSuivant = ($chemins && isset($chemins['id_chemin'])) ? $chemins['id_chemin'] : false;
return $idCheminSuivant;
}
 
private function comparerNoeuds() {
$idPremierNoeud = $this->getIdPremierNoeud();
$idDernierNoeud = $this->getIdDernierNoeud();
if ( strcmp($idPremierNoeud, $this->idNoeud ) == 0 ) {
$this->mettreAJourChemin('directe', __LINE__);
$this->idNoeud = $idDernierNoeud;
} else {
$this->mettreAJourChemin('indirecte', __LINE__);
$this->idNoeud = $idPremierNoeud;
}
}
 
private function getIdPremierNoeud() {
$requete = 'SELECT id_noeud '.
'FROM osm_chemin_a_noeuds '.
"WHERE id_chemin = {$this->idChemin} ".
'ORDER BY ordre ASC '.
'LIMIT 0,1 '.
' -- '.__FILE__.' : '.__LINE__;
$noeud = $this->bdd->recuperer($requete);
$idPremierNoeud = ($noeud) ? $noeud['id_noeud'] : false;
return $idPremierNoeud;
}
}
/trunk/scripts/modules/osm/config.ini
New file
0,0 → 1,9
; Ajouter les nouvelles version à la suite dans versions et versionsDonnees.
version = "1.0"
dossierSql = "{ref:dossierDonneesEflore}osm/"
 
[fichiers]
structureSql = "osm.sql"
 
[chemins]
structureSql = "{ref:dossierSql}{ref:version}/{ref:fichiers.structureSql}"
/trunk/scripts/modules/osm/MiseAJour.php
1,10 → 1,16
<?php
/**
* Exemple lancement:
* /opt/lampp/bin/php -d memory_limit=3500M /home/mohcen/web/cartoOSM/scripts/cli.php osm/mise_a_jour -a recupererRelationAMod
* -f fichier_osm_change -e fichier_osm_nouveau
*/
class MiseAjour extends Script {
* Permet de mettre à jour les contours à partir d'un fichier de diff.
*
* Exemple de lancement du script :
* /opt/lampp/bin/php -d memory_limit=3500M cli.php osm -a maj -f fichier_osm_change -e fichier_osm_nouveau
*/
class MiseAJour {
private $conteneur;
private $bdd;
private $messages;
private $mode;
 
private $communes = array();
private $relations_communes = array();
private $relation_a_chemins = array();
12,183 → 18,209
private $noeuds = array();
private $pas = 10000;
private $pas_commune = 1000;
private $elementType = '';
 
protected $parametres_autorises = array(
'-f' => array(true, null, 'Chemin du fichier osm à analyser'));
public function __construct($conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->messages = $this->conteneur->getMessages();
$this->mode = $this->conteneur->getParametre('m');
}
 
/**
* Fonction qui parcourt tous les ways les noeuds de chaque relation en prenant en considération l'ordre et
* le sens de chaque ways concaténés ensemble (séparés par des virgules). Update du champ polygone de chaque
* relation dans la table `osm_relations`
*/
public function executer() {
$this->bdd = new Bdd();
 
// Lancement de l'action demandée
$cmd = $this->getParametre('a');
switch ($cmd) {
case 'MAJ' :
$this->MettreAjour();
$cmd = $this->conteneur->getParametre('a');
switch ($cmd) {
case 'maj' :
$this->mettreAjour();
break;
default :
$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
default :
$msgTpl = "Erreur : la commande '%s' n'est pas prise en compte par la classe %s !";
$msg = sprintf($msgTpl, $cmd, get_class($this));
throw new Exception($msg);
}
}
print "\n";// Pour ramener à la ligne en fin de script
}
 
 
/**
* Fonction permettant de traiter et d'analyser le fichier de différence et de mettre à jour la base de données
* en tenant compte des trois cas:Suppression, Création ,modification
*/
private function MettreAjour() {
$lecteur = new XMLReader();
if ($lecteur->open($this->getParametre('f'))) {
$dom = new DomDocument();
while ($lecteur->read()) {
if ($lecteur->nodeType == XMLREADER::ELEMENT) {
if ($lecteur->localName == 'create') {
$creations = $lecteur->expand();
$this-> analyserCreations($creations);
}
if ($lecteur->localName == 'modify') {
$modifications = $lecteur->expand();
$this-> analyserModifications($modifications);
}
if ($lecteur->localName == 'delete') {
$suppressions = $lecteur->expand();
$this-> analyserSuppressions($suppressions);
}
}
private function mettreAjour() {
$lecteur = $this->getLecteurXml();
while ($lecteur->read()) {
if ($lecteur->nodeType == XMLREADER::ELEMENT) {
$this->elementType = $lecteur->localName;
$this->analyserElementXml($lecteur->localName, $lecteur->expand());
}
} else {
$e = "Impossible d'ouvrir le fichier osm : %s";
$this->traiterErreur($e, array($this->getParametre('f')));
 
if ($this->mode == 'manuel') {
$this->messages->afficherAvancement("Analyse de la ligne du fichier de diff OSM : ", 1);
}
}
}
 
/**
* Fonction permettant le traitement du cas création concernant les relations, ways et les noeuds.
*/
private function analyserCreations($creations) {
$relations = $creations->getElementsByTagName('relation');
foreach ($relations as $relation) {
$this-> analyserRelation($relation);
if (count($this->relation_a_chemins) > $this->pas) {
$this->insererRelationAChemins();
private function getLecteurXml() {
$fichierOsm = $this->conteneur->getParametre('f');
$lecteur = new XMLReader();
$ouvertureXmlOk = $lecteur->open($fichierOsm);
if ($ouvertureXmlOk === false) {
$msgTpl = "Impossible d'ouvrir le fichier osm : %s";
$msg = sprintf($msgTpl, $this->conteneur->getParametre('f'));
new Exception($msg);
}
return $lecteur;
}
 
private function analyserElementXml($noeudDom) {
$relations = $noeudDom->getElementsByTagName('relation');
if ($relations->length > 0) {
foreach ($relations as $relation) {
$this->analyserRelation($relation);
$this->traiterRelations();
}
if (count($this->relations_communes) > $this->pas_commune) {
$this->insererRelationsCommunes();
}
}
 
$ways = $creations->getElementsByTagName('way');
foreach ($ways as $way) {
$this->analyserWay($way);
if (count($this->chemin_a_noeuds) > $this->pas) {
$this->insererCheminANoeuds();
if ($ways->length > 0) {
foreach ($ways as $way) {
$this->analyserWay($way);
$this->traiterCheminANoeuds();
}
}
 
$noeuds = $creations->getElementsByTagName('node');
foreach ($noeuds as $noeud) {
$this->analyserNode($noeud);
if (count($this->noeuds) > $this->pas) {
$this->insererNoeuds();
if ($noeuds->length > 0) {
foreach ($noeuds as $noeud) {
$this->analyserNode($noeud);
$this->traiterNoeuds();
}
}
$this->insererRelationsCommunes();
$this->insererRelationAChemins();
$this->insererCheminANoeuds();
$this->insererNoeuds();
 
$this->traiterElementsOrphelins();
}
 
/**
* Fonction permettant le traitement du cas modification concernant les relations, ways et les noeuds.
*/
private function analyserModifications($modifications) {
$relations = $modifications->getElementsByTagName('relation');
foreach ($relations as $relation) {
$this-> analyserRelation($relation);
if (count($this->relation_a_chemins) > $this->pas) {
$this->modifierRelationAChemins();
private function traiterRelations() {
if (count($this->relation_a_chemins) > $this->pas) {
switch ($this->elementType) {
case 'create' :
$this->insererRelationAChemins();
break;
case 'modify' :
$this->modifierRelationAChemins();
break;
case 'delete' :
$this->supprimerRelationAChemins();
break;
}
if (count($this->relations_communes) > $this->pas_commune) {
$this->modifierRelationsCommunes();
}
if (count($this->relations_communes) > $this->pas_commune) {
switch ($this->elementType) {
case 'create' :
$this->insererRelationsCommunes();
break;
case 'modify' :
$this->modifierRelationsCommunes();
break;
case 'delete' :
$this->supprimerRelationsCommunes();
break;
}
}
$ways = $modifications->getElementsByTagName('way');
foreach ($ways as $way) {
$this->analyserWay($way);
if (count($this->chemin_a_noeuds) > $this->pas) {
$this->modifierCheminANoeuds();
}
 
private function traiterChemins() {
if (count($this->chemin_a_noeuds) > $this->pas) {
switch ($this->elementType) {
case 'create' :
$this->insererCheminANoeuds();
break;
case 'modify' :
$this->modifierCheminANoeuds();
break;
case 'delete' :
$this->supprimerCheminANoeuds();
break;
}
}
$noeuds = $modifications->getElementsByTagName('node');
foreach ($noeuds as $noeud) {
$this->analyserNode($noeud);
if (count($this->noeuds) > $this->pas) {
$this->modifierNoeuds();
}
 
private function traiterNoeuds() {
if (count($this->noeuds) > $this->pas) {
switch ($this->elementType) {
case 'create' :
$this->insererNoeuds();
break;
case 'modify' :
$this->modifierNoeuds();
break;
case 'delete' :
$this->supprimerNoeuds();
break;
}
}
$this->modifierRelationsCommunes();
$this->modifierRelationAChemins();
$this->modifierCheminANoeuds();
$this->modifierNoeuds();
}
 
/**
* Fonction permettant le traitement du cas suppression concernant les relations, ways et les noeuds.
*/
private function analyserSuppressions($suppressions) {
$relations = $suppressions->getElementsByTagName('relation');
foreach ($relations as $relation) {
$this-> analyserRelation($relation);
if (count($this->relation_a_chemins) > $this->pas) {
private function traiterElementsOrphelins() {
switch ($this->elementType) {
case 'create' :
$this->insererRelationsCommunes();
$this->insererRelationAChemins();
$this->insererCheminANoeuds();
$this->insererNoeuds();
break;
case 'modify' :
$this->modifierRelationsCommunes();
$this->modifierRelationAChemins();
$this->modifierCheminANoeuds();
$this->modifierNoeuds();
break;
case 'delete' :
$this->supprimerRelationsCommunes();
$this->supprimerRelationAChemins();
}
if (count($this->relations_communes) > $this->pas_commune) {
$this->supprimerRelationsCommunes();
}
}
$ways = $suppressions->getElementsByTagName('way');
foreach ($ways as $way) {
$this->analyserWay($way);
if (count($this->chemin_a_noeuds) > $this->pas) {
$this->supprimerCheminANoeuds();
}
}
$noeuds = $suppressions->getElementsByTagName('node');
foreach ($noeuds as $noeud) {
$this->analyserNode($noeud);
if (count($this->noeuds) > $this->pas) {
$this->supprimerNoeuds();
}
break;
}
$this->supprimerRelationsCommunes();
$this->supprimerRelationAChemins();
$this->supprimerCheminANoeuds();
$this->supprimerNoeuds();
}
 
 
/**
* Récupère l'id commune, nom commune et le code INSEE et remplie la table `osm_relations`
*/
private function analyserRelation($relation) {
$relation_id = $this->proteger($relation->getAttribute('id'));
$relation_id = $relation->getAttribute('id');
$chemins = $relation->getElementsByTagName('member');
foreach ($chemins as $chemin) {
if ($chemin->getAttribute('type') == 'way') { //écarter le noeud centrale
$chemin_id = $this->proteger($chemin->getAttribute('ref'));
$role = $this->proteger($chemin->getAttribute('role'));//role: null, inner, outer, exclave et enclave.
$chemin_id = $chemin->getAttribute('ref');
$role = $chemin->getAttribute('role');//role: null, inner, outer, exclave et enclave.
$this->relation_a_chemins[] = array($relation_id, $chemin_id, $role);
}
}
 
$tags = $relation->getElementsByTagName('tag');
if ($tags->length > 0) {
$this->analyserTags($relation_id, $tags);
}
}
 
private function analyserTags($relation_id, $tags) {
$commune_nom = null;
$commune_insee = null;
$tags = $relation->getElementsByTagName('tag');
foreach ($tags as $tag) {
$tag_cle = $tag->getAttribute('k');
$tag_val = $tag->getAttribute('v');
switch ($tag_cle) {
case 'name' :
$commune_nom = $this->proteger($tag_val);
$commune_nom = $tag_val;
break;
case 'ref:INSEE' :
$commune_insee = $this->proteger($tag_val);
$commune_insee = $tag_val;
break;
}
if (!is_null($commune_nom) && !is_null($commune_insee)) {
209,14 → 241,12
* Récupère l'id_way et tous les id_node de chaque way et remplie la table `osm_chemin_a_noeuds`
*/
private function analyserWay($way) {
$chemin_id = $this->proteger($way->getAttribute('id'));
$chemin_id = $way->getAttribute('id');
$noeuds = $way->getElementsByTagName('nd');
$ordre = 0;
$noeuds = $way->getElementsByTagName('nd');
$chemin_a_noeuds = array();
foreach ($noeuds as $noeud) {
$noeud_id = $this->proteger($noeud->getAttribute('ref'));
$ordre++;
$this->chemin_a_noeuds[] = array($chemin_id, $noeud_id, $ordre);
$noeud_id = $noeud->getAttribute('ref');
$this->chemin_a_noeuds[] = array($chemin_id, $noeud_id, ++$ordre);
}
}
 
224,33 → 254,37
* Fonction qui récupère tous les l'id_node et les valeurs(Lat/Lon) correspondantes et remplie la table `osm_noeuds`
*/
private function analyserNode($node) {
$noeud_id = $this->proteger($node->getAttribute('id'));
$lat = $this->proteger($node->getAttribute('lat'));
$lon = $this->proteger($node->getAttribute('lon'));
$this->noeuds[] = array($noeud_id, $lat, $lon);
$this->noeuds[] = array(
$node->getAttribute('id'),
$node->getAttribute('lat'),
$node->getAttribute('lon')
);
}
 
//Insertion des relations
private function insererRelationsCommunes() {
$requete = 'INSERT INTO osm_relations (id_relation, nom, code_insee) '.
'VALUES '.$this->creerValuesMultiple($this->relations_communes);
$this->inserer($requete);
$requete = 'INSERT INTO osm_relations (id_relation, nom, code_insee) '.
'VALUES '.$this->creerValuesMultiple($this->relations_communes).
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
$this->relations_communes = array();
}
 
//Insertion des relations à chemins
private function insererRelationAChemins() {
$requete = 'INSERT INTO osm_relation_a_chemins (id_relation, id_chemin, role) '.
'VALUES '.$this->creerValuesMultiple($this->relation_a_chemins);
$this->inserer($requete);
$requete = 'INSERT INTO osm_relation_a_chemins (id_relation, id_chemin, role) '.
'VALUES '.$this->creerValuesMultiple($this->relation_a_chemins).
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
$this->relation_a_chemins = array();
}
 
//Insertion des chemins à noeuds
private function insererCheminANoeuds() {
$requete = 'INSERT INTO osm_chemin_a_noeuds (id_chemin, id_noeud, ordre) '.
'VALUES '.$this->creerValuesMultiple($this->chemin_a_noeuds);
$this->inserer($requete);
$requete = 'INSERT INTO osm_chemin_a_noeuds (id_chemin, id_noeud, ordre) '.
'VALUES '.$this->creerValuesMultiple($this->chemin_a_noeuds).
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
$this->chemin_a_noeuds = array();
}
 
257,19 → 291,21
//Insertion des noeuds
private function insererNoeuds() {
$requete = 'INSERT INTO osm_noeuds (id_noeud, lat, `long`) '.
'VALUES '.$this->creerValuesMultiple($this->noeuds);
$this->inserer($requete);
'VALUES '.$this->creerValuesMultiple($this->noeuds).
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
$this->noeuds = array();
}
 
//Update des relations
private function modifierRelationsCommunes() {
$donnees = $this->relations_communes;
foreach ($donnees as $donnee) {
$requete = 'UPDATE osm_relations '.
"SET id_relation = $donnee[0], nom = $donnee[1], code_insee = $donnee[2] ".
"WHERE id_relation = $donnee[0]";
$this->inserer($requete);
foreach ($this->relations_communes as $donnee) {
$infosP = $this->bdd->proteger($donnee);
$requete = 'UPDATE osm_relations '.
"SET id_relation = $infosP[0], nom = $infosP[1], code_insee = $infosP[2] ".
"WHERE id_relation = $infosP[0] ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
$this->relations_communes = array();
}
279,19 → 315,13
*de la table osm_relation_a_chemins et insérer la nouvelle
*/
private function modifierRelationAChemins() {
$relations_a_chemins_a_supp = array();
$donnees = $this->relation_a_chemins;
foreach ($donnees as $donnee) {
$relations_a_chemins_a_supp[] = $donnee[0];
}
$values_chaine = '('.implode(',',array_unique($relations_a_chemins_a_supp)).')';
$requete = 'DELETE FROM osm_relation_a_chemins '.
"WHERE id_relation IN $values_chaine";
$this->inserer($requete);
foreach ($donnees as $donnee) {
$this->supprimerRelationAChemins();
foreach ($this->relation_a_chemins as $donnee) {
$infosP = $this->bdd->proteger($donnee);
$requete = 'INSERT INTO osm_relation_a_chemins (id_relation, id_chemin, role) '.
"VALUES ($donnee[0], $donnee[1], $donnee[2]);";
$this->inserer($requete);
"VALUES ($infosP[0], $infosP[1], $infosP[2]) ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
$this->relation_a_chemins = array();
}
301,98 → 331,87
*de la table osm_chemins_a_noeuds et insérer le nouveau
*/
private function modifierCheminANoeuds() {
$chemin_a_noeuds_a_supp = array();
$donnees = $this->chemin_a_noeuds;
foreach ($donnees as $donnee) {
$chemin_a_noeuds_a_supp[] = $donnee[0];
}
$values_chaine = '('.implode(',',array_unique($chemin_a_noeuds_a_supp)).')';
$requete = 'DELETE FROM osm_chemin_a_noeuds '.
"WHERE id_chemin IN $values_chaine";
$this->inserer($requete);
foreach ($donnees as $donnee) {
$this->supprimerCheminANoeuds();
foreach ($this->chemin_a_noeuds as $donnee) {
$infosP = $this->bdd->proteger($donnee);
$requete = 'INSERT INTO osm_chemin_a_noeuds (id_chemin, id_noeud, ordre) '.
"VALUES ($donnee[0], $donnee[1], $donnee[2]);";
$this->inserer($requete);
"VALUES ($infosP[0], $infosP[1], $infosP[2]) ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
$this->chemin_a_noeuds = array();
}
 
 
//Update des noeuds
private function modifierNoeuds() {
$donnees = $this->noeuds;
foreach ($donnees as $donnee) {
foreach ($this->noeuds as $donnee) {
$infosP = $this->bdd->proteger($donnee);
$requete = 'UPDATE osm_noeuds '.
"SET id_noeud = $donnee[0], lat = $donnee[1], `long` = $donnee[2] ".
"WHERE id_noeud = $donnee[0]";
$this->inserer($requete);
"SET id_noeud = $infosP[0], lat = $infosP[1], `long` = $infosP[2] ".
"WHERE id_noeud = $infosP[0] ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
$this->noeuds = array();
}
 
 
//Suppressions des relations
private function supprimerRelationsCommunes() {
$donnees = $this->relations_communes;
foreach ($donnees as $donnee) {
$requete = 'DELETE FROM osm_relations '.
"WHERE id_relation = $donnee[0]";
$this->inserer($requete);
}
$idsIn = $this->getIds($this->relations_communes);
$this->relations_communes = array();
$requete = 'DELETE FROM osm_relations '.
"WHERE id_relation IN ($idsIn) ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
 
//Suppressions des relations à chemins
private function supprimerRelationAChemins() {
$donnees = $this->relations_communes;
foreach ($donnees as $donnee) {
$donnees = $this->relation_a_chemins;
$requete = 'DELETE FROM osm_relation_a_chemins '.
"WHERE id_relation = $donnee[0]";
$this->inserer($requete);
}
$idsIn = $this->getIds($this->relation_a_chemins);
$this->relation_a_chemins = array();
$requete = 'DELETE FROM osm_relation_a_chemins '.
"WHERE id_relation IN ($idsIn) ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
 
//Suppressions des chemins à noeuds
private function supprimerCheminANoeuds() {
$donnees = $this->chemin_a_noeuds;
foreach ($donnees as $donnee) {
$donnees = $this->relation_a_chemins;
$requete = 'DELETE FROM osm_chemin_a_noeuds '.
"WHERE id_chemin = $donnee[0]";
$this->inserer($requete);
}
$idsIn = $this->getIds($this->chemin_a_noeuds);
$this->chemin_a_noeuds = array();
$requete = 'DELETE FROM osm_chemin_a_noeuds '.
"WHERE id_chemin IN ($idsIn) ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
 
//Suppressions des chemins à noeuds
private function supprimerNoeuds() {
$donnees = $this->noeuds;
foreach ($donnees as $donnee) {
$requete = 'DELETE FROM osm_noeuds '.
"WHERE id_noeud = $donnee[0]";
$this->inserer($requete);
}
$idsIn = $this->getIds($this->noeuds);
$this->noeuds = array();
}
 
private function inserer($requete) {
$requete = 'DELETE FROM osm_noeuds '.
"WHERE id_noeud IN ($idsIn) ".
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
 
private function proteger($chaine) {
return $this->bdd->proteger($chaine);
private function getIds(&$tableau) {
$ids = array();
foreach ($tableau as $info) {
$ids[] = $this->bdd->proteger($info[0]);
}
$idsSansDoublon = array_unique($ids);
$idsIn = implode(',', $idsSansDoublon);
return $idsIn;
}
 
private function creerValuesMultiple($donnees) {
$values = array();
foreach ($donnees as $donnee) {
$values[] = implode(',', $donnee);
foreach ($donnees as $infos) {
$infosP = $this->bdd->proteger($infos);
$values[] = implode(',', $infosP);
}
$values_chaine = '('.implode('),(', $values).')';
return $values_chaine;
$valuesClause = '('.implode('),(', $values).')';
return $valuesClause;
}
}
?>
}
/trunk/scripts/modules/osm/Osm.php
New file
0,0 → 1,104
<?php
//declare(encoding='UTF-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
*
* 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
* @author Aurélien PERONNET <aurelien@tela-botanica.org>
* @copyright Copyright (c) 2012, 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
*/
// 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() {
try {
$this->initialiserProjet(self::PROJET_NOM);
 
// Lancement de l'action demandée
$cmd = $this->getParametre('a');
switch ($cmd) {
case 'chargerStructureSql' :
$this->chargerStructureSql();
break;
case 'analyser' :
$script = $this->chargerClasse('ParseurOsm');
$script->executer();
break;
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!");
}
} catch (Exception $e) {
$this->traiterErreur($e->getMessage());
}
print "\n";// Pour ramener à la ligne en fin de script
}
 
protected function initialiserProjet($projetNom) {
$this->projetNom = $projetNom;
}
 
private function chargerClasse($classe) {
require_once $classe.'.php';
$conteneur = new Conteneur($this->parametres);
return new $classe($conteneur);
}
}
/trunk/scripts/modules/osm/ParseurOsm.php
1,11 → 1,18
<?php
/**
* Exemple de lancement du script :
* /opt/lampp/bin/php cli.php osm/parseur_osm -a compter -f "/home/jpm/Stockage/osm/languedoc-roussillon-communes.osm"
*
* Analyse du fichir OSM :
* /opt/lampp/bin/php cli.php osm -a analyser -f "../donnees/osm/france_communes_new.osm" -m manuel
*
*/
class ParseurOsm extends Script {
class ParseurOsm {
 
private $conteneur;
private $bdd;
private $messages;
private $mode;
 
private $communes = array();
private $relations_communes = array();
private $relation_a_chemins = array();
14,22 → 21,20
private $pas = 10000;
private $pas_commune = 1000;
 
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 __construct($conteneur) {
$this->conteneur = $conteneur;
$this->bdd = $this->conteneur->getBdd();
$this->messages = $this->conteneur->getMessages();
$this->mode = $this->conteneur->getParametre('m');
}
 
public function executer() {
$this->bdd = new Bdd();
 
// Lancement de l'action demandée
$cmd = $this->getParametre('a');
switch ($cmd) {
case 'analyser' :
$cmd = $this->conteneur->getParametre('a');
switch ($cmd) {
case 'analyser' :
$this->lireFichierOsm();
break;
case 'ordre' :
$this->ordonnerWays();
break;
case 'polygone' :
$this->remplirPolygone();
break;
36,74 → 41,58
case 'zero' :
$this->remettreOrdreAZero();
break;
case 'ordonnerPolygoneInc' :
$this->relationsPolygoneIncomplet(1, 0);
break;
case 'remplirPolygoneInc' :
$this->remplirCommunesPolygoneIncomplet();
break;
case 'renommer' :
$this->renommerEnPolygoneIncomplet();
break;
case 'centre' :
$this->centroid();
break;
default :
$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
$this->messages->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
}
}
}
 
 
/**
/**
* Lit le fichier OSM et lance l'analyse des noeuds xml en fonction de leur type.
*/
private function lireFichierOsm() {
$lecteur = new XMLReader();
if ($lecteur->open($this->getParametre('f'))) {
$dom = new DomDocument();
while ($lecteur->read()) {
if ($lecteur->nodeType == XMLREADER::ELEMENT) {
if ($lecteur->localName == 'relation') {
$relation = $lecteur->expand();
$this->analyserRelation($relation);
$lecteur = $this->getLecteurXml();
while ($lecteur->read()) {
if ($lecteur->nodeType == XMLREADER::ELEMENT) {
$this->analyserElementXml($lecteur->localName, $lecteur->expand());
}
if ($this->mode == 'manuel') {
$this->messages->afficherAvancement("Analyse de la ligne du fichier OSM : ", 1);
}
}
$this->insererElementsOrphelins();
}
 
if (count($this->relation_a_chemins) > $this->pas) {
$this->insererRelationAChemins();
}
if (count($this->relations_communes) > $this->pas_commune) {
$this->insererRelationsCommunes();
}
} else if ($lecteur->localName == 'way') {
$way = $lecteur->expand();
$this->analyserWay($way);
private function analyserElementXml($elementNom, $noeudDom) {
switch ($elementNom) {
case 'relation' :
$this->analyserRelation($noeudDom);
break;
case 'way' :
$this->analyserWay($noeudDom);
break;
case 'node' :
$this->analyserNode($noeudDom);
break;
}
}
 
if (count($this->chemin_a_noeuds) > $this->pas) {
$this->insererCheminANoeuds();
}
} else if ($lecteur->localName == 'node') {
$node = $lecteur->expand();
$this->analyserNode($node);
if (count($this->noeuds) > $this->pas) {
$this->insererNoeuds();
}
}
}
if (count($this->noeuds) > $this->pas) {
$this->insererNoeuds();
$this->insererCheminANoeuds();
}
if ($this->getParametre('m') == 'manuel') {
$this->afficherAvancement("Analyse de la ligne du fichier OSM : ", 1);
}
}
$this->insererRelationsCommunes();
$this->insererRelationAChemins();
$this->insererCheminANoeuds();
$this->insererNoeuds();
} else {
$e = "Impossible d'ouvrir le fichier osm : %s";
$this->traiterErreur($e, array($this->getParametre('f')));
private function insererElementsOrphelins() {
$this->insererRelationsCommunes();
$this->insererRelationAChemins();
$this->insererCheminANoeuds();
$this->insererNoeuds();
}
 
private function getLecteurXml() {
$fichierOsm = $this->conteneur->getParametre('f');
$lecteur = new XMLReader();
$ouvertureXmlOk = $lecteur->open($fichierOsm);
if ($ouvertureXmlOk === false) {
$msgTpl = "Impossible d'ouvrir le fichier osm : %s";
$msg = sprintf($msgTpl, $this->conteneur->getParametre('f'));
new Exception($msg);
}
return $lecteur;
}
 
/**
110,39 → 99,64
* Récupère l'id commune, nom commune et le code INSEE et remplie la table `CommuneOSM`
*/
private function analyserRelation($relation) {
$relation_id = $this->proteger($relation->getAttribute('id'));
$idRelation = $relation->getAttribute('id');
 
$chemins = $relation->getElementsByTagName('member');
$this->analyserChemins($idRelation, $chemins);
if (count($this->relation_a_chemins) > $this->pas) {
$this->insererRelationAChemins();
}
 
$tags = $relation->getElementsByTagName('tag');
$this->analyserTags($idRelation, $tags);
if (count($this->relations_communes) > $this->pas_commune) {
$this->insererRelationsCommunes();
}
}
 
private function analyserChemins($relation_id, $chemins) {
foreach ($chemins as $chemin) {
if ($chemin->getAttribute('type') == 'way') { //écarter le noeud centrale
$chemin_id = $this->proteger($chemin->getAttribute('ref'));
$role = $this->proteger($chemin->getAttribute('role'));//role: null, inner, outer, exclave et enclave.
$chemin_id = $chemin->getAttribute('ref');
$role = $chemin->getAttribute('role');//role: null, inner, outer, exclave et enclave.
$this->relation_a_chemins[] = array($relation_id, $chemin_id, $role);
}
}
}
 
private function analyserTags($relation_id, $tags) {
$commune_nom = null;
$commune_insee = null;
$tags = $relation->getElementsByTagName('tag');
foreach ($tags as $tag) {
$tag_cle = $tag->getAttribute('k');
$tag_val = $tag->getAttribute('v');
 
switch ($tag_cle) {
case 'name' :
$commune_nom = $this->proteger($tag_val);
$commune_nom = $tag_val;
break;
case 'ref:INSEE' :
$commune_insee = $this->proteger($tag_val);
$commune_insee = $tag_val;
break;
}
 
if (!is_null($commune_nom) && !is_null($commune_insee)) {
$this->relations_communes[] = array($relation_id, $commune_nom, $commune_insee);
 
if (!isset($this->relations_communes[$relation_id])) {
$this->relations_communes[$relation_id] = array($relation_id, $commune_nom, $commune_insee);
} else {
$e = "La relation #%s possédant le tag ref:INSEE «%s» est déjà prise en compte.";
$this->messages->traiterErreur($e, array($relation_id, $commune_insee));
}
 
if (!isset($this->communes[$commune_insee])) {
$this->communes[$commune_insee] = $relation_id;
} else {
$e = "La relation #%s contient déjà le tag ref:INSEE avec la valeur %s.".
"Veuillez corriger la carte OSM.";
$this->traiterErreur($e, array($this->communes[$commune_insee], $commune_insee, $relation_id));
$this->messages->traiterErreur($e, array($this->communes[$commune_insee], $commune_insee, $relation_id));
}
break;
break;// Stoppe le foreach car nous avons les infos nécessaires
}
}
}
151,15 → 165,17
* Récupère l'id_way et tous les id_node de chaque way et remplie la table `osm_chemin_a_noeuds`
*/
private function analyserWay($way) {
$chemin_id = $this->proteger($way->getAttribute('id'));
$ordre = 0;
$chemin_id = $way->getAttribute('id');
$ordre = 1;
$noeuds = $way->getElementsByTagName('nd');
$chemin_a_noeuds = array();
foreach ($noeuds as $noeud) {
$noeud_id = $this->proteger($noeud->getAttribute('ref'));
$ordre++;
$this->chemin_a_noeuds[] = array($chemin_id, $noeud_id, $ordre);
$noeud_id = $noeud->getAttribute('ref');
$this->chemin_a_noeuds[] = array($chemin_id, $noeud_id, $ordre++);
}
 
if (count($this->chemin_a_noeuds) > $this->pas) {
$this->insererCheminANoeuds();
}
}
 
/**
166,502 → 182,63
* Fonction qui récupère tous les l'id_node et les valeurs(Lat/Lon) correspondantes et remplie la table `osm_noeuds`
*/
private function analyserNode($node) {
$noeud_id = $this->proteger($node->getAttribute('id'));
$lat = $this->proteger($node->getAttribute('lat'));
$lon = $this->proteger($node->getAttribute('lon'));
$noeud_id = $node->getAttribute('id');
$lat = $node->getAttribute('lat');
$lon = $node->getAttribute('lon');
$this->noeuds[] = array($noeud_id, $lat, $lon);
 
if (count($this->noeuds) > $this->pas) {
$this->insererNoeuds();
}
}
 
private function insererRelationsCommunes() {
$requete = 'INSERT INTO osm_relations (id_relation, nom, code_insee) '.
'VALUES '.$this->creerValuesMultiple($this->relations_communes);
$this->inserer($requete);
if (count($this->relations_communes) > 0) {
$requete = 'INSERT INTO osm_relations (id_relation, nom, code_insee) '.
'VALUES '.$this->creerValuesMultiple($this->relations_communes).
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
$this->relations_communes = array();
}
 
private function insererRelationAChemins() {
$requete = 'INSERT INTO osm_relation_a_chemins (id_relation, id_chemin, role) '.
'VALUES '.$this->creerValuesMultiple($this->relation_a_chemins);
$this->inserer($requete);
if (count($this->relation_a_chemins) > 0) {
$requete = 'INSERT INTO osm_relation_a_chemins (id_relation, id_chemin, role) '.
'VALUES '.$this->creerValuesMultiple($this->relation_a_chemins).
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
$this->relation_a_chemins = array();
}
 
private function insererCheminANoeuds() {
$requete = 'INSERT INTO osm_chemin_a_noeuds (id_chemin, id_noeud, ordre) '.
'VALUES '.$this->creerValuesMultiple($this->chemin_a_noeuds);
$this->inserer($requete);
if (count($this->chemin_a_noeuds) > 0) {
$requete = 'INSERT INTO osm_chemin_a_noeuds (id_chemin, id_noeud, ordre) '.
'VALUES '.$this->creerValuesMultiple($this->chemin_a_noeuds).
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
$this->chemin_a_noeuds = array();
}
 
private function insererNoeuds() {
$requete = 'INSERT INTO osm_noeuds (id_noeud, lat, `long`) '.
'VALUES '.$this->creerValuesMultiple($this->noeuds);
$this->inserer($requete);
if (count($this->noeuds) > 0) {
$requete = 'INSERT INTO osm_noeuds (id_noeud, lat, `long`) '.
'VALUES '.$this->creerValuesMultiple($this->noeuds).
' -- '.__FILE__.' : '.__LINE__;
$this->bdd->requeter($requete);
}
$this->noeuds = array();
}
 
/**
* Fonction qui rajoute l'ordre et le sens de chaque way d'une relation dans la table `osm_relation_a_chemins`
* ALGO:
* -On fait un select de toutes les ways d'une relation.
* -On fait un count sur le tableau ways resutlant.
* -On met l'ordre du premier Way à 0.
* -On met : Actuelway = id_premier_way
* -Select dans table nodes, les nodes du way actuel
* -On prend le dernier noeud
* -On met : ActuelNoeud = id_dernier_noeud
* -Boucle for (i = 0; i < count(tabeau_way); i++) { sur le nombre de ways
* -On sélectionne id_way suivant qui contient le dernier_noeud du précédent
* (En écartant l'id_way déja existant )
* -On recherche les noeuds du nouveau way
* -On teste sur les extrémités du way précédent(dernier noeud) et suivant(premier noeud)
* -si égalité: $nombrePolygone=1;
* -sens:directe
* -ordre++
* -ActuelNoeud = id_dernier_noeud
* sinon
* -sens:indirecte
* -ordre++
* -ActuelNoeud = id_premier_noeud
* }
*/
private function ordonnerWays() {
$requete = 'SELECT DISTINCT id_relation '.
'FROM osm_relation_a_chemins ';
$relations = $this->bdd->recupererTous($requete);
foreach ($relations as $relation) {
$idRelation = $relation['id_relation'];
$requete = 'SELECT id_chemin '.
'FROM osm_relation_a_chemins '.
"WHERE id_relation = $idRelation";
$ways = $this->bdd->recupererTous($requete);
$nombreWays = count($ways);
// premier élément du tableau
$idPremierWay = $ways[0]['id_chemin'];
$wayActuel = $idPremierWay;
$requete = 'UPDATE osm_relation_a_chemins '.
'SET ordre = 0, sens = "directe" '.
"WHERE id_relation = $idRelation ".
"AND id_chemin = $wayActuel ";
$this->inserer($requete);
// selection dernier noeud
$requete = 'SELECT id_noeud '.
'FROM osm_chemin_a_noeuds '.
"WHERE id_chemin = $wayActuel ORDER BY ordre";
$nodes = $this->bdd->recupererTous($requete);
$nombreNodes = count($nodes);
$dernierNoeud = $nodes[$nombreNodes - 1]['id_noeud'];
$noeudActuel = $dernierNoeud;
for ($ordre = 1; $ordre < $nombreWays; $ordre++) {
//selectionner le way qui possède le dernier noeud du précédent way et écarter l'actuel
$requete = 'SELECT WN.id_chemin '.
'FROM osm_relation_a_chemins AS RW LEFT JOIN osm_chemin_a_noeuds AS WN ON (RW.id_chemin = WN.id_chemin) '.
"WHERE WN.id_noeud = $noeudActuel ".
"AND WN.id_chemin != $wayActuel ".
"AND RW.id_relation = $idRelation ";
$ways = $this->bdd->recupererTous($requete);
if (isset($ways[0])) {
$wayActuel = $ways[0]['id_chemin'];
$requete = 'SELECT id_noeud '.
'FROM osm_chemin_a_noeuds '.
"WHERE id_chemin = $wayActuel ORDER BY ordre ";
$nodes = $this->bdd->recupererTous($requete);
$nombreNodes = count($nodes);
if ( strcmp($nodes[0]['id_noeud'], $noeudActuel ) == 0 ) {
$requete = 'UPDATE osm_relation_a_chemins '.
"SET ordre = '$ordre', sens = 'directe' ".
"WHERE id_relation = $idRelation ".
"AND id_chemin = $wayActuel ";
$this->inserer($requete);
$noeudActuel = $nodes[$nombreNodes-1]['id_noeud'];
} else {
$requete = 'UPDATE osm_relation_a_chemins '.
"SET ordre = '$ordre', sens = 'indirecte' ".
"WHERE id_relation = $idRelation ".
"AND id_chemin = $wayActuel";
$this->inserer($requete);
$noeudActuel = $nodes[0]['id_noeud'];
}
}
}
}
}
 
/**
* Fonction qui parcourt tous les ways les noeuds de chaque relation en prenant en considération l'ordre et
* le sens de chaque ways concaténés ensemble(séparés par des virgules). Update du champ polygone de chaque
* relation dans la table `osm_relations`
*/
private function remplirPolygone() {
$polygone = array();
$idNodes = array();
$String = '';
$requete = 'SELECT id_relation, nom, code_insee FROM osm_relations ';
$relations = $this->bdd->recupererTous($requete);
foreach ($relations as $relation) {
$idCommune = $relation['id_relation'];
$nomCommune = $relation['nom'];
$INSEE = $relation['code_insee'];
$requete = 'SELECT id_chemin FROM osm_relation_a_chemins '.
"WHERE id_relation = $idCommune ".
'ORDER BY ordre';
$ways = $this->bdd->recupererTous($requete);
foreach ($ways as $way) {
$idWay = $way['id_chemin'];
$requeteSensWay= "SELECT sens FROM osm_relation_a_chemins WHERE id_relation = $idCommune
AND id_chemin = $idWay";
$sens = $this->bdd->recupererTous($requeteSensWay);
$requeteNodes = "SELECT id_noeud FROM osm_chemin_a_noeuds WHERE id_chemin= $idWay ORDER BY ordre ";
$nodes = $this->bdd->recupererTous($requeteNodes);
if($sens[0]['sens'] == "directe") {
foreach ($nodes as $node) {
$idNodes[] = $node['id_noeud'];
}
$noeuds = implode(", ", $idNodes);
//requête IN qui gère l'ordre des noeuds de chaque way (CAS ASC)
$requeteLatitudeLongitude = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '.
'FROM osm_chemin_a_noeuds WN, osm_noeuds NLL '.
"WHERE NLL.id_noeud IN ($noeuds) ".
'AND WN.id_noeud = NLL.id_noeud '.
"AND WN.id_chemin = $idWay ORDER BY WN.ordre ASC";
unset($noeuds);
unset($idNodes);
$LatLons = $this->bdd->recupererTous($requeteLatitudeLongitude);
foreach ($LatLons as $LatLon) {
$Latitude = $LatLon['lat'];
$Longitude = $LatLon['long'];
$String = "$Latitude $Longitude";
$polygone[] = $String;
}
} else {
foreach ($nodes as $node) {
$idNodes[] = $node['id_noeud'];
}
$noeuds = implode(", ", $idNodes);
//requête IN qui gère l'ordre des noeuds de chaque way (CAS DESC)
$requeteLatitudeLongitude = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '.
'FROM osm_chemin_a_noeuds WN ,osm_noeuds NLL '.
"WHERE NLL.id_noeud IN ($noeuds) ".
'AND WN.id_noeud = NLL.id_noeud '.
"AND WN.id_chemin = $idWay ORDER BY WN.ordre DESC";
unset($noeuds);
unset($idNodes);
$LatLons = $this->bdd->recupererTous($requeteLatitudeLongitude);
foreach ($LatLons as $LatLon) {
$Latitude = $LatLon['lat'];
$Longitude = $LatLon['long'];
$String = "$Latitude $Longitude";
$polygone[] = $String;
}
}
}
$this->etatPolygone($polygone, $idCommune, $nomCommune, $INSEE);
unset($separationVirgule);
unset($requeteNodes);
unset($String);
unset($polygone);
}
}
 
private function etatPolygone($polygone, $idCommune, $nomCommune, $INSEE) {
$separationVirgulePolygone = implode(', ', $polygone);
$nomCommuneProtege = $this->bdd->proteger($nomCommune);
$InseeProtege = $this->bdd->proteger($INSEE);
if ($polygone[0] == $polygone[count($polygone)-1]) { //test sur début et fin du polygone
//requête replace pour gérer la mise à jour à la suite
$requete = 'REPLACE INTO osm_communes (id_relation, nom, code_insee, polygon, note ) '.
"VALUES ($idCommune, $nomCommuneProtege, $InseeProtege, ".
"POLYFROMTEXT('MULTIPOLYGON ((($separationVirgulePolygone)))'),'Polygone complet');";
} else {
$requete = 'REPLACE INTO osm_communes (id_relation, nom, code_insee, polygon, note ) '.
"VALUES ($idCommune, $nomCommuneProtege, $InseeProtege, ".
"POLYFROMTEXT('MULTIPOLYGON ((($separationVirgulePolygone)))'),'Polygone incomplet');";
}
$this->inserer($requete);
}
 
//Fonction qui remet à zéro l'ordre des ways des communes des polygones incomplets fait précédement
private function remettreOrdreAZero() {
$requeteRelations = "SELECT id_relation FROM osm_communes WHERE note LIKE 'Polygone incomplet'";
$relations = $this->bdd->recupererTous($requeteRelations);
foreach ($relations as $relation) {
$idRelation = $relation['id_relation'];
$requeteWays = "SELECT id_chemin FROM osm_relation_a_chemins WHERE id_relation= $idRelation";
$ways = $this->bdd->recupererTous($requeteWays);
foreach ($ways as $way) {
$idWay = $way['id_chemin'];
$this-> inserer('UPDATE osm_relation_a_chemins SET ordre = NULL '.
"WHERE id_relation = $idRelation AND id_chemin = $idWay ;");
}
}
 
}
 
/**
* Fonction qui récupère les relations des polygones incomplets et appelle pour chaque relation la fonction
* ordonnerPolygoneIncomplet($ordre,$tour,$idRelation,$nombrePolygone)
*/
private function relationsPolygoneIncomplet($ordre, $tour) {
$nombrePolygone = 1;
$requeteRelations = "SELECT id_relation FROM osm_communes WHERE note LIKE 'Polygone incomplet'";
$relations = $this->bdd->recupererTous($requeteRelations);
foreach ($relations as $relation) {
$nombrePolygone = 1;
$idRelation = $relation['id_relation'];
$this->ordonnerPolygoneIncomplet($ordre,$tour,$idRelation,$nombrePolygone);
}
}
 
/**
* Fonction récursive qui exécute la même tâche que la fonction ordonnerWays() pour chaque polygone d'un
* multipolygone et remplie le champ NbPoly dans la table `osm_relation_a_chemins` qui correspond au nombre de polygone fermé
* dans le multipolygone
*/
private function ordonnerPolygoneIncomplet($ordre, $tour, $idRelation, $nombrePolygone) {
$requeteWays = 'SELECT id_chemin FROM osm_relation_a_chemins '.
"WHERE id_relation = $idRelation AND ordre = 'NULL'";
$ways = $this->bdd->recupererTous($requeteWays);
$tempWays = $ways;
$nombreWays = count($ways);
// premier élément du tableau
$idPremierWay = $ways[0]['id_chemin'];
$wayActuel = $idPremierWay;
$this-> inserer('UPDATE osm_relation_a_chemins '.
"SET ordre = $ordre, sens = 'directe', nbre_poly = $nombrePolygone ".
"WHERE id_relation = $idRelation ".
"AND id_chemin = $wayActuel ;");
//selection dernier noeud
$requeteNodes = "SELECT id_noeud FROM osm_chemin_a_noeuds WHERE id_chemin = $wayActuel ORDER BY ordre;";
$nodes = $this->bdd->recupererTous($requeteNodes);
$nombreNodes = count($nodes);
$premierNoeud = $nodes[0]['id_noeud'];
$dernierNoeud = $nodes[$nombreNodes-1]['id_noeud'];
$noeudActuel = $dernierNoeud;
$tour++;
//Condition pour laquelle la boucle while continue à tourner; tant que le premier noeud du polygone n'est
//égale au dernier et tant qu'il reste des ways à gérer
while (($premierNoeud != $noeudActuel) && (($ordre % 1000) < count($tempWays))) {
//select le way qui possède le dernier noeud du précédent way et écarter l'actuel
$nombrePolygone;
$ordre++;
//select des ways qui n'ont pas été ordonnés: on obtient à chaque itération les ways qui restent à ordonner
$requeteWays = 'SELECT WN.id_chemin FROM (osm_chemin_a_noeuds WN, osm_relation_a_chemins RW) '.
"WHERE WN.id_noeud = $noeudActuel AND WN.id_chemin != $wayActuel ".
"AND RW.id_chemin = WN.id_chemin AND RW.id_relation = $idRelation ".
"AND RW.ordre = 'NULL' ;";
$ways = $this->bdd->recupererTous($requeteWays);
 
if (isset($ways[0])) {
$wayActuel = $ways[0]['id_chemin'];
$requeteNodes = "SELECT id_noeud FROM osm_chemin_a_noeuds WHERE id_chemin = $wayActuel ORDER BY ordre;";
$nodes = $this->bdd->recupererTous($requeteNodes);
$nombreNodes = count($nodes);
if (strcmp($nodes[0]['id_noeud'], $noeudActuel ) == 0) {
$this-> inserer("UPDATE osm_relation_a_chemins SET ordre = '$ordre', sens = 'directe', ".
"nbre_poly = $nombrePolygone ".
"WHERE osm_relation_a_chemins.id_relation = $idRelation ".
"AND osm_relation_a_chemins.id_chemin = $wayActuel");
$noeudActuel = $nodes[$nombreNodes-1]['id_noeud'];
} else {
$this-> inserer('UPDATE osm_relation_a_chemins '.
"SET ordre = '$ordre', sens = 'indirecte', ".
"nbre_poly = $nombrePolygone ".
"WHERE id_relation = $idRelation ".
"AND id_chemin = $wayActuel");
$noeudActuel = $nodes[0]['id_noeud'];
}
}
}
$ordre = 1000 * $tour; //différencier chaque polygone: pour chaque polygone on a un multiple de mille
$requeteCount = "SELECT ordre FROM osm_relation_a_chemins WHERE id_relation = $idRelation AND ordre = 0";
$count = $this->bdd->recupererTous($requeteCount);
if ((count($count)) != 0) { // s'ils en restent des ways à gérer
$nombrePolygone++;
//appelle de la fonction récursive
$this->ordonnerPolygoneIncomplet($ordre, $tour, $idRelation, $nombrePolygone);
}
}
 
/**
* Fonction qui récupère les relations des polygones incomplets et appelle pour chaque relation la fonction
* remplirPolygoneIncomplet($idRelation);
*/
private function remplirCommunesPolygoneIncomplet() {
$nombrePolygone = 1;
$requeteRelations = "SELECT id_relation FROM osm_communes WHERE note LIKE 'Polygone incomplet'";
$relations = $this->bdd->recupererTous($requeteRelations);
foreach ($relations as $relation) {
$idRelation = $relation['id_relation'];
$this->remplirPolygoneIncomplet($idRelation);//appel de la fonction avec comme paramètre ID-commune
}
}
 
/**
* Fonction qui exécute la même tâche que la fonction remplirPolygone() pour chaque polygone d'un multipolygone
* et renvoie un tableau MultiPolygone[] où chaque case contient un polygone fermé et appelle la fonction
* etatMultiPolygone($multiPolygone, $idCommune) qui remplie le Multipolygone de la commune correspondante
*/
private function remplirPolygoneIncomplet($idCommune) {
$polygone = array();
$multiPolygone = array();//tableau multipolygone qui contient tous les polygones d'un multipolygone
$idNodes = array();
$roles = array();//tableau roles qui contient les roles des ways
$String = "";
//sélectionner le nombre de polygones qui existe dans un multipolygone
$requete = 'SELECT MAX(nbre_poly) AS nbre_poly '.
'FROM osm_relation_a_chemins '.
"WHERE id_relation = $idCommune";
$nombrePolygone = $this->bdd->recupererTous($requete);
$nbPoly = $nombrePolygone[0]['nbre_poly'];
for ($tour = 1; $tour <= $nbPoly; $tour++) {//boucle for qui parcourt chaque polygone du multipolygone
$requeteWays = 'SELECT id_chemin FROM osm_relation_a_chemins '.
"WHERE id_relation = $idCommune ".
"AND nbre_poly = $tour ORDER BY ordre";
$ways = $this->bdd->recupererTous($requeteWays);
foreach ($ways as $way) {
$idWay = $way['id_chemin'];
$requeteSensWay = 'SELECT sens FROM osm_relation_a_chemins '.
"WHERE id_relation = $idCommune ".
"AND id_chemin = $idWay";//sélection de l'orientation du way
$sens= $this->bdd->recupererTous($requeteSensWay);
$requeteNodes = "SELECT id_noeud FROM osm_chemin_a_noeuds WHERE id_chemin= $idWay ORDER BY ordre";
$nodes = $this->bdd->recupererTous($requeteNodes);
if ($sens[0]['sens'] == "directe") {//test sur le sens des ways
foreach ($nodes as $node) {
$idNodes[] = $node['id_noeud'];
}
$noeuds = implode(", ", $idNodes);
//requête IN qui gère l'ordre des noeuds de chaque way (CAS ASC)
$requeteLatitudeLongitude = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '.
'FROM osm_chemin_a_noeuds WN, osm_noeuds NLL '.
"WHERE NLL.id_noeud IN ($noeuds) ".
'AND WN.id_noeud = NLL.id_noeud '.
"AND WN.id_chemin= $idWay ORDER BY WN.ordre ASC";
unset($noeuds);
unset($idNodes);
$LatLons = $this->bdd->recupererTous($requeteLatitudeLongitude);
foreach ($LatLons as $LatLon) {
$Latitude = $LatLon['lat'];
$Longitude = $LatLon['long'];
$String = "$Latitude $Longitude";
$polygone[] = $String;
}
} else {
foreach ($nodes as $node) {
$idNodes[] = $node['id_noeud'];
}
$noeuds = implode(", ", $idNodes);
//requête IN qui gère l'ordre des noeuds de chaque way (CAS DESC)
$requeteLatitudeLongitude = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '.
'FROM osm_chemin_a_noeuds WN, osm_noeuds NLL '.
"WHERE NLL.id_noeud IN ($noeuds) ".
'AND WN.id_noeud = NLL.id_noeud '.
"AND WN.id_chemin= $idWay ORDER BY WN.ordre DESC";
unset($noeuds);
unset($idNodes);
$LatLons = $this->bdd->recupererTous($requeteLatitudeLongitude);
foreach ($LatLons as $LatLon) {
$Latitude = $LatLon['lat'];
$Longitude = $LatLon['long'];
$String = "$Latitude $Longitude";
$polygone[] = $String;
}
}
}
$requeteRole = 'SELECT DISTINCT role '.
'FROM osm_relation_a_chemins '.
"WHERE id_relation = $idCommune ".
"AND nbre_poly = $tour ";
$role = $this->bdd->recupererTous($requeteRole);
$role = $role[0]['role'];
$separationVirgulePolygone = implode(", ", $polygone);
$multiPolygone[] = $separationVirgulePolygone;
$roles[] = $role;
unset($separationVirgulePolygone);
unset($polygone);
}
$this->etatMultiPolygone($multiPolygone, $roles, $idCommune, $nbPoly);//appel de la fonction de remplissage
}
 
/**
* Remplie le champ polygone à partir du tableau MultiPolygone
*/
private function etatMultiPolygone($multiPolygone, $roles, $idCommune, $nbPoly) {
$note = $this->proteger('Polygone complet');
if ($nbPoly == 2 && ((in_array('inner', $roles)) || (in_array('enclave', $roles)))) {//cas Outer Inner à deux polygones
$multiPoly = implode('),(', $multiPolygone);
$requete = 'UPDATE osm_communes '.
"SET polygon = MPOLYFROMTEXT('MULTIPOLYGON((($multiPoly)))'), ".
"note = $note ".
"WHERE id_relation = $idCommune ";
$this->inserer($requete);
}
if ((in_array('inner', $roles)) || (in_array('enclave', $roles)) != 1) { //tous les autres cas
$multiPoly = implode(')),((', $multiPolygone);
$requete = 'UPDATE osm_communes '.
"SET polygon = MPOLYFROMTEXT('MULTIPOLYGON((($multiPoly)))'), ".
"note = $note ".
"WHERE id_relation = $idCommune ";
$this->inserer($requete);
}
}
 
/**
* Renomme la note des polygones vides d'un polygone complet en polygone incomplet
*/
private function renommerEnPolygoneIncomplet() {
$requete = 'SELECT id_relation, ASTEXT(polygon) AS poly '.
'FROM osm_communes ';
$etatPolygones = $this->bdd->recupererTous($requete);
foreach ($etatPolygones as $etatPolygone ) {
if (isset($etatPolygone['poly']) == 0) {//test si le polygone est vide
$idCommune = $this->proteger($etatPolygone['id_relation']);
$note = $this->proteger('Polygone incomplet');
$requete = 'UPDATE osm_communes '.
"SET note = $note ".
"WHERE id_relation = $idCommune ";
$this->inserer($requete);
}
}
}
 
 
/**
* Récupère le point centre de chaque polygone et remplie la colonne "centre"
*/
private function centroid() {
$requete = 'SELECT id_relation, ASTEXT(polygon) AS poly '.
'FROM osm_communes ';
$communes = $this->bdd->recupererTous($requete);
foreach ($communes as $commune) {
$multipolygone = $commune['poly'];
$requete = "SELECT ASTEXT(CENTROID(MPOLYFROMTEXT('$multipolygone'))) AS centre ";
$point = $this->bdd->recupererTous($requete);
$centre = $this->proteger($point[0]['centre']);
$idCom = $this->proteger($commune['id_relation']);
$requete = 'UPDATE osm_communes '.
"SET centre = POINTFROMTEXT($centre) ".
"WHERE id_relation = $idCom ";
$this->inserer($requete);
}
}
 
private function creerValuesMultiple($donnees) {
$values = array();
foreach ($donnees as $donnee) {
$values[] = implode(',', $donnee);
foreach ($donnees as $infos) {
$infosP = $this->bdd->proteger($infos);
$values[] = implode(',', $infosP);
}
$values_chaine = '('.implode('),(', $values).')';
return $values_chaine;
$valuesClause = '('.implode('),(', $values).')';
return $valuesClause;
}
 
private function inserer($requete) {
$this->bdd->requeter($requete);
}
 
private function proteger($chaine) {
return $this->bdd->proteger($chaine);
}
 
}
?>
}
/trunk/scripts/modules/osm/shell/carto-osm-service
New file
0,0 → 1,41
#!/bin/sh
#/etc/rc.d/init.d/
#
# Jean-Pascal MILCENT & Mohcen BENMOUNAH [19 juillet 2011]
# Service de lancement des scripts d'integration des donnees OSM pour le service de Geocadage Inverse
#
case "$1" in
 
start)
 
echo "Demarrage de carto-osm-cron :"
nohup /usr/local/sbin/carto-osm-cron 1>/dev/null 2>/dev/null &
 
;;
 
stop)
 
echo "Arret de carto-osm-cron"
PID=`ps -eaf | grep carto-osm-cron | grep -v grep | tr -s ' ' | cut -d' ' -f2 | head -n1`
kill -9 ${PID}
 
;;
 
status)
 
echo -n "Voici les PID du processus carto-osm-cron :"
PID=`ps -eaf | grep carto-osm-cron | grep -v grep | tr -s ' ' | cut -d' ' -f2 | head -n1`
echo ${PID}
 
;;
 
 
*)
 
echo "Usage: {start|stop|status}"
 
exit 1
 
;;
 
esac
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/scripts/modules/osm/shell/carto-osm-cron
New file
0,0 → 1,30
#!/bin/bash
#
# Mohcen BENMOUNAH & Jean-Pascal MILCENT [19 juillet 2011]
# /etc/init.d/carto-osm : demarage/arrete/etat du cron de l'integration des donnees OSM pour le Geocodage Inverse (carto-osm)
# Lancement toutes les semaines le samedi matin après 3h00
 
while true
do
JOUR=$(date "+%u")
# Si nous sommes samedi (=6)
if [ $JOUR -eq 6 ] ; then
HEURE=$(date "+%H")
# Si nous sommes à 3 heures du matin
if [ $HEURE -eq 3 ] ; then
logger "carto-osm-maj : lancement script"
sudo -u telabotap /usr/local/sbin/carto-osm-maj
logger "carto-osm-maj : arret script"
# Nous retenterons de vérifier jour et heure dans 6 jours
sleep 6d
else
# Tentative toutes les heures
logger "carto-osm-maj : tentative heure $HEURE"
sleep 1h
fi
else
# Tentative tous les jours
logger "carto-osm-maj : tentative jour $JOUR"
sleep 1d
fi
done
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/scripts/modules/osm/shell/carto-osm-maj
New file
0,0 → 1,91
#!/bin/bash
#
# Script de lancement de l'integration des donnees OSM pour le geocodage inverse
# Mohcen BENMOUNAH & Jean-Pascal MILCENT [19 juillet 2011]
#
ageEnSeconde(){ expr `date +%s` - `stat -c %Y $1`; };
 
if [ -f config.cfg ] ; then
source config.cfg
echo $DATE;
else
echo "Veuillez paramétrer le script en renommant le fichier 'config.defaut.cfg' en 'config.cfg'."
exit;
fi
 
echo "Export de l'emplacement du binaire Java dans la variable d'environnement JAVACMD";
export JAVACMD="$CHEMIN_JAVA"
 
echo "Export de l'emplacement du dossier tmp pour Osmosis"
export JAVACMD_OPTIONS="-Djava.io.tmpdir=$OSMOSIS_DOSSIER_TMP -Xmx4G"
 
if [ ! -f "$DOSSIER_OSM/$FICHIER_OSM" ] || [ `ageEnSeconde "$DOSSIER_OSM/$FICHIER_OSM"` -gt 86000 ] ; then
echo "Téléchargement du nouveau fichier PBF ...";
wget $URL_FICHIER_OSM -O "$DOSSIER_OSM/$FICHIER_OSM"
else
echo "Fichier $FICHIER_OSM existant à moins d'un jour.";
fi
 
if [ ! -f "$DOSSIER_OSM/$FICHIER_ZG_NEW" ] || [ `ageEnSeconde "$DOSSIER_OSM/$FICHIER_ZG_NEW"` -gt 86000 ] ; then
echo "Filtrage du fichier en cours ...";
$CHEMIN_OSMOSIS \
-v \
--read-pbf-fast "$DOSSIER_OSM/$FICHIER_OSM" workers=6 \
--tf accept-relations admin_level=8 \
--tf accept-relations type=boundary \
--tf accept-relations ref:INSEE=* \
--used-way \
--used-node \
--wx "$DOSSIER_OSM/$FICHIER_ZG_NEW"
fi
 
HEURE_DEBUT=`date +"%F %X"`;
echo "Début éxecution scripts php : $HEURE_DEBUT";
 
if [ ! -f "$DOSSIER_OSM/$FICHIER_ZG_OLD" ] ; then
echo "Création des tables osm en cours ...";
$CHEMIN_PHP -d memory_limit=$MEMORY_LIMIT_PHP $CHEMIN_SCRIPT/cli.php osm -a chargerStructureSql -v $VERBOSITE > $FICHIER_LOG
 
echo "Analyse du fichier osm en cours ...";
$CHEMIN_PHP -d memory_limit=$MEMORY_LIMIT_PHP $CHEMIN_SCRIPT/cli.php osm -a analyser -v $VERBOSITE -f "$DOSSIER_OSM/$FICHIER_ZG_NEW" >> $FICHIER_LOG
else
echo "Suppression du fichier DIFF existant en cours ...";
rm -f "$DOSSIER_OSM/$FICHIER_ZG_DIFF"
 
echo "Déduction de la différence en cours ...";
$CHEMIN_OSMOSIS\
--read-xml file="$DOSSIER_OSM/$FICHIER_ZG_NEW" \
--read-xml file="$DOSSIER_OSM/$FICHIER_ZG_OLD" \
--derive-change \
--write-xml-change file="$DOSSIER_OSM/$FICHIER_ZG_DIFF"
 
echo "Début de la mise à jour de base ...";
$CHEMIN_PHP -d memory_limit=$MEMORY_LIMIT_PHP $CHEMIN_SCRIPT/cli.php mise_a_jour -a MAJ -f "$DOSSIER_OSM/$FICHIER_ZG_DIFF" > $FICHIER_LOG
fi
 
echo "Renommage du fichier NEW en OLD en cours ...";
mv "$DOSSIER_OSM/$FICHIER_ZG_NEW" "$DOSSIER_OSM/$FICHIER_ZG_OLD" >> $FICHIER_LOG
 
echo "Traitement de l'ordre en cours ...";
$CHEMIN_PHP -d memory_limit=$MEMORY_LIMIT_PHP $CHEMIN_SCRIPT/cli.php osm -a ordre -v $VERBOSITE >> $FICHIER_LOG
 
echo "Remplissage des polygones en cours ...";
$CHEMIN_PHP -d memory_limit=$MEMORY_LIMIT_PHP $CHEMIN_SCRIPT/cli.php osm -a polygone -v $VERBOSITE >> $FICHIER_LOG
 
echo "Remise de l'ordre à zéro en cours ...";
$CHEMIN_PHP -d memory_limit=$MEMORY_LIMIT_PHP $CHEMIN_SCRIPT/cli.php osm -a zero -v $VERBOSITE >> $FICHIER_LOG
 
echo "Traitement de l'ordre des polygones incomplets en cours ...";
$CHEMIN_PHP -d memory_limit=$MEMORY_LIMIT_PHP $CHEMIN_SCRIPT/cli.php osm -a ordonnerPolygoneInc -v $VERBOSITE >> $FICHIER_LOG
 
echo "Remplissage des polygones incomplets en cours ...";
$CHEMIN_PHP -d memory_limit=$MEMORY_LIMIT_PHP $CHEMIN_SCRIPT/cli.php osm -a remplirPolygoneInc -v $VERBOSITE >> $FICHIER_LOG
 
echo "Renommage des polygones incomplets en cours ...";
$CHEMIN_PHP -d memory_limit=$MEMORY_LIMIT_PHP $CHEMIN_SCRIPT/cli.php osm -a renommer -v $VERBOSITE >> $FICHIER_LOG
 
echo "Definition des centroïdes en cours ...";
$CHEMIN_PHP -d memory_limit=$MEMORY_LIMIT_PHP $CHEMIN_SCRIPT/cli.php osm -a centre -v $VERBOSITE >> $FICHIER_LOG
 
HEURE_FIN=`date +"%F %X"`;
echo "Fin éxecution scripts php : $HEURE_FIN";
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/scripts/modules/osm/shell/config.defaut.cfg
New file
0,0 → 1,26
# Binaires
CHEMIN_JAVA="/usr/local/jre/bin/java"
CHEMIN_PHP="/usr/local/php/5.5/bin/php"
CHEMIN_SCRIPT="/home/apitela/www/scripts/eflore"
 
# Dossiers, fichiers & urls
# Pour tester : http://download.geofabrik.de/europe/france/languedoc-roussillon-latest.osm.pbf
URL_FICHIER_OSM="http://download.geofabrik.de/europe/france-latest.osm.pbf"
DOSSIER_OSM="/home/jpm/web/eflore/eflore-projets/donnees/osm"
FICHIER_OSM="fr.osm.pbf"
FICHIER_ZG_NEW="fr_communes_new.osm"
FICHIER_ZG_OLD="fr_communes_old.osm"
FICHIER_ZG_DIFF="fr_communes_diff.osm"
 
# Osmosis
CHEMIN_OSMOSIS="/usr/local/sbin/osmosis-0.43.1/bin"
OSMOSIS_DOSSIER_TMP="$DOSSIER_OSM/tmp"
 
# Logs
VERBOSITE=3
DATE=`date +"%F"`
CHEMIN_LOG="$DOSSIER_OSM/logs"
FICHIER_LOG="$CHEMIN_LOG/analyse_${DATE}.log"
 
# Paramètres PHP
MEMORY_LIMIT_PHP="8000M"
/trunk/scripts/modules/osm/shell/extract-poly
New file
0,0 → 1,29
#!/bin/bash
# Utilisation : ./extract-poly fr-p.osm.pbf fr-14
# Paramètres : .
# - 1 : nom du fichier .pbf dont on veut extraire une portion avec un fichier .poly
# - 2 : nom du fichier .poly sans extenssion (l'extrait aura le même nom avec l'extenssion .pbf)
#
if [ -f config.cfg ] ; then
source config.cfg
echo $DATE;
else
echo "Veuillez paramétrer le script en renommant le fichier 'config.defaut.cfg' en 'config.cfg'."
exit;
fi
 
FICHIER_OSM=$1
FICHIER=$2
 
echo "Export de l'emplacement du binaire Java dans la variable d'environnement JAVACMD";
export JAVACMD="$CHEMIN_JAVA"
 
echo "Export de l'emplacement du dossier tmp pour Osmosis"
export JAVACMD_OPTIONS="-Djava.io.tmpdir=$OSMOSIS_DOSSIER_TMP -Xmx4G"
 
echo "Filtrage du fichier en cours ...";
$CHEMIN_OSMOSIS \
-v \
--read-pbf-fast "$DOSSIER_OSM/$FICHIER_OSM" workers=6 \
--bounding-polygon file="$DOSSIER_OSM/$FICHIER.poly" \
--write-pbf file="$DOSSIER_OSM/$FICHIER.pbf"
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/scripts/modules/osm/shell/extract-communes
New file
0,0 → 1,34
#!/bin/bash
# Utilisation : ./extract-communes fr-14
# Paramètres : .
# - 1 : nom du fichier .pbf dont on veut extraire les communes (sans extenssion)
# Sortie : nom du fichier .pbf suffixé par "_new" et avec l'extenssion .osm
#
ageEnSeconde(){ expr `date +%s` - `stat -c %Y $1`; };
 
if [ -f config.cfg ] ; then
source config.cfg
echo $DATE;
else
echo "Veuillez paramétrer le script en renommant le fichier 'config.defaut.cfg' en 'config.cfg'."
exit;
fi
 
FICHIER=$1
 
echo "Export de l'emplacement du binaire Java dans la variable d'environnement JAVACMD";
export JAVACMD="$CHEMIN_JAVA"
 
echo "Export de l'emplacement du dossier tmp pour Osmosis"
export JAVACMD_OPTIONS="-Djava.io.tmpdir=$OSMOSIS_DOSSIER_TMP -Xmx4G"
 
echo "Filtrage du fichier en cours ...";
$CHEMIN_OSMOSIS \
-v \
--read-pbf-fast "$DOSSIER_OSM/$FICHIER.pbf" workers=6 \
--tf accept-relations admin_level=8 \
--tf accept-relations type=boundary \
--tf accept-relations ref:INSEE=* \
--used-way \
--used-node \
--wx "$DOSSIER_OSM/${FICHIER}_new.osm"
Property changes:
Added: svn:executable
+*
\ No newline at end of property
/trunk/scripts/modules/osm/shell
New file
Property changes:
Added: svn:ignore
+config.cfg
/trunk/scripts/modules/osm
Property changes:
Added: svn:ignore
+.config.ini.swp