Statistics
| Revision:

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

History | View | Annotate | Download (32.6 KB)

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

    
43
import java.awt.Graphics2D;
44
import java.awt.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.QuadtreeGt2;
93
import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeJts;
94
import com.iver.cit.gvsig.fmap.spatialindex.RTreeJsi;
95
import com.iver.cit.gvsig.fmap.spatialindex.RTreeSptLib;
96
import com.iver.cit.gvsig.fmap.spatialindex.SpatialIndexException;
97
import com.iver.utiles.FileUtils;
98
import com.iver.utiles.IPersistance;
99
import com.iver.utiles.PostProcessSupport;
100
import com.iver.utiles.XMLEntity;
101
import com.iver.utiles.swing.threads.Cancellable;
102
import com.iver.utiles.swing.threads.CancellableMonitorable;
103

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

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

    
116
        /** Leyenda de la capa vectorial */
117
        private VectorialLegend legend;
118

    
119
        private int typeShape = -1;
120

    
121
        private LayerChangeSupport layerChangeSupport = new LayerChangeSupport();
122

    
123
        private ReadableVectorial source;
124

    
125
        private SelectableDataSource sds;
126

    
127
        private SelectionSupport selectionSupport = new SelectionSupport();
128

    
129
        private SpatialCache spatialCache = null;
130
        private boolean spatialCacheEnabled = true;
131

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

    
138
        private boolean bHasJoin = false;
139

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

    
183
        /**
184
         * If we use a persistent spatial index associated with this layer, and the
185
         * index is not intrisic to the layer (for example spatial databases) this
186
         * method looks for existent spatial index, and loads it.
187
         *
188
         */
189
        private void loadSpatialIndex() {
190
                //FIXME: Al abrir el indice en fichero...
191
                //?C?mo lo liberamos? un metodo Layer.shutdown()
192

    
193

    
194
                ReadableVectorial source = getSource();
195
                //REVISAR QUE PASA CON LOS DRIVERS DXF, DGN, etc.
196
                //PUES SON VECTORIALFILEADAPTER
197
                if (!(source instanceof VectorialFileAdapter)) {
198
                        // we are not interested in db adapters
199
                        return;
200
                }
201
                VectorialDriver driver = source.getDriver();
202
                if (!(driver instanceof BoundedShapes)) {
203
                        // we dont spatially index layers that are not bounded
204
                        return;
205
                }
206
                File file = ((VectorialFileAdapter) source).getFile();
207
                String fileName = file.getAbsolutePath();
208
                File sptFile = new File(fileName + ".qix");
209
                if (!sptFile.exists() || (!(sptFile.length() > 0))) {
210
                        // before to exit, look for it in temp path
211
                        String tempPath = System.getProperty("java.io.tmpdir");
212
                        fileName = tempPath + File.separator + sptFile.getName();
213
                        sptFile = new File(fileName);
214
                        // it doesnt exists, must to create
215
                        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
216
                                return;
217
                        }// if
218
                }// if
219

    
220
                try {
221
                        source.start();
222
                        spatialIndex = new QuadtreeGt2(FileUtils.getFileWithoutExtension(sptFile),
223
                                        "NM", source.getFullExtent(), source.getShapeCount(), false);
224
                } catch (SpatialIndexException e) {
225
                        spatialIndex = null;
226
                        e.printStackTrace();
227
                        return;
228
                } catch (DriverIOException e) {
229
                        // TODO Auto-generated catch block
230
                        e.printStackTrace();
231
                }
232

    
233
        }
234

    
235
        /**
236
         * Checks if it has associated an external spatial index
237
         * (an spatial index file).
238
         *
239
         * It looks for it in main file path, or in temp system path.
240
         * If main file is rivers.shp, it looks for a file called
241
         * rivers.shp.qix.
242

243
         * @return
244
         */
