Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / layers / vectorial / FLyrVect.java @ 30038

History | View | Annotate | Download (43.3 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 org.gvsig.fmap.mapcontext.layers.vectorial;
42

    
43
import java.awt.Graphics2D;
44
import java.awt.Point;
45
import java.awt.geom.AffineTransform;
46
import java.awt.geom.Point2D;
47
import java.awt.image.BufferedImage;
48
import java.net.URI;
49
import java.util.Set;
50
import java.util.TreeSet;
51

    
52
import org.cresques.cts.ICoordTrans;
53
import org.gvsig.compat.print.PrintAttributes;
54
import org.gvsig.fmap.dal.DALLocator;
55
import org.gvsig.fmap.dal.DataManager;
56
import org.gvsig.fmap.dal.DataStore;
57
import org.gvsig.fmap.dal.DataStoreParameters;
58
import org.gvsig.fmap.dal.exception.DataException;
59
import org.gvsig.fmap.dal.exception.ReadException;
60
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
61
import org.gvsig.fmap.dal.feature.FeatureQuery;
62
import org.gvsig.fmap.dal.feature.FeatureSet;
63
import org.gvsig.fmap.dal.feature.FeatureStore;
64
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
65
import org.gvsig.fmap.dal.feature.FeatureType;
66
import org.gvsig.fmap.dal.feature.exception.CreateGeometryException;
67
import org.gvsig.fmap.geom.Geometry;
68
import org.gvsig.fmap.geom.GeometryLocator;
69
import org.gvsig.fmap.geom.GeometryManager;
70
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
71
import org.gvsig.fmap.geom.Geometry.TYPES;
72
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
73
import org.gvsig.fmap.geom.primitive.Circle;
74
import org.gvsig.fmap.geom.primitive.Envelope;
75
import org.gvsig.fmap.geom.type.GeometryType;
76
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
77
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
78
import org.gvsig.fmap.mapcontext.MapContextLocator;
79
import org.gvsig.fmap.mapcontext.ViewPort;
80
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
81
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
82
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
83
import org.gvsig.fmap.mapcontext.exceptions.ReprojectLayerException;
84
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
85
import org.gvsig.fmap.mapcontext.exceptions.XMLLayerException;
86
import org.gvsig.fmap.mapcontext.layers.AbstractLinkProperties;
87
import org.gvsig.fmap.mapcontext.layers.FLayer;
88
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
89
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
90
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
91
import org.gvsig.fmap.mapcontext.layers.operations.VectorialXMLItem;
92
import org.gvsig.fmap.mapcontext.layers.operations.XMLItem;
93
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
94
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
95
import org.gvsig.fmap.mapcontext.rendering.legend.LegendException;
96
import org.gvsig.fmap.mapcontext.rendering.legend.events.FeatureDrawnNotification;
97
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
98
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
99
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendContentsChangedListener;
100
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
101
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
102
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
103
import org.gvsig.tools.ToolsLocator;
104
import org.gvsig.tools.dynobject.exception.DynMethodException;
105
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
106
import org.gvsig.tools.exception.BaseException;
107
import org.gvsig.tools.locator.LocatorException;
108
import org.gvsig.tools.observer.Observable;
109
import org.gvsig.tools.observer.Observer;
110
import org.gvsig.tools.persistence.PersistenceException;
111
import org.gvsig.tools.persistence.PersistenceManager;
112
import org.gvsig.tools.persistence.PersistenceValidateExceptions;
113
import org.gvsig.tools.persistence.PersistentState;
114
import org.gvsig.tools.task.Cancellable;
115
import org.gvsig.utils.XMLEntity;
116
import org.gvsig.utils.XMLException;
117
import org.slf4j.LoggerFactory;
118

    
119

    
120
/**
121
 * Capa b?sica Vectorial.
122
 *
123
 * @author Fernando Gonz?lez Cort?s
124
 */
125

    
126
// TODO Cuando no sea para pruebas debe no ser public
127
public class FLyrVect extends FLyrDefault implements VectorLayer, LegendContentsChangedListener,
128
Observer {
129
        final static private org.slf4j.Logger logger = LoggerFactory.getLogger(FLyrVect.class);
130
        private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
131
        /** Leyenda de la capa vectorial */
132
        private IVectorLegend legend;
133
        private int typeShape = -1;
134
        private FeatureStore featureStore=null;
135
        private SpatialCache spatialCache = new SpatialCache();
136

    
137
        /**
138
         * An implementation of gvSIG spatial index
139
         */
140
        //    protected ISpatialIndex spatialIndex = null;
141
        private boolean bHasJoin = false;
142
        private XMLEntity orgXMLEntity = null;
143
        private XMLEntity loadSelection = null;
144
        private IVectorLegend loadLegend = null;
145

    
146
        //Lo a?ado. Caracter?sticas de HyperEnlace (LINK)
147
        private FLyrVectLinkProperties linkProperties=new FLyrVectLinkProperties();
148

    
149
        /*
150
         * jaume. Stuff from ILabeled.
151
         */
152
        private boolean isLabeled;
153
        protected ILabelingStrategy strategy;
154

    
155
        /**
156
         * Devuelve el VectorialAdapater de la capa.
157
         *
158
         * @return VectorialAdapter.
159
         */
160
        public DataStore getDataStore() {
161
                if (!this.isAvailable()) {
162
                        return null;
163
                }
164
                return featureStore;
165
        }
166

    
167
        /**
168
         * If we use a persistent spatial index associated with this layer, and the
169
         * index is not intrisic to the layer (for example spatial databases) this
170
         * method looks for existent spatial index, and loads it.
171
         *
172
         */
173
        //    private void loadSpatialIndex() {
174
        //        //FIXME: Al abrir el indice en fichero...
175
        //        //?C?mo lo liberamos? un metodo Layer.shutdown()
176
        //
177
        //
178
        //        ReadableVectorial source = getSource();
179
        //        //REVISAR QUE PASA CON LOS DRIVERS DXF, DGN, etc.
180
        //        //PUES SON VECTORIALFILEADAPTER
181
        //        if (!(source instanceof VectorialFileAdapter)) {
182
        //            // we are not interested in db adapters
183
        //            return;
184
        //        }
185
        //        VectorialDriver driver = source.getDriver();
186
        //        if (!(driver instanceof BoundedShapes)) {
187
        //            // we dont spatially index layers that are not bounded
188
        //            return;
189
        //        }
190
        //        File file = ((VectorialFileAdapter) source).getFile();
191
        //        String fileName = file.getAbsolutePath();
192
        //        File sptFile = new File(fileName + ".qix");
193
        //        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
194
        //            // before to exit, look for it in temp path
195
        //            String tempPath = System.getProperty("java.io.tmpdir");
196
        //            fileName = tempPath + File.separator + sptFile.getName();
197
        //            sptFile = new File(fileName);
198
        //            // it doesnt exists, must to create
199
        //            if (!sptFile.exists() || (!(sptFile.length() > 0))) {
200
        //                return;
201
        //            }// if
202
        //        }// if
203
        //
204
        //        try {
205
        //            source.start();
206
        //            spatialIndex = new QuadtreeGt2(FileUtils.getFileWithoutExtension(sptFile),
207
        //                    "NM", source.getFullExtent(), source.getShapeCount(), false);
208
        //            source.setSpatialIndex(spatialIndex);
209
        //        } catch (SpatialIndexException e) {
210
        //            spatialIndex = null;
211
        //            e.printStackTrace();
212
        //            return;
213
        //        } catch (ReadDriverException e) {
214
        //            spatialIndex = null;
215
        //            e.printStackTrace();
216
        //            return;
217
        //        }
218
        //
219
        //    }
220

    
221
        /**
222
         * Checks if it has associated an external spatial index
223
         * (an spatial index file).
224
         *
225
         * It looks for it in main file path, or in temp system path.
226
         * If main file is rivers.shp, it looks for a file called
227
         * rivers.shp.qix.
228

229
         * @return
230
         */
231
        //    public boolean isExternallySpatiallyIndexed() {
232
        //        /*
233
        //         * FIXME (AZABALA): Independizar del tipo de fichero de ?ndice
234
        //          * con el que se trabaje (ahora mismo considera la extension .qix,
235
        //         * pero esto depender? del tipo de ?ndice)
236
        //         * */
237
        //        ReadableVectorial source = getSource();
238
        //        if (!(source instanceof VectorialFileAdapter)) {
239
        //            // we are not interested in db adapters.
240
        //            // think in non spatial dbs, like HSQLDB
241
        //            return false;
242
        //        }
243
        //        File file = ((VectorialFileAdapter) source).getFile();
244
        //        String fileName = file.getAbsolutePath();
245
        //        File sptFile = new File(fileName + ".qix");
246
        //        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
247
        //            // before to exit, look for it in temp path
248
        //            // it doesnt exists, must to create
249
        //            String tempPath = System.getProperty("java.io.tmpdir");
250
        //            fileName = tempPath + File.separator + sptFile.getName();
251
        //            sptFile = new File(fileName);
252
        //            if (!sptFile.exists() || (!(sptFile.length() > 0))) {
253
        //                return false;
254
        //            }// if
255
        //        }// if
256
        //        return true;
257
        //    }
258
        /**
259
         * Inserta el VectorialAdapter a la capa.
260
         *
261
         * @param va
262
         *            VectorialAdapter.
263
         *
264
         * @deprecated esto deber?a se ser protected
265
         */
266
          public void setDataStore(DataStore dataStore) throws LoadLayerException {
267
                if (this.featureStore != null && this.featureStore != dataStore){
268
                        this.featureStore.deleteObserver(this);
269
                }
270

    
271
                featureStore = (FeatureStore)dataStore;
272

    
273
                IVectorLegend legend = null;
274
                try {
275
                        legend = (IVectorLegend) dataStore.invokeDynMethod(
276
                                        "getLegend", null);
277

    
278
                } catch (DynMethodNotSupportedException e1) {
279
                        try {
280
                                legend = MapContextLocator.getMapContextManager()
281
                                                .createDefaultVectorLegend(getShapeType());
282
                        } catch (ReadException e) {
283
                                throw new LoadLayerException(this.getName(), e);
284
                        }
285
//                        try {
286
//                                                                legend = LegendFactory.createSingleSymbolLegend(this
287
//                                                .getShapeType());
288
//                        } catch (ReadException e) {
289
//                                throw new LoadLayerException(this.getName(), e);
290
//                        }
291

    
292
                } catch (DynMethodException e1) {
293
                        throw new LoadLayerException(this.getName(), e1);
294
                }
295
                this.setLegend((IVectorLegend) legend);
296

    
297

    
298
                ILabelingStrategy labeler = null;
299
                try {
300
                        labeler = (ILabelingStrategy) dataStore.invokeDynMethod(
301
                                        "getLabeling", null);
302
                } catch (DynMethodNotSupportedException e1) {
303
                        labeler = null;
304
                } catch (DynMethodException e1) {
305
                        throw new LoadLayerException(this.getName(), e1);
306
                }
307

    
308
                if (labeler != null) {
309
                        try {
310
                                labeler.setLayer(this);
311
                        } catch (ReadException e) {
312
                                throw new LoadLayerException(this.getName(), e);
313
                        }
314
                        this.setLabelingStrategy(labeler);
315
                        this.setIsLabeled(true); // TODO: ac? no s'hauria de detectar si t? etiquetes?????
316
                }
317

    
318
                this.delegate(dataStore);
319

    
320
                dataStore.addObserver(this);
321

    
322
                // azabala: we check if this layer could have a file spatial index
323
                // and load it if it exists
324
                //        loadSpatialIndex();
325
        }
326

    
327
        public Envelope getFullEnvelope() throws ReadException {
328
                Envelope rAux;
329
                try {
330
                        rAux = getFeatureStore().getEnvelope();
331
                } catch (BaseException e) {
332
                        throw new ReadException(getName(),e);
333
                }
334

    
335
                //Esto es para cuando se crea una capa nueva con el fullExtent de ancho y alto 0.
336
                if (rAux == null || rAux.getMaximum(0)-rAux.getMinimum(0)==0 && rAux.getMaximum(1)-rAux.getMinimum(1)==0) {
337
                        try {
338
                                rAux= geomManager.createEnvelope(0,0,100,100, SUBTYPES.GEOM2D);
339
                        } catch (CreateEnvelopeException e) {
340
                                logger.error("Error creating the envelope", e);
341
                                e.printStackTrace();
342
                        }
343
                }
344
                // Si existe reproyecci?n, reproyectar el extent
345
                ICoordTrans ct = getCoordTrans();
346
                try{
347
                        if (ct != null) {
348
                                Point2D pt1 = new Point2D.Double(rAux.getMinimum(0), rAux.getMinimum(1));
349
                                Point2D pt2 = new Point2D.Double(rAux.getMaximum(0), rAux.getMaximum(1));
350
                                pt1 = ct.convert(pt1, null);
351
                                pt2 = ct.convert(pt2, null);
352
                                try {
353
                                        rAux = geomManager.createEnvelope(pt1.getX(),pt1.getY(),pt2.getX(),pt2.getY(), SUBTYPES.GEOM2D);
354
                                } catch (CreateEnvelopeException e) {
355
                                        logger.error("Error creating the envelope", e);
356
                                        e.printStackTrace();
357
                                }//new Rectangle2D.Double();
358
                        }
359
                }catch (IllegalStateException e) {
360
                        this.setAvailable(false);
361
                        this.addError(new ReprojectLayerException(getName(), e));
362
                }
363
                return rAux;
364

    
365
        }
366

    
367
        /**
368
         * Draws using IFeatureIterator. This method will replace the old draw(...) one.
369
         * @autor jaume dominguez faus - jaume.dominguez@iver.es
370
         * @param image
371
         * @param g
372
         * @param viewPort
373
         * @param cancel
374
         * @param scale
375
         * @throws ReadDriverException
376
         */
377
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
378
                        Cancellable cancel, double scale) throws ReadException {
379
                if (!this.isWithinScale(scale)) {
380
                        return;
381
                }
382
                if (cancel.isCanceled()) {
383
                        return;
384
                }
385

    
386
                if (spatialCache.isEnabled()) {
387
                        spatialCache.clearAll();
388
                        legend.addDrawingObserver(this);
389
                }
390

    
391
                try {
392
                        legend.draw(image, g, viewPort, cancel, scale, null,
393
                                        getCoordTrans(), getFeatureStore());
394

    
395
                } catch (LegendException e) {
396
                        this.setVisible(false);
397
                        this.setActive(false);
398
                        throw new ReadException(getName(), e);
399
                } finally {
400
                        if (spatialCache.isEnabled()) {
401
                                legend.deleteDrawingObserver(this);
402
                        }
403
                }
404
        }
405

    
406
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
407
                        double scale, PrintAttributes properties) throws ReadException {
408
                if (!this.isWithinScale(scale)) {
409
                        return;
410
                }
411
                if (cancel.isCanceled()) {
412
                        return;
413
                }
414

    
415
                try {
416
                        legend.print( g, viewPort, cancel, scale, null,
417
                                        getCoordTrans(), getFeatureStore(), properties);
418

    
419
                } catch (LegendException e) {
420
                        this.setVisible(false);
421
                        this.setActive(false);
422
                        throw new ReadException(getName(), e);
423
                }
424
        }
