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.spatial.geomcomp;
028:
029: import java.util.ArrayList;
030: import java.util.List;
031:
032: import fr.ign.cogit.geoxygene.datatools.Geodatabase;
033: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_OrientableSurface;
034: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Surface;
035: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_SurfaceBoundary;
036:
037: /** NON UTILISE POUR LE MOMENT. A TERMINER ET TESTER.
038: * Complexe ayant toutes les propriétés géométriques d'une surface.
039: * C'est une liste de surfaces orientées (GM_OrientableSurfaces) contigues.
040: * Hérite de GM_OrientableCurve, mais le lien n'apparaît pas explicitement (problème de double héritage en java). Les méthodes et attributs ont été reportés.
041: *
042: * <P> ATTENTION : normalement, il faudrait remplir le set "element" (contrainte : toutes les primitives du generateur
043: * sont dans le complexe). Ceci n'est pas implémenté pour le moment.
044: * <P> A FAIRE AUSSI : iterateur sur "generator"
045: *
046: * @author Thierry Badard & Arnaud Braun
047: * @version 1.0
048: *
049: */
050:
051: public class GM_CompositeSurface extends GM_Composite {
052:
053: ////////////////////////////////////////////////////////////////////////
054: ////////////////////////////////////////////////////////////////////////
055: // Attribut "generator" et méthodes pour le traiter ////////////////////
056: ////////////////////////////////////////////////////////////////////////
057: ////////////////////////////////////////////////////////////////////////
058: /** Les GM_OrientableSurface constituant self. */
059: protected List generator;
060:
061: /** Renvoie la liste des GM_OrientableSurface */
062: public List getGenerator() {
063: return generator;
064: }
065:
066: /** Renvoie la GM_OrientableSurface de rang i */
067: public GM_OrientableSurface getGenerator(int i) {
068: return (GM_OrientableSurface) this .generator.get(i);
069: }
070:
071: /** Affecte une GM_OrientableSurface au rang i. Attention : aucun contrôle de continuité n'est effectué. */
072: public void setGenerator(int i, GM_OrientableSurface value) {
073: this .generator.set(i, value);
074: }
075:
076: /** Ajoute une GM_OrientableSurface en fin de liste. Attention : aucun contrôle de continuité n'est effectué. */
077: public void addGenerator(GM_OrientableSurface value) {
078: this .generator.add(value);
079: }
080:
081: /** A FAIRE.
082: * Ajoute une GM_OrientableSurface en fin de liste avec un contrôle de continuité avec la tolérance passée en paramètre.
083: * Envoie une exception en cas de problème. */
084: public void addGenerator(GM_OrientableSurface value,
085: double tolerance) throws Exception {
086: }
087:
088: /** A FAIRE.
089: * Ajoute une GM_OrientableSurface en fin de liste avec un contrôle de continuité avec la tolérance passée en paramètre.
090: * Eventuellement change le sens d'orientation de la surface pour assurer la continuite.
091: * Envoie une exception en cas de problème. */
092: public void addGeneratorTry(GM_OrientableSurface value,
093: double tolerance) throws Exception {
094: }
095:
096: /** Ajoute une GM_OrientableSurface au rang i. Attention : aucun contrôle de continuité n'est effectué. */
097: public void addGenerator(int i, GM_OrientableSurface value) {
098: this .generator.add(i, value);
099: }
100:
101: /** Efface la (ou les) GM_OrientableSurface passé en paramètre. Attention : aucun contrôle de continuité n'est effectué. */
102: public void removeGenerator(GM_OrientableSurface value)
103: throws Exception {
104: if (this .generator.size() == 1)
105: throw new Exception(
106: "Il n'y a qu'un objet dans l'association.");
107: else
108: this .generator.remove(value);
109: }
110:
111: /** Efface la GM_OrientableSurface de rang i. Attention : aucun contrôle de continuité n'est effectué. */
112: public void removeGenerator(int i) throws Exception {
113: if (this .generator.size() == 1)
114: throw new Exception(
115: "Il n'y a qu'un objet dans l'association.");
116: else
117: this .generator.remove(i);
118: }
119:
120: /** Nombre de GM_OrientableSurface constituant self */
121: public int sizeGenerator() {
122: return this .generator.size();
123: }
124:
125: ////////////////////////////////////////////////////////////////////////
126: ////////////////////////////////////////////////////////////////////////
127: // Constructeurs ///////////////////////////////////////////////////////
128: ////////////////////////////////////////////////////////////////////////
129: ////////////////////////////////////////////////////////////////////////
130: // les constructeurs sont calques sur ceux de GM_Surface
131: /** Constructeur par défaut */
132: public GM_CompositeSurface() {
133: generator = new ArrayList();
134: primitive = new GM_Surface();
135: proxy[0] = (GM_Surface) primitive;
136: GM_OrientableSurface proxy1 = new GM_OrientableSurface();
137: proxy1.orientation = -1;
138: proxy1.proxy[0] = (GM_Surface) primitive;
139: proxy1.proxy[1] = proxy1;
140: proxy1.primitive = new GM_Surface((GM_Surface) primitive);
141: proxy[1] = proxy1;
142: }
143:
144: /** Constructeur à partir d'une et d'une seule GM_OrientableSurface.
145: * L'orientation vaut +1. */
146: public GM_CompositeSurface(GM_OrientableSurface oCurve) {
147: generator = new ArrayList();
148: generator.add(oCurve);
149: primitive = new GM_Surface();
150: // this.simplifyPrimitive(); -> creer la primitive
151: proxy[0] = (GM_Surface) primitive;
152: GM_OrientableSurface proxy1 = new GM_OrientableSurface();
153: proxy1.orientation = -1;
154: proxy1.proxy[0] = (GM_Surface) primitive;
155: proxy1.proxy[1] = proxy1;
156: proxy1.primitive = new GM_Surface((GM_Surface) primitive);
157: proxy[1] = proxy1;
158: }
159:
160: ////////////////////////////////////////////////////////////////////////
161: ////////////////////////////////////////////////////////////////////////
162: // Attributs et méthodes héritées de GM_OrientableSurface ////////////////
163: ////////////////////////////////////////////////////////////////////////
164: ////////////////////////////////////////////////////////////////////////
165: // On simule l'heritage du modele en reportant les attributs et methodes
166: // de GM_OrientableSurface
167: // On n'a pas repris l'attribut "orientation" qui ne sert a rien ici.
168:
169: /** Primitive. Elle doit etre recalculée à chaque modification de self : fait dans getPrimitive(). */
170: protected GM_Surface primitive;
171:
172: /** Renvoie la primitive de self. */
173: // le calcul est fait en dynamique dans la methode privee simplifyPrimitve.
174: public GM_Surface getPrimitive(Geodatabase data) {
175: this .simplifyPrimitive(data);
176: return this .primitive;
177: }
178:
179: /**
180: * Attribut stockant les primitives orientées de cette primitive.
181: * Proxy[0] est celle orientée positivement.
182: * Proxy[1] est celle orientée négativement.
183: * On accède aux primitives orientées par getPositive() et getNegative().
184: */
185: protected GM_OrientableSurface[] proxy = new GM_OrientableSurface[2];
186:
187: /** Renvoie la primitive orientée positivement. */
188: public GM_OrientableSurface getPositive(Geodatabase data) {
189: this .simplifyPrimitive(data);
190: return this .primitive; // equivaut a return this.proxy[0]
191: }
192:
193: /** Renvoie la primitive orientée négativement. */
194: public GM_OrientableSurface getNegative(Geodatabase data) {
195: this .simplifyPrimitive(data);
196: return this .primitive.getNegative();
197: }
198:
199: /** Redéfinition de l'opérateur "boundary" sur GM_OrientableSurface. Renvoie une GM_SurfaceBoundary. */
200: public GM_SurfaceBoundary boundary(Geodatabase data) {
201: this .simplifyPrimitive(data);
202: return this .primitive.boundary();
203: }
204:
205: ////////////////////////////////////////////////////////////////////////
206: ////////////////////////////////////////////////////////////////////////
207: // Méthodes "validate" /////////////////////////////////////////////////
208: ////////////////////////////////////////////////////////////////////////
209: ////////////////////////////////////////////////////////////////////////
210: // cette méthode n'est pas dans la norme.
211: /** A FAIRE - renvoie toujours true pour le moment.
212: * Vérifie la continuité des composants. Renvoie TRUE s'ils sont contigus, FALSE sinon. */
213: public boolean validate(double tolerance) {
214: /* for (int i=0; i<generator.size()-1; i++) {
215: GM_OrientableCurve oCurve1 = (GM_OrientableCurve)generator.get(i);
216: GM_Curve prim1 = (GM_Curve)oCurve1.getPrimitive();
217: GM_OrientableCurve oCurve2 = (GM_OrientableCurve)generator.get(i+1);
218: GM_Curve prim2 = (GM_Curve)oCurve2.getPrimitive();
219: DirectPosition pt1 = prim1.endPoint();
220: DirectPosition pt2 = prim2.startPoint();
221: if (!pt1.equals(pt2,tolerance))
222: return false;
223: }*/
224: return true;
225: }
226:
227: ////////////////////////////////////////////////////////////////////////
228: ////////////////////////////////////////////////////////////////////////
229: // Méthodes privées pour usage interne /////////////////////////////////
230: ////////////////////////////////////////////////////////////////////////
231: ////////////////////////////////////////////////////////////////////////
232: /** Calcule la primitive se self. MARCHE PAS*/
233: private void simplifyPrimitive(Geodatabase data) {
234: /* int n = generator.size();
235: if (n > 1) {
236: GM_Surface prim = (GM_Surface)this.primitive;
237: prim = this.getGenerator(0);
238: // clonage de la primitive
239: GM_Surface union = new GM_Surface();
240: for (int i=0; i<prim.cardPatch(); i++)
241: union.appendPatch(prim.getPatch(i));
242:
243: union = prim;
244: for (int i=1; i<n; i++) {
245: GM_Surface surf = new GM_Surface(((GM_Surface)this.getGenerator(i)).getPrimitive());
246: union = (GM_Surface)union.union(data,0.0000000001,surf);
247: }
248: }*/
249: }
250:
251: }
|