Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrVect.java @ 5223

History | View | Annotate | Download (31.4 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.Point;
45
import java.awt.geom.Point2D;
46
import java.awt.geom.Rectangle2D;
47
import java.awt.image.BufferedImage;
48
import java.io.File;
49
import java.io.IOException;
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.DataSourceFactory;
56
import com.hardcode.gdbms.engine.data.NoSuchTableException;
57
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
58
import com.iver.cit.gvsig.fmap.DriverException;
59
import com.iver.cit.gvsig.fmap.ViewPort;
60
import com.iver.cit.gvsig.fmap.core.IGeometry;
61
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
62
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
63
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
64
import com.iver.cit.gvsig.fmap.drivers.VectorialDatabaseDriver;
65
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
66
import com.iver.cit.gvsig.fmap.edition.AnnotationEditableAdapter;
67
import com.iver.cit.gvsig.fmap.edition.EditionEvent;
68
import com.iver.cit.gvsig.fmap.edition.EditionException;
69
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
70
import com.iver.cit.gvsig.fmap.edition.VectorialEditableDBAdapter;
71
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
72
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
73
import com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint;
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.SingleLayer;
77
import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData;
78
import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialXMLItem;
79
import com.iver.cit.gvsig.fmap.layers.layerOperations.XMLItem;
80
import com.iver.cit.gvsig.fmap.operations.Cancellable;
81
import com.iver.cit.gvsig.fmap.operations.CancellableMonitorable;
82
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
83
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
84
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
85
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
86
import com.iver.cit.gvsig.fmap.rendering.Legend;
87
import com.iver.cit.gvsig.fmap.rendering.LegendChangedEvent;
88
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
89
import com.iver.cit.gvsig.fmap.rendering.SingleSymbolLegend;
90
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
91
import com.iver.cit.gvsig.fmap.spatialindex.IPersistentSpatialIndex;
92
import com.iver.cit.gvsig.fmap.spatialindex.ISpatialIndex;
93
import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeJts;
94
import com.iver.cit.gvsig.fmap.spatialindex.RTreeSptLib;
95
import com.iver.cit.gvsig.fmap.spatialindex.SpatialIndexException;
96
import com.iver.utiles.FileUtils;
97
import com.iver.utiles.IPersistance;
98
import com.iver.utiles.PostProcessSupport;
99
import com.iver.utiles.XMLEntity;
100

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

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

    
113
        /** Leyenda de la capa vectorial */
114
        private VectorialLegend legend;
115

    
116
        private int typeShape = -1;
117

    
118
        private LayerChangeSupport layerChangeSupport = new LayerChangeSupport();
119

    
120
        private ReadableVectorial source;
121

    
122
        private SelectableDataSource sds;
123

    
124
        private SelectionSupport selectionSupport = new SelectionSupport();
125
        
126
        private SpatialCache spatialCache = null;
127
        private boolean spatialCacheEnabled = true;
128

    
129
        // protected SpatialIndex spatialIndex = null;
130
        /**
131
         * An implementation of gvSIG spatial index
132
         */
133
        protected ISpatialIndex spatialIndex = null;
134

    
135
        private boolean bHasJoin = false;
136

    
137
        /**
138
         * A?ade un SelectionListener a la lista de listeners.
139
         *
140
         * @param listener
141
         *            SelectionListener.
142
         */
143
        /*
144
         * public void addSelectionListener(SelectionListener listener) { try {
145
         * getRecordset().addSelectionListener(listener); } catch (DriverException
146
         * e) { // TODO Auto-generated catch block e.printStackTrace(); } }
147
         */
148
        /**
149
         * Borra un selectionListener de la lista de listeners.
150
         *
151
         * @param listener
152
         *            SelectionListener
153
         */
154
        /*
155
         * public void removeSelectionListener(SelectionListener listener) { try {
156
         * getRecordset().removeSelectionListener(listener); } catch
157
         * (DriverException e) { // TODO Auto-generated catch block
158
         * e.printStackTrace(); } }
159
         */
160
        /**
161
         * Cuando ocurre un evento de cambio en la selecci?n, ?ste puede ser uno de
162
         * una gran cantidad de eventos. Con el fin de no propagar todos estos
163
         * eventos, se realiza la propagaci?n de manera manual al final de la
164
         * "r?faga" de eventos
165
         */
166
        /*
167
         * public void fireSelectionEvents() { try {
168
         * getRecordset().fireSelectionEvents(); } catch (DriverException e) { //
169
         * TODO Auto-generated catch block e.printStackTrace(); } }
170
         */
171
        /**
172
         * Devuelve el VectorialAdapater de la capa.
173
         *
174
         * @return VectorialAdapter.
175
         */
176
        public ReadableVectorial getSource() {
177
                return source;
178
        }
179

    
180
        /**
181
         * If we use a persistent spatial index associated with this layer, and the
182
         * index is not intrisic to the layer (for example spatial databases) this
183
         * method looks for existent spatial index, and loads it.
184
         *
185
         */
186
        private void loadSpatialIndex() {
187
                ReadableVectorial source = getSource();
188
                if (!(source instanceof VectorialFileAdapter)) {
189
                        // we are not interested in db adapters
190
                        return;
191
                }
192
                VectorialDriver driver = source.getDriver();
193
                if (!(driver instanceof BoundedShapes)) {
194
                        // we dont spatially index layers that are not bounded
195
                        return;
196
                }
197
                File file = ((VectorialFileAdapter) source).getFile();
198
                String fileName = FileUtils.getFileWithoutExtension(file);
199
                File sptFile = new File(fileName + ".dat");
200
                if (!sptFile.exists() || (!(sptFile.length() > 0))) {
201
                        // before to exit, look for it in temp path
202

    
203
                        String tempPath = System.getProperty("java.io.tmpdir");
204
                        fileName = tempPath + File.separator + sptFile.getName();
205
                        sptFile = new File(fileName);
206
                        // it doesnt exists, must to create
207
                        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
208
                                return;
209
                        }// if
210
                }// if
211
                try {
212
                        spatialIndex = new RTreeSptLib(false, FileUtils
213
                                        .getFileWithoutExtension(sptFile));
214
                } catch (SpatialIndexException e) {
215
                        spatialIndex = null;
216
                        e.printStackTrace();
217
                        return;
218
                }
219
        }