425

    
426
        /**
427
         * <p>
428
         * Creates an spatial index associated to this layer.
429
         * The spatial index will used
430
         * the native projection of the layer, so if the layer is reprojected, it will
431
         * be ignored.
432
         * </p>
433
         * @param cancelMonitor instance of CancellableMonitorable that allows
434
         * to monitor progress of spatial index creation, and cancel the process
435
         */
436
        //    public void createSpatialIndex(CancellableMonitorable cancelMonitor){
437
        //         // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
438
        //        // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
439
        //        // para que acepten recorrer sin geometria, solo con rectangulos.
440
        //
441
        //        //If this vectorial layer is based in a spatial database, the spatial
442
        //        //index is already implicit. We only will index file drivers
443
        //        ReadableVectorial va = getSource();
444
        //        //We must think in non spatial databases, like HSQLDB
445
        //        if(!(va instanceof VectorialFileAdapter)){
446
        //            return;
447
        //        }
448
        //        if (!(va.getDriver() instanceof BoundedShapes)) {
449
        //            return;
450
        //        }
451
        //        File file = ((VectorialFileAdapter) va).getFile();
452
        //        String fileName = file.getAbsolutePath();
453
        //        ISpatialIndex localCopy = null;
454
        //        try {
455
        //            va.start();
