Statistics
| Revision:

root / tags / v2_0_0_Build_2011 / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / layers / vectorial / FLyrVect.java @ 33562

History | View | Annotate | Download (45.1 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.util.Set;
49
import java.util.TreeSet;
50

    
51
import org.cresques.cts.ICoordTrans;
52
import org.slf4j.LoggerFactory;
53

    
54
import org.gvsig.compat.print.PrintAttributes;
55
import org.gvsig.fmap.dal.DALLocator;
56
import org.gvsig.fmap.dal.DataManager;
57
import org.gvsig.fmap.dal.DataStore;
58
import org.gvsig.fmap.dal.DataStoreParameters;
59
import org.gvsig.fmap.dal.exception.DataException;
60
import org.gvsig.fmap.dal.exception.ReadException;
61
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
62
import org.gvsig.fmap.dal.feature.FeatureQuery;
63
import org.gvsig.fmap.dal.feature.FeatureSet;
64
import org.gvsig.fmap.dal.feature.FeatureStore;
65
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
66
import org.gvsig.fmap.dal.feature.FeatureType;
67
import org.gvsig.fmap.dal.feature.exception.CreateGeometryException;
68
import org.gvsig.fmap.geom.Geometry;
69
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
70
import org.gvsig.fmap.geom.Geometry.TYPES;
71
import org.gvsig.fmap.geom.GeometryLocator;
72
import org.gvsig.fmap.geom.GeometryManager;
73
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
74
import org.gvsig.fmap.geom.primitive.Circle;
75
import org.gvsig.fmap.geom.primitive.Envelope;
76
import org.gvsig.fmap.geom.type.GeometryType;
77
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
78
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
79
import org.gvsig.fmap.mapcontext.MapContextLocator;
80
import org.gvsig.fmap.mapcontext.ViewPort;
81
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
82
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
83
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
84
import org.gvsig.fmap.mapcontext.exceptions.ReprojectLayerException;
85
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
86
import org.gvsig.fmap.mapcontext.layers.FLayer;
87
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
88
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
89
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
90
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
91
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
92
import org.gvsig.fmap.mapcontext.rendering.legend.LegendException;
93
import org.gvsig.fmap.mapcontext.rendering.legend.events.FeatureDrawnNotification;
94
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
95
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
96
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendContentsChangedListener;
97
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
98
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
99
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
100
import org.gvsig.metadata.exceptions.MetadataException;
101
import org.gvsig.tools.ToolsLocator;
102
import org.gvsig.tools.dynobject.DynObjectSet;
103
import org.gvsig.tools.dynobject.DynStruct;
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.PersistenceManager;
111
import org.gvsig.tools.persistence.PersistentState;
112
import org.gvsig.tools.persistence.exception.PersistenceException;
113
import org.gvsig.tools.task.Cancellable;
114

    
115

    
116
/**
117
 * Capa b?sica Vectorial.
118
 *
119
 * @author Fernando Gonz?lez Cort?s
120
 */
121

    
122
public class FLyrVect extends FLyrDefault implements VectorLayer, LegendContentsChangedListener,
123
Observer {
124
        final static private org.slf4j.Logger logger = LoggerFactory.getLogger(FLyrVect.class);
125
        private final GeometryManager geomManager = GeometryLocator.getGeometryManager();
126

    
127
        /** Leyenda de la capa vectorial */
128
        private IVectorLegend legend;
129
        private int typeShape = -1;
130
        private FeatureStore featureStore=null;
131
        private SpatialCache spatialCache = new SpatialCache();
132

    
133
        /**
134
         * An implementation of gvSIG spatial index
135
         */
136
        //    protected ISpatialIndex spatialIndex = null;
137
        //private boolean bHasJoin = false;
138
        private IVectorLegend loadLegend = null;
139

    
140
        //Lo a?ado. Caracter?sticas de HyperEnlace (LINK)
141
//        private FLyrVectLinkProperties linkProperties=new FLyrVectLinkProperties();
142

    
143
        public FLyrVect() {
144
                super();
145
        }
146
        /**
147
         * Devuelve el VectorialAdapater de la capa.
148
         *
149
         * @return VectorialAdapter.
150
         */
151
        public DataStore getDataStore() {
152
                if (!this.isAvailable()) {
153
                        return null;
154
                }
155
                return featureStore;
156
        }
157

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

    
212
        /**
213
         * Checks if it has associated an external spatial index
214
         * (an spatial index file).
215
         *
216
         * It looks for it in main file path, or in temp system path.
217
         * If main file is rivers.shp, it looks for a file called
218
         * rivers.shp.qix.
219

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

    
262
                featureStore = (FeatureStore)dataStore;
263

    
264
                ILegend legend = MapContextLocator.getMapContextManager().getLegend(dataStore);
265

    
266
                if( legend == null ) {
267
                        throw new LegendLayerException(this.getName());                                
268
                }
269
                
270
                this.setLegend((IVectorLegend)legend);
271

    
272

    
273
                ILabelingStrategy labeler = null;
274
                try {
275
                        labeler = (ILabelingStrategy) dataStore.invokeDynMethod(
276
                                        "getLabeling", null);
277
                } catch (DynMethodNotSupportedException e1) {
278
                        labeler = null;
279
                } catch (DynMethodException e1) {
280
                        logger.error("Can't load the specific lebeling strategy provided for the layer {}.", this.getName(), e1);
281
                }
282

    
283
                if (labeler != null) {
284
                        try {
285
                                labeler.setLayer(this);
286
                                this.setLabelingStrategy(labeler);
287
                                this.setIsLabeled(true); // TODO: ac? no s'hauria de detectar si t? etiquetes?????
288
                        } catch (ReadException e) {
289
                                logger.error("Can't assign the specific lebeling strategy to the layer {}.", this.getName(), e);
290
                        }
291
                }
292

    
293
                this.delegate(dataStore);
294

    
295
                dataStore.addObserver(this);
296

    
297
                 // azabala: we check if this layer could have a file spatial index
298
                // and load it if it exists
299
                //        loadSpatialIndex();
300
        }
301

    
302
        public Envelope getFullEnvelope() throws ReadException {
303
                Envelope rAux;
304
                try {
305
                        rAux = getFeatureStore().getEnvelope();
306
                } catch (BaseException e) {
307
                        throw new ReadException(getName(),e);
308
                }
309

    
310
                //Esto es para cuando se crea una capa nueva con el fullExtent de ancho y alto 0.
311
                if (rAux == null || rAux.getMaximum(0)-rAux.getMinimum(0)==0 && rAux.getMaximum(1)-rAux.getMinimum(1)==0) {
312
                        try {
313
                                rAux= geomManager.createEnvelope(0,0,100,100, SUBTYPES.GEOM2D);
314
                        } catch (CreateEnvelopeException e) {
315
                                logger.error("Error creating the envelope", e);
316
                                e.printStackTrace();
317
                        }
318
                }
319
                // Si existe reproyecci?n, reproyectar el extent
320
                ICoordTrans ct = getCoordTrans();
321
                try{
322
                        if (ct != null) {
323
                                Point2D pt1 = new Point2D.Double(rAux.getMinimum(0), rAux.getMinimum(1));
324
                                Point2D pt2 = new Point2D.Double(rAux.getMaximum(0), rAux.getMaximum(1));
325
                                pt1 = ct.convert(pt1, null);
326
                                pt2 = ct.convert(pt2, null);
327
                                try {
328
                                        rAux = geomManager.createEnvelope(pt1.getX(),pt1.getY(),pt2.getX(),pt2.getY(), SUBTYPES.GEOM2D);
329
                                } catch (CreateEnvelopeException e) {
330
                                        logger.error("Error creating the envelope", e);
331
                                        e.printStackTrace();
332
                                }//new Rectangle2D.Double();
333
                        }
334
                }catch (IllegalStateException e) {
335
                        this.setAvailable(false);
336
                        this.addError(new ReprojectLayerException(getName(), e));
337
                }
338
                return rAux;
339

    
340
        }
341

    
342
        /**
343
         * Draws using IFeatureIterator. This method will replace the old draw(...) one.
344
         * @autor jaume dominguez faus - jaume.dominguez@iver.es
345
         * @param image
346
         * @param g
347
         * @param viewPort
348
         * @param cancel
349
         * @param scale
350
         * @throws ReadDriverException
351
         */
352
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
353
                        Cancellable cancel, double scale) throws ReadException {
354
                
355
                if (legend == null) {
356
                        return;
357
                }
358
                
359
                if (!this.isWithinScale(scale)) {
360
                        return;
361
                }
362
                if (cancel.isCanceled()) {
363
                        return;
364
                }
365

    
366
                if (spatialCache.isEnabled()) {
367
                        spatialCache.clearAll();
368
                        legend.addDrawingObserver(this);
369
                }
370

    
371
                try {
372
                        legend.draw(image, g, viewPort, cancel, scale, null,
373
                                        getCoordTrans(), getFeatureStore());
374

    
375
                } catch (LegendException e) {
376
                        this.setVisible(false);
377
                        this.setActive(false);
378
                        throw new ReadException(getName(), e);
379
                } finally {
380
                        if (spatialCache.isEnabled()) {
381
                                legend.deleteDrawingObserver(this);
382
                        }
383
                }
384
        }
385
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
386
                        double scale, PrintAttributes properties) throws ReadException {
387
                if (!this.isWithinScale(scale)) {
388
                        return;
389
                }
390
                if (cancel.isCanceled()) {
391
                        return;
392
                }
393

    
394
                try {
395
                        legend.print( g, viewPort, cancel, scale, null,
396
                                        getCoordTrans(), getFeatureStore(), properties);
397

    
398
                } catch (LegendException e) {
399
                        this.setVisible(false);
400
                        this.setActive(false);
401
                        throw new ReadException(getName(), e);
402
                }
403
        }
