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.geomprim;
028:
029: import fr.ign.cogit.geoxygene.spatial.coordgeom.DirectPositionList;
030: import fr.ign.cogit.geoxygene.spatial.coordgeom.GM_Polygon;
031:
032: //import datatools.Geodatabase;
033:
034: /**
035: * Surface orient�e. A de l'int�r�t pour traiter les trous : un trou est une surface orient�e n�gativement.
036: * A aussi de l'int�r�t en 3D.
037: * Une surface orient�e positivement � sa fronti�re dans le sens direct (la surface est � gauche de la fronti�re).
038: * Une surface orient�e n�gativement � sa fronti�re dans le sens des aiguilles d'une montre (la surface est � droite de la fronti�re).
039: * En 3D, on peut repr�senter un vecteur normal � la surface avec la r�gle du tire-bouchon.
040: * Si l'orientation est +1, alors self est une GM_Surface, de primitive elle-m�me.
041: * Si l'orientation est -1, alors self est une GM_OrientableSurface, de primitive une GM_Surface renvers�e par rapport � la surface positive.
042: *
043: * @author Thierry Badard & Arnaud Braun
044: * @version 1.0
045: *
046: */
047:
048: public class GM_OrientableSurface extends GM_OrientablePrimitive {
049:
050: /** Primitive */
051: public GM_Surface primitive;
052:
053: /** Renvoie la primitive de self */
054: public GM_Surface getPrimitive() {
055: return this .primitive;
056: }
057:
058: /** Attribut stockant les primitives orient�es de cette primitive.
059: * Proxy[0] est celle orient�e positivement.
060: * Proxy[1] est celle orient�e n�gativement.
061: * On acc�de aux primitives orient�es par getPositive() et getNegative(). */
062: public GM_OrientableSurface[] proxy = new GM_OrientableSurface[2];
063:
064: /** Renvoie la primitive orient�e positivement correspondant � self. */
065: public GM_OrientableSurface getPositive() {
066: return proxy[0];
067: }
068:
069: /** Renvoie la primitive orient�e n�gativement correspondant � self. */
070: // on recalcule en dynamique la primitive de la primitive orientee negativement, qui est "renversee"
071: // par rapport a la primitive orientee positivement.
072: public GM_OrientableSurface getNegative() {
073: GM_Surface proxy1prim = (GM_Surface) proxy[1].primitive;
074: proxy1prim.getPatch().clear();
075: GM_Surface proxy0 = (GM_Surface) proxy[1].proxy[0];
076: int n = proxy0.sizePatch();
077: if (n > 0)
078: for (int i = 0; i < n; i++)
079: proxy1prim.addPatch(proxy0.getPatch(n - 1 - i)
080: .reverse());
081: return proxy[1];
082: }
083:
084: /** Red�finition de l'op�rateur "boundary" sur GM_Object. Renvoie une GM_SurfaceBoundary, c'est-�-dire un GM_Ring pour
085: * repr�senter l'ext�rieur, et �ventuellement des GM_Ring pour repr�senter les trous.
086: * ATTENTION ne fonctionne que pour les surfaces compos�es d'un seul patch, qui est un polygone. */
087: public GM_SurfaceBoundary boundary() {
088: GM_Surface s = (GM_Surface) this .getPrimitive();
089: int n = s.sizePatch();
090: if (n == 1) {
091: GM_Polygon poly = (GM_Polygon) s.getPatch(0);
092: GM_SurfaceBoundary bdy = new GM_SurfaceBoundary();
093: bdy.exterior = poly.getExterior();
094: bdy.interior = poly.getInterior();
095: return bdy;
096: } else {
097: System.out
098: .println("GM_OrientableSurface::boundary() : cette m�thode ne fonctionne que pour les surfaces compos�es d'un et d'un seul patch.");
099: return null;
100: }
101: }
102:
103: /** EXPERIMENTAL. M�thode "boundary" � utiliser dans le cas des surfaces en plusieurs morceaux
104: * En effet, dans ce cas, on fait appel � Oracle, d'o� le param�tre data. */
105: // A REVOIR : valeur de la tol�rance.
106: /* public GM_SurfaceBoundary boundary(Geodatabase data) throws Exception {
107: GM_Surface s = (GM_Surface)this.getPrimitive();
108: int n = s.sizePatch();
109: if (n == 1) {
110: GM_Polygon poly = (GM_Polygon)s.getPatch(0);
111: GM_SurfaceBoundary bdy = new GM_SurfaceBoundary();
112: bdy.exterior = poly.getExterior();
113: bdy.interior = poly.getInterior();
114: return bdy;
115: }
116: else if (n == 0) {
117: System.out.println("GM_OrientableSurface::boundary() : la surface est vide ");
118: return null;
119: }
120: else {
121: // Dans le cas des polygones composes de plusieurs patchs, on va utiliser Oracle pour calculer la frontiere
122: // On convertit les patchs en surface et on va en calculer l'union.
123: // Puis on renvoie la frontiere de cette union.
124: GM_Surface union = new GM_Surface(((GM_Surface)this.getPrimitive()).getPatch(0));
125: for (int i=1; i<n; i++) {
126: GM_Surface surf = new GM_Surface(((GM_Surface)this.getPrimitive()).getPatch(i));
127: union = (GM_Surface)union.union(data,0.0000000001,surf);
128: }
129: return union.boundary();
130: }
131: }*/
132:
133: /** Renvoie les coordonnees de la primitive. */
134: public DirectPositionList coord() {
135: return getPrimitive().coord();
136: }
137:
138: }
|