456
        //            localCopy = new QuadtreeGt2(fileName, "NM", va.getFullExtent(),
457
        //                    va.getShapeCount(), true);
458
        //
459
        //        } catch (SpatialIndexException e1) {
460
        //            // Probably we dont have writing permissions
461
        //            String directoryName = System.getProperty("java.io.tmpdir");
462
        //            File newFile = new File(directoryName +
463
        //                    File.separator +
464
        //                    file.getName());
465
        //            String newFileName = newFile.getName();
466
        //            try {
467
        //                localCopy = new QuadtreeGt2(newFileName, "NM", va.getFullExtent(),
468
        //                        va.getShapeCount(), true);
469
        //            } catch (SpatialIndexException e) {
470
        //                // if we cant build a file based spatial index, we'll build
471
        //                // a pure memory spatial index
472
        //                localCopy = new QuadtreeJts();
473
        //            } catch (ReadException e) {
474
        //                localCopy = new QuadtreeJts();
475
        //            }
476
        //
477
        //        } catch(Exception e){
478
        //            e.printStackTrace();
479
        //        }//try
480
        //        BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
481
        //        try {
482
        //            for (int i=0; i < va.getShapeCount(); i++)
483
        //            {
484
        //                if(cancelMonitor != null){
485
        //                    if(cancelMonitor.isCanceled())
486
        //                        return;
487
        //                    cancelMonitor.reportStep();
488
        //                }
489
        //                Rectangle2D r = shapeBounds.getShapeBounds(i);