220

    
221
        /**
222
         * Checks if it has associated an external spatial index
223
         *
224
         * @return
225
         */
226
        public boolean isExternallySpatiallyIndexed() {
227
                ReadableVectorial source = getSource();
228
                if (!(source instanceof VectorialFileAdapter)) {
229
                        // we are not interested in db adapters
230
                        return false;
231
                }
232
                File file = ((VectorialFileAdapter) source).getFile();
233
                String fileName = FileUtils.getFileWithoutExtension(file);
234
                File sptFile = new File(fileName + ".dat");
235
                if (!sptFile.exists() || (!(sptFile.length() > 0))) {
236
                        // before to exit, look for it in temp path
237
                        // it doesnt exists, must to create
238
                        String tempPath = System.getProperty("java.io.tmpdir");
239
                        fileName = tempPath + File.separator + sptFile.getName();
240
                        sptFile = new File(fileName);
241
                        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
242
                                return false;
243
                        }// if
244
                }// if
245
                return true;
246
        }
247

    
248
        /**
249
         * Inserta el VectorialAdapter a la capa.
250
         *
251
         * @param va
252
         *            VectorialAdapter.
253
         */
254
        public void setSource(ReadableVectorial rv) {
255
                source = rv;
256
                // azabala: we check if this layer could have a file spatial index
257
                // , if it has, and load it if it exists
258
                loadSpatialIndex();
259
        }
260

    
261
        /**
262
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
263
         */
264
        public Rectangle2D getFullExtent() throws DriverException {
265
                try {
266
                        Rectangle2D rAux;
267
                        logger.debug("source.start()");
268
                        source.start();
269
                        rAux = source.getFullExtent();
270
                        logger.debug("source.stop()");
271
                        source.stop();
272

    
273
                        // Si existe reproyecci?n, reproyectar el extent
274
                        ICoordTrans ct = getCoordTrans();
275

    
276
                        if (ct != null) {
277
                                Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
278
                                Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
279
                                pt1 = ct.convert(pt1, null);
280
                                pt2 = ct.convert(pt2, null);
281
                                rAux = new Rectangle2D.Double();
282
                                rAux.setFrameFromDiagonal(pt1, pt2);
283
                        }
284

    
285
                        return rAux;
286
                } catch (DriverIOException e) {
287
                        throw new DriverException(e);
288
                }
289
        }
290

    
291
        /**
292
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage,
293
         *      java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort)
294
         */
