001: /*
002: * This file is part of the GeOxygene project source files.
003: *
004: * GeOxygene aims at providing an open framework which implements OGC/ISO specifications for
005: * the development and deployment of geographic (GIS) applications. It is a open source
006: * contribution of the COGIT laboratory at the Institut Géographique National (the French
007: * National Mapping Agency).
008: *
009: * See: http://oxygene-project.sourceforge.net
010: *
011: * Copyright (C) 2005 Institut Géographique National
012: *
013: * This library is free software; you can redistribute it and/or modify it under the terms
014: * of the GNU Lesser General Public License as published by the Free Software Foundation;
015: * either version 2.1 of the License, or any later version.
016: *
017: * This library is distributed in the hope that it will be useful, but WITHOUT ANY
018: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
019: * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
020: *
021: * You should have received a copy of the GNU Lesser General Public License along with
022: * this library (see file LICENSE if present); if not, write to the Free Software
023: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024: *
025: */
026:
027: package fr.ign.cogit.geoxygene.contrib.appariement.reseaux.topologie;
028:
029: import java.util.ArrayList;
030: import java.util.Iterator;
031: import java.util.List;
032:
033: import fr.ign.cogit.geoxygene.contrib.appariement.EnsembleDeLiens;
034: import fr.ign.cogit.geoxygene.contrib.appariement.reseaux.LienReseaux;
035: import fr.ign.cogit.geoxygene.contrib.cartetopo.Arc;
036: import fr.ign.cogit.geoxygene.contrib.cartetopo.Groupe;
037: import fr.ign.cogit.geoxygene.contrib.cartetopo.Noeud;
038: import fr.ign.cogit.geoxygene.contrib.geometrie.Distances;
039: import fr.ign.cogit.geoxygene.spatial.coordgeom.GM_LineString;
040:
041: /**
042: * Un Groupe est un ensemble d'arcs et de noeuds d'un reseau.
043: * L'appariement de réseaux à des échelles différentes abouti à de nombreux appariements 1-n,
044: * d'un objet vers un groupe.
045: *
046: * @author Mustiere - IGN / Laboratoire COGIT
047: * @version 1.0
048: *
049: */
050:
051: public class GroupeApp extends Groupe {
052:
053: private String resultatAppariement;
054:
055: public String getResultatAppariement() {
056: return resultatAppariement;
057: }
058:
059: public void setResultatAppariement(String resultat) {
060: resultatAppariement = resultat;
061: }
062:
063: /** affecte le resultat de l'appariement sur le groupe et ses composants */
064: public void setResultatAppariementGlobal(String resultat) {
065: setResultatAppariement(resultat);
066: Iterator itComposants;
067: itComposants = this .getListeArcs().iterator();
068: while (itComposants.hasNext()) {
069: ArcApp arc = (ArcApp) itComposants.next();
070: arc.setResultatAppariement(resultat);
071: }
072: itComposants = this .getListeNoeuds().iterator();
073: while (itComposants.hasNext()) {
074: NoeudApp noeud = (NoeudApp) itComposants.next();
075: noeud.setResultatAppariement(resultat);
076: }
077: }
078:
079: /** Liens qui référencent l'objet apparié */
080: private List liens = new ArrayList();
081:
082: public List getLiens() {
083: return liens;
084: }
085:
086: public void setLiens(List liens) {
087: this .liens = liens;
088: }
089:
090: public void addLiens(LienReseaux liens) {
091: this .liens.add(liens);
092: }
093:
094: /** Renvoie les liens de l'objet qui appartiennent à la liste liensPertinents */
095: public List getLiens(List liensPertinents) {
096: List listeTmp = new ArrayList(this .getLiens());
097: listeTmp.retainAll(liensPertinents);
098: return listeTmp;
099: }
100:
101: /** Les noeuds d'entree dans le groupe comp (au sens de la communication).
102: * La notion d'entrée / sortie est relative au préappariement d'arcs et au noeud ref passé en paramètre.
103: * La liste en sortie contient des NoeudApp */
104: public List noeudsEntree(NoeudApp noeudref,
105: EnsembleDeLiens liensPreappArcs) {
106: List arcsRef = new ArrayList();
107: List arcs = new ArrayList();
108: List arcsOK = new ArrayList();
109: List noeuds = new ArrayList();
110: ArcApp arccomp;
111: int i, j;
112:
113: arcsRef = noeudref.entrantsOrientes();
114: for (i = 0; i < this .getListeNoeuds().size(); i++) {
115: arcs = ((NoeudApp) this .getListeNoeuds().get(i))
116: .entrantsOrientes();
117: for (j = 0; j < arcs.size(); j++) {
118: arccomp = (ArcApp) arcs.get(j);
119: if (this .getListeArcs().contains(arccomp))
120: continue;
121: arcsOK = arccomp
122: .arcsRefEnCorrespondance(liensPreappArcs);
123: arcsOK.retainAll(arcsRef);
124: if (arcsOK.size() != 0) {
125: noeuds.add(this .getListeNoeuds().get(i));
126: break;
127: }
128: }
129: }
130: return noeuds;
131: }
132:
133: /** Les noeuds de sortie dans le groupe (au sens de la communication).
134: * La notion d'entrée / sortie est relative au préappariement d'arcs et au noeud ref passé en paramètre.
135: * La liste en sortie contient des Noeud */
136: public List noeudsSortie(NoeudApp noeudref,
137: EnsembleDeLiens liensPreappArcs) {
138: List arcsRef = new ArrayList();
139: List arcs = new ArrayList();
140: List arcsOK = new ArrayList();
141: List noeuds = new ArrayList();
142: ArcApp arcComp;
143: int i, j;
144:
145: arcsRef = noeudref.sortantsOrientes();
146: for (i = 0; i < this .getListeNoeuds().size(); i++) {
147: arcs = ((NoeudApp) this .getListeNoeuds().get(i))
148: .sortantsOrientes();
149: for (j = 0; j < arcs.size(); j++) {
150: arcComp = (ArcApp) arcs.get(j);
151: if (this .getListeArcs().contains(arcComp))
152: continue;
153: arcsOK = arcComp
154: .arcsRefEnCorrespondance(liensPreappArcs);
155: arcsOK.retainAll(arcsRef);
156: if (arcsOK.size() != 0) {
157: noeuds.add(this .getListeNoeuds().get(i));
158: break;
159: }
160: }
161: }
162: return noeuds;
163: }
164:
165: /** Enleve les premier et dernier noeuds du groupe.
166: * Utile pour traiter les plus courts chemins. */
167: public void enleveExtremites() {
168: NoeudApp ext;
169: if (this .getListeNoeuds().size() == 0)
170: return;
171: ext = (NoeudApp) this .getListeNoeuds().get(0);
172: this .getListeNoeuds().remove(ext);
173: ext.getListeGroupes().remove(this );
174: if (this .getListeNoeuds().size() == 0)
175: return;
176: ext = (NoeudApp) this .getListeNoeuds().get(
177: this .getListeNoeuds().size() - 1);
178: this .getListeNoeuds().remove(ext);
179: ext.getListeGroupes().remove(this );
180: }
181:
182: /** Plus court chemin dans this pour relier les noeudsDepart aux noeudsArrivee,
183: * NB: le pcc renvoyé ici NE CONTIENT PAS les noeuds initiaux et finaux */
184: public GroupeApp plusCourtChemin(List noeudsDepart,
185: List noeudsArrivee, double longMax) {
186: GroupeApp pccMin = null, pcc;
187: double longueur, longMin = longMax + 1;
188: Noeud iniComp, finComp;
189: for (int j = 0; j < noeudsDepart.size(); j++) {
190: for (int k = 0; k < noeudsArrivee.size(); k++) {
191: iniComp = (Noeud) noeudsDepart.get(j);
192: finComp = (Noeud) noeudsArrivee.get(k);
193: pcc = (GroupeApp) iniComp.plusCourtChemin(finComp,
194: this , longMax);
195: if (pcc == null)
196: continue;
197: longueur = pcc.longueur();
198: if (longueur < longMin) {
199: longMin = longueur;
200: if (pccMin != null)
201: pccMin.vide();
202: pccMin = pcc;
203: continue;
204: }
205: pcc.vide();
206: }
207: }
208: return pccMin;
209: }
210:
211: ///////////////////////////////////////////////////////////////////////////////////////////////////////
212: // FILTRAGES DES GROUPES LORS DE L'APPARIEMENT
213: ///////////////////////////////////////////////////////////////////////////////////////////////////////
214: /** Méthode permettant de filtrer un groupe du graphe de comparaison, supposé apparié
215: * avec un noeud du graphe de référence.
216: * D'après thèse de Thomas Devogèle (1997), avec ajouts de Sébastien Mustière (2002).
217: * S'appuie principalement sur des recherches d'impasses et des calculs de plus courts chemins.
218: * NB: le groupe en sortie peut être vide (filtrage trop fort)*/
219: public void filtrageGroupePendantAppariementDesNoeuds(
220: NoeudApp noeudRef, EnsembleDeLiens liensPreappArcs) {
221: int nbArcs;
222: boolean complet;
223:
224: // le traitement diffère pour les groupes complets à l'origine et les autres
225: if (noeudRef.correspCommunicants(this , liensPreappArcs) == 1)
226: complet = true;
227: else
228: complet = false;
229:
230: // 1. Elimination des impasses de BD comp. Récursif
231: while (true) {
232: nbArcs = this .getListeArcs().size();
233: if (nbArcs == 1)
234: break; // ajout seb mars 2005
235: this .filtrageImpasses();
236: if (this .getListeArcs().size() == nbArcs)
237: break;
238: }
239:
240: // 2. Elimination des impasses au sein du groupe (sans tenir compte des autres arcs de BDcomp)
241: // ET dont l'extrémité (à l'extérieure du groupe) n'a pas d'autre troncon apparié avec des arcs
242: // de la BDRef par le préappariement. Recursif tant qu'on en enleve encore
243: while (true) {
244: nbArcs = this .getListeArcs().size();
245: if (nbArcs == 1)
246: break; // ajout seb mars 2005
247: this .filtrageImpassesNonApparie(liensPreappArcs);
248: if (this .getListeArcs().size() == nbArcs)
249: break;
250: }
251:
252: // 3. Pour les groupes incomplets :
253: // Elimination des impasses au sein du groupe (sans tenir compte des autres arcs de BDcomp)
254: // ET dont l'extrémité (à l'extérieure du groupe) a tous ses troncons adjacents (y compris l'impasse)
255: // appariés avec le même arc de BDcomp. Recursif.
256: if (!complet) {
257: while (true) {
258: nbArcs = this .getListeArcs().size();
259: if (nbArcs == 1)
260: break; // ajout seb mars 2005
261: // modif Seb par rapport à Thomas
262: this .filtrageImpassesTousApparies(liensPreappArcs);
263: if (this .getListeArcs().size() == nbArcs)
264: break;
265: }
266: }
267:
268: // 3. Pour les groupes complets :
269: // Elimination des impasses au sein du groupe (sans tenir compte des autres arcs de BDcomp)
270: // qui laissent le groupe complet si on les enlève
271: if (complet) {
272: while (true) {
273: nbArcs = this .getListeArcs().size();
274: if (nbArcs == 1)
275: break; // ajout seb mars 2005
276: // modif Seb par rapport à Thomas
277: this
278: .filtrageImpassesComplets(noeudRef,
279: liensPreappArcs);
280: if (this .getListeArcs().size() == nbArcs)
281: break;
282: }
283: }
284:
285: // 4. Filtrage par plus court chemin
286: this .filtragePlusCourtChemin(noeudRef, liensPreappArcs);
287:
288: // 5. (idem 3)
289: if (!complet) {
290: while (true) {
291: nbArcs = this .getListeArcs().size();
292: if (nbArcs == 1)
293: break; // ajout seb mars 2005
294: // modif Seb par rapport à Thomas
295: this .filtrageImpassesTousApparies(liensPreappArcs);
296: if (this .getListeArcs().size() == nbArcs)
297: break;
298: }
299: }
300:
301: if (complet) {
302: while (true) {
303: nbArcs = this .getListeArcs().size();
304: if (nbArcs == 1)
305: break; // ajout seb mars 2005
306: // modif Seb par rapport à Thomas
307: this
308: .filtrageImpassesComplets(noeudRef,
309: liensPreappArcs);
310: if (this .getListeArcs().size() == nbArcs)
311: break;
312: }
313: }
314: }
315:
316: /** Methode utile pour le filtrage des groupes
317: * Elimination des impasses de BD comp */
318: private void filtrageImpasses() {
319: int i;
320: ArcApp arcComp;
321: List impassesDebut = new ArrayList();
322: List impassesFin = new ArrayList();
323:
324: // Recherche des arcs à éliminer
325: for (i = 0; i < this .getListeArcs().size(); i++) {
326: arcComp = (ArcApp) this .getListeArcs().get(i);
327: if (arcComp.impasseDebut())
328: impassesDebut.add(arcComp);
329: if (arcComp.impasseFin())
330: impassesFin.add(arcComp);
331: }
332: // Elimination des arcs à éliminer ainsi que de leurs extrémités libres
333: for (i = 0; i < impassesDebut.size(); i++) {
334: arcComp = (ArcApp) impassesDebut.get(i);
335: this .getListeArcs().remove(arcComp);
336: arcComp.getListeGroupes().remove(this );
337: this .getListeNoeuds().remove(arcComp.getNoeudIni());
338: ((NoeudApp) arcComp.getNoeudIni()).getListeGroupes()
339: .remove(this );
340: }
341: for (i = 0; i < impassesFin.size(); i++) {
342: arcComp = (ArcApp) impassesFin.get(i);
343: this .getListeArcs().remove(arcComp);
344: arcComp.getListeGroupes().remove(this );
345: this .getListeNoeuds().remove(arcComp.getNoeudFin());
346: ((NoeudApp) arcComp.getNoeudFin()).getListeGroupes()
347: .remove(this );
348: }
349: }
350:
351: /** Methode utile pour le filtrage des groupes
352: * Elimination des impasses AU SEIN du groupe et dont l'extrémité (à l'extérieure du groupe)
353: * n'a pas d'autre troncon apparié avec des arcs de la BD Ref (par le préappariement) */
354: private void filtrageImpassesNonApparie(
355: EnsembleDeLiens liensPreappArcs) {
356: int i, j;
357: boolean match;
358: ArcApp arcComp, arcAdjacent;
359: List adjacentsComp = new ArrayList();
360: List impassesDebut = new ArrayList();
361: List impassesFin = new ArrayList();
362:
363: // Recherche des arcs à éliminer
364: for (i = 0; i < this .getListeArcs().size(); i++) {
365: arcComp = (ArcApp) this .getListeArcs().get(i);
366: match = false;
367: if (arcComp.impasseDebut(this )) {
368: adjacentsComp = arcComp.getNoeudIni().arcs();
369: for (j = 0; j < adjacentsComp.size(); j++) {
370: arcAdjacent = (ArcApp) adjacentsComp.get(j);
371: if (arcAdjacent == arcComp)
372: continue;
373: if (arcAdjacent.aUnCorrespondant(liensPreappArcs)) {
374: match = true;
375: break;
376: }
377: }
378: if (!match)
379: impassesDebut.add(arcComp);
380: }
381: if (arcComp.impasseFin(this )) {
382: adjacentsComp = arcComp.getNoeudFin().arcs();
383: for (j = 0; j < adjacentsComp.size(); j++) {
384: arcAdjacent = (ArcApp) adjacentsComp.get(j);
385: if (arcAdjacent == arcComp)
386: continue;
387: if (arcAdjacent.aUnCorrespondant(liensPreappArcs)) {
388: match = true;
389: break;
390: }
391: }
392: if (!match)
393: impassesFin.add(arcComp);
394: }
395: }
396:
397: // Elimination des arcs à éliminer ainsi que de leurs extrémités libres
398: for (i = 0; i < impassesDebut.size(); i++) {
399: arcComp = (ArcApp) impassesDebut.get(i);
400: this .getListeArcs().remove(arcComp);
401: arcComp.getListeGroupes().remove(this );
402: this .getListeNoeuds().remove(arcComp.getNoeudIni());
403: ((NoeudApp) arcComp.getNoeudIni()).getListeGroupes()
404: .remove(this );
405: }
406: for (i = 0; i < impassesFin.size(); i++) {
407: arcComp = (ArcApp) impassesFin.get(i);
408: this .getListeArcs().remove(arcComp);
409: arcComp.getListeGroupes().remove(this );
410: this .getListeNoeuds().remove(arcComp.getNoeudFin());
411: ((NoeudApp) arcComp.getNoeudFin()).getListeGroupes()
412: .remove(this );
413: }
414: }
415:
416: /** Methode utile pour le filtrage des groupes
417: * Filtrage par "réduction"
418: * Elimination des impasses au sein du groupe et dont l'extrémité (à l'extérieure du groupe)
419: * a tous ses troncons appariés avec le même arc de BDcomp. */
420: private void filtrageImpassesTousApparies(
421: EnsembleDeLiens liensPreappArcs) {
422: int i, j;
423: List arcsCommuns = new ArrayList();
424: List arcsNouveaux = new ArrayList();
425: List arcsCompCommuniquants = new ArrayList();
426: ArcApp arcComp;
427: boolean communs;
428: List impassesDebut = new ArrayList();
429: List impassesFin = new ArrayList();
430:
431: // Recherche des arcs à éliminer
432: for (i = 0; i < this .getListeArcs().size(); i++) {
433: arcComp = (ArcApp) this .getListeArcs().get(i);
434: if (arcComp.impasseDebut(this )) {
435: // on cherche si tous les entrants/sortants du noeud ini de Arc_Comp
436: // sont appariés avec au moins un même arc de BDref commun
437: communs = true;
438: arcsCompCommuniquants = arcComp.getNoeudIni().arcs();
439: arcsCommuns = arcComp
440: .arcsRefEnCorrespondance(liensPreappArcs);
441: for (j = 0; j < arcsCompCommuniquants.size(); j++) {
442: arcsNouveaux = ((ArcApp) arcsCompCommuniquants
443: .get(j))
444: .arcsRefEnCorrespondance(liensPreappArcs);
445: if (arcsNouveaux.size() == 0)
446: continue;
447: arcsCommuns.retainAll(arcsNouveaux);
448: if (arcsCommuns.size() == 0) {
449: communs = false;
450: break;
451: }
452: }
453: if (communs)
454: impassesDebut.add(arcComp);
455: }
456: if (arcComp.impasseFin(this )) {
457: // on cherche si tous les entrants/sortants du noeud fin de arcComp
458: // sont appariés avec au moins un même arc de BDref commun
459: communs = true;
460: arcsCompCommuniquants = arcComp.getNoeudFin().arcs();
461: arcsCommuns = arcComp
462: .arcsRefEnCorrespondance(liensPreappArcs);
463: for (j = 0; j < arcsCompCommuniquants.size(); j++) {
464: arcsNouveaux = ((ArcApp) arcsCompCommuniquants
465: .get(j))
466: .arcsRefEnCorrespondance(liensPreappArcs);
467: if (arcsNouveaux.size() == 0)
468: continue;
469: arcsCommuns.retainAll(arcsNouveaux);
470: if (arcsCommuns.size() == 0) {
471: communs = false;
472: break;
473: }
474: }
475: if (communs)
476: impassesFin.add(arcComp);
477: }
478: }
479:
480: // Elimination des arcs à éliminer ainsi que de leurs extrémités libres
481: for (i = 0; i < impassesDebut.size(); i++) {
482: arcComp = (ArcApp) impassesDebut.get(i);
483: this .getListeArcs().remove(arcComp);
484: arcComp.getListeGroupes().remove(this );
485: this .getListeNoeuds().remove(arcComp.getNoeudIni());
486: ((NoeudApp) arcComp.getNoeudIni()).getListeGroupes()
487: .remove(this );
488: }
489: for (i = 0; i < impassesFin.size(); i++) {
490: arcComp = (ArcApp) impassesFin.get(i);
491: this .getListeArcs().remove(arcComp);
492: arcComp.getListeGroupes().remove(this );
493: this .getListeNoeuds().remove(arcComp.getNoeudFin());
494: ((NoeudApp) arcComp.getNoeudFin()).getListeGroupes()
495: .remove(this );
496: }
497: }
498:
499: /** Methode utile pour le filtrage des groupes
500: * Elimination des impasses de BD comp */
501: private void filtrageImpassesComplets(NoeudApp noeudRef,
502: EnsembleDeLiens liensPreappArcs) {
503: int i;
504: ArcApp arccomp;
505: int correspondance;
506: List arcsATester = new ArrayList();
507:
508: // Recherche des arcs à éliminer
509: arcsATester.addAll(this .getListeArcs());
510: for (i = 0; i < arcsATester.size(); i++) {
511: arccomp = (ArcApp) arcsATester.get(i);
512: if (arccomp.impasseDebut(this )) {
513: // on enlève l'arc, et on vérifie si le goupe est toujours complet, sinon on remet l'arc
514: this .getListeArcs().remove(arccomp);
515: arccomp.getListeGroupes().remove(this );
516: this .getListeNoeuds().remove(arccomp.getNoeudIni());
517: ((NoeudApp) arccomp.getNoeudIni()).getListeGroupes()
518: .remove(this );
519: correspondance = noeudRef.correspCommunicants(this ,
520: liensPreappArcs);
521: if (correspondance == 1)
522: return;
523: this .getListeArcs().add(arccomp);
524: arccomp.getListeGroupes().add(this );
525: this .getListeNoeuds().add(arccomp.getNoeudIni());
526: ((NoeudApp) arccomp.getNoeudIni()).getListeGroupes()
527: .add(this );
528: }
529: if (arccomp.impasseFin(this )) {
530: // on enlève l'arc, et on vérifie si le goupe est toujours complet, sinon on remet l'arc
531: this .getListeArcs().remove(arccomp);
532: arccomp.getListeGroupes().remove(this );
533: this .getListeNoeuds().remove(arccomp.getNoeudFin());
534: ((NoeudApp) arccomp.getNoeudFin()).getListeGroupes()
535: .remove(this );
536: correspondance = noeudRef.correspCommunicants(this ,
537: liensPreappArcs);
538: if (correspondance == 1)
539: return;
540: this .getListeArcs().add(arccomp);
541: arccomp.getListeGroupes().add(this );
542: this .getListeNoeuds().add(arccomp.getNoeudFin());
543: ((NoeudApp) arccomp.getNoeudFin()).getListeGroupes()
544: .add(this );
545: }
546: }
547: }
548:
549: /** Méthode utile pour le filtrage des groupes */
550: private void filtragePlusCourtChemin(NoeudApp noeudRef,
551: EnsembleDeLiens liensPreappArcs) {
552:
553: List noeudsIn = new ArrayList();
554: List noeudsOut = new ArrayList();
555: List arcsOK = new ArrayList();
556: List noeudsOK = new ArrayList();
557: List noeudsAEnlever = new ArrayList();
558: List arcsAEnlever = new ArrayList();
559: GroupeApp pcc;
560: NoeudApp in, out, noeudComp;
561: ArcApp arcComp;
562: int i, j, k;
563:
564: noeudsIn = this .noeudsEntree(noeudRef, liensPreappArcs);
565: noeudsOut = this .noeudsSortie(noeudRef, liensPreappArcs);
566:
567: // Quand il n'y que des entrants ou que des sortants, on les garde ainsi que
568: // les arcs qui les relient (bidouille, j'en conviens)
569: if (noeudsIn.size() == 0) {
570: noeudsIn.addAll(noeudsOut);
571: }
572: if (noeudsOut.size() == 0) {
573: noeudsOut.addAll(noeudsIn);
574: }
575:
576: for (i = 0; i < noeudsIn.size(); i++) {
577: for (j = 0; j < noeudsOut.size(); j++) {
578: in = (NoeudApp) noeudsIn.get(i);
579: out = (NoeudApp) noeudsOut.get(j);
580: // if ( in == out ) continue;
581: pcc = (GroupeApp) in.plusCourtChemin(out, this , 0); // plus court chemin dans le groupe
582: if (pcc == null)
583: continue;
584: for (k = 0; k < pcc.getListeArcs().size(); k++) {
585: arcsOK.add(pcc.getListeArcs().get(k));
586: }
587: for (k = 0; k < pcc.getListeNoeuds().size(); k++) {
588: noeudsOK.add(pcc.getListeNoeuds().get(k));
589: }
590: // A faire ? vider le pcc pour faire propre ?
591: }
592: }
593:
594: for (i = 0; i < this .getListeNoeuds().size(); i++) {
595: if (!noeudsOK.contains(this .getListeNoeuds().get(i)))
596: noeudsAEnlever.add(this .getListeNoeuds().get(i));
597: }
598: for (i = 0; i < this .getListeArcs().size(); i++) {
599: if (!arcsOK.contains(this .getListeArcs().get(i)))
600: arcsAEnlever.add(this .getListeArcs().get(i));
601: }
602: for (i = 0; i < noeudsAEnlever.size(); i++) {
603: noeudComp = (NoeudApp) noeudsAEnlever.get(i);
604: this .getListeNoeuds().remove(noeudComp);
605: noeudComp.getListeGroupes().remove(this );
606: }
607: for (i = 0; i < arcsAEnlever.size(); i++) {
608: arcComp = (ArcApp) arcsAEnlever.get(i);
609: this .getListeArcs().remove(arcComp);
610: arcComp.getListeGroupes().remove(this );
611: }
612: }
613:
614: //////////////////////////////////////////////////////////////////////////////////////
615: // POUR EXPORT UNIQUEMENT
616: //////////////////////////////////////////////////////////////////////////////////////
617: /** Pour l'export : mise bout à bout des arcs du groupe, dans le bon ordre. NB: n'est valable que pour un groupe
618: * où les arcs sont bout à bout, et dans le bon ordre, comme ceux issus du plus_court_chemin
619: * Cas particuliers :
620: * si le goupe est vide, renvoie null;
621: * si le goupe ne contient que des points, renvoie une ligne dégénérée contenant 2 fois le premier point. */
622: public GM_LineString compileArcs(Arc arcRef) {
623: Arc arc, premierArc;
624: Noeud premierNoeud;
625: GM_LineString chemin = new GM_LineString();
626: GM_LineString chemin2 = new GM_LineString();
627: Iterator itArcs = this .getListeArcs().iterator();
628: double d1, d2;
629: int i;
630:
631: if (!(itArcs.hasNext())) {
632: if (this .getListeNoeuds().size() == 0)
633: return null;
634: chemin.addControlPoint(((NoeudApp) this .getListeNoeuds()
635: .get(0)).getCoord());
636: chemin.addControlPoint(((NoeudApp) this .getListeNoeuds()
637: .get(0)).getCoord());
638: return chemin;
639: }
640:
641: // on met bout à bout les arcs
642: premierArc = (ArcApp) this .getListeArcs().get(0);
643: if (this .getListeNoeuds().contains(premierArc.getNoeudIni()))
644: premierNoeud = premierArc.getNoeudFin();
645: else
646: premierNoeud = premierArc.getNoeudIni();
647:
648: while (itArcs.hasNext()) {
649: arc = (Arc) itArcs.next();
650: if (arc.getNoeudIni() == premierNoeud) {
651: for (i = 0; i < arc.getCoord().size(); i++) {
652: chemin.addControlPoint(arc.getCoord().get(i));
653: premierNoeud = arc.getNoeudFin();
654: }
655: } else {
656: for (i = 0; i < arc.getCoord().size(); i++) {
657: chemin.addControlPoint(arc.getCoord().get(
658: arc.getCoord().size() - i - 1));
659: premierNoeud = arc.getNoeudIni();
660: }
661: }
662: }
663:
664: // on inverse l'arc au besoin.
665: d1 = Distances.distance(chemin.startPoint(), arcRef
666: .getGeometrie().startPoint())
667: + Distances.distance(chemin.endPoint(), arcRef
668: .getGeometrie().endPoint());
669: d2 = Distances.distance(chemin.startPoint(), arcRef
670: .getGeometrie().endPoint())
671: + Distances.distance(chemin.endPoint(), arcRef
672: .getGeometrie().startPoint());
673: if (d1 < d2)
674: chemin2 = chemin;
675: else {
676: for (i = 0; i < chemin.sizeControlPoint(); i++) {
677: chemin2.addControlPoint(chemin.getControlPoint(chemin
678: .sizeControlPoint()
679: - i - 1));
680: }
681: }
682:
683: return chemin2;
684: }
685:
686: }
|