Statistics
| Revision:

svn-gvsig-desktop / branches / v051 / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrVect.java @ 3947

History | View | Annotate | Download (21.6 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package com.iver.cit.gvsig.fmap.layers;
42

    
43
import java.awt.Graphics2D;
44
import java.awt.geom.Point2D;
45
import java.awt.geom.Rectangle2D;
46
import java.awt.image.BufferedImage;
47
import java.io.IOException;
48
import java.util.ArrayList;
49
import java.util.BitSet;
50

    
51
import org.apache.log4j.Logger;
52
import org.cresques.cts.ICoordTrans;
53

    
54
import com.hardcode.driverManager.Driver;
55
import com.hardcode.driverManager.DriverLoadException;
56
import com.hardcode.gdbms.engine.data.DataSource;
57
import com.hardcode.gdbms.engine.data.DataSourceFactory;
58
import com.hardcode.gdbms.engine.data.NoSuchTableException;
59
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
60
import com.hardcode.gdbms.engine.values.DoubleValue;
61
import com.hardcode.gdbms.engine.values.FloatValue;
62
import com.hardcode.gdbms.engine.values.NullValue;
63
import com.hardcode.gdbms.engine.values.NumericValue;
64
import com.hardcode.gdbms.engine.values.Value;
65
import com.iver.cit.gvsig.fmap.DriverException;
66
import com.iver.cit.gvsig.fmap.ViewPort;
67
import com.iver.cit.gvsig.fmap.core.IGeometry;
68
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
69
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
70
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
71
import com.iver.cit.gvsig.fmap.drivers.DriverAttributes;
72
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
73
import com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver;
74
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
75
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
76
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
77
import com.iver.cit.gvsig.fmap.layers.layerOperations.Labelable;
78
import com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData;
79
import com.iver.cit.gvsig.fmap.layers.layerOperations.Selectable;
80
import com.iver.cit.gvsig.fmap.layers.layerOperations.SingleLayer;
81
import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData;
82
import com.iver.cit.gvsig.fmap.operations.Cancellable;
83
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
84
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
85
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
86
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
87
import com.iver.cit.gvsig.fmap.rendering.Legend;
88
import com.iver.cit.gvsig.fmap.rendering.LegendChangedEvent;
89
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
90
import com.iver.cit.gvsig.fmap.rendering.SingleSymbolLegend;
91
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
92
import com.iver.utiles.IPersistance;
93
import com.iver.utiles.PostProcessSupport;
94
import com.iver.utiles.XMLEntity;
95
import com.vividsolutions.jts.geom.Coordinate;
96
import com.vividsolutions.jts.geom.Envelope;
97
import com.vividsolutions.jts.index.quadtree.Quadtree;
98

    
99

    
100
/**
101
 * Capa b?sica Vectorial.
102
 *
103
 * @author Fernando Gonz?lez Cort?s
104
 */
105

    
106
//TODO Cuando no sea para pruebas debe no ser public
107
public class FLyrVect extends FLyrDefault implements Labelable, Selectable,
108
        AlphanumericData, ClassifiableVectorial, SingleLayer, VectorialData,
109
        RandomVectorialData {
110
        private static Logger logger = Logger.getLogger(FLyrVect.class.getName());
111

    
112
        /** Leyenda de la capa vectorial */
113
        private VectorialLegend legend;
114
        private int typeShape = -1;
115
        private SelectionSupport selectionSupport = new SelectionSupport();
116
        private LayerChangeSupport layerChangeSupport = new LayerChangeSupport();
117
        private VectorialAdapter source;
118
        private SelectableDataSource sds;
119
    
120
    private Quadtree spatialIndex = null;
121
    
122
    private boolean bHasJoin = false;
123

    
124
        /**
125
         * A?ade un SelectionListener a la lista de listeners.
126
         *
127
         * @param listener SelectionListener.
128
         */
129
        public void addSelectionListener(SelectionListener listener) {
130
                selectionSupport.addSelectionListener(listener);
131
        }
132

    
133
        /**
134
         * Borra un selectionListener de la lista de listeners.
135
         *
136
         * @param listener SelectionListener
137
         */
138
        public void removeSelectionListener(SelectionListener listener) {
139
                selectionSupport.removeSelectionListener(listener);
140
        }
141

    
142
        /**
143
         * Cuando ocurre un evento de cambio en la selecci?n, ?ste puede ser uno de
144
         * una gran cantidad de eventos. Con el fin de no propagar todos estos
145
         * eventos, se realiza la propagaci?n de manera manual al final de la
146
         * "r?faga" de eventos
147
         */
148
        public void fireSelectionEvents() {
149
                selectionSupport.fireSelectionEvents();
150
        }
151

    
152
        /**
153
         * Devuelve el VectorialAdapater de la capa.
154
         *
155
         * @return VectorialAdapter.
156
         */
157
        public VectorialAdapter getSource() {
158
                return source;
159
        }
160

    
161
        /**
162
         * Inserta el VectorialAdapter a la capa.
163
         *
164
         * @param va VectorialAdapter.
165
         */
166
        public void setSource(VectorialAdapter va) {
167
                source = va;
168
        }
169

    
170
        /**
171
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
172
         */
173
        public Rectangle2D getFullExtent() throws DriverException {
174
                try {
175
                        Rectangle2D rAux;
176
                        logger.debug("source.start()");
177
                        source.start();
178
                        rAux = source.getFullExtent();
179
                        logger.debug("source.stop()");
180
                        source.stop();
181

    
182
                        // Si existe reproyecci?n, reproyectar el extent
183
                        ICoordTrans ct = getCoordTrans();
184

    
185
                        if (ct != null) {
186
                                Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
187
                                Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
188
                                pt1 = ct.convert(pt1, null);
189
                                pt2 = ct.convert(pt2, null);
190
                                rAux = new Rectangle2D.Double();
191
                                rAux.setFrameFromDiagonal(pt1, pt2);
192
                        }
193

    
194
                        return rAux;
195
                } catch (DriverIOException e) {
196
                        throw new DriverException(e);
197
                }
198
        }
199

    
200
        /**
201
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage,
202
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort)
203
         */
204
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
205
                Cancellable cancel,double scale) throws DriverException {
206
            
207
                if (isWithinScale(scale)){        
208
            // Las que solo tienen etiquetado sin pintar el shape,
209
            // no pasamos por ellas
210
            boolean bDrawShapes = true;
211
            if (legend instanceof SingleSymbolLegend)
212
            {
213
                if (legend.getDefaultSymbol().isShapeVisible() == false)
214
                    bDrawShapes = false;
215
            }
216
            if (bDrawShapes)
217
            {
218
                Strategy strategy = StrategyManager.getStrategy(this);    
219
                try{
220
                strategy.draw(image, g, viewPort, cancel);
221
                }catch (DriverException e) {
222
                                        this.setVisible(false);
223
                                        this.setActive(false);
224
                                        throw e;
225
                                }
226
            }
227
    
228
                    if (getVirtualLayers() != null) {
229
                            getVirtualLayers().draw(image, g, viewPort, cancel,scale);
230
                    }
231
    
232
                    if (getLayerText() != null) {
233
                            getLayerText().draw(image, g, viewPort, cancel,scale);
234
                    }
235
                }
236
        }
237

    
238
        /**
239
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
240
         *                 com.iver.cit.gvsig.fmap.ViewPort,
241
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
242
         */
243
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,double scale)
244
                throws DriverException {
245
                if (isVisible() && isWithinScale(scale)){        
246
                Strategy strategy = StrategyManager.getStrategy(this);
247

    
248
                strategy.print(g, viewPort, cancel);
249

    
250
                if (getLayerText() != null) {
251
                        getLayerText().draw(null, g, viewPort, cancel,scale);
252
                }
253
                }
254
        }