404

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

    
485
        //    public void createSpatialIndex() {
486
        //        createSpatialIndex(null);
487
        //    }
488

    
489

    
490
        public void setLegend(IVectorLegend legend) throws LegendLayerException {
491
                if (this.legend == legend){
492
                        return;
493
                }
494
                if (this.legend != null && this.legend.equals(legend)){
495
                        return;
496
                }
497
                IVectorLegend oldLegend = this.legend;
498
                this.legend = legend;
499
                if (oldLegend != null) {
500
                        oldLegend.removeLegendListener(this);
501
                        oldLegend.deleteDrawingObserver(this);
502
                }
503
                if (legend != null) {
504
                        this.legend.addDrawingObserver(this);
505
                        this.legend.addLegendListener(this);
506
                }
507
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
508
                                oldLegend, this.legend);
509
                e.setLayer(this);
510
                callLegendChanged(e);
511
        }
512

    
513
        /**
514
         * Devuelve la Leyenda de la capa.
515
         *
516
         * @return Leyenda.
517
         */
518
        public ILegend getLegend() {
519
                return legend;
520
        }
521

    
522
        /**
523
         * Devuelve el tipo de shape que contiene la capa.
524
         *
525
         * @return tipo de shape.
526
         *
527
         * @throws ReadException
528
         */