245
        public boolean isExternallySpatiallyIndexed() {
246
                /*
247
                 * FIXME (AZABALA): Independizar del tipo de fichero de ?ndice
248
                  * con el que se trabaje (ahora mismo considera la extension .qix,
249
             * pero esto depender? del tipo de ?ndice)
250
                 * */
251
                ReadableVectorial source = getSource();
252
                if (!(source instanceof VectorialFileAdapter)) {
253
                        // we are not interested in db adapters.
254
                        // think in non spatial dbs, like HSQLDB
255
                        return false;
256
                }
257
                File file = ((VectorialFileAdapter) source).getFile();
258
                String fileName = file.getAbsolutePath();
259
                File sptFile = new File(fileName + ".qix");
260
                if (!sptFile.exists() || (!(sptFile.length() > 0))) {
261
                        // before to exit, look for it in temp path
262
                        // it doesnt exists, must to create
263
                        String tempPath = System.getProperty("java.io.tmpdir");
264
                        fileName = tempPath + File.separator + sptFile.getName();
265
                        sptFile = new File(fileName);
266
                        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
267
                                return false;
268
                        }// if
269
                }// if
270
                return true;
271
        }
272

    
273
        /**
274
         * Inserta el VectorialAdapter a la capa.
275
         *
276
         * @param va
277
         *            VectorialAdapter.
278
         */
279
        public void setSource(ReadableVectorial rv) {
280
                source = rv;
281
                // azabala: we check if this layer could have a file spatial index
282
                // and load it if it exists
283
                loadSpatialIndex();
284
        }
285

    
286
        /**
287
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#getFullExtent()
288
         */
289
        public Rectangle2D getFullExtent() throws DriverException {
290
                try {
291
                        Rectangle2D rAux;
292
                        logger.debug(getName() + "_source.start()");
293
                        source.start();
294
                        rAux = source.getFullExtent();
295
                        logger.debug(getName() + "_source.stop()");
296
                        source.stop();
297

    
298
                        // Si existe reproyecci?n, reproyectar el extent
299
                        ICoordTrans ct = getCoordTrans();
300

    
301
                        if (ct != null) {
302
                                Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
303
                                Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
304
                                pt1 = ct.convert(pt1, null);
305
                                pt2 = ct.convert(pt2, null);
306
                                rAux = new Rectangle2D.Double();
307
                                rAux.setFrameFromDiagonal(pt1, pt2);
308
                        }
309

    
310
                        return rAux;
311
                } catch (DriverIOException e) {
312
                        throw new DriverException(e);
313
                }
314
        }
315

    
316
        /**
317
         * @see com.iver.cit.gvsig.fmap.layers.LayerOperations#draw(java.awt.image.BufferedImage,
318
         *      java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort)
319
         */
320
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
321
                        Cancellable cancel, double scale) throws DriverException {
322

    
323
                if (isWithinScale(scale)) {
324
                        // Las que solo tienen etiquetado sin pintar el shape,
325
                        // no pasamos por ellas
326
                        boolean bDrawShapes = true;
327
                        if (legend instanceof SingleSymbolLegend) {
328
                                if (legend.getDefaultSymbol().isShapeVisible() == false)
329
                                        bDrawShapes = false;
330
                        }
331
                        if (bDrawShapes) {
332
                                Strategy strategy = StrategyManager.getStrategy(this);
333
                                try {
334
                                        strategy.draw(image, g, viewPort, cancel);
335
                                } catch (DriverException e) {
336
                                        this.setVisible(false);
337
                                        this.setActive(false);
338
                                        throw e;
339
                                }
340
                        }
341
                        if (getVirtualLayers() != null) {
342
                                getVirtualLayers().draw(image, g, viewPort, cancel, scale);
343
                        }
344

    
345
                        if (getLayerText() != null) {
346
                                getLayerText().draw(image, g, viewPort, cancel, scale);
347
                        }
348
                }
349
        }
350

    
351
        /**
352
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
353
         *      com.iver.cit.gvsig.fmap.ViewPort,
354
         *      com.iver.utiles.swing.threads.Cancellable)
355
         */
356
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
357
                        double scale) throws DriverException {
358
                if (isVisible() && isWithinScale(scale)) {
359
                        Strategy strategy = StrategyManager.getStrategy(this);
360

    
361
                        strategy.print(g, viewPort, cancel);
362

    
363
                        if (getLayerText() != null) {
364
                                getLayerText().draw(null, g, viewPort, cancel, scale);
365
                        }
366
                }
367
        }
368

    
369
        /**
370
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#createLabelLayer(int)
371
         */
372
        // public FLayer createLabelLayer(int fieldId) {