490
        //                if(r != null)
491
        //                    localCopy.insert(r, i);
492
        //            } // for
493
        //            va.stop();
494
        //            if(localCopy instanceof IPersistentSpatialIndex)
495
        //                ((IPersistentSpatialIndex) localCopy).flush();
496
        //            spatialIndex = localCopy;
497
        //            //vectorial adapter needs a reference to the spatial index, to solve
498
        //            //request for feature iteration based in spatial queries
499
        //            source.setSpatialIndex(spatialIndex);
500
        //        } catch (ReadException e) {
501
        //            // TODO Auto-generated catch block
502
        //            e.printStackTrace();
503
        //        }
504
        //    }
505

    
506
        //    public void createSpatialIndex() {
507
        //        createSpatialIndex(null);
508
        //    }
509

    
510

    
511
        public void setLegend(IVectorLegend r) throws LegendLayerException {
512
                if (this.legend == r){
513
                        return;
514
                }
515
                if (this.legend != null && this.legend.equals(r)){
516
                        return;
517
                }
518
                IVectorLegend oldLegend = legend;
519
                legend = r;
520
//                try {
521
//                        legend.setFeatureStore(getFeatureStore());
522
//                } catch (ReadException e1) {
523
//                        throw new LegendLayerException(getName(),e1);
524
//                } catch (DataException e) {
525
//                        throw new LegendLayerException(getName(),e);
526
//                } finally{
527
//                        this.updateDrawVersion();
528
//                }
529

    
530
                if (oldLegend != null) {
531
                        oldLegend.removeLegendListener(this);
532
                        oldLegend.deleteDrawingObserver(this);
533
                }
534
                if (legend != null) {
535
                        legend.addLegendListener(this);
536
                }
537

    
538
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
539
                                oldLegend, legend);
540
                e.setLayer(this);
541
                callLegendChanged(e);
542
        }
543

    
544
        /**
545
         * Devuelve la Leyenda de la capa.
546
         *
547
         * @return Leyenda.
548
         */
549
        public ILegend getLegend() {
550
                return legend;
551
        }
552

    
553
        /**
554
         * Devuelve el tipo de shape que contiene la capa.
555
         *
556
         * @return tipo de shape.
557
         *
558
         * @throws ReadException
559
         */
560
        public int getShapeType() throws ReadException {
561
                if (typeShape == -1) {
562
                        FeatureType featureType;
563
                        try {
564
                                featureType = (((FeatureStore)getDataStore()).getDefaultFeatureType());
565
                        } catch (DataException e) {
566
                                throw new ReadException(getName(),e);
567
                        }
568
                        int indexGeom=featureType.getDefaultGeometryAttributeIndex();
569
                        typeShape=featureType.getAttributeDescriptor(indexGeom).getGeometryType();
570
                }
571
                return typeShape;
572
        }
573

    
574
        public XMLEntity getXMLEntity() throws XMLException {
575

    
576
                if (!this.isAvailable() && this.orgXMLEntity != null) {
577
                        return this.orgXMLEntity;
578
                }
579
                XMLEntity xml = super.getXMLEntity();
580
                if (getLegend()!=null){
581
                        XMLEntity xmlLegend=getLegend().getXMLEntity();
582
                        xmlLegend.putProperty("tagName","legend");
583
                        xml.addChild(xmlLegend);
584
                }
585
                try {
586
                        PersistenceManager manager = ToolsLocator.getPersistenceManager();
587
                        PersistentState stateFeatureStore=manager.getState(getFeatureStore());
588
                        stateFeatureStore.set("tagName","featureStore");
589
                        // xml.addChild(((XMLEntityState)stateFeatureStore).getXMLEntity());
590
                } catch (PersistenceException e) {
591
                        throw new XMLLayerException(getName(),e);
592
                } catch (PersistenceValidateExceptions e) {
593
                        throw new XMLLayerException(getName(), e);
594
                }
595
                // properties from ILabelable
596
                xml.putProperty("isLabeled", isLabeled);
597
                if (strategy != null) {
598
                        XMLEntity strategyXML = strategy.getXMLEntity();
599
                        strategyXML.putProperty("tagName", "labelingStrategy");
600
                        xml.addChild(strategy.getXMLEntity());
601
                }
602
                xml.addChild(getLinkProperties().getXMLEntity());
603
                return xml;
604
        }
605
        /*
606
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
607
         */
