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.surfaces;
028:
029: import java.sql.Time;
030: import java.util.ArrayList;
031: import java.util.HashSet;
032: import java.util.Iterator;
033: import java.util.List;
034: import java.util.Set;
035:
036: import fr.ign.cogit.geoxygene.contrib.appariement.EnsembleDeLiens;
037: import fr.ign.cogit.geoxygene.contrib.appariement.Lien;
038: import fr.ign.cogit.geoxygene.contrib.cartetopo.Arc;
039: import fr.ign.cogit.geoxygene.contrib.cartetopo.CarteTopo;
040: import fr.ign.cogit.geoxygene.contrib.cartetopo.Groupe;
041: import fr.ign.cogit.geoxygene.contrib.cartetopo.Noeud;
042: import fr.ign.cogit.geoxygene.contrib.geometrie.Distances;
043: import fr.ign.cogit.geoxygene.contrib.geometrie.Operateurs;
044: import fr.ign.cogit.geoxygene.contrib.graphe.ARM;
045: import fr.ign.cogit.geoxygene.contrib.operateurs.Ensemble;
046: import fr.ign.cogit.geoxygene.feature.DataSet;
047: import fr.ign.cogit.geoxygene.feature.FT_Feature;
048: import fr.ign.cogit.geoxygene.feature.FT_FeatureCollection;
049: import fr.ign.cogit.geoxygene.spatial.coordgeom.GM_LineString;
050: import fr.ign.cogit.geoxygene.spatial.geomaggr.GM_Aggregate;
051: import fr.ign.cogit.geoxygene.spatial.geomaggr.GM_MultiSurface;
052: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Point;
053: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Surface;
054: import fr.ign.cogit.geoxygene.spatial.geomroot.GM_Object;
055: import fr.ign.cogit.geoxygene.util.index.Tiling;
056:
057: /**
058: * Appariement de surfaces.
059: * Processus défini dans la thèse de Atef Bel Hadj Ali (2001),
060: * et resume dans le rapport [Mustiere 2002]:
061: * ("Description des processus d'appariement mis en oeuvre au COGIT",SR/2002.0072, chap.6).
062: *
063: * @author Braun & Mustière - Laboratoire COGIT
064: * version 1.0
065: *
066: */
067:
068: public abstract class AppariementSurfaces {
069:
070: /**
071: * Appariement entre deux ensembles de surfaces.
072: * Processus inspiré de celui défini dans la thèse de Atef Bel Hadj Ali (2001),
073: * et resumé dans le rapport de Seb
074: * ("Description des processus d'appariement mise en oeuvre au COGIT",SR/2002.0072, chap.6).
075: *
076: * NB 1 : LE CAS DES LIENS N-M N'EST PAS VRAIMENT SATIFAISANT
077: * ET DOIT ENCORE ETRE REVU (reflechir aux mesures). Néanmoins...
078: * le processus a été amélioré pour mieux raffiner le traitement des liens n-m :
079: * un lien n-m issu du regroupement des liens 1-1 peut être redécoupé en
080: * plusieurs liens n'-m', alors que le processus d'Atef ne semble permettre
081: * que de simplifier ce groupe n-m en UN seul groupe n'-m' (n'<=n, m'<=m)
082: *
083: * NB 2 :Les liens finaux sont qualifiés (evaluation) par la mesure de
084: * distance surfacique entre groupes de surfaces.
085: *
086: * NB 3 : si la population de référence n'est pas indexée, elle le sera pendant le calcul
087: *
088: * NB 4 : l'appariement est symétrique (si ref et comp sont échangés, les résultats sont identiques)
089: *
090: * @param popRef : population des objets de référence.
091: * Ces objets doivent avoir une géométrie "geom" de type GM_Polygon
092: * @param popComp : population des objets de comparaison
093: * Ces objets doivent avoir une géométrie "geom" de type GM_Polygon
094: * @param param : paramètres de l'appariement
095: *
096: *
097: * @return : liens d'appariement calculés. Ces liens peuvent être de type n-m.
098: */
099: public static EnsembleDeLiens appariementSurfaces(
100: FT_FeatureCollection popRef, FT_FeatureCollection popComp,
101: ParametresAppSurfaces param) {
102: EnsembleDeLiens liensPreApp, liensRegroupes, liensFiltres;
103:
104: // indexation au besoin des surfaces de comparaison
105: if (!popComp.hasSpatialIndex()) {
106: System.out
107: .println("-- Indexation spatiale des surfaces de comparaison "
108: + new Time(System.currentTimeMillis()));
109: popComp.initSpatialIndex(Tiling.class, true);
110: }
111:
112: // pré-appariement selon un test sur la surface de l'intersection
113: // entre les surfaces de référence et de comparaison
114: System.out
115: .println("-- Pre-appariement sur des critères d'intersection "
116: + new Time(System.currentTimeMillis()));
117: liensPreApp = preAppariementSurfaces(popRef, popComp, param);
118:
119: // appariement par recherche des regroupements optimaux
120: if (param.regroupementOptimal) {
121: System.out
122: .println("-- Appariement par recherche des regroupements optimaux : "
123: + new Time(System.currentTimeMillis()));
124: liensRegroupes = rechercheRegroupementsOptimaux(
125: liensPreApp, popRef, popComp, param);
126: } else
127: liensRegroupes = liensPreApp;
128:
129: // recollage des petites surfaces non encore appariées
130: if (param.ajoutPetitesSurfaces) {
131: System.out
132: .println("-- Recollage des petites surfaces non encore appariées : "
133: + new Time(System.currentTimeMillis()));
134: ajoutPetitesSurfaces(liensRegroupes, popRef, popComp, param);
135: }
136:
137: // filtrage final pour n'accepter que les appariements suffisament bons
138: if (param.filtrageFinal) {
139: System.out.println("-- Filtrage final : "
140: + new Time(System.currentTimeMillis()));
141: liensFiltres = filtreLiens(liensRegroupes, param);
142: } else
143: liensFiltres = liensRegroupes;
144:
145: System.out.println("-- Création de la géométrie des liens : "
146: + new Time(System.currentTimeMillis()));
147: creeGeometrieDesLiens(liensFiltres, param.persistant);
148:
149: System.out.println("Fin du traitement");
150:
151: return liensFiltres;
152: }
153:
154: /** 2 surfaces sont pré-appariées si elles respectent le "test d'association"
155: * défini par Atef Bel Hadj Ali (2001). C'est-à-dire si :
156: * 1/ l'intersection des surfaces a une taille supérieure au seuil "surface_min"
157: * ET
158: * 2/ l'intersection fait au moins la taille d'une des surfaces multipliée
159: * par le paramètre "pourcentage_min".
160: *
161: * NB 1 : Par construction : chaque lien pointe vers UN SEUL objet de la population
162: * de référence et vers UN SEUL objet de la population de comparaison.
163: * NB 2 : Aucune géométrie n'est instanciée pour les liens créés.
164: * NB 3 : l'appariement est symétrique.
165: * NB 4 : la population de comparaison est indexée si elle ne l'était pas avant
166: *
167: * @param popRef : population des objets de référence.
168: * @param popComp : population des objets de comparaison.
169: * @param param : paramètres de l'appariement.
170: *
171: * @return : liens de pré-appariement calculés.
172: */
173: public static EnsembleDeLiens preAppariementSurfaces(
174: FT_FeatureCollection popRef, FT_FeatureCollection popComp,
175: ParametresAppSurfaces param) {
176:
177: EnsembleDeLiens preAppLiens = new EnsembleDeLiens();
178: Lien lien;
179: FT_FeatureCollection candidatComp;
180: FT_Feature featureRef, featureComp;
181: GM_Object geomRef, geomComp;
182: double surfaceIntersection, pourcentageRecouvrement;
183:
184: if (!popComp.hasSpatialIndex()) {
185: System.out
186: .println("Indexation spatiale de la poplation des surfaces de comparaison");
187: popComp.initSpatialIndex(Tiling.class, true);
188: }
189:
190: popRef.initIterator();
191: while (popRef.hasNext()) {
192: featureRef = popRef.next();
193: geomRef = (GM_Object) featureRef.getGeom();
194: if (!(geomRef instanceof GM_Surface)) {
195: System.out
196: .println("Objet de la population de référence sans géométrie surfacique COGITID = "
197: + featureRef.getId());
198: continue;
199: }
200:
201: // Test d'association sur tous les objets comp intersectant l'objet ref
202: candidatComp = popComp.select(geomRef);
203: candidatComp.initIterator();
204: while (candidatComp.hasNext()) {
205: featureComp = candidatComp.next();
206: geomComp = (GM_Object) featureComp.getGeom();
207: if (!(geomComp instanceof GM_Surface)) {
208: System.out
209: .println("Objet de la population de comparaison sans géométrie surfacique COGITID = "
210: + featureComp.getId());
211: continue;
212: }
213: // création éventuelle d'un nouveau lien de pré-appariement
214: GM_Object inter = Operateurs.intersectionRobuste(
215: geomRef, geomComp, param.resolutionMin,
216: param.resolutionMax);
217: if (inter == null)
218: continue; // si plantage aux calculs d'intersection
219: surfaceIntersection = inter.area();
220: if (surfaceIntersection <= param.surface_min_intersection)
221: continue;
222: pourcentageRecouvrement = Math.max(surfaceIntersection
223: / geomRef.area(), surfaceIntersection
224: / geomComp.area());
225: if (pourcentageRecouvrement < param.pourcentage_min_intersection)
226: continue; //intersection pas suffisante
227: lien = (Lien) preAppLiens.nouvelElement();
228: lien.addObjetRef(featureRef);
229: lien.addObjetComp(featureComp);
230: lien.setEvaluation(pourcentageRecouvrement);
231: }
232: }
233: System.out
234: .println(" Nombre de liens (1-1) créés au pré-appariement "
235: + preAppLiens.size());
236: return preAppLiens;
237: }
238:
239: /** On recherche les regroupements optimaux de liens de pré-appariement, pour
240: * maximiser la distance surfacique entre les groupes de référence et de comparaison.
241: *
242: * NB : l'appariement est symétrique
243: *
244: * @param param : paramètres de l'appariement
245: * @param liensPreApp : liens issus du pré-appariement
246: * @return : liens d'appariement calculés (contient des objets de la classe Lien).
247: * Ces liens sont des liens n-m.
248: */
249: public static EnsembleDeLiens rechercheRegroupementsOptimaux(
250: EnsembleDeLiens liensPreApp, FT_FeatureCollection popRef,
251: FT_FeatureCollection popComp, ParametresAppSurfaces param) {
252: EnsembleDeLiens liensGroupes;
253: Lien lienGroupe, lienArc;
254: double distSurfMin, distExacMax, dist;
255: CarteTopo grapheDesLiens;
256: Groupe groupeTotal, groupeConnexe, groupeLight;
257: Iterator itGroupes, itCombinaisons, itNoeuds, itArcs;
258: List groupesConnexes;
259: List arcsEnlevables, arcsNonEnlevables, arcsDuGroupeEnleves, arcsDuGroupeEnlevesFinal;
260: Noeud noeud;
261: FT_Feature feat;
262: int i = 0;
263: List groupesGardes = new ArrayList();
264: List groupesDecomposes;
265:
266: //on crée les liens n-m (groupes connexes du graphe des liens)
267: grapheDesLiens = liensPreApp.transformeEnCarteTopo(popRef,
268: popComp);
269: groupeTotal = (Groupe) grapheDesLiens.getPopGroupes()
270: .nouvelElement();
271: groupeTotal.setListeArcs(grapheDesLiens.getListeArcs());
272: groupeTotal.setListeNoeuds(grapheDesLiens.getListeNoeuds());
273: groupesConnexes = groupeTotal.decomposeConnexes();
274: System.out.println("Nombre de liens (n-m) à traiter "
275: + groupesConnexes.size());
276:
277: // on parcours tous les liens n-m créés
278: itGroupes = groupesConnexes.iterator();
279: while (itGroupes.hasNext()) {
280: i++;
281: if (i % 10000 == 0)
282: System.out.println("Nb de groupes traités : " + i
283: + " "
284: + new Time(System.currentTimeMillis()));
285: groupeConnexe = (Groupe) itGroupes.next();
286:
287: // pour les objets isolés ou les liens 1-1, on ne fait rien de plus
288: if (groupeConnexe.getListeArcs().size() == 0)
289: continue;
290: if (groupeConnexe.getListeArcs().size() == 1) {
291: groupesGardes.add(groupeConnexe);
292: continue;
293: }
294:
295: // pour les groupes n-m, on va essayer d'enlever des arcs
296: // mais on garde à coup sûr les liens avec suffisament de recouvremnt
297: arcsEnlevables = new ArrayList(groupeConnexe.getListeArcs());
298: arcsNonEnlevables = new ArrayList();
299: itArcs = arcsEnlevables.iterator();
300: while (itArcs.hasNext()) {
301: Arc arc = (Arc) itArcs.next();
302: lienArc = (Lien) arc.getCorrespondant(0);
303: if (lienArc.getEvaluation() > param.pourcentage_intersection_sur)
304: arcsNonEnlevables.add(arc);
305: }
306: arcsEnlevables.removeAll(arcsNonEnlevables);
307: if (arcsEnlevables.size() == 0) { //si on ne peut rien enlever, on s'arrête là
308: groupesGardes.add(groupeConnexe);
309: continue;
310: }
311:
312: //on cherche à enlever toutes les combinaisons possibles d'arcs virables
313: itCombinaisons = Ensemble.combinaisons(arcsEnlevables)
314: .iterator();
315: distSurfMin = 2; // cas de distance surfacique à minimiser
316: distExacMax = 0; // cas de completude / exactitude à maximiser
317: arcsDuGroupeEnlevesFinal = new ArrayList();
318: while (itCombinaisons.hasNext()) { //boucle sur les combinaisons possibles
319: arcsDuGroupeEnleves = (List) itCombinaisons.next();
320: groupeLight = groupeConnexe.copie();
321: groupeLight.getListeArcs().removeAll(
322: arcsDuGroupeEnleves);
323: if (groupeLight.getListeArcs().size() == 0)
324: continue; //on refuse la solution extreme de ne rien garder comme apparié
325: dist = mesureEvaluationGroupe(groupeLight, popRef,
326: popComp, param);
327: if (param.minimiseDistanceSurfacique) {
328: // cas de distance surfacique à minimiser
329: if (dist < distSurfMin) {
330: distSurfMin = dist;
331: arcsDuGroupeEnlevesFinal = arcsDuGroupeEnleves;
332: }
333: } else {
334: // cas de completude / exactitude à maximiser
335: if (dist > distExacMax) {
336: distExacMax = dist;
337: arcsDuGroupeEnlevesFinal = arcsDuGroupeEnleves;
338: }
339: }
340: } //fin boucle sur les combinaisons possibles
341: groupeConnexe.getListeArcs().removeAll(
342: arcsDuGroupeEnlevesFinal); //simplification finale des liens d'appariement du groupe
343: groupesDecomposes = groupeConnexe.decomposeConnexes(); //création des groupes finaux gardés
344: groupesGardes.addAll(groupesDecomposes);
345: }
346:
347: // création des liens retenus (passage de structure graphe à liens):
348: // les groupes qui restent dans la carte topo représentent les liens finaux.
349: liensGroupes = new EnsembleDeLiens();
350: liensGroupes.setNom("Liens issus d'un appariement de surfaces");
351: // on parcours tous les groupes connexes créés
352: itGroupes = groupesGardes.iterator();
353: while (itGroupes.hasNext()) {
354: groupeConnexe = (Groupe) itGroupes.next();
355: if (groupeConnexe.getListeArcs().size() == 0)
356: continue; // cas des noeuds isolés
357: //if ( groupeConnexe.getListenoeuds().size() == 0 ) continue;
358: lienGroupe = (Lien) liensGroupes.nouvelElement();
359: itNoeuds = groupeConnexe.getListeNoeuds().iterator();
360: while (itNoeuds.hasNext()) {
361: noeud = (Noeud) itNoeuds.next();
362: feat = noeud.getCorrespondant(0);
363: if (popRef.getElements().contains(feat))
364: lienGroupe.addObjetRef(feat);
365: if (popComp.getElements().contains(feat))
366: lienGroupe.addObjetComp(feat);
367: // nettoyage de la carteTopo créée
368: noeud.setCorrespondants(new ArrayList());
369: }
370: }
371: return liensGroupes;
372: }
373:
374: /** Distance surfacique ou complétude "étendue" sur un groupe.
375: * Attention: vide le groupe au passage.
376: * MESURE NON SATISFAISANTE POUR LIENS N-M : moyenne entre parties connexes A REVOIR */
377: private static double mesureEvaluationGroupe(Groupe groupe,
378: FT_FeatureCollection popRef, FT_FeatureCollection popComp,
379: ParametresAppSurfaces param) {
380: List groupesConnexes;
381: Iterator itGroupes, itNoeuds;
382: GM_MultiSurface geomRef, geomComp;
383: double dist, distTot = 0;
384: Groupe groupeConnnexe;
385: Noeud noeud;
386: FT_Feature feat;
387:
388: // on décompose le groupe en parties connexes
389: groupesConnexes = groupe.decomposeConnexes();
390: itGroupes = groupesConnexes.iterator();
391: while (itGroupes.hasNext()) {
392: // on mesure la qualité de l'appariement pour chaque partie connexe,
393: groupeConnnexe = (Groupe) itGroupes.next();
394: if (groupeConnnexe.getListeArcs().size() == 0)
395: continue;
396: geomRef = new GM_MultiSurface();
397: geomComp = new GM_MultiSurface();
398: itNoeuds = groupeConnnexe.getListeNoeuds().iterator();
399: while (itNoeuds.hasNext()) {
400: noeud = (Noeud) itNoeuds.next();
401: feat = noeud.getCorrespondant(0);
402: //if ( feat.getPopulation()==popRef ) geomRef.add(feat.getGeom());
403: //if ( feat.getPopulation()==popComp ) geomComp.add(feat.getGeom());
404: if (popRef.getElements().contains(feat))
405: geomRef.add(feat.getGeom());
406: if (popComp.getElements().contains(feat))
407: geomComp.add(feat.getGeom());
408: }
409: if (param.minimiseDistanceSurfacique) {
410: dist = Distances.distanceSurfaciqueRobuste(geomRef,
411: geomComp);
412: } else
413: dist = Distances.exactitude(geomRef, geomComp)
414: + Distances.completude(geomRef, geomComp);
415: // on combine les mesures des parties connexes
416: distTot = distTot + dist;
417: }
418:
419: return distTot; // / groupesConnexes.size();
420: }
421:
422: //Bourrin: a optimiser
423: public static void ajoutPetitesSurfaces(EnsembleDeLiens liens,
424: FT_FeatureCollection popRef, FT_FeatureCollection popComp,
425: ParametresAppSurfaces param) {
426: Iterator itRef = popRef.getElements().iterator();
427: Iterator itLiens = liens.getElements().iterator();
428: Set objetsRefLies = new HashSet();
429: FT_FeatureCollection objetsAdjacents;
430: Lien lienAdjacent, lien2;
431: double surfAdj;
432: boolean tousPareils;
433:
434: if (!popRef.hasSpatialIndex()) {
435: System.out
436: .println("Indexation spatiale des surfaces de référence "
437: + new Time(System.currentTimeMillis()));
438: popRef.initSpatialIndex(Tiling.class, true);
439: }
440:
441: while (itLiens.hasNext()) {
442: Lien lien = (Lien) itLiens.next();
443: objetsRefLies.addAll(lien.getObjetsRef());
444: }
445:
446: while (itRef.hasNext()) {
447: FT_Feature objetRef = (FT_Feature) itRef.next();
448: if (objetsRefLies.contains(objetRef))
449: continue;
450: // cas d'un objet non apparié
451: objetsAdjacents = popRef.select(objetRef.getGeom());
452: if (objetsAdjacents == null)
453: continue;
454: if (objetsAdjacents.size() == 1)
455: continue;
456: objetsAdjacents.remove(objetRef);
457: lienAdjacent = liensDeObj((FT_Feature) objetsAdjacents
458: .get(0), liens);
459: surfAdj = ((FT_Feature) objetsAdjacents.get(0)).getGeom()
460: .area();
461: if (lienAdjacent == null)
462: continue;
463: tousPareils = true;
464: for (int i = 1; i < objetsAdjacents.size(); i++) {
465: lien2 = liensDeObj((FT_Feature) objetsAdjacents.get(i),
466: liens);
467: if (lienAdjacent != lien2) {
468: tousPareils = false;
469: break;
470: }
471: surfAdj = surfAdj
472: + ((FT_Feature) objetsAdjacents.get(i))
473: .getGeom().area();
474: }
475: if (!tousPareils)
476: continue;
477: if (objetRef.getGeom().area() / surfAdj > param.seuilPourcentageTaillePetitesSurfaces)
478: continue;
479: lienAdjacent.addObjetRef(objetRef);
480: }
481: }
482:
483: private static Lien liensDeObj(FT_Feature objet,
484: EnsembleDeLiens liens) {
485: Iterator itLiens = liens.getElements().iterator();
486:
487: while (itLiens.hasNext()) {
488: Lien lien = (Lien) itLiens.next();
489: if (lien.getObjetsRef().contains(objet))
490: return lien;
491: }
492: return null;
493: }
494:
495: public static EnsembleDeLiens filtreLiens(
496: EnsembleDeLiens liensRegroupes, ParametresAppSurfaces param) {
497: EnsembleDeLiens liensFiltres = new EnsembleDeLiens();
498: Lien lien, lienOK;
499: double distSurf;
500:
501: Iterator itGroupes = liensRegroupes.getElements().iterator();
502: while (itGroupes.hasNext()) {
503: lien = (Lien) itGroupes.next();
504: // si on depasse le seuil acceptable: on refuse.
505: if (param.minimiseDistanceSurfacique) {
506: distSurf = lien.distanceSurfaciqueRobuste();
507: if (distSurf < param.distSurfMaxFinal) {
508: lienOK = (Lien) liensFiltres.nouvelElement();
509: lienOK.copie(lien);
510: lienOK.setEvaluation(distSurf);
511: }
512: } else {
513: if ((lien.exactitude() > param.completudeExactitudeMinFinal)
514: && (lien.completude() > param.completudeExactitudeMinFinal)) {
515: lienOK = (Lien) liensFiltres.nouvelElement();
516: lienOK.copie(lien);
517: }
518: }
519: }
520: System.out
521: .println(" Nombre de liens retenus après filtrage : "
522: + liensFiltres.size());
523: return liensFiltres;
524: }
525:
526: public static void creeGeometrieDesLiens(EnsembleDeLiens liens,
527: boolean persistant) {
528: FT_FeatureCollection objetsRef, objetsComp;
529: FT_Feature objetComp;
530: GM_Point pointAccrocheRef, pointAccrocheComp;
531: CarteTopo armRef, armComp;
532: Iterator itLiens = liens.getElements().iterator();
533: Iterator itArcs, itNoeuds, itObjetsComp;
534: Arc arc;
535: Noeud noeud;
536: GM_Aggregate geomLien;
537:
538: if (persistant)
539: DataSet.db.begin();
540: System.out.println("Création de la géométrie des liens");
541: while (itLiens.hasNext()) {
542: Lien lien = (Lien) itLiens.next();
543: if (lien.getObjetsRef().size() == 0) {
544: System.out
545: .println("Attention, lien sans objet de référence");
546: continue;
547: }
548: if (lien.getObjetsComp().size() == 0) {
549: System.out
550: .println("Attention, lien sans objet de comparaison");
551: continue;
552: }
553:
554: if (persistant)
555: DataSet.db.makePersistent(lien);
556: geomLien = new GM_Aggregate();
557: lien.setGeom(geomLien);
558:
559: objetsRef = new FT_FeatureCollection();
560: objetsRef.getElements().addAll(lien.getObjetsRef());
561: armRef = ARM.creeARMsurObjetsQuelconques(objetsRef);
562: // ajout des traits reliant les objets ref
563: itArcs = armRef.getPopArcs().getElements().iterator();
564: while (itArcs.hasNext()) {
565: arc = (Arc) itArcs.next();
566: geomLien.add(arc.getGeometrie());
567: }
568: // ajout des points centroides des objets ref
569: itNoeuds = armRef.getPopNoeuds().getElements().iterator();
570: while (itNoeuds.hasNext()) {
571: noeud = (Noeud) itNoeuds.next();
572: geomLien.add(noeud.getGeometrie());
573: }
574:
575: objetsComp = new FT_FeatureCollection();
576: objetsComp.getElements().addAll(lien.getObjetsComp());
577: armComp = ARM.creeARMsurObjetsQuelconques(objetsComp);
578: // ajout des traits reliant les objets ref
579: itArcs = armComp.getPopArcs().getElements().iterator();
580: while (itArcs.hasNext()) {
581: arc = (Arc) itArcs.next();
582: geomLien.add(arc.getGeometrie());
583: }
584: // ajout des points centroides des objets ref
585: itNoeuds = armComp.getPopNoeuds().getElements().iterator();
586: while (itNoeuds.hasNext()) {
587: noeud = (Noeud) itNoeuds.next();
588: geomLien.add(noeud.getGeometrie());
589: }
590:
591: //ajout des traits reliant les objets comp au point d'accroche ref
592: pointAccrocheRef = ((Noeud) armRef.getPopNoeuds()
593: .getElements().get(0)).getGeometrie();
594: itObjetsComp = lien.getObjetsComp().iterator();
595: while (itObjetsComp.hasNext()) {
596: objetComp = (FT_Feature) itObjetsComp.next();
597: pointAccrocheComp = (GM_Point) objetComp.getGeom()
598: .centroid();
599: if (pointAccrocheComp == null)
600: continue;
601: GM_LineString trait = new GM_LineString();
602: trait.addControlPoint(pointAccrocheRef.getPosition());
603: trait.addControlPoint(pointAccrocheComp.getPosition());
604: geomLien.add(trait);
605: // pour faire joli :
606: //Vecteur V = new Vecteur();
607: //V.setX(0.1);V.setY(0);
608: //geomLien.add(V.translate(trait));
609: }
610:
611: }
612: if (persistant) {
613: System.out.println("-- Stockage: commit: "
614: + new Time(System.currentTimeMillis()));
615: DataSet.db.commit();
616: }
617: }
618:
619: }
|