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 |
* 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 extends Script { |
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'); |
$cmd = $this->conteneur->getParametre('a'); |
switch ($cmd) { |
case 'MAJ' : |
$this->MettreAjour(); |
case 'maj' : |
$this->mettreAjour(); |
break; |
default : |
$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd)); |
$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(); |
private function mettreAjour() { |
$lecteur = $this->getLecteurXml(); |
while ($lecteur->read()) { |
if ($lecteur->nodeType == XMLREADER::ELEMENT) { |
if ($lecteur->localName == 'create') { |
$creations = $lecteur->expand(); |
$this-> analyserCreations($creations); |
$this->elementType = $lecteur->localName; |
$this->analyserElementXml($lecteur->localName, $lecteur->expand()); |
} |
if ($lecteur->localName == 'modify') { |
$modifications = $lecteur->expand(); |
$this-> analyserModifications($modifications); |
|
if ($this->mode == 'manuel') { |
$this->messages->afficherAvancement("Analyse de la ligne du fichier de diff OSM : ", 1); |
} |
if ($lecteur->localName == 'delete') { |
$suppressions = $lecteur->expand(); |
$this-> analyserSuppressions($suppressions); |
} |
} |
|
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); |
} |
} else { |
$e = "Impossible d'ouvrir le fichier osm : %s"; |
$this->traiterErreur($e, array($this->getParametre('f'))); |
return $lecteur; |
} |
} |
|
/** |
* Fonction permettant le traitement du cas création concernant les relations, ways et les noeuds. |
*/ |
private function analyserCreations($creations) { |
$relations = $creations->getElementsByTagName('relation'); |
private function analyserElementXml($noeudDom) { |
$relations = $noeudDom->getElementsByTagName('relation'); |
if ($relations->length > 0) { |
foreach ($relations as $relation) { |
$this-> analyserRelation($relation); |
if (count($this->relation_a_chemins) > $this->pas) { |
$this->insererRelationAChemins(); |
$this->traiterRelations(); |
} |
if (count($this->relations_communes) > $this->pas_commune) { |
$this->insererRelationsCommunes(); |
} |
} |
|
$ways = $creations->getElementsByTagName('way'); |
if ($ways->length > 0) { |
foreach ($ways as $way) { |
$this->analyserWay($way); |
if (count($this->chemin_a_noeuds) > $this->pas) { |
$this->insererCheminANoeuds(); |
$this->traiterCheminANoeuds(); |
} |
} |
|
$noeuds = $creations->getElementsByTagName('node'); |
if ($noeuds->length > 0) { |
foreach ($noeuds as $noeud) { |
$this->analyserNode($noeud); |
if (count($this->noeuds) > $this->pas) { |
$this->insererNoeuds(); |
$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); |
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) { |
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); |
} |
|
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); |
} |
|
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; |
} |
} |
} |
|
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(); |
} |
|
/** |
* 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) { |
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,17 → 254,19 |
* 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); |
'VALUES '.$this->creerValuesMultiple($this->relations_communes). |
' -- '.__FILE__.' : '.__LINE__; |
$this->bdd->requeter($requete); |
$this->relations_communes = array(); |
} |
|
241,8 → 273,9 |
//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); |
'VALUES '.$this->creerValuesMultiple($this->relation_a_chemins). |
' -- '.__FILE__.' : '.__LINE__; |
$this->bdd->requeter($requete); |
$this->relation_a_chemins = array(); |
} |
|
249,8 → 282,9 |
//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); |
'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) { |
foreach ($this->relations_communes as $donnee) { |
$infosP = $this->bdd->proteger($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); |
"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) { |
$idsIn = $this->getIds($this->relations_communes); |
$this->relations_communes = array(); |
$requete = 'DELETE FROM osm_relations '. |
"WHERE id_relation = $donnee[0]"; |
$this->inserer($requete); |
"WHERE id_relation IN ($idsIn) ". |
' -- '.__FILE__.' : '.__LINE__; |
$this->bdd->requeter($requete); |
} |
$this->relations_communes = array(); |
} |
|
//Suppressions des relations à chemins |
private function supprimerRelationAChemins() { |
$donnees = $this->relations_communes; |
foreach ($donnees as $donnee) { |
$donnees = $this->relation_a_chemins; |
$idsIn = $this->getIds($this->relation_a_chemins); |
$this->relation_a_chemins = array(); |
$requete = 'DELETE FROM osm_relation_a_chemins '. |
"WHERE id_relation = $donnee[0]"; |
$this->inserer($requete); |
"WHERE id_relation IN ($idsIn) ". |
' -- '.__FILE__.' : '.__LINE__; |
$this->bdd->requeter($requete); |
} |
$this->relation_a_chemins = array(); |
} |
|
//Suppressions des chemins à noeuds |
private function supprimerCheminANoeuds() { |
$donnees = $this->chemin_a_noeuds; |
foreach ($donnees as $donnee) { |
$donnees = $this->relation_a_chemins; |
$idsIn = $this->getIds($this->chemin_a_noeuds); |
$this->chemin_a_noeuds = array(); |
$requete = 'DELETE FROM osm_chemin_a_noeuds '. |
"WHERE id_chemin = $donnee[0]"; |
$this->inserer($requete); |
"WHERE id_chemin IN ($idsIn) ". |
' -- '.__FILE__.' : '.__LINE__; |
$this->bdd->requeter($requete); |
} |
$this->chemin_a_noeuds = array(); |
} |
|
//Suppressions des chemins à noeuds |
private function supprimerNoeuds() { |
$donnees = $this->noeuds; |
foreach ($donnees as $donnee) { |
$idsIn = $this->getIds($this->noeuds); |
$this->noeuds = array(); |
$requete = 'DELETE FROM osm_noeuds '. |
"WHERE id_noeud = $donnee[0]"; |
$this->inserer($requete); |
} |
$this->noeuds = array(); |
} |
|
private function inserer($requete) { |
"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; |
} |
} |
?> |
} |