295
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
296
                        Cancellable cancel, double scale) throws DriverException {
297

    
298
                if (isWithinScale(scale)) {
299
                        // Las que solo tienen etiquetado sin pintar el shape,
300
                        // no pasamos por ellas
301
                        boolean bDrawShapes = true;
302
                        if (legend instanceof SingleSymbolLegend) {
303
                                if (legend.getDefaultSymbol().isShapeVisible() == false)
304
                                        bDrawShapes = false;
305
                        }
306
                        if (bDrawShapes) {
307
                                Strategy strategy = StrategyManager.getStrategy(this);
308
                                try {
309
                                        strategy.draw(image, g, viewPort, cancel);
310
                                } catch (DriverException e) {
311
                                        this.setVisible(false);
312
                                        this.setActive(false);
313
                                        throw e;
314
                                }
315
                        }
316
                        if (getVirtualLayers() != null) {
317
                                getVirtualLayers().draw(image, g, viewPort, cancel, scale);
318
                        }
319

    
320
                        if (getLayerText() != null) {
321
                                getLayerText().draw(image, g, viewPort, cancel, scale);
322
                        }
323
                }
324
        }
325

    
326
        /**
327
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
328
         *      com.iver.cit.gvsig.fmap.ViewPort,
329
         *      com.iver.cit.gvsig.fmap.operations.Cancellable)
330
         */
331
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
332
                        double scale) throws DriverException {
333
                if (isVisible() && isWithinScale(scale)) {
334
                        Strategy strategy = StrategyManager.getStrategy(this);
335

    
336
                        strategy.print(g, viewPort, cancel);
337

    
338
                        if (getLayerText() != null) {
339
                                getLayerText().draw(null, g, viewPort, cancel, scale);
340
                        }
341
                }
342
        }
343

    
344
        /**
345
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#createLabelLayer(int)
346
         */
347
        // public FLayer createLabelLayer(int fieldId) {
348
        public FLayer createLabelLayer(SelectableDataSource ds) {
349
                FLyrText layerText = null;
350
                try {
351
                        layerText = new FLyrText();
352
                        layerText.setLegend((VectorialLegend) getLegend());
353
                        layerText.createLabels(this);
354
                } catch (FieldNotFoundException e1) {
355
                        // TODO Auto-generated catch block
356
                        e1.printStackTrace();
357
                } catch (DriverException e1) {
358
                        // TODO Auto-generated catch block
359
                        e1.printStackTrace();
360
                }
361

    
362
                setLayerText(layerText);
363
                layerText.setCoordTrans(getCoordTrans());
364
                return layerText;
365
        }
366

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

    
374
        /*
375
         * (non-Javadoc)
376
         *
377
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#deleteSpatialIndex()
378
         */
379
        public void deleteSpatialIndex() {
380
                spatialIndex = null;
381
        }
382

    
383
        /**
384
         * Creates an spatial index associated to this layers.
385
         *
386
         * @param cancelMonitor
387
         *            instance of CancellableMonitorable that allows to monitor
388
         *            progress of spatial index creation, and cancel the process
389
         */
390
        public void createSpatialIndex(CancellableMonitorable cancelMonitor) {
391
                // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
392
                // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
393
                // para que acepten recorrer sin geometria, solo con rectangulos.
394

    
395
                // //If this vectorial layer is based in a spatial database, the spatial
396
                // index is already implicit. We only will index file drivers
397
                ReadableVectorial va = getSource();
398
                if (!(va instanceof VectorialFileAdapter)) {
399
                        return;
400
                }
401
                if (!(va.getDriver() instanceof BoundedShapes)) {
402
                        return;
403
                }
404
                File file = ((VectorialFileAdapter) va).getFile();
405
                String fileName = FileUtils.getFileWithoutExtension(file);
406
                try {
407
                        spatialIndex = new RTreeSptLib(true, fileName);
408
                } catch (SpatialIndexException e1) {
409
                        // Probably we dont have writing permissions
410
                        String directoryName = System.getProperty("java.io.tmpdir");
411
                        File newFile = new File(file.getName());
412
                        String newFileName = newFile.getName();
413
                        try {
414
                                spatialIndex = new RTreeSptLib(true, directoryName
415
                                                + File.pathSeparator + newFileName);
416
                        } catch (SpatialIndexException e) {
417
                                // si no lo podemos crear en fichero, lo creamos en memoria
418
                                spatialIndex = new QuadtreeJts();
419
                        }
420
                }// try
421

    
422
                ICoordTrans ct = getCoordTrans();
423
                BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
424
                try {
425
                        va.start();
426

    
427
                        for (int i = 0; i < va.getShapeCount(); i++) {
428
                                if (cancelMonitor != null) {
429
                                        if (cancelMonitor.isCanceled())
430
                                                return;
431
                                        cancelMonitor.reportStep();
432
                                }
433
                                Rectangle2D r = shapeBounds.getShapeBounds(i);
434
                                if (ct != null) {
435
                                        r = ct.convert(r);
436
                                }
437
                                spatialIndex.insert(r, i);
438
                                if (spatialIndex instanceof IPersistentSpatialIndex) {
439
                                        if ((i % 50) == 0) {// flush spatial index in buckets of 50
440
                                                ((IPersistentSpatialIndex) spatialIndex).flush();
441
                                        }
442
                                }
443
                        } // for
444
                        va.stop();
445
                        if (spatialIndex instanceof IPersistentSpatialIndex)
446
                                ((IPersistentSpatialIndex) spatialIndex).flush();
447
                } catch (DriverIOException e) {
448
                        // TODO Auto-generated catch block
449
                        e.printStackTrace();
450
                } catch (IOException e) {
451
                        // TODO Auto-generated catch block
452
                        e.printStackTrace();
453
                }
454
        }