529
        public int getShapeType() throws ReadException {
530
                if (typeShape == -1) {
531
                        FeatureType featureType;
532
                        try {
533
                                featureType = (((FeatureStore)getDataStore()).getDefaultFeatureType());
534
                        } catch (DataException e) {
535
                                throw new ReadException(getName(),e);
536
                        }
537
                        int indexGeom=featureType.getDefaultGeometryAttributeIndex();
538
                        typeShape=featureType.getAttributeDescriptor(indexGeom).getGeometryType();
539
                }
540
                return typeShape;
541
        }
542
        
543
        public void saveToState(PersistentState state) throws PersistenceException {
544

    
545
                if (!this.isAvailable()) {
546
                        return;
547
                }
548
                
549
                super.saveToState(state);
550

    
551
                if (getLegend()!=null) {
552
                        state.set("legend", getLegend());
553
                }
554
                
555
                FeatureStore fst = null;
556
                fst = getFeatureStore();
557

    
558
                if (fst != null) {
559
                        state.set("featureStore", fst);
560
                }
561
                
562
                state.set("isLabeled", isLabeled);
563
                
564
                if (strategy != null) {
565
                        state.set("labelingStrategy", strategy);
566
                }                
567
                
568
                if (getLinkProperties() != null) {
569
                        state.set("linkProperties", getLinkProperties());
570
                }
571
                
572
//                state.set("bHasJoin", bHasJoin);
573
                state.set("typeShape", typeShape);
574
        }
575

    
576
//        public XMLEntity getXMLEntity() throws XMLException {
577
//
578
//                if (!this.isAvailable() && this.orgXMLEntity != null) {
579
//                        return this.orgXMLEntity;
580
//                }
581
//                XMLEntity xml = super.getXMLEntity();
582
//                if (getLegend()!=null){
583
//                        XMLEntity xmlLegend=getLegend().getXMLEntity();
584
//                        xmlLegend.putProperty("tagName","legend");
585
//                        xml.addChild(xmlLegend);
586
//                }
587
//                try {
588
//                        PersistenceManager manager = ToolsLocator.getPersistenceManager();
589
//                        PersistentState stateFeatureStore=manager.getState(getFeatureStore());
590
//                        stateFeatureStore.set("tagName","featureStore");
591
//                        xml.addChild(((XMLEntityState)stateFeatureStore).getXMLEntity());
592
//                } catch (ReadException e) {
593
//                        throw new XMLLayerException(getName(),e);
594
//                } catch (PersistenceException e) {
595
//                        throw new XMLLayerException(getName(),e);
596
//                }
597
//                // properties from ILabelable
598
//                xml.putProperty("isLabeled", isLabeled);
599
//                if (strategy != null) {
600
//                        XMLEntity strategyXML = strategy.getXMLEntity();
601
//                        strategyXML.putProperty("tagName", "labelingStrategy");
602
//                        xml.addChild(strategy.getXMLEntity());
603
//                }
604
//                xml.addChild(getLinkProperties().getXMLEntity());
605
//                return xml;
606
//        }
607
        
608
        
609
        
610

    
611
        public void loadFromState(PersistentState state) throws PersistenceException {
612
                
613
                super.loadFromState(state);
614
                
615
                DataStore store = (DataStore) state.get("featureStore");
616
                try {
617
                        this.setDataStore(store);
618
                } catch (LoadLayerException e) {
619
                        throw new PersistenceException("While loading FLyrVect from state.", e);
620
                }
621

    
622
                IVectorLegend lgnd = (IVectorLegend) state.get("legend");
623
                try {
624
                        this.setLegend(lgnd);
625
                } catch (LegendLayerException e) {
626
                        throw new PersistenceException("While loading FLyrVect from state.", e);
627
                }
628

    
629
                Boolean isLbl = new Boolean(false);
630
                ILabelingStrategy lblst = null;
631
                
632
                try {
633
                        isLbl = (Boolean) state.get("isLabeled");
634
                        if (isLbl.booleanValue()) {
635
                                lblst = (ILabelingStrategy) state.get("labelingStrategy");
636
                        }
637
                } catch (Exception ex) {
638
                        throw new PersistenceException("While loading FLyrVect from state.", ex);
639
                }
640
                
641
                /*
642
                String _labelFieldName = null;
643
                String _labelfield = null;
644
                */
645
                
646
                if (isLbl.booleanValue()) {
647
                        this.setIsLabeled(true);
648
                        this.setLabelingStrategy(lblst);
649
                } else {
650
                        this.setIsLabeled(false);
651
                        this.setLabelingStrategy(null);
652
                }
653
                
654
//                try {
655
//                        linkProperties = (FLyrVectLinkProperties) state.get("linkProperties");
656
//                } catch (PersistenceException pex) {
657
//                        // not mandatory
658
//                        linkProperties = null;
659
//                }
660
                
661
                        
662
                //bHasJoin = state.getBoolean("bHasJoin");
663
                typeShape = state.getInt("typeShape");
664

    
665
//                        try { _labelFieldName = state.getString("labelFieldName"); } catch (PersistenceException ex) {
666
//                                _labelFieldName = null;
667
//                        }
668
//                        try { _labelfield = state.getString("labelfield"); } catch (PersistenceException ex) {
669
//                                _labelfield = null;
670
//                        }
671
                        
672
                        // ILabelingStrategy not implemented
673
//                        if (_labelFieldName != null) {
674
//                                
675
//                                AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
676
//                                try {
677
//                                        labeling.setLayer(this);
678
//                                } catch (ReadException e) {
679
//                                        logger.error("While setting layer to AttrInTableLabelingStrategy: " + e.getMessage());
680
//                                }
681
//                                labeling.setUsesFixedSize(true);
682
//                                labeling.setFixedSize(10);
683
//                                labeling.setTextField(_labelFieldName);
684
//                                labeling.setHeightField(state.getString("labelHeightFieldName"));
685
//                                labeling.setRotationField(state.getString("labelRotationFieldName"));
686
//                                setLabelingStrategy(labeling);
687
//                                setIsLabeled(true);
688
//                                
689
//                        } else {
690
//                                if (_labelfield != null) {
691
//                                        
692
//                                        AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
693
//                                        try {
694
//                                                labeling.setLayer(this);
695
//                                        } catch (ReadException e) {
696
//                                                logger.error("While setting layer to AttrInTableLabelingStrategy: " + e.getMessage());
697
//                                        }
698
//                                        labeling.setUsesFixedSize(true);
699
//                                        labeling.setFixedSize(10);
700
//                                        labeling.setTextField(_labelfield);
701
//                                        labeling.setHeightField(state.getString("labelFieldHeight"));
702
//                                        labeling.setRotationField(state.getString("labelFieldRotation"));
703
//                                        setLabelingStrategy(labeling);
704
//                                        setIsLabeled(true);
705
//                                }
706
//                        }
707
                        
708
        }