608
        public void setXMLEntity(XMLEntity xml) throws XMLException {
609
                try {
610
                        super.setXMLEntity(xml);
611
                        XMLEntity legendXML = xml.firstChild("tagName","legend");
612
                        // IVectorLegend leg = LegendFactory.createFromXML(legendXML);  FIXME 
613

    
614
                        //            PersistentState persistentState=new XMLEntityState(new XMLEntityManager());
615
                        XMLEntity xmlStore=xml.firstChild("tagName","featureStore");
616
                        // XMLEntityManager xmlManger = new XMLEntityManager();
617
                        // PersistentState state = xmlManger.createState(xmlStore);
618
                        PersistentState state = null; // FIXME
619
                        DataStore store = (DataStore) ToolsLocator.getPersistenceManager().create(state);
620
                        //            persistentState.createState(xmlStore);
621

    
622
                        //            DataManager dm=DALLocator.getDataManager();
623

    
624
                        this.setDataStore(store);
625
                        /* end patch */
626
                        
627
                        this.setIsLabeled(false);
628
//                        FIXME jjdc, deberia delegar todo en la persistencia de legend y strategy.
629
//                        try {
630
//                                setLegend(leg);
631
//                        } catch (LegendLayerException e) {
632
//                                throw new XMLLegendException(e);
633
//                        }
634
//
635
//                        // set properties for ILabelable
636
//
637
//                        if (xml.contains("isLabeled")
638
//                                        && xml.getBooleanProperty(("isLabeled"))) {
639
//                                XMLEntity labelingXML = xml.firstChild("tagName", "labelingStrategy");
640
//                                if (labelingXML != null){
641
//
642
//                                        isLabeled = true;
643
//                                        try {
644
//                                                this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this);
645
//                                        } catch (NotExistInXMLEntity neXMLEX) {
646
//                                                // no strategy was set, just continue;
647
//                                                logger.warn("Reached what should be unreachable code");
648
//                                        }
649
//                                } else {
650
//                                        isLabeled = false;
651
//                                }
652
//                        } else if (legendXML.contains("labelFieldName")|| legendXML.contains("labelfield")) {
653
//                            /* (jaume) begin patch;
654
//                         * for backward compatibility purposes. Since gvSIG v1.1 labeling is
655
//                         * no longer managed by the Legend but by the ILabelingStrategy. The
656
//                         * following allows restoring older projects' labelings.
657
//                         */
658
//                                String labelTextField =        null;
659
//                            if (legendXML.contains("labelFieldName")){
660
//                                    labelTextField = legendXML.getStringProperty("labelFieldName");
661
//                                    if (labelTextField != null) {
662
//                                            AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
663
//                                            labeling.setLayer(this);
664
//                                            labeling.setUsesFixedSize(true);
665
//                                            labeling.setFixedSize(10);
666
//                                            labeling.setTextField(labelTextField);
667
//                                            labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
668
//                                            labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
669
//                                            this.setLabelingStrategy(labeling);
670
//                                            this.setIsLabeled(true);
671
//                                    }
672
//                            }else{
673
//                                    labelTextField = legendXML.getStringProperty("labelfield");
674
//                                    if (labelTextField != null) {
675
//                                            AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
676
//                                            labeling.setLayer(this);
677
//                                            labeling.setUsesFixedSize(true);
678
//                                            labeling.setFixedSize(10);
679
//                                            labeling.setTextField(labelTextField);
680
//                                            labeling.setHeightField(legendXML.getStringProperty("labelFieldHeight"));
681
//                                            labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
682
//                                            this.setLabelingStrategy(labeling);
683
//                                            this.setIsLabeled(true);
684
//                                    }
685
//                            }
686
//                }else{
687
//                                isLabeled = false;
688
//                        }
689
                        XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
690
                        if (xmlLinkProperties != null){
691
                                getLinkProperties().setXMLEntity(xmlLinkProperties);
692
                        }
693
                } catch (Exception e) {
694
                        e.printStackTrace();
695
                        this.setAvailable(false);
696
                        this.orgXMLEntity = xml;
697

    
698
                }
699
                //
700

    
701
        }
702

    
703
        public void setXMLEntityNew(XMLEntity xml) throws XMLException {
704
                //        try {
705
                //            super.setXMLEntity(xml);
706
                //
707
                //            XMLEntity legendXML = xml.getChild(0);
708
                //            IVectorLegend leg = LegendFactory.createFromXML(legendXML);
709
                //            /* (jaume) begin patch;
710
                //             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
711
                //             * no longer managed by the Legend but by the ILabelingStrategy. The
712
                //             * following allows restoring older projects' labelings.
713
                //             */
714
                //            if (legendXML.contains("labelFieldHeight")) {
715
                //                AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
716
                //                labeling.setLayer(this);
717
                //                labeling.setTextField(legendXML.getStringProperty("labelFieldHeight"));
718
                //                labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
719
                //                this.setLabelingStrategy(labeling);
720
                //                this.setIsLabeled(true);
721
                //              }
722
                //            /* end patch */
723
                //            try {
724
                //                getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
725
                //
726
                //                this.setLoadSelection(xml.getChild(1));
727
                //            } catch (ReadException e1) {
728
                //                this.setAvailable(false);
729
                //                throw new XMLException(e1);
730
                //            }
731
                //            // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
732
                //            // el final
733
                //            // de la lectura del proyecto
734
                //            if (xml.contains("hasJoin")) {
735
                //                setIsJoined(true);
736
                //                PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
737
                //            } else {
738
                //                this.setLoadLegend(leg);
739
                //            }
740
                //
741
                //        } catch (XMLException e) {
742
                //            this.setAvailable(false);
743
                //            this.orgXMLEntity = xml;
744
                //        } catch (Exception e) {
745
                //            this.setAvailable(false);
746
                //            this.orgXMLEntity = xml;
747
                //        }
748

    
749

    
750
        }
751

    
752

    
753
        /**
754
         * Sobreimplementaci?n del m?todo toString para que las bases de datos
755
         * identifiquen la capa.
756
         *
757
         * @return DOCUMENT ME!
758
         */
759
        public String toString() {
760
                /*
761
                 * Se usa internamente para que la parte de datos identifique de forma
762
                 * un?voca las tablas
763
                 */
764
                String ret = super.toString();
765

    
766
                return "layer" + ret.substring(ret.indexOf('@') + 1);
767
        }
768

    
769
        public boolean isJoined() {
770
                return bHasJoin;
771
        }
772

    
773
        /**
774
         * Returns if a layer is spatially indexed
775
         *
776
         * @return if this layer has the ability to proces spatial queries without
777
         *         secuential scans.
778
         */
779
        //    public boolean isSpatiallyIndexed() {
780
        //        ReadableVectorial source = getSource();
781
        //        if (source instanceof ISpatialDB)
782
        //            return true;
783
        //
784
        ////FIXME azabala
785
        ///*
786
        // * Esto es muy dudoso, y puede cambiar.
787
        // * Estoy diciendo que las que no son fichero o no son
788
        // * BoundedShapes estan indexadas. Esto es mentira, pero
789
        // * as? quien pregunte no querr? generar el indice.
790
        // * Esta por ver si interesa generar el indice para capas
791
        // * HSQLDB, WFS, etc.
792
        // */
793
        //        if(!(source instanceof VectorialFileAdapter)){
794
        //            return true;
795
        //        }
796
        //        if (!(source.getDriver() instanceof BoundedShapes)) {
797
        //            return true;
798
        //        }
799
        //
800
        //        if (getISpatialIndex() != null)
801
        //            return true;
802
        //        return false;
803
        //    }
804

    
805
        public void setIsJoined(boolean hasJoin) {
806
                bHasJoin = hasJoin;
807
        }
808

    
809
        //    /**
810
        //     * @return Returns the spatialIndex.
811
        //     */