455

    
456
        /*
457
         * (non-Javadoc)
458
         *
459
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#createIndex()
460
         */
461
        public void createSpatialIndex() {
462
                createSpatialIndex(null);
463
        }
464

    
465
        /**
466
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor,
467
         *      FBitSet)
468
         */
469
        public void process(FeatureVisitor visitor, FBitSet subset)
470
                        throws DriverException, VisitException {
471
                Strategy s = StrategyManager.getStrategy(this);
472
                s.process(visitor, subset);
473
        }
474

    
475
        /**
476
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor)
477
         */
478
        public void process(FeatureVisitor visitor) throws DriverException,
479
                        VisitException {
480
                Strategy s = StrategyManager.getStrategy(this);
481
                s.process(visitor);
482
        }
483

    
484
        /**
485
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor,
486
         *      Rectangle2D)
487
         */
488
        public void process(FeatureVisitor visitor, Rectangle2D rect)
489
                        throws DriverException, VisitException {
490
                Strategy s = StrategyManager.getStrategy(this);
491
                s.process(visitor, rect);
492
        }
493

    
494
        /**
495
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setSelection(com.iver.cit.gvsig.fmap.operations.selection.VectorialSubSet)
496
         */
497
        /*
498
         * public void setSelection(FBitSet selection) { try {
499
         * getRecordset().setSelection(selection); } catch (DriverException e) { //
500
         * TODO Auto-generated catch block e.printStackTrace(); }
501
         * fireSelectionEvents(); }
502
         */
503
        /**
504
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#isSelected(int)
505
         */
506
        /*
507
         * public boolean isSelected(int index) { try { return
508
         * getRecordset().isSelected(index); } catch (DriverException e) { // TODO
509
         * Auto-generated catch block e.printStackTrace(); } return false; }
510
         */
511
        /**
512
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getSelection()
513
         */
514
        /*
515
         * public FBitSet getSelection() { try { return
516
         * getRecordset().getSelection(); } catch (DriverException e) { // TODO
517
         * Auto-generated catch block e.printStackTrace(); } return new FBitSet(); }
518
         */
519
        /**
520
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#clearSelection()
521
         */
522
        /*
523
         * public void clearSelection() { try { getRecordset().clearSelection(); }
524
         * catch (DriverException e) { // TODO Auto-generated catch block
525
         * e.printStackTrace(); } }
526
         */
527

    
528
        /*
529
         * (non-Javadoc)
530
         *
531
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#queryByRect(java.awt.geom.Rectangle2D)
532
         */
533
        public FBitSet queryByRect(Rectangle2D rect) throws DriverException {
534
                Strategy s = StrategyManager.getStrategy(this);
535

    
536
                return s.queryByRect(rect);
537
        }
538

    
539
        public FBitSet queryByPoint(Point2D p, double tolerance)
540
                        throws DriverException {
541
                Strategy s = StrategyManager.getStrategy(this);
542
                return s.queryByPoint(p, tolerance);
543
        }
544

    
545
        public FBitSet queryByShape(IGeometry g, int relationship)
546
                        throws DriverException, VisitException {
547
                Strategy s = StrategyManager.getStrategy(this);
548
                return s.queryByShape(g, relationship);
549
        }
