Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 1046 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1046 Rev 1055
1
<?php
1
<?php
2
/**
2
/**
3
 * Exemple de lancement du script :
3
 * Exemple de lancement du script :
4
 *
4
 *
5
 * Analyse du fichir OSM :
5
 * Analyse du fichir OSM :
6
 * /opt/lampp/bin/php cli.php osm -a analyser -f "../donnees/osm/france_communes_new.osm" -m manuel
6
 * /opt/lampp/bin/php cli.php osm -a analyser -f "../donnees/osm/france_communes_new.osm" -m manuel
7
 *
7
 *
8
 */
8
 */
9
class ParseurOsm {
9
class ParseurOsm {
10
 
10
 
11
	private $conteneur;
11
	private $conteneur;
12
	private $bdd;
12
	private $bdd;
13
	private $messages;
13
	private $messages;
14
	private $mode;
14
	private $mode;
15
 
15
 
16
	private $communes = array();
16
	private $communes = array();
17
	private $relations_communes = array();
17
	private $relations_communes = array();
18
	private $relation_a_chemins = array();
18
	private $relation_a_chemins = array();
19
	private $chemin_a_noeuds = array();
19
	private $chemin_a_noeuds = array();
20
	private $noeuds = array();
20
	private $noeuds = array();
21
	private $pas = 10000;
21
	private $pas = 10000;
22
	private $pas_commune = 1000;
22
	private $pas_commune = 1000;
23
 
23
 
24
	public function __construct($conteneur) {
24
	public function __construct($conteneur) {
25
		$this->conteneur = $conteneur;
25
		$this->conteneur = $conteneur;
26
		$this->bdd = $this->conteneur->getBdd();
26
		$this->bdd = $this->conteneur->getBdd();
27
		$this->messages = $this->conteneur->getMessages();
27
		$this->messages = $this->conteneur->getMessages();
28
		$this->mode = $this->conteneur->getParametre('m');
28
		$this->mode = $this->conteneur->getParametre('m');
29
	}
29
	}
30
 
30
 
31
	public function executer() {
31
	public function executer() {
32
		// Lancement de l'action demandée
32
		// Lancement de l'action demandée
33
		$cmd = $this->conteneur->getParametre('a');
33
		$cmd = $this->conteneur->getParametre('a');
34
		switch ($cmd) {
34
		switch ($cmd) {
35
			case 'analyser' :
35
			case 'analyser' :
36
				$this->lireFichierOsm();
36
				$this->lireFichierOsm();
37
				break;
37
				break;
38
			case 'polygone' :
38
			case 'polygone' :
39
				$this->remplirPolygone();
39
				$this->remplirPolygone();
40
				break;
40
				break;
41
			case 'zero' :
41
			case 'zero' :
42
				$this->remettreOrdreAZero();
42
				$this->remettreOrdreAZero();
43
				break;
43
				break;
44
			default :
44
			default :
45
				$this->messages->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
45
				$this->messages->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
46
		}
46
		}
47
	}
47
	}
48
 
48
 
49
	/**
49
	/**
50
	 * Lit le fichier OSM et lance l'analyse des noeuds xml en fonction de leur type.
50
	 * Lit le fichier OSM et lance l'analyse des noeuds xml en fonction de leur type.
51
	 */
51
	 */
52
	private function lireFichierOsm() {
52
	private function lireFichierOsm() {
53
		$lecteur = $this->getLecteurXml();
53
		$lecteur = $this->getLecteurXml();
54
		while ($lecteur->read()) {
54
		while ($lecteur->read()) {
55
			if ($lecteur->nodeType == XMLREADER::ELEMENT) {
55
			if ($lecteur->nodeType == XMLREADER::ELEMENT) {
56
				$this->analyserElementXml($lecteur->localName, $lecteur->expand());
56
				$this->analyserElementXml($lecteur->localName, $lecteur->expand());
57
			}
57
			}
58
			if ($this->mode == 'manuel') {
58
			if ($this->mode == 'manuel') {
59
				$this->messages->afficherAvancement("Analyse de la ligne du fichier OSM : ", 1);
59
				$this->messages->afficherAvancement("Analyse de la ligne du fichier OSM : ", 1);
60
			}
60
			}
61
		}
61
		}
62
		$this->insererElementsOrphelins();
62
		$this->insererElementsOrphelins();
63
	}
63
	}
64
 
64
 
65
	private function analyserElementXml($elementNom, $noeudDom) {
65
	private function analyserElementXml($elementNom, $noeudDom) {
66
		switch ($elementNom) {
66
		switch ($elementNom) {
67
			case 'relation' :
67
			case 'relation' :
68
				$this->analyserRelation($noeudDom);
68
				$this->analyserRelation($noeudDom);
69
				break;
69
				break;
70
			case 'way' :
70
			case 'way' :
71
				$this->analyserWay($noeudDom);
71
				$this->analyserWay($noeudDom);
72
				break;
72
				break;
73
			case 'node' :
73
			case 'node' :
74
				$this->analyserNode($noeudDom);
74
				$this->analyserNode($noeudDom);
75
				break;
75
				break;
76
		}
76
		}
77
	}
77
	}
78
 
78
 
79
	private function insererElementsOrphelins() {
79
	private function insererElementsOrphelins() {
80
		$this->insererRelationsCommunes();
80
		$this->insererRelationsCommunes();
81
		$this->insererRelationAChemins();
81
		$this->insererRelationAChemins();
82
		$this->insererCheminANoeuds();
82
		$this->insererCheminANoeuds();
83
		$this->insererNoeuds();
83
		$this->insererNoeuds();
84
	}
84
	}
85
 
85
 
86
	private function getLecteurXml() {
86
	private function getLecteurXml() {
87
		$fichierOsm = $this->conteneur->getParametre('f');
87
		$fichierOsm = $this->conteneur->getParametre('f');
88
		$lecteur = new XMLReader();
88
		$lecteur = new XMLReader();
89
		$ouvertureXmlOk = $lecteur->open($fichierOsm);
89
		$ouvertureXmlOk = $lecteur->open($fichierOsm);
90
		if ($ouvertureXmlOk === false) {
90
		if ($ouvertureXmlOk === false) {
91
			$msgTpl = "Impossible d'ouvrir le fichier osm : %s";
91
			$msgTpl = "Impossible d'ouvrir le fichier osm : %s";
92
			$msg = sprintf($msgTpl, $this->conteneur->getParametre('f'));
92
			$msg = sprintf($msgTpl, $this->conteneur->getParametre('f'));
93
			new Exception($msg);
93
			new Exception($msg);
94
		}
94
		}
95
		return $lecteur;
95
		return $lecteur;
96
	}
96
	}
97
 
97
 
98
	/**
98
	/**
99
	 * Récupère l'id commune, nom commune et le code INSEE et remplie la table `CommuneOSM`
99
	 * Récupère l'id commune, nom commune et le code INSEE et remplie la table `CommuneOSM`
100
	 */
100
	 */
101
	private function analyserRelation($relation) {
101
	private function analyserRelation($relation) {
102
		$idRelation = $relation->getAttribute('id');
102
		$idRelation = $relation->getAttribute('id');
103
 
103
 
104
		$chemins = $relation->getElementsByTagName('member');
104
		$chemins = $relation->getElementsByTagName('member');
105
		$this->analyserChemins($idRelation, $chemins);
105
		$this->analyserChemins($idRelation, $chemins);
106
		if (count($this->relation_a_chemins) > $this->pas) {
106
		if (count($this->relation_a_chemins) > $this->pas) {
107
			$this->insererRelationAChemins();
107
			$this->insererRelationAChemins();
108
		}
108
		}
109
 
109
 
110
		$tags = $relation->getElementsByTagName('tag');
110
		$tags = $relation->getElementsByTagName('tag');
111
		$this->analyserTags($idRelation, $tags);
111
		$this->analyserTags($idRelation, $tags);
112
		if (count($this->relations_communes) > $this->pas_commune) {
112
		if (count($this->relations_communes) > $this->pas_commune) {
113
			$this->insererRelationsCommunes();
113
			$this->insererRelationsCommunes();
114
		}
114
		}
115
	}
115
	}
116
 
116
 
117
	private function analyserChemins($relation_id, $chemins) {
117
	private function analyserChemins($relation_id, $chemins) {
-
 
118
		$ordreChemin = 1;
118
		foreach ($chemins as $chemin) {
119
		foreach ($chemins as $chemin) {
119
			if ($chemin->getAttribute('type') == 'way') { //écarter le noeud centrale
120
			if ($chemin->getAttribute('type') == 'way') { //écarter le noeud centrale
120
				$chemin_id = $chemin->getAttribute('ref');
121
				$chemin_id = $chemin->getAttribute('ref');
121
				$role = $chemin->getAttribute('role');//role: null, inner, outer, exclave et enclave.
122
				$role = $chemin->getAttribute('role');//role: null, inner, outer, exclave et enclave.
122
				$this->relation_a_chemins[] = array($relation_id, $chemin_id, $role);
123
				$this->relation_a_chemins[] = array($relation_id, $chemin_id, $role, $ordreChemin++);
123
			}
124
			}
124
		}
125
		}
125
	}
126
	}
126
 
127
 
127
	private function analyserTags($relation_id, $tags) {
128
	private function analyserTags($relation_id, $tags) {
128
		$commune_nom = null;
129
		$commune_nom = null;
129
		$commune_insee = null;
130
		$commune_insee = null;
130
		foreach ($tags as $tag) {
131
		foreach ($tags as $tag) {
131
			$tag_cle = $tag->getAttribute('k');
132
			$tag_cle = $tag->getAttribute('k');
132
			$tag_val = $tag->getAttribute('v');
133
			$tag_val = $tag->getAttribute('v');
133
 
134
 
134
			switch ($tag_cle) {
135
			switch ($tag_cle) {
135
				case 'name' :
136
				case 'name' :
136
					$commune_nom = $tag_val;
137
					$commune_nom = $tag_val;
137
					break;
138
					break;
138
				case 'ref:INSEE' :
139
				case 'ref:INSEE' :
139
					$commune_insee = $tag_val;
140
					$commune_insee = $tag_val;
140
					break;
141
					break;
141
			}
142
			}
142
 
143
 
143
			if (!is_null($commune_nom) && !is_null($commune_insee)) {
144
			if (!is_null($commune_nom) && !is_null($commune_insee)) {
144
 
145
 
145
				if (!isset($this->relations_communes[$relation_id])) {
146
				if (!isset($this->relations_communes[$relation_id])) {
146
					$this->relations_communes[$relation_id] = array($relation_id, $commune_nom, $commune_insee);
147
					$this->relations_communes[$relation_id] = array($relation_id, $commune_nom, $commune_insee);
147
				} else {
148
				} else {
148
					$e = "La relation #%s possédant le tag ref:INSEE «%s» est déjà prise en compte.";
149
					$e = "La relation #%s possédant le tag ref:INSEE «%s» est déjà prise en compte.";
149
					$this->messages->traiterErreur($e, array($relation_id, $commune_insee));
150
					$this->messages->traiterErreur($e, array($relation_id, $commune_insee));
150
				}
151
				}
151
 
152
 
152
				if (!isset($this->communes[$commune_insee])) {
153
				if (!isset($this->communes[$commune_insee])) {
153
					$this->communes[$commune_insee] = $relation_id;
154
					$this->communes[$commune_insee] = $relation_id;
154
				} else {
155
				} else {
155
					$e = "La relation #%s contient déjà le tag ref:INSEE avec la valeur %s.".
156
					$e = "La relation #%s contient déjà le tag ref:INSEE avec la valeur %s.".
156
						"Veuillez corriger la carte OSM.";
157
						"Veuillez corriger la carte OSM.";
157
					$this->messages->traiterErreur($e, array($this->communes[$commune_insee], $commune_insee, $relation_id));
158
					$this->messages->traiterErreur($e, array($this->communes[$commune_insee], $commune_insee, $relation_id));
158
				}
159
				}
159
				break;// Stoppe le foreach car nous avons les infos nécessaires
160
				break;// Stoppe le foreach car nous avons les infos nécessaires
160
			}
161
			}
161
		}
162
		}
162
	}
163
	}
163
 
164
 
164
	/**
165
	/**
165
	 * Récupère l'id_way et tous les id_node de chaque way et remplie la table `osm_chemin_a_noeuds`
166
	 * Récupère l'id_way et tous les id_node de chaque way et remplie la table `osm_chemin_a_noeuds`
166
	 */
167
	 */
167
	private function analyserWay($way) {
168
	private function analyserWay($way) {
168
		$chemin_id = $way->getAttribute('id');
169
		$chemin_id = $way->getAttribute('id');
169
		$ordre = 1;
170
		$ordre = 1;
170
		$noeuds = $way->getElementsByTagName('nd');
171
		$noeuds = $way->getElementsByTagName('nd');
171
		foreach ($noeuds as $noeud) {
172
		foreach ($noeuds as $noeud) {
172
			$noeud_id = $noeud->getAttribute('ref');
173
			$noeud_id = $noeud->getAttribute('ref');
173
			$this->chemin_a_noeuds[] = array($chemin_id, $noeud_id, $ordre++);
174
			$this->chemin_a_noeuds[] = array($chemin_id, $noeud_id, $ordre++);
174
		}
175
		}
175
 
176
 
176
		if (count($this->chemin_a_noeuds) > $this->pas) {
177
		if (count($this->chemin_a_noeuds) > $this->pas) {
177
			$this->insererCheminANoeuds();
178
			$this->insererCheminANoeuds();
178
		}
179
		}
179
	}
180
	}
180
 
181
 
181
	/**
182
	/**
182
	 * Fonction qui récupère tous les l'id_node et les valeurs(Lat/Lon) correspondantes et remplie la table `osm_noeuds`
183
	 * Fonction qui récupère tous les l'id_node et les valeurs(Lat/Lon) correspondantes et remplie la table `osm_noeuds`
183
	 */
184
	 */
184
	private function analyserNode($node) {
185
	private function analyserNode($node) {
185
		$noeud_id = $node->getAttribute('id');
186
		$noeud_id = $node->getAttribute('id');
186
		$lat = $node->getAttribute('lat');
187
		$lat = $node->getAttribute('lat');
187
		$lon = $node->getAttribute('lon');
188
		$lon = $node->getAttribute('lon');
188
		$this->noeuds[] = array($noeud_id, $lat, $lon);
189
		$this->noeuds[] = array($noeud_id, $lat, $lon);
189
 
190
 
190
		if (count($this->noeuds) > $this->pas) {
191
		if (count($this->noeuds) > $this->pas) {
191
			$this->insererNoeuds();
192
			$this->insererNoeuds();
192
		}
193
		}
193
	}
194
	}
194
 
195
 
195
	private function insererRelationsCommunes() {
196
	private function insererRelationsCommunes() {
196
		if (count($this->relations_communes) > 0) {
197
		if (count($this->relations_communes) > 0) {
197
			$requete = 'INSERT INTO osm_relations (id_relation, nom, code_insee) '.
198
			$requete = 'INSERT INTO osm_relations (id_relation, nom, code_insee) '.
198
				'VALUES '.$this->creerValuesMultiple($this->relations_communes).
199
				'VALUES '.$this->creerValuesMultiple($this->relations_communes).
199
				' -- '.__FILE__.' : '.__LINE__;
200
				' -- '.__FILE__.' : '.__LINE__;
200
			$this->bdd->requeter($requete);
201
			$this->bdd->requeter($requete);
201
		}
202
		}
202
		$this->relations_communes = array();
203
		$this->relations_communes = array();
203
	}
204
	}
204
 
205
 
205
	private function insererRelationAChemins() {
206
	private function insererRelationAChemins() {
206
		if (count($this->relation_a_chemins) > 0) {
207
		if (count($this->relation_a_chemins) > 0) {
207
			$requete = 'INSERT INTO osm_relation_a_chemins (id_relation, id_chemin, role) '.
208
			$requete = 'INSERT INTO osm_relation_a_chemins (id_relation, id_chemin, role, ordre) '.
208
				'VALUES '.$this->creerValuesMultiple($this->relation_a_chemins).
209
				'VALUES '.$this->creerValuesMultiple($this->relation_a_chemins).
209
				' -- '.__FILE__.' : '.__LINE__;
210
				' -- '.__FILE__.' : '.__LINE__;
210
			$this->bdd->requeter($requete);
211
			$this->bdd->requeter($requete);
211
		}
212
		}
212
		$this->relation_a_chemins = array();
213
		$this->relation_a_chemins = array();
213
	}
214
	}
214
 
215
 
215
	private function insererCheminANoeuds() {
216
	private function insererCheminANoeuds() {
216
		if (count($this->chemin_a_noeuds) > 0) {
217
		if (count($this->chemin_a_noeuds) > 0) {
217
			$requete = 'INSERT INTO osm_chemin_a_noeuds (id_chemin, id_noeud, ordre) '.
218
			$requete = 'INSERT INTO osm_chemin_a_noeuds (id_chemin, id_noeud, ordre) '.
218
				'VALUES '.$this->creerValuesMultiple($this->chemin_a_noeuds).
219
				'VALUES '.$this->creerValuesMultiple($this->chemin_a_noeuds).
219
				' -- '.__FILE__.' : '.__LINE__;
220
				' -- '.__FILE__.' : '.__LINE__;
220
			$this->bdd->requeter($requete);
221
			$this->bdd->requeter($requete);
221
		}
222
		}
222
		$this->chemin_a_noeuds = array();
223
		$this->chemin_a_noeuds = array();
223
	}
224
	}
224
 
225
 
225
	private function insererNoeuds() {
226
	private function insererNoeuds() {
226
		if (count($this->noeuds) > 0) {
227
		if (count($this->noeuds) > 0) {
227
			$requete = 'INSERT INTO osm_noeuds (id_noeud, lat, `long`) '.
228
			$requete = 'INSERT INTO osm_noeuds (id_noeud, lat, `long`) '.
228
				'VALUES '.$this->creerValuesMultiple($this->noeuds).
229
				'VALUES '.$this->creerValuesMultiple($this->noeuds).
229
				' -- '.__FILE__.' : '.__LINE__;
230
				' -- '.__FILE__.' : '.__LINE__;
230
			$this->bdd->requeter($requete);
231
			$this->bdd->requeter($requete);
231
		}
232
		}
232
		$this->noeuds = array();
233
		$this->noeuds = array();
233
	}
234
	}
234
 
235
 
235
	private function creerValuesMultiple($donnees) {
236
	private function creerValuesMultiple($donnees) {
236
		$values = array();
237
		$values = array();
237
		foreach ($donnees as $infos) {
238
		foreach ($donnees as $infos) {
238
			$infosP = $this->bdd->proteger($infos);
239
			$infosP = $this->bdd->proteger($infos);
239
			$values[] = implode(',', $infosP);
240
			$values[] = implode(',', $infosP);
240
		}
241
		}
241
		$valuesClause = '('.implode('),(', $values).')';
242
		$valuesClause = '('.implode('),(', $values).')';
242
		return $valuesClause;
243
		return $valuesClause;
243
	}
244
	}
244
}
245
}