709

    
710
//        public void setXMLEntity(XMLEntity xml) throws XMLException {
711
//                try {
712
//                        super.setXMLEntity(xml);
713
//                        XMLEntity legendXML = xml.firstChild("tagName","legend");
714
//                        IVectorLegend leg = LegendFactory.createFromXML(legendXML);
715
//
716
//                        //            PersistentState persistentState=new XMLEntityState(new XMLEntityManager());
717
//                        XMLEntity xmlStore=xml.firstChild("tagName","featureStore");
718
//                        XMLEntityManager xmlManger = new XMLEntityManager();
719
//                        PersistentState state = xmlManger.createState(xmlStore);
720
//                        DataStore store = (DataStore) ToolsLocator.getPersistenceManager().create(state);
721
//                        //            persistentState.createState(xmlStore);
722
//
723
//                        //            DataManager dm=DALLocator.getDataManager();
724
//
725
//                        this.setDataStore(store);
726
//                        /* end patch */
727
//                        try {
728
//                                setLegend(leg);
729
//                        } catch (LegendLayerException e) {
730
//                                throw new XMLLegendException(e);
731
//                        }
732
//                        // set properties for ILabelable
733
//
734
//                        if (xml.contains("isLabeled")
735
//                                        && xml.getBooleanProperty(("isLabeled"))) {
736
//                                XMLEntity labelingXML = xml.firstChild("tagName", "labelingStrategy");
737
//                                if (labelingXML != null){
738
//
739
//                                        isLabeled = true;
740
//                                        try {
741
//                                                this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this);
742
//                                        } catch (NotExistInXMLEntity neXMLEX) {
743
//                                                // no strategy was set, just continue;
744
//                                                logger.warn("Reached what should be unreachable code");
745
//                                        }
746
//                                } else {
747
//                                        isLabeled = false;
748
//                                }
749
//                        } else if (legendXML.contains("labelFieldName")|| legendXML.contains("labelfield")) {
750
//                            /* (jaume) begin patch;
751
//                         * for backward compatibility purposes. Since gvSIG v1.1 labeling is
752
//                         * no longer managed by the Legend but by the ILabelingStrategy. The
753
//                         * following allows restoring older projects' labelings.
754
//                         */
755
//                                String labelTextField =        null;
756
//                            if (legendXML.contains("labelFieldName")){
757
//                                    labelTextField = legendXML.getStringProperty("labelFieldName");
758
//                                    if (labelTextField != null) {
759
//                                            AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
760
//                                            labeling.setLayer(this);
761
//                                            labeling.setUsesFixedSize(true);
762
//                                            labeling.setFixedSize(10);
763
//                                            labeling.setTextField(labelTextField);
764
//                                            labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
765
//                                            labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
766
//                                            this.setLabelingStrategy(labeling);
767
//                                            this.setIsLabeled(true);
768
//                                    }
769
//                            }else{
770
//                                    labelTextField = legendXML.getStringProperty("labelfield");
771
//                                    if (labelTextField != null) {
772
//                                            AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
773
//                                            labeling.setLayer(this);
774
//                                            labeling.setUsesFixedSize(true);
775
//                                            labeling.setFixedSize(10);
776
//                                            labeling.setTextField(labelTextField);
777
//                                            labeling.setHeightField(legendXML.getStringProperty("labelFieldHeight"));
778
//                                            labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
779
//                                            this.setLabelingStrategy(labeling);
780
//                                            this.setIsLabeled(true);
781
//                                    }
782
//                            }
783
//                }else{
784
//                                isLabeled = false;
785
//                        }
786
//                        XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
787
//                        if (xmlLinkProperties != null){
788
//                                getLinkProperties().setXMLEntity(xmlLinkProperties);
789
//                        }
790
//                } catch (Exception e) {
791
//                        e.printStackTrace();
792
//                        this.setAvailable(false);
793
//                        this.orgXMLEntity = xml;
794
//
795
//                }
796
//                //
797
//
798
//        }
799

    
800

    
801

    
802

    
803
        /**
804
         * Sobreimplementaci?n del m?todo toString para que las bases de datos
805
         * identifiquen la capa.
806
         *
807
         * @return DOCUMENT ME!
808
         */