255

    
256
        /**
257
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#createLabelLayer(int)
258
         */
259
        // public FLayer createLabelLayer(int fieldId) {
260
    public FLayer createLabelLayer(SelectableDataSource ds) {
261
                FLyrText layerText = null;
262
        try {
263
            layerText = new FLyrText();
264
                        layerText.setLegend((VectorialLegend) getLegend());
265
            layerText.createLabels(this);
266
                } catch (FieldNotFoundException e1) {
267
                        // TODO Auto-generated catch block
268
                        e1.printStackTrace();
269
                } catch (DriverException e1) {
270
                        // TODO Auto-generated catch block
271
                        e1.printStackTrace();
272
        }
273

    
274

    
275
                setLayerText(layerText);
276
                layerText.setCoordTrans(getCoordTrans());
277
                return layerText;
278
        }
279

    
280
        /**
281
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#removeLabels()
282
         */
283
        public void removeLabels() {
284
                setLayerText(null);
285
        }
286

    
287
        /* (non-Javadoc)
288
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#createIndex()
289
         */
290
        public void createSpatialIndex() {
291
        // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
292
        // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
293
        // para que acepten recorrer sin geometria, solo con rectangulos.
294
        spatialIndex = new Quadtree();
295
        VectorialAdapter va = getSource();
296
        ICoordTrans ct = getCoordTrans();
297
        BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
298
        try {
299
            va.start();
300

    
301
            for (int i=0; i < va.getShapeCount(); i++)
302
            {               
303
                Rectangle2D r = shapeBounds.getShapeBounds(i);
304
                // TODO: MIRAR COMO SE TRAGAR?A ESTO LO DE LAS REPROYECCIONES
305
                if (ct != null) {
306
                    r = ct.convert(r);
307
                }
308
                Coordinate c1 = new Coordinate(r.getMinX(), r.getMinY());
309
                Coordinate c2 = new Coordinate(r.getMaxX(), r.getMaxY());
310
                Envelope env = new Envelope(c1, c2);
311
                spatialIndex.insert(env, new Integer(i));
312
            } // for
313
            va.stop();
314
        } catch (DriverIOException e) {
315
            // TODO Auto-generated catch block
316
            e.printStackTrace();
317
        } catch (IOException e) {
318
            // TODO Auto-generated catch block
319
            e.printStackTrace();
320
        }
321
        
322
        }
