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.feature;
028:
029: import java.util.ArrayList;
030: import java.util.Iterator;
031: import java.util.List;
032:
033: import fr.ign.cogit.geoxygene.spatial.geomroot.GM_Object;
034: import fr.ign.cogit.geoxygene.datatools.Geodatabase;
035:
036: /** Classe mère pour tout jeu de données.
037: * Un DataSet peut par exemple correspondre à une zone d'une BD, ou seulement un thème.
038: * Un DataSet est constitué de manière récursive d'un ensemble de jeux de données,
039: * et d'un ensemble de populations, elles mêmes constituées d'un ensemble d'éléments.
040: *
041: * @author Sébastien Mustière
042: * @version 1.1
043: *
044: * 9.02.2006 : extension de la méthode chargeExtractionThematiqueEtSpatiale (grosso)
045: *
046: */
047:
048: public class DataSet {
049:
050: protected int id;
051:
052: /** Renvoie l'identifiant */
053: public int getId() {
054: return id;
055: }
056:
057: /** Affecte un identifiant. */
058: public void setId(int Id) {
059: id = Id;
060: }
061:
062: /** Paramètre statique de connexion à la BD */
063: public static Geodatabase db;
064:
065: ///////////////////////////////////////////////////////
066: // Constructeurs / Chargement / persistance
067: ///////////////////////////////////////////////////////
068:
069: /** Constructeur par défaut. */
070: public DataSet() {
071: this .ojbConcreteClass = this .getClass().getName();
072: }
073:
074: /** Constructeur par défaut, recopiant les champs de métadonnées du DataSet en paramètre sur le nouveau */
075: public DataSet(DataSet DS) {
076: this .ojbConcreteClass = this .getClass().getName();
077: if (DS == null)
078: return;
079: this .setNom(DS.getNom());
080: this .setTypeBD(DS.getTypeBD());
081: this .setModele(DS.getModele());
082: this .setZone(DS.getZone());
083: this .setDate(DS.getDate());
084: this .setCommentaire(DS.getCommentaire());
085: }
086:
087: /** Chargement des instances des populations persistantes d'un jeu de données. */
088: public void chargeElements() {
089: if (!this .getPersistant()) {
090: System.out
091: .println("----- ATTENTION : Probleme au chargement du jeu de donnees "
092: + this .getNom());
093: System.out
094: .println("----- Impossible de charger les elements d'un jeu de donnees non persistant");
095: return;
096: }
097:
098: // chargement recursif des dataset composants this
099: Iterator itDS = this .getComposants().iterator();
100: while (itDS.hasNext()) {
101: DataSet DS = (DataSet) itDS.next();
102: if (DS.getPersistant())
103: DS.chargeElements();
104: }
105:
106: // chargement recursif des populations de this
107: System.out.println("");
108: System.out.println("###### Chargement des elements du DataSet "
109: + this .getNom());
110: Iterator itPop = this .getPopulations().iterator();
111: while (itPop.hasNext()) {
112: Population pop = (Population) itPop.next();
113: if (pop.getPersistant())
114: pop.chargeElements();
115: }
116: }
117:
118: /** Chargement des instances des populations persistantes d'un jeu de données qui
119: * intersectent une géométrie donnée (extraction géométrique). */
120: public void chargeElementsPartie(GM_Object geom) {
121: if (!this .getPersistant()) {
122: System.out
123: .println("----- ATTENTION : Probleme au chargement du jeu de donnees "
124: + this .getNom());
125: System.out
126: .println("----- Impossible de charger les elements d'un jeu de donnees non persistant");
127: return;
128: }
129: // chargement recursif des dataset composants this
130: Iterator itDS = this .getComposants().iterator();
131: while (itDS.hasNext()) {
132: DataSet DS = (DataSet) itDS.next();
133: if (DS.getPersistant())
134: DS.chargeElementsPartie(geom);
135: }
136:
137: // chargement recursif des populations de this
138: System.out.println("");
139: System.out.println("###### Chargement des elements du DataSet "
140: + this .getNom());
141: Iterator itPop = this .getPopulations().iterator();
142: while (itPop.hasNext()) {
143: Population pop = (Population) itPop.next();
144: if (pop.getPersistant())
145: pop.chargeElementsPartie(geom);
146: }
147: }
148:
149: /** Chargement des instances des populations persistantes d'un jeu de données qui
150: * intersectent une géométrie donnée.
151: * ATTENTION: les tables qui stockent les éléments doivent avoir été indexées dans Oracle.
152: * ATTENTION AGAIN: seules les populations avec une géométrie sont chargées.
153: */
154: public void chargeElementsPartie(Extraction zoneExtraction) {
155: chargeElementsPartie(zoneExtraction.getGeom());
156: }
157:
158: /**Méthode de chargement pour les test. Elle est un peu tordue
159: * dans le paramétrage mais permet de ne charger que ce qu'on veut.
160: * Elle permet de charger les instances des populations persistantes
161: * d'un jeu de données qui :
162: * - intersectent une géométrie donnée (extraction géométrique),
163: * - ET qui appartiennent à certains thèmes et populations précisés en entrée.
164: *
165: * @param geom : Définit la zone d'extraction.
166: *
167: * @param themes : Définit les sous-DS du DS à charger. Pour le DS lui-même,
168: * et pour chaque sous-DS, on précise également quelles populations
169: * sont chargées. Ce paramètre est une liste de liste de String
170: * composée comme suit (si la liste est nulle on charge tout) :
171: * 1/ Le premier élément est soit null (on charge alors toutes les populations
172: * directement sous le DS), soit une liste contenant les noms des populations
173: * directement sous le DS que l'on charge (si la liste est vide, on ne charge rien).
174: *
175: * 2/ Tous les autres éléments sont des listes (une pour chaque sous-DS) qui
176: * contiennent chacune d'abord le nom d'un sous-DS que l'on veut charger,
177: * puis soit rien d'autre si on charge toutes les populations du sous-DS,
178: * soit le nom des populations du sous-DS que l'on veut charger.
179: *
180: * NB: Attention aux majuscules et aux accents.
181: *
182: * EXEMPLE de parametre themes pour un DS repréentant la BDCarto, et
183: * spécifiant qu'on ne veut charger que les troncon et les noeud du thème
184: * routier, et les troncons du thème hydro, mais tout le thème ferré.
185: * theme = {null, liste1, liste2, liste3}, avec :
186: * - null car il n'y a pas de population directement sous le DS BDCarto,
187: * - liste1 = {"Routier", "Tronçons de route", "Noeuds routier"},
188: * - liste2 = {"Hydrographie", "Tronçons de cours d'eau"},
189: * - liste3 = {"Ferré"}.
190: *
191: */
192: public void chargeExtractionThematiqueEtSpatiale(GM_Object geom,
193: List themes) {
194: if (!this .getPersistant()) {
195: System.out
196: .println("----- ATTENTION : Probleme au chargement du jeu de donnees "
197: + this .getNom());
198: System.out
199: .println("----- Impossible de charger les elements d'un jeu de donnees non persistant");
200: return;
201: }
202:
203: List populationsACharger, themeACharger, extraitThemes;
204: Iterator itThemes, itPopulationsACharger;
205: String nom;
206: boolean aCharger;
207:
208: // chargement recursif des dataset composants this
209: Iterator itDS = this .getComposants().iterator();
210: while (itDS.hasNext()) {
211: DataSet DS = (DataSet) itDS.next();
212: populationsACharger = null;
213: if (themes == null)
214: aCharger = true;
215: else {
216: itThemes = themes.iterator();
217: themeACharger = (List) itThemes.next();
218: if (!itThemes.hasNext())
219: aCharger = true;
220: else {
221: aCharger = false;
222: while (itThemes.hasNext()) {
223: themeACharger = (List) itThemes.next();
224: if (DS.getNom().equals(themeACharger.get(0))) {
225: aCharger = true;
226: if (themeACharger.size() == 1) {
227: populationsACharger = null;
228: break;
229: }
230: extraitThemes = new ArrayList(themeACharger);
231: extraitThemes.remove(0);
232: populationsACharger = new ArrayList();
233: populationsACharger.add(extraitThemes);
234: break;
235: }
236: }
237: }
238: }
239: if (aCharger && DS.getPersistant())
240: DS.chargeExtractionThematiqueEtSpatiale(geom,
241: populationsACharger);
242: }
243:
244: // chargement des populations de this (directement sous this)
245: if (themes == null)
246: populationsACharger = null;
247: else {
248: itThemes = themes.iterator();
249: populationsACharger = (List) itThemes.next();
250: }
251: System.out.println("");
252: System.out.println("###### Chargement des elements du DataSet "
253: + this .getNom());
254: Iterator itPop = this .getPopulations().iterator();
255: while (itPop.hasNext()) {
256: Population pop = (Population) itPop.next();
257: if (populationsACharger == null)
258: aCharger = true;
259: else {
260: aCharger = false;
261: itPopulationsACharger = populationsACharger.iterator();
262: while (itPopulationsACharger.hasNext()) {
263: nom = (String) itPopulationsACharger.next();
264: if (pop.getNom().equals(nom)) {
265: aCharger = true;
266: break;
267: }
268: }
269: }
270: if (aCharger && pop.getPersistant()) {
271: if (geom != null)
272: pop.chargeElementsPartie(geom);
273: else
274: pop.chargeElements();
275: }
276: }
277:
278: }
279:
280: /** Pour un jeu de données persistant, détruit le jeu de données, ses thèmes et ses objets populations -
281: * ATTENTION : ne détruit pas les éléments des populations (pour cela vider les tables Oracle)
282: */
283: public void detruitJeu() {
284: if (!this .getPersistant()) {
285: System.out
286: .println("----- ATTENTION : Probleme à la destruction du jeu de donnees "
287: + this .getNom());
288: System.out
289: .println("----- Le jeu de données n'est pas persistant");
290: return;
291: }
292: // destruction des populations de this
293: Iterator itPop = this .getPopulations().iterator();
294: while (itPop.hasNext()) {
295: Population pop = (Population) itPop.next();
296: if (pop.getPersistant())
297: pop.detruitPopulation();
298: }
299:
300: // destruction recursive des dataset composants this
301: System.out.println(" ");
302: Iterator itDS = this .getComposants().iterator();
303: while (itDS.hasNext()) {
304: DataSet DS = (DataSet) itDS.next();
305: if (DS.getPersistant())
306: DS.detruitJeu();
307: }
308:
309: // destruction des zones d'extraction associées à this
310: System.out.println(" ");
311: Iterator itExt = this .getExtractions().iterator();
312: while (itExt.hasNext()) {
313: Extraction ex = (Extraction) itExt.next();
314: System.out
315: .println("###### Destruction de la zone d'extraction "
316: + ex.getNom());
317: db.deletePersistent(ex);
318: }
319:
320: //destruction de this
321: System.out.println("###### Destruction du DataSet "
322: + this .getNom());
323: db.deletePersistent(this );
324: }
325:
326: /** Booléen spécifiant si le thème est persistant ou non (vrai par défaut).
327: * NB : si un jeu de données est non persistant, tous ses thèmes sont non persistants.
328: * Mais si un jeu de données est persistant, certains de ses thèmes peuvent ne pas l'être.
329: *
330: * ATTENTION: pour des raisons propres à OJB, même si la classe DataSet est concrète,
331: * il n'est pas possible de créer un objet PERSISTANT de cette classe,
332: * il faut utiliser les sous-classes.
333: */
334: // NB pour codeurs : laisser 'true' par défaut. Sinon, comme cet attribut n'est pas persistant,
335: // cela pose des problèmes au chargement (un thème persistant chargé a son attribut persistant à false.
336: protected boolean persistant = true;
337:
338: public boolean getPersistant() {
339: return persistant;
340: }
341:
342: public void setPersistant(boolean b) {
343: persistant = b;
344: }
345:
346: ///////////////////////////////////////////////////////
347: // Metadonnées
348: ///////////////////////////////////////////////////////
349: /** Nom de la classe concrète de this : pour OJB, ne pas manipuler directement */
350: protected String ojbConcreteClass;
351:
352: public String getOjbConcreteClass() {
353: return ojbConcreteClass;
354: }
355:
356: public void setOjbConcreteClass(String S) {
357: ojbConcreteClass = S;
358: }
359:
360: /** Nom du jeu de données */
361: protected String nom;
362:
363: public String getNom() {
364: return nom;
365: }
366:
367: public void setNom(String S) {
368: nom = S;
369: }
370:
371: /** Type de BD (BDcarto, BDTopo...). */
372: protected String typeBD;
373:
374: public String getTypeBD() {
375: return typeBD;
376: }
377:
378: public void setTypeBD(String S) {
379: typeBD = S;
380: }
381:
382: /** Modèle utilisé (format shape, structuré...). */
383: protected String modele;
384:
385: public String getModele() {
386: return modele;
387: }
388:
389: public void setModele(String S) {
390: modele = S;
391: }
392:
393: /** Zone géographique couverte. */
394: protected String zone;
395:
396: public String getZone() {
397: return zone;
398: }
399:
400: public void setZone(String S) {
401: zone = S;
402: }
403:
404: /** Date des données. */
405: protected String date;
406:
407: public String getDate() {
408: return date;
409: }
410:
411: public void setDate(String S) {
412: date = S;
413: }
414:
415: /** Commentaire quelconque. */
416: protected String commentaire;
417:
418: public String getCommentaire() {
419: return commentaire;
420: }
421:
422: public void setCommentaire(String S) {
423: commentaire = S;
424: }
425:
426: ///////////////////////////////////////////////////////
427: // Thèmes du jeu de données
428: ///////////////////////////////////////////////////////
429: /** Un DataSet se décompose récursivement en un ensemble de DataSet.
430: * Le lien de DataSet vers lui-même est un lien 1-n.
431: * Les méthodes get (sans indice) et set sont nécessaires au mapping.
432: * Les autres méthodes sont là seulement pour faciliter l'utilisation de la relation.
433: * ATTENTION: Pour assurer la bidirection, il faut modifier les listes uniquement avec ces methodes.
434: * NB: si il n'y a pas d'objet en relation, la liste est vide mais n'est pas "null".
435: * Pour casser toutes les relations, faire setListe(new ArrayList()) ou emptyListe().
436: */
437: protected List composants = new ArrayList();
438:
439: /** Récupère la liste des DataSet composant this. */
440: public List getComposants() {
441: return composants;
442: }
443:
444: /** Définit la liste des DataSet composant le DataSet, et met à jour la relation inverse. */
445: public void setComposants(List L) {
446: List old = new ArrayList(composants);
447: Iterator it1 = old.iterator();
448: while (it1.hasNext()) {
449: DataSet O = (DataSet) it1.next();
450: O.setAppartientA(null);
451: }
452: Iterator it2 = L.iterator();
453: while (it2.hasNext()) {
454: DataSet O = (DataSet) it2.next();
455: O.setAppartientA(this );
456: }
457: }
458:
459: /** Récupère le ième élément de la liste des DataSet composant this. */
460: public DataSet getComposant(int i) {
461: return (DataSet) composants.get(i);
462: }
463:
464: /** Ajoute un objet à la liste des DataSet composant le DataSet, et met à jour la relation inverse. */
465: public void addComposant(DataSet O) {
466: if (O == null)
467: return;
468: composants.add(O);
469: O.setAppartientA(this );
470: }
471:
472: /** Enlève un élément de la liste DataSet composant this, et met à jour la relation inverse. */
473: public void removeComposant(DataSet O) {
474: if (O == null)
475: return;
476: composants.remove(O);
477: O.setAppartientA(null);
478: }
479:
480: /** Vide la liste des DataSet composant this, et met à jour la relation inverse. */
481: public void emptyComposants() {
482: List old = new ArrayList(composants);
483: Iterator it = old.iterator();
484: while (it.hasNext()) {
485: DataSet O = (DataSet) it.next();
486: O.setAppartientA(null);
487: }
488: }
489:
490: /** Recupère le DataSet composant de this avec le nom donné. */
491: public DataSet getComposant(String nom) {
492: DataSet th;
493: Iterator it = this .getComposants().iterator();
494: while (it.hasNext()) {
495: th = (DataSet) it.next();
496: if (th.getNom().equals(nom))
497: return th;
498: }
499: System.out.println("----- ATTENTION : DataSet composant #"
500: + nom + "# introuvable dans le DataSet "
501: + this .getNom());
502: return null;
503: }
504:
505: /** Relation inverse à Composants */
506: private DataSet appartientA;
507:
508: /** Récupère le DataSet dont this est composant. */
509: public DataSet getAppartientA() {
510: return appartientA;
511: }
512:
513: /** Définit le DataSet dont this est composant., et met à jour la relation inverse. */
514: public void setAppartientA(DataSet O) {
515: DataSet old = appartientA;
516: appartientA = O;
517: if (old != null)
518: old.getComposants().remove(this );
519: if (O != null) {
520: appartientAID = O.getId();
521: if (!(O.getComposants().contains(this )))
522: O.getComposants().add(this );
523: } else
524: appartientAID = 0;
525: }
526:
527: private int appartientAID;
528:
529: /** Ne pas utiliser, necessaire au mapping OJB */
530: public void setAppartientAID(int I) {
531: appartientAID = I;
532: }
533:
534: /** Ne pas utiliser, necessaire au mapping OJB */
535: public int getAppartientAID() {
536: return appartientAID;
537: }
538:
539: /** Liste des population du DataSet.
540: * Les méthodes get (sans indice) et set sont nécessaires au mapping.
541: * Les autres méthodes sont là seulement pour faciliter l'utilisation de la relation.
542: * ATTENTION: Pour assurer la bidirection, il faut modifier les listes uniquement avec ces methodes.
543: * NB: si il n'y a pas d'objet en relation, la liste est vide mais n'est pas "null".
544: * Pour casser toutes les relations, faire setListe(new ArrayList()) ou emptyListe().
545: */
546: protected List populations = new ArrayList();
547:
548: /** Récupère la liste des populations en relation. */
549: public List getPopulations() {
550: return populations;
551: }
552:
553: /** Définit la liste des populations en relation, et met à jour la relation inverse. */
554: public void setPopulations(List L) {
555: List old = new ArrayList(populations);
556: Iterator it1 = old.iterator();
557: while (it1.hasNext()) {
558: Population O = (Population) it1.next();
559: O.setDataSet(null);
560: }
561: Iterator it2 = L.iterator();
562: while (it2.hasNext()) {
563: Population O = (Population) it2.next();
564: O.setDataSet(this );
565: }
566: }
567:
568: /** Récupère le ième élément de la liste des populations en relation. */
569: public Population getPopulation(int i) {
570: return (Population) populations.get(i);
571: }
572:
573: /** Ajoute un objet à la liste des populations en relation, et met à jour la relation inverse. */
574: public void addPopulation(Population O) {
575: if (O == null)
576: return;
577: populations.add(O);
578: O.setDataSet(this );
579: }
580:
581: /** Enlève un élément de la liste des populations en relation, et met à jour la relation inverse. */
582: public void removePopulation(Population O) {
583: if (O == null)
584: return;
585: populations.remove(O);
586: O.setDataSet(null);
587: }
588:
589: /** Vide la liste des populations en relation, et met à jour la relation inverse. */
590: public void emptyPopulations() {
591: List old = new ArrayList(populations);
592: Iterator it = old.iterator();
593: while (it.hasNext()) {
594: Population O = (Population) it.next();
595: O.setDataSet(null);
596: }
597: }
598:
599: /** Recupère la population avec le nom donné. */
600: public Population getPopulation(String nom) {
601: Population th;
602: Iterator it = this .getPopulations().iterator();
603: while (it.hasNext()) {
604: th = (Population) it.next();
605: if (th.getNom().equals(nom))
606: return th;
607: }
608: System.out.println("=============== ATTENTION : population '"
609: + nom + "' introuvable ==============");
610: return null;
611: }
612:
613: /** Liste des zones d'extraction définies pour ce DataSt */
614: protected List extractions = new ArrayList();
615:
616: /** Récupère la liste des extractions en relation. */
617: public List getExtractions() {
618: return extractions;
619: }
620:
621: /** Définit la liste des extractions en relation. */
622: public void setExtractions(List L) {
623: extractions = L;
624: }
625:
626: /** Ajoute un élément de la liste des extractions en relation. */
627: public void addExtraction(Extraction O) {
628: extractions.add(O);
629: }
630:
631: }
|