Subversion Repositories eFlore/Projets.eflore-projets

Rev

Rev 167 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
167 jpm 1
<?php
2
/**
392 jpm 3
 * Exemple de lancement du script :
4
 * /opt/lampp/bin/php cli.php osm/parseur_osm -a compter -f "/home/jpm/Stockage/osm/languedoc-roussillon-communes.osm"
5
 *
167 jpm 6
 */
7
class ParseurOsm extends Script {
392 jpm 8
 
167 jpm 9
	private $communes = array();
10
	private $relations_communes = array();
11
	private $relation_a_chemins = array();
12
	private $chemin_a_noeuds = array();
13
	private $noeuds = array();
14
	private $pas = 10000;
15
	private $pas_commune = 1000;
392 jpm 16
 
167 jpm 17
	protected $parametres_autorises = array(
18
		'-f' => array(true, null, 'Chemin du fichier osm à analyser'),
19
		'-m' => array(false, 'auto', 'Mode «auto» ou «manuel». En manuel, les compteurs dans les boucles sont affichés.'));
20
 
21
	public function executer() {
22
		$this->bdd = new Bdd();
23
 
24
		// Lancement de l'action demandée
25
		$cmd = $this->getParametre('a');
26
	    switch ($cmd) {
27
	    	case 'analyser' :
28
				$this->lireFichierOsm();
29
				break;
30
			case 'ordre' :
31
				$this->ordonnerWays();
32
				break;
33
			case 'polygone' :
34
				$this->remplirPolygone();
35
				break;
36
			case 'zero' :
37
				$this->remettreOrdreAZero();
38
				break;
39
			case 'ordonnerPolygoneInc' :
40
				$this->relationsPolygoneIncomplet(1, 0);
41
				break;
42
			case 'remplirPolygoneInc' :
43
				$this->remplirCommunesPolygoneIncomplet();
44
				break;
45
			case 'renommer' :
46
				$this->renommerEnPolygoneIncomplet();
47
				break;
48
			case 'centre' :
49
				$this->centroid();
50
				break;
51
			default :
52
				$this->traiterErreur('Erreur : la commande "%s" n\'existe pas!', array($cmd));
53
		}
54
    }
55
 
392 jpm 56
 
167 jpm 57
    /**
58
	 * Lit le fichier OSM et lance l'analyse des noeuds xml en fonction de leur type.
392 jpm 59
	 */
167 jpm 60
	private function lireFichierOsm() {
61
		$lecteur = new XMLReader();
62
		if ($lecteur->open($this->getParametre('f'))) {
63
			$dom = new DomDocument();
64
			while ($lecteur->read()) {
65
				if ($lecteur->nodeType == XMLREADER::ELEMENT) {
66
					if ($lecteur->localName == 'relation') {
67
						$relation = $lecteur->expand();
68
						$this->analyserRelation($relation);
392 jpm 69
 
167 jpm 70
						if (count($this->relation_a_chemins) > $this->pas) {
71
							$this->insererRelationAChemins();
72
						}
73
						if (count($this->relations_communes) > $this->pas_commune) {
74
							$this->insererRelationsCommunes();
75
						}
76
					} else if ($lecteur->localName == 'way') {
77
						$way = $lecteur->expand();
78
						$this->analyserWay($way);
392 jpm 79
 
167 jpm 80
						if (count($this->chemin_a_noeuds) > $this->pas) {
81
							$this->insererCheminANoeuds();
82
						}
83
					} else if ($lecteur->localName == 'node') {
84
						$node = $lecteur->expand();
85
						$this->analyserNode($node);
86
						if (count($this->noeuds) > $this->pas) {
87
							$this->insererNoeuds();
88
						}
89
					}
90
				}
91
				if (count($this->noeuds) > $this->pas) {
92
					$this->insererNoeuds();
93
					$this->insererCheminANoeuds();
94
				}
95
				if ($this->getParametre('m') == 'manuel') {
96
					$this->afficherAvancement("Analyse de la ligne du fichier OSM : ", 1);
97
				}
98
			}
99
			$this->insererRelationsCommunes();
100
			$this->insererRelationAChemins();
101
			$this->insererCheminANoeuds();
102
			$this->insererNoeuds();
103
		} else {
104
			$e = "Impossible d'ouvrir le fichier osm : %s";
105
			$this->traiterErreur($e, array($this->getParametre('f')));
106
		}
107
	}
392 jpm 108
 
167 jpm 109
	/**
110
	 * Récupère l'id commune, nom commune et le code INSEE et remplie la table `CommuneOSM`
392 jpm 111
	 */
167 jpm 112
	private function analyserRelation($relation) {
113
		$relation_id = $this->proteger($relation->getAttribute('id'));
114
		$chemins = $relation->getElementsByTagName('member');
115
		foreach ($chemins as $chemin) {
116
			if ($chemin->getAttribute('type') == 'way') { //écarter le noeud centrale
117
				$chemin_id = $this->proteger($chemin->getAttribute('ref'));
118
				$role = $this->proteger($chemin->getAttribute('role'));//role: null, inner, outer, exclave et enclave.
392 jpm 119
				$this->relation_a_chemins[] = array($relation_id, $chemin_id, $role);
167 jpm 120
			}
121
		}
122
		$commune_nom = null;
123
		$commune_insee = null;
124
		$tags = $relation->getElementsByTagName('tag');
125
		foreach ($tags as $tag) {
126
			$tag_cle = $tag->getAttribute('k');
127
			$tag_val = $tag->getAttribute('v');
128
			switch ($tag_cle) {
129
				case 'name' :
130
					$commune_nom = $this->proteger($tag_val);
392 jpm 131
					break;
167 jpm 132
				case 'ref:INSEE' :
133
					$commune_insee = $this->proteger($tag_val);
134
					break;
135
			}
136
			if (!is_null($commune_nom) && !is_null($commune_insee)) {
137
				$this->relations_communes[] = array($relation_id, $commune_nom, $commune_insee);
138
				if (!isset($this->communes[$commune_insee])) {
139
					$this->communes[$commune_insee] = $relation_id;
140
				} else {
141
					$e = "La relation #%s contient déjà le tag ref:INSEE avec la valeur %s.".
142
						"Veuillez corriger la carte OSM.";
143
					$this->traiterErreur($e, array($this->communes[$commune_insee], $commune_insee, $relation_id));
144
				}
145
				break;
146
			}
392 jpm 147
		}
167 jpm 148
	}
392 jpm 149
 
167 jpm 150
	/**
151
	 * Récupère l'id_way et tous les id_node de chaque way et remplie la table `osm_chemin_a_noeuds`
392 jpm 152
	 */
167 jpm 153
	private function analyserWay($way) {
154
		$chemin_id = $this->proteger($way->getAttribute('id'));
155
		$ordre = 0;
156
		$noeuds = $way->getElementsByTagName('nd');
157
		$chemin_a_noeuds = array();
158
		foreach ($noeuds as $noeud) {
159
			$noeud_id = $this->proteger($noeud->getAttribute('ref'));
160
			$ordre++;
161
	    	$this->chemin_a_noeuds[] = array($chemin_id, $noeud_id, $ordre);
162
		}
163
	}
392 jpm 164
 
165
	/**
167 jpm 166
	 * Fonction qui récupère tous les l'id_node et les valeurs(Lat/Lon) correspondantes et remplie la table `osm_noeuds`
392 jpm 167
	 */
167 jpm 168
	private function analyserNode($node) {
169
		$noeud_id = $this->proteger($node->getAttribute('id'));
170
		$lat = $this->proteger($node->getAttribute('lat'));
171
		$lon = $this->proteger($node->getAttribute('lon'));
172
		$this->noeuds[] = array($noeud_id, $lat, $lon);
173
	}
392 jpm 174
 
167 jpm 175
	private function insererRelationsCommunes() {
176
		$requete =	'INSERT INTO osm_relations (id_relation, nom, code_insee) '.
177
					'VALUES '.$this->creerValuesMultiple($this->relations_communes);
178
		$this->inserer($requete);
179
		$this->relations_communes = array();
180
	}
392 jpm 181
 
167 jpm 182
	private function insererRelationAChemins() {
183
		$requete =	'INSERT INTO osm_relation_a_chemins (id_relation, id_chemin, role) '.
184
					'VALUES '.$this->creerValuesMultiple($this->relation_a_chemins);
185
		$this->inserer($requete);
186
		$this->relation_a_chemins = array();
392 jpm 187
	}
188
 
167 jpm 189
	private function insererCheminANoeuds() {
190
		$requete = 	'INSERT INTO osm_chemin_a_noeuds (id_chemin, id_noeud, ordre) '.
191
					'VALUES '.$this->creerValuesMultiple($this->chemin_a_noeuds);
192
		$this->inserer($requete);
193
		$this->chemin_a_noeuds = array();
194
	}
392 jpm 195
 
167 jpm 196
	private function insererNoeuds() {
197
		$requete = 'INSERT INTO osm_noeuds (id_noeud, lat, `long`) '.
198
	    		   'VALUES '.$this->creerValuesMultiple($this->noeuds);
199
		$this->inserer($requete);
200
		$this->noeuds = array();
201
	}
392 jpm 202
 
167 jpm 203
	/**
392 jpm 204
	 * Fonction qui rajoute l'ordre et le sens de chaque way d'une relation dans la table `osm_relation_a_chemins`
167 jpm 205
	 * ALGO:
206
	 * -On fait un select de toutes les ways d'une relation.
207
	 * -On fait un count sur le tableau ways resutlant.
208
	 * -On met l'ordre du premier Way à 0.
209
	 * -On met : Actuelway = id_premier_way
210
	 * -Select dans table nodes, les nodes du way actuel
392 jpm 211
	 * -On prend le dernier noeud
167 jpm 212
	 * -On met : ActuelNoeud = id_dernier_noeud
213
	 * -Boucle for (i = 0; i < count(tabeau_way); i++) { sur le nombre de ways
392 jpm 214
	 * 		-On sélectionne id_way suivant qui contient le dernier_noeud du précédent
215
	 * 		(En écartant l'id_way déja existant )
167 jpm 216
	 * 		-On recherche les noeuds du nouveau way
217
	 * 		-On teste sur les extrémités du way précédent(dernier noeud) et suivant(premier noeud)
218
	 * 		-si égalité: $nombrePolygone=1;
219
	 * 			-sens:directe
220
	 * 			-ordre++
221
	 * 			-ActuelNoeud = id_dernier_noeud
392 jpm 222
	 * 		sinon
167 jpm 223
	 * 			-sens:indirecte
224
	 * 	    	-ordre++
225
	 * 			-ActuelNoeud = id_premier_noeud
226
	 * }
227
	 */
228
	private function ordonnerWays() {
229
		$requete = 'SELECT DISTINCT id_relation '.
230
					'FROM osm_relation_a_chemins ';
231
        $relations = $this->bdd->recupererTous($requete);
232
        foreach ($relations as $relation) {
233
        	$idRelation = $relation['id_relation'];
234
			$requete = 	'SELECT id_chemin '.
235
        				'FROM osm_relation_a_chemins '.
236
        				"WHERE id_relation = $idRelation";
237
			$ways = $this->bdd->recupererTous($requete);
238
          	$nombreWays = count($ways);
239
			// premier élément du tableau
240
	        $idPremierWay = $ways[0]['id_chemin'];
241
			$wayActuel  = $idPremierWay;
392 jpm 242
			$requete = 'UPDATE  osm_relation_a_chemins '.
243
						'SET  ordre =  0,  sens =  "directe" '.
244
						"WHERE  id_relation = $idRelation ".
167 jpm 245
						"AND  id_chemin = $wayActuel ";
246
			$this->inserer($requete);
392 jpm 247
			// selection dernier noeud
167 jpm 248
			$requete = 'SELECT id_noeud '.
249
						'FROM osm_chemin_a_noeuds '.
250
						"WHERE id_chemin = $wayActuel ORDER BY ordre";
251
			$nodes = $this->bdd->recupererTous($requete);
252
			$nombreNodes = count($nodes);
253
			$dernierNoeud = $nodes[$nombreNodes - 1]['id_noeud'];
254
			$noeudActuel = $dernierNoeud;
255
			for ($ordre = 1; $ordre < $nombreWays; $ordre++) {
392 jpm 256
				//selectionner le way qui possède le dernier noeud du précédent way et écarter l'actuel
257
				$requete = 'SELECT WN.id_chemin '.
167 jpm 258
							'FROM osm_relation_a_chemins AS RW LEFT JOIN osm_chemin_a_noeuds AS WN ON (RW.id_chemin = WN.id_chemin) '.
259
							"WHERE WN.id_noeud = $noeudActuel ".
260
							"AND WN.id_chemin != $wayActuel ".
261
							"AND RW.id_relation = $idRelation ";
262
				$ways = $this->bdd->recupererTous($requete);
263
				if (isset($ways[0])) {
264
					$wayActuel =  $ways[0]['id_chemin'];
265
					$requete = 'SELECT id_noeud '.
266
								'FROM osm_chemin_a_noeuds '.
392 jpm 267
								"WHERE id_chemin = $wayActuel ORDER BY ordre ";
167 jpm 268
					$nodes = $this->bdd->recupererTous($requete);
269
					$nombreNodes = count($nodes);
270
					if ( strcmp($nodes[0]['id_noeud'], $noeudActuel ) == 0 ) {
271
						$requete = 'UPDATE osm_relation_a_chemins '.
392 jpm 272
									"SET ordre = '$ordre', sens = 'directe' ".
167 jpm 273
									"WHERE id_relation = $idRelation ".
274
									"AND id_chemin = $wayActuel ";
275
						$this->inserer($requete);
276
						$noeudActuel = $nodes[$nombreNodes-1]['id_noeud'];
277
					} else {
278
						$requete = 'UPDATE osm_relation_a_chemins '.
279
									"SET ordre = '$ordre', sens = 'indirecte' ".
280
									"WHERE id_relation = $idRelation ".
281
									"AND id_chemin = $wayActuel";
282
						$this->inserer($requete);
283
						$noeudActuel = $nodes[0]['id_noeud'];
284
					}
285
				}
286
			}
287
        }
288
	}
289
 
290
	/**
392 jpm 291
	 * Fonction qui parcourt tous les ways les noeuds de chaque relation en prenant en considération l'ordre et
292
	 * le sens de chaque ways concaténés ensemble(séparés par des virgules). Update du champ polygone de chaque
293
	 * relation dans la table  `osm_relations`
167 jpm 294
	 */
295
	private function remplirPolygone() {
296
		$polygone = array();
392 jpm 297
		$idNodes = array();
167 jpm 298
		$String = '';
299
        $requete = 'SELECT id_relation, nom, code_insee FROM osm_relations ';
300
        $relations = $this->bdd->recupererTous($requete);
301
        foreach ($relations as $relation) {
302
        	$idCommune = $relation['id_relation'];
303
			$nomCommune = $relation['nom'];
304
        	$INSEE = $relation['code_insee'];
392 jpm 305
    		$requete = 'SELECT id_chemin FROM osm_relation_a_chemins '.
167 jpm 306
        				"WHERE id_relation = $idCommune ".
307
        				'ORDER BY ordre';
308
			$ways = $this->bdd->recupererTous($requete);
309
		    foreach ($ways as $way) {
310
        		$idWay = $way['id_chemin'];
392 jpm 311
        		$requeteSensWay= "SELECT sens FROM osm_relation_a_chemins WHERE id_relation = $idCommune
167 jpm 312
        						 AND id_chemin = $idWay";
313
				$sens = $this->bdd->recupererTous($requeteSensWay);
314
        		$requeteNodes = "SELECT id_noeud FROM osm_chemin_a_noeuds WHERE id_chemin= $idWay ORDER BY ordre ";
315
				$nodes = $this->bdd->recupererTous($requeteNodes);
316
				if($sens[0]['sens'] == "directe") {
317
	        		foreach ($nodes as $node) {
318
						$idNodes[] = $node['id_noeud'];
319
        			}
320
       				$noeuds = implode(", ", $idNodes);
392 jpm 321
       				//requête IN qui gère l'ordre des noeuds de chaque way (CAS ASC)
322
					$requeteLatitudeLongitude = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '.
323
												'FROM osm_chemin_a_noeuds WN, osm_noeuds NLL '.
167 jpm 324
												"WHERE NLL.id_noeud IN ($noeuds) ".
325
												'AND WN.id_noeud = NLL.id_noeud '.
326
												"AND WN.id_chemin = $idWay ORDER BY WN.ordre ASC";
327
					unset($noeuds);
328
					unset($idNodes);
329
					$LatLons = $this->bdd->recupererTous($requeteLatitudeLongitude);
330
			        foreach ($LatLons as $LatLon) {
331
		        			$Latitude = $LatLon['lat'];
392 jpm 332
						    $Longitude = $LatLon['long'];
333
						  	$String = "$Latitude $Longitude";
167 jpm 334
							$polygone[] = $String;
335
			       	}
336
				} else {
337
					foreach ($nodes as $node) {
338
						$idNodes[] = $node['id_noeud'];
339
        			}
340
        			$noeuds = implode(", ", $idNodes);
392 jpm 341
        			//requête IN qui gère l'ordre des noeuds de chaque way (CAS DESC)
342
        			$requeteLatitudeLongitude = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '.
167 jpm 343
        									    'FROM osm_chemin_a_noeuds WN ,osm_noeuds NLL '.
344
        									    "WHERE NLL.id_noeud IN ($noeuds) ".
345
        									    'AND WN.id_noeud = NLL.id_noeud '.
346
        									    "AND WN.id_chemin = $idWay ORDER BY WN.ordre DESC";
347
					unset($noeuds);
348
					unset($idNodes);
349
					$LatLons = $this->bdd->recupererTous($requeteLatitudeLongitude);
350
					foreach ($LatLons as $LatLon) {
351
		        		$Latitude = $LatLon['lat'];
392 jpm 352
						$Longitude = $LatLon['long'];
353
						$String = "$Latitude $Longitude";
167 jpm 354
		        		$polygone[] = $String;
355
				  	}
356
				}
392 jpm 357
            }
167 jpm 358
       			$this->etatPolygone($polygone, $idCommune, $nomCommune, $INSEE);
359
	       		unset($separationVirgule);
360
				unset($requeteNodes);
361
				unset($String);
362
				unset($polygone);
363
		}
364
	}
392 jpm 365
 
167 jpm 366
	private function etatPolygone($polygone, $idCommune, $nomCommune, $INSEE) {
367
			$separationVirgulePolygone = implode(', ', $polygone);
368
			$nomCommuneProtege = $this->bdd->proteger($nomCommune);
369
			$InseeProtege = $this->bdd->proteger($INSEE);
370
			if ($polygone[0] == $polygone[count($polygone)-1]) { //test sur début et fin du polygone
371
				//requête replace pour gérer la mise à jour à la suite
372
				$requete = 'REPLACE INTO osm_communes (id_relation, nom, code_insee, polygon, note ) '.
392 jpm 373
						   "VALUES ($idCommune, $nomCommuneProtege, $InseeProtege, ".
167 jpm 374
						   "POLYFROMTEXT('MULTIPOLYGON ((($separationVirgulePolygone)))'),'Polygone complet');";
375
			} else {
376
				$requete = 'REPLACE INTO osm_communes (id_relation, nom, code_insee, polygon, note ) '.
392 jpm 377
						   "VALUES ($idCommune, $nomCommuneProtege, $InseeProtege, ".
167 jpm 378
						   "POLYFROMTEXT('MULTIPOLYGON ((($separationVirgulePolygone)))'),'Polygone incomplet');";
379
			}
380
			$this->inserer($requete);
381
	}
382
 
383
	//Fonction qui remet à zéro l'ordre des ways des communes des polygones incomplets fait précédement
384
	private function remettreOrdreAZero() {
385
		$requeteRelations = "SELECT id_relation FROM osm_communes WHERE note LIKE 'Polygone incomplet'";
386
        $relations = $this->bdd->recupererTous($requeteRelations);
387
       	foreach ($relations as $relation) {
388
       		$idRelation = $relation['id_relation'];
389
       		$requeteWays = "SELECT id_chemin FROM osm_relation_a_chemins WHERE id_relation= $idRelation";
390
			$ways = $this->bdd->recupererTous($requeteWays);
391
			foreach ($ways as $way) {
392
				$idWay = $way['id_chemin'];
392 jpm 393
				$this->	inserer('UPDATE osm_relation_a_chemins SET ordre = NULL '.
167 jpm 394
								"WHERE id_relation = $idRelation AND id_chemin = $idWay ;");
395
			}
396
		}
397
 
398
	}
392 jpm 399
 
167 jpm 400
	/**
401
	 * Fonction qui récupère les relations des polygones incomplets et appelle pour chaque relation la fonction
402
	 * ordonnerPolygoneIncomplet($ordre,$tour,$idRelation,$nombrePolygone)
403
	 */
404
	private function relationsPolygoneIncomplet($ordre, $tour) {
405
		$nombrePolygone = 1;
406
		$requeteRelations = "SELECT id_relation FROM osm_communes WHERE note LIKE 'Polygone incomplet'";
407
        	$relations = $this->bdd->recupererTous($requeteRelations);
408
            foreach ($relations as $relation) {
409
       			$nombrePolygone = 1;
410
            	$idRelation = $relation['id_relation'];
411
            	$this->ordonnerPolygoneIncomplet($ordre,$tour,$idRelation,$nombrePolygone);
412
            }
413
	}
392 jpm 414
 
167 jpm 415
	/**
416
	 * Fonction récursive qui exécute la même tâche que la fonction ordonnerWays() pour chaque polygone d'un
417
	 * multipolygone et remplie le champ NbPoly dans la table `osm_relation_a_chemins` qui correspond au nombre de polygone fermé
418
	 * dans le multipolygone
419
	 */
420
	private function ordonnerPolygoneIncomplet($ordre, $tour, $idRelation, $nombrePolygone) {
392 jpm 421
		$requeteWays = 'SELECT id_chemin FROM osm_relation_a_chemins '.
167 jpm 422
						"WHERE id_relation = $idRelation AND ordre = 'NULL'";
423
		$ways = $this->bdd->recupererTous($requeteWays);
424
		$tempWays = $ways;
425
		$nombreWays = count($ways);
426
   		// premier élément du tableau
427
        $idPremierWay = $ways[0]['id_chemin'];
428
		$wayActuel = $idPremierWay;
392 jpm 429
		$this->	inserer('UPDATE osm_relation_a_chemins '.
167 jpm 430
						 "SET ordre = $ordre, sens = 'directe', nbre_poly = $nombrePolygone ".
392 jpm 431
						 "WHERE id_relation = $idRelation ".
167 jpm 432
						 "AND id_chemin = $wayActuel ;");
392 jpm 433
		//selection dernier noeud
167 jpm 434
		$requeteNodes = "SELECT id_noeud FROM osm_chemin_a_noeuds WHERE id_chemin = $wayActuel ORDER BY ordre;";
435
		$nodes = $this->bdd->recupererTous($requeteNodes);
436
		$nombreNodes = count($nodes);
437
		$premierNoeud = $nodes[0]['id_noeud'];
438
		$dernierNoeud = $nodes[$nombreNodes-1]['id_noeud'];
439
		$noeudActuel = $dernierNoeud;
392 jpm 440
		$tour++;
441
		//Condition pour laquelle la boucle while continue à tourner; tant que le premier noeud du polygone n'est
167 jpm 442
		//égale au dernier et tant qu'il reste des ways à gérer
443
		while (($premierNoeud != $noeudActuel) && (($ordre % 1000) < count($tempWays))) {
392 jpm 444
			//select le way qui possède le dernier noeud du précédent way et écarter l'actuel
167 jpm 445
			$nombrePolygone;
446
			$ordre++;
447
			//select des ways qui n'ont pas été ordonnés: on obtient à chaque itération les ways qui restent à ordonner
448
			$requeteWays = 'SELECT WN.id_chemin FROM (osm_chemin_a_noeuds WN, osm_relation_a_chemins RW) '.
449
						   "WHERE WN.id_noeud = $noeudActuel AND WN.id_chemin != $wayActuel ".
450
						   "AND RW.id_chemin = WN.id_chemin AND RW.id_relation = $idRelation ".
451
						   "AND RW.ordre = 'NULL' ;";
452
			$ways = $this->bdd->recupererTous($requeteWays);
392 jpm 453
 
167 jpm 454
			if (isset($ways[0])) {
455
				$wayActuel = $ways[0]['id_chemin'];
392 jpm 456
				$requeteNodes = "SELECT id_noeud FROM osm_chemin_a_noeuds WHERE id_chemin = $wayActuel ORDER BY ordre;";
167 jpm 457
				$nodes = $this->bdd->recupererTous($requeteNodes);
458
				$nombreNodes = count($nodes);
459
				if (strcmp($nodes[0]['id_noeud'], $noeudActuel ) == 0) {
460
					$this->	inserer("UPDATE osm_relation_a_chemins SET ordre = '$ordre', sens = 'directe', ".
461
									"nbre_poly = $nombrePolygone ".
462
									"WHERE osm_relation_a_chemins.id_relation = $idRelation ".
463
							        "AND osm_relation_a_chemins.id_chemin = $wayActuel");
464
					$noeudActuel = $nodes[$nombreNodes-1]['id_noeud'];
465
				} else {
392 jpm 466
					$this->	inserer('UPDATE osm_relation_a_chemins '.
167 jpm 467
									"SET ordre = '$ordre', sens = 'indirecte', ".
392 jpm 468
									"nbre_poly = $nombrePolygone ".
167 jpm 469
							        "WHERE id_relation = $idRelation ".
470
						         	"AND id_chemin = $wayActuel");
471
					$noeudActuel = $nodes[0]['id_noeud'];
472
				}
473
			}
392 jpm 474
		}
475
		$ordre = 1000 * $tour; //différencier chaque polygone: pour chaque polygone on a un multiple de mille
167 jpm 476
		$requeteCount = "SELECT ordre FROM osm_relation_a_chemins WHERE id_relation = $idRelation AND ordre = 0";
477
		$count = $this->bdd->recupererTous($requeteCount);
478
		if ((count($count)) != 0) { // s'ils en restent des ways à gérer
479
			$nombrePolygone++;
392 jpm 480
			//appelle de la fonction récursive
167 jpm 481
			$this->ordonnerPolygoneIncomplet($ordre, $tour, $idRelation, $nombrePolygone);
392 jpm 482
		}
167 jpm 483
	}
392 jpm 484
 
167 jpm 485
	/**
486
	 * Fonction qui récupère les relations des polygones incomplets et appelle pour chaque relation la fonction
487
	 * remplirPolygoneIncomplet($idRelation);
488
	 */
489
	private function remplirCommunesPolygoneIncomplet() {
490
		$nombrePolygone = 1;
491
		$requeteRelations = "SELECT id_relation FROM osm_communes WHERE note LIKE 'Polygone incomplet'";
492
        	$relations = $this->bdd->recupererTous($requeteRelations);
493
            foreach ($relations as $relation) {
494
       			$idRelation = $relation['id_relation'];
392 jpm 495
				$this->remplirPolygoneIncomplet($idRelation);//appel de la fonction avec comme paramètre ID-commune
167 jpm 496
            }
497
	}
392 jpm 498
 
167 jpm 499
	/**
500
	 * Fonction qui exécute la même tâche que la fonction remplirPolygone() pour chaque polygone d'un multipolygone
392 jpm 501
	 * et renvoie un tableau MultiPolygone[] où chaque case contient un polygone fermé et appelle la fonction
167 jpm 502
	 * etatMultiPolygone($multiPolygone, $idCommune) qui remplie le Multipolygone de la commune correspondante
503
	 */
504
	private function remplirPolygoneIncomplet($idCommune) {
505
		$polygone = array();
392 jpm 506
		$multiPolygone = array();//tableau multipolygone qui contient tous les polygones d'un multipolygone
507
		$idNodes = array();
508
		$roles = array();//tableau roles qui contient les roles des ways
167 jpm 509
		$String = "";
392 jpm 510
		//sélectionner le nombre de polygones qui existe dans un multipolygone
167 jpm 511
		$requete = 'SELECT MAX(nbre_poly) AS nbre_poly '.
512
					'FROM osm_relation_a_chemins '.
513
					"WHERE id_relation = $idCommune";
514
        $nombrePolygone = $this->bdd->recupererTous($requete);
515
        $nbPoly = $nombrePolygone[0]['nbre_poly'];
516
		for ($tour = 1; $tour <= $nbPoly; $tour++) {//boucle for qui parcourt chaque polygone du multipolygone
392 jpm 517
        	$requeteWays = 	'SELECT id_chemin FROM osm_relation_a_chemins '.
518
        					"WHERE id_relation = $idCommune ".
167 jpm 519
							"AND nbre_poly = $tour ORDER BY ordre";
520
		    $ways = $this->bdd->recupererTous($requeteWays);
521
		    foreach ($ways as $way) {
522
        		$idWay = $way['id_chemin'];
392 jpm 523
   				$requeteSensWay = 'SELECT sens FROM osm_relation_a_chemins '.
524
   								  "WHERE id_relation = $idCommune ".
167 jpm 525
        						  "AND id_chemin = $idWay";//sélection de l'orientation du way
526
        		$sens= $this->bdd->recupererTous($requeteSensWay);
527
        		$requeteNodes = "SELECT id_noeud FROM osm_chemin_a_noeuds WHERE id_chemin= $idWay ORDER BY ordre";
528
				$nodes = $this->bdd->recupererTous($requeteNodes);
529
        		if ($sens[0]['sens'] == "directe") {//test sur le sens des ways
530
	        		foreach ($nodes as $node) {
531
						$idNodes[] = $node['id_noeud'];
532
        			}
533
       				$noeuds = implode(", ", $idNodes);
392 jpm 534
       				//requête IN qui gère l'ordre des noeuds de chaque way (CAS ASC)
167 jpm 535
					$requeteLatitudeLongitude = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '.
536
												'FROM osm_chemin_a_noeuds WN, osm_noeuds NLL '.
537
												"WHERE NLL.id_noeud IN ($noeuds) ".
538
												'AND WN.id_noeud = NLL.id_noeud '.
539
												"AND WN.id_chemin= $idWay ORDER BY WN.ordre ASC";
540
					unset($noeuds);
541
					unset($idNodes);
542
					$LatLons = $this->bdd->recupererTous($requeteLatitudeLongitude);
543
			        foreach ($LatLons as $LatLon) {
544
	        			$Latitude = $LatLon['lat'];
392 jpm 545
					    $Longitude = $LatLon['long'];
546
					  	$String = "$Latitude $Longitude";
167 jpm 547
						$polygone[] = $String;
548
			  		}
549
				} else {
550
					foreach ($nodes as $node) {
551
						$idNodes[] = $node['id_noeud'];
552
        			}
553
        			$noeuds = implode(", ", $idNodes);
392 jpm 554
        			//requête IN qui gère l'ordre des noeuds de chaque way (CAS DESC)
167 jpm 555
        			$requeteLatitudeLongitude = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '.
556
												'FROM osm_chemin_a_noeuds WN, osm_noeuds NLL '.
557
												"WHERE NLL.id_noeud IN ($noeuds) ".
558
												'AND WN.id_noeud = NLL.id_noeud '.
559
												"AND WN.id_chemin= $idWay ORDER BY WN.ordre DESC";
560
					unset($noeuds);
561
					unset($idNodes);
562
					$LatLons = $this->bdd->recupererTous($requeteLatitudeLongitude);
563
					foreach ($LatLons as $LatLon) {
564
		        		$Latitude = $LatLon['lat'];
392 jpm 565
						$Longitude = $LatLon['long'];
566
						$String = "$Latitude $Longitude";
167 jpm 567
		        		$polygone[] = $String;
568
					}
569
				}
392 jpm 570
			}
167 jpm 571
			$requeteRole = 'SELECT DISTINCT role '.
392 jpm 572
						   'FROM  osm_relation_a_chemins '.
573
						   "WHERE id_relation = $idCommune ".
167 jpm 574
						   "AND nbre_poly = $tour ";
575
			$role = $this->bdd->recupererTous($requeteRole);
576
			$role = $role[0]['role'];
577
			$separationVirgulePolygone = implode(", ", $polygone);
578
	       	$multiPolygone[] = $separationVirgulePolygone;
579
	     	$roles[] = $role;
580
			unset($separationVirgulePolygone);
581
			unset($polygone);
582
		}
583
			$this->etatMultiPolygone($multiPolygone, $roles, $idCommune, $nbPoly);//appel de la fonction de remplissage
584
	}
392 jpm 585
 
167 jpm 586
	/**
587
	 * Remplie le champ polygone à partir du tableau MultiPolygone
392 jpm 588
	 */
167 jpm 589
	private function etatMultiPolygone($multiPolygone, $roles, $idCommune, $nbPoly) {
590
		$note = $this->proteger('Polygone complet');
392 jpm 591
		if ($nbPoly == 2 && ((in_array('inner', $roles)) || (in_array('enclave', $roles)))) {//cas Outer Inner à deux polygones
167 jpm 592
			$multiPoly = implode('),(', $multiPolygone);
593
			$requete = 'UPDATE osm_communes '.
392 jpm 594
						"SET polygon = MPOLYFROMTEXT('MULTIPOLYGON((($multiPoly)))'), ".
595
		           		"note = $note ".
167 jpm 596
		           		"WHERE id_relation = $idCommune ";
597
			$this->inserer($requete);
392 jpm 598
		}
599
		if ((in_array('inner', $roles)) || (in_array('enclave', $roles)) != 1) { //tous les autres cas
167 jpm 600
			$multiPoly = implode(')),((', $multiPolygone);
601
			$requete = 'UPDATE osm_communes '.
602
						"SET polygon = MPOLYFROMTEXT('MULTIPOLYGON((($multiPoly)))'), ".
392 jpm 603
	             		"note = $note ".
167 jpm 604
	             		"WHERE id_relation = $idCommune ";
605
			$this->inserer($requete);
606
		}
392 jpm 607
	}
608
 
167 jpm 609
	/**
610
	 * Renomme la note des polygones vides d'un polygone complet en polygone incomplet
392 jpm 611
	 */
167 jpm 612
	private function renommerEnPolygoneIncomplet() {
613
		$requete = 'SELECT id_relation, ASTEXT(polygon) AS poly '.
614
					'FROM osm_communes ';
615
		$etatPolygones = $this->bdd->recupererTous($requete);
616
		foreach ($etatPolygones as $etatPolygone ) {
617
			if (isset($etatPolygone['poly']) == 0) {//test si le polygone est vide
618
				$idCommune = $this->proteger($etatPolygone['id_relation']);
619
				$note = $this->proteger('Polygone incomplet');
620
				$requete = 'UPDATE osm_communes '.
392 jpm 621
							"SET note = $note ".
167 jpm 622
							"WHERE id_relation = $idCommune ";
623
				$this->inserer($requete);
392 jpm 624
			}
625
		}
167 jpm 626
	}
627
 
628
 
629
	/**
630
	 * Récupère le point centre de chaque polygone et remplie la colonne "centre"
631
	 */
632
	private function centroid() {
633
		$requete = 'SELECT id_relation, ASTEXT(polygon) AS poly '.
634
					'FROM osm_communes ';
635
		$communes = $this->bdd->recupererTous($requete);
636
		foreach ($communes as $commune) {
637
			$multipolygone = $commune['poly'];
638
			$requete = "SELECT ASTEXT(CENTROID(MPOLYFROMTEXT('$multipolygone'))) AS centre ";
639
			$point = $this->bdd->recupererTous($requete);
640
        	$centre = $this->proteger($point[0]['centre']);
641
        	$idCom = $this->proteger($commune['id_relation']);
642
        	$requete = 'UPDATE osm_communes '.
392 jpm 643
        				"SET centre = POINTFROMTEXT($centre) ".
167 jpm 644
        				"WHERE id_relation = $idCom ";
645
        	$this->inserer($requete);
646
		}
647
	}
392 jpm 648
 
167 jpm 649
	private function creerValuesMultiple($donnees) {
650
		$values = array();
651
		foreach ($donnees as $donnee) {
652
			$values[] = implode(',', $donnee);
653
		}
654
		$values_chaine = '('.implode('),(', $values).')';
655
		return $values_chaine;
656
	}
392 jpm 657
 
167 jpm 658
	private function inserer($requete) {
659
		$this->bdd->requeter($requete);
660
	}
392 jpm 661
 
167 jpm 662
	private function proteger($chaine) {
663
		return $this->bdd->proteger($chaine);
664
	}
392 jpm 665
 
167 jpm 666
}
667
?>