550

    
551
        public XMLItem[] getInfo(Point p, double tolerance) throws DriverException {
552
                Point2D pReal = this.getFMap().getViewPort().toMapPoint(p);
553
                FBitSet bs = queryByPoint(pReal, tolerance);
554
                VectorialXMLItem[] item = new VectorialXMLItem[1];
555
                item[0] = new VectorialXMLItem(bs, this);
556

    
557
                return item;
558
        }
559

    
560
        /**
561
         * @throws DriverException
562
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getRecordset()
563
         */
564
        /*
565
         * public SelectableDataSource getRecordset() throws DriverException { if
566
         * (sds == null){ try { DataSource ds = getSource().getRecordset();
567
         *
568
         * if (ds == null) { return null; }
569
         *
570
         * sds = new SelectableDataSource(ds);
571
         * //sds.setSelectionSupport(selectionSupport);
572
         *
573
         * return sds; } catch (DriverLoadException e) { throw new
574
         * DriverException(e); } catch
575
         * (com.hardcode.gdbms.engine.data.driver.DriverException e) { throw new
576
         * DriverException(e); } } return sds; }
577
         */
578
        /**
579
         * Para cuando haces una uni?n, sustituyes el recorset por el nuevo. De esta
580
         * forma, podr?s poner leyendas basadas en el nuevo recordset
581
         *
582
         * @param newSds
583
         * @throws DriverException
584
         * @throws FieldNotFoundException
585
         * @throws FieldNotFoundException
586
         */
587
        /*
588
         * public void setRecordset(SelectableDataSource newSds) throws
589
         * DriverException, FieldNotFoundException { sds = newSds;
590
         * //sds.setSelectionSupport(selectionSupport); legend.setDataSource(sds);
591
         * logger.debug("Recordset cambiado a " + sds.getName()); }
592
         */
593
        /**
594
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setLegend(int,
595
         *      com.iver.cit.gvsig.fmap.rendering.Legend)
596
         */
597
        public void setLegend(VectorialLegend r) throws DriverException,
598
                        FieldNotFoundException {
599
                VectorialLegend oldLegend = legend;
600
                legend = r;
601

    
602
                try {
603
                        legend.setDataSource(getRecordset());
604

    
605
                        if (legend.getLabelField() != null) {
606
                                // sds.start();
607
                                // int idLabelField =
608
                                // getRecordset().getFieldIndexByName(legend.getLabelField());
609
                                createLabelLayer(getSource().getRecordset());
610
                                // sds.stop();
611
                        } else
612
                                removeLabels();
613
                } catch (DriverException e) {
614
                        throw new DriverException(e);
615
                } catch (FieldNotFoundException e) {
616
                        // TODO Auto-generated catch block
617
                        e.printStackTrace();
618
                } catch (DriverLoadException e) {
619
                        // TODO Auto-generated catch block
620
                        e.printStackTrace();
621
                }
622

    
623
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
624
                                oldLegend, legend);
625
                callLegendChanged(e);
626
        }
627

    
628
        /**
629
         * Devuelve la Leyenda de la capa.
630
         *
631
         * @return Leyenda.
632
         */
633
        public Legend getLegend() {
634
                return legend;
635
        }
636

    
637
        /**
638
         * Devuelve el tipo de shape que contiene la capa.
639
         *
640
         * @return tipo de shape.
641
         *
642
         * @throws DriverException
643
         */
644
        public int getShapeType() throws DriverException {
645
                if (typeShape == -1) {
646
                        try {
647
                                logger.debug("source.start()");
648
                                getSource().start();
649
                                typeShape = getSource().getShapeType();
650
                                logger.debug("source.stop()");
651
                                getSource().stop();
652
                        } catch (DriverIOException e) {
653
                                throw new DriverException(e);
654
                        }
655
                }
656

    
657
                return typeShape;
658
        }
659

    
660
        /**
661
         * @throws XMLException
662
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
663
         */