809
        public String toString() {
810
                /*
811
                 * Se usa internamente para que la parte de datos identifique de forma
812
                 * un?voca las tablas
813
                 */
814
                String ret = super.toString();
815

    
816
                return "layer" + ret.substring(ret.indexOf('@') + 1);
817
        }
818

    
819
//        public boolean isJoined() {
820
//                return bHasJoin;
821
//        }
822

    
823
        /**
824
         * Returns if a layer is spatially indexed
825
         *
826
         * @return if this layer has the ability to proces spatial queries without
827
         *         secuential scans.
828
         */
829
        //    public boolean isSpatiallyIndexed() {
830
        //        ReadableVectorial source = getSource();
831
        //        if (source instanceof ISpatialDB)
832
        //            return true;
833
        //
834
        ////FIXME azabala
835
        ///*
836
        // * Esto es muy dudoso, y puede cambiar.
837
        // * Estoy diciendo que las que no son fichero o no son
838
        // * BoundedShapes estan indexadas. Esto es mentira, pero
839
        // * as? quien pregunte no querr? generar el indice.
840
        // * Esta por ver si interesa generar el indice para capas
841
        // * HSQLDB, WFS, etc.
842
        // */
843
        //        if(!(source instanceof VectorialFileAdapter)){
844
        //            return true;
845
        //        }
846
        //        if (!(source.getDriver() instanceof BoundedShapes)) {
847
        //            return true;
848
        //        }
849
        //
850
        //        if (getISpatialIndex() != null)
851
        //            return true;
852
        //        return false;
853
        //    }
854
//
855
//        public void setIsJoined(boolean hasJoin) {
856
//                bHasJoin = hasJoin;
857
//        }
858

    
859
        //    /**
860
        //     * @return Returns the spatialIndex.
861
        //     */
862
        //    public ISpatialIndex getISpatialIndex() {
863
        //        return spatialIndex;
864
        //    }
865
        //    /**
866
        //     * Sets the spatial index. This could be useful if, for some
867
        //     * reasons, you want to work with a distinct spatial index
868
        //     * (for example, a spatial index which could makes nearest
869
        //     * neighbour querys)
870
        //     * @param spatialIndex
871
        //     */
872
        //    public void setISpatialIndex(ISpatialIndex spatialIndex){
873
        //        this.spatialIndex = spatialIndex;
874
        //    }
875

    
876
        public void setEditing(boolean b) throws StartEditionLayerException {
877
                super.setEditing(b);
878
                if (b){
879
                        try {
880
                                getFeatureStore().edit();
881
                        } catch (ReadException e) {
882
                                throw new StartEditionLayerException(getName(),e);
883
                        } catch (DataException e) {
884
                                throw new StartEditionLayerException(getName(),e);
885
                        }
886
                }
887
                setSpatialCacheEnabled(b);
888
                callEditionChanged(LayerEvent
889
                                .createEditionChangedEvent(this, "edition"));
890

    
891
        }
892

    
893
        
894
        /**
895
         * @deprecated Use {@link #getSpatialCache()}
896
         */
897
        public void clearSpatialCache()
898
        {
899
                spatialCache.clearAll();
900
        }
901

    
902
        /**
903
         * @deprecated Use {@link #getSpatialCache()}
904
         */
905
        public boolean isSpatialCacheEnabled() {
906
                return spatialCache.isEnabled();
907
        }
908

    
909
        /**
910
         * @deprecated Use {@link #getSpatialCache()}
911
         */
912
        public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
913
                spatialCache.setEnabled(spatialCacheEnabled);
914
        }
915

    
916
        public SpatialCache getSpatialCache() {
917
                return spatialCache;
918
        }
919

    
920
        /**
921
         * Siempre es un numero mayor de 1000
922
         * @param maxFeatures
923
         */
924
        public void setMaxFeaturesInEditionCache(int maxFeatures) {
925
                if (maxFeatures > spatialCache.getMaxFeatures()) {
926
                        spatialCache.setMaxFeatures(maxFeatures);
927
                }
928

    
929
        }
930

    
931
        /**
932
         * This method returns a boolean that is used by the FPopMenu
933
         * to make visible the properties menu or not. It is visible by
934
         * default, and if a later don't have to show this menu only
935
         * has to override this method.
936
         * @return
937
         * If the properties menu is visible (or not)
938
         */
939
        public boolean isPropertiesMenuVisible(){
940
                return true;
941
        }
942

    
943
        public void reload() throws ReloadLayerException {
944
                super.reload();
945
                try {
946
                        DataManager dataManager=DALLocator.getDataManager();
947
                        DataStoreParameters storeParameters;
948

    
949
                        storeParameters = getFeatureStore().getParameters();
950

    
951
                        DataStore dataStore=dataManager.createStore(storeParameters);
952
                        setDataStore(dataStore);
953
                        getFeatureStore().refresh();
954
                } catch (Exception e) {
955
                        throw new ReloadLayerException(getName(),e);
956
                }
957
                //        try {
958
                //            this.source.getDriver().reload();
959
                //            if (this.getLegend() == null) {
960
                //                if (this.getRecordset().getDriver() instanceof WithDefaultLegend) {
961
                //                    WithDefaultLegend aux = (WithDefaultLegend) this.getRecordset().getDriver();
962
                //                    this.setLegend((IVectorLegend) aux.getDefaultLegend());
963
                //                    this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
964
                //                } else {
965
                //                    this.setLegend(LegendFactory.createSingleSymbolLegend(
966
                //                            this.getShapeType()));
967
                //                }
968
                //            }
969
                //
970
                //        } catch (LegendLayerException e) {
971
                //            this.setAvailable(false);
972
                //            throw new ReloadLayerException(getName(),e);
973
                //        } catch (ReadException e) {
974
                //            this.setAvailable(false);
975
                //            throw new ReloadLayerException(getName(),e);
976
                //        }
977

    
978

    
979
        }
