Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
<?php/*** Exemple de lancement du script :** Analyse du fichir OSM :* /opt/lampp/bin/php cli.php osm -a analyser -f "../donnees/osm/france_communes_new.osm" -m manuel**/class ParseurOsm {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;public function __construct($conteneur) {$this->conteneur = $conteneur;$this->bdd = $this->conteneur->getBdd();$this->messages = $this->conteneur->getMessages();$this->mode = $this->conteneur->getParametre('m');}public function executer() {// Lancement de l'action demandée$cmd = $this->conteneur->getParametre('a');switch ($cmd) {case 'analyser' :$this->lireFichierOsm();break;case 'polygone' :$this->remplirPolygone();break;case 'zero' :$this->remettreOrdreAZero();break;default :$this->messages->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));}}/*** Lit le fichier OSM et lance l'analyse des noeuds xml en fonction de leur type.*/private function lireFichierOsm() {$lecteur = $this->getLecteurXml();while ($lecteur->read()) {if ($lecteur->nodeType == XMLREADER::ELEMENT) {$this->analyserElementXml($lecteur->localName, $lecteur->expand());}if ($this->mode == 'manuel') {$this->messages->afficherAvancement("Analyse de la ligne du fichier OSM : ", 1);}}$this->insererElementsOrphelins();}private function analyserElementXml($elementNom, $noeudDom) {switch ($elementNom) {case 'relation' :$this->analyserRelation($noeudDom);break;case 'way' :$this->analyserWay($noeudDom);break;case 'node' :$this->analyserNode($noeudDom);break;}}private function insererElementsOrphelins() {$this->insererRelationsCommunes();$this->insererRelationAChemins();$this->insererCheminANoeuds();$this->insererNoeuds();}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;}/*** Récupère l'id commune, nom commune et le code INSEE et remplie la table `CommuneOSM`*/private function analyserRelation($relation) {$idRelation = $relation->getAttribute('id');$chemins = $relation->getElementsByTagName('member');$this->analyserChemins($idRelation, $chemins);if (count($this->relation_a_chemins) > $this->pas) {$this->insererRelationAChemins();}$tags = $relation->getElementsByTagName('tag');$this->analyserTags($idRelation, $tags);if (count($this->relations_communes) > $this->pas_commune) {$this->insererRelationsCommunes();}}private function analyserChemins($relation_id, $chemins) {$ordreChemin = 1;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, $ordreChemin++);}}}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)) {if (!isset($this->relations_communes[$relation_id])) {$this->relations_communes[$relation_id] = array($relation_id, $commune_nom, $commune_insee);} else {$e = "La relation #%s possédant le tag ref:INSEE «%s» est déjà prise en compte.";$this->messages->traiterErreur($e, array($relation_id, $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->messages->traiterErreur($e, array($this->communes[$commune_insee], $commune_insee, $relation_id));}break;// Stoppe le foreach car nous avons les infos nécessaires}}}/*** 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');$ordre = 1;$noeuds = $way->getElementsByTagName('nd');foreach ($noeuds as $noeud) {$noeud_id = $noeud->getAttribute('ref');$this->chemin_a_noeuds[] = array($chemin_id, $noeud_id, $ordre++);}if (count($this->chemin_a_noeuds) > $this->pas) {$this->insererCheminANoeuds();}}/*** 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 = $node->getAttribute('id');$lat = $node->getAttribute('lat');$lon = $node->getAttribute('lon');$this->noeuds[] = array($noeud_id, $lat, $lon);if (count($this->noeuds) > $this->pas) {$this->insererNoeuds();}}private function insererRelationsCommunes() {if (count($this->relations_communes) > 0) {$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();}private function insererRelationAChemins() {if (count($this->relation_a_chemins) > 0) {$requete = 'INSERT INTO osm_relation_a_chemins (id_relation, id_chemin, role, ordre) '.'VALUES '.$this->creerValuesMultiple($this->relation_a_chemins).' -- '.__FILE__.' : '.__LINE__;$this->bdd->requeter($requete);}$this->relation_a_chemins = array();}private function insererCheminANoeuds() {if (count($this->chemin_a_noeuds) > 0) {$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();}private function insererNoeuds() {if (count($this->noeuds) > 0) {$requete = 'INSERT INTO osm_noeuds (id_noeud, lat, `long`) '.'VALUES '.$this->creerValuesMultiple($this->noeuds).' -- '.__FILE__.' : '.__LINE__;$this->bdd->requeter($requete);}$this->noeuds = array();}private function creerValuesMultiple($donnees) {$values = array();foreach ($donnees as $infos) {$infosP = $this->bdd->proteger($infos);$values[] = implode(',', $infosP);}$valuesClause = '('.implode('),(', $values).')';return $valuesClause;}}