373
        public FLayer createLabelLayer(SelectableDataSource ds) {
374
                FLyrText layerText = null;
375
                try {
376
                        layerText = new FLyrText();
377
                        layerText.setLegend((VectorialLegend) getLegend());
378
                        layerText.createLabels(this);
379
                } catch (FieldNotFoundException e1) {
380
                        // TODO Auto-generated catch block
381
                        e1.printStackTrace();
382
                } catch (DriverException e1) {
383
                        // TODO Auto-generated catch block
384
                        e1.printStackTrace();
385
                }
386

    
387
                setLayerText(layerText);
388
                layerText.setCoordTrans(getCoordTrans());
389
                return layerText;
390
        }
391

    
392
        /**
393
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#removeLabels()
394
         */
395
        public void removeLabels() {
396
                setLayerText(null);
397
        }
398

    
399
        /*
400
         * (non-Javadoc)
401
         *
402
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#deleteSpatialIndex()
403
         */
404
        public void deleteSpatialIndex() {
405
                //must we delete possible spatial indexes files?
406
                spatialIndex = null;
407
        }
408

    
409

    
410

    
411
   /**
412
    * <p>
413
    * Creates an spatial index associated to this layer.
414
    * The spatial index will used
415
    * the native projection of the layer, so if the layer is reprojected, it will
416
    * be ignored.
417
    * </p>
418
    * @param cancelMonitor instance of CancellableMonitorable that allows
419
    * to monitor progress of spatial index creation, and cancel the process
420
    */
421
    public void createSpatialIndex(CancellableMonitorable cancelMonitor){
422
             // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
423
        // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
424
        // para que acepten recorrer sin geometria, solo con rectangulos.
425

    
426
            //If this vectorial layer is based in a spatial database, the spatial
427
                //index is already implicit. We only will index file drivers
428
            ReadableVectorial va = getSource();
429
            //We must think in non spatial databases, like HSQLDB
430
                if(!(va instanceof VectorialFileAdapter)){
431
                        return;
432
                }
433
                if (!(va.getDriver() instanceof BoundedShapes)) {
434
                        return;
435
                }
436
                File file = ((VectorialFileAdapter) va).getFile();
437
                String fileName = file.getAbsolutePath();
438
                ISpatialIndex localCopy = null;
439
                try {
440
                        va.start();
441
                        localCopy = new QuadtreeGt2(fileName, "NM", va.getFullExtent(),
442
                                        va.getShapeCount(), true);
443

    
444
                } catch (SpatialIndexException e1) {
445
                        // Probably we dont have writing permissions
446
                        String directoryName = System.getProperty("java.io.tmpdir");
447
                        File newFile = new File(directoryName +
448
                                        File.separator +
449
                                        file.getName());
450
                        String newFileName = newFile.getName();
451
                        try {
452
                                localCopy = new QuadtreeGt2(newFileName, "NM", va.getFullExtent(),
453
                                                va.getShapeCount(), true);
454
                        } catch (SpatialIndexException e) {
455
                                // if we cant build a file based spatial index, we'll build
456
                                // a pure memory spatial index
457
                                localCopy = new QuadtreeJts();
458
                        } catch (DriverIOException e) {
459
                                // TODO Auto-generated catch block
460
                                e.printStackTrace();
461
                        }
462

    
463
                }catch(Exception e){
464
                        e.printStackTrace();
465
                }//try
466
        BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
467
        try {
468
            for (int i=0; i < va.getShapeCount(); i++)
469
            {
470
                    if(cancelMonitor != null){
471
                            if(cancelMonitor.isCanceled())
472
                                    return;
473
                            cancelMonitor.reportStep();
474
                    }
475
                Rectangle2D r = shapeBounds.getShapeBounds(i);
476
                localCopy.insert(r, i);
477
            } // for
478
            va.stop();
479
            if(localCopy instanceof IPersistentSpatialIndex)
480
                    ((IPersistentSpatialIndex) localCopy).flush();
481
            spatialIndex = localCopy;
482
        } catch (DriverIOException e) {
483
            // TODO Auto-generated catch block
484
            e.printStackTrace();
485
        } catch (IOException e) {
486
            // TODO Auto-generated catch block
487
            e.printStackTrace();
488
        }
489
    }
490

    
491
        /**
492
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#createIndex()
493
         */