323

    
324
        /**
325
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor,
326
         *                 FBitSet)
327
         */
328
        public void process(FeatureVisitor visitor, FBitSet subset)
329
                throws DriverException, VisitException {
330
                Strategy s = StrategyManager.getStrategy(this);
331
                s.process(visitor, subset);
332
        }
333

    
334
        /**
335
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor)
336
         */
337
        public void process(FeatureVisitor visitor)
338
                throws DriverException, VisitException {
339
                Strategy s = StrategyManager.getStrategy(this);
340
                s.process(visitor);
341
        }
342

    
343
        /**
344
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setSelection(com.iver.cit.gvsig.fmap.operations.selection.VectorialSubSet)
345
         */
346
        public void setSelection(FBitSet selection) {
347
                selectionSupport.setSelection(selection);
348
                fireSelectionEvents();
349
        }
350

    
351
        /**
352
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#isSelected(int)
353
         */
354
        public boolean isSelected(int index) {
355
                return selectionSupport.isSelected(index);
356
        }
357

    
358
        /**
359
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getSelection()
360
         */
361
        public FBitSet getSelection() {
362
                return selectionSupport.getSelection();
363
        }
364

    
365
        /**
366
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#clearSelection()
367
         */
368
        public void clearSelection() {
369
                selectionSupport.clearSelection();
370
        }
371

    
372
        /* (non-Javadoc)
373
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#queryByRect(java.awt.geom.Rectangle2D)
374
         */
375
        public FBitSet queryByRect(Rectangle2D rect) throws DriverException {
376
                Strategy s = StrategyManager.getStrategy(this);
377

    
378
                return s.queryByRect(rect);
379
        }
380

    
381
    public FBitSet queryByPoint(Point2D p, double tolerance) throws DriverException
382
    {
383
        Strategy s = StrategyManager.getStrategy(this);
384
        return s.queryByPoint(p, tolerance);       
385
    }
386
    
387
    public FBitSet queryByShape(IGeometry g, int relationship) throws DriverException, VisitException
388
    {
389
        Strategy s = StrategyManager.getStrategy(this);
390
        return s.queryByShape(g, relationship);        
391
    }
392
        /**
393
         * @throws DriverException
394
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getRecordset()
395
         */
396
        public SelectableDataSource getRecordset() throws DriverException {
397
                if (sds == null){
398
                        try {
399
                                DataSource ds = source.getRecordset();
400

    
401
                                if (ds == null) {
402
                                        return null;
403
                                }
404

    
405
                                sds = new SelectableDataSource(ds);
406
                                sds.setSelectionSupport(selectionSupport);
407
                                
408
                                return sds;
409
                        } catch (DriverLoadException e) {
410
                                throw new DriverException(e);
411
                        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
412
                                throw new DriverException(e);
413
            }
414
                }
415
                return sds;
416
        }
417
    
418
    /**
419
     * Para cuando haces una uni?n, sustituyes el recorset por el nuevo.
420
     * De esta forma, podr?s poner leyendas basadas en el nuevo
421
     * recordset
422
     * @param newSds
423
     * @throws DriverException 
424
     * @throws FieldNotFoundException 
425
     * @throws FieldNotFoundException 
426
     */
427
    public void setRecordset(SelectableDataSource newSds) throws DriverException, FieldNotFoundException
428
    {
429
        sds = newSds;
430
        sds.setSelectionSupport(selectionSupport);
431
        legend.setDataSource(sds);
432
        logger.debug("Recordset cambiado a " + sds.getName());
433
    }