980

    
981
        protected void setLoadSelection(Object xml) {
982
                // this.loadSelection = xml;
983
        }
984

    
985
        protected void setLoadLegend(IVectorLegend legend) {
986
                this.loadLegend = legend;
987
        }
988

    
989
        protected void putLoadSelection() {
990
                //        if (this.loadSelection == null) return;
991
                //        try {
992
                //            this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
993
                //        } catch (ReadDriverException e) {
994
                //            throw new XMLException(e);
995
                //        }
996
                //        this.loadSelection = null;
997

    
998
        }
999
        protected void putLoadLegend() throws LegendLayerException {
1000
                if (this.loadLegend == null) {
1001
                        return;
1002
                }
1003
                this.setLegend(this.loadLegend);
1004
                this.loadLegend = null;
1005
        }
1006

    
1007
        protected void cleanLoadOptions() {
1008
                this.loadLegend = null;
1009
        }
1010

    
1011
        public boolean isWritable() {
1012
                return getFeatureStore().allowWrite();
1013
        }
1014

    
1015
        public FLayer cloneLayer() throws Exception {
1016
                FLyrVect clonedLayer = new FLyrVect();
1017
                clonedLayer.setDataStore(getDataStore());
1018
//                if (isJoined()) {
1019
//                        clonedLayer.setIsJoined(true);
1020
//                }
1021
                clonedLayer.setVisible(isVisible());
1022
                //        clonedLayer.setISpatialIndex(getISpatialIndex());
1023
                clonedLayer.setName(getName());
1024
                clonedLayer.setCoordTrans(getCoordTrans());
1025

    
1026
                clonedLayer.setLegend((IVectorLegend)getLegend().cloneLegend());
1027

    
1028
                clonedLayer.setIsLabeled(isLabeled());
1029
                ILabelingStrategy labelingStrategy=getLabelingStrategy();
1030
        if (labelingStrategy!=null) {
1031
                        clonedLayer.setLabelingStrategy(labelingStrategy);
1032
                }
1033

    
1034
                return clonedLayer;
1035
        }
1036

    
1037

    
1038
        protected boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, double dpi, CartographicSupport csSym, Geometry geom, int[] xyCoords) {
1039
                return isOnePoint(graphicsTransform, viewPort, geom, xyCoords) && csSym.getCartographicSize(viewPort, dpi, geom) <= 1;
1040
        }
1041

    
1042
        private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, Geometry geom, int[] xyCoords) {
1043
                boolean onePoint = false;
1044
                int type=geom.getType();
1045
                if (type == Geometry.TYPES.NULL) {
1046
                        return false;
1047
                }
1048
                if (type!=Geometry.TYPES.POINT && type!=Geometry.TYPES.MULTIPOINT) {
1049

    
1050
                        Envelope geomBounds = geom.getEnvelope();
1051

    
1052
                        ICoordTrans ct = getCoordTrans();
1053

    
1054
                        // Se supone que la geometria ya esta reproyectada
1055
                        // if (ct!=null) {
1056
                        // // geomBounds = ct.getInverted().convert(geomBounds);
1057
                        // geomBounds = geomBounds.convert(ct);
1058
                        // }
1059

    
1060
                        double dist1Pixel = viewPort.getDist1pixel();
1061

    
1062
                        onePoint = (geomBounds.getLength(0)  <= dist1Pixel
1063
                                        && geomBounds.getLength(1) <= dist1Pixel);
1064

    
1065
                        if (onePoint) {
1066
                                // avoid out of range exceptions
1067
                                org.gvsig.fmap.geom.primitive.Point p;
1068
                                try {
1069
                                        p = geomManager.createPoint(geomBounds.getMinimum(0), geomBounds.getMinimum(1), SUBTYPES.GEOM2D);
1070
                                        p.transform(viewPort.getAffineTransform());
1071
                                        p.transform(graphicsTransform);
1072
                                        xyCoords[0] = (int) p.getX();
1073
                                        xyCoords[1] = (int) p.getY();
1074
                                } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
1075
                                        logger.error("Error creating a point", e);
1076
                                }
1077

    
1078
                        }
1079

    
1080
                }
1081
                return onePoint;
1082
        }
1083
        /*
1084
         * jaume. Stuff from ILabeled.
1085
         */
1086
        private boolean isLabeled;
1087
        protected ILabelingStrategy strategy;
1088

    
1089
        public boolean isLabeled() {
1090
                return isLabeled;
1091
        }
1092

    
1093
        public void setIsLabeled(boolean isLabeled) {
1094
                this.isLabeled = isLabeled;
1095
        }
1096

    
1097
        public ILabelingStrategy getLabelingStrategy() {
1098
                return strategy;
1099
        }
1100

    
1101
        public void setLabelingStrategy(ILabelingStrategy strategy) {
1102
                this.strategy = strategy;
1103
                
1104
                if (strategy == null) {
1105
                        return;
1106
                }
1107
                
1108
                try {
1109
                        strategy.setLayer(this);
1110
                } catch (ReadException e) {
1111
                        logger.error("While setting layer to ILabelingStrategy: " + e.getMessage());
1112
                }
1113

    
1114
        }
