Statistics
| Revision:

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

History | View | Annotate | Download (45.4 KB)

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

    
53
import org.cresques.cts.ICoordTrans;
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.GeometryLocator;
70
import org.gvsig.fmap.geom.GeometryManager;
71
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
72
import org.gvsig.fmap.geom.Geometry.TYPES;
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.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.rendering.legend.ILegend;
92
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
93
import org.gvsig.fmap.mapcontext.rendering.legend.LegendException;
94
import org.gvsig.fmap.mapcontext.rendering.legend.events.FeatureDrawnNotification;
95
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
96
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
97
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendContentsChangedListener;
98
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
99
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
100
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
101
import org.gvsig.metadata.exceptions.MetadataException;
102
import org.gvsig.tools.ToolsLocator;
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
import org.slf4j.LoggerFactory;
115

    
116

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

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

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

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

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

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

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

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

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

    
263
                featureStore = (FeatureStore)dataStore;
264

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

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

    
273

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

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

    
294
                this.delegate(dataStore);
295

    
296
                dataStore.addObserver(this);
297

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

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

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

    
341
        }
342

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

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

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

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

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

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

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

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

    
490

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

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

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

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

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

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

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

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

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

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

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

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

    
801

    
802

    
803

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

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

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

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

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

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

    
892
        }
893

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

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

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

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

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

    
930
        }
931

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

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

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

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

    
979

    
980
        }
981

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

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

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

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

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

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

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

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

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

    
1035
                return clonedLayer;
1036
        }
1037

    
1038

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

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

    
1051
                        Envelope geomBounds = geom.getEnvelope();
1052

    
1053
                        ICoordTrans ct = getCoordTrans();
1054

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

    
1061
                        double dist1Pixel = viewPort.getDist1pixel();
1062

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

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

    
1079
                        }
1080

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

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

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

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

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

    
1115
        }
1116

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

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

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

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

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

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

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

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

    
1191

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

    
1200
        }
1201

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

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

    
1221
        }
1222
        public Iterator getInfo(Point p, double tolerance, Cancellable cancel) throws LoadLayerException, DataException {
1223
                
1224
                Point2D infop = new Point2D.Double(p.x, p.y);
1225
                Point2D pReal = this.getMapContext().getViewPort().toMapPoint(infop);
1226
                FeatureSet featureCollection=null;
1227
                try {
1228
                        featureCollection = queryByPoint(pReal, tolerance, getFeatureStore().getDefaultFeatureType());
1229
                } catch (DataException e) {
1230
                        // TODO Auto-generated catch block
1231
                        e.printStackTrace();
1232
                }
1233
//                VectorialXMLItem[] item = new VectorialXMLItem[1];
1234
//                item[0] = new VectorialXMLItem(featureCollection, this);
1235

    
1236
                return featureCollection.iterator();
1237
        }
1238

    
1239
        public void legendCleared(LegendClearEvent event) {
1240
                // this.updateDrawVersion(); TODO
1241
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
1242
                                legend, legend);
1243
                this.callLegendChanged(e);
1244
        }
1245

    
1246
        public boolean symbolChanged(SymbolLegendEvent e) {
1247
                LegendChangedEvent ev = LegendChangedEvent.createLegendChangedEvent(
1248
                                legend, legend);
1249
                this.callLegendChanged(ev);
1250
                return true;
1251
        }
