Statistics
| Revision:

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

History | View | Annotate | Download (31.2 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.drivers.shp.IndexedShpDriver;
67
import com.iver.cit.gvsig.fmap.edition.AnnotationEditableAdapter;
68
import com.iver.cit.gvsig.fmap.edition.EditionEvent;
69
import com.iver.cit.gvsig.fmap.edition.EditionException;
70
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
71
import com.iver.cit.gvsig.fmap.edition.VectorialEditableDBAdapter;
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.InfoByPoint;
75
import com.iver.cit.gvsig.fmap.layers.layerOperations.Labelable;
76
import com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData;
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.layers.layerOperations.VectorialXMLItem;
80
import com.iver.cit.gvsig.fmap.layers.layerOperations.XMLItem;
81
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
82
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
83
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
84
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
85
import com.iver.cit.gvsig.fmap.rendering.Legend;
86
import com.iver.cit.gvsig.fmap.rendering.LegendChangedEvent;
87
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
88
import com.iver.cit.gvsig.fmap.rendering.SingleSymbolLegend;
89
import com.iver.cit.gvsig.fmap.rendering.VectorialLegend;
90
import com.iver.cit.gvsig.fmap.spatialindex.IPersistentSpatialIndex;
91
import com.iver.cit.gvsig.fmap.spatialindex.ISpatialIndex;
92
import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeJts;
93
import com.iver.cit.gvsig.fmap.spatialindex.RTreeSptLib;
94
import com.iver.cit.gvsig.fmap.spatialindex.SpatialIndexException;
95
import com.iver.utiles.FileUtils;
96
import com.iver.utiles.IPersistance;
97
import com.iver.utiles.PostProcessSupport;
98
import com.iver.utiles.XMLEntity;
99
import com.iver.utiles.swing.threads.Cancellable;
100
import com.iver.utiles.swing.threads.CancellableMonitorable;
101

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

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

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

    
117
        private int typeShape = -1;
118

    
119
        private LayerChangeSupport layerChangeSupport = new LayerChangeSupport();
120

    
121
        private ReadableVectorial source;
122

    
123
        private SelectableDataSource sds;
124

    
125
        private SelectionSupport selectionSupport = new SelectionSupport();
126

    
127
        private SpatialCache spatialCache = null;
128
        private boolean spatialCacheEnabled = true;
129

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

    
136
        private boolean bHasJoin = false;
137

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
345
        /**
346
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#createLabelLayer(int)
347
         */
348
        // public FLayer createLabelLayer(int fieldId) {
349
        public FLayer createLabelLayer(SelectableDataSource ds) {
350
                FLyrText layerText = null;
351
                try {
352
                        layerText = new FLyrText();
353
                        layerText.setLegend((VectorialLegend) getLegend());
354
                        layerText.createLabels(this);
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
                layerText.setCoordTrans(getCoordTrans());
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
        /*
376
         * (non-Javadoc)
377
         *
378
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#deleteSpatialIndex()
379
         */
380
        public void deleteSpatialIndex() {
381
                spatialIndex = null;
382
        }
383

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
558
                return item;
559
        }
560

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

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

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

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

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

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

    
658
                return typeShape;
659
        }
660

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

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

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

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

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

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

    
749
                return xml;
750
        }
751

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

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

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

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

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

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

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

    
825
        }
826

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
957
                                // /vea.setSpatialIndex(getSpatialIndex());
958
                                // /vea.setFullExtent(getFullExtent());
959
                                vea.startEdition(EditionEvent.GRAPHIC);
960
                                setSource(vea);
961
                                getRecordset().setSelectionSupport(
962
                                                vea.getOriginalAdapter().getRecordset()
963
                                                                .getSelectionSupport());
964

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

    
994
                callEditionChanged(LayerEvent
995
                                .createEditionChangedEvent(this, "edition"));
996

    
997
        }
998

    
999
        /**
1000
         * Para cuando haces una uni?n, sustituyes el recorset por el nuevo. De esta
1001
         * forma, podr?s poner leyendas basadas en el nuevo recordset
1002
         *
1003
         * @param newSds
1004
         */
1005
        public void setRecordset(SelectableDataSource newSds) {
1006
                sds = newSds;
1007
                sds.setSelectionSupport(selectionSupport);
1008
        }
1009
        /*
1010
         * public SelectionSupport getSelectionSupport() { return selectionSupport; }
1011
         *
1012
         * public void setSelectionSupport(SelectionSupport selectionSupport) {
1013
         * this.selectionSupport = selectionSupport; }
1014
         */
1015

    
1016
        public SpatialCache createSpatialCache() {
1017
               spatialCache = new SpatialCache();
1018
                return spatialCache;
1019
        }
1020

    
1021
//        public void setSpatialCache(SpatialCache spatialCache) {
1022
//                this.spatialCache = spatialCache;
1023
//        }
1024

    
1025
        public boolean isSpatialCacheEnabled() {
1026
                return spatialCacheEnabled;
1027
        }
1028

    
1029
        public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
1030
                this.spatialCacheEnabled = spatialCacheEnabled;
1031
        }
1032

    
1033
        public SpatialCache getSpatialCache() {
1034
                return spatialCache;
1035
        }
1036

    
1037
}