Source Code Cross Referenced for Arc.java in  » GIS » GeOxygene-1.3 » fr » ign » cogit » geoxygene » contrib » cartetopo » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » GIS » GeOxygene 1.3 » fr.ign.cogit.geoxygene.contrib.cartetopo 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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.cartetopo;
028:
029:        import java.util.ArrayList;
030:        import java.util.Collection;
031:        import java.util.Iterator;
032:        import java.util.List;
033:
034:        import fr.ign.cogit.geoxygene.contrib.geometrie.Distances;
035:        import fr.ign.cogit.geoxygene.contrib.geometrie.Operateurs;
036:        import fr.ign.cogit.geoxygene.contrib.geometrie.Rectangle;
037:        import fr.ign.cogit.geoxygene.feature.Population;
038:        import fr.ign.cogit.geoxygene.spatial.coordgeom.DirectPosition;
039:        import fr.ign.cogit.geoxygene.spatial.coordgeom.DirectPositionList;
040:        import fr.ign.cogit.geoxygene.spatial.coordgeom.GM_LineString;
041:        import fr.ign.cogit.geoxygene.spatial.coordgeom.GM_Polygon;
042:        import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Point;
043:
044:        /**
045:         * Classe des arcs de la carte topo.
046:         * Les arcs ont pour géométrie une GM_LineString, et peuvent être orientés.
047:         * Des méthodes sont prévues pour une gestion de réseau, de graphe, et de carte topologique.
048:         * 
049:         * English: arcs of a topological map
050:         * @author  Mustière/Bonin
051:         * @version 1.0
052:         */
053:
054:        public class Arc extends ElementCarteTopo {
055:
056:            public Arc() {
057:            }
058:
059:            /////////////////////////////////////////////////////////////////////////////////////////////////
060:            //                                      Géométrie
061:            /////////////////////////////////////////////////////////////////////////////////////////////////
062:            /** Renvoie le GM_LineString qui définit la géométrie de self */
063:            public GM_LineString getGeometrie() {
064:                return (GM_LineString) geom;
065:            }
066:
067:            /** Définit le GM_LineString qui définit la géométrie de self */
068:            public void setGeometrie(GM_LineString geometrie) {
069:                this .setGeom(geometrie);
070:            }
071:
072:            /** Renvoie la liste de DirectPosition qui définit les coordonnées de self */
073:            public DirectPositionList getCoord() {
074:                return geom.coord();
075:            }
076:
077:            /** Définit la liste de DirectPosition qui définit les coordonnées de self */
078:            public void setCoord(DirectPositionList dpl) {
079:                geom = new GM_LineString(dpl);
080:            }
081:
082:            /////////////////////////////////////////////////////////////////////////////////////////////////
083:            //                          Gestion de la topologie arc / noeuds  
084:            /////////////////////////////////////////////////////////////////////////////////////////////////
085:            private Noeud noeudIni;
086:
087:            /** Renvoie le noeud initial de self */
088:            public Noeud getNoeudIni() {
089:                return this .noeudIni;
090:            }
091:
092:            /** Définit le noeud initial de self. 
093:             * NB: met à jour la relation inverse "sortants" de noeud
094:             */
095:            public void setNoeudIni(Noeud noeud) {
096:                if (noeud != null) {
097:                    this .noeudIni = noeud;
098:                    if (!noeud.getSortants().contains(this ))
099:                        noeud.addSortant(this );
100:                } else {
101:                    if (this .getNoeudIni() != null)
102:                        this .getNoeudIni().getSortants().remove(noeud);
103:                    noeudIni = null;
104:                }
105:            }
106:
107:            private Noeud noeudFin;
108:
109:            /** Renvoie le noeud final de self */
110:            public Noeud getNoeudFin() {
111:                return this .noeudFin;
112:            }
113:
114:            /** Définit le noeud final de self.
115:             * NB: met à jour la relation inverse "entrants" de noeud
116:             */
117:            public void setNoeudFin(Noeud noeud) {
118:                if (noeud != null) {
119:                    this .noeudFin = noeud;
120:                    if (!noeud.getEntrants().contains(this ))
121:                        noeud.addEntrant(this );
122:                } else {
123:                    if (this .getNoeudFin() != null)
124:                        this .getNoeudFin().getEntrants().remove(noeud);
125:                    noeudFin = null;
126:                }
127:            }
128:
129:            /** Renvoie le noeud initial et final de self */
130:            public List noeuds() {
131:                List noeuds = new ArrayList();
132:                if (!(noeudIni == null))
133:                    noeuds.add(noeudIni);
134:                if (!(noeudFin == null))
135:                    noeuds.add(noeudFin);
136:                return noeuds;
137:            }
138:
139:            /** Projete le point P sur l'arc et découpe l'arc en 2 avec ce point projeté.
140:             * NB: si la projection tombe sur une extrémité de l'arc : ne fait rien.
141:             */
142:            public void projeteEtDecoupe(GM_Point P) {
143:                DirectPositionList listePoints = this .getGeometrie().coord();
144:                DirectPositionList ptsAvant, ptsApres;
145:                Arc arcAvant, arcApres;
146:                double d, dmin;
147:                DirectPosition pt, ptmin;
148:                int positionMin = 0;
149:                Noeud nouveauNoeud;
150:
151:                if (this .getCarteTopo() == null)
152:                    return;
153:
154:                Population popNoeuds = this .getCarteTopo().getPopNoeuds();
155:                Population popArcs = this .getCarteTopo().getPopArcs();
156:                int i;
157:
158:                if (listePoints.size() < 2)
159:                    return;
160:                ptmin = Operateurs.projection(P.getPosition(), listePoints
161:                        .get(0), listePoints.get(1));
162:                dmin = Distances.distance(P.getPosition(), ptmin);
163:                for (i = 1; i < listePoints.size() - 1; i++) {
164:                    pt = Operateurs.projection(P.getPosition(), listePoints
165:                            .get(i), listePoints.get(i + 1));
166:                    d = Distances.distance(P.getPosition(), pt);
167:                    if (d < dmin) {
168:                        ptmin = pt;
169:                        dmin = d;
170:                        positionMin = i;
171:                    }
172:                }
173:                if (Distances.distance(ptmin, listePoints.get(0)) == 0)
174:                    return;
175:                if (Distances.distance(ptmin, listePoints.get(listePoints
176:                        .size() - 1)) == 0)
177:                    return;
178:
179:                // création du nouveau noeud
180:                nouveauNoeud = (Noeud) popNoeuds.nouvelElement();
181:                nouveauNoeud.setGeometrie(new GM_Point(ptmin));
182:
183:                // création des nouveaux arcs
184:                ptsAvant = new DirectPositionList();
185:                ptsApres = new DirectPositionList();
186:
187:                for (i = 0; i <= positionMin; i++)
188:                    ptsAvant.add(listePoints.get(i));
189:                ptsAvant.add(ptmin);
190:                arcAvant = (Arc) popArcs.nouvelElement();
191:                arcAvant.setGeometrie(new GM_LineString(ptsAvant));
192:
193:                if (Distances.distance(ptmin, listePoints.get(positionMin + 1)) != 0)
194:                    ptsApres.add(ptmin);
195:                for (i = positionMin + 1; i < listePoints.size(); i++)
196:                    ptsApres.add(listePoints.get(i));
197:                arcApres = (Arc) popArcs.nouvelElement();
198:                arcApres.setGeometrie(new GM_LineString(ptsApres));
199:
200:                // instanciation de la topologie et des attributs
201:                this .getNoeudIni().getSortants().remove(this );
202:                arcAvant.setNoeudIni(this .getNoeudIni());
203:                arcAvant.setNoeudFin(nouveauNoeud);
204:                arcAvant.setCorrespondants(this .getCorrespondants());
205:                arcAvant.setOrientation(this .getOrientation());
206:
207:                arcApres.setNoeudIni(nouveauNoeud);
208:                this .getNoeudFin().getEntrants().remove(this );
209:                arcApres.setNoeudFin(this .getNoeudFin());
210:                arcApres.setCorrespondants(this .getCorrespondants());
211:                arcApres.setOrientation(this .getOrientation());
212:
213:                //destruction de l'ancien arc
214:                this .setNoeudIni(null);
215:                this .setNoeudFin(null);
216:                popArcs.enleveElement(this );
217:            }
218:
219:            /////////////////////////////////////////////////////////////////////////////////////////////////
220:            //                          Gestion de la topologie arc / faces
221:            /////////////////////////////////////////////////////////////////////////////////////////////////
222:            /** Renvoie la face à gauche et à droite de self */
223:            public List faces() {
224:                List faces = new ArrayList();
225:                if (this .getFaceGauche() != null)
226:                    faces.add(this .getFaceGauche());
227:                if (this .getFaceDroite() != null)
228:                    faces.add(this .getFaceDroite());
229:                return faces;
230:            }
231:
232:            private Face faceGauche;
233:
234:            /** Renvoie la face à gauche de self */
235:            public Face getFaceGauche() {
236:                return this .faceGauche;
237:            }
238:
239:            /** Définit la face à gauche de self.
240:             * NB: met à jour la relation inverse "arsc directs" de face
241:             */
242:            public void setFaceGauche(Face face) {
243:                if (face != null) {
244:                    this .faceGauche = face;
245:                    if (!face.getArcsDirects().contains(this ))
246:                        face.addArcDirect(this );
247:                } else {
248:                    if (this .getFaceGauche() != null)
249:                        this .getFaceGauche().getArcsDirects().remove(face);
250:                    faceGauche = null;
251:                }
252:            }
253:
254:            private Face faceDroite;
255:
256:            /** Renvoie la face à droite de self */
257:            public Face getFaceDroite() {
258:                return this .faceDroite;
259:            }
260:
261:            /** Définit la face à droite de self.
262:             * NB: met à jour la relation inverse "arsc indirects" de face
263:             */
264:            public void setFaceDroite(Face face) {
265:                if (face != null) {
266:                    this .faceDroite = face;
267:                    if (!face.getArcsIndirects().contains(this ))
268:                        face.addArcIndirect(this );
269:                } else {
270:                    if (this .getFaceDroite() != null)
271:                        this .getFaceDroite().getArcsIndirects().remove(face);
272:                    faceDroite = null;
273:                }
274:            }
275:
276:            /** Recherche du cycle du réseau à droite de l'arc en se basant sur la topologie de RESEAU uniquement.
277:             *  Renvoie une liste (ArrayList) de 3 éléments : 
278:             *    - get(0): Liste des arcs dans l'ordre de parcours du cycle 
279:             *              Liste classée dans le sens anti-trigonometrique (sauf pour la face exterieure).
280:             *              (liste de type "ArrayList", contenant elle-même des "Arc").
281:             *    - get(1): Liste des orientations des arc : true si l'arc à sa face à droite, false sinon
282:             *              (liste de type "ArrayList", contenant elle-même des objets "Boolean").
283:             *    - get(2) : La géométrie du polygone faisant le tour du cycle
284:             *               (de type "GM_Polygon)
285:             *  NB: la liste retournée est égale à null si on n'a pas trouvé de cycle 
286:             *          (cas pouvant arriver si la topologie arcs/noeuds n'est pas complète.
287:             *  NB: ne nécessite PAS d'avoir une topologie arcs/faces instanciée. 
288:             *  NB: nécessite d'avoir une topologie arcs/noeuds instanciée. 
289:             *  NB: un cycle passe 2 fois (une fois dans chaque sens) par les cul-de-sac si il y en a.
290:             */
291:            public List cycleADroite() {
292:                Arc arcEnCours;
293:                boolean sensEnCours;
294:                List arcOriente;
295:                GM_LineString contour = new GM_LineString();
296:                ;
297:                List arcsDuCycle = new ArrayList();
298:                List orientationsDuCycle = new ArrayList();
299:                List resultat = new ArrayList();
300:                int i;
301:
302:                // intialisation avec le premier arc du cycle (this) qui est par définition dans le bon sens 
303:                arcEnCours = this ;
304:                sensEnCours = true;
305:
306:                // on parcours le cycle dans le sens anti-trigonometrique, 
307:                // jusqu'à revenir sur this en le parcourant dans le bon sens 
308:                // (précision utile à la gestion des cul-de-sac).
309:                while (true) {
310:                    // ajout de l'arc en cours au cycle...
311:                    arcsDuCycle.add(arcEnCours);
312:                    orientationsDuCycle.add(new Boolean(sensEnCours));
313:                    if (sensEnCours) { // arc dans le bon sens
314:                        for (i = 0; i < arcEnCours.getGeometrie()
315:                                .sizeControlPoint() - 1; i++) {
316:                            contour.addControlPoint(arcEnCours.getGeometrie()
317:                                    .getControlPoint(i));
318:                        }
319:                        arcOriente = arcEnCours.arcSuivantFin();
320:                    } else { // arc dans le sens inverse 
321:                        for (i = arcEnCours.getGeometrie().sizeControlPoint() - 1; i > 0; i--) {
322:                            contour.addControlPoint(arcEnCours.getGeometrie()
323:                                    .getControlPoint(i));
324:                        }
325:                        arcOriente = arcEnCours.arcSuivantDebut();
326:                    }
327:                    if (arcOriente == null) {
328:                        return null;
329:                    }
330:
331:                    // au suivant...
332:                    arcEnCours = (Arc) arcOriente.get(0); //l'arc
333:                    sensEnCours = !((Boolean) arcOriente.get(1)).booleanValue(); //le sens de l'arc par rapport au cycle
334:
335:                    //c'est fini ?
336:                    if (arcEnCours == this  && sensEnCours)
337:                        break;
338:                }
339:
340:                // ajout du dernier point pour finir la boucle du polygone
341:                contour.addControlPoint(contour.startPoint());
342:
343:                resultat.add(arcsDuCycle);
344:                resultat.add(orientationsDuCycle);
345:                resultat.add(new GM_Polygon(contour));
346:                return resultat;
347:            }
348:
349:            /** Recherche du cycle du réseau à gauche de l'arc en se basant sur la topologie de RESEAU uniquement.
350:             *  Renvoie une liste (ArrayList) de 3 éléments : 
351:             *    - get(0): Liste des arcs dans l'ordre de parcours du cycle. 
352:             *              Liste classée dans le sens trigonometrique (sauf pour la face exterieure).
353:             *              (liste de type "ArrayList", contenant elle-même des "Arc").
354:             *    - get(1): Liste des orientations des arc : true si l'arc à sa face à gauche, false sinon
355:             *              (liste de type "ArrayList", contenant elle-même des objets "Boolean").
356:             *    - get(2) : La géométrie du polygone faisant le tour du cycle
357:             *               (de type "GM_Polygon)
358:             *  NB: la liste retournée est égale à null si on n'a pas trouvé de cycle 
359:             *          (cas pouvant arriver si la topologie arcs/noeuds n'est pas complète.
360:             *  NB: ne nécessite PAS d'avoir une topologie arcs/faces instanciée. 
361:             *  NB: nécessite d'avoir une topologie arcs/noeuds instanciée. 
362:             *  NB: un cycle passe 2 fois (une fois dans chaque sens) par les cul-de-sac si il y en a.
363:             */
364:            public List cycleAGauche() {
365:                Arc arcEnCours;
366:                boolean sensEnCours;
367:                List arcOriente;
368:                GM_LineString contour = new GM_LineString();
369:                ;
370:                List arcsDuCycle = new ArrayList();
371:                List orientationsDuCycle = new ArrayList();
372:                List resultat = new ArrayList();
373:                int i;
374:
375:                // intialisation avec le premier arc du cycle (this) qui est par définition dans le bon sens 
376:                arcEnCours = this ;
377:                sensEnCours = true;
378:
379:                // on parcours le cycle dans le sens anti-trigonometrique, 
380:                // jusqu'à revenir sur this en le parcourant dans le bon sens 
381:                // (précision utile à la gestion des cul-de-sac).
382:                while (true) {
383:                    // ajout de l'arc en cours au cycle...
384:                    arcsDuCycle.add(arcEnCours);
385:                    orientationsDuCycle.add(new Boolean(sensEnCours));
386:                    if (sensEnCours) { // arc dans le bon sens
387:                        for (i = 0; i < arcEnCours.getGeometrie()
388:                                .sizeControlPoint() - 1; i++) {
389:                            contour.addControlPoint(arcEnCours.getGeometrie()
390:                                    .getControlPoint(i));
391:                        }
392:                        arcOriente = arcEnCours.arcPrecedentFin();
393:                    } else { // arc dans le sens inverse 
394:                        for (i = arcEnCours.getGeometrie().sizeControlPoint() - 1; i > 0; i--) {
395:                            contour.addControlPoint(arcEnCours.getGeometrie()
396:                                    .getControlPoint(i));
397:                        }
398:                        arcOriente = arcEnCours.arcPrecedentDebut();
399:                    }
400:                    if (arcOriente == null) {
401:                        return null;
402:                    }
403:
404:                    // au suivant...
405:                    arcEnCours = (Arc) arcOriente.get(0); //l'arc
406:                    sensEnCours = !((Boolean) arcOriente.get(1)).booleanValue(); //le sens de l'arc par rapport au cycle
407:
408:                    //c'est fini ?
409:                    if (arcEnCours == this  && sensEnCours)
410:                        break;
411:                }
412:
413:                // ajout du dernier point pour finir la boucle du polygone
414:                contour.addControlPoint(contour.startPoint());
415:
416:                resultat.add(arcsDuCycle);
417:                resultat.add(orientationsDuCycle);
418:                resultat.add(new GM_Polygon(contour));
419:                return resultat;
420:            }
421:
422:            /////////////////////////////////////////////////////////////////////////////////////////////////
423:            //                      Gestion de type carte topopolgique 
424:            /////////////////////////////////////////////////////////////////////////////////////////////////
425:            // Les arcs sont classés autour d'un noeud en fonction de leur géométrie. 
426:            // Ceci permet en particulier de parcourir facilement les cycles d'un graphe.
427:            /////////////////////////////////////////////////////////////////////////////////////////////////
428:
429:            /** Arc suivant self à son noeud final, au sens des cartes topologiques.
430:             *  L'arc suivant est l'arc incident au noeud final de self, 
431:             *  et suivant self dans l'ordre trigonométrique autour de ce noeud final.
432:             *
433:             *  NB: renvoie une liste de 2 éléments :
434:             *      element 1, liste.get(0) = l'arc
435:             *      element 2, liste.get(1) = Boolean, true si entrant, false si sortant
436:             *  NB: calcul réalisé pour chaque appel de la méthode.
437:             *  NB : l'arcSuivant peut être self, en cas de cul de sac sur le noeud final.
438:             */
439:            public List arcSuivantFin() {
440:                if (this .getNoeudFin() == null)
441:                    return null;
442:                List arcs = (List) this .getNoeudFin().arcsClasses().get(0);
443:                List arcsOrientation = (List) this .getNoeudFin().arcsClasses()
444:                        .get(1);
445:                Iterator itArcs = arcs.iterator();
446:                Iterator itArcsOrientation = arcsOrientation.iterator();
447:                Boolean orientationEntrant;
448:                Arc arc;
449:                List resultat = new ArrayList();
450:
451:                // On parcours la liste des arcs autour du noeud final
452:                // Quand on y rencontre this en tant qu'entrant, on renvoie le suivant dans la liste
453:                // NB: cette notion d'entrant est nécesaire pour bien gérer les boucles
454:                while (itArcs.hasNext()) {
455:                    arc = (Arc) itArcs.next();
456:                    orientationEntrant = (Boolean) itArcsOrientation.next();
457:                    if ((arc == this ) && orientationEntrant.booleanValue()) {
458:                        if (itArcs.hasNext()) {
459:                            resultat.add((Arc) itArcs.next());
460:                            resultat.add((Boolean) itArcsOrientation.next());
461:                        } else {
462:                            resultat.add((Arc) arcs.get(0));
463:                            resultat.add((Boolean) arcsOrientation.get(0));
464:                        }
465:                        return resultat;
466:                    }
467:                }
468:                return null;
469:            }
470:
471:            /** Arc suivant self à son noeud initial, au sens des cartes topologiques.
472:             *  L'arc suivant est l'arc incident au noeud initial de self, 
473:             *  et suivant self dans l'ordre trigonométrique autour de ce noeud initial.
474:             *
475:             *  NB: renvoie une liste de 2 éléments :
476:             *      element 1, liste.get(0) = l'arc
477:             *      element 2, liste.get(1) = Boolean, true si entrant, false si sortant
478:             *  NB: calcul réalisé pour chaque appel de la méthode.
479:             *  NB : l'arcSuivant peut être self, en cas de cul de sac sur le noeud initial.
480:             */
481:            public List arcSuivantDebut() {
482:                if (this .getNoeudIni() == null)
483:                    return null;
484:                List arcs = (List) this .getNoeudIni().arcsClasses().get(0);
485:                List arcsOrientation = (List) this .getNoeudIni().arcsClasses()
486:                        .get(1);
487:                Iterator itArcs = arcs.iterator();
488:                Iterator itArcsOrientation = arcsOrientation.iterator();
489:                Boolean orientationEntrant;
490:                Arc arc;
491:                List resultat = new ArrayList();
492:
493:                // On parcours la liste des arcs autour du noeud initial
494:                // Quand on y rencontre this en tant que sortant, on renvoie le suivant dans la liste
495:                // NB: cette notion de sortant est nécesaire pour bien gérer les boucles.
496:                while (itArcs.hasNext()) {
497:                    arc = (Arc) itArcs.next();
498:                    orientationEntrant = (Boolean) itArcsOrientation.next();
499:                    if ((arc == this ) && !orientationEntrant.booleanValue()) {
500:                        if (itArcs.hasNext()) {
501:                            resultat.add((Arc) itArcs.next());
502:                            resultat.add((Boolean) itArcsOrientation.next());
503:                        } else {
504:                            resultat.add((Arc) arcs.get(0));
505:                            resultat.add((Boolean) arcsOrientation.get(0));
506:                        }
507:                        return resultat;
508:                    }
509:                }
510:                return null;
511:            }
512:
513:            /** Arc précédant self à son noeud final, au sens des cartes topologiques.
514:             *  L'arc précédent est l'arc incident au noeud final de self, 
515:             *  et précédant self dans l'ordre trigonométrique autour de ce noeud final.
516:             *
517:             *  NB: renvoie une liste de 2 éléments :
518:             *      element 1, liste.get(0) = l'arc
519:             *      element 2, liste.get(1) = Boolean, true si entrant, false si sortant
520:             *  NB: calcul réalisé pour chaque appel de la méthode.
521:             *  NB : l'arc précédent peut être self, en cas de cul de sac sur le noeud final.
522:             */
523:            public List arcPrecedentFin() {
524:                if (this .getNoeudFin() == null)
525:                    return null;
526:                List arcs = (List) this .getNoeudFin().arcsClasses().get(0);
527:                List arcsOrientation = (List) this .getNoeudFin().arcsClasses()
528:                        .get(1);
529:                Iterator itArcs = arcs.iterator();
530:                Iterator itArcsOrientation = arcsOrientation.iterator();
531:                Boolean orientationEntrant, orientationPrecedent;
532:                Arc arc, arcPrecedent;
533:                List resultat = new ArrayList();
534:
535:                // On parcours la liste des arcs autour du noeud final
536:                // Quand on y rencontre this en tant qu'entrant, on renvoie le précédant dans la liste
537:                // NB: cette notion de précédant est nécesaire pour bien gérer les boucles.
538:                arc = (Arc) itArcs.next();
539:                orientationEntrant = (Boolean) itArcsOrientation.next();
540:                if ((arc == this ) && orientationEntrant.booleanValue()) {
541:                    resultat.add((Arc) arcs.get(arcs.size() - 1));
542:                    resultat
543:                            .add((Boolean) arcsOrientation.get(arcs.size() - 1));
544:                    return resultat;
545:                }
546:                while (itArcs.hasNext()) {
547:                    arcPrecedent = arc;
548:                    orientationPrecedent = orientationEntrant;
549:                    arc = (Arc) itArcs.next();
550:                    orientationEntrant = (Boolean) itArcsOrientation.next();
551:                    if ((arc == this ) && orientationEntrant.booleanValue()) {
552:                        resultat.add(arcPrecedent);
553:                        resultat.add(orientationPrecedent);
554:                        return resultat;
555:                    }
556:                }
557:                return null;
558:            }
559:
560:            /** Arc précédent self à son noeud initial, au sens des cartes topologiques.
561:             *  L'arc précédent est l'arc incident au noeud initial de self, 
562:             *  et précédent self dans l'ordre trigonométrique autour de ce noeud initial.
563:             *
564:             *  NB: renvoie une liste de 2 éléments :
565:             *      element 1, liste.get(0) = l'arc
566:             *      element 2, liste.get(1) = Boolean, true si entrant, false si sortant
567:             *  NB: calcul réalisé pour chaque appel de la méthode.
568:             *  NB : l'arc précédent peut être self, en cas de cul de sac sur le noeud initial.
569:             */
570:            public List arcPrecedentDebut() {
571:                if (this .getNoeudIni() == null)
572:                    return null;
573:                List arcs = (List) this .getNoeudIni().arcsClasses().get(0);
574:                List arcsOrientation = (List) this .getNoeudIni().arcsClasses()
575:                        .get(1);
576:                Iterator itArcs = arcs.iterator();
577:                Iterator itArcsOrientation = arcsOrientation.iterator();
578:                Boolean orientationEntrant, orientationPrecedent;
579:                Arc arc, arcPrecedent;
580:                List resultat = new ArrayList();
581:
582:                // On parcours la liste des arcs autour du noeud initial
583:                // Quand on y rencontre this en tant que sortant, on renvoie le précédant dans la liste
584:                // NB: cette notion de précédant est nécesaire pour bien gérer les boucles.
585:                arc = (Arc) itArcs.next();
586:                orientationEntrant = (Boolean) itArcsOrientation.next();
587:                if ((arc == this ) && !orientationEntrant.booleanValue()) {
588:                    resultat.add((Arc) arcs.get(arcs.size() - 1));
589:                    resultat
590:                            .add((Boolean) arcsOrientation.get(arcs.size() - 1));
591:                    return resultat;
592:                }
593:                while (itArcs.hasNext()) {
594:                    arcPrecedent = arc;
595:                    orientationPrecedent = orientationEntrant;
596:                    arc = (Arc) itArcs.next();
597:                    orientationEntrant = (Boolean) itArcsOrientation.next();
598:                    if ((arc == this ) && !orientationEntrant.booleanValue()) {
599:                        resultat.add(arcPrecedent);
600:                        resultat.add(orientationPrecedent);
601:                        return resultat;
602:                    }
603:                }
604:                return null;
605:            }
606:
607:            /////////////////////////////////////////////////////////////////////////////////////////////////
608:            //                              Gestion d'un réseau orienté 
609:            /////////////////////////////////////////////////////////////////////////////////////////////////
610:            // NB: ne pas confondre orientation définie par l'attribut "orientation" (traité ici),
611:            //      et l'orientation définie implicitement par le sens de stockage de la géométrie    
612:
613:            private int orientation = 2;
614:
615:            /** Renvoie l'orientation. L'orientation vaut 2 dans les deux sens, -1 en sens indirect et 1 en sens direct */
616:            public int getOrientation() {
617:                return this .orientation;
618:            }
619:
620:            /** Définit l'orientation. L'orientation vaut 2 dans les deux sens, -1 en sens indirect et 1 en sens direct */
621:            public void setOrientation(int orientation) {
622:                this .orientation = orientation;
623:            }
624:
625:            /* Noeuds initiaux de l'arc, au sens de son orientation. 
626:             * Si l'arc est en double sens (orientation = 2), les deux noeuds extrémités sont renvoyés.
627:             * Sinon, un seul noeud est renvoyé.
628:             * NB: à ne pas confondre avec getNoeudIni, qui renvoie le noeud initial au sens du stockage
629:             */
630:            public List inisOrientes() {
631:                List noeuds = new ArrayList();
632:                if ((orientation == 2 || orientation == 1)
633:                        && !(noeudIni == null))
634:                    noeuds.add(noeudIni);
635:                if ((orientation == 2 || orientation == -1)
636:                        && !(noeudFin == null))
637:                    noeuds.add(noeudFin);
638:                return noeuds;
639:            }
640:
641:            /* Noeuds finaux de l'arc, au sens de son orientation. 
642:             * Si l'arc est en double sens (orientation = 2), les deux noeuds extrémités sont renvoyés.
643:             * Sinon, un seul noeud est renvoyé.
644:             * NB: à ne pas confondre avec getNoeudFin, qui renvoie le noeud final au sens du stockage
645:             */
646:            public List finsOrientes() {
647:                List noeuds = new ArrayList();
648:                if ((orientation == 2 || orientation == -1)
649:                        && !(noeudIni == null))
650:                    noeuds.add(noeudIni);
651:                if ((orientation == 2 || orientation == 1)
652:                        && !(noeudFin == null))
653:                    noeuds.add(noeudFin);
654:                return noeuds;
655:            }
656:
657:            //	///////////////////////////////////////////////////////////////////////////////////////////////
658:            //								  Gestion des poids pour les plus courts chemins
659:            //	///////////////////////////////////////////////////////////////////////////////////////////////
660:            private double poids = 0;
661:
662:            /** Renvoie le poids de l'arc, pour les calculs de plus court chemin */
663:            public double getPoids() {
664:                return this .poids;
665:            }
666:
667:            /** Définit le poids de l'arc, pour les calculs de plus court chemin */
668:            public void setPoids(double d) {
669:                this .poids = d;
670:            }
671:
672:            /////////////////////////////////////////////////////////////////////////////////////////////////
673:            //                              Gestion des groupes
674:            /////////////////////////////////////////////////////////////////////////////////////////////////
675:
676:            /* Groupes auquels self appartient */
677:            private Collection listeGroupes = new ArrayList();
678:
679:            /** Renvoie la liste des groupes de self*/
680:            public Collection getListeGroupes() {
681:                return this .listeGroupes;
682:            }
683:
684:            /** Définit la liste des groupes de self*/
685:            public void setListegroupes(Collection liste) {
686:                this .listeGroupes = liste;
687:            }
688:
689:            /** Ajoute un groupe à self*/
690:            public void addGroupe(Groupe groupe) {
691:                if (groupe != null && !listeGroupes.contains(groupe)) {
692:                    this .listeGroupes.add(groupe);
693:                    if (!groupe.getListeArcs().contains(this ))
694:                        groupe.addArc(this );
695:                }
696:            }
697:
698:            /////////////////////////////////////////////////////////////////////////////////////////////////
699:            //                      Pour la gestion des requetes spatiales 
700:            /////////////////////////////////////////////////////////////////////////////////////////////////
701:            private Rectangle rectangleEnglobant = null;
702:
703:            /** Rectangle englobant de l'arc, orienté le long des axes des x,y.
704:             * NB: le rectangle est calculé au premier appel de cette fonction.
705:             * Si l'arc est modifié, la valeur n'est pas mise à jour : il faut le faire explicitement au besoin avec calculeRectangleEnglobant.
706:             */
707:            public Rectangle getRectangleEnglobant() {
708:                if (this .rectangleEnglobant == null)
709:                    this .calculeRectangleEnglobant();
710:                return this .rectangleEnglobant;
711:            }
712:
713:            /** Calcule le rectangle englobant x,y en fonction de la géométrie */
714:            public void calculeRectangleEnglobant() {
715:                this .rectangleEnglobant = Rectangle.rectangleEnglobant(this 
716:                        .getGeometrie());
717:            }
718:
719:            protected boolean proche(Arc arc, double distance) {
720:                return arc.getRectangleEnglobant().intersecte(
721:                        this .getRectangleEnglobant().dilate(distance));
722:            }
723:
724:            /////////////////////////////////////////////////////////////////////////////////////////////////
725:            //                      Opérateurs de calculs sur les arcs 
726:            /////////////////////////////////////////////////////////////////////////////////////////////////
727:            /** Distance euclidienne entre le noeud et self */
728:            public double distance(Noeud noeud) {
729:                return (Distances.distance(noeud.getCoord(), this 
730:                        .getGeometrie()));
731:            }
732:
733:            /** Première composante de la distance de Hausdorff de self vers l'arc. 	 
734:             * Elle est calculee comme le maximum des distances d'un point intermediaire
735:             * de self à l'arc. Cette approximation peut différer sensiblement 
736:             * de la definition theorique. 
737:             * NB : défini en théorie à 3D, mais non vérifié en profondeur */
738:            public double premiereComposanteHausdorff(Arc arc) {
739:                return (Distances.premiereComposanteHausdorff(this 
740:                        .getGeometrie(), arc.getGeometrie()));
741:            }
742:
743:            /** Distance de Hausdorff entre self et l'arc. 
744:             * Elle est calculee comme le maximum des distances d'un point intermediaire
745:             * d'une des lignes a l'autre ligne. Dans certains cas cette definition
746:             * differe de la definition theorique car la distance de Hausdorff ne se
747:             * realise pas necessairement sur un point intermediaire. Mais cela est rare
748:             * sur des données réel. Cette implementation est un bon compromis entre
749:             * simplicité et précision.
750:             * NB : défini en théorie à 3D, mais non vérifié en profondeur */
751:            public double hausdorff(Arc arc) {
752:                return (Distances.hausdorff(this .getGeometrie(), arc
753:                        .getGeometrie()));
754:            }
755:
756:            /** Longueur euclidienne de l'arc. Est calculé en 3D si la géométrie est définie en 3D */
757:            public double longueur() {
758:                return this.getGeometrie().length();
759:            }
760:
761:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.