Source Code Cross Referenced for CarteTopo.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) 


0001:        /*
0002:         * This file is part of the GeOxygene project source files. 
0003:         * 
0004:         * GeOxygene aims at providing an open framework which implements OGC/ISO specifications for 
0005:         * the development and deployment of geographic (GIS) applications. It is a open source 
0006:         * contribution of the COGIT laboratory at the Institut Géographique National (the French 
0007:         * National Mapping Agency).
0008:         * 
0009:         * See: http://oxygene-project.sourceforge.net 
0010:         *  
0011:         * Copyright (C) 2005 Institut Géographique National
0012:         *
0013:         * This library is free software; you can redistribute it and/or modify it under the terms
0014:         * of the GNU Lesser General Public License as published by the Free Software Foundation; 
0015:         * either version 2.1 of the License, or any later version.
0016:         *
0017:         * This library is distributed in the hope that it will be useful, but WITHOUT ANY 
0018:         * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 
0019:         * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
0020:         *
0021:         * You should have received a copy of the GNU Lesser General Public License along with 
0022:         * this library (see file LICENSE if present); if not, write to the Free Software 
0023:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0024:         *  
0025:         */
0026:
0027:        package fr.ign.cogit.geoxygene.contrib.cartetopo;
0028:
0029:        import java.util.ArrayList;
0030:        import java.util.Iterator;
0031:        import java.util.List;
0032:
0033:        import fr.ign.cogit.geoxygene.contrib.geometrie.Distances;
0034:        import fr.ign.cogit.geoxygene.contrib.geometrie.Operateurs;
0035:        import fr.ign.cogit.geoxygene.feature.DataSet;
0036:        import fr.ign.cogit.geoxygene.feature.FT_Feature;
0037:        import fr.ign.cogit.geoxygene.feature.FT_FeatureCollection;
0038:        import fr.ign.cogit.geoxygene.feature.Population;
0039:        import fr.ign.cogit.geoxygene.spatial.coordgeom.DirectPosition;
0040:        import fr.ign.cogit.geoxygene.spatial.coordgeom.DirectPositionList;
0041:        import fr.ign.cogit.geoxygene.spatial.coordgeom.GM_Envelope;
0042:        import fr.ign.cogit.geoxygene.spatial.coordgeom.GM_LineString;
0043:        import fr.ign.cogit.geoxygene.spatial.coordgeom.GM_Polygon;
0044:        import fr.ign.cogit.geoxygene.spatial.geomaggr.GM_MultiCurve;
0045:        import fr.ign.cogit.geoxygene.spatial.geomaggr.GM_MultiPoint;
0046:        import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Point;
0047:        import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Ring;
0048:        import fr.ign.cogit.geoxygene.spatial.geomroot.GM_Object;
0049:        import fr.ign.cogit.geoxygene.util.index.Tiling;
0050:
0051:        /**
0052:         * Classe racine de la carte topo. 
0053:         * Une carte topo est une composition d'arcs, de noeuds, de faces et de groupes.
0054:         * Une carte topo est vue comme un DataSet particulier. 
0055:         * Elle a éventuellement une topologie (SPAGHETTI, NETWORK ou MAP).
0056:         * 
0057:         * English: a topological map is an oriented graph, with arcs sorted around the nodes;
0058:         * @author  Mustière/Bonin
0059:         * @version 1.0
0060:         */
0061:
0062:        public class CarteTopo extends DataSet {
0063:
0064:            //	Accès aux composants de la carte topo
0065:
0066:            /** Population des arcs de la carte topo. */
0067:            public Population getPopArcs() {
0068:                return this .getPopulation("Arc");
0069:            }
0070:
0071:            /** Population des noeuds de la carte topo. */
0072:            public Population getPopNoeuds() {
0073:                return this .getPopulation("Noeud");
0074:            }
0075:
0076:            /** Population des faces de la carte topo. */
0077:            public Population getPopFaces() {
0078:                return this .getPopulation("Face");
0079:            }
0080:
0081:            /** Population des groupes de la carte topo. */
0082:            public Population getPopGroupes() {
0083:                return this .getPopulation("Groupe");
0084:            }
0085:
0086:            /** Liste des noeuds de la carte topo. Surcharge de getPopNoeuds().getElements(). */
0087:            public List getListeNoeuds() {
0088:                return this .getPopNoeuds().getElements();
0089:            }
0090:
0091:            /** Liste des arcs de la carte topo. Surcharge de getPopArcs().getElements(). */
0092:            public List getListeArcs() {
0093:                return this .getPopArcs().getElements();
0094:            }
0095:
0096:            /** Liste des faces de la carte topo. Surcharge de getPopFaces().getElements(). */
0097:            public List getListeFaces() {
0098:                return this .getPopFaces().getElements();
0099:            }
0100:
0101:            /** Liste des groupes de la carte topo. Surcharge de getPopGroupes().getElements(). */
0102:            public List getListeGroupes() {
0103:                return this .getPopGroupes().getElements();
0104:            }
0105:
0106:            /** Ajoute un noeud à la population des noeuds de la carte topo. 
0107:            	Attention : même si la carte topo est persistante, le noeud n'est pas rendu persistant dans cette méthode */
0108:            public void addNoeud(Noeud noeud) {
0109:                this .getPopNoeuds().add(noeud);
0110:            }
0111:
0112:            /** Ajoute un arc à la population des arcs de la carte topo. 
0113:            	Attention : même si la carte topo est persistante, le noeud n'est pas rendu persistant dans cette méthode */
0114:            public void addArc(Arc arc) {
0115:                this .getPopArcs().add(arc);
0116:            }
0117:
0118:            /** Ajoute une face à la population des faces de la carte topo. 
0119:            	Attention : même si la carte topo est persistante, le noeud n'est pas rendu persistant dans cette méthode */
0120:            public void addFace(Face face) {
0121:                this .getPopFaces().add(face);
0122:            }
0123:
0124:            /** Ajoute un groupe à la population des groupes de la carte topo. 
0125:            	Attention : même si la carte topo est persistante, le noeud n'est pas rendu persistant dans cette méthode */
0126:            public void addGroupe(Groupe groupe) {
0127:                this .getPopGroupes().add(groupe);
0128:            }
0129:
0130:            /////////////////////////////////////////////////////////////////////////////////////////////
0131:            //	Constructeurs
0132:            /////////////////////////////////////////////////////////////////////////////////////////////
0133:            /** Constructeur par défaut;
0134:             *  ATTENTION, constructeur à éviter car aucune population n'est créée:
0135:             * seule un objet carteTopo est créé */
0136:            public CarteTopo() {
0137:            }
0138:
0139:            /** Constructeur d'une carte topo non persistante.
0140:             *  Le nom logique peut ête utilisé si la carte topo apparient à un DataSet, 
0141:             *  il peut être une chaîne vide sinon.
0142:             * 
0143:             *  Par ce constructeur, la carte topo contient des arcs/noeuds/faces/groupes  
0144:             *  des classes CarteTopo.Arc, CarteTopo.Noeud, CarteTopo.Face, CarteTopo.Groupe.
0145:             */
0146:            public CarteTopo(String nomLogique) {
0147:                this .ojbConcreteClass = this .getClass().getName(); // nécessaire pour ojb
0148:                this .setNom(nomLogique);
0149:                this .setPersistant(false);
0150:                Population arcs = new Population(false, "Arc",
0151:                        fr.ign.cogit.geoxygene.contrib.cartetopo.Arc.class,
0152:                        true);
0153:                this .addPopulation(arcs);
0154:                Population noeuds = new Population(false, "Noeud",
0155:                        fr.ign.cogit.geoxygene.contrib.cartetopo.Noeud.class,
0156:                        true);
0157:                this .addPopulation(noeuds);
0158:                Population faces = new Population(false, "Face",
0159:                        fr.ign.cogit.geoxygene.contrib.cartetopo.Face.class,
0160:                        true);
0161:                this .addPopulation(faces);
0162:                Population groupes = new Population(false, "Groupe",
0163:                        fr.ign.cogit.geoxygene.contrib.cartetopo.Groupe.class,
0164:                        false);
0165:                this .addPopulation(groupes);
0166:            }
0167:
0168:            /////////////////////////////////////////////////////////////////////////////////////////////
0169:            //	Attributs de la carte topo     
0170:            /////////////////////////////////////////////////////////////////////////////////////////////
0171:
0172:            // Description de la structure topologique
0173:            /** Spaghetti = pas de relation topologique entre arcs, noeuds et faces */
0174:            public static final int SPAGHETTI = 0;
0175:            /** Network = topologie arc / noeuds */
0176:            public static final int NETWORK = 1;
0177:            /** Network = topologie arc / noeuds / faces */
0178:            public static final int MAP = 2;
0179:            /** Niveau de topologie : 
0180:             * SPAGHETTI = pas de topologie ; NETWORK = topologie arcs/noeuds ; MAP (par défaut) = topologie arcs/noeuds/faces 
0181:             * NB : utiliser les constantes SPAGHETTI, NETWORK ou MAP pour remplir cet attribut.
0182:             * Remarque codeurs : Le code se sert très peu de l'attribut "type" pour l'instant. A revoir.
0183:             */
0184:            private int type = MAP;
0185:
0186:            public int getType() {
0187:                return type;
0188:            }
0189:
0190:            public void setType(int i) {
0191:                type = i;
0192:            }
0193:
0194:            /////////////////////////////////////////////////////////////////////////////////////////////
0195:            //	COPIE et VIDAGE de la carte topo     
0196:            /////////////////////////////////////////////////////////////////////////////////////////////
0197:            /** Copie d'une carte topologique avec toutes les relations topologiques.
0198:             * Les liens "correspondants" sont aussi dupliqués.
0199:             * 
0200:             * ATTENTION: ne fonctionne bien que pour une carteTopo non spécialisée 
0201:             * (i.e. avec carteTopo.Arc, carte.Noeud...).
0202:             * En effet, les objets copiés appartiendront au package cartetopo. 
0203:             */
0204:            public CarteTopo copie(String nomLogique) {
0205:                Noeud noeud, noeudCopie;
0206:                Arc arc, arcCopie;
0207:                Face face, faceCopie;
0208:                Groupe groupe, groupeCopie;
0209:                FT_Feature corresp;
0210:                Iterator itNoeuds, itArcs, itCorresp, itArcsCopies, itFaces, itGroupes, itGroupesCopies;
0211:                ArrayList noeuds, noeudsCopies, arcs, arcsCopies, faces, facesCopies;
0212:
0213:                // création d'une nouvelle carte        
0214:                CarteTopo carte = new CarteTopo(nomLogique);
0215:
0216:                // copie des objets, sans relation topologique        
0217:                itNoeuds = this .getPopNoeuds().getElements().iterator();
0218:                while (itNoeuds.hasNext()) {
0219:                    noeud = (Noeud) itNoeuds.next();
0220:                    noeudCopie = (Noeud) carte.getPopNoeuds().nouvelElement();
0221:                    noeudCopie.setGeometrie(noeud.getGeometrie());
0222:                    itCorresp = noeud.getCorrespondants().iterator();
0223:                    while (itCorresp.hasNext()) {
0224:                        corresp = (FT_Feature) itCorresp.next();
0225:                        noeudCopie.addCorrespondant(corresp);
0226:                    }
0227:                }
0228:                itArcs = this .getPopArcs().getElements().iterator();
0229:                while (itArcs.hasNext()) {
0230:                    arc = (Arc) itArcs.next();
0231:                    arcCopie = (Arc) carte.getPopArcs().nouvelElement();
0232:                    arcCopie.setGeometrie(arc.getGeometrie());
0233:                    itCorresp = arc.getCorrespondants().iterator();
0234:                    while (itCorresp.hasNext()) {
0235:                        corresp = (FT_Feature) itCorresp.next();
0236:                        arcCopie.addCorrespondant(corresp);
0237:                    }
0238:                }
0239:                itFaces = this .getPopFaces().getElements().iterator();
0240:                while (itFaces.hasNext()) {
0241:                    face = (Face) itFaces.next();
0242:                    faceCopie = (Face) carte.getPopFaces().nouvelElement();
0243:                    faceCopie.setGeometrie(face.getGeometrie());
0244:                    itCorresp = face.getCorrespondants().iterator();
0245:                    while (itCorresp.hasNext()) {
0246:                        corresp = (FT_Feature) itCorresp.next();
0247:                        faceCopie.addCorrespondant(corresp);
0248:                    }
0249:                }
0250:                itGroupes = this .getPopGroupes().getElements().iterator();
0251:                while (itGroupes.hasNext()) {
0252:                    groupe = (Groupe) itGroupes.next();
0253:                    groupeCopie = (Groupe) carte.getPopGroupes()
0254:                            .nouvelElement();
0255:                    itCorresp = groupe.getCorrespondants().iterator();
0256:                    while (itCorresp.hasNext()) {
0257:                        corresp = (FT_Feature) itCorresp.next();
0258:                        groupeCopie.addCorrespondant(corresp);
0259:                    }
0260:                }
0261:
0262:                if (type == SPAGHETTI)
0263:                    return carte;
0264:
0265:                // copie des relations topologiques        
0266:                noeuds = new ArrayList(this .getPopNoeuds().getElements());
0267:                noeudsCopies = new ArrayList(carte.getPopNoeuds().getElements());
0268:                arcs = new ArrayList(this .getPopArcs().getElements());
0269:                arcsCopies = new ArrayList(carte.getPopArcs().getElements());
0270:                faces = new ArrayList(this .getPopFaces().getElements());
0271:                facesCopies = new ArrayList(carte.getPopArcs().getElements());
0272:
0273:                itArcs = this .getPopArcs().getElements().iterator();
0274:                itArcsCopies = carte.getPopArcs().getElements().iterator();
0275:                while (itArcs.hasNext()) {
0276:                    arc = (Arc) itArcs.next();
0277:                    arcCopie = (Arc) itArcsCopies.next();
0278:                    arcCopie.setNoeudIni((Noeud) noeudsCopies.get(noeuds
0279:                            .indexOf(arc.getNoeudIni())));
0280:                    arcCopie.setNoeudFin((Noeud) noeudsCopies.get(noeuds
0281:                            .indexOf(arc.getNoeudFin())));
0282:                    if (arc.getFaceGauche() != null) {
0283:                        arcCopie.setFaceGauche((Face) facesCopies.get(faces
0284:                                .indexOf(arc.getFaceGauche())));
0285:                    }
0286:                    if (arc.getFaceDroite() != null) {
0287:                        arcCopie.setFaceDroite((Face) facesCopies.get(faces
0288:                                .indexOf(arc.getFaceDroite())));
0289:                    }
0290:                }
0291:
0292:                itGroupes = this .getPopGroupes().getElements().iterator();
0293:                itGroupesCopies = carte.getPopGroupes().getElements()
0294:                        .iterator();
0295:                while (itGroupes.hasNext()) {
0296:                    groupe = (Groupe) itGroupes.next();
0297:                    groupeCopie = (Groupe) itGroupesCopies.next();
0298:                    itNoeuds = groupeCopie.getListeNoeuds().iterator();
0299:                    while (itNoeuds.hasNext()) {
0300:                        noeud = (Noeud) itNoeuds.next();
0301:                        groupeCopie.addNoeud((Noeud) noeudsCopies.get(noeuds
0302:                                .indexOf(noeud)));
0303:                    }
0304:                    itArcs = groupeCopie.getListeArcs().iterator();
0305:                    while (itArcs.hasNext()) {
0306:                        arc = (Arc) itArcs.next();
0307:                        groupeCopie.addArc((Arc) arcsCopies.get(arcs
0308:                                .indexOf(arc)));
0309:                    }
0310:                    itFaces = groupeCopie.getListeFaces().iterator();
0311:                    while (itFaces.hasNext()) {
0312:                        face = (Face) itFaces.next();
0313:                        groupeCopie.addFace((Face) facesCopies.get(faces
0314:                                .indexOf(face)));
0315:                    }
0316:                }
0317:                return carte;
0318:            }
0319:
0320:            /** Enlève des arcs de la carteTopo, en enlevant aussi les relations topologiques
0321:             * les concernant (avec les faces et noeuds).
0322:             */
0323:            public void enleveArcs(List arcsAEnlever) {
0324:                Iterator itArcs = arcsAEnlever.iterator();
0325:                Arc arc;
0326:                while (itArcs.hasNext()) {
0327:                    arc = (Arc) itArcs.next();
0328:                    this .getPopArcs().remove(arc);
0329:                    arc.setNoeudFin(null);
0330:                    arc.setNoeudIni(null);
0331:                    arc.setFaceDroite(null);
0332:                    arc.setFaceGauche(null);
0333:                }
0334:            }
0335:
0336:            /** Enlève des noeuds de la carteTopo, en enlevant aussi les relations topologiques
0337:             * les concernant (avec les arcs et par conséquent avec les faces).
0338:             */
0339:            public void enleveNoeuds(List noeudsAEnlever) {
0340:                Iterator itNoeuds = noeudsAEnlever.iterator();
0341:                Iterator itArcs;
0342:                Noeud noeud;
0343:                Arc arc;
0344:                while (itNoeuds.hasNext()) {
0345:                    noeud = (Noeud) itNoeuds.next();
0346:                    this .getPopNoeuds().remove(noeud);
0347:                    itArcs = noeud.getEntrants().iterator();
0348:                    while (itArcs.hasNext()) {
0349:                        arc = (Arc) itArcs.next();
0350:                        arc.setNoeudFin(null);
0351:                    }
0352:                    itArcs = noeud.getSortants().iterator();
0353:                    while (itArcs.hasNext()) {
0354:                        arc = (Arc) itArcs.next();
0355:                        arc.setNoeudIni(null);
0356:                    }
0357:                }
0358:            }
0359:
0360:            /** Enlève des faces de la carteTopo, en enlevant aussi les relations topologiques
0361:             * les concernant (avec les arcs et par conséquent avec les noeuds).
0362:             */
0363:            public void enleveFaces(List facesAEnlever) {
0364:                Iterator itFaces = facesAEnlever.iterator();
0365:                Iterator itArcs;
0366:                Face face;
0367:                Arc arc;
0368:                while (itFaces.hasNext()) {
0369:                    face = (Face) itFaces.next();
0370:                    this .getPopFaces().remove(face);
0371:                    itArcs = face.getArcsDirects().iterator();
0372:                    while (itArcs.hasNext()) {
0373:                        arc = (Arc) itArcs.next();
0374:                        arc.setFaceGauche(null);
0375:                    }
0376:                    itArcs = face.getArcsIndirects().iterator();
0377:                    while (itArcs.hasNext()) {
0378:                        arc = (Arc) itArcs.next();
0379:                        arc.setFaceDroite(null);
0380:                    }
0381:                }
0382:            }
0383:
0384:            /////////////////////////////////////////////////////////////////////////////////////////////
0385:            //	Instanciation ou nettoyage de la topologie de réseau 
0386:            /////////////////////////////////////////////////////////////////////////////////////////////
0387:
0388:            /** Instancie la topologie de réseau d'une Carte Topo, 
0389:             *  en se basant sur la géométrie 2D des arcs et des noeuds.
0390:             *  Autrement dit: crée les relation "noeud initial" et "noeud final" d'un arc.
0391:             * 
0392:             *  ATTENTION: cette méthode ne rajoute pas de noeuds. Si un arc n'a pas de noeud
0393:             *  localisé à son extrémité, il n'aura pas de noeud initial (ou final).
0394:             *  DE PLUS si plusieurs noeuds sont trop proches (cf. param tolérance), 
0395:             *  alors un des noeuds est choisi au hasard pour la relation arc/noeud,
0396:             *  ce qui n'est pas correct.
0397:             *  IL EST DONC CONSEILLE DE FILTRER LES DOUBLONS AVANT SI NECESSAIRE.
0398:             * 
0399:             *  NB: si cela n'avait pas été fait avant, 
0400:             *  la population des noeuds est indexée dans cette méthode
0401:             *  (dallage, paramètre = 20).
0402:             * 
0403:             *  @param tolerance
0404:             *  Le paramètre "tolerance" spécifie la distance maximale acceptée entre
0405:             *  la position d'un noeud et la position d'une extrémité de ligne, 
0406:             *  pour considérer ce noeud comme extrémité (la tolérance peut être nulle).
0407:             * 
0408:             */
0409:            public void creeTopologieArcsNoeuds(double tolerance) {
0410:                Arc arc;
0411:                Iterator itArcs;
0412:                FT_FeatureCollection selection;
0413:
0414:                // initialisation de l'index au besoin		
0415:                if (!this .getPopNoeuds().hasSpatialIndex())
0416:                    this .getPopNoeuds()
0417:                            .initSpatialIndex(Tiling.class, true, 20);
0418:
0419:                itArcs = this .getPopArcs().getElements().iterator();
0420:                while (itArcs.hasNext()) {
0421:                    arc = (Arc) itArcs.next();
0422:                    selection = this .getPopNoeuds().select(
0423:                            arc.getGeometrie().startPoint(), tolerance);
0424:                    if (selection.getElements().size() != 0)
0425:                        arc.setNoeudIni((Noeud) selection.getElements().get(0));
0426:                    selection = this .getPopNoeuds().select(
0427:                            arc.getGeometrie().endPoint(), tolerance);
0428:                    if (selection.getElements().size() != 0)
0429:                        arc.setNoeudFin((Noeud) selection.getElements().get(0));
0430:                }
0431:
0432:            }
0433:
0434:            /**  Crée un nouveau noeud à l'extrémité de chaque arc si il n'y en a pas.
0435:             *   Les noeuds existants sont tous conservés.
0436:             * 
0437:             *  NB: la topologie arcs/noeuds est instanciée au passage.
0438:             * 
0439:             *  NB: si cela n'avait pas été fait avant, 
0440:             *  la population des noeuds est indexée dans cette méthode.
0441:             * 	Paramètres de l'index = le même que celui des arcs si il existe, 
0442:             *  sinon Dallage avec à peu près 50 noeuds par dalle.
0443:             * 
0444:             */
0445:            public void creeNoeudsManquants(double tolerance) {
0446:                Arc arc;
0447:                Noeud noeud;
0448:                Iterator itArcs;
0449:                FT_FeatureCollection selection;
0450:
0451:                // initialisation de l'index au besoin
0452:                // si on peut, on prend les mêmes paramètres que le dallage des arcs		
0453:                if (!this .getPopNoeuds().hasSpatialIndex()) {
0454:                    if (this .getPopArcs().hasSpatialIndex()) {
0455:                        this .getPopNoeuds().initSpatialIndex(
0456:                                this .getPopArcs().getSpatialIndex());
0457:                        this .getPopNoeuds().getSpatialIndex()
0458:                                .setAutomaticUpdate(true);
0459:                    } else {
0460:                        GM_Envelope enveloppe = this .getPopArcs().envelope();
0461:                        int nb = (int) Math.sqrt(this .getPopArcs().size() / 20);
0462:                        if (nb == 0)
0463:                            nb = 1;
0464:                        this .getPopNoeuds().initSpatialIndex(Tiling.class,
0465:                                true, enveloppe, nb);
0466:                    }
0467:                }
0468:
0469:                itArcs = this .getPopArcs().getElements().iterator();
0470:                ;
0471:                while (itArcs.hasNext()) {
0472:                    arc = (Arc) itArcs.next();
0473:                    //noeud initial
0474:                    selection = this .getPopNoeuds().select(
0475:                            arc.getGeometrie().startPoint(), tolerance);
0476:                    if (selection.getElements().size() == 0) {
0477:                        noeud = (Noeud) this .getPopNoeuds().nouvelElement(
0478:                                new GM_Point(arc.getGeometrie().startPoint()));
0479:                    } else
0480:                        noeud = (Noeud) selection.getElements().get(0);
0481:                    arc.setNoeudIni(noeud);
0482:
0483:                    //noeud final
0484:                    selection = this .getPopNoeuds().select(
0485:                            arc.getGeometrie().endPoint(), tolerance);
0486:                    if (selection.getElements().size() == 0) {
0487:                        noeud = (Noeud) this .getPopNoeuds().nouvelElement(
0488:                                new GM_Point(arc.getGeometrie().endPoint()));
0489:                    } else
0490:                        noeud = (Noeud) selection.getElements().get(0);
0491:                    arc.setNoeudFin(noeud);
0492:                }
0493:            }
0494:
0495:            /** Filtrage des noeuds isolés (c'est-à-dire connectés à aucun arc).
0496:             *  Ceux-ci sont enlevés de la Carte Topo  
0497:             *  IMPORTANT : La topologie de réseau doit avoir été instanciée,
0498:             *  sinon tous les noeuds sont enlevés.
0499:             */
0500:            public void filtreNoeudsIsoles() {
0501:                Iterator itNoeuds;
0502:                List aJeter = new ArrayList();
0503:                Noeud noeud;
0504:
0505:                itNoeuds = this .getPopNoeuds().getElements().iterator();
0506:                while (itNoeuds.hasNext()) {
0507:                    noeud = (Noeud) itNoeuds.next();
0508:                    if (noeud.arcs().size() == 0)
0509:                        aJeter.add(noeud);
0510:                }
0511:                itNoeuds = aJeter.iterator();
0512:                while (itNoeuds.hasNext()) {
0513:                    noeud = (Noeud) itNoeuds.next();
0514:                    this .getPopNoeuds().enleveElement(noeud);
0515:                }
0516:            }
0517:
0518:            /** Filtrage des noeuds doublons (plusieurs noeuds localisés au même endroit).
0519:             * 
0520:             * NB: si cela n'avait pas été fait avant, 
0521:             * la population des noeuds est indexée dans cette méthode 
0522:             * (dallage, paramètre = 20).
0523:             * 
0524:             * Cette méthode gère les conséquences sur la topologie, 
0525:             * si celle-ci a été instanciée auparavant. 
0526:             * Cette méthode gère aussi les conséquences sur les correspondants (un
0527:             * noeud gardé a pour correspondants tous les correspondants des doublons).
0528:             * 
0529:             * @param tolerance 
0530:             * Le paramètre tolérance spécifie la distance maximale pour considérer deux
0531:             * noeuds positionnés au même endroit.
0532:             */
0533:            public void filtreDoublons(double tolerance) {
0534:                Iterator itNoeuds, itDoublons, itCorresp, itArcs;
0535:                Noeud doublon, noeud;
0536:                Arc arc;
0537:                FT_Feature corresp;
0538:                List aJeter = new ArrayList();
0539:                FT_FeatureCollection selection;
0540:
0541:                // initialisation de l'index au besoin		
0542:                if (!this .getPopNoeuds().hasSpatialIndex()) {
0543:                    this .getPopNoeuds()
0544:                            .initSpatialIndex(Tiling.class, true, 20);
0545:                }
0546:                itNoeuds = this .getPopNoeuds().getElements().iterator();
0547:                while (itNoeuds.hasNext()) {
0548:                    noeud = (Noeud) itNoeuds.next();
0549:                    if (aJeter.contains(noeud))
0550:                        continue;
0551:                    selection = this .getPopNoeuds().select(noeud.getCoord(),
0552:                            tolerance);
0553:                    itDoublons = selection.getElements().iterator();
0554:                    while (itDoublons.hasNext()) {
0555:                        doublon = (Noeud) itDoublons.next();
0556:                        if (doublon == noeud)
0557:                            continue;
0558:                        // on a trouvé un doublon à jeter
0559:                        // on gère les conséquences sur la topologie et les correspondants
0560:                        aJeter.add(doublon);
0561:                        itCorresp = doublon.getCorrespondants().iterator();
0562:                        while (itCorresp.hasNext()) {
0563:                            corresp = (FT_Feature) itCorresp.next();
0564:                            noeud.addCorrespondant(corresp);
0565:                        }
0566:                        itArcs = doublon.getEntrants().iterator();
0567:                        while (itArcs.hasNext()) {
0568:                            arc = (Arc) itArcs.next();
0569:                            noeud.addEntrant(arc);
0570:                        }
0571:                        itArcs = doublon.getSortants().iterator();
0572:                        while (itArcs.hasNext()) {
0573:                            arc = (Arc) itArcs.next();
0574:                            noeud.addSortant(arc);
0575:                        }
0576:                    }
0577:                }
0578:                itNoeuds = aJeter.iterator();
0579:                while (itNoeuds.hasNext()) {
0580:                    noeud = (Noeud) itNoeuds.next();
0581:                    this .getPopNoeuds().enleveElement(noeud);
0582:                }
0583:            }
0584:
0585:            /** Filtrage des noeuds "simples", c'est-à-dire avec seulement deux arcs incidents,
0586:             * si ils ont des orientations compatibles.
0587:             * Ces noeuds sont enlevés et un seul arc est créé à la place des deux arcs incidents.
0588:             *  
0589:             * Cette méthode gère les conséquences sur la topologie arcs/noeuds/faces.
0590:             * Cette méthode gère aussi les conséquences sur les correspondants.
0591:             * (un nouvel arc a pour correspondants tous les correspondants des deux
0592:             * arcs incidents). 
0593:             * Cette méthode gère les conséquences sur l'orientation
0594:             * 
0595:             * IMPORTANT: la topologie arcs/noeuds doit avoir été instanciée avant 
0596:             * de lancer cette méthode
0597:             */
0598:            public void filtreNoeudsSimples() {
0599:                Iterator itNoeuds, itCorresp;
0600:                List geometries, arcsIncidents;
0601:                Noeud noeud, noeudIni1, noeudIni2, noeudFin1, noeudFin2;
0602:                Arc arcTotal, arc1, arc2;
0603:                Face faceDroite1, faceDroite2, faceGauche1, faceGauche2;
0604:                FT_Feature corresp;
0605:
0606:                itNoeuds = this .getPopNoeuds().getElements().iterator();
0607:                List noeudsElimines = new ArrayList();
0608:                while (itNoeuds.hasNext()) {
0609:                    noeud = (Noeud) itNoeuds.next();
0610:                    arcsIncidents = noeud.arcs();
0611:                    if (arcsIncidents.size() != 2)
0612:                        continue;
0613:                    if (arcsIncidents.get(0) == arcsIncidents.get(1))
0614:                        continue; // gestion des boucles
0615:                    if (noeud.entrantsOrientes().size() == 0)
0616:                        continue; // incompatibilité d'orientation
0617:                    if (noeud.sortantsOrientes().size() == 0)
0618:                        continue; // incompatibilité d'orientation
0619:                    if ((noeud.entrantsOrientes().size() + noeud
0620:                            .sortantsOrientes().size()) == 3)
0621:                        continue; // incompatibilité d'orientation
0622:
0623:                    arcTotal = (Arc) this .getPopArcs().nouvelElement();
0624:                    geometries = new ArrayList();
0625:                    arc1 = (Arc) arcsIncidents.get(0);
0626:                    arc2 = (Arc) arcsIncidents.get(1);
0627:                    geometries.add(arc1.getGeometrie());
0628:                    geometries.add(arc2.getGeometrie());
0629:
0630:                    //création de la nouvelle géométrie
0631:                    arcTotal.setGeometrie(Operateurs.compileArcs(geometries));
0632:
0633:                    //gestion des conséquences sur l'orientation et les correspondants
0634:                    arcTotal.setOrientation(arc1.getOrientation());
0635:                    itCorresp = arc1.getCorrespondants().iterator();
0636:                    while (itCorresp.hasNext()) {
0637:                        corresp = (FT_Feature) itCorresp.next();
0638:                        if (!arcTotal.getCorrespondants().contains(corresp))
0639:                            arcTotal.addCorrespondant(corresp);
0640:                    }
0641:                    arc1.setCorrespondants(new ArrayList());
0642:
0643:                    itCorresp = arc2.getCorrespondants().iterator();
0644:                    while (itCorresp.hasNext()) {
0645:                        corresp = (FT_Feature) itCorresp.next();
0646:                        arcTotal.addCorrespondant(corresp);
0647:                    }
0648:                    arc2.setCorrespondants(new ArrayList());
0649:
0650:                    itCorresp = noeud.getCorrespondants().iterator();
0651:                    while (itCorresp.hasNext()) {
0652:                        corresp = (FT_Feature) itCorresp.next();
0653:                        if (!arcTotal.getCorrespondants().contains(corresp))
0654:                            arcTotal.addCorrespondant(corresp);
0655:                    }
0656:                    noeud.setCorrespondants(new ArrayList());
0657:
0658:                    //gestion des conséquences sur la topologie
0659:                    faceDroite1 = arc1.getFaceDroite();
0660:                    faceGauche1 = arc1.getFaceGauche();
0661:                    faceDroite2 = arc2.getFaceDroite();
0662:                    faceGauche2 = arc2.getFaceGauche();
0663:                    noeudIni1 = arc1.getNoeudIni();
0664:                    noeudFin1 = arc1.getNoeudFin();
0665:                    noeudIni2 = arc2.getNoeudIni();
0666:                    noeudFin2 = arc2.getNoeudFin();
0667:
0668:                    // conséquences sur le premier arc 			
0669:                    if (noeudIni1 == noeud) {
0670:                        noeudIni1.getSortants().remove(arc1);
0671:                        if (noeudFin1 != null) {
0672:                            noeudFin1.getEntrants().remove(arc1);
0673:                            noeudFin1.addSortant(arcTotal);
0674:
0675:                        }
0676:                        if (faceDroite1 != null) {
0677:                            faceDroite1.getArcsIndirects().remove(arc1);
0678:                            arcTotal.setFaceGauche(faceDroite1);
0679:                        }
0680:                        if (faceGauche1 != null) {
0681:                            faceGauche1.getArcsDirects().remove(arc1);
0682:                            arcTotal.setFaceDroite(faceGauche1);
0683:                        }
0684:                    } else {
0685:                        noeudFin1.getEntrants().remove(arc1);
0686:                        if (noeudIni1 != null) {
0687:                            noeudIni1.getSortants().remove(arc1);
0688:                            noeudIni1.addSortant(arcTotal);
0689:                        }
0690:                        if (faceDroite1 != null) {
0691:                            faceDroite1.getArcsIndirects().remove(arc1);
0692:                            arcTotal.setFaceDroite(faceDroite1);
0693:                        }
0694:                        if (faceGauche1 != null) {
0695:                            faceGauche1.getArcsDirects().remove(arc1);
0696:                            arcTotal.setFaceGauche(faceGauche1);
0697:                        }
0698:                    }
0699:
0700:                    // conséquences sur le deuxième arc 			
0701:                    if (noeudIni2 == noeud) {
0702:                        noeudIni2.getSortants().remove(arc2);
0703:                        if (noeudFin2 != null) {
0704:                            noeudFin2.getEntrants().remove(arc2);
0705:                            noeudFin2.addEntrant(arcTotal);
0706:
0707:                        }
0708:                        if (faceDroite2 != null) {
0709:                            faceDroite2.getArcsIndirects().remove(arc2);
0710:                        }
0711:                        if (faceGauche2 != null) {
0712:                            faceGauche1.getArcsDirects().remove(arc2);
0713:                        }
0714:                    } else {
0715:                        noeudFin2.getEntrants().remove(arc2);
0716:                        if (noeudIni2 != null) {
0717:                            noeudIni2.getSortants().remove(arc2);
0718:                            noeudIni2.addEntrant(arcTotal);
0719:                        }
0720:                        if (faceDroite2 != null) {
0721:                            faceDroite2.getArcsIndirects().remove(arc2);
0722:                        }
0723:                        if (faceGauche2 != null) {
0724:                            faceGauche2.getArcsDirects().remove(arc2);
0725:                        }
0726:                    }
0727:
0728:                    //Elimination des arcs et du noeud inutile
0729:                    this .getPopArcs().enleveElement(arc1);
0730:                    this .getPopArcs().enleveElement(arc2);
0731:                    noeudsElimines.add(noeud);
0732:                }
0733:                int i;
0734:                for (i = 0; i < noeudsElimines.size(); i++) {
0735:                    this .getPopNoeuds().enleveElement(
0736:                            (Noeud) noeudsElimines.get(i));
0737:                }
0738:            }
0739:
0740:            /** Filtre les arcs en double 
0741:             * (en double = même géométrie et même orientation).
0742:             * 
0743:             * Attention: les conséquences sur la topologie arcs/faces ne sont pas gérées.
0744:             */
0745:            public void filtreArcsDoublons() {
0746:                List arcs = this .getPopArcs().getElements();
0747:                List arcsAEnlever = new ArrayList();
0748:                for (int i = 0; i < arcs.size(); i++) {
0749:                    Arc arci = (Arc) arcs.get(i);
0750:                    if (arcsAEnlever.contains(arci))
0751:                        continue;
0752:                    for (int j = i + 1; j < arcs.size(); j++) {
0753:                        Arc arcj = (Arc) arcs.get(j);
0754:                        if (!arcj.getGeom().equals(arci.getGeom()))
0755:                            continue;
0756:                        if (arcj.getOrientation() != arcj.getOrientation())
0757:                            continue;
0758:                        arcsAEnlever.add(arcj);
0759:                        Iterator itCor = arcj.getCorrespondants().iterator();
0760:                        while (itCor.hasNext()) {
0761:                            FT_Feature corresp = (FT_Feature) itCor.next();
0762:                            arci.addCorrespondant(corresp);
0763:                        }
0764:                        arcj.setCorrespondants(new ArrayList());
0765:                        arcj.setNoeudFin(null);
0766:                        arcj.setNoeudIni(null);
0767:                    }
0768:                }
0769:                this .getPopArcs().removeAll(arcsAEnlever);
0770:            }
0771:
0772:            /** Transforme la carte topo pour la rendre planaire :
0773:             *  les arcs sont découpés à chaque intersection d'arcs, 
0774:             *  et un noeud est créé à chaque extrémité d'arc.
0775:             * 
0776:             *  NB: la topologie arcs/noeuds de la carte en sortie est instanciée.
0777:             * 
0778:             *  NB: les populations d'arcs et de noeuds sont indexées pendant la méthode,
0779:             *  si cela n'avait pas déjà été fait avant.
0780:             *  Les paramètres de ces index sont: 
0781:             *  20x20 cases pour les noeuds, ~50 arcs par case pour les arcs.
0782:             *  Si cela ne convient pas: instancier les topologies avant. 
0783:             * 
0784:             *  NB: les "correspondants" des arcs et noeuds suivent le découpage, 
0785:             *  de même que l'attribut orientation.
0786:             *  MAIS ATTENTION: 
0787:             *  - les liens vers des groupes ne suivent pas. 
0788:             *  - les attributs/liens particuliers (cas où les arcs proviennent 
0789:             *    d'une carteTopo spécialisée) ne suivent pas non plus
0790:             *  - la topologie des faces est détruite aussi 
0791:             * 
0792:             * @param tolerance
0793:             * Paramètre de tolérance sur la localisation des noeuds:
0794:             * deux extrémités d'arc à moins de cette distance sont considérées superposées
0795:             * (utilisé lors de la construction de la topologie arcs/noeuds).
0796:             * Ce paramètre peut être nul.
0797:             */
0798:            public void rendPlanaire(double tolerance) {
0799:                Arc arc, arcSel;
0800:                FT_FeatureCollection selection;
0801:                List listeInter;
0802:                GM_Object nodedLineStrings, intersection;
0803:                Iterator itSel, itDecoupes;
0804:                List dejaTraites = new ArrayList();
0805:                List arcsEnleves = new ArrayList();
0806:                GM_MultiPoint frontiereArc, frontiereArcSel;
0807:                GM_Point ptArcIni, ptArcFin, ptArcSelIni, ptArcSelFin;
0808:
0809:                if (this .getPopArcs().size() == 0)
0810:                    return;
0811:                // initialisation de l'index des arcs au besoin		
0812:                if (!this .getPopArcs().hasSpatialIndex())
0813:                    this .getPopArcs().initSpatialIndex(Tiling.class, true);
0814:
0815:                for (int i = 0; i < this .getPopArcs().size(); i++) {
0816:                    arc = (Arc) this .getPopArcs().get(i);
0817:                    if (arcsEnleves.contains(arc))
0818:                        continue;
0819:                    if (dejaTraites.contains(arc))
0820:                        continue;
0821:
0822:                    //les arcs qui croisent l'arc courant
0823:                    // Optimisation et blindage pour tous les cas non garanti (Seb)
0824:                    selection = this .getPopArcs().select(arc.getGeometrie());
0825:                    selection.remove(arc);
0826:                    selection.getElements().removeAll(arcsEnleves);
0827:
0828:                    listeInter = new ArrayList();
0829:                    itSel = selection.getElements().iterator();
0830:                    ptArcIni = new GM_Point(arc.getGeometrie().startPoint());
0831:                    ptArcFin = new GM_Point(arc.getGeometrie().endPoint());
0832:                    frontiereArc = new GM_MultiPoint();
0833:                    frontiereArc.add(ptArcIni);
0834:                    frontiereArc.add(ptArcFin);
0835:                    while (itSel.hasNext()) {
0836:                        arcSel = (Arc) itSel.next();
0837:
0838:                        //				if (arcSel == arc) continue;
0839:
0840:                        ptArcSelIni = new GM_Point(arcSel.getGeometrie()
0841:                                .startPoint());
0842:                        ptArcSelFin = new GM_Point(arcSel.getGeometrie()
0843:                                .endPoint());
0844:
0845:                        intersection = arcSel.getGeometrie().intersection(
0846:                                arc.getGeometrie());
0847:
0848:                        /* //modif Seb: tentative d'accélération : buggé mais je ne trouve pas pourquoi
0849:                        if (intersection instanceof GM_Point ) {
0850:                        	if ( Operateurs.superposes(ptArcIni, (GM_Point)intersection) || 
0851:                        		 Operateurs.superposes(ptArcFin, (GM_Point)intersection) ) { 		     
0852:                        		if ( Operateurs.superposes(ptArcSelIni, (GM_Point)intersection) || 
0853:                        			 Operateurs.superposes(ptArcSelFin, (GM_Point)intersection) )  		     
0854:                        			continue;
0855:                        	}
0856:                        	listeInter.add(arcSel);
0857:                        	continue;
0858:                        }
0859:                         */
0860:                        frontiereArcSel = new GM_MultiPoint();
0861:                        frontiereArcSel.add(ptArcSelIni);
0862:                        frontiereArcSel.add(ptArcSelFin);
0863:                        if (frontiereArc.contains(intersection)) {
0864:                            if (frontiereArcSel.contains(intersection))
0865:                                continue;
0866:                        }
0867:                        listeInter.add(arcSel);
0868:                    }
0869:
0870:                    if (listeInter.size() == 0)
0871:                        continue; //pas d'intersection avec cet arc
0872:
0873:                    //on découpe tout
0874:                    itSel = listeInter.iterator();
0875:                    nodedLineStrings = arc.getGeometrie();
0876:                    while (itSel.hasNext()) {
0877:                        arcSel = (Arc) itSel.next();
0878:                        nodedLineStrings = nodedLineStrings.union(arcSel
0879:                                .getGeometrie());
0880:                    }
0881:                    listeInter.add(arc); // on le rajoute pour la suite
0882:                    if (nodedLineStrings instanceof  GM_LineString) {
0883:                        System.out
0884:                                .println("Problème pour rendre le graphe planaire");
0885:                        System.out
0886:                                .println("  l'intersection de plusieurs arcs donne un seul arc (pb non résolu, pb JTS?)");
0887:                        System.out.println("  pb sur l'arc "
0888:                                + arc.getGeom().coord());
0889:                        continue;
0890:                    }
0891:                    if (nodedLineStrings instanceof  GM_MultiCurve) { //cas où il faut découper
0892:                        //1: on rajoute les morceaux d'arcs découpés
0893:                        itDecoupes = ((GM_MultiCurve) nodedLineStrings)
0894:                                .getList().iterator();
0895:                        while (itDecoupes.hasNext()) {
0896:                            GM_LineString ligneDecoupe = (GM_LineString) itDecoupes
0897:                                    .next();
0898:                            Arc arcNouveau = (Arc) this .getPopArcs()
0899:                                    .nouvelElement(ligneDecoupe);
0900:                            //on recherche à quel(s) arc(s) initial appartient chaque bout découpé
0901:                            itSel = listeInter.iterator();
0902:                            while (itSel.hasNext()) {
0903:                                arcSel = (Arc) itSel.next();
0904:                                // on devrait mettre ==0 ci-dessous, mais pour gérer les erreurs d'arrondi on met <0.01
0905:                                if (Distances.premiereComposanteHausdorff(
0906:                                        ligneDecoupe, arcSel.getGeometrie()) < 0.01) {
0907:                                    //on appartient à lui
0908:                                    arcNouveau.getCorrespondants().addAll(
0909:                                            arcSel.getCorrespondants());
0910:                                    arcNouveau.setOrientation(arcSel
0911:                                            .getOrientation());
0912:                                    //si on appartient à l'arc initial, pas la peine de revenir
0913:                                    if (arcSel == arc)
0914:                                        dejaTraites.add(arcNouveau);
0915:                                }
0916:                            }
0917:                        }
0918:
0919:                        //2: on virera les arcs initiaux qui ont été découpés
0920:                        itSel = listeInter.iterator();
0921:                        while (itSel.hasNext()) {
0922:                            arcSel = (Arc) itSel.next();
0923:                            arcsEnleves.add(arcSel);
0924:                            arcSel.setCorrespondants(new ArrayList());
0925:                        }
0926:                        continue;
0927:                    }
0928:
0929:                    //cas imprévu: OUPS
0930:                    System.out
0931:                            .println("Problème pour rendre le graphe planaire");
0932:                    System.out
0933:                            .println("  bug non identifié : l'union donne une "
0934:                                    + nodedLineStrings.getClass());
0935:                    System.out.println("  pb sur l'arc "
0936:                            + arc.getGeom().coord());
0937:                }
0938:
0939:                this .enleveArcs(arcsEnleves);
0940:                //On construit les nouveaux noeuds éventuels et la topologie arcs/noeuds
0941:                this .getPopNoeuds().setElements(new ArrayList());
0942:                this .creeNoeudsManquants(tolerance);
0943:            }
0944:
0945:            /** Fusionne en un seul noeud, tous les noeuds proches de moins de "tolerance"
0946:             * Les correspondants suivent, la topologie arcs/noeuds aussi.
0947:             * NB: les petits arcs qui n'ont plus de sens sont aussi éliminés.
0948:             * Plus précisément ce sont ceux qui partent et arrivent sur un même
0949:             * nouveau noeud créé, et restant à moins de "tolerance" de ce nouveau noeud
0950:             * 
0951:             * Un index spatial (dallage) est créé si cela n'avait pas été fait avant, 
0952:             * mais il est toujours conseillé de le faire en dehors de cette méthode,
0953:             * pour controler la taille du dallage.
0954:             */
0955:            public void fusionNoeuds(double tolerance) {
0956:                Iterator itNoeudsProches, itArcs;
0957:                Noeud noeud, nouveauNoeud, noeudProche;
0958:                Arc arc;
0959:                List aEnlever = new ArrayList();
0960:                FT_FeatureCollection noeudsProches;
0961:                List arcsModifies;
0962:
0963:                if (!this .getPopArcs().hasSpatialIndex())
0964:                    this .getPopArcs().initSpatialIndex(Tiling.class, true);
0965:
0966:                for (int i = 0; i < this .getPopNoeuds().size(); i++) {
0967:                    noeud = (Noeud) this .getPopNoeuds().getElements().get(i);
0968:                    //On cherche les noeuds voisins
0969:                    noeudsProches = this .getPopNoeuds().select(
0970:                            noeud.getGeometrie(), tolerance);
0971:                    noeudsProches.removeAll(aEnlever);
0972:                    if (noeudsProches.size() < 2)
0973:                        continue;
0974:
0975:                    //Si il y a des voisins, on crée un nouveau noeud
0976:                    GM_MultiPoint points = new GM_MultiPoint();
0977:                    itNoeudsProches = noeudsProches.getElements().iterator();
0978:                    while (itNoeudsProches.hasNext()) {
0979:                        noeudProche = (Noeud) itNoeudsProches.next();
0980:                        points.add(noeudProche.getGeometrie());
0981:                    }
0982:                    GM_Point centroide = (GM_Point) points.centroid();
0983:                    nouveauNoeud = (Noeud) this .getPopNoeuds().nouvelElement();
0984:                    nouveauNoeud.setGeometrie(centroide);
0985:
0986:                    //On raccroche tous les arcs à ce nouveau noeud
0987:                    arcsModifies = new ArrayList();
0988:                    itNoeudsProches = noeudsProches.getElements().iterator();
0989:                    while (itNoeudsProches.hasNext()) {
0990:                        noeudProche = (Noeud) itNoeudsProches.next();
0991:                        nouveauNoeud.getCorrespondants().addAll(
0992:                                noeudProche.getCorrespondants());
0993:                        noeudProche.setCorrespondants(new ArrayList());
0994:                        aEnlever.add(noeudProche);
0995:                        //modification de chaque arc du noeud proche à bouger
0996:                        itArcs = noeudProche.arcs().iterator();
0997:                        while (itArcs.hasNext()) {
0998:                            arc = (Arc) itArcs.next();
0999:                            arcsModifies.add(arc);
1000:                            if (arc.getNoeudIni() == noeudProche) {
1001:                                arc.setNoeudIni(nouveauNoeud);
1002:                                arc.getGeometrie().coord().set(
1003:                                        0,
1004:                                        nouveauNoeud.getGeometrie()
1005:                                                .getPosition());
1006:                            }
1007:                            if (arc.getNoeudFin() == noeudProche) {
1008:                                arc.setNoeudFin(nouveauNoeud);
1009:                                int fin = arc.getGeometrie().coord().size() - 1;
1010:                                arc.getGeometrie().coord().set(
1011:                                        fin,
1012:                                        nouveauNoeud.getGeometrie()
1013:                                                .getPosition());
1014:                            }
1015:                        }
1016:                        //On enlève les arcs qui n'ont plus lieu d'être
1017:                        // (tout petit autour du nouveau noeud)
1018:                        itArcs = arcsModifies.iterator();
1019:                        while (itArcs.hasNext()) {
1020:                            arc = (Arc) itArcs.next();
1021:                            if (arc.getNoeudIni() == nouveauNoeud
1022:                                    && arc.getNoeudFin() == nouveauNoeud) {
1023:                                if (Distances.hausdorff(arc.getGeometrie(),
1024:                                        noeudProche.getGeometrie()) <= tolerance) {
1025:                                    nouveauNoeud.getCorrespondants().addAll(
1026:                                            arc.getCorrespondants());
1027:                                    arc.setNoeudIni(null);
1028:                                    arc.setNoeudFin(null);
1029:                                    this .getPopArcs().remove(arc);
1030:                                }
1031:                            }
1032:                        }
1033:                    }
1034:                }
1035:                //on enleve tous les anciens noeuds
1036:                Iterator itAEnlever = aEnlever.iterator();
1037:                while (itAEnlever.hasNext()) {
1038:                    noeud = (Noeud) itAEnlever.next();
1039:                    this .getPopNoeuds().remove(noeud);
1040:                }
1041:            }
1042:
1043:            /** Fusionne en un seul noeud, tous les noeuds contenu dans une même
1044:             * surface de la population de surfaces passée en paramètre.
1045:             * 
1046:             * Les correspondants suivent, la topologie arcs/noeuds aussi.
1047:             * 
1048:             * NB: les petits arcs qui n'ont plus de sens sont aussi éliminés.
1049:             * Plus précisément ce sont ceux qui partent et arrivent sur un même
1050:             * nouveau noeud créé, et restant dans la surface de fusion.
1051:             * 
1052:             * Un index spatial (dallage) est créé si cela n'avait pas été fait avant, 
1053:             * mais il est toujours conseillé de le faire en dehors de cette méthode,
1054:             * pour controler la taille du dallage.
1055:             */
1056:            public void fusionNoeuds(Population popSurfaces) {
1057:                Iterator itNoeudsProches, itArcs;
1058:                Noeud noeud, nouveauNoeud, noeudProche;
1059:                Arc arc;
1060:                List aEnlever = new ArrayList();
1061:                FT_FeatureCollection noeudsProches;
1062:                List arcsModifies;
1063:                Iterator itSurf = popSurfaces.getElements().iterator();
1064:
1065:                if (!this .getPopNoeuds().hasSpatialIndex())
1066:                    this .getPopNoeuds().initSpatialIndex(Tiling.class, true);
1067:
1068:                while (itSurf.hasNext()) {
1069:                    FT_Feature surf = (FT_Feature) itSurf.next();
1070:                    noeudsProches = this .getPopNoeuds().select(surf.getGeom());
1071:                    noeudsProches.removeAll(aEnlever);
1072:                    if (noeudsProches.size() < 2)
1073:                        continue;
1074:
1075:                    //Si il y a plusieurs noeuds dans la surface, on crée un nouveau noeud
1076:                    GM_MultiPoint points = new GM_MultiPoint();
1077:                    itNoeudsProches = noeudsProches.getElements().iterator();
1078:                    while (itNoeudsProches.hasNext()) {
1079:                        noeudProche = (Noeud) itNoeudsProches.next();
1080:                        points.add(noeudProche.getGeometrie());
1081:                    }
1082:                    GM_Point centroide = (GM_Point) points.centroid();
1083:                    nouveauNoeud = (Noeud) this .getPopNoeuds().nouvelElement();
1084:                    nouveauNoeud.setGeometrie(centroide);
1085:
1086:                    //On raccroche tous les arcs à ce nouveau noeud
1087:                    arcsModifies = new ArrayList();
1088:                    itNoeudsProches = noeudsProches.getElements().iterator();
1089:                    while (itNoeudsProches.hasNext()) {
1090:                        noeudProche = (Noeud) itNoeudsProches.next();
1091:                        nouveauNoeud.getCorrespondants().addAll(
1092:                                noeudProche.getCorrespondants());
1093:                        noeudProche.setCorrespondants(new ArrayList());
1094:                        aEnlever.add(noeudProche);
1095:                        //modification de chaque arc du noeud proche à bouger
1096:                        itArcs = noeudProche.arcs().iterator();
1097:                        while (itArcs.hasNext()) {
1098:                            arc = (Arc) itArcs.next();
1099:                            arcsModifies.add(arc);
1100:                            if (arc.getNoeudIni() == noeudProche) {
1101:                                arc.setNoeudIni(nouveauNoeud);
1102:                                arc.getGeometrie().coord().set(
1103:                                        0,
1104:                                        nouveauNoeud.getGeometrie()
1105:                                                .getPosition());
1106:                            }
1107:                            if (arc.getNoeudFin() == noeudProche) {
1108:                                arc.setNoeudFin(nouveauNoeud);
1109:                                int fin = arc.getGeometrie().coord().size() - 1;
1110:                                arc.getGeometrie().coord().set(
1111:                                        fin,
1112:                                        nouveauNoeud.getGeometrie()
1113:                                                .getPosition());
1114:                            }
1115:                        }
1116:                        //On enlève les arcs qui n'ont plus lieu d'être
1117:                        // (tout petit autour du nouveau noeud)
1118:                        itArcs = arcsModifies.iterator();
1119:                        while (itArcs.hasNext()) {
1120:                            arc = (Arc) itArcs.next();
1121:                            if (arc.getNoeudIni() == nouveauNoeud
1122:                                    && arc.getNoeudFin() == nouveauNoeud) {
1123:                                if (surf.getGeom().contains(arc.getGeometrie())) {
1124:                                    nouveauNoeud.getCorrespondants().addAll(
1125:                                            arc.getCorrespondants());
1126:                                    arc.setNoeudIni(null);
1127:                                    arc.setNoeudFin(null);
1128:                                    this .getPopArcs().remove(arc);
1129:                                }
1130:                            }
1131:                        }
1132:                    }
1133:                }
1134:                //on enleve tous les anciens noeuds
1135:                Iterator itAEnlever = aEnlever.iterator();
1136:                while (itAEnlever.hasNext()) {
1137:                    noeud = (Noeud) itAEnlever.next();
1138:                    this .getPopNoeuds().remove(noeud);
1139:                }
1140:            }
1141:
1142:            /** Découpe la carte topo this en fonction des noeuds d'une autre carte topo (ct).
1143:             * En détail: 
1144:             * Pour chaque noeud N de la carte topo en entrée, 
1145:             * on prend chaque arc de this qui en est proche (c'est-à-dire à moins de distanceMaxNoeudArc). 
1146:             * Si aucune des extrémités de cet arc est à moins de distanceMaxProjectionNoeud du noeud N,
1147:             * alors on découpe l'arc en y projetant le noeud N.
1148:             * 
1149:             * Si impassesSeulement = true: seules les noeuds N extrémités d'impasse peuvent être projetées
1150:             * 
1151:             * La topologie arcs/noeuds, l'orientation et les correspondants suivent.  
1152:             * 
1153:             * Les arcs de this sont indexés au passage si cela n'avait pas été fait avant.
1154:             *
1155:             */
1156:            public void projete(CarteTopo ct, double distanceMaxNoeudArc,
1157:                    double distanceMaxProjectionNoeud, boolean impassesSeulement) {
1158:                Arc arc;
1159:                Noeud noeud;
1160:                Iterator itNoeuds = ct.getPopNoeuds().getElements().iterator();
1161:                Iterator itArcs;
1162:
1163:                if (!this .getPopArcs().hasSpatialIndex()) {
1164:                    int nb = (int) Math.sqrt(this .getPopArcs().size() / 20);
1165:                    if (nb == 0)
1166:                        nb = 1;
1167:                    this .getPopArcs().initSpatialIndex(Tiling.class, true, nb);
1168:                }
1169:
1170:                while (itNoeuds.hasNext()) {
1171:                    noeud = (Noeud) itNoeuds.next();
1172:                    if (impassesSeulement) {
1173:                        if (noeud.arcs().size() != 1)
1174:                            continue;
1175:                    }
1176:                    itArcs = this .getPopArcs().select(noeud.getGeom(),
1177:                            distanceMaxNoeudArc).getElements().iterator();
1178:                    while (itArcs.hasNext()) {
1179:                        arc = (Arc) itArcs.next();
1180:                        if (Distances.distance(arc.getGeometrie().startPoint(),
1181:                                noeud.getGeometrie().getPosition()) < distanceMaxProjectionNoeud)
1182:                            continue;
1183:                        if (Distances.distance(arc.getGeometrie().endPoint(),
1184:                                noeud.getGeometrie().getPosition()) < distanceMaxProjectionNoeud)
1185:                            continue;
1186:                        arc.projeteEtDecoupe(noeud.getGeometrie());
1187:                    }
1188:                }
1189:            }
1190:
1191:            /** Découpe la carte topo this en fonction de tous les points (noeuds et points intermediaires)
1192:             * d'une autre carte topo (ct).
1193:             * En détail: 
1194:             * Pour chaque point P de la carte topo en entrée, 
1195:             * on prend chaque arc de this qui en est proche (c'est-à-dire à moins de distanceMaxNoeudArc). 
1196:             * Si aucune des extrémités de cet arc est à moins de distanceMaxProjectionNoeud du noeud P,
1197:             * alors on découpe l'arc en y projetant le noeud P.
1198:             * 
1199:             * La topologie arcs/noeuds, l'orientation et les correspondants suivent.  
1200:             * 
1201:             * Les arcs de this sont indexés au passage si cela n'avait pas été fait avant.
1202:             *
1203:             */
1204:            public void projeteTousLesPoints(CarteTopo ct,
1205:                    double distanceMaxNoeudArc,
1206:                    double distanceMaxProjectionNoeud) {
1207:                Arc arc, arcCT;
1208:                Iterator itArcsCT = ct.getPopArcs().getElements().iterator();
1209:                Iterator itArcs, itPointsCT;
1210:
1211:                if (!this .getPopArcs().hasSpatialIndex()) {
1212:                    int nb = (int) Math.sqrt(this .getPopArcs().size() / 20);
1213:                    if (nb == 0)
1214:                        nb = 1;
1215:                    this .getPopArcs().initSpatialIndex(Tiling.class, true, nb);
1216:                }
1217:
1218:                while (itArcsCT.hasNext()) {
1219:                    arcCT = (Arc) itArcsCT.next();
1220:                    itPointsCT = arcCT.getGeometrie().coord().getList()
1221:                            .iterator();
1222:                    while (itPointsCT.hasNext()) {
1223:                        DirectPosition dp = (DirectPosition) itPointsCT.next();
1224:                        if (Distances.distance(arcCT.getGeometrie()
1225:                                .startPoint(), dp) < distanceMaxProjectionNoeud)
1226:                            continue;
1227:                        if (Distances.distance(arcCT.getGeometrie().endPoint(),
1228:                                dp) < distanceMaxProjectionNoeud)
1229:                            continue;
1230:                        itArcs = this .getPopArcs().select(dp,
1231:                                distanceMaxNoeudArc).getElements().iterator();
1232:                        while (itArcs.hasNext()) {
1233:                            arc = (Arc) itArcs.next();
1234:                            if (Distances.distance(arc.getGeometrie()
1235:                                    .startPoint(), dp) < distanceMaxProjectionNoeud)
1236:                                continue;
1237:                            if (Distances.distance(arc.getGeometrie()
1238:                                    .endPoint(), dp) < distanceMaxProjectionNoeud)
1239:                                continue;
1240:                            arc.projeteEtDecoupe(new GM_Point(dp));
1241:                        }
1242:                    }
1243:                }
1244:            }
1245:
1246:            /** Découpe la carte topo this en fonction d'un ensemble de points (GM_Point).
1247:             * En détail: 
1248:             * Pour chaque point en entrée, 
1249:             * on prend chaque arc de this qui en est proche (c'est-à-dire à moins de distanceMaxNoeudArc). 
1250:             * Si aucune des extrémités de cet arc est à moins de distanceMaxProjectionNoeud du noeud N,
1251:             * alors on découpe l'arc en y projetant le noeud N.
1252:             * 
1253:             * La topologie arcs/noeuds, l'orientation et les correspondants suivent.  
1254:             *
1255:             */
1256:            public void projete(List pts, double distanceMaxNoeudArc,
1257:                    double distanceMaxProjectionNoeud) {
1258:                Arc arc;
1259:                Iterator itPts = pts.iterator();
1260:                Iterator itArcs;
1261:                while (itPts.hasNext()) {
1262:                    GM_Point point = (GM_Point) itPts.next();
1263:                    itArcs = this .getPopArcs().select(point,
1264:                            distanceMaxNoeudArc).getElements().iterator();
1265:                    while (itArcs.hasNext()) {
1266:                        arc = (Arc) itArcs.next();
1267:                        if (Distances.distance(arc.getGeometrie().startPoint(),
1268:                                point.getPosition()) < distanceMaxProjectionNoeud)
1269:                            continue;
1270:                        if (Distances.distance(arc.getGeometrie().endPoint(),
1271:                                point.getPosition()) < distanceMaxProjectionNoeud)
1272:                            continue;
1273:                        arc.projeteEtDecoupe(point);
1274:                    }
1275:                }
1276:            }
1277:
1278:            /////////////////////////////////////////////////////////////////////////////////////////////
1279:            //	Instanciation de la topologie de faces
1280:            /////////////////////////////////////////////////////////////////////////////////////////////
1281:            /** Crée les faces à partir d'un graphe planaire et instancie la topologie face / arcs. 
1282:             *  Une face est délimitée par un cycle minimal du graphe.
1283:             *
1284:             *  Le paramètre persistant spécifie si les faces créées, ainsi que la topologie, sont rendus persistants. 
1285:             *  Si oui, il faut appeler cette méthode dans une transaction ouverte.
1286:             *
1287:             *  NB1 : la topologie de réseau arcs/noeuds doit avoir été instanciée.
1288:             *  NB2 : une face "extérieure" est créée (sa géométrie entoure le "trou" de l'extérieur qu'est le réseau.
1289:             *        Donc, dans le cas d'une topologie complete arcs/faces, tous les arcs ont une face gauche 
1290:             *        et une face à droite.
1291:             *  NB3 : ATTENTION : en cas d'un réseau non connexe, une face extérieure différente est crée pour chaque 
1292:             *        partie connexe ! 
1293:             *  NB4 : Les culs de sac ont la même face à gauche et à droite, et la face "longe le cul de sac";
1294:             *        i.e. la géométrie de la face fait un aller/retour sur le cul-de-sac.
1295:             *  NB5 : Méthode en théorie conçue pour les graphes planaires uniquement (testée dans ce cadre uniquement).
1296:             *       La méthode est en théorie valable pour les graphes non planaires, mais les faces créées
1297:             *       seront étranges (on ne recrée pas les intersections manquantes, on les ignore).
1298:             *       Si il existe des arcs sans noeud initial ou final (topologie de réseau pas complete), 
1299:             *       alors ces arcs n'ont ni face à gauche, ni face à droite
1300:             */
1301:            public void creeTopologieFaces() {
1302:                List arcsDejaTraitesADroite = new ArrayList();
1303:                List arcsDejaTraitesAGauche = new ArrayList();
1304:                List cycle;
1305:                List arcsDuCycle;
1306:                List orientationsArcsDuCycle;
1307:                Iterator itArcs, itArcsCycle, itOrientations;
1308:                Arc arc, arcCycle;
1309:                Face face;
1310:                GM_Polygon geometrieDuCycle;
1311:                boolean orientationOk = true;
1312:                Population popFaces = this .getPopFaces();
1313:
1314:                // Parcours de tous les arcs du graphe. Puis, pour chaque arc: 
1315:                //    - recherche du cycle à droite et du cycle à gauche
1316:                //    - creation des faces correspondantes
1317:                //    - on note les arcs par lesquels on est déjà passé pour ne pas refaire le travail
1318:                itArcs = this .getPopArcs().getElements().iterator();
1319:                while (itArcs.hasNext()) {
1320:                    arc = (Arc) itArcs.next();
1321:                    // a droite
1322:                    if (!arcsDejaTraitesADroite.contains(arc)) {
1323:                        cycle = arc.cycleADroite();
1324:                        if (cycle == null)
1325:                            continue;
1326:                        arcsDuCycle = (List) cycle.get(0);
1327:                        orientationsArcsDuCycle = (List) cycle.get(1);
1328:                        geometrieDuCycle = (GM_Polygon) cycle.get(2);
1329:                        face = (Face) popFaces.nouvelElement();
1330:                        face.setGeometrie(geometrieDuCycle);
1331:                        //if ( persistant ) JeuDeDonnees.db.makePersistent(face);
1332:                        itArcsCycle = arcsDuCycle.iterator();
1333:                        itOrientations = orientationsArcsDuCycle.iterator();
1334:                        while (itArcsCycle.hasNext()) {
1335:                            arcCycle = (Arc) itArcsCycle.next();
1336:                            orientationOk = ((Boolean) itOrientations.next())
1337:                                    .booleanValue();
1338:                            if (orientationOk) {
1339:                                arcCycle.setFaceDroite(face);
1340:                                arcsDejaTraitesADroite.add(arcCycle);
1341:                            } else {
1342:                                arcCycle.setFaceGauche(face);
1343:                                arcsDejaTraitesAGauche.add(arcCycle);
1344:                            }
1345:                        }
1346:                    }
1347:                    // a gauche
1348:                    if (!arcsDejaTraitesAGauche.contains(arc)) {
1349:                        cycle = arc.cycleAGauche();
1350:                        if (cycle == null)
1351:                            continue;
1352:                        arcsDuCycle = (List) cycle.get(0);
1353:                        orientationsArcsDuCycle = (List) cycle.get(1);
1354:                        geometrieDuCycle = (GM_Polygon) cycle.get(2);
1355:                        face = (Face) popFaces.nouvelElement();
1356:                        face.setGeometrie(geometrieDuCycle);
1357:                        //if ( persistant ) JeuDeDonnees.db.makePersistent(face);
1358:                        itArcsCycle = arcsDuCycle.iterator();
1359:                        itOrientations = orientationsArcsDuCycle.iterator();
1360:                        while (itArcsCycle.hasNext()) {
1361:                            arcCycle = (Arc) itArcsCycle.next();
1362:                            orientationOk = ((Boolean) itOrientations.next())
1363:                                    .booleanValue();
1364:                            if (orientationOk) {
1365:                                arcCycle.setFaceGauche(face);
1366:                                arcsDejaTraitesAGauche.add(arcCycle);
1367:                            } else {
1368:                                arcCycle.setFaceDroite(face);
1369:                                arcsDejaTraitesADroite.add(arcCycle);
1370:                            }
1371:                        }
1372:                    }
1373:                }
1374:            }
1375:
1376:            /** Détruit les relations topologique d'une face avec tous ses arcs entourants */
1377:            public void videTopologieFace(Face face) {
1378:                Iterator it = face.arcs().iterator();
1379:                Arc arc;
1380:                while (it.hasNext()) {
1381:                    arc = (Arc) it.next();
1382:                    arc.setFaceDroite(null);
1383:                    arc.setFaceGauche(null);
1384:                }
1385:            }
1386:
1387:            /** Ajoute des arcs et des noeuds à la carteTopo this qui ne contient que des faces.
1388:             * Ces arcs sont les arcs entourant les faces.
1389:             * 
1390:             * Les relations topologiques arcs/noeuds/surfaces sont instanciées au passage.
1391:             * 
1392:             * Les trous sont gérés.
1393:             * Les faces en entrée peuvent avoir une orientation quelconque (direct), cela est géré.
1394:             * Par contre, on ne s'appuie que sur les points intermédiaires existants dans les polygones des faces :
1395:             * les relations topologiques sont donc bien gérés uniquement si les polygones ont des géométrie "compatibles".
1396:             * 
1397:             * @param filtrageNoeudsSimples
1398:             *   Si ce paramètre est égal à false, alors on crée un arc et deux noeuds 
1399:             *   pour chaque segment reliant des points intermédiares des surfaces.  
1400:             *   Si ce paramètre est égal à true, alors on fusionne les arcs et on ne retient  
1401:             *   que les noeuds qui ont 3 arcs incidents ou qui servent de point initial/final à une face. 
1402:             * 	
1403:             * @author  Mustière/Bonin
1404:             * 
1405:             * @date 09/05/2006
1406:             * 
1407:             */
1408:            public void ajouteArcsEtNoeudsAuxFaces(boolean filtrageNoeudsSimples) {
1409:                DirectPosition pt1, pt2;
1410:                Iterator itPts;
1411:                boolean sensDirect;
1412:
1413:                // On crée un arc pour chaque segment reliant deux points intermédiaires d'une surface
1414:                // Pour deux faces adjacentes, on duplique ces arcs. On fait le ménage après.
1415:                Iterator itFaces = this .getPopFaces().getElements().iterator();
1416:                while (itFaces.hasNext()) {
1417:                    Face face = (Face) itFaces.next();
1418:                    GM_Polygon geomFace = face.getGeometrie();
1419:                    //gestion du contour
1420:                    DirectPositionList ptsDeLaSurface = geomFace
1421:                            .exteriorCoord();
1422:                    sensDirect = Operateurs.sensDirect(ptsDeLaSurface);
1423:                    itPts = ptsDeLaSurface.getList().iterator();
1424:                    pt1 = (DirectPosition) itPts.next();
1425:                    while (itPts.hasNext()) {
1426:                        pt2 = (DirectPosition) itPts.next();
1427:                        Arc arc = (Arc) this .getPopArcs().nouvelElement();
1428:                        GM_LineString segment = new GM_LineString();
1429:                        segment.addControlPoint(pt1);
1430:                        segment.addControlPoint(pt2);
1431:                        arc.setGeom(segment);
1432:                        if (sensDirect)
1433:                            arc.setFaceGauche(face);
1434:                        else
1435:                            arc.setFaceDroite(face);
1436:                        pt1 = pt2;
1437:                    }
1438:                    //gestion des trous
1439:                    Iterator itTrous = geomFace.getInterior().iterator();
1440:                    while (itTrous.hasNext()) {
1441:                        GM_Ring trou = (GM_Ring) itTrous.next();
1442:                        DirectPositionList geomTrou = trou.getPrimitive()
1443:                                .coord();
1444:                        sensDirect = Operateurs.sensDirect(geomTrou);
1445:                        itPts = geomTrou.getList().iterator();
1446:                        pt1 = (DirectPosition) itPts.next();
1447:                        while (itPts.hasNext()) {
1448:                            pt2 = (DirectPosition) itPts.next();
1449:                            Arc arc = (Arc) this .getPopArcs().nouvelElement();
1450:                            GM_LineString segment = new GM_LineString();
1451:                            segment.addControlPoint(pt1);
1452:                            segment.addControlPoint(pt2);
1453:                            arc.setGeom(segment);
1454:                            if (sensDirect)
1455:                                arc.setFaceDroite(face);
1456:                            else
1457:                                arc.setFaceGauche(face);
1458:                            pt1 = pt2;
1459:                        }
1460:                    }
1461:                }
1462:
1463:                //indexation spatiale des arcs crées
1464:                //on crée un dallage avec en moyenne 20 objets par case
1465:                FT_FeatureCollection arcsNonTraites = new FT_FeatureCollection(
1466:                        this .getPopArcs().getElements());
1467:                int nb = (int) Math.sqrt(arcsNonTraites.size() / 20);
1468:                if (nb == 0)
1469:                    nb = 1;
1470:                arcsNonTraites.initSpatialIndex(Tiling.class, true, nb);
1471:
1472:                // filtrage des arcs en double dus aux surfaces adjacentes
1473:                List arcsAEnlever = new ArrayList();
1474:                Iterator itArcs = this .getPopArcs().getElements().iterator();
1475:                while (itArcs.hasNext()) {
1476:                    Arc arc = (Arc) itArcs.next();
1477:                    if (!arcsNonTraites.contains(arc))
1478:                        continue;
1479:                    arcsNonTraites.remove(arc);
1480:                    FT_FeatureCollection arcsProches = arcsNonTraites.select(
1481:                            arc.getGeometrie().startPoint(), 0);
1482:                    Iterator itArcsProches = arcsProches.getElements()
1483:                            .iterator();
1484:                    while (itArcsProches.hasNext()) {
1485:                        Arc arc2 = (Arc) itArcsProches.next();
1486:                        if (arc2.getGeometrie().startPoint().equals(
1487:                                arc.getGeometrie().startPoint(), 0)
1488:                                && arc2.getGeometrie().endPoint().equals(
1489:                                        arc.getGeometrie().endPoint(), 0)) {
1490:                            arcsAEnlever.add(arc2);
1491:                            arcsNonTraites.remove(arc2);
1492:                            if (arc2.getFaceDroite() != null)
1493:                                arc.setFaceDroite(arc2.getFaceDroite());
1494:                            if (arc2.getFaceGauche() != null)
1495:                                arc.setFaceGauche(arc2.getFaceGauche());
1496:                        }
1497:                        if (arc2.getGeometrie().startPoint().equals(
1498:                                arc.getGeometrie().endPoint(), 0)
1499:                                && arc2.getGeometrie().endPoint().equals(
1500:                                        arc.getGeometrie().startPoint(), 0)) {
1501:                            arcsAEnlever.add(arc2);
1502:                            arcsNonTraites.remove(arc2);
1503:                            if (arc2.getFaceDroite() != null)
1504:                                arc.setFaceGauche(arc2.getFaceDroite());
1505:                            if (arc2.getFaceGauche() != null)
1506:                                arc.setFaceDroite(arc2.getFaceGauche());
1507:                        }
1508:                    }
1509:                }
1510:                this .getPopArcs().removeAll(arcsAEnlever);
1511:
1512:                // ajout des noeuds et des relations topologiqes arc/noeud
1513:                this .creeNoeudsManquants(0);
1514:
1515:                // filtrage de tous les noeuds simples (degré=2)
1516:                if (filtrageNoeudsSimples)
1517:                    this .filtreNoeudsSimples();
1518:            }
1519:
1520:            /////////////////////////////////////////////////////////////////////////////////////////////
1521:            //	Pour les calculs de plus court chemin
1522:            /////////////////////////////////////////////////////////////////////////////////////////////
1523:
1524:            /** Initialise le poids de chaque arc comme étant égal à sa longueur;
1525:             *  NB: utile uniquement aux plus courts chemins */
1526:            public void initialisePoids() {
1527:                Arc arc;
1528:                Iterator itArcs = this .getPopArcs().getElements().iterator();
1529:                while (itArcs.hasNext()) {
1530:                    arc = (Arc) itArcs.next();
1531:                    if (arc.getGeometrie() == null)
1532:                        arc.setPoids(0);
1533:                    arc.setPoids(arc.longueur());
1534:                }
1535:            }
1536:
1537:            /////////////////////////////////////////////////////////////////////////////////////////////
1538:            //	IMPORT: remplissage de la carte topo à partir de Features
1539:            /////////////////////////////////////////////////////////////////////////////////////////////
1540:
1541:            /** Charge en mémoire les élements de la classe 'nomClasseGeo'
1542:             * et remplit 'this' avec des correspondants de ces éléments.*/
1543:            public void importClasseGeo(String nomClasseGeo) {
1544:                Chargeur.importClasseGeo(nomClasseGeo, this );
1545:            }
1546:
1547:            /** Remplit 'this' avec des correspondants des éléments de 'listeFeature'.*/
1548:            public void importClasseGeo(FT_FeatureCollection listeFeatures) {
1549:                Chargeur.importClasseGeo(listeFeatures, this);
1550:            }
1551:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.