494
        public void createSpatialIndex() {
495
                createSpatialIndex(null);
496
        }
497

    
498
        /**
499
         * @see com.iver.cit.gvsig.fmap.layers.VectorialOperations#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor,
500
         *      FBitSet)
501
         */
502
        public void process(FeatureVisitor visitor, FBitSet subset)
503
                        throws DriverException, VisitException {
504
                Strategy s = StrategyManager.getStrategy(this);
505
                s.process(visitor, subset);
506
        }
507

    
508
        /**
509
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor)
510
         */
511
        public void process(FeatureVisitor visitor) throws DriverException,
512
                        VisitException {
513
                Strategy s = StrategyManager.getStrategy(this);
514
                s.process(visitor);
515
        }
516

    
517
        /**
518
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor,
519
         *      Rectangle2D)
520
         */
521
        public void process(FeatureVisitor visitor, Rectangle2D rect)
522
                        throws DriverException, VisitException {
523
                Strategy s = StrategyManager.getStrategy(this);
524
                s.process(visitor, rect);
525
        }
526

    
527
        /**
528
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setSelection(com.iver.cit.gvsig.fmap.operations.selection.VectorialSubSet)
529
         */
530
        /*
531
         * public void setSelection(FBitSet selection) { try {
532
         * getRecordset().setSelection(selection); } catch (DriverException e) { //
533
         * TODO Auto-generated catch block e.printStackTrace(); }
534
         * fireSelectionEvents(); }
535
         */
536
        /**
537
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#isSelected(int)
538
         */
539
        /*
540
         * public boolean isSelected(int index) { try { return
541
         * getRecordset().isSelected(index); } catch (DriverException e) { // TODO
542
         * Auto-generated catch block e.printStackTrace(); } return false; }
543
         */
544
        /**
545
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getSelection()
546
         */
547
        /*
548
         * public FBitSet getSelection() { try { return
549
         * getRecordset().getSelection(); } catch (DriverException e) { // TODO
550
         * Auto-generated catch block e.printStackTrace(); } return new FBitSet(); }
551
         */
552
        /**
553
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#clearSelection()
554
         */
555
        /*
556
         * public void clearSelection() { try { getRecordset().clearSelection(); }
557
         * catch (DriverException e) { // TODO Auto-generated catch block
558
         * e.printStackTrace(); } }
559
         */
560

    
561
        /*
562
         * (non-Javadoc)
563
         *
564
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData#queryByRect(java.awt.geom.Rectangle2D)
565
         */
566
        public FBitSet queryByRect(Rectangle2D rect) throws DriverException {
567
                Strategy s = StrategyManager.getStrategy(this);
568

    
569
                return s.queryByRect(rect);
570
        }
571

    
572
        public FBitSet queryByPoint(Point2D p, double tolerance)
573
                        throws DriverException {
574
                Strategy s = StrategyManager.getStrategy(this);
575
                return s.queryByPoint(p, tolerance);
576
        }
577

    
578
        public FBitSet queryByShape(IGeometry g, int relationship)
579
                        throws DriverException, VisitException {
580
                Strategy s = StrategyManager.getStrategy(this);
581
                return s.queryByShape(g, relationship);
582
        }
583

    
584
        public XMLItem[] getInfo(Point p, double tolerance) throws DriverException {
585
                Point2D pReal = this.getFMap().getViewPort().toMapPoint(p);
586
                FBitSet bs = queryByPoint(pReal, tolerance);
587
                VectorialXMLItem[] item = new VectorialXMLItem[1];
588
                item[0] = new VectorialXMLItem(bs, this);
589

    
590
                return item;
591
        }
592

    
593
        /**
594
         * @throws DriverException
595
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getRecordset()
596
         */
597
        /*
598
         * public SelectableDataSource getRecordset() throws DriverException { if
599
         * (sds == null){ try { DataSource ds = getSource().getRecordset();
600
         *
601
         * if (ds == null) { return null; }
602
         *
603
         * sds = new SelectableDataSource(ds);
604
         * //sds.setSelectionSupport(selectionSupport);
605
         *
606
         * return sds; } catch (DriverLoadException e) { throw new
607
         * DriverException(e); } catch
608
         * (com.hardcode.gdbms.engine.data.driver.DriverException e) { throw new
609
         * DriverException(e); } } return sds; }
610
         */
