New file |
0,0 → 1,245 |
<?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; |
} |
} |