1115

    
1116
        public void drawLabels(BufferedImage image, Graphics2D g, ViewPort viewPort,
1117
                        Cancellable cancel, double scale, double dpi) throws ReadException {
1118
                if (strategy!=null && isWithinScale(scale)) {
1119
                        strategy.draw(image, g, viewPort, cancel, dpi);
1120
                }
1121
        }
1122

    
1123
        public void printLabels(Graphics2D g, ViewPort viewPort,
1124
                        Cancellable cancel, double scale,
1125
                        PrintAttributes properties) throws ReadException {
1126
                if (strategy != null) {
1127
                        strategy.print(g, viewPort, cancel, properties);
1128
                }
1129
        }
1130
        //M?todos para el uso de HyperLinks en capas FLyerVect
1131

    
1132
        /**
1133
         * Return true, because a Vectorial Layer supports HyperLink
1134
         */
1135
        public boolean allowLinks()
1136
        {
1137
                return true;
1138
        }
1139

    
1140
        /**
1141
         * Returns an instance of AbstractLinkProperties that contains the information
1142
         * of the HyperLink
1143
         * @return Abstra
1144
         */
1145
//        public AbstractLinkProperties getLinkProperties()
1146
//        {
1147
//                return linkProperties;
1148
//        }
1149

    
1150
        /**
1151
         * Provides an array with URIs. Returns one URI by geometry that includes the point
1152
         * in its own geometry limits with a allowed tolerance.
1153
         * @param layer, the layer
1154
         * @param point, the point to check that is contained or not in the geometries in the layer
1155
         * @param tolerance, the tolerance allowed. Allowed margin of error to detect if the  point
1156
         *                 is contained in some geometries of the layer
1157
         * @return
1158
         * @throws ReadException
1159
         * @throws BehaviorException
1160
         */
1161
//        public URI[] getLink(Point2D point, double tolerance) throws ReadException
1162
//        {
1163
//                //return linkProperties.getLink(this)
1164
//                return linkProperties.getLink(this,point,tolerance);
1165
//        }
1166

    
1167
        public void load() throws LoadLayerException {
1168
                super.load();
1169
        }
1170

    
1171
        public FeatureStore getFeatureStore() {
1172
                return (FeatureStore)getDataStore();
1173
        }
1174

    
1175
        public FeatureSet queryByPoint(Point2D mapPoint, double tol, FeatureType featureType) throws DataException {
1176
                GeometryManager manager = GeometryLocator.getGeometryManager();
1177
                org.gvsig.fmap.geom.primitive.Point center;
1178
                try {
1179
                        center = (org.gvsig.fmap.geom.primitive.Point)manager.create(TYPES.POINT, SUBTYPES.GEOM2D);
1180
                        center.setX(mapPoint.getX());
1181
                        center.setY(mapPoint.getY());
1182
                        Circle circle = (Circle)manager.create(TYPES.CIRCLE, SUBTYPES.GEOM2D);
1183
                        circle.setPoints(center, tol);
1184
                        return queryByGeometry(circle, featureType);
1185
                } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
1186
                        throw new CreateGeometryException(TYPES.CIRCLE, SUBTYPES.GEOM2D, e);
1187
                }
1188
        }
1189

    
1190

    
1191
        public FeatureSet queryByGeometry(Geometry geom, FeatureType featureType) throws DataException {
1192
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
1193
                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
1194
                featureQuery.setFeatureType(featureType);
1195
                IntersectsGeometryEvaluator iee=new IntersectsGeometryEvaluator(geom,getMapContext().getViewPort().getProjection(),featureStore.getDefaultFeatureType(),geomName);
1196
                featureQuery.setFilter(iee);
1197
                return getFeatureStore().getFeatureSet(featureQuery);
1198

    
1199
        }
1200

    
1201
        public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType)
1202
        throws DataException {
1203
                return queryByEnvelope(envelope, featureType, null);
1204
        }
1205

    
1206
        public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType, String[] names)
1207
        throws DataException {
1208
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
1209
                if (names==null){
1210
                        featureQuery.setFeatureType(featureType);
1211
                }else{
1212
                        featureQuery.setAttributeNames(names);
1213
                        featureQuery.setFeatureTypeId(featureType.getId());
1214
                }
1215
                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
1216
                ContainsEnvelopeEvaluator iee=new ContainsEnvelopeEvaluator(envelope,getMapContext().getViewPort().getProjection(),featureStore.getDefaultFeatureType(),geomName);
1217
                featureQuery.setFilter(iee);
1218
                return getFeatureStore().getFeatureSet(featureQuery);
1219

    
1220
        }
1221

    
1222
    public DynObjectSet getInfo(Point p, double tolerance, Cancellable cancel)
1223
        throws LoadLayerException, DataException {
1224
                
1225
                Point2D infop = new Point2D.Double(p.x, p.y);
1226
                Point2D pReal = this.getMapContext().getViewPort().toMapPoint(infop);
1227
        return queryByPoint(pReal, tolerance, getFeatureStore()
1228
            .getDefaultFeatureType());
1229
        }
1230

    
1231
        public void legendCleared(LegendClearEvent event) {
1232
                // this.updateDrawVersion(); TODO
1233
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
1234
                                legend, legend);
1235
                this.callLegendChanged(e);
1236
        }
1237

    
1238
        public boolean symbolChanged(SymbolLegendEvent e) {
1239
                LegendChangedEvent ev = LegendChangedEvent.createLegendChangedEvent(
1240
                                legend, legend);
1241
                this.callLegendChanged(ev);
1242
                return true;
1243
        }
