Statistics
| Revision:

root / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrVect.java @ 2978

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

    
94

    
95
/**
96
 * Capa b?sica Vectorial.
97
 *
98
 * @author Fernando Gonz?lez Cort?s
99
 */
100

    
101
//TODO Cuando no sea para pruebas debe no ser public
102
public class FLyrVect extends FLyrDefault implements Labelable, Selectable,
103
        AlphanumericData, ClassifiableVectorial, SingleLayer, VectorialData,
104
        RandomVectorialData {
105
        private static Logger logger = Logger.getLogger(FLyrVect.class.getName());
106

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

    
119
        /**
120
         * A?ade un SelectionListener a la lista de listeners.
121
         *
122
         * @param listener SelectionListener.
123
         */
124
        public void addSelectionListener(SelectionListener listener) {
125
                selectionSupport.addSelectionListener(listener);
126
        }
127

    
128
        /**
129
         * Borra un selectionListener de la lista de listeners.
130
         *
131
         * @param listener SelectionListener
132
         */
133
        public void removeSelectionListener(SelectionListener listener) {
134
                selectionSupport.removeSelectionListener(listener);
135
        }
136

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

    
147
        /**
148
         * Devuelve el VectorialAdapater de la capa.
149
         *
150
         * @return VectorialAdapter.
151
         */
152
        public VectorialAdapter getSource() {
153
                return source;
154
        }
155

    
156
        /**
157
         * Inserta el VectorialAdapter a la capa.
158
         *
159
         * @param va VectorialAdapter.
160
         */
161
        public void setSource(VectorialAdapter va) {
162
                source = va;
163
        }
164

    
165
        /**
166
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
167
         */
168
        public Rectangle2D getFullExtent() throws DriverException {
169
                try {
170
                        Rectangle2D rAux;
171
                        logger.debug("source.start()");
172
                        source.start();
173
                        rAux = source.getFullExtent();
174
                        logger.debug("source.stop()");
175
                        source.stop();
176

    
177
                        // Si existe reproyecci?n, reproyectar el extent
178
                        ICoordTrans ct = getCoordTrans();
179

    
180
                        if (ct != null) {
181
                                Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
182
                                Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
183
                                pt1 = ct.convert(pt1, null);
184
                                pt2 = ct.convert(pt2, null);
185
                                rAux = new Rectangle2D.Double();
186
                                rAux.setFrameFromDiagonal(pt1, pt2);
187
                        }
188

    
189
                        return rAux;
190
                } catch (DriverIOException e) {
191
                        throw new DriverException(e);
192
                }
193
        }
194

    
195
        /**
196
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage,
197
         *                 java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort)
198
         */
199
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
200
                Cancellable cancel,double scale) throws DriverException {
201
            
202
                if (isWithinScale(scale)){        
203
            
204
                Strategy strategy = StrategyManager.getStrategy(this);
205

    
206
                strategy.draw(image, g, viewPort, cancel);
207

    
208
                if (getVirtualLayers() != null) {
209
                        getVirtualLayers().draw(image, g, viewPort, cancel,scale);
210
                }
211

    
212
                if (getLayerText() != null) {
213
                        getLayerText().draw(image, g, viewPort, cancel,scale);
214
                }
215
                }
216
        }
217

    
218
        /**
219
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
220
         *                 com.iver.cit.gvsig.fmap.ViewPort,
221
         *                 com.iver.cit.gvsig.fmap.operations.Cancellable)
222
         */
223
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,double scale)
224
                throws DriverException {
225
                if (isVisible() && isWithinScale(scale)){        
226
                Strategy strategy = StrategyManager.getStrategy(this);
227

    
228
                strategy.print(g, viewPort, cancel);
229

    
230
                if (getLayerText() != null) {
231
                        getLayerText().draw(null, g, viewPort, cancel,scale);
232
                }
233
                }
234
        }
235

    
236
        /**
237
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#createLabelLayer(int)
238
         */
239
        // public FLayer createLabelLayer(int fieldId) {
