Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*** 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();private $chemin_a_noeuds = array();private $noeuds = array();private $pas = 10000;private $pas_commune = 1000;private $elementType = '';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 '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 relationsprivate 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 à cheminsprivate 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 à noeudsprivate 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 noeudsprivate 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 relationsprivate 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 noeudsprivate 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 relationsprivate 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 à cheminsprivate 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 à noeudsprivate 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 à noeudsprivate 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;}}