1244

    
1245
        public void update(Observable observable, Object notification) {
1246
                if (observable.equals(this.featureStore)) {
1247
                        if (notification instanceof FeatureStoreNotification) {
1248
                                FeatureStoreNotification event = (FeatureStoreNotification) notification;
1249
                                if (event.getType() == FeatureStoreNotification.AFTER_CANCELEDITING
1250
                                                || event.getType() == FeatureStoreNotification.AFTER_DELETE
1251
                                                || event.getType() == FeatureStoreNotification.AFTER_UNDO
1252
                                                || event.getType() == FeatureStoreNotification.AFTER_REDO
1253
                                                || event.getType() == FeatureStoreNotification.AFTER_REFRESH
1254
                                                || event.getType() == FeatureStoreNotification.AFTER_UPDATE
1255
                                                || event.getType() == FeatureStoreNotification.AFTER_UPDATE_TYPE
1256
                                                || event.getType() == FeatureStoreNotification.SELECTION_CHANGE
1257
                                                || event.getType() == FeatureStoreNotification.AFTER_INSERT) {
1258
                                        this.updateDrawVersion();
1259

    
1260
                                } else if (event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE
1261
                                                || event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
1262
                                        this.setAvailable(false);
1263
                                        
1264
                                        
1265
                                        //                                        try {
1266
                                        //                                                reload();
1267
                                        //                                        } catch (ReloadLayerException e) {
1268
                                        //                                                this.setAvailable(false);
1269
                                        //                                        }
1270
                                        
1271
                                } else if (event.getType() == FeatureStoreNotification.AFTER_FINISHEDITING){
1272

    
1273
                                }
1274
                        }
1275

    
1276
                }
1277
                // Only if its an event from our own legend
1278
                else 
1279
                        //I comment this line because a legend doesn't implements the Observable interface.
1280
                        //This code is necessary on edition.
1281
                        //if (observable == getLegend()) {
1282
                        if (notification instanceof FeatureDrawnNotification) {
1283
                                Geometry geometry = ((FeatureDrawnNotification) notification)
1284
                                                .getDrawnGeometry();
1285
                                spatialCache.insert(geometry.getEnvelope(), geometry);
1286
                        //}
1287
                }
1288

    
1289
        }
1290

    
1291
        /*
1292
         * (non-Javadoc)
1293
         *
1294
         * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1295
         */
1296
        public Set getMetadataChildren() {
1297
                Set ret = new TreeSet();
1298
                ret.add(this.featureStore);
1299
                return ret;
1300
        }
1301

    
1302
        /*
1303
         * (non-Javadoc)
1304
         *
1305
         * @see org.gvsig.metadata.Metadata#getMetadataID()
1306
         */
1307
        public Object getMetadataID() throws MetadataException {
1308
                return "Layer(" + this.getName() + "):"
1309
                + this.featureStore.getMetadataID();
1310
        }
1311

    
1312
        /*
1313
         * (non-Javadoc)
1314
         *
1315
         * @see org.gvsig.metadata.Metadata#getMetadataName()
1316
         */
1317
        public String getMetadataName() throws MetadataException {
1318
                return "Layer '" + this.getName() + "':"
1319
                + this.featureStore.getMetadataName();
1320
        }
1321

    
1322
        public GeometryType getTypeVectorLayer() throws DataException, LocatorException, GeometryTypeNotSupportedException, GeometryTypeNotValidException {
1323
                // FIXME Esto deberia de pedirse a FType!!!!
1324
                FeatureStore fs = this.getFeatureStore();
1325
                FeatureType fType = fs.getDefaultFeatureType();
1326
                FeatureAttributeDescriptor attr = fType.getAttributeDescriptor(fType
1327
                                .getDefaultGeometryAttributeIndex());
1328
                GeometryType geomType = GeometryLocator.getGeometryManager()
1329
                                .getGeometryType(attr.getGeometryType(),
1330
                                                attr.getGeometrySubType());
1331
                return geomType;
1332
        }
1333

    
1334
        public static void registerPersistent() {
1335
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
1336
                if( manager.getDefinition(FLyrDefault.class) == null ) {
1337
                        FLyrDefault.registerPersistent();
1338
                }
1339
                DynStruct definition = manager.addDefinition(
1340
                                FLyrVect.class,
1341
                                "FLyrVect",
1342
                                "FLyrVect Persistence definition",
1343
                                null, 
1344
                                null
1345
                );
1346
                definition.extend( PersistenceManager.PERSISTENCE_NAMESPACE,  "FLyrDefault" );
1347

    
1348
                definition.addDynFieldObject("legend")
1349
                        .setClassOfValue(IVectorLegend.class)
1350
                        .setMandatory(true);
1351
                definition.addDynFieldObject("featureStore")
1352
                        .setClassOfValue(FeatureStore.class)
1353
                        .setMandatory(true);
1354
                definition.addDynFieldBoolean("isLabeledDate").setMandatory(true);
1355
                //definition.addDynFieldBoolean("bHasJoin").setMandatory(true);
1356
                definition.addDynFieldInt("typeShape").setMandatory(true);
1357
                definition.addDynFieldObject("labelingStrategy")
1358
                        .setClassOfValue(ILabelingStrategy.class)
1359
                        .setMandatory(false);
1360
//                definition.addDynFieldObject("linkProperties")
1361
//                        .setClassOfValue(FLyrVectLinkProperties.class)
1362
//                        .setMandatory(false);
1363
        
1364
        }
1365

    
1366
        protected void doDispose() throws BaseException {
1367
                dispose(featureStore);
1368
                spatialCache.clearAll();
1369
        }
1370
}