conteneur = $conteneur; $this->bdd = $this->conteneur->getBdd(); $this->messages = $this->conteneur->getMessages(); $this->mode = $this->conteneur->getParametre('m'); } /** * Fonction qui parcourt tous les ways les noeuds de chaque relation en prenant en considération l'ordre et * le sens de chaque ways concaténés ensemble (séparés par des virgules). Update du champ polygone de chaque * relation dans la table `osm_relations` */ public function executer() { // Lancement de l'action demandée $cmd = $this->conteneur->getParametre('a'); switch ($cmd) { case 'ordonnerPolygoneInc' : $this->ordonnerRelationsAuPolygoneIncomplet(); break; case 'remplirPolygoneInc' : $this->remplirRelationsAuPolygoneIncomplet(); break; case 'renommer' : $this->renommerEnPolygoneIncomplet(); break; default : $msgTpl = "Erreur : la commande '%s' n'est pas prise en compte par la classe %s !"; $msg = sprintf($msgTpl, $cmd, get_class($this)); throw new Exception($msg); } print "\n";// Pour ramener à la ligne en fin de script } /** * Fonction qui récupère les relations des polygones incomplets et appelle pour chaque relation la fonction * ordonnerPolygoneIncomplet($ordre,$tour,$idRelation,$nombrePolygone) */ private function ordonnerRelationsAuPolygoneIncomplet() { $relations = $this->getRelationsAuPolygoneIncomplet(); foreach ($relations as $relation) { $idRelation = $relation['id_relation']; $this->ordonnerCheminsMultiPolygone($idRelation); if ($this->mode == 'manuel') { $this->messages->afficherAvancement("Réparation du polygone incomplet : ", 1); } } } /** * Fonction récursive qui exécute la même tâche que la fonction ordonnerWays() pour chaque polygone d'un * multipolygone et remplie le champ NbPoly dans la table `osm_relation_a_chemins` qui correspond au nombre de polygone fermé * dans le multipolygone */ private function ordonnerCheminsMultiPolygone($idRelation, $numPolygone = 1, $ordre = 1, $tour = 1) { $chemins = $this->getChemins($idRelation); $nbreCheminsTotal = count($chemins); // premier élément du tableau $idPremierChemin = $chemins[0]['id_chemin']; $idChemin = $idPremierChemin; $this->mettreAJourChemin($idRelation, $idPremierChemin, $ordre, 'directe', $numPolygone); //selection dernier noeud $nodes = $this->getNoeuds($idPremierChemin); $nombreNodes = count($nodes); $premierNoeud = $nodes[0]['id_noeud']; $dernierNoeud = $nodes[$nombreNodes - 1]['id_noeud']; $noeudActuel = $dernierNoeud; //Condition pour laquelle la boucle while continue à tourner; tant que le premier noeud du polygone n'est //égale au dernier et tant qu'il reste des ways à gérer while (($premierNoeud != $noeudActuel) && (($ordre % 1000) < $nbreCheminsTotal)) { //select le way qui possède le dernier noeud du précédent way et écarter l'actuel $ordre++; $chemins = $this->getCheminsAOrdonner($idRelation, $idChemin, $noeudActuel); if (isset($chemins[0])) { $idChemin = $chemins[0]['id_chemin']; $nodes = $this->getNoeuds($idChemin); $nombreNodes = count($nodes); if (strcmp($nodes[0]['id_noeud'], $noeudActuel ) == 0) { $sens = 'directe'; $noeudActuel = $nodes[$nombreNodes-1]['id_noeud']; } else { $sens = 'indirecte'; $noeudActuel = $nodes[0]['id_noeud']; } $this->mettreAJourChemin($idRelation, $idChemin, $ordre, $sens, $numPolygone); } } $ordre = 1000 * $tour; //différencier chaque polygone: pour chaque polygone on a un multiple de mille if ($this->getNombreChemins($idRelation) != 0) { //appelle de la méthode récursivement $this->ordonnerCheminsMultiPolygone($idRelation, ++$numPolygone, $ordre, ++$tour); } } private function getRelationsAuPolygoneIncomplet() { $requete = 'SELECT id_relation '. 'FROM osm_communes '. "WHERE notes = 'Polygone incomplet' ". ' -- '.__FILE__.' : '.__LINE__; $relations = $this->bdd->recupererTous($requete); return $relations; } private function getChemins($idRelation) { $requete = 'SELECT id_chemin '. 'FROM osm_relation_a_chemins '. "WHERE id_relation = $idRelation ". "AND ordre IS NULL ". ' -- '.__FILE__.' : '.__LINE__; $chemins = $this->bdd->recupererTous($requete); return $chemins; } /** * Select des ways qui n'ont pas été ordonnés: on obtient à chaque itération les ways qui restent à ordonner */ private function getCheminsAOrdonner($idRelation, $idChemin, $idNoeud) { $requete = 'SELECT cn.id_chemin '. 'FROM osm_relation_a_chemins AS rc '. ' INNER JOIN osm_chemin_a_noeuds AS cn ON (rc.id_chemin = cn.id_chemin) '. "WHERE cn.id_noeud = $idNoeud ". "AND cn.id_chemin != $idChemin ". "AND rc.id_relation = $idRelation ". "AND rc.ordre IS NULL ". ' -- '.__FILE__.' : '.__LINE__; $chemins = $this->bdd->recupererTous($requete); return $chemins; } private function getNoeuds($idChemin) { $requete = 'SELECT id_noeud '. 'FROM osm_chemin_a_noeuds '. "WHERE id_chemin = $idChemin ". 'ORDER BY ordre '. ' -- '.__FILE__.' : '.__LINE__; $noeuds = $this->bdd->recupererTous($requete); return $noeuds; } private function getNombreChemins($idRelation) { $requete = 'SELECT COUNT(id_chemin) AS nbre '. 'FROM osm_relation_a_chemins '. "WHERE id_relation = $idRelation ". 'AND ordre = 0 '. ' -- '.__FILE__.' : '.__LINE__; $infos = $this->bdd->recuperer($requete); return $infos['nbre']; } private function mettreAJourChemin($idRelation, $idChemin, $ordre, $sens, $nbrePoly) { $requete = 'UPDATE osm_relation_a_chemins '. "SET ordre = '$ordre', sens = '$sens', num_poly = $nbrePoly ". "WHERE id_relation = $idRelation ". "AND id_chemin = $idChemin ". ' -- '.__FILE__.' : '.__LINE__; $this->bdd->requeter($requete); } /** * Fonction qui récupère les relations des polygones incomplets et appelle pour chaque relation la fonction * remplirPolygoneIncomplet($idRelation); */ private function remplirRelationsAuPolygoneIncomplet() { $relations = $this->getRelationsAuPolygoneIncomplet(); foreach ($relations as $relation) { $this->remplirPolygoneIncomplet($relation['id_relation']); if ($this->mode == 'manuel') { $this->messages->afficherAvancement("Création du polygone incomplet : ", 1); } } } /** * Fonction qui exécute la même tâche que la fonction remplirPolygone() pour chaque polygone d'un multipolygone * et renvoie un tableau MultiPolygone[] où chaque case contient un polygone fermé. Puis met à jour le polygone * de la commune. */ private function remplirPolygoneIncomplet($idRelation) { // Tableau multipolygone qui contient tous les polygones d'un multipolygone $multiPolygone = array(); // Tableau roles qui contient les différents roles des chemins de la relation $roles = array(); // Sélectionner le nombre de polygones qui existe dans un multipolygone $nbPoly = $this->getNombrePoly($idRelation); //boucle for qui parcourt chaque polygone du multipolygone for ($numPoly = 1; $numPoly <= $nbPoly; $numPoly++) { $polygone = array(); $chemins = $this->getCheminsParPolygone($idRelation, $numPoly); foreach ($chemins as $chemin) { $role = $chemin['role']; $roles[$role] = (isset($roles[$role])) ? $roles[$role]++ : 1; $noeuds = $this->getNoeudsPourCheminEtSens($chemin['id_chemin'], $chemin['sens']); $polygone = array_merge($polygone, $noeuds); } $multiPolygone[] = implode(', ', $polygone); } $this->mettreAJourMultiPolygone($multiPolygone, $roles, $idRelation, $nbPoly); } private function getNombrePoly($idRelation) { $requete = 'SELECT MAX(num_poly) AS num_poly '. 'FROM osm_relation_a_chemins '. "WHERE id_relation = $idRelation ". ' -- '.__FILE__.' : '.__LINE__; $resultat = $this->bdd->recuperer($requete); return $resultat['num_poly']; } private function getCheminsParPolygone($idRelation, $numPoly) { $requete = 'SELECT id_chemin, sens, role '. 'FROM osm_relation_a_chemins '. "WHERE id_relation = $idRelation ". "AND num_poly = $numPoly ". 'ORDER BY ordre '. ' -- '.__FILE__.' : '.__LINE__; $chemins = $this->bdd->recupererTous($requete); return $chemins; } private function getNoeudsPourCheminEtSens($idChemin, $sens) { $tri = ($sens == 'directe') ? 'ASC' : 'DESC'; $requete = 'SELECT NLL.id_noeud, NLL.lat, NLL.`long` '. 'FROM osm_chemin_a_noeuds AS WN '. ' INNER JOIN osm_noeuds AS NLL ON (WN.id_noeud = NLL.id_noeud) '. "WHERE WN.id_chemin = $idChemin ". "ORDER BY WN.ordre $tri ". ' -- '.__FILE__.' : '.__LINE__; $noeuds = $this->bdd->recupererTous($requete); $latLng = array(); foreach ($noeuds as $noeud) { $latLng[] = $noeud['lat'].' '.$noeud['long']; } return $latLng; } /** * Remplie le champ polygone à partir du tableau MultiPolygone */ private function mettreAJourMultiPolygone($multiPolygone, $roles, $idRelation, $nbPoly) { // Présence d'une enclave contenue dans cette entité administrative mais qui appartient à une autre entité administrative if ((isset($roles['inner']) || isset($roles['enclave']))) { if ($nbPoly == 2) { $multiPoly = implode('),(', $multiPolygone); } else { $multiPoly = null; $msgTpl = "La relation '%s' possède plus de 2 polygones de type enclaves."; $this->messages->traiterErreur($msgTpl, array($idRelation)); } } else { // Tous les autres cas $multiPoly = implode(')),((', $multiPolygone); } if (isset($multiPoly)) { $this->mettreAJourCommune($idRelation, $multiPoly); } } private function mettreAJourCommune($idRelation, $multiPoly) { $requete = 'UPDATE osm_communes '. "SET polygone = MPOLYFROMTEXT('MULTIPOLYGON((($multiPoly)))'), ". "notes = 'Polygone complet' ". "WHERE id_relation = $idRelation ". ' -- '.__FILE__.' : '.__LINE__; $this->bdd->requeter($requete); } /** * Renomme la note des polygones vides d'un polygone complet en polygone incomplet */ private function renommerEnPolygoneIncomplet() { $requete = 'UPDATE osm_communes '. "SET notes = 'Polygone incomplet' ". "WHERE ASTEXT(polygone) IS NULL ". ' -- '.__FILE__.' : '.__LINE__; $retour = $this->bdd->requeter($requete); $this->messages->traiterInfo("Nombre de polygones définis à incomplet : ".$retour->rowCount()); } }