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.example;
028:
029: import fr.ign.cogit.geoxygene.datatools.Geodatabase;
030: import fr.ign.cogit.geoxygene.datatools.ojb.GeodatabaseOjbFactory;
031: import fr.ign.cogit.geoxygene.feature.FT_Feature;
032: import fr.ign.cogit.geoxygene.spatial.coordgeom.GM_LineString;
033: import fr.ign.cogit.geoxygene.spatial.geomcomp.GM_CompositeCurve;
034: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Curve;
035: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_CurveBoundary;
036: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_OrientableCurve;
037: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Primitive;
038: import fr.ign.cogit.geoxygene.spatial.geomprim.GM_Ring;
039:
040: /**
041: * Utilisation du package spatial pour les primitives linéaires : Exemple de code.
042: * On suppose qu'il existe une classe persistante "donnees.defaut.Troncon_route"
043: * (sinon changer le nom de la classe dans le code).
044: *
045: * @author Thierry Badard & Arnaud Braun
046: * @version 1.1
047: *
048: */
049:
050: public class TestGeomCurve {
051:
052: /* Attributs */
053: private Geodatabase db;
054: private Class tronconClass; // classe de troncons
055: private String nomClasse = "geoxygene.geodata.Troncon_route"; // nom de la classe a charger
056: int identifiant1 = 50736; // identifiant de l'objet qu'on va charger
057: int identifiant2 = 50717; // identifiant pour former une composite curve
058: int identifiant3 = 50716; // identifiant pour former une composite curve
059: int identifiant4 = 50724; // identifiant pour former une composite curve
060:
061: /* Creates new GeomCurve */
062: public TestGeomCurve() {
063: db = GeodatabaseOjbFactory.newInstance();
064: try {
065: tronconClass = Class.forName(nomClasse);
066: } catch (ClassNotFoundException e) {
067: System.out.println(nomClasse + " : non trouvee");
068: System.exit(0);
069: }
070: }
071:
072: /* Methode main */
073: public static void main(String args[]) {
074:
075: TestGeomCurve test = new TestGeomCurve();
076:
077: test.testOrientation();
078: test.testBoundary();
079: test.testComposite();
080:
081: }
082:
083: /* Amusons nous avec les notions de courbes orientees et de primitive */
084: public void testOrientation() {
085:
086: /////////////////////////////////////////////////////////////////////////////////////////////
087: // Pour bien comprendre ce qui suit :
088: // GM_Curve herite de GM_OrientableCurve, qui herite de GM_OrientablePrimitive (abstrait), qui herite de GM_Primitive (abstrait).
089: // Une primitive possede 2 primitives orientees (+1 et -1) auxquelles on accede par
090: // getPositive() (pour avoir celle orientee positivement) et getNegative(pour avoir celle orientee negativement).
091: // Soit oriPrim une primitive orientee. On a les proprietes suivantes :
092: // oriPrim.getOrientation() = +1 => oriPrim.getPositive() = oriPrim.
093: // oriPrim.getOrientation() = -1 => oriPrim.getNegative() = oriPrim.
094: // oriPrim.getPositive().getNegative() = oriPrim.
095: // Une GM_Curve est PAR DEFINITION la primitive orientee positivement.
096: // Une GM_OrientableCurve orientee positivement EST une GM_Curve.
097: // Soit curve une GM_Curve. On a la propriete suivante : curve.getPositive() = curve.
098: // L'operateur getPrimitive() permet de recuperer la GM_Curve d'une courbe orientee.
099: // Soit curve une GM_Curve. On a la propriete suivante : curve.getPrimitive() = curve.
100: // Soit oriCurve une courbe orientee negativement construite avec curve.getNegative().
101: // Alors oriCurve.getPrimitive() renvoie une GM_Curve renversee par rapport a curve.
102: // Donc pour renverser une courbe, il faut faire : curve.getNegative().getPrimitive()
103: ///////////////////////////////////////////////////////////////////////////////////////////////
104:
105: // Declaration des variables
106: FT_Feature tron;
107: Integer gid;
108: GM_Curve curve;
109: GM_Primitive prim;
110: GM_OrientableCurve oriCurve;
111:
112: System.out.println("#### test orientation");
113:
114: // Debut d'une transaction
115: System.out.println("Debut transaction");
116: db.begin();
117:
118: // On charge un FT_Feature par son identifiant, avec OJB
119: // Remarque : l'identifiant doit etre de type Integer et non int
120: gid = new Integer(identifiant1);
121: tron = (FT_Feature) db.load(tronconClass, gid);
122: System.out.println("identifiant de l'objet charge : "
123: + tron.getId());
124:
125: // Examinons la geometrie du FT_Feature
126: curve = (GM_Curve) tron.getGeom();
127: System.out.println(curve);
128: System.out.println("orientation : " + curve.getOrientation());
129: // l'orientation vaut +1 : c'est normal, c'est une GM_Curve
130:
131: // A SAVOIR : le "hashCode" est lie la place en memoire de l'objet.
132: // meme hashCode <==> meme objet
133:
134: // Examinons la primitive de la geometrie du FT_Feature
135: prim = curve.getPrimitive();
136: System.out.println("hash code de la courbe : "
137: + curve.hashCode());
138: System.out.println("hash code de la primitive : "
139: + prim.hashCode());
140: // curve et prim sont le meme objet : normal, car l'orientation est positive
141:
142: // Examinons la courbe orientee positivement a partir de curve
143: oriCurve = curve.getPositive();
144: System.out.println("nouvelle orientation : "
145: + oriCurve.getOrientation());
146: System.out
147: .println("hash code de la courbe orientee positivement : "
148: + oriCurve.hashCode());
149: //curve, prim, et oriCurve sont le meme objet : normal, car l'orientation est positive
150:
151: // Examinons la courbe orientee negativement a partir de curve
152: oriCurve = curve.getNegative();
153: System.out.println("nouvelle orientation : "
154: + oriCurve.getOrientation());
155: System.out
156: .println("hash code de la courbe orientee negativement : "
157: + oriCurve.hashCode());
158: // c'est un nouvel objet
159:
160: // Examinons la primitive de la courbe orientee negativement
161: prim = oriCurve.getPrimitive();
162: System.out.println("type de la primitive :"
163: + prim.getClass().getName());
164: curve = (GM_Curve) prim; // cast - on reutilise le nom de variable curve
165: System.out.println(curve);
166: // la primitive renvoie une courbe renversee par rapport a tout a l'heure
167: System.out
168: .println("hash code de la primitive de la courbe orientee negativement: "
169: + curve.hashCode());
170: // c'est un nouvel objet
171:
172: // Jouons avec la courbe orientee negativement oriCurve
173: // oriCurve etant deja orientee negativement, son "getNegative" renvoie le meme objet
174: System.out
175: .println("orientation de la courbe orientee negativement : "
176: + (oriCurve.getNegative()).getOrientation());
177: System.out
178: .println("hash code de la courbe orientee negativement : "
179: + (oriCurve.getNegative()).hashCode());
180:
181: // Oh miracle, le "getPositive" sur oriCurve renvoie le meme objet que la courbe initiale
182: // Donc : curve.getNegative().getPositive() = curve
183: System.out
184: .println("orientation de la courbe orientee positivement : "
185: + (oriCurve.getPositive()).getOrientation());
186: System.out
187: .println("hash code de la courbe orientee positivement : "
188: + (oriCurve.getPositive()).hashCode());
189:
190: // Jouons avec la primitive de la courbe orientee negativement (cette primitive s'appelle curve)
191: System.out.println("hash code de la primitive : "
192: + curve.hashCode()); // on l'a deja affiche plus haut
193: System.out
194: .println("hash code du getPositive() de la primitive : "
195: + curve.getPositive().hashCode()); // c'est le meme
196: System.out
197: .println("hash code du getNegative() de la primitive : "
198: + curve.getNegative().hashCode()); // c'est un nouvel objet
199: System.out
200: .println("hash code de la primitive du getNegative() de la primitive : "
201: + curve.getNegative().getPrimitive().hashCode());
202: // et voila, on retrouve encore la courbe initiale
203: // Donc : curve.getNegative().getPrimitive().getNegative().getPrimitive() = curve
204:
205: // Fin
206: System.out.println("Commit");
207: db.commit();
208:
209: }
210:
211: /* Amusons nous avec les frontieres */
212: public void testBoundary() {
213:
214: // Declaration des variables
215: FT_Feature tron;
216: Integer gid;
217: GM_Curve curve;
218: GM_OrientableCurve oriCurve;
219: GM_CurveBoundary curveBdy;
220:
221: System.out.println("#### test boundary");
222:
223: // Debut d'une transaction
224: System.out.println("Debut transaction");
225: db.begin();
226:
227: // On charge un FT_Feature et sa geometrie
228: gid = new Integer(identifiant1);
229: tron = (FT_Feature) db.load(tronconClass, gid);
230: System.out.println("identifiant de l'objet charge : "
231: + tron.getId());
232: curve = (GM_Curve) tron.getGeom();
233:
234: // Frontiere de la courbe en passant par GM_CurveBoundary
235: // l'operation "boundary" recupere un GM_CurveBoundary
236: // l'operation getEndPoint() et getStartPoint() recupere des GM_Point.
237: // Donc : on connait le CRS
238: curveBdy = curve.boundary();
239: System.out
240: .println("start point : " + curveBdy.getStartPoint());
241: System.out.println("end point : " + curveBdy.getEndPoint());
242: System.out.println("CRS du end point : "
243: + curveBdy.getEndPoint().getCRS());
244:
245: // Frontiere de la courbe en passant par startPoint() et endPoint()
246: // on recupere des DirectPosition
247: // Il n'y a pas de CRS a priori
248: System.out.println("start point : " + curve.startPoint());
249: System.out.println("end point : " + curve.endPoint());
250:
251: // Une petite experience...
252: // On change la valeur de la coordonnees Y du premier point de la courbe
253: double oldY = ((GM_LineString) curve.getSegment(0))
254: .getControlPoint(0).getY();
255: ((GM_LineString) curve.getSegment(0)).getControlPoint(0).setY(
256: 100000.0);
257: // On regarde
258: System.out.println("nouveau start point(Y) : "
259: + curveBdy.getStartPoint().getPosition().getY()); // ca n'a pas change
260: System.out.println("nouveau start point(Y) : "
261: + curve.startPoint().getY()); // ici, ca a change
262: // Pourquoi ? avec startPoint() on accede directement aux coordonnees,
263: // alors qu'avec "boundary" on a cree des nouveaux points "independants" des coordonnees de la courbe.
264: // Il faut donc rappeler la methode "boundary" pour repercuter le changement de coordonnees.
265: curveBdy = curve.boundary();
266: System.out.println("nouveau start point(Y) : "
267: + curveBdy.getStartPoint().getPosition().getY()); // OK maintenant
268:
269: // on reaffecte l'ancienne valeur ...
270: ((GM_LineString) curve.getSegment(0)).getControlPoint(0).setY(
271: oldY);
272:
273: // Rejouons avec les courbes orientees
274: oriCurve = curve.getNegative();
275: // la methode "boundary()" s'applique sur GM_OrientableCurve (et donc aussi sur GM_Curve)
276: curveBdy = oriCurve.boundary();
277: System.out
278: .println("start point : " + curveBdy.getStartPoint());
279: System.out.println("end point : " + curveBdy.getEndPoint());
280: // startPoint() et endPoint() ne marche que sur GM_Curve (et pas GM_OrientableCurve) -> on passe par la primitive
281: curve = oriCurve.getPrimitive();
282: System.out.println("start point : " + curve.startPoint());
283: System.out.println("end point : " + curve.endPoint());
284:
285: // Commit
286: System.out.println("Commit");
287: db.commit();
288:
289: }
290:
291: /* Amusons nous avec les composite curves */
292: public void testComposite() {
293:
294: // Declaration des variables
295: FT_Feature tron;
296: Integer gid;
297: GM_Curve curve;
298: GM_Primitive prim;
299: GM_OrientableCurve oriCurve;
300: GM_CompositeCurve compCurve;
301: GM_CurveBoundary curveBdy;
302:
303: System.out.println("#### test composite");
304:
305: // on recupere la tolerance dans les metadonnees d'Oracle
306: // rigoureusement ici, on recupere la tolerance sur les X, on suppose que c'est la meme sur les Y
307: double tolerance = db.getMetadata(tronconClass).getTolerance(0);
308: System.out.println("tolerance : " + tolerance);
309:
310: // Debut d'une transaction
311: System.out.println("Debut transaction");
312: db.begin();
313:
314: // On charge un FT_Feature et sa geometrie
315: gid = new Integer(identifiant1);
316: tron = (FT_Feature) db.load(tronconClass, gid);
317: System.out.println("identifiant de l'objet charge : "
318: + tron.getId());
319: curve = (GM_Curve) tron.getGeom();
320: System.out.println(curve);
321:
322: // On cree une composite curve a partir d'une courbe orientee (positivement ou negativement)
323: //compCurve = new GM_CompositeCurve(curve.getNegative());
324: compCurve = new GM_CompositeCurve(curve);
325:
326: // On charge un FT_Feature et sa geometrie
327: gid = new Integer(identifiant2);
328: tron = (FT_Feature) db.load(tronconClass, gid);
329: System.out.println("identifiant de l'objet charge : "
330: + tron.getId());
331: curve = (GM_Curve) tron.getGeom();
332: System.out.println(curve);
333:
334: // On ajoute un element a la composite curve
335: //compCurve.appendGenerator(curve); // sans filet (pas de parametre "tolerance")
336: //compCurve.appendGenerator(curve,tolerance); // avec verification du chainage, mais sans retourner la courbe
337: // essayer en rompant le chainage pour voir.
338:
339: // proprement, il faut faire comme ceci :
340: // si ca chaine, on ajoute, sinon on ajoute l'oppose,
341: // sinon affiche un message et on continue sans avoir rien fait en affichant une exception
342: try {
343: compCurve.addGeneratorTry(curve, tolerance);
344: } catch (Exception e1) {
345: System.out.println(e1.getMessage());
346: }
347:
348: // On charge un FT_Feature et sa geometrie
349: gid = new Integer(identifiant3);
350: tron = (FT_Feature) db.load(tronconClass, gid);
351: System.out.println("identifiant de l'objet charge : "
352: + tron.getId());
353: curve = (GM_Curve) tron.getGeom();
354: System.out.println(curve);
355:
356: // On ajoute encore
357: try {
358: compCurve.addGeneratorTry(curve, tolerance);
359: } catch (Exception e1) {
360: System.out.println(e1.getMessage());
361: }
362:
363: // On charge un FT_Feature et sa geometrie
364: gid = new Integer(identifiant4);
365: tron = (FT_Feature) db.load(tronconClass, gid);
366: System.out.println("identifiant de l'objet charge : "
367: + tron.getId());
368: curve = (GM_Curve) tron.getGeom();
369: System.out.println(curve);
370:
371: // On ajoute encore
372: try {
373: compCurve.addGeneratorTry(curve, tolerance);
374: } catch (Exception e1) {
375: System.out.println(e1.getMessage());
376: }
377:
378: // Verifions que le chainage est OK
379: System.out.println("validate : "
380: + compCurve.validate(tolerance));
381:
382: // Examinons la frontiere
383: curveBdy = compCurve.boundary();
384: System.out
385: .println("start point : " + curveBdy.getStartPoint());
386: System.out.println("end point : " + curveBdy.getEndPoint());
387:
388: // Examinons la primitive
389: System.out
390: .println("nombre de composants de la composite curve : "
391: + compCurve.sizeGenerator());
392: curve = compCurve.getPrimitive();
393: System.out.println("hash code de la primitive : "
394: + curve.hashCode());
395: System.out.println(curve);
396: // on observe qu'il y a des doublon : la courbe est en fait constituee de plusieurs segments
397: //(corresondant aux courbes initiales)
398: System.out.println("nombre de segments de la primitive : "
399: + curve.sizeSegment());
400: // pour eliminer les doublons : caster en une seule linestring
401: GM_LineString theLinestring = curve.asLineString(0.0, 0.0,
402: tolerance);
403: System.out.println("linestring : ");
404: System.out.println(theLinestring);
405:
406: // Examinons les courbe orientees a partir de compCurve
407: oriCurve = compCurve.getPositive();
408: System.out
409: .println("hash code de la courbe orientee positivement : "
410: + oriCurve.hashCode()); // meme chose que la primitive
411: oriCurve = compCurve.getNegative();
412: System.out
413: .println("hash code de la courbe orientee negativement : "
414: + oriCurve.hashCode()); // nouvel objet
415: System.out.println(oriCurve.getPrimitive()); // courbe renversee par rapport a plus haut
416:
417: // Utilisons GM_Ring(anneau)
418: // constructeur a partir d'une compCurve - sans filet
419: // GM_Ring ring = new GM_Ring(compCurve);
420:
421: // constructeur a partir d'une compCurve - avec verification du chainage et de la fermeture
422: try {
423: GM_Ring ring = new GM_Ring(compCurve, tolerance);
424: System.out.println("validate ring :"
425: + ring.validate(tolerance));
426: } catch (Exception e) {
427: System.out.println(e.getMessage());
428: }
429:
430: // Commit
431: System.out.println("Commit");
432: db.commit();
433: }
434:
435: }
|