611
        /**
612
         * Para cuando haces una uni?n, sustituyes el recorset por el nuevo. De esta
613
         * forma, podr?s poner leyendas basadas en el nuevo recordset
614
         *
615
         * @param newSds
616
         * @throws DriverException
617
         * @throws FieldNotFoundException
618
         * @throws FieldNotFoundException
619
         */
620
        /*
621
         * public void setRecordset(SelectableDataSource newSds) throws
622
         * DriverException, FieldNotFoundException { sds = newSds;
623
         * //sds.setSelectionSupport(selectionSupport); legend.setDataSource(sds);
624
         * logger.debug("Recordset cambiado a " + sds.getName()); }
625
         */
626
        /**
627
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#setLegend(int,
628
         *      com.iver.cit.gvsig.fmap.rendering.Legend)
629
         */
630
        public void setLegend(VectorialLegend r) throws DriverException,
631
                        FieldNotFoundException {
632
                VectorialLegend oldLegend = legend;
633
                legend = r;
634

    
635
                try {
636
                        legend.setDataSource(getRecordset());
637

    
638
                        if (legend.getLabelField() != null) {
639
                                // sds.start();
640
                                // int idLabelField =
641
                                // getRecordset().getFieldIndexByName(legend.getLabelField());
642
                                createLabelLayer(getSource().getRecordset());
643
                                // sds.stop();
644
                        } else
645
                                removeLabels();
646
                } catch (DriverException e) {
647
                        throw new DriverException(e);
648
                } catch (FieldNotFoundException e) {
649
                        // TODO Auto-generated catch block
650
                        e.printStackTrace();
651
                } catch (DriverLoadException e) {
652
                        // TODO Auto-generated catch block
653
                        e.printStackTrace();
654
                }
655

    
656
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
657
                                oldLegend, legend);
658
                callLegendChanged(e);
659
        }
660

    
661
        /**
662
         * Devuelve la Leyenda de la capa.
663
         *
664
         * @return Leyenda.
665
         */
666
        public Legend getLegend() {
667
                return legend;
668
        }
669

    
670
        /**
671
         * Devuelve el tipo de shape que contiene la capa.
672
         *
673
         * @return tipo de shape.
674
         *
675
         * @throws DriverException
676
         */
677
        public int getShapeType() throws DriverException {
678
                if (typeShape == -1) {
679
                        try {
680
                                logger.debug("source.start()");
681
                                getSource().start();
682
                                typeShape = getSource().getShapeType();
683
                                logger.debug("source.stop()");
684
                                getSource().stop();
685
                        } catch (DriverIOException e) {
686
                                throw new DriverException(e);
687
                        }
688
                }
689

    
690
                return typeShape;
691
        }
692

    
693
        /**
694
         * @throws XMLException
695
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperties()
696
         */