434

    
435
        /**
436
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setLegend(int,
437
         *                 com.iver.cit.gvsig.fmap.rendering.Legend)
438
         */
439
        public void setLegend(VectorialLegend r)
440
                throws DriverException, FieldNotFoundException {
441
                VectorialLegend oldLegend = legend;
442
                legend = r;
443

    
444
                try {
445
                        legend.setDataSource(getRecordset());
446

    
447
                        if (legend.getLabelField() != null) {
448
                            // sds.start();
449
                                // int idLabelField = getRecordset().getFieldIndexByName(legend.getLabelField());
450
                                createLabelLayer(sds);
451
                                // sds.stop();
452
                        }
453
                        else
454
                            removeLabels();
455
                } catch (DriverException e) {
456
                        throw new DriverException(e);
457
                } catch (FieldNotFoundException e) {
458
                        // TODO Auto-generated catch block
459
                        e.printStackTrace();
460
        }
461

    
462
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(oldLegend, legend);
463
                callLegendChanged(e);
464
        }
465

    
466
        /**
467
         * Devuelve la Leyenda de la capa.
468
         *
469
         * @return Leyenda.
470
         */
471
        public Legend getLegend() {
472
                return legend;
473
        }
474

    
475
        /**
476
         * Devuelve el tipo de shape que contiene la capa.
477
         *
478
         * @return tipo de shape.
479
         *
480
         * @throws DriverException
481
         */
482
        public int getShapeType() throws DriverException {
483
                if (typeShape == -1) {
484
                        try {
485
                                logger.debug("source.start()");
486
                                source.start();
487
                                typeShape = source.getShapeType();
488
                                logger.debug("source.stop()");
489
                                source.stop();
490
                        } catch (DriverIOException e) {
491
                                throw new DriverException(e);
492
                        }
493
                }
494

    
495
                return typeShape;
496
        }
497

    
498
        /**
499
         * @throws XMLException
500
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
501
         */
502
        public XMLEntity getXMLEntity() throws XMLException {
503
                XMLEntity xml = super.getXMLEntity();
504
        xml.addChild(legend.getXMLEntity());
505
        xml.addChild(selectionSupport.getXMLEntity());
506

    
507
                if (source instanceof VectorialFileAdapter) {
508
                        xml.putProperty("type", "vectorial");
509
                        xml.putProperty("file", ((VectorialFileAdapter) source).getFile());
510
                        try {
511
                                xml.putProperty("recordset-name", getRecordset().getName());
512
                        } catch (DriverException e) {
513
                                throw new XMLException(e);
514
                        }
515
                } else if (source instanceof VectorialDBAdapter) {
516
            xml.putProperty("type", "vectorial");
517
            
518
            VectorialDatabaseDriver dbDriver = (VectorialDatabaseDriver) source.getDriver();
519
            
520
            // Guardamos el nombre del driver para poder recuperarlo
521
            // con el DriverManager de Fernando.
522
            xml.putProperty("db", dbDriver.getName());            
523
            try {
524
                xml.putProperty("recordset-name", getRecordset().getName());
525
            } catch (DriverException e) {
526
                throw new XMLException(e);
527
            }
528
            xml.addChild(dbDriver.getXMLEntity()); // Tercer child. Antes hemos metido la leyenda y el selection support
529
        } else if (source instanceof VectorialAdapter) { 
530
            // Se supone que hemos hecho algo gen?rico.
531
            xml.putProperty("type", "vectorial");
532
            
533
            VectorialDriver driver = (VectorialDriver) source.getDriver();
534
            
535
            // Guardamos el nombre del driver para poder recuperarlo
536
            // con el DriverManager de Fernando.
537
            xml.putProperty("other", driver.getName());            
538
            try {
539
                xml.putProperty("recordset-name", getRecordset().getName());
540
            } catch (DriverException e) {
541
                throw new XMLException(e);
542
            }
543
            if (driver instanceof IPersistance)
544
            {
545
                // xml.putProperty("className", driver.getClass().getName());
546
                IPersistance persist = (IPersistance) driver;
547
                xml.addChild(persist.getXMLEntity()); // Tercer child. Antes hemos metido la leyenda y el selection support
548
            }
549
                } 
550
                xml.putProperty("driverName", getSource().getDriver().getName());
551
        if (bHasJoin)
552
            xml.putProperty("hasJoin", "true");
553
        
554
        
555
                return xml;
556
        }
557

    
558
        /**
559
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
560
         */
561
        public void setXMLEntity03(XMLEntity xml)