1252

    
1253
        public void update(Observable observable, Object notification) {
1254
                if (observable.equals(this.featureStore)) {
1255
                        if (notification instanceof FeatureStoreNotification) {
1256
                                FeatureStoreNotification event = (FeatureStoreNotification) notification;
1257
                                if (event.getType() == FeatureStoreNotification.AFTER_CANCELEDITING
1258
                                                || event.getType() == FeatureStoreNotification.AFTER_DELETE
1259
                                                || event.getType() == FeatureStoreNotification.AFTER_UNDO
1260
                                                || event.getType() == FeatureStoreNotification.AFTER_REDO
1261
                                                || event.getType() == FeatureStoreNotification.AFTER_REFRESH
1262
                                                || event.getType() == FeatureStoreNotification.AFTER_UPDATE
1263
                                                || event.getType() == FeatureStoreNotification.AFTER_UPDATE_TYPE
1264
                                                || event.getType() == FeatureStoreNotification.SELECTION_CHANGE
1265
                                                || event.getType() == FeatureStoreNotification.AFTER_INSERT) {
1266
                                        this.updateDrawVersion();
1267

    
1268
                                } else if (event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE
1269
                                                || event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
1270
                                        this.setAvailable(false);
1271
                                        
1272
                                        
1273
                                        //                                        try {
1274
                                        //                                                reload();
1275
                                        //                                        } catch (ReloadLayerException e) {
1276
                                        //                                                this.setAvailable(false);
1277
                                        //                                        }
1278
                                        
1279
                                } else if (event.getType() == FeatureStoreNotification.AFTER_FINISHEDITING){
1280

    
1281
                                }
1282
                        }
1283

    
1284
                }
1285
                // Only if its an event from our own legend
1286
                else 
1287
                        //I comment this line because a legend doesn't implements the Observable interface.
1288
                        //This code is necessary on edition.
1289
                        //if (observable == getLegend()) {
1290
                        if (notification instanceof FeatureDrawnNotification) {
1291
                                Geometry geometry = ((FeatureDrawnNotification) notification)
1292
                                                .getDrawnGeometry();
1293
                                spatialCache.insert(geometry.getEnvelope(), geometry);
1294
                        //}
1295
                }
1296

    
1297
        }
1298

    
1299
        /*
1300
         * (non-Javadoc)
1301
         *
1302
         * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1303
         */
1304
        public Set getMetadataChildren() {
1305
                Set ret = new TreeSet();
1306
                ret.add(this.featureStore);
1307
                return ret;
1308
        }
1309

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

    
1320
        /*
1321
         * (non-Javadoc)
1322
         *
1323
         * @see org.gvsig.metadata.Metadata#getMetadataName()
1324
         */
1325
        public String getMetadataName() throws MetadataException {
1326
                return "Layer '" + this.getName() + "':"
1327
                + this.featureStore.getMetadataName();
1328
        }
1329

    
1330
        public GeometryType getTypeVectorLayer() throws DataException, LocatorException, GeometryTypeNotSupportedException, GeometryTypeNotValidException {
1331
                // FIXME Esto deberia de pedirse a FType!!!!
1332
                FeatureStore fs = this.getFeatureStore();
1333
                FeatureType fType = fs.getDefaultFeatureType();
1334
                FeatureAttributeDescriptor attr = fType.getAttributeDescriptor(fType
1335
                                .getDefaultGeometryAttributeIndex());
1336
                GeometryType geomType = GeometryLocator.getGeometryManager()
1337
                                .getGeometryType(attr.getGeometryType(),
1338
                                                attr.getGeometrySubType());
1339
                return geomType;
1340
        }
1341

    
1342
        public static void registerPersistent() {
1343
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
1344
                if( manager.getDefinition(FLyrDefault.class) == null ) {
1345
                        FLyrDefault.registerPersistent();
1346
                }
1347
                DynStruct definition = manager.addDefinition(
1348
                                FLyrVect.class,
1349
                                "FLyrVect",
1350
                                "FLyrVect Persistence definition",
1351
                                null, 
1352
                                null
1353
                );
1354
                definition.extend( PersistenceManager.PERSISTENCE_NAMESPACE,  "FLyrDefault" );
1355

    
1356
                definition.addDynFieldObject("legend")
1357
                        .setClassOfValue(IVectorLegend.class)
1358
                        .setMandatory(true);
1359
                definition.addDynFieldObject("featureStore")
1360
                        .setClassOfValue(FeatureStore.class)
1361
                        .setMandatory(true);
1362
                definition.addDynFieldBoolean("isLabeledDate").setMandatory(true);
1363
                //definition.addDynFieldBoolean("bHasJoin").setMandatory(true);
1364
                definition.addDynFieldInt("typeShape").setMandatory(true);
1365
                definition.addDynFieldObject("labelingStrategy")
1366
                        .setClassOfValue(ILabelingStrategy.class)
1367
                        .setMandatory(false);
1368
//                definition.addDynFieldObject("linkProperties")
1369
//                        .setClassOfValue(FLyrVectLinkProperties.class)
1370
//                        .setMandatory(false);
1371
        
1372
        }
1373

    
1374
        protected void doDispose() throws BaseException {
1375
                dispose(featureStore);
1376
                spatialCache.clearAll();
1377
        }
1378
}