697
        public XMLEntity getXMLEntity() throws XMLException {
698
                XMLEntity xml = super.getXMLEntity();
699
                xml.addChild(getLegend().getXMLEntity());
700
                try {
701
                        xml.addChild(getRecordset().getSelectionSupport().getXMLEntity());
702

    
703
                } catch (DriverException e1) {
704
                        e1.printStackTrace();
705
                        throw new XMLException(e1);
706
                }
707
                //Repongo el mismo ReadableVectorial m?s abajo para cuando se guarda el proyecto.
708
                ReadableVectorial rv=getSource();
709
                if (getSource() instanceof VectorialEditableAdapter) {
710
                        setSource(((VectorialEditableAdapter) source).getOriginalAdapter());
711
                }
712
                if (getSource() instanceof VectorialFileAdapter) {
713
                        xml.putProperty("type", "vectorial");
714
                        xml.putProperty("file", ((VectorialFileAdapter) getSource())
715
                                        .getFile());
716
                        // try {
717
                        try {
718
                                xml.putProperty("recordset-name", getSource().getRecordset()
719
                                                .getName());
720
                        } catch (DriverLoadException e) {
721
                                // TODO Auto-generated catch block
722
                                e.printStackTrace();
723
                        }
724
                        // } catch (DriverException e) {
725
                        // throw new XMLException(e);
726
                        // }
727
                } else if (source instanceof VectorialDBAdapter) {
728
                        xml.putProperty("type", "vectorial");
729

    
730
                        VectorialDatabaseDriver dbDriver = (VectorialDatabaseDriver) getSource()
731
                                        .getDriver();
732

    
733
                        // Guardamos el nombre del driver para poder recuperarlo
734
                        // con el DriverManager de Fernando.
735
                        xml.putProperty("db", dbDriver.getName());
736
                        // try {
737
                        try {
738
                                xml.putProperty("recordset-name", getSource().getRecordset()
739
                                                .getName());
740
                        } catch (DriverLoadException e) {
741
                                // TODO Auto-generated catch block
742
                                e.printStackTrace();
743
                        }
744
                        // } catch (DriverException e) {
745
                        // throw new XMLException(e);
746
                        // }
747
                        xml.addChild(dbDriver.getXMLEntity()); // Tercer child. Antes hemos
748
                                                                                                        // metido la leyenda y el
749
                                                                                                        // selection support
750
                } else if (source instanceof VectorialAdapter) {
751
                        // Se supone que hemos hecho algo gen?rico.
752
                        xml.putProperty("type", "vectorial");
753

    
754
                        VectorialDriver driver = (VectorialDriver) getSource().getDriver();
755

    
756
                        // Guardamos el nombre del driver para poder recuperarlo
757
                        // con el DriverManager de Fernando.
758
                        xml.putProperty("other", driver.getName());
759
                        // try {
760
                        try {
761
                                xml.putProperty("recordset-name", getSource().getRecordset()
762
                                                .getName());
763
                        } catch (DriverLoadException e) {
764
                                // TODO Auto-generated catch block
765
                                e.printStackTrace();
766
                        }
767
                        // } catch (DriverException e) {
768
                        // throw new XMLException(e);
769
                        // }
770
                        if (driver instanceof IPersistance) {
771
                                // xml.putProperty("className", driver.getClass().getName());
772
                                IPersistance persist = (IPersistance) driver;
773
                                xml.addChild(persist.getXMLEntity()); // Tercer child. Antes
774
                                                                                                                // hemos metido la
775
                                                                                                                // leyenda y el
776
                                                                                                                // selection support
777
                        }
778
                }
779
                setSource(rv);
780
                xml.putProperty("driverName", getSource().getDriver().getName());
781
                if (bHasJoin)
782
                        xml.putProperty("hasJoin", "true");
783

    
784
                return xml;
785
        }
786

    
787
        /**
788
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
789
         */
790
        public void setXMLEntity03(XMLEntity xml) throws XMLException {
791

    
792
                super.setXMLEntity(xml);
793
                legend = LegendFactory.createFromXML03(xml.getChild(0));
794

    
795
                try {
796
                        // legend.setDataSource(getRecordset());
797
                        setLegend(legend);
798
                } catch (FieldNotFoundException e) {
799
                        throw new XMLException(e);
800
                } catch (DriverException e) {
801
                        throw new XMLException(e);
802
                }
803

    
804
                try {
805
                        getRecordset().getSelectionSupport()
806
                                        .setXMLEntity03(xml.getChild(1));
807
                } catch (DriverException e) {
808
                        e.printStackTrace();
809
                }
810
        }
811

    
812
        /**
813
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
814
         */
815
        public void setXMLEntity(XMLEntity xml) throws XMLException {
816
                super.setXMLEntity(xml);
817

    
818
                VectorialLegend leg = LegendFactory.createFromXML(xml.getChild(0));
819
                try {
820
                        getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
821
                        String recordsetName = xml.getStringProperty("recordset-name");
822

    
823
                        LayerFactory.getDataSourceFactory().changeDataSourceName(
824
                                        getSource().getRecordset().getName(), recordsetName);
825
                        // Hacemos que el recordset que hemos creado antes (los
826
                        // recordset se crean antes que todo) sea el recordset
827
                        // de esta capa. Y del que se crea automaticamente
828
                        // en el setLegend del createLayer, nos olvidamos
829
                        SelectableDataSource sds = new SelectableDataSource(LayerFactory
830
                                        .getDataSourceFactory().createRandomDataSource(
831
                                                        recordsetName, DataSourceFactory.AUTOMATIC_OPENING));
832
                        // sds.setSelectionSupport(selectionSupport);
833
                        // ((EditableAdapter)getSource()).setRecordSet(sds);
834
                } catch (NoSuchTableException e1) {
835
                        throw new XMLException(e1);
836
                } catch (com.hardcode.gdbms.engine.data.driver.DriverException e1) {
837
                        throw new XMLException(e1);
838
                } catch (DriverLoadException e1) {
839
                        throw new XMLException(e1);
840
                } catch (DriverException e1) {
841
                        throw new XMLException(e1);
842
                }
843
                // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
844
                // el final
845
                // de la lectura del proyecto
846
                if (xml.contains("hasJoin")) {
847
                        setIsJoined(true);
848
                        PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
849
                } else {
850
                        try {
851
                                // legend.setDataSource(getRecordset());
852
                                setLegend(leg);
853
                        } catch (FieldNotFoundException e) {
854
                                throw new XMLException(e);
855
                        } catch (DriverException e) {
856
                                throw new XMLException(e);
857
                        }
858
                }
859

    
860
        }
