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;
028:
029: import java.util.ArrayList;
030: import java.util.Iterator;
031: import java.util.List;
032:
033: import fr.ign.cogit.geoxygene.contrib.geometrie.Distances;
034: import fr.ign.cogit.geoxygene.contrib.geometrie.Operateurs;
035: import fr.ign.cogit.geoxygene.feature.FT_Feature;
036: import fr.ign.cogit.geoxygene.spatial.coordgeom.DirectPosition;
037: import fr.ign.cogit.geoxygene.spatial.coordgeom.GM_LineString;
038: import fr.ign.cogit.geoxygene.spatial.geomaggr.GM_Aggregate;
039: import fr.ign.cogit.geoxygene.spatial.geomaggr.GM_MultiCurve;
040: import fr.ign.cogit.geoxygene.spatial.geomaggr.GM_MultiSurface;
041: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Point;
042: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Surface;
043: import fr.ign.cogit.geoxygene.spatial.geomroot.GM_Object;
044:
045: /**
046: * Resultat de l'appariement : lien entre des objets homologues de deux bases de données.
047: * Un lien a aussi une géométrie qui est sa représentation graphique.
048: *
049: * @author Mustiere / IGN Laboratoire COGIT
050: * @version 1.0
051: */
052:
053: public class Lien extends FT_Feature {
054:
055: /** Les objets d'une BD pointés par le lien */
056: protected List objetsRef = new ArrayList();
057:
058: public List getObjetsRef() {
059: return objetsRef;
060: }
061:
062: public void setObjetsRef(List liste) {
063: objetsRef = liste;
064: }
065:
066: public void addObjetRef(FT_Feature objet) {
067: objetsRef.add(objet);
068: }
069:
070: public void addObjetsRef(List objets) {
071: objetsRef.addAll(objets);
072: }
073:
074: /** Les objets de l'autre BD pointés par le lien */
075: protected List objetsComp = new ArrayList();
076:
077: public List getObjetsComp() {
078: return objetsComp;
079: }
080:
081: public void setObjetsComp(List liste) {
082: objetsComp = liste;
083: }
084:
085: public void addObjetComp(FT_Feature objet) {
086: objetsComp.add(objet);
087: }
088:
089: public void addObjetsComp(List objets) {
090: objetsComp.addAll(objets);
091: }
092:
093: /** Estimation de la qualité du lien d'appariement.
094: * Entre 0 et 1 en général */
095: private double evaluation;
096:
097: public double getEvaluation() {
098: return evaluation;
099: }
100:
101: public void setEvaluation(double evaluation) {
102: this .evaluation = evaluation;
103: }
104:
105: /** Liste d'indicateurs utilisés pendant les calculs d'appariement */
106: protected List indicateurs = new ArrayList();
107:
108: public List getIndicateurs() {
109: return indicateurs;
110: }
111:
112: public void setIndicateurs(List liste) {
113: indicateurs = liste;
114: }
115:
116: public void addIndicateur(Object objet) {
117: indicateurs.add(objet);
118: }
119:
120: /** Texte libre pour décrire le lien d'appariement */
121: protected String commentaire = new String();
122:
123: public String getCommentaire() {
124: return commentaire;
125: }
126:
127: public void setCommentaire(String commentaire) {
128: this .commentaire = commentaire;
129: }
130:
131: /** Texte libre pour décrire le nom du procesus d'appariement. */
132: protected String nom = new String();
133:
134: public String getNom() {
135: return nom;
136: }
137:
138: public void setNom(String nom) {
139: this .nom = nom;
140: }
141:
142: /** Texte libre pour décrire le type d'appariement (ex. "Noeud-Noeud").*/
143: protected String type = new String();
144:
145: public String getType() {
146: return type;
147: }
148:
149: public void setType(String type) {
150: this .type = type;
151: }
152:
153: /** Texte libre pour décrire les objets de la BD1 pointés. */
154: protected String reference = new String();
155:
156: public String getReference() {
157: return reference;
158: }
159:
160: public void setReference(String reference) {
161: this .reference = reference;
162: }
163:
164: /** Texte libre pour décrire les objets de la BD2 pointés.*/
165: protected String comparaison = new String();
166:
167: public String getComparaison() {
168: return comparaison;
169: }
170:
171: public void setComparaison(String comparaison) {
172: this .comparaison = comparaison;
173: }
174:
175: //////////////////////////////////////////////////////
176: // Methodes utiles à la manipulation des liens
177: //////////////////////////////////////////////////////
178:
179: //////////////////////////////////////////////////////
180: // POUR TOUS LES LIENS
181: //////////////////////////////////////////////////////
182: /** recopie les valeurs de lienACopier dans this
183: */
184: public void copie(Lien lienACopier) {
185: this .setObjetsComp(lienACopier.getObjetsComp());
186: this .setObjetsRef(lienACopier.getObjetsRef());
187: this .setEvaluation(lienACopier.getEvaluation());
188: this .setGeom(lienACopier.getGeom());
189: this .setIndicateurs(lienACopier.getIndicateurs());
190: this .setCorrespondants(lienACopier.getCorrespondants());
191: this .setCommentaire(lienACopier.getCommentaire());
192: this .setNom(lienACopier.getNom());
193: this .setType(lienACopier.getType());
194: this .setReference(lienACopier.getReference());
195: this .setComparaison(lienACopier.getComparaison());
196: }
197:
198: ///////////////////////////////////////////
199: // Pour calcul de la géométrie des liens
200: ///////////////////////////////////////////
201:
202: //////////////////////////////////////////////////////////////
203: //////////////////////////////////////////////////////////////
204: // ATTENTION
205: //
206: // LES CODES CI-DESSOUS PERMETTENT DE CREER DES GEOMETRIES
207: // COMPLEXES QUI...
208: // 1/ SONT UTILES POUR AVOIR UNE REPRESENTATION FINE
209: // 2/ MAIS NE SONT PAS TRES BLINDEES (code en cours d'affinage)
210: //
211: // A UTILSER AVEC PRECAUTION DONC
212: //////////////////////////////////////////////////////////////
213: //////////////////////////////////////////////////////////////
214:
215: /** Définit des petits tirets entre 2 lignes pour représenter un lien d'appariement */
216: public static GM_MultiCurve tirets(GM_LineString LS1,
217: GM_LineString LS2, double pas) {
218: double long1, long2;
219: int nb_tirets;
220: GM_MultiCurve tirets = new GM_MultiCurve();
221: GM_LineString tiret;
222: DirectPosition pt1, pt2;
223: int i;
224:
225: long1 = LS1.length();
226: long2 = LS2.length();
227: nb_tirets = (int) (long1 / pas);
228: for (i = 0; i <= nb_tirets; i++) {
229: tiret = new GM_LineString();
230: pt1 = Operateurs.pointEnAbscisseCurviligne(LS1, i * pas);
231: pt2 = Operateurs.pointEnAbscisseCurviligne(LS2, i * pas
232: * long2 / long1);
233: if (pt1 == null || pt2 == null)
234: continue;
235: tiret.addControlPoint(pt1);
236: tiret.addControlPoint(pt2);
237: tirets.add(tiret);
238: }
239: return tirets;
240: }
241:
242: /** Définit des petits tirets entre 1 ligne et un point pour représenter un lien d'appariement */
243: public static GM_MultiCurve tirets(GM_LineString LS1, GM_Point PT,
244: double pas) {
245: double long1;
246: int nb_tirets;
247: GM_MultiCurve tirets = new GM_MultiCurve();
248: GM_LineString tiret;
249: DirectPosition pt1, pt2;
250: int i;
251:
252: long1 = LS1.length();
253: nb_tirets = (int) (long1 / pas);
254: for (i = 0; i <= nb_tirets; i++) {
255: tiret = new GM_LineString();
256: pt1 = Operateurs.pointEnAbscisseCurviligne(LS1, i * pas);
257: pt2 = PT.getPosition();
258: if (pt1 == null || pt2 == null)
259: continue;
260: tiret.addControlPoint(pt1);
261: tiret.addControlPoint(pt2);
262: tirets.add(tiret);
263: }
264: return tirets;
265: }
266:
267: /** Définit la géométrie d'un lien entre 2 lignes par un trait reliant les milieux des lignes */
268: public static GM_LineString tiret(GM_LineString LS1,
269: GM_LineString LS2) {
270: GM_LineString tiret = new GM_LineString();
271: tiret.addControlPoint(Operateurs.milieu(LS1));
272: tiret.addControlPoint(Operateurs.milieu(LS2));
273: return tiret;
274: }
275:
276: /** Définit la géométrie d'un lien entre 1 ligne et un point par un trait
277: * reliant le milieu de la ligne au point */
278: public static GM_LineString tiret(GM_LineString LS1, GM_Point PT) {
279: GM_LineString tiret = new GM_LineString();
280: tiret.addControlPoint(Operateurs.milieu(LS1));
281: tiret.addControlPoint(PT.getPosition());
282: return tiret;
283: }
284:
285: /** Définit des petits tirets entre 2 lignes pour représenter un lien d'appariement.
286: * NB: projete les points sur l'arc LS2, plutot que de se baser sur l'abscisse curviligne */
287: public static GM_MultiCurve tiretsProjetes(GM_LineString LS1,
288: GM_LineString LS2, double pas) {
289: double long1;
290: int nb_tirets;
291: GM_MultiCurve tirets = new GM_MultiCurve();
292: GM_LineString tiret;
293: DirectPosition pt1, pt2;
294: int i;
295:
296: long1 = LS1.length();
297: nb_tirets = (int) (long1 / pas);
298: for (i = 0; i <= nb_tirets; i++) {
299: tiret = new GM_LineString();
300: pt1 = Operateurs.pointEnAbscisseCurviligne(LS1, i * pas);
301: pt2 = Operateurs.projection(pt1, LS2);
302: if (pt1 == null || pt2 == null)
303: continue;
304: tiret.addControlPoint(pt1);
305: tiret.addControlPoint(pt2);
306: tirets.add(tiret);
307: }
308: return tirets;
309: }
310:
311: /** Définit des petits tirets entre 1 ligne et un aggregat pour représenter un lien d'appariement.
312: * NB: projete les points sur l'aggregat, plutot que de se baser sur l'abscisse curviligne */
313: public static GM_MultiCurve tiretsProjetes(GM_LineString LS1,
314: GM_Aggregate aggregat, double pas) {
315: double long1;
316: int nb_tirets;
317: GM_MultiCurve tirets = new GM_MultiCurve();
318: GM_LineString tiret;
319: DirectPosition pt1, pt2;
320: int i;
321:
322: long1 = LS1.length();
323: nb_tirets = (int) (long1 / pas);
324: for (i = 0; i <= nb_tirets; i++) {
325: tiret = new GM_LineString();
326: pt1 = Operateurs.pointEnAbscisseCurviligne(LS1, i * pas);
327: pt2 = Operateurs.projection(pt1, aggregat);
328: if (pt1 == null || pt2 == null)
329: continue;
330: tiret.addControlPoint(pt1);
331: tiret.addControlPoint(pt2);
332: tirets.add(tiret);
333: }
334: return tirets;
335: }
336:
337: /** Définit la géométrie d'un lien entre 2 lignes par un trait reliant les lignes */
338: public static GM_LineString tiretProjete(GM_LineString LS1,
339: GM_LineString LS2) {
340: DirectPosition milieu = Operateurs.milieu(LS1);
341: DirectPosition projete = Operateurs.projection(milieu, LS2);
342: GM_LineString tiret = new GM_LineString();
343: tiret.addControlPoint(milieu);
344: tiret.addControlPoint(projete);
345: return tiret;
346: }
347:
348: /** Définit la géométrie d'un lien entre 2 lignes par un trait reliant la ligne à l'aggregat */
349: public static GM_LineString tiretProjete(GM_LineString LS1,
350: GM_Aggregate aggegat) {
351: DirectPosition milieu = Operateurs.milieu(LS1);
352: DirectPosition projete = Operateurs.projection(milieu, aggegat);
353: GM_LineString tiret = new GM_LineString();
354: tiret.addControlPoint(milieu);
355: tiret.addControlPoint(projete);
356: return tiret;
357: }
358:
359: /** Définit la géométrie d'un lien entre 1 point et son projeté sur la ligne */
360: public static GM_LineString tiretProjete(GM_Point PT,
361: GM_LineString LS2) {
362: DirectPosition pt = PT.getPosition();
363: DirectPosition projete = Operateurs.projection(pt, LS2);
364: GM_LineString tiret = new GM_LineString();
365: tiret.addControlPoint(pt);
366: tiret.addControlPoint(projete);
367: return tiret;
368: }
369:
370: /** Définit la géométrie d'un lien entre 1 point et son projeté sur l'aggregat */
371: public static GM_LineString tiretProjete(GM_Point PT,
372: GM_Aggregate aggregat) {
373: DirectPosition pt = PT.getPosition();
374: DirectPosition projete = Operateurs.projection(pt, aggregat);
375: GM_LineString tiret = new GM_LineString();
376: tiret.addControlPoint(pt);
377: tiret.addControlPoint(projete);
378: return tiret;
379: }
380:
381: /** Affecte une géométrie au lien.
382: * Cette géométrie est principalement adaptée au cas de l'appariement de réseaux.
383: * Attention: peut laisser une geometrie nullle si on ne pointe vers rien (cas des noeuds souvent).
384: *
385: * @param tirets
386: * true: crée des petits traits régulièrement espacés pour relier les arcs;
387: * false: ne crée pour chaque arc qu'un seul trait reliant le milieu de l'arc.
388: *
389: * @param pas
390: * L'écart entre les tirets, le cas échéant
391: * */
392: public void setGeometrieReseaux(boolean tirets, double pas) {
393: Iterator itObjRef, itObjComp;
394: GM_Object geomRef = null, geomComp = null;
395: boolean refPoint;
396: GM_Aggregate geomLien, groupe;
397: GM_Object buffer;
398: GM_Point centroide;
399: GM_LineString ligne;
400: GM_MultiCurve lignes;
401:
402: geomLien = new GM_Aggregate();
403: itObjRef = this .getObjetsRef().iterator();
404: while (itObjRef.hasNext()) {
405: // determination du coté ref
406: geomRef = ((FT_Feature) itObjRef.next()).getGeom();
407: if (geomRef instanceof GM_Point)
408: refPoint = true;
409: else {
410: if (geomRef instanceof GM_LineString)
411: refPoint = false;
412: else {
413: System.out
414: .println("Géométrie réseau: Type de géométrie non géré "
415: + geomRef.getClass());
416: continue;
417: }
418: }
419:
420: // cas "1 noeud ref --> d'autres choses": 1 tiret + 1 buffer
421: if (refPoint) {
422: groupe = new GM_Aggregate();
423: itObjComp = this .getObjetsComp().iterator();
424: while (itObjComp.hasNext()) {
425: // determination du coté comp
426: geomComp = ((FT_Feature) itObjComp.next())
427: .getGeom();
428: groupe.add(geomComp);
429: }
430: buffer = groupe.buffer(20);
431: centroide = (GM_Point) buffer.centroid();
432: ligne = new GM_LineString();
433: ligne.addControlPoint(centroide.getPosition());
434: ligne.addControlPoint(((GM_Point) geomRef)
435: .getPosition());
436: geomLien.add(buffer);
437: geomLien.add(ligne);
438: continue;
439: }
440:
441: // cas "1 arc ref --> d'autres choses": des tirets
442: GM_Aggregate aggr = new GM_Aggregate();
443: itObjComp = this .getObjetsComp().iterator();
444: while (itObjComp.hasNext()) {
445: // determination du coté comp
446: geomComp = ((FT_Feature) itObjComp.next()).getGeom();
447: aggr.add(geomComp);
448: }
449: if (tirets) {
450: lignes = tiretsProjetes((GM_LineString) geomRef, aggr,
451: pas);
452: geomLien.add(lignes);
453: } else {
454: ligne = tiretProjete((GM_LineString) geomRef, aggr);
455: geomLien.add(ligne);
456: }
457: }
458: if (geomLien.size() != 0)
459: this .setGeom(geomLien);
460: }
461:
462: //////////////////////////////////////////////////////
463: // POUR LES LIENS VERS DES SURFACES
464: //////////////////////////////////////////////////////
465: /** Distance surfacique entre les surfaces du lien ;
466: * Methode UNIQUEMENT valable pour des liens pointant vers 1 ou n
467: * objets ref et com avec une géométrie SURFACIQUE.
468: */
469: public double distanceSurfaciqueRobuste() {
470: GM_MultiSurface geomRef = new GM_MultiSurface();
471: GM_MultiSurface geomComp = new GM_MultiSurface();
472: FT_Feature obj;
473: GM_Object geometrie;
474: Iterator it;
475:
476: it = this .getObjetsRef().iterator();
477: while (it.hasNext()) {
478: obj = (FT_Feature) it.next();
479: geometrie = (GM_Object) obj.getGeom();
480: if (!(geometrie instanceof GM_Surface))
481: return 2;
482: geomRef.add(geometrie);
483: }
484: it = this .getObjetsComp().iterator();
485: while (it.hasNext()) {
486: obj = (FT_Feature) it.next();
487: geometrie = (GM_Object) obj.getGeom();
488: if (!(geometrie instanceof GM_Surface))
489: return 2;
490: geomComp.add(geometrie);
491: }
492:
493: return Distances.distanceSurfaciqueRobuste(geomRef, geomComp);
494: }
495:
496: /** Exactitude (définie par Atef) entre les surfaces du lien ;
497: * Methode UNIQUEMENT valable pour des liens pointant vers 1 ou n
498: * objets ref et com avec une géométrie SURFACIQUE.
499: */
500: public double exactitude() {
501: GM_MultiSurface geomRef = new GM_MultiSurface();
502: GM_MultiSurface geomComp = new GM_MultiSurface();
503: FT_Feature obj;
504: GM_Object geometrie;
505: Iterator it;
506:
507: it = this .getObjetsRef().iterator();
508: while (it.hasNext()) {
509: obj = (FT_Feature) it.next();
510: geometrie = (GM_Object) obj.getGeom();
511: if (!(geometrie instanceof GM_Surface))
512: return 2;
513: geomRef.add(geometrie);
514: }
515: it = this .getObjetsComp().iterator();
516: while (it.hasNext()) {
517: obj = (FT_Feature) it.next();
518: geometrie = (GM_Object) obj.getGeom();
519: if (!(geometrie instanceof GM_Surface))
520: return 2;
521: geomComp.add(geometrie);
522: }
523:
524: return Distances.exactitude(geomRef, geomComp);
525: }
526:
527: /** Exactitude (définie par Atef) entre les surfaces du lien ;
528: * Methode UNIQUEMENT valable pour des liens pointant vers 1 ou n
529: * objets ref et com avec une géométrie SURFACIQUE.
530: */
531: public double completude() {
532: GM_MultiSurface geomRef = new GM_MultiSurface();
533: GM_MultiSurface geomComp = new GM_MultiSurface();
534: FT_Feature obj;
535: GM_Object geometrie;
536: Iterator it;
537:
538: it = this .getObjetsRef().iterator();
539: while (it.hasNext()) {
540: obj = (FT_Feature) it.next();
541: geometrie = (GM_Object) obj.getGeom();
542: if (!(geometrie instanceof GM_Surface))
543: return 2;
544: geomRef.add(geometrie);
545: }
546: it = this .getObjetsComp().iterator();
547: while (it.hasNext()) {
548: obj = (FT_Feature) it.next();
549: geometrie = (GM_Object) obj.getGeom();
550: if (!(geometrie instanceof GM_Surface))
551: return 2;
552: geomComp.add(geometrie);
553: }
554:
555: return Distances.exactitude(geomRef, geomComp);
556: }
557:
558: }
|