Rev 880 | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*** Exemple lancement:* /opt/lampp/bin/php -d memory_limit=3500M cli.php osm/mise_a_jour -a MAJ -f fichier_osm_a_analyser*/class MiseAjour extends Script {private $communes = array();private $relations_communes = array();private $relation_a_chemins = array();private $chemin_a_noeuds = array();private $noeuds = array();private $pas = 10000;private $pas_commune = 1000;protected $parametres_autorises = array('-f' => 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 relationsprivate 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 à cheminsprivate 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 à noeudsprivate 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 noeudsprivate function insererNoeuds() {$requete = 'INSERT INTO osm_noeuds (id_noeud, lat, `long`) '.'VALUES '.$this->creerValuesMultiple($this->noeuds);$this->inserer($requete);$this->noeuds = array();}//Update des relationsprivate 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 noeudsprivate 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 relationsprivate 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 à cheminsprivate 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 à noeudsprivate 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 à noeudsprivate 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;}}?>