664
        public XMLEntity getXMLEntity() throws XMLException {
665
                XMLEntity xml = super.getXMLEntity();
666
                xml.addChild(getLegend().getXMLEntity());
667
                try {
668
                        xml.addChild(getRecordset().getSelectionSupport().getXMLEntity());
669

    
670
                } catch (DriverException e1) {
671
                        e1.printStackTrace();
672
                        throw new XMLException(e1);
673
                }
674
                if (getSource() instanceof VectorialEditableAdapter) {
675
                        setSource(((VectorialEditableAdapter) source).getOriginalAdapter());
676
                }
677
                if (getSource() instanceof VectorialFileAdapter) {
678
                        xml.putProperty("type", "vectorial");
679
                        xml.putProperty("file", ((VectorialFileAdapter) getSource())
680
                                        .getFile());
681
                        // try {
682
                        try {
683
                                xml.putProperty("recordset-name", getSource().getRecordset()
684
                                                .getName());
685
                        } catch (DriverLoadException e) {
686
                                // TODO Auto-generated catch block
687
                                e.printStackTrace();
688
                        }
689
                        // } catch (DriverException e) {
690
                        // throw new XMLException(e);
691
                        // }
692
                } else if (source instanceof VectorialDBAdapter) {
693
                        xml.putProperty("type", "vectorial");
694

    
695
                        VectorialDatabaseDriver dbDriver = (VectorialDatabaseDriver) getSource()
696
                                        .getDriver();
697

    
698
                        // Guardamos el nombre del driver para poder recuperarlo
699
                        // con el DriverManager de Fernando.
700
                        xml.putProperty("db", dbDriver.getName());
701
                        // try {
702
                        try {
703
                                xml.putProperty("recordset-name", getSource().getRecordset()
704
                                                .getName());
705
                        } catch (DriverLoadException e) {
706
                                // TODO Auto-generated catch block
707
                                e.printStackTrace();
708
                        }
709
                        // } catch (DriverException e) {
710
                        // throw new XMLException(e);
711
                        // }
712
                        xml.addChild(dbDriver.getXMLEntity()); // Tercer child. Antes hemos
713
                                                                                                        // metido la leyenda y el
714
                                                                                                        // selection support
715
                } else if (source instanceof VectorialAdapter) {
716
                        // Se supone que hemos hecho algo gen?rico.
717
                        xml.putProperty("type", "vectorial");
718

    
719
                        VectorialDriver driver = (VectorialDriver) getSource().getDriver();
720

    
721
                        // Guardamos el nombre del driver para poder recuperarlo
722
                        // con el DriverManager de Fernando.
723
                        xml.putProperty("other", driver.getName());
724
                        // try {
725
                        try {
726
                                xml.putProperty("recordset-name", getSource().getRecordset()
727
                                                .getName());
728
                        } catch (DriverLoadException e) {
729
                                // TODO Auto-generated catch block
730
                                e.printStackTrace();
731
                        }
732
                        // } catch (DriverException e) {
733
                        // throw new XMLException(e);
734
                        // }
735
                        if (driver instanceof IPersistance) {
736
                                // xml.putProperty("className", driver.getClass().getName());
737
                                IPersistance persist = (IPersistance) driver;
738
                                xml.addChild(persist.getXMLEntity()); // Tercer child. Antes
739
                                                                                                                // hemos metido la
740
                                                                                                                // leyenda y el
741
                                                                                                                // selection support
742
                        }
743
                }
744
                xml.putProperty("driverName", getSource().getDriver().getName());
745
                if (bHasJoin)
746
                        xml.putProperty("hasJoin", "true");
747

    
748
                return xml;
749
        }
750

    
751
        /**
752
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
753
         */
754
        public void setXMLEntity03(XMLEntity xml) throws XMLException {
755

    
756
                super.setXMLEntity(xml);
757
                legend = LegendFactory.createFromXML03(xml.getChild(0));
758

    
759
                try {
760
                        // legend.setDataSource(getRecordset());
761
                        setLegend(legend);
762
                } catch (FieldNotFoundException e) {
763
                        throw new XMLException(e);
764
                } catch (DriverException e) {
765
                        throw new XMLException(e);
766
                }
767

    
768
                try {
769
                        getRecordset().getSelectionSupport()
770
                                        .setXMLEntity03(xml.getChild(1));
771
                } catch (DriverException e) {
772
                        e.printStackTrace();
773
                }
774
        }
775

    
776
        /**
777
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
778
         */
