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 'maj' : $this->mettreAjour(); 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 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 = $this->getLecteurXml(); while ($lecteur->read()) { if ($lecteur->nodeType == XMLREADER::ELEMENT) { $this->elementType = $lecteur->localName; $this->analyserElementXml($lecteur->localName, $lecteur->expand()); } if ($this->mode == 'manuel') { $this->messages->afficherAvancement("Analyse de la ligne du fichier de diff OSM : ", 1); } } } 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(); } } $ways = $creations->getElementsByTagName('way'); if ($ways->length > 0) { foreach ($ways as $way) { $this->analyserWay($way); $this->traiterCheminANoeuds(); } } $noeuds = $creations->getElementsByTagName('node'); if ($noeuds->length > 0) { foreach ($noeuds as $noeud) { $this->analyserNode($noeud); $this->traiterNoeuds(); } } $this->traiterElementsOrphelins(); } 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; } } } 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; } } } 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(); break; case 'delete' : $this->supprimerRelationsCommunes(); $this->supprimerRelationAChemins(); $this->supprimerCheminANoeuds(); $this->supprimerNoeuds(); break; } } /** * Récupère l'id commune, nom commune et le code INSEE et remplie la table `osm_relations` */ private function analyserRelation($relation) { $relation_id = $relation->getAttribute('id'); $chemins = $relation->getElementsByTagName('member'); foreach ($chemins as $chemin) { if ($chemin->getAttribute('type') == 'way') { //écarter le noeud centrale $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; foreach ($tags as $tag) { $tag_cle = $tag->getAttribute('k'); $tag_val = $tag->getAttribute('v'); switch ($tag_cle) { case 'name' : $commune_nom = $tag_val; break; case 'ref:INSEE' : $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->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)); } break; } } } /** * 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 = $way->getAttribute('id'); $noeuds = $way->getElementsByTagName('nd'); $ordre = 0; foreach ($noeuds as $noeud) { $noeud_id = $noeud->getAttribute('ref'); $this->chemin_a_noeuds[] = array($chemin_id, $noeud_id, ++$ordre); } } /** * 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) { $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). ' -- '.__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). ' -- '.__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). ' -- '.__FILE__.' : '.__LINE__; $this->bdd->requeter($requete); $this->chemin_a_noeuds = array(); } //Insertion des noeuds private function insererNoeuds() { $requete = 'INSERT INTO osm_noeuds (id_noeud, lat, `long`) '. 'VALUES '.$this->creerValuesMultiple($this->noeuds). ' -- '.__FILE__.' : '.__LINE__; $this->bdd->requeter($requete); $this->noeuds = array(); } //Update des relations private function modifierRelationsCommunes() { 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(); } /* *Update des relations à chemins en supprimant l'ancienne relation et tous ses chemins *de la table osm_relation_a_chemins et insérer la nouvelle */ private function modifierRelationAChemins() { $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 ($infosP[0], $infosP[1], $infosP[2]) ". ' -- '.__FILE__.' : '.__LINE__; $this->bdd->requeter($requete); } $this->relation_a_chemins = array(); } /* *Update des chemins à noeuds en supprimant l'ancien chemin et tous ses noeuds *de la table osm_chemins_a_noeuds et insérer le nouveau */ private function modifierCheminANoeuds() { $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 ($infosP[0], $infosP[1], $infosP[2]) ". ' -- '.__FILE__.' : '.__LINE__; $this->bdd->requeter($requete); } $this->chemin_a_noeuds = array(); } //Update des noeuds private function modifierNoeuds() { foreach ($this->noeuds as $donnee) { $infosP = $this->bdd->proteger($donnee); $requete = 'UPDATE osm_noeuds '. "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() { $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() { $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() { $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() { $idsIn = $this->getIds($this->noeuds); $this->noeuds = array(); $requete = 'DELETE FROM osm_noeuds '. "WHERE id_noeud IN ($idsIn) ". ' -- '.__FILE__.' : '.__LINE__; $this->bdd->requeter($requete); } 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 $infos) { $infosP = $this->bdd->proteger($infos); $values[] = implode(',', $infosP); } $valuesClause = '('.implode('),(', $values).')'; return $valuesClause; } }