Subversion Repositories eFlore/Projets.eflore-projets

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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