812
        //    public ISpatialIndex getISpatialIndex() {
813
        //        return spatialIndex;
814
        //    }
815
        //    /**
816
        //     * Sets the spatial index. This could be useful if, for some
817
        //     * reasons, you want to work with a distinct spatial index
818
        //     * (for example, a spatial index which could makes nearest
819
        //     * neighbour querys)
820
        //     * @param spatialIndex
821
        //     */
822
        //    public void setISpatialIndex(ISpatialIndex spatialIndex){
823
        //        this.spatialIndex = spatialIndex;
824
        //    }
825

    
826
        public void setEditing(boolean b) throws StartEditionLayerException {
827
                super.setEditing(b);
828
                if (b){
829
                        try {
830
                                getFeatureStore().edit();
831
                        } catch (ReadException e) {
832
                                throw new StartEditionLayerException(getName(),e);
833
                        } catch (DataException e) {
834
                                throw new StartEditionLayerException(getName(),e);
835
                        }
836
                }
837
                setSpatialCacheEnabled(b);
838
                callEditionChanged(LayerEvent
839
                                .createEditionChangedEvent(this, "edition"));
840

    
841
        }
842

    
843
        
844
        /**
845
         * @deprecated Use {@link #getSpatialCache()}
846
         */
847
        public void clearSpatialCache()
848
        {
849
                spatialCache.clearAll();
850
        }
851

    
852
        /**
853
         * @deprecated Use {@link #getSpatialCache()}
854
         */
855
        public boolean isSpatialCacheEnabled() {
856
                return spatialCache.isEnabled();
857
        }
858

    
859
        /**
860
         * @deprecated Use {@link #getSpatialCache()}
861
         */
862
        public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
863
                spatialCache.setEnabled(spatialCacheEnabled);
864
        }
865

    
866
        public SpatialCache getSpatialCache() {
867
                return spatialCache;
868
        }
869

    
870
        /**
871
         * Siempre es un numero mayor de 1000
872
         * @param maxFeatures
873
         */
874
        public void setMaxFeaturesInEditionCache(int maxFeatures) {
875
                if (maxFeatures > spatialCache.getMaxFeatures()) {
876
                        spatialCache.setMaxFeatures(maxFeatures);
877
                }
878

    
879
        }
880

    
881
        /**
882
         * This method returns a boolean that is used by the FPopMenu
883
         * to make visible the properties menu or not. It is visible by
884
         * default, and if a later don't have to show this menu only
885
         * has to override this method.
886
         * @return
887
         * If the properties menu is visible (or not)
888
         */
889
        public boolean isPropertiesMenuVisible(){
890
                return true;
891
        }
892

    
893
        public void reload() throws ReloadLayerException {
894
                super.reload();
895
                try {
896
                        DataManager dataManager=DALLocator.getDataManager();
897
                        DataStoreParameters storeParameters;
898

    
899
                        storeParameters = getFeatureStore().getParameters();
900

    
901
                        DataStore dataStore=dataManager.createStore(storeParameters);
902
                        setDataStore(dataStore);
903
                        getFeatureStore().refresh();
904
                } catch (Exception e) {
905
                        throw new ReloadLayerException(getName(),e);
906
                }
907
                //        try {
908
                //            this.source.getDriver().reload();
909
                //            if (this.getLegend() == null) {
910
                //                if (this.getRecordset().getDriver() instanceof WithDefaultLegend) {
911
                //                    WithDefaultLegend aux = (WithDefaultLegend) this.getRecordset().getDriver();
912
                //                    this.setLegend((IVectorLegend) aux.getDefaultLegend());
913
                //                    this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
914
                //                } else {
915
                //                    this.setLegend(LegendFactory.createSingleSymbolLegend(
916
                //                            this.getShapeType()));
917
                //                }
918
                //            }
919
                //
920
                //        } catch (LegendLayerException e) {
921
                //            this.setAvailable(false);
922
                //            throw new ReloadLayerException(getName(),e);
923
                //        } catch (ReadException e) {
924
                //            this.setAvailable(false);
925
                //            throw new ReloadLayerException(getName(),e);
926
                //        }
927

    
928

    
929
        }
930

    
931
        protected void setLoadSelection(XMLEntity xml) {
932
                this.loadSelection = xml;
933
        }
934

    
935
        protected void setLoadLegend(IVectorLegend legend) {
936
                this.loadLegend = legend;
937
        }
938

    
939
        protected void putLoadSelection() throws XMLException {
940
                //        if (this.loadSelection == null) return;
941
                //        try {
942
                //            this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
943
                //        } catch (ReadDriverException e) {
944
                //            throw new XMLException(e);
945
                //        }
946
                //        this.loadSelection = null;
947

    
948
        }
949
        protected void putLoadLegend() throws LegendLayerException {
950
                if (this.loadLegend == null) {
951
                        return;
952
                }
953
                this.setLegend(this.loadLegend);
954
                this.loadLegend = null;
955
        }
956

    
957
        protected void cleanLoadOptions() {
958
                this.loadLegend = null;
959
                this.loadSelection = null;
960
        }
961

    
962
        public boolean isWritable() {
963
                return getFeatureStore().allowWrite();
964
        }
965

    
966
        public FLayer cloneLayer() throws Exception {
967
                FLyrVect clonedLayer = new FLyrVect();
968
                clonedLayer.setDataStore(getDataStore());
969
                if (isJoined()) {
970
                        clonedLayer.setIsJoined(true);
971
                }
972
                clonedLayer.setVisible(isVisible());
973
                //        clonedLayer.setISpatialIndex(getISpatialIndex());
974
                clonedLayer.setName(getName());
975
                clonedLayer.setCoordTrans(getCoordTrans());
976

    
977
                clonedLayer.setLegend((IVectorLegend)getLegend().cloneLegend());
978

    
979
                clonedLayer.setIsLabeled(isLabeled());
980
                ILabelingStrategy labelingStrategy=getLabelingStrategy();
981
        if (labelingStrategy!=null) {
982
                        clonedLayer.setLabelingStrategy(labelingStrategy);
983
                }
984

    
985
                return clonedLayer;
986
        }