240
    public FLayer createLabelLayer(SelectableDataSource ds) {
241
                ArrayList labels = new ArrayList();
242

    
243
                try {
244
                        VectorialAdapter adapter = getSource();
245
                        logger.debug("adapter.start()");
246
                        adapter.start();
247
                        ds.start();
248

    
249
                        //VectorialDriver driver = (VectorialDriver) adapter.getDriver();
250
            long sc;
251

    
252
            sc = ds.getRowCount();
253
            
254
            int fieldId = ds.getFieldIndexByName(legend.getLabelField());
255

    
256
            DriverAttributes attr = adapter.getDriverAttributes();
257
            boolean bMustClone = false;
258
            if (attr != null)
259
            {
260
                if (attr.isLoadedInMemory())
261
                {
262
                    bMustClone = attr.isLoadedInMemory();               
263
                }
264
            }
265
            ICoordTrans ct = getCoordTrans();
266
            
267
                        VectorialLegend l = (VectorialLegend) getLegend();
268
                        int idFieldHeightText = -1;
269
                        int idFieldRotationText = -1;
270
                        
271

    
272
                        if (l.getLabelHeightField() != null) {
273
                                l.setBWithHeightText(true);
274
                                idFieldHeightText = ds.getFieldIndexByName(l.getLabelHeightField());
275
                        }else{
276
                                l.setBWithHeightText(false);
277
                        }
278

    
279
                        boolean bWithRotationText = false;
280

    
281
                        if (l.getLabelRotationField() != null) {
282
                                bWithRotationText = true;
283
                                idFieldRotationText = ds.getFieldIndexByName(l.getLabelRotationField());
284
                        }
285

    
286
                        for (int i = 0; i < sc; i++) {
287
                                Value val = ds.getFieldValue(i, fieldId);
288

    
289
                                if ((val instanceof NullValue) || (val == null)) {
290
                                        continue;
291
                                }
292

    
293
                                IGeometry geom = adapter.getShape(i);
294

    
295
                                if (geom == null) {
296
                                        continue;
297
                                }
298
                if (ct != null) {
299
                    if (bMustClone)
300
                        geom = geom.cloneGeometry();
301
                    geom.reProject(ct);
302
                }
303
                
304
                                FSymbol symbol = l.getDefaultSymbol();
305

    
306
                                // TODO: El m?todo contenedor (createLabelLayer) debe recoger
307
                                // los par?metros de posicionamiento y de allowDuplicates
308
                                // if (i >= 328)
309
                                //         System.out.println("i= " + i + " " + val.toString());
310
                                FLabel[] lbls = geom.createLabels(0, true);
311

    
312
                                for (int j = 0; j < lbls.length; j++) {
313
                                        if (lbls[j] != null) {
314
                                                lbls[j].setString(val.toString());
315

    
316
                                                if (l.isBWithHeightText()) {
317
                                                        FloatValue height = (FloatValue) ds.getFieldValue(i,
318
                                                                        idFieldHeightText);
319
                                                        lbls[j].setHeight(height.getValue());
320
                                                } else {
321
                            // El tama?o del texto va siempre en el simbolo por defecto
322
                            // cuando no hay un campo de altura de texto
323
                            // TODO: Todo esto cambiar? con el nuevo sistema de leyendas...
324
                                                        if (l.getDefaultSymbol()!=null)
325
                                                        lbls[j].setHeight(l.getDefaultSymbol().getFontSize());
326
                                                }
327

    
328
                                                if (bWithRotationText) {
329
                                                        DoubleValue rotation = (DoubleValue) ds.getFieldValue(i,
330
                                                                        idFieldRotationText);
331
                                                        lbls[j].setRotation(rotation.getValue());
332
                                                }
333
                                                labels.add(lbls[j]);        
334
                                        }
335

    
336
                                        
337
                                }
338
                        }
339

    
340
                        //long t2 = System.currentTimeMillis();
341
                        logger.debug("adapter.stop()");
342
                        ds.stop();
343
                        adapter.stop();
344
                } catch (DriverIOException e) {
345
                        e.printStackTrace();
346
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
347
                        // TODO Auto-generated catch block
348
                        e.printStackTrace();
349
                }
350

    
351
                FLyrText layerText = new FLyrText(labels);
352

    
353
                try {
354
                        layerText.setLegend((VectorialLegend) getLegend());
355
                } catch (FieldNotFoundException e1) {
356
                        // TODO Auto-generated catch block
357
                        e1.printStackTrace();
358
                } catch (DriverException e1) {
359
                        // TODO Auto-generated catch block
360
                        e1.printStackTrace();
361
                }
362

    
363
                setLayerText(layerText);
364

    
365
                return layerText;
366
        }