562
                throws XMLException {
563
                
564
                super.setXMLEntity(xml);
565
                legend = LegendFactory.createFromXML03(xml.getChild(0));
566

    
567
                try {
568
                        // legend.setDataSource(getRecordset());
569
                        setLegend(legend);
570
                } catch (FieldNotFoundException e) {
571
                        throw new XMLException(e);
572
                } catch (DriverException e) {
573
                        throw new XMLException(e);
574
                }        
575

    
576
                selectionSupport.setXMLEntity03(xml.getChild(1));
577
        }
578

    
579
        /**
580
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
581
         */
582
        public void setXMLEntity(XMLEntity xml)
583
                throws XMLException {
584
        super.setXMLEntity(xml);
585
                
586
                legend = LegendFactory.createFromXML(xml.getChild(0));
587
                selectionSupport.setXMLEntity(xml.getChild(1));
588

    
589
                String recordsetName = xml.getStringProperty("recordset-name");
590
                try {
591
                        LayerFactory.getDataSourceFactory().changeDataSourceName(
592
                    getRecordset().getName(), recordsetName
593
                                        );
594
            // Hacemos que el recordset que hemos creado antes (los
595
            // recordset se crean antes que todo) sea el recordset
596
            // de esta capa. Y del que se crea automaticamente
597
            // en el setLegend del createLayer, nos olvidamos
598
            setRecordset(new SelectableDataSource(LayerFactory.getDataSourceFactory()
599
                        .createRandomDataSource(recordsetName, DataSourceFactory.AUTOMATIC_OPENING)));
600
                } catch (NoSuchTableException e1) {
601
                        throw new XMLException(e1);
602
                } catch (DriverException e1) {
603
                        throw new XMLException(e1);                
604
        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e1) {
605
            throw new XMLException(e1);
606
        } catch (DriverLoadException e1) {
607
            throw new XMLException(e1);
608
        } catch (FieldNotFoundException e) {
609
            e.printStackTrace();
610
            throw new XMLException(e);
611
        }
612
        // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta el final
613
        // de la lectura del proyecto
614
        if (xml.contains("hasJoin"))
615
        {
616
            setIsJoined(true);
617
            PostProcessSupport.addToPostProcess(this,"setLegend", legend, 1);
618
        }
619
        else
620
        {
621
            try {
622
                // legend.setDataSource(getRecordset());
623
                setLegend(legend);
624
            } catch (FieldNotFoundException e) {
625
                throw new XMLException(e);
626
            } catch (DriverException e) {
627
                throw new XMLException(e);
628
            }   
629
        }       
630
        
631
        }
632

    
633
        /**
634
         * A?ade un LegendListener a la lista de Listeners.
635
         *
636
         * @param listener LegendListener.
637
         */
638
        public void addLegendListener(LegendListener listener) {
639
                layerChangeSupport.addLayerListener(listener);
640
        }
641

    
642
        /**
643
         * Llamada al m?todo callLegendChanged de los listener.
644
         *
645
         * @param e Evento.
646
         */
647
        private void callLegendChanged(LegendChangedEvent e) {
648
                layerChangeSupport.callLegendChanged(e);
649
        }
650

    
651
        /**
652
         * Borra un LegendListener de la lista de Listeners
653
         *
654
         * @param listener LegendListener.
655
         */
656
        public void removeLegendListener(LegendListener listener) {
657
                layerChangeSupport.removeLayerListener(listener);
658
        }
659

    
660
        /**
661
         * Sobreimplementaci?n del m?todo toString para que las bases de datos
662
         * identifiquen la capa.
663
         *
664
         * @return DOCUMENT ME!
665
         */
666
        public String toString() {
667
                /*
668
                 * Se usa internamente para que la parte de datos
669
                 * identifique de forma un?voca las tablas
670
                 */
671
                String ret = super.toString();
672

    
673
                return "layer" + ret.substring(ret.indexOf('@') + 1);
674
        }
675

    
676
    public boolean isJoined() {
677
        return bHasJoin;
678
    }
679

    
680
    public void setIsJoined(boolean hasJoin) {
681
        bHasJoin = hasJoin;
682
    }
683

    
684
    /**
685
     * @return Returns the spatialIndex.
686
     */
687
    public Quadtree getSpatialIndex() {
688
        return spatialIndex;
689
    }
690

    
691
        public SelectionSupport getSelectionSupport() {
692
                return selectionSupport;
693
        }
694

    
695
        public void setSelectionSupport(SelectionSupport selectionSupport) {
696
                this.selectionSupport = selectionSupport;
697
        }
698
}