779
        public void setXMLEntity(XMLEntity xml) throws XMLException {
780
                super.setXMLEntity(xml);
781

    
782
                VectorialLegend leg = LegendFactory.createFromXML(xml.getChild(0));
783
                try {
784
                        getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
785
                        String recordsetName = xml.getStringProperty("recordset-name");
786

    
787
                        LayerFactory.getDataSourceFactory().changeDataSourceName(
788
                                        getSource().getRecordset().getName(), recordsetName);
789
                        // Hacemos que el recordset que hemos creado antes (los
790
                        // recordset se crean antes que todo) sea el recordset
791
                        // de esta capa. Y del que se crea automaticamente
792
                        // en el setLegend del createLayer, nos olvidamos
793
                        SelectableDataSource sds = new SelectableDataSource(LayerFactory
794
                                        .getDataSourceFactory().createRandomDataSource(
795
                                                        recordsetName, DataSourceFactory.AUTOMATIC_OPENING));
796
                        // sds.setSelectionSupport(selectionSupport);
797
                        // ((EditableAdapter)getSource()).setRecordSet(sds);
798
                } catch (NoSuchTableException e1) {
799
                        throw new XMLException(e1);
800
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e1) {
801
                        throw new XMLException(e1);
802
                } catch (DriverLoadException e1) {
803
                        throw new XMLException(e1);
804
                } catch (DriverException e1) {
805
                        throw new XMLException(e1);
806
                }
807
                // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
808
                // el final
809
                // de la lectura del proyecto
810
                if (xml.contains("hasJoin")) {
811
                        setIsJoined(true);
812
                        PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
813
                } else {
814
                        try {
815
                                // legend.setDataSource(getRecordset());
816
                                setLegend(leg);
817
                        } catch (FieldNotFoundException e) {
818
                                throw new XMLException(e);
819
                        } catch (DriverException e) {
820
                                throw new XMLException(e);
821
                        }
822
                }
823

    
824
        }
825

    
826
        /**
827
         * A?ade un LegendListener a la lista de Listeners.
828
         *
829
         * @param listener
830
         *            LegendListener.
831
         */
832
        public void addLegendListener(LegendListener listener) {
833
                layerChangeSupport.addLayerListener(listener);
834
        }
835

    
836
        /**
837
         * Llamada al m?todo callLegendChanged de los listener.
838
         *
839
         * @param e
840
         *            Evento.
841
         */
842
        private void callLegendChanged(LegendChangedEvent e) {
843
                layerChangeSupport.callLegendChanged(e);
844
        }
845

    
846
        /**
847
         * Borra un LegendListener de la lista de Listeners
848
         *
849
         * @param listener
850
         *            LegendListener.
851
         */
852
        public void removeLegendListener(LegendListener listener) {
853
                layerChangeSupport.removeLayerListener(listener);
854
        }
855

    
856
        /**
857
         * Sobreimplementaci?n del m?todo toString para que las bases de datos
858
         * identifiquen la capa.
859
         *
860
         * @return DOCUMENT ME!
861
         */
862
        public String toString() {
863
                /*
864
                 * Se usa internamente para que la parte de datos identifique de forma
865
                 * un?voca las tablas
866
                 */
867
                String ret = super.toString();
868

    
869
                return "layer" + ret.substring(ret.indexOf('@') + 1);
870
        }
871

    
872
        public boolean isJoined() {
873
                return bHasJoin;
874
        }
875

    
876
        /**
877
         * Returns if a layer is spatially indexed
878
         *
879
         * @return if this layer has the ability to proces spatial queries without
880
         *         secuential scans.
881
         */
882
        public boolean isSpatiallyIndexed() {
883
                ReadableVectorial source = getSource();
884
                if (source instanceof ISpatialDB)
885
                        return true;
886
                if (getISpatialIndex() != null)
887
                        return true;
888
                return false;
889
        }
890

    
891
        public void setIsJoined(boolean hasJoin) {
892
                bHasJoin = hasJoin;
893
        }
894

    
895
        /**
896
         * @return Returns the spatialIndex.
897
         */
898
        public ISpatialIndex getISpatialIndex() {
899
                return spatialIndex;
900
        }
901

    
902
        /*
903
         * public SelectableDataSource getRecordset() { try { return
904
         * getSource().getRecordset(); } catch (DriverLoadException e) { // TODO
905
         * Auto-generated catch block e.printStackTrace(); } return null; }
906
         */
907

    
908
        /**
909
         * @throws DriverException
910
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getRecordset()
911
         */
912
        public SelectableDataSource getRecordset() throws DriverException {
913
                if (sds == null) {
914
                        try {
915
                                SelectableDataSource ds = source.getRecordset();
916

    
917
                                if (ds == null) {
918
                                        return null;
919
                                }
920

    
921
                                sds = ds;
922
                                sds.setSelectionSupport(selectionSupport);
923

    
924
                        } catch (DriverLoadException e) {
925
                                throw new DriverException(e);
926
                        }
927
                }
928
                return sds;
929
        }
930

    
931
        /*
932
         * (non-Javadoc)
933
         *
934
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setEditing(boolean)
935
         */