367

    
368
        /**
369
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#removeLabels()
370
         */
371
        public void removeLabels() {
372
                setLayerText(null);
373
        }
374

    
375
        /* (non-Javadoc)
376
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#createIndex()
377
         */
378
        public void createSpatialIndex() {
379
        // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
380
        // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
381
        // para que acepten recorrer sin geometria, solo con rectangulos.
382
        spatialIndex = new Quadtree();
383
        VectorialAdapter va = getSource();
384
        ICoordTrans ct = getCoordTrans();
385
        BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
386
        try {
387
            va.start();
388

    
389
            for (int i=0; i < va.getShapeCount(); i++)
390
            {               
391
                Rectangle2D r = shapeBounds.getShapeBounds(i);
392
                // TODO: MIRAR COMO SE TRAGAR?A ESTO LO DE LAS REPROYECCIONES
393
                if (ct != null) {
394
                    r = ct.convert(r);
395
                }
396
                Coordinate c1 = new Coordinate(r.getMinX(), r.getMinY());
397
                Coordinate c2 = new Coordinate(r.getMaxX(), r.getMaxY());
398
                Envelope env = new Envelope(c1, c2);
399
                spatialIndex.insert(env, new Integer(i));
400
            } // for
401
            va.stop();
402
        } catch (DriverIOException e) {
403
            // TODO Auto-generated catch block
404
            e.printStackTrace();
405
        } catch (IOException e) {
406
            // TODO Auto-generated catch block
407
            e.printStackTrace();
408
        }
409
        
410
        }
411

    
412
        /**
413
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor,
414
         *                 FBitSet)
415
         */
416
        public void process(FeatureVisitor visitor, FBitSet subset)
417
                throws DriverException, VisitException {
418
                Strategy s = StrategyManager.getStrategy(this);
419
                s.process(visitor, subset);
420
        }
421

    
422
        /**
423
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor)
424
         */
425
        public void process(FeatureVisitor visitor)
426
                throws DriverException, VisitException {
427
                Strategy s = StrategyManager.getStrategy(this);
428
                s.process(visitor);
429
        }
430

    
431
        /**
432
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setSelection(com.iver.cit.gvsig.fmap.operations.selection.VectorialSubSet)
433
         */
434
        public void setSelection(FBitSet selection) {
435
                selectionSupport.setSelection(selection);
436
                fireSelectionEvents();
437
        }
438

    
439
        /**
440
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#isSelected(int)
441
         */
442
        public boolean isSelected(int index) {
443
                return selectionSupport.isSelected(index);
444
        }
445

    
446
        /**
447
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getSelection()
448
         */
449
        public FBitSet getSelection() {
450
                return selectionSupport.getSelection();
451
        }
452

    
453
        /**
454
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#clearSelection()
455
         */
456
        public void clearSelection() {
457
                selectionSupport.clearSelection();
458
        }
459

    
460
        /* (non-Javadoc)
461
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#queryByRect(java.awt.geom.Rectangle2D)
462
         */
463
        public FBitSet queryByRect(Rectangle2D rect) throws DriverException {
464
                Strategy s = StrategyManager.getStrategy(this);
465

    
466
                return s.queryByRect(rect);
467
        }
468

    
469
    public FBitSet queryByPoint(Point2D p, double tolerance) throws DriverException
470
    {
471
        Strategy s = StrategyManager.getStrategy(this);
472
        return s.queryByPoint(p, tolerance);       
473
    }
474
    
475
    public FBitSet queryByShape(IGeometry g, int relationship) throws DriverException, VisitException
476
    {
477
        Strategy s = StrategyManager.getStrategy(this);
478
        return s.queryByShape(g, relationship);        
479
    }
480
        /**
481
         * @throws DriverException
482
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getRecordset()
483
         */
484
        public SelectableDataSource getRecordset() throws DriverException {
485
                if (sds == null){
486
                        try {
487
                                DataSource ds = source.getRecordset();
488

    
489
                                if (ds == null) {
490
                                        return null;
491
                                }
492

    
493
                                sds = new SelectableDataSource(ds);
494
                                sds.setSelectionSupport(selectionSupport);
495
                                
496
                                return sds;
497
                        } catch (DriverLoadException e) {
498
                                throw new DriverException(e);
499
                        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e) {
500
                                throw new DriverException(e);
501
            }
502
                }
503
                return sds;
504
        }
505
    
