array(true, null, 'Chemin du fichier osm à analyser')); public function executer() { $this->bdd = new Bdd(); // Lancement de l'action demandée $cmd = $this->getParametre('a'); switch ($cmd) { case 'MAJ' : $this->MettreAjour(); break; default : $this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd)); } } /** * 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); } } } } else { $e = "Impossible d'ouvrir le fichier osm : %s"; $this->traiterErreur($e, array($this->getParametre('f'))); } } /** * 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(); } 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(); } } $noeuds = $creations->getElementsByTagName('node'); foreach ($noeuds as $noeud) { $this->analyserNode($noeud); if (count($this->noeuds) > $this->pas) { $this->insererNoeuds(); } } $this->insererRelationsCommunes(); $this->insererRelationAChemins(); $this->insererCheminANoeuds(); $this->insererNoeuds(); } /** * 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(); } if (count($this->relations_communes) > $this->pas_commune) { $this->modifierRelationsCommunes(); } } $ways = $modifications->getElementsByTagName('way'); foreach ($ways as $way) { $this->analyserWay($way); if (count($this->chemin_a_noeuds) > $this->pas) { $this->modifierCheminANoeuds(); } } $noeuds = $modifications->getElementsByTagName('node'); foreach ($noeuds as $noeud) { $this->analyserNode($noeud); if (count($this->noeuds) > $this->pas) { $this->modifierNoeuds(); } } $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) { $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(); } } $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')); $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. $this->relation_a_chemins[] = array($relation_id, $chemin_id, $role); } } $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); break; case 'ref:INSEE' : $commune_insee = $this->proteger($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 = $this->proteger($way->getAttribute('id')); $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); } } /** * 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); } //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); $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); $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); $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); $this->inserer($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); } $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() { $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) { $requete = 'INSERT INTO osm_relation_a_chemins (id_relation, id_chemin, role) '. "VALUES ($donnee[0], $donnee[1], $donnee[2]);"; $this->inserer($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() { $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) { $requete = 'INSERT INTO osm_chemin_a_noeuds (id_chemin, id_noeud, ordre) '. "VALUES ($donnee[0], $donnee[1], $donnee[2]);"; $this->inserer($requete); } $this->chemin_a_noeuds = array(); } //Update des noeuds private function modifierNoeuds() { $donnees = $this->noeuds; foreach ($donnees as $donnee) { $requete = 'UPDATE osm_noeuds '. "SET id_noeud = $donnee[0], lat = $donnee[1], `long` = $donnee[2] ". "WHERE id_noeud = $donnee[0]"; $this->inserer($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); } $this->relations_communes = array(); } //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); } $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; $requete = 'DELETE FROM osm_chemin_a_noeuds '. "WHERE id_chemin = $donnee[0]"; $this->inserer($requete); } $this->chemin_a_noeuds = array(); } //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); } $this->noeuds = array(); } private function inserer($requete) { $this->bdd->requeter($requete); } private function proteger($chaine) { return $this->bdd->proteger($chaine); } private function creerValuesMultiple($donnees) { $values = array(); foreach ($donnees as $donnee) { $values[] = implode(',', $donnee); } $values_chaine = '('.implode('),(', $values).')'; return $values_chaine; } } ?>