987

    
988

    
989
        protected boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, double dpi, CartographicSupport csSym, Geometry geom, int[] xyCoords) {
990
                return isOnePoint(graphicsTransform, viewPort, geom, xyCoords) && csSym.getCartographicSize(viewPort, dpi, geom) <= 1;
991
        }
992

    
993
        private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, Geometry geom, int[] xyCoords) {
994
                boolean onePoint = false;
995
                int type=geom.getType();
996
                if (type == Geometry.TYPES.NULL) {
997
                        return false;
998
                }
999
                if (type!=Geometry.TYPES.POINT && type!=Geometry.TYPES.MULTIPOINT) {
1000

    
1001
                        Envelope geomBounds = geom.getEnvelope();
1002

    
1003
                        ICoordTrans ct = getCoordTrans();
1004

    
1005
                        // Se supone que la geometria ya esta reproyectada
1006
                        // if (ct!=null) {
1007
                        // // geomBounds = ct.getInverted().convert(geomBounds);
1008
                        // geomBounds = geomBounds.convert(ct);
1009
                        // }
1010

    
1011
                        double dist1Pixel = viewPort.getDist1pixel();
1012

    
1013
                        onePoint = (geomBounds.getLength(0)  <= dist1Pixel
1014
                                        && geomBounds.getLength(1) <= dist1Pixel);
1015

    
1016
                        if (onePoint) {
1017
                                // avoid out of range exceptions
1018
                                org.gvsig.fmap.geom.primitive.Point p;
1019
                                try {
1020
                                        p = geomManager.createPoint(geomBounds.getMinimum(0), geomBounds.getMinimum(1), SUBTYPES.GEOM2D);
1021
                                        p.transform(viewPort.getAffineTransform());
1022
                                        p.transform(graphicsTransform);
1023
                                        xyCoords[0] = (int) p.getX();
1024
                                        xyCoords[1] = (int) p.getY();
1025
                                } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
1026
                                        logger.error("Error creating a point", e);
1027
                                }
1028

    
1029
                        }
1030

    
1031
                }
1032
                return onePoint;
1033
        }
1034
        public boolean isLabeled() {
1035
                return isLabeled;
1036
        }
1037

    
1038
        public void setIsLabeled(boolean isLabeled) {
1039
                this.isLabeled = isLabeled;
1040
        }
1041

    
1042
        public ILabelingStrategy getLabelingStrategy() {
1043
                return strategy;
1044
        }
1045

    
1046
        public void setLabelingStrategy(ILabelingStrategy strategy) {
1047
                this.strategy = strategy;
1048
                try {
1049
                        strategy.setLayer(this);
1050
                } catch (ReadException e) {
1051
                        // TODO Auto-generated catch block
1052
                        e.printStackTrace();
1053
                }
1054

    
1055
        }
1056

    
1057
        public void drawLabels(BufferedImage image, Graphics2D g, ViewPort viewPort,
1058
                        Cancellable cancel, double scale, double dpi) throws ReadException {
1059
                if (strategy!=null && isWithinScale(scale)) {
1060
                        strategy.draw(image, g, viewPort, cancel, dpi);
1061
                }
1062
        }
1063

    
1064
        public void printLabels(Graphics2D g, ViewPort viewPort,
1065
                        Cancellable cancel, double scale,
1066
                        PrintAttributes properties) throws ReadException {
1067
                if (strategy != null) {
1068
                        strategy.print(g, viewPort, cancel, properties);
1069
                }
1070
        }
1071
        //M?todos para el uso de HyperLinks en capas FLyerVect
1072

    
1073
        /**
1074
         * Return true, because a Vectorial Layer supports HyperLink
1075
         */
1076
        public boolean allowLinks()
1077
        {
1078
                return true;
1079
        }
1080

    
1081
        /**
1082
         * Returns an instance of AbstractLinkProperties that contains the information
1083
         * of the HyperLink
1084
         * @return Abstra
1085
         */
1086
        public AbstractLinkProperties getLinkProperties()
1087
        {
1088
                return linkProperties;
1089
        }
1090

    
1091
        /**
1092
         * Provides an array with URIs. Returns one URI by geometry that includes the point
1093
         * in its own geometry limits with a allowed tolerance.
1094
         * @param layer, the layer
1095
         * @param point, the point to check that is contained or not in the geometries in the layer
1096
         * @param tolerance, the tolerance allowed. Allowed margin of error to detect if the  point
1097
         *                 is contained in some geometries of the layer
1098
         * @return
1099
         * @throws ReadException
1100
         * @throws BehaviorException
1101
         */
1102
        public URI[] getLink(Point2D point, double tolerance) throws ReadException
1103
        {
1104
                //return linkProperties.getLink(this)
1105
                return linkProperties.getLink(this,point,tolerance);
1106
        }
1107

    
1108
        public void load() throws LoadLayerException {
1109
                super.load();
1110
        }
1111

    
1112
        public FeatureStore getFeatureStore() {
1113
                return (FeatureStore)getDataStore();
1114
        }
1115

    
1116
        public FeatureSet queryByPoint(Point2D mapPoint, double tol, FeatureType featureType) throws DataException {
1117
                GeometryManager manager = GeometryLocator.getGeometryManager();
1118
                org.gvsig.fmap.geom.primitive.Point center;
1119
                try {
1120
                        center = (org.gvsig.fmap.geom.primitive.Point)manager.create(TYPES.POINT, SUBTYPES.GEOM2D);
1121
                        center.setX(mapPoint.getX());
1122
                        center.setY(mapPoint.getY());
1123
                        Circle circle = (Circle)manager.create(TYPES.CIRCLE, SUBTYPES.GEOM2D);
1124
                        circle.setPoints(center, tol);
1125
                        return queryByGeometry(circle, featureType);
1126
                } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
1127
                        throw new CreateGeometryException(TYPES.CIRCLE, SUBTYPES.GEOM2D, e);
1128
                }
1129
        }