506
    /**
507
     * Para cuando haces una uni?n, sustituyes el recorset por el nuevo.
508
     * De esta forma, podr?s poner leyendas basadas en el nuevo
509
     * recordset
510
     * @param newSds
511
     * @throws DriverException 
512
     * @throws FieldNotFoundException 
513
     * @throws FieldNotFoundException 
514
     */
515
    public void setRecordset(SelectableDataSource newSds) throws DriverException, FieldNotFoundException
516
    {
517
        sds = newSds;
518
        sds.setSelectionSupport(selectionSupport);
519
        legend.setDataSource(sds);
520
        logger.debug("Recordset cambiado a " + sds.getName());
521
    }
522

    
523
        /**
524
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setLegend(int,
525
         *                 com.iver.cit.gvsig.fmap.rendering.Legend)
526
         */
527
        public void setLegend(VectorialLegend r)
528
                throws DriverException, FieldNotFoundException {
529
                VectorialLegend oldLegend = legend;
530
                legend = r;
531

    
532
                try {
533
                        legend.setDataSource(getRecordset());
534

    
535
                        if (legend.getLabelField() != null) {
536
                            // sds.start();
537
                                // int idLabelField = getRecordset().getFieldIndexByName(legend.getLabelField());
538
                                createLabelLayer(sds);
539
                                // sds.stop();
540
                        }
541
                        else
542
                            removeLabels();
543
                } catch (DriverException e) {
544
                        throw new DriverException(e);
545
                } catch (FieldNotFoundException e) {
546
                        // TODO Auto-generated catch block
547
                        e.printStackTrace();
548
        }
549

    
550
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(oldLegend, legend);
551
                callLegendChanged(e);
552
        }
553

    
554
        /**
555
         * Devuelve la Leyenda de la capa.
556
         *
557
         * @return Leyenda.
558
         */
559
        public Legend getLegend() {
560
                return legend;
561
        }
562

    
563
        /**
564
         * Devuelve el tipo de shape que contiene la capa.
565
         *
566
         * @return tipo de shape.
567
         *
568
         * @throws DriverException
569
         */
570
        public int getShapeType() throws DriverException {
571
                if (typeShape == -1) {
572
                        try {
573
                                logger.debug("source.start()");
574
                                source.start();
575
                                typeShape = source.getShapeType();
576
                                logger.debug("source.stop()");
577
                                source.stop();
578
                        } catch (DriverIOException e) {
579
                                throw new DriverException(e);
580
                        }
581
                }
582

    
583
                return typeShape;
584
        }
585

    
586
        /**
587
         * @throws XMLException
588
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
589
         */
590
        public XMLEntity getXMLEntity() throws XMLException {
591
                XMLEntity xml = super.getXMLEntity();
592
        xml.addChild(legend.getXMLEntity());
593
        xml.addChild(selectionSupport.getXMLEntity());
594

    
595
                if (source instanceof VectorialFileAdapter) {
596
                        xml.putProperty("type", "vectorial");
597
                        xml.putProperty("file", ((VectorialFileAdapter) source).getFile());
598
                        try {
599
                                xml.putProperty("recordset-name", getRecordset().getName());
600
                        } catch (DriverException e) {
601
                                throw new XMLException(e);
602
                        }
603
                } else if (source instanceof VectorialDBAdapter) {
604
            xml.putProperty("type", "vectorial");
605
            
606
            VectorialDatabaseDriver dbDriver = (VectorialDatabaseDriver) source.getDriver();
607
            
608
            // Guardamos el nombre del driver para poder recuperarlo
609
            // con el DriverManager de Fernando.
610
            xml.putProperty("db", dbDriver.getName());            
611
            try {
612
                xml.putProperty("recordset-name", getRecordset().getName());
613
            } catch (DriverException e) {
614
                throw new XMLException(e);
615
            }
616
            xml.addChild(dbDriver.getXMLEntity()); // Tercer child. Antes hemos metido la leyenda y el selection support
617
                } else if (source instanceof WFSAdapter) {
618
                }
619
                xml.putProperty("driverName", getSource().getDriver().getName());
620
        if (bHasJoin)
621
            xml.putProperty("hasJoin", "true");
622
        
623
        
624
                return xml;
625
        }
626

    
627
        /**
628
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
629
         */
630
        public void setXMLEntity03(XMLEntity xml)