861

    
862
        /**
863
         * A?ade un LegendListener a la lista de Listeners.
864
         *
865
         * @param listener
866
         *            LegendListener.
867
         */
868
        public void addLegendListener(LegendListener listener) {
869
                layerChangeSupport.addLayerListener(listener);
870
        }
871

    
872
        /**
873
         * Llamada al m?todo callLegendChanged de los listener.
874
         *
875
         * @param e
876
         *            Evento.
877
         */
878
        private void callLegendChanged(LegendChangedEvent e) {
879
                layerChangeSupport.callLegendChanged(e);
880
        }
881

    
882
        /**
883
         * Borra un LegendListener de la lista de Listeners
884
         *
885
         * @param listener
886
         *            LegendListener.
887
         */
888
        public void removeLegendListener(LegendListener listener) {
889
                layerChangeSupport.removeLayerListener(listener);
890
        }
891

    
892
        /**
893
         * Sobreimplementaci?n del m?todo toString para que las bases de datos
894
         * identifiquen la capa.
895
         *
896
         * @return DOCUMENT ME!
897
         */
898
        public String toString() {
899
                /*
900
                 * Se usa internamente para que la parte de datos identifique de forma
901
                 * un?voca las tablas
902
                 */
903
                String ret = super.toString();
904

    
905
                return "layer" + ret.substring(ret.indexOf('@') + 1);
906
        }
907

    
908
        public boolean isJoined() {
909
                return bHasJoin;
910
        }
911

    
912
        /**
913
         * Returns if a layer is spatially indexed
914
         *
915
         * @return if this layer has the ability to proces spatial queries without
916
         *         secuential scans.
917
         */
918
        public boolean isSpatiallyIndexed() {
919
                ReadableVectorial source = getSource();
920
                if (source instanceof ISpatialDB)
921
                        return true;
922
                if (getISpatialIndex() != null)
923
                        return true;
924
                return false;
925
        }
926

    
927
        public void setIsJoined(boolean hasJoin) {
928
                bHasJoin = hasJoin;
929
        }
930

    
931
        /**
932
         * @return Returns the spatialIndex.
933
         */
934
        public ISpatialIndex getISpatialIndex() {
935
                return spatialIndex;
936
        }
937

    
938
        /*
939
         * public SelectableDataSource getRecordset() { try { return
940
         * getSource().getRecordset(); } catch (DriverLoadException e) { // TODO
941
         * Auto-generated catch block e.printStackTrace(); } return null; }
942
         */
943

    
944
        /**
945
         * @throws DriverException
946
         * @see com.iver.cit.gvsig.fmap.layers.CommonOperations#getRecordset()
947
         */
948
        public SelectableDataSource getRecordset() throws DriverException {
949
                if (sds == null) {
950
                        try {
951
                                SelectableDataSource ds = source.getRecordset();
952

    
953
                                if (ds == null) {
954
                                        return null;
955
                                }
956

    
957
                                sds = ds;
958
                                sds.setSelectionSupport(selectionSupport);
959

    
960
                        } catch (DriverLoadException e) {
961
                                throw new DriverException(e);
962
                        }
963
                }
964
                return sds;
965
        }
966

    
967
        /*
968
         * (non-Javadoc)
969
         *
970
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setEditing(boolean)
971
         */