1130

    
1131

    
1132
        public FeatureSet queryByGeometry(Geometry geom, FeatureType featureType) throws DataException {
1133
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
1134
                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
1135
                featureQuery.setFeatureType(featureType);
1136
                IntersectsGeometryEvaluator iee=new IntersectsGeometryEvaluator(geom,getMapContext().getViewPort().getProjection(),featureStore.getDefaultFeatureType(),geomName);
1137
                featureQuery.setFilter(iee);
1138
                return getFeatureStore().getFeatureSet(featureQuery);
1139

    
1140
        }
1141

    
1142
        public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType)
1143
        throws DataException {
1144
                return queryByEnvelope(envelope, featureType, null);
1145
        }
1146

    
1147
        public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType, String[] names)
1148
        throws DataException {
1149
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
1150
                if (names==null){
1151
                        featureQuery.setFeatureType(featureType);
1152
                }else{
1153
                        featureQuery.setAttributeNames(names);
1154
                        featureQuery.setFeatureTypeId(featureType.getId());
1155
                }
1156
                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
1157
                ContainsEnvelopeEvaluator iee=new ContainsEnvelopeEvaluator(envelope,getMapContext().getViewPort().getProjection(),featureStore.getDefaultFeatureType(),geomName);
1158
                featureQuery.setFilter(iee);
1159
                return getFeatureStore().getFeatureSet(featureQuery);
1160

    
1161
        }
1162
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws LoadLayerException, DataException {
1163
                Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p);
1164
                FeatureSet featureCollection=null;
1165
                try {
1166
                        featureCollection = queryByPoint(pReal, tolerance, getFeatureStore().getDefaultFeatureType());
1167
                } catch (DataException e) {
1168
                        // TODO Auto-generated catch block
1169
                        e.printStackTrace();
1170
                }
1171
                VectorialXMLItem[] item = new VectorialXMLItem[1];
1172
                item[0] = new VectorialXMLItem(featureCollection, this);
1173

    
1174
                return item;
1175
        }
1176

    
1177
        public void legendCleared(LegendClearEvent event) {
1178
                // this.updateDrawVersion(); TODO
1179
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
1180
                                legend, legend);
1181
                this.callLegendChanged(e);
1182
        }
1183

    
1184
        public boolean symbolChanged(SymbolLegendEvent e) {
1185
                LegendChangedEvent ev = LegendChangedEvent.createLegendChangedEvent(
1186
                                legend, legend);
1187
                this.callLegendChanged(ev);
1188
                return true;
1189
        }
1190

    
1191
        public void update(Observable observable, Object notification) {
1192
                if (observable.equals(this.featureStore)) {
1193
                        if (notification instanceof FeatureStoreNotification) {
1194
                                FeatureStoreNotification event = (FeatureStoreNotification) notification;
1195
                                if (event.getType() == FeatureStoreNotification.AFTER_CANCELEDITING
1196
                                                || event.getType() == FeatureStoreNotification.AFTER_DELETE
1197
                                                || event.getType() == FeatureStoreNotification.AFTER_UNDO
1198
                                                || event.getType() == FeatureStoreNotification.AFTER_REDO
1199
                                                || event.getType() == FeatureStoreNotification.AFTER_REFRESH
1200
                                                || event.getType() == FeatureStoreNotification.AFTER_UPDATE
1201
                                                || event.getType() == FeatureStoreNotification.AFTER_UPDATE_TYPE
1202
                                                || event.getType() == FeatureStoreNotification.SELECTION_CHANGE
1203
                                                || event.getType() == FeatureStoreNotification.AFTER_INSERT) {
1204
                                        this.updateDrawVersion();
1205

    
1206
                                } else if (event.getType() == FeatureStoreNotification.AFTER_FINISHEDITING
1207
                                                || event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE
1208
                                                || event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
1209
                                        this.setAvailable(false);
1210

    
1211
                                        //                                        try {
1212
                                        //                                                reload();
1213
                                        //                                        } catch (ReloadLayerException e) {
1214
                                        //                                                this.setAvailable(false);
1215
                                        //                                        }
1216
                                }
1217

    
1218
                        }
1219

    
1220
                }
1221
                // Only if its an event from our own legend
1222
                else if (observable == getLegend()) {
1223
                        if (notification instanceof FeatureDrawnNotification) {
1224
                                Geometry geometry = ((FeatureDrawnNotification) notification)
1225
                                                .getDrawnGeometry();
1226
                                spatialCache.insert(geometry.getEnvelope(), geometry);
1227
                        }
1228
                }
1229

    
1230
        }
1231

    
1232
        /*
1233
         * (non-Javadoc)
1234
         *
1235
         * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1236
         */
1237
        public Set getMetadataChildren() {
1238
                Set ret = new TreeSet();
1239
                ret.add(this.featureStore);
1240
                return ret;
1241
        }
1242

    
1243
        /*
1244
         * (non-Javadoc)
1245
         *
1246
         * @see org.gvsig.metadata.Metadata#getMetadataID()
1247
         */
1248
        public Object getMetadataID() {
1249
                return "Layer(" + this.getName() + "):"
1250
                + this.featureStore.getMetadataID();
1251
        }
1252

    
1253
        /*
1254
         * (non-Javadoc)
1255
         *
1256
         * @see org.gvsig.metadata.Metadata#getMetadataName()
1257
         */
1258
        public String getMetadataName() {
1259
                return "Layer '" + this.getName() + "':"
1260
                + this.featureStore.getMetadataName();
1261
        }
1262

    
1263
        public GeometryType getTypeVectorLayer() throws DataException, LocatorException, GeometryTypeNotSupportedException, GeometryTypeNotValidException {
1264
                // FIXME Esto deberia de pedirse a FType!!!!
1265
                FeatureStore fs = this.getFeatureStore();
1266
                FeatureType fType = fs.getDefaultFeatureType();
1267
                FeatureAttributeDescriptor attr = fType.getAttributeDescriptor(fType
1268
                                .getDefaultGeometryAttributeIndex());
1269
                GeometryType geomType = GeometryLocator.getGeometryManager()
1270
                                .getGeometryType(attr.getGeometryType(),
1271
                                                attr.getGeometrySubType());
1272
                return geomType;
1273
        }
1274

    
1275
}