631
                throws XMLException {
632
                
633
                super.setXMLEntity(xml);
634
                legend = LegendFactory.createFromXML03(xml.getChild(0));
635

    
636
                try {
637
                        // legend.setDataSource(getRecordset());
638
                        setLegend(legend);
639
                } catch (FieldNotFoundException e) {
640
                        throw new XMLException(e);
641
                } catch (DriverException e) {
642
                        throw new XMLException(e);
643
                }        
644

    
645
                selectionSupport.setXMLEntity03(xml.getChild(1));
646
        }
647

    
648
        /**
649
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
650
         */
651
        public void setXMLEntity(XMLEntity xml)
652
                throws XMLException {
653
        super.setXMLEntity(xml);
654
                
655
                legend = LegendFactory.createFromXML(xml.getChild(0));
656
                selectionSupport.setXMLEntity(xml.getChild(1));
657

    
658
                String recordsetName = xml.getStringProperty("recordset-name");
659
                try {
660
                        LayerFactory.getDataSourceFactory().changeDataSourceName(
661
                    getRecordset().getName(), recordsetName
662
                                        );
663
            // Hacemos que el recordset que hemos creado antes (los
664
            // recordset se crean antes que todo) sea el recordset
665
            // de esta capa. Y del que se crea automaticamente
666
            // en el setLegend del createLayer, nos olvidamos
667
            setRecordset(new SelectableDataSource(LayerFactory.getDataSourceFactory()
668
                        .createRandomDataSource(recordsetName, DataSourceFactory.AUTOMATIC_OPENING)));
669
                } catch (NoSuchTableException e1) {
670
                        throw new XMLException(e1);
671
                } catch (DriverException e1) {
672
                        throw new XMLException(e1);                
673
        } catch (com.hardcode.gdbms.engine.data.driver.DriverException e1) {
674
            throw new XMLException(e1);
675
        } catch (DriverLoadException e1) {
676
            throw new XMLException(e1);
677
        } catch (FieldNotFoundException e) {
678
            e.printStackTrace();
679
            throw new XMLException(e);
680
        }
681
        // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta el final
682
        // de la lectura del proyecto
683
        if (xml.contains("hasJoin"))
684
        {
685
            setIsJoined(true);
686
            PostProcessSupport.addToPostProcess(this,"setLegend", legend, 1);
687
        }
688
        else
689
        {
690
            try {
691
                // legend.setDataSource(getRecordset());
692
                setLegend(legend);
693
            } catch (FieldNotFoundException e) {
694
                throw new XMLException(e);
695
            } catch (DriverException e) {
696
                throw new XMLException(e);
697
            }   
698
        }       
699
        
700
        }
701

    
702
        /**
703
         * A?ade un LegendListener a la lista de Listeners.
704
         *
705
         * @param listener LegendListener.
706
         */
707
        public void addLegendListener(LegendListener listener) {
708
                layerChangeSupport.addLayerListener(listener);
709
        }
710

    
711
        /**
712
         * Llamada al m?todo callLegendChanged de los listener.
713
         *
714
         * @param e Evento.
715
         */
716
        private void callLegendChanged(LegendChangedEvent e) {
717
                layerChangeSupport.callLegendChanged(e);
718
        }
719

    
720
        /**
721
         * Borra un LegendListener de la lista de Listeners
722
         *
723
         * @param listener LegendListener.
724
         */
725
        public void removeLegendListener(LegendListener listener) {
726
                layerChangeSupport.removeLayerListener(listener);
727
        }
728

    
729
        /**
730
         * Sobreimplementaci?n del m?todo toString para que las bases de datos
731
         * identifiquen la capa.
732
         *
733
         * @return DOCUMENT ME!
734
         */
735
        public String toString() {
736
                /*
737
                 * Se usa internamente para que la parte de datos
738
                 * identifique de forma un?voca las tablas
739
                 */
740
                String ret = super.toString();
741

    
742
                return "layer" + ret.substring(ret.indexOf('@') + 1);
743
        }
744

    
745
    public boolean isJoined() {
746
        return bHasJoin;
747
    }
748

    
749
    public void setIsJoined(boolean hasJoin) {
750
        bHasJoin = hasJoin;
751
    }
752

    
753
    /**
754
     * @return Returns the spatialIndex.
755
     */
756
    public Quadtree getSpatialIndex() {
757
        return spatialIndex;
758
    }
759
}