001: /*
002: * This file is part of the GeOxygene project source files.
003: *
004: * GeOxygene aims at providing an open framework which implements OGC/ISO specifications for
005: * the development and deployment of geographic (GIS) applications. It is a open source
006: * contribution of the COGIT laboratory at the Institut Géographique National (the French
007: * National Mapping Agency).
008: *
009: * See: http://oxygene-project.sourceforge.net
010: *
011: * Copyright (C) 2005 Institut Géographique National
012: *
013: * This library is free software; you can redistribute it and/or modify it under the terms
014: * of the GNU Lesser General Public License as published by the Free Software Foundation;
015: * either version 2.1 of the License, or any later version.
016: *
017: * This library is distributed in the hope that it will be useful, but WITHOUT ANY
018: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
019: * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
020: *
021: * You should have received a copy of the GNU Lesser General Public License along with
022: * this library (see file LICENSE if present); if not, write to the Free Software
023: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024: *
025: */
026:
027: package fr.ign.cogit.geoxygene.contrib.appariement.reseaux.topologie;
028:
029: import java.util.ArrayList;
030: import java.util.Collection;
031: import java.util.HashSet;
032: import java.util.Iterator;
033: import java.util.List;
034:
035: import fr.ign.cogit.geoxygene.contrib.appariement.EnsembleDeLiens;
036: import fr.ign.cogit.geoxygene.contrib.appariement.reseaux.LienReseaux;
037: import fr.ign.cogit.geoxygene.contrib.cartetopo.Arc;
038: import fr.ign.cogit.geoxygene.contrib.geometrie.Distances;
039: import fr.ign.cogit.geoxygene.feature.FT_Feature;
040: import fr.ign.cogit.geoxygene.spatial.coordgeom.DirectPosition;
041:
042: /**
043: * Arc d'un reseau à apparier.
044: *
045: * @author Mustiere - IGN / Laboratoire COGIT
046: * @version 1.0
047: *
048: */
049:
050: public class ArcApp extends Arc {
051:
052: /** Evaluation du résultat de l'appariement sur l'arc. */
053: private String resultatAppariement;
054:
055: public String getResultatAppariement() {
056: return resultatAppariement;
057: }
058:
059: public void setResultatAppariement(String resultat) {
060: resultatAppariement = resultat;
061: }
062:
063: /** Liens qui référencent les objets auquel l'arc est apparié dans un autre réseau. */
064: private List liens = new ArrayList();
065:
066: public List getLiens() {
067: return liens;
068: }
069:
070: public void setLiens(List liens) {
071: this .liens = liens;
072: }
073:
074: public void addLiens(LienReseaux liens) {
075: this .liens.add(liens);
076: }
077:
078: ////////////////////////////////////////////////////
079: // POUR MANIPULER LES LIENS
080: ////////////////////////////////////////////////////
081:
082: /** Renvoie les liens de l'objet qui appartiennent à la liste liensPertinents */
083: public List getLiens(List liensPertinents) {
084: List listeTmp = new ArrayList(this .getLiens());
085: listeTmp.retainAll(liensPertinents);
086: return listeTmp;
087: }
088:
089: /** Recherche des noeuds en correspondance aux extrémités de l'arc,
090: * que ce soit en entree ou en sortie (au sens de la circulation, i.e. de l'attribut orientation)
091: *
092: * Renvoie une liste de 4 listes:
093: * 0: les noeuds en correspondance au début de l'arc, et en entree
094: * 1: les noeuds en correspondance au début de l'arc, et en sortie
095: * 2: les noeuds en correspondance à la fin de l'arc, et en entree
096: * 3: les noeuds en correspondance à la fin de l'arc, et en sortie
097: */
098: public List noeudsEnCorrespondanceAuxExtremites(
099: EnsembleDeLiens liensNoeuds, EnsembleDeLiens liensArcs) {
100: List tousNoeuds;
101: Iterator itTousGroupes;
102: List noeudsDebutIn = new ArrayList(), noeudsDebutOut = new ArrayList();
103: List noeudsFinIn = new ArrayList(), noeudsFinOut = new ArrayList();
104: List resultat = new ArrayList();
105: NoeudApp noeudRef;
106: GroupeApp groupeComp;
107:
108: // traitement du noeud ini
109: noeudRef = (NoeudApp) this .getNoeudIni();
110: // noeud INI apparié avec un ou des noeuds
111: tousNoeuds = noeudRef.noeudsCompEnCorrespondance(liensNoeuds);
112: if (this .getOrientation() != 1)
113: noeudsDebutIn.addAll(tousNoeuds);
114: if (this .getOrientation() != -1)
115: noeudsDebutOut.addAll(tousNoeuds);
116:
117: // noeud INI apparié avec un groupe
118: itTousGroupes = noeudRef.groupesCompEnCorrespondance(
119: liensNoeuds).iterator();
120: while (itTousGroupes.hasNext()) {
121: groupeComp = (GroupeApp) itTousGroupes.next();
122: if (this .getOrientation() != 1)
123: noeudsDebutIn.addAll(groupeComp.noeudsEntree(noeudRef,
124: liensArcs));
125: if (this .getOrientation() != -1)
126: noeudsDebutOut.addAll(groupeComp.noeudsSortie(noeudRef,
127: liensArcs));
128: }
129:
130: // traitement du noeud fin
131: noeudRef = (NoeudApp) this .getNoeudFin();
132: // noeud FIN apparié avec un ou des noeuds
133: tousNoeuds = noeudRef.noeudsCompEnCorrespondance(liensNoeuds);
134: if (this .getOrientation() != -1)
135: noeudsFinIn.addAll(tousNoeuds);
136: if (this .getOrientation() != 1)
137: noeudsFinOut.addAll(tousNoeuds);
138:
139: // noeud FIN apparié avec un groupe
140: itTousGroupes = noeudRef.groupesCompEnCorrespondance(
141: liensNoeuds).iterator();
142: while (itTousGroupes.hasNext()) {
143: groupeComp = (GroupeApp) itTousGroupes.next();
144: if (this .getOrientation() != -1)
145: noeudsFinIn.addAll(groupeComp.noeudsEntree(noeudRef,
146: liensArcs));
147: if (this .getOrientation() != 1)
148: noeudsFinOut.addAll(groupeComp.noeudsSortie(noeudRef,
149: liensArcs));
150: }
151: resultat.add(noeudsDebutIn);
152: resultat.add(noeudsDebutOut);
153: resultat.add(noeudsFinIn);
154: resultat.add(noeudsFinOut);
155:
156: return resultat;
157: }
158:
159: /** Arcs reliés à this par l'appariement passé en paramètre.
160: * Cette liste ne contient pas de doublon.
161: * La liste contient des Arc_Comp. */
162: public List arcsCompEnCorrespondance(EnsembleDeLiens liens) {
163: List liensOK;
164: Collection arcs = new HashSet();
165: LienReseaux lien;
166: Iterator itLiensOK;
167:
168: liensOK = new ArrayList(this .getLiens());
169: liensOK.retainAll(liens.getElements());
170: itLiensOK = liensOK.iterator();
171: while (itLiensOK.hasNext()) {
172: lien = (LienReseaux) itLiensOK.next();
173: arcs.addAll(lien.getArcs2());
174: }
175: return new ArrayList(arcs);
176: }
177:
178: /** Arcs reliés à this par l'appariement passé en paramètre.
179: * La liste contient des Arc_Ref. */
180: public List arcsRefEnCorrespondance(EnsembleDeLiens liens) {
181: List arcs = new ArrayList();
182: List liensOK;
183: LienReseaux lien;
184: int i;
185:
186: liensOK = new ArrayList(this .getLiens());
187: liensOK.retainAll(liens.getElements());
188: for (i = 0; i < liensOK.size(); i++) {
189: lien = (LienReseaux) liensOK.get(i);
190: arcs.addAll(lien.getArcs1());
191: }
192: return arcs;
193: }
194:
195: /** Renvoie la liste des objets géo initaux reliés à un arc ref ou un noeud ref
196: * qui est en correspondance avec this (un arc_comp) à travers liens,
197: * soit directement, soit par l'intermédiaire d'un groupe.
198: */
199: public List objetsGeoRefEnCorrespondance(EnsembleDeLiens liens) {
200: List objetsCtEnCorrespondance = new ArrayList();
201: List objetsGeoEnCorrespondance = new ArrayList();
202: List liensOK;
203: LienReseaux lien;
204: Iterator itGroupes, itLiens, itObjetsCT;
205:
206: // objets de reseauRef en correspondance directe avec this.
207: liensOK = new ArrayList(this .getLiens());
208: liensOK.retainAll(liens.getElements());
209: itLiens = liensOK.iterator();
210: while (itLiens.hasNext()) {
211: lien = (LienReseaux) itLiens.next();
212: objetsCtEnCorrespondance.addAll(lien.getArcs1());
213: objetsCtEnCorrespondance.addAll(lien.getNoeuds1());
214: }
215:
216: // objets de reseauRef en correspondance avec this à travers un groupe
217: itGroupes = this .getListeGroupes().iterator();
218: while (itGroupes.hasNext()) {
219: GroupeApp groupe = (GroupeApp) itGroupes.next();
220: liensOK = new ArrayList(groupe.getLiens());
221: liensOK.retainAll(liens.getElements());
222: itLiens = liensOK.iterator();
223: while (itLiens.hasNext()) {
224: lien = (LienReseaux) itLiens.next();
225: objetsCtEnCorrespondance.addAll(lien.getArcs1());
226: objetsCtEnCorrespondance.addAll(lien.getNoeuds1());
227: }
228: }
229:
230: // objets geo correspondants
231: itObjetsCT = objetsCtEnCorrespondance.iterator();
232: while (itObjetsCT.hasNext()) {
233: FT_Feature objetCT = (FT_Feature) itObjetsCT.next();
234: objetsGeoEnCorrespondance.addAll(objetCT
235: .getCorrespondants());
236: }
237:
238: return objetsGeoEnCorrespondance;
239: }
240:
241: /** A un correspondant par l'appariement passé en paramètre ? */
242: public boolean aUnCorrespondant(EnsembleDeLiens liens) {
243: List liensOK = new ArrayList();
244: liensOK = new ArrayList(this .getLiens());
245: liensOK.retainAll(liens.getElements());
246: if (liensOK.size() != 0)
247: return true;
248: return false;
249: }
250:
251: /** A un correspondant par l'appariement passé en paramètre, soit directement,
252: * soit par l'intermédiaire d'un groupe ? */
253: public boolean aUnCorrespondantGeneralise(EnsembleDeLiens liens) {
254: if (this .aUnCorrespondant(liens))
255: return true;
256: Iterator itGroupes = this .getListeGroupes().iterator();
257: while (itGroupes.hasNext()) {
258: GroupeApp groupe = (GroupeApp) itGroupes.next();
259: List liensDuGroupe = groupe.getLiens(liens.getElements());
260: if (liensDuGroupe.size() != 0)
261: return true;
262: }
263: return false;
264: }
265:
266: ////////////////////////////////////////////////////
267: // POUR MANIPULER LA TOPOLOGIE ET LA GEOMETRIE
268: ////////////////////////////////////////////////////
269:
270: /** L'arc est il une impasse ? */
271: public boolean impasse() {
272: return (this .impasseDebut() || this .impasseFin());
273: }
274:
275: /** L'arc est il une impasse au début (noeud ini fond de l'impasse) ? */
276: public boolean impasseDebut() {
277: if ((this .getNoeudIni().arcs().size()) == 1)
278: return true;
279: return false;
280: }
281:
282: /** L'arc est il une impasse à la fin (noeud fin fond de l'impasse) ? */
283: public boolean impasseFin() {
284: if ((this .getNoeudFin().arcs().size()) == 1)
285: return true;
286: return false;
287: }
288:
289: /** L'arc est il une boucle (noeud ini = noeud fin) ? */
290: public boolean boucle() {
291: if (this .getNoeudFin() == this .getNoeudIni())
292: return true;
293: return false;
294: }
295:
296: /** L'arc est il une impasse au sein du groupe ? */
297: public boolean impasse(GroupeApp groupe) {
298: return (this .impasseDebut(groupe) || this .impasseFin(groupe));
299: }
300:
301: /** L'arc est il une impasse au sein du groupe, au début (noeud ini fond de l'impasse) ? */
302: public boolean impasseDebut(GroupeApp groupe) {
303: List arcs = new ArrayList();
304: arcs = new ArrayList(this .getNoeudIni().arcs());
305: arcs.retainAll(groupe.getListeArcs());
306: if (arcs.size() == 1)
307: return true;
308: return false;
309: }
310:
311: /** L'arc est il une impasse au sein du groupe, à la fin (noeud final au fond de l'impasse) ? */
312: public boolean impasseFin(GroupeApp groupe) {
313: List arcs = new ArrayList();
314: arcs = new ArrayList(this .getNoeudFin().arcs());
315: arcs.retainAll(groupe.getListeArcs());
316: if (arcs.size() == 1)
317: return true;
318: return false;
319: }
320:
321: /** Première composante de la distance de Hausdorff de self vers l'arc.
322: * Version optimisée pour l'appariement:
323: * si cette distance est supérieure à Dmax, alors renvoie Double.MAX_VALUE,
324: * sans plus de précision.
325: */
326: public double premiereComposanteHausdorff(Arc arc, double dmax) {
327: double dist, hausdorff = 0;
328: Iterator itPts = this .getGeometrie().coord().getList()
329: .iterator();
330: while (itPts.hasNext()) {
331: DirectPosition pt = (DirectPosition) itPts.next();
332: dist = Distances.distance(pt, arc.getGeometrie());
333: if (dist > dmax)
334: return Double.MAX_VALUE;
335: if (dist > hausdorff)
336: hausdorff = dist;
337: }
338: return hausdorff;
339: }
340:
341: }
|