936
        public void setEditing(boolean b) throws EditionException {
937
                super.setEditing(b);
938
                try {
939
                        if (b) {
940
                                VectorialEditableAdapter vea = null;
941
                                // TODO: Qu? pasa si hay m?s tipos de adapters?
942
                                // FJP: Se podr?a pasar como argumento el
943
                                // VectorialEditableAdapter
944
                                // que se quiera usar para evitar meter c?digo aqu? de este
945
                                // estilo.
946
                                if (getSource() instanceof VectorialDBAdapter) {
947
                                        vea = new VectorialEditableDBAdapter();
948
                                } else if (this instanceof FLyrAnnotation) {
949
                                        /*if (getSource().getDriver() instanceof AddEventThemeDriver) {
950
                                                vea = new EventThemeAnnotationEditableAdapter(
951
                                                                (FLyrAnnotation) this);
952
                                        } else {*/
953
                                                vea = new AnnotationEditableAdapter(
954
                                                                (FLyrAnnotation) this);
955
                                        //}
956
                                } /*else if (getSource().getDriver() instanceof AddEventThemeDriver) {
957

958
                                        vea = new EventThemeEditableAdapter();
959
                                }*/ else {
960
                                        vea = new VectorialEditableAdapter();
961
                                }
962
                                vea.setOriginalVectorialAdapter(getSource());
963

    
964
                                // /vea.setSpatialIndex(getSpatialIndex());
965
                                // /vea.setFullExtent(getFullExtent());
966
                                vea.startEdition(EditionEvent.GRAPHIC);
967
                                setSource(vea);
968
                                getRecordset().setSelectionSupport(
969
                                                vea.getOriginalAdapter().getRecordset()
970
                                                                .getSelectionSupport());
971

    
972
                        } else {
973
                                VectorialEditableAdapter vea = (VectorialEditableAdapter) getSource();
974
                                setSource(vea.getOriginalAdapter());
975
                        }
976
                        // Si tenemos una leyenda, hay que pegarle el cambiazo a su
977
                        // recordset
978
                        setRecordset(getSource().getRecordset());
979
                        if (getLegend() instanceof VectorialLegend) {
980
                                VectorialLegend ley = (VectorialLegend) getLegend();
981
                                ley.setDataSource(getSource().getRecordset());
982
                                // Esto lo pongo para evitar que al dibujar sobre un
983
                                // dxf, dwg, o dgn no veamos nada. Es debido al checkbox
984
                                // de la leyenda de textos "dibujar solo textos".
985
                                // if (ley.getDefaultSymbol() == null)
986
                                {
987
                                        ley.setDefaultSymbol(new FSymbol(getShapeType()));
988
                                        ley.useDefaultSymbol(true);
989
                                }
990
                        }
991
                } catch (DriverLoadException e) {
992
                        e.printStackTrace();
993
                        throw new EditionException(e);
994
                } catch (DriverException e) {
995
                        e.printStackTrace();
996
                        throw new EditionException(e);
997
                } catch (FieldNotFoundException e) {
998
                        e.printStackTrace();
999
                        throw new EditionException(e);
1000
                }
1001

    
1002
                callEditionChanged(LayerEvent
1003
                                .createEditionChangedEvent(this, "edition"));
1004

    
1005
        }
1006

    
1007
        /**
1008
         * Para cuando haces una uni?n, sustituyes el recorset por el nuevo. De esta
1009
         * forma, podr?s poner leyendas basadas en el nuevo recordset
1010
         *
1011
         * @param newSds
1012
         */
1013
        public void setRecordset(SelectableDataSource newSds) {
1014
                sds = newSds;
1015
                sds.setSelectionSupport(selectionSupport);
1016
        }
1017
        /*
1018
         * public SelectionSupport getSelectionSupport() { return selectionSupport; }
1019
         *
1020
         * public void setSelectionSupport(SelectionSupport selectionSupport) {
1021
         * this.selectionSupport = selectionSupport; }
1022
         */
1023

    
1024
        public SpatialCache getSpatialCache() {
1025
        if (spatialCache == null)
1026
        {
1027
                spatialCache = new SpatialCache();
1028
        }
1029
                return spatialCache;
1030
        }
1031

    
1032
        public void setSpatialCache(SpatialCache spatialCache) {
1033
                this.spatialCache = spatialCache;
1034
        }
1035

    
1036
        public boolean isSpatialCacheEnabled() {
1037
                return spatialCacheEnabled;
1038
        }
1039

    
1040
        public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
1041
                this.spatialCacheEnabled = spatialCacheEnabled;
1042
        }
1043

    
1044
}