972
        public void setEditing(boolean b) throws EditionException {
973
                super.setEditing(b);
974
                try {
975
                        if (b) {
976
                                VectorialEditableAdapter vea = null;
977
                                // TODO: Qu? pasa si hay m?s tipos de adapters?
978
                                // FJP: Se podr?a pasar como argumento el
979
                                // VectorialEditableAdapter
980
                                // que se quiera usar para evitar meter c?digo aqu? de este
981
                                // estilo.
982
                                if (getSource() instanceof VectorialDBAdapter) {
983
                                        vea = new VectorialEditableDBAdapter();
984
                                } else if (this instanceof FLyrAnnotation) {
985
                                        vea = new AnnotationEditableAdapter(
986
                                                        (FLyrAnnotation) this);
987
                                } else {
988
                                        vea = new VectorialEditableAdapter();
989
                                }
990
                                vea.setOriginalVectorialAdapter(getSource());
991

    
992
                                // /vea.setSpatialIndex(getSpatialIndex());
993
                                // /vea.setFullExtent(getFullExtent());
994
                                vea.startEdition(EditionEvent.GRAPHIC);
995
                                setSource(vea);
996
                                getRecordset().setSelectionSupport(
997
                                                vea.getOriginalAdapter().getRecordset()
998
                                                                .getSelectionSupport());
999

    
1000
                        } else {
1001
                                VectorialEditableAdapter vea = (VectorialEditableAdapter) getSource();
1002
                                setSource(vea.getOriginalAdapter());
1003
                        }
1004
                        // Si tenemos una leyenda, hay que pegarle el cambiazo a su
1005
                        // recordset
1006
                        setRecordset(getSource().getRecordset());
1007
                        if (getLegend() instanceof VectorialLegend) {
1008
                                VectorialLegend ley = (VectorialLegend) getLegend();
1009
                                ley.setDataSource(getSource().getRecordset());
1010
                                // Esto lo pongo para evitar que al dibujar sobre un
1011
                                // dxf, dwg, o dgn no veamos nada. Es debido al checkbox
1012
                                // de la leyenda de textos "dibujar solo textos".
1013
                                if (!(getSource().getDriver() instanceof IndexedShpDriver)){
1014
                                        ley.setDefaultSymbol(new FSymbol(getShapeType()));
1015
                                }
1016
                                ley.useDefaultSymbol(true);
1017
                        }
1018
                } catch (DriverLoadException e) {
1019
                        e.printStackTrace();
1020
                        throw new EditionException(e);
1021
                } catch (DriverException e) {
1022
                        e.printStackTrace();
1023
                        throw new EditionException(e);
1024
                } catch (FieldNotFoundException e) {
1025
                        e.printStackTrace();
1026
                        throw new EditionException(e);
1027
                }
1028

    
1029
                callEditionChanged(LayerEvent
1030
                                .createEditionChangedEvent(this, "edition"));
1031

    
1032
        }
1033

    
1034
        /**
1035
         * Para cuando haces una uni?n, sustituyes el recorset por el nuevo. De esta
1036
         * forma, podr?s poner leyendas basadas en el nuevo recordset
1037
         *
1038
         * @param newSds
1039
         */
1040
        public void setRecordset(SelectableDataSource newSds) {
1041
                sds = newSds;
1042
                sds.setSelectionSupport(selectionSupport);
1043
        }
1044
        /*
1045
         * public SelectionSupport getSelectionSupport() { return selectionSupport; }
1046
         *
1047
         * public void setSelectionSupport(SelectionSupport selectionSupport) {
1048
         * this.selectionSupport = selectionSupport; }
1049
         */
1050

    
1051
        public SpatialCache createSpatialCache() {
1052
               spatialCache = new SpatialCache();
1053
                return spatialCache;
1054
        }
1055

    
1056
//        public void setSpatialCache(SpatialCache spatialCache) {
1057
//                this.spatialCache = spatialCache;
1058
//        }
1059

    
1060
        public boolean isSpatialCacheEnabled() {
1061
                return spatialCacheEnabled;
1062
        }
1063

    
1064
        public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
1065
                this.spatialCacheEnabled = spatialCacheEnabled;
1066
        }
1067

    
1068
        public SpatialCache getSpatialCache() {
1069
                return spatialCache;
1070
        }
1071

    
1072
}