Statistics
| Revision:

svn-gvsig-desktop / tags / v2_0_0_Build_2020 / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / layers / vectorial / FLyrVect.java @ 33790

History | View | Annotate | Download (49.6 KB)

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

    
121
public class FLyrVect extends FLyrDefault implements VectorLayer,
122
    LegendContentsChangedListener, Observer {
123

    
124
    final static private org.slf4j.Logger logger =
125
        LoggerFactory.getLogger(FLyrVect.class);
126
    private final GeometryManager geomManager =
127
        GeometryLocator.getGeometryManager();
128

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

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

    
141
    private boolean isLabeled;
142
    protected ILabelingStrategy strategy;
143

    
144
    public FLyrVect() {
145
        super();
146
    }
147

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

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

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

    
265
        featureStore = (FeatureStore) dataStore;
266

    
267
        ILegend legend =
268
            MapContextLocator.getMapContextManager().getLegend(dataStore);
269

    
270
        if (legend == null) {
271
            throw new LegendLayerException(this.getName());
272
        }
273

    
274
        this.setLegend((IVectorLegend) legend);
275

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

    
289
        if (labeler != null) {
290
            labeler.setLayer(this);
291
            this.setLabelingStrategy(labeler);
292
            this.setIsLabeled(true); // TODO: ac? no s'hauria de detectar si t?
293
                                     // etiquetes?????
294
        }
295

    
296
        this.delegate(dataStore);
297

    
298
        dataStore.addObserver(this);
299

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

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

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

    
353
    }
354

    
355
    /**
356
     * Draws using IFeatureIterator. This method will replace the old draw(...)
357
     * one.
358
     * 
359
     * @autor jaume dominguez faus - jaume.dominguez@iver.es
360
     * @param image
361
     * @param g
362
     * @param viewPort
363
     * @param cancel
364
     * @param scale
365
     * @throws ReadDriverException
366
     */
367
    public void draw(BufferedImage image,
368
        Graphics2D g,
369
        ViewPort viewPort,
370
        Cancellable cancel,
371
        double scale) throws ReadException {
372

    
373
        if (legend == null) {
374
            return;
375
        }
376

    
377
        if (!this.isWithinScale(scale)) {
378
            return;
379
        }
380
        if (cancel.isCanceled()) {
381
            return;
382
        }
383

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

    
389
        try {
390
            legend.draw(image,
391
                g,
392
                viewPort,
393
                cancel,
394
                scale,
395
                null,
396
                getCoordTrans(),
397
                getFeatureStore());
398

    
399
        } catch (LegendException e) {
400
            this.setVisible(false);
401
            this.setActive(false);
402
            throw new ReadException(getName(), e);
403
        } finally {
404
            if (spatialCache.isEnabled()) {
405
                legend.deleteDrawingObserver(this);
406
            }
407
        }
408
    }
409

    
410
    public void print(Graphics2D g,
411
        ViewPort viewPort,
412
        Cancellable cancel,
413
        double scale,
414
        PrintAttributes properties) throws ReadException {
415
        if (!this.isWithinScale(scale)) {
416
            return;
417
        }
418
        if (cancel.isCanceled()) {
419
            return;
420
        }
421

    
422
        try {
423
            legend.print(g,
424
                viewPort,
425
                cancel,
426
                scale,
427
                null,
428
                getCoordTrans(),
429
                getFeatureStore(),
430
                properties);
431

    
432
        } catch (LegendException e) {
433
            this.setVisible(false);
434
            this.setActive(false);
435
            throw new ReadException(getName(), e);
436
        }
437
    }
438

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

    
521
    // public void createSpatialIndex() {
522
    // createSpatialIndex(null);
523
    // }
524

    
525
    public void setLegend(IVectorLegend legend) throws LegendLayerException {
526
        if (this.legend == legend) {
527
            return;
528
        }
529
        if (this.legend != null && this.legend.equals(legend)) {
530
            return;
531
        }
532
        IVectorLegend oldLegend = this.legend;
533
        this.legend = legend;
534
        if (oldLegend != null) {
535
            oldLegend.removeLegendListener(this);
536
            oldLegend.deleteDrawingObserver(this);
537
        }
538
        if (legend != null) {
539
            this.legend.addDrawingObserver(this);
540
            this.legend.addLegendListener(this);
541
        }
542
        LegendChangedEvent e =
543
            LegendChangedEvent.createLegendChangedEvent(oldLegend, this.legend);
544
        e.setLayer(this);
545
        callLegendChanged(e);
546
    }
547

    
548
    /**
549
     * Devuelve la Leyenda de la capa.
550
     * 
551
     * @return Leyenda.
552
     */
553
    public ILegend getLegend() {
554
        return legend;
555
    }
556

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

    
580
    public void saveToState(PersistentState state) throws PersistenceException {
581

    
582
        if (!this.isAvailable()) {
583
            return;
584
        }
585

    
586
        super.saveToState(state);
587

    
588
        if (getLegend() != null) {
589
            state.set("legend", getLegend());
590
        }
591

    
592
        FeatureStore fst = null;
593
        fst = getFeatureStore();
594

    
595
        if (fst != null) {
596
            state.set("featureStore", fst);
597
        }
598

    
599
        state.set("isLabeled", isLabeled);
600

    
601
        if (strategy != null) {
602
            state.set("labelingStrategy", strategy);
603
        }
604

    
605
        if (getLinkProperties() != null) {
606
            state.set("linkProperties", getLinkProperties());
607
        }
608

    
609
        // state.set("bHasJoin", bHasJoin);
610
        state.set("typeShape", typeShape);
611
    }
612

    
613
    // public XMLEntity getXMLEntity() throws XMLException {
614
    //
615
    // if (!this.isAvailable() && this.orgXMLEntity != null) {
616
    // return this.orgXMLEntity;
617
    // }
618
    // XMLEntity xml = super.getXMLEntity();
619
    // if (getLegend()!=null){
620
    // XMLEntity xmlLegend=getLegend().getXMLEntity();
621
    // xmlLegend.putProperty("tagName","legend");
622
    // xml.addChild(xmlLegend);
623
    // }
624
    // try {
625
    // PersistenceManager manager = ToolsLocator.getPersistenceManager();
626
    // PersistentState stateFeatureStore=manager.getState(getFeatureStore());
627
    // stateFeatureStore.set("tagName","featureStore");
628
    // xml.addChild(((XMLEntityState)stateFeatureStore).getXMLEntity());
629
    // } catch (ReadException e) {
630
    // throw new XMLLayerException(getName(),e);
631
    // } catch (PersistenceException e) {
632
    // throw new XMLLayerException(getName(),e);
633
    // }
634
    // // properties from ILabelable
635
    // xml.putProperty("isLabeled", isLabeled);
636
    // if (strategy != null) {
637
    // XMLEntity strategyXML = strategy.getXMLEntity();
638
    // strategyXML.putProperty("tagName", "labelingStrategy");
639
    // xml.addChild(strategy.getXMLEntity());
640
    // }
641
    // xml.addChild(getLinkProperties().getXMLEntity());
642
    // return xml;
643
    // }
644

    
645
    public void loadFromState(PersistentState state) throws PersistenceException {
646

    
647
        super.loadFromState(state);
648

    
649
        DataStore store = (DataStore) state.get("featureStore");
650
        try {
651
            this.setDataStore(store);
652
        } catch (LoadLayerException e) {
653
            throw new PersistenceException("While loading FLyrVect from state.",
654
                e);
655
        }
656

    
657
        IVectorLegend lgnd = (IVectorLegend) state.get("legend");
658
        try {
659
            this.setLegend(lgnd);
660
        } catch (LegendLayerException e) {
661
            throw new PersistenceException("While loading FLyrVect from state.",
662
                e);
663
        }
664

    
665
        Boolean isLbl = new Boolean(false);
666
        ILabelingStrategy lblst = null;
667

    
668
        try {
669
            isLbl = (Boolean) state.get("isLabeled");
670
            if (isLbl.booleanValue()) {
671
                lblst = (ILabelingStrategy) state.get("labelingStrategy");
672
            }
673
        } catch (Exception ex) {
674
            throw new PersistenceException("While loading FLyrVect from state.",
675
                ex);
676
        }
677

    
678
        /*
679
         * String _labelFieldName = null;
680
         * String _labelfield = null;
681
         */
682

    
683
        if (isLbl.booleanValue()) {
684
            this.setIsLabeled(true);
685
            this.setLabelingStrategy(lblst);
686
        } else {
687
            this.setIsLabeled(false);
688
            this.setLabelingStrategy(null);
689
        }
690

    
691
        // try {
692
        // linkProperties = (FLyrVectLinkProperties)
693
        // state.get("linkProperties");
694
        // } catch (PersistenceException pex) {
695
        // // not mandatory
696
        // linkProperties = null;
697
        // }
698

    
699
        // bHasJoin = state.getBoolean("bHasJoin");
700
        typeShape = state.getInt("typeShape");
701

    
702
        // try { _labelFieldName = state.getString("labelFieldName"); } catch
703
        // (PersistenceException ex) {
704
        // _labelFieldName = null;
705
        // }
706
        // try { _labelfield = state.getString("labelfield"); } catch
707
        // (PersistenceException ex) {
708
        // _labelfield = null;
709
        // }
710

    
711
        // ILabelingStrategy not implemented
712
        // if (_labelFieldName != null) {
713
        //
714
        // AttrInTableLabelingStrategy labeling = new
715
        // AttrInTableLabelingStrategy();
716
        // try {
717
        // labeling.setLayer(this);
718
        // } catch (ReadException e) {
719
        // logger.error("While setting layer to AttrInTableLabelingStrategy: " +
720
        // e.getMessage());
721
        // }
722
        // labeling.setUsesFixedSize(true);
723
        // labeling.setFixedSize(10);
724
        // labeling.setTextField(_labelFieldName);
725
        // labeling.setHeightField(state.getString("labelHeightFieldName"));
726
        // labeling.setRotationField(state.getString("labelRotationFieldName"));
727
        // setLabelingStrategy(labeling);
728
        // setIsLabeled(true);
729
        //
730
        // } else {
731
        // if (_labelfield != null) {
732
        //
733
        // AttrInTableLabelingStrategy labeling = new
734
        // AttrInTableLabelingStrategy();
735
        // try {
736
        // labeling.setLayer(this);
737
        // } catch (ReadException e) {
738
        // logger.error("While setting layer to AttrInTableLabelingStrategy: " +
739
        // e.getMessage());
740
        // }
741
        // labeling.setUsesFixedSize(true);
742
        // labeling.setFixedSize(10);
743
        // labeling.setTextField(_labelfield);
744
        // labeling.setHeightField(state.getString("labelFieldHeight"));
745
        // labeling.setRotationField(state.getString("labelFieldRotation"));
746
        // setLabelingStrategy(labeling);
747
        // setIsLabeled(true);
748
        // }
749
        // }
750

    
751
    }
752

    
753
    // public void setXMLEntity(XMLEntity xml) throws XMLException {
754
    // try {
755
    // super.setXMLEntity(xml);
756
    // XMLEntity legendXML = xml.firstChild("tagName","legend");
757
    // IVectorLegend leg = LegendFactory.createFromXML(legendXML);
758
    //
759
    // // PersistentState persistentState=new XMLEntityState(new
760
    // XMLEntityManager());
761
    // XMLEntity xmlStore=xml.firstChild("tagName","featureStore");
762
    // XMLEntityManager xmlManger = new XMLEntityManager();
763
    // PersistentState state = xmlManger.createState(xmlStore);
764
    // DataStore store = (DataStore)
765
    // ToolsLocator.getPersistenceManager().create(state);
766
    // // persistentState.createState(xmlStore);
767
    //
768
    // // DataManager dm=DALLocator.getDataManager();
769
    //
770
    // this.setDataStore(store);
771
    // /* end patch */
772
    // try {
773
    // setLegend(leg);
774
    // } catch (LegendLayerException e) {
775
    // throw new XMLLegendException(e);
776
    // }
777
    // // set properties for ILabelable
778
    //
779
    // if (xml.contains("isLabeled")
780
    // && xml.getBooleanProperty(("isLabeled"))) {
781
    // XMLEntity labelingXML = xml.firstChild("tagName", "labelingStrategy");
782
    // if (labelingXML != null){
783
    //
784
    // isLabeled = true;
785
    // try {
786
    // this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this);
787
    // } catch (NotExistInXMLEntity neXMLEX) {
788
    // // no strategy was set, just continue;
789
    // logger.warn("Reached what should be unreachable code");
790
    // }
791
    // } else {
792
    // isLabeled = false;
793
    // }
794
    // } else if (legendXML.contains("labelFieldName")||
795
    // legendXML.contains("labelfield")) {
796
    // /* (jaume) begin patch;
797
    // * for backward compatibility purposes. Since gvSIG v1.1 labeling is
798
    // * no longer managed by the Legend but by the ILabelingStrategy. The
799
    // * following allows restoring older projects' labelings.
800
    // */
801
    // String labelTextField = null;
802
    // if (legendXML.contains("labelFieldName")){
803
    // labelTextField = legendXML.getStringProperty("labelFieldName");
804
    // if (labelTextField != null) {
805
    // AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
806
    // labeling.setLayer(this);
807
    // labeling.setUsesFixedSize(true);
808
    // labeling.setFixedSize(10);
809
    // labeling.setTextField(labelTextField);
810
    // labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
811
    // labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
812
    // this.setLabelingStrategy(labeling);
813
    // this.setIsLabeled(true);
814
    // }
815
    // }else{
816
    // labelTextField = legendXML.getStringProperty("labelfield");
817
    // if (labelTextField != null) {
818
    // AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
819
    // labeling.setLayer(this);
820
    // labeling.setUsesFixedSize(true);
821
    // labeling.setFixedSize(10);
822
    // labeling.setTextField(labelTextField);
823
    // labeling.setHeightField(legendXML.getStringProperty("labelFieldHeight"));
824
    // labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
825
    // this.setLabelingStrategy(labeling);
826
    // this.setIsLabeled(true);
827
    // }
828
    // }
829
    // }else{
830
    // isLabeled = false;
831
    // }
832
    // XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
833
    // if (xmlLinkProperties != null){
834
    // getLinkProperties().setXMLEntity(xmlLinkProperties);
835
    // }
836
    // } catch (Exception e) {
837
    // e.printStackTrace();
838
    // this.setAvailable(false);
839
    // this.orgXMLEntity = xml;
840
    //
841
    // }
842
    // //
843
    //
844
    // }
845

    
846
    /**
847
     * Sobreimplementaci?n del m?todo toString para que las bases de datos
848
     * identifiquen la capa.
849
     * 
850
     * @return DOCUMENT ME!
851
     */
852
    public String toString() {
853
        /*
854
         * Se usa internamente para que la parte de datos identifique de forma
855
         * un?voca las tablas
856
         */
857
        String ret = super.toString();
858

    
859
        return "layer" + ret.substring(ret.indexOf('@') + 1);
860
    }
861

    
862
    // public boolean isJoined() {
863
    // return bHasJoin;
864
    // }
865

    
866
    /**
867
     * Returns if a layer is spatially indexed
868
     * 
869
     * @return if this layer has the ability to proces spatial queries without
870
     *         secuential scans.
871
     */
872
    // public boolean isSpatiallyIndexed() {
873
    // ReadableVectorial source = getSource();
874
    // if (source instanceof ISpatialDB)
875
    // return true;
876
    //
877
    // //FIXME azabala
878
    // /*
879
    // * Esto es muy dudoso, y puede cambiar.
880
    // * Estoy diciendo que las que no son fichero o no son
881
    // * BoundedShapes estan indexadas. Esto es mentira, pero
882
    // * as? quien pregunte no querr? generar el indice.
883
    // * Esta por ver si interesa generar el indice para capas
884
    // * HSQLDB, WFS, etc.
885
    // */
886
    // if(!(source instanceof VectorialFileAdapter)){
887
    // return true;
888
    // }
889
    // if (!(source.getDriver() instanceof BoundedShapes)) {
890
    // return true;
891
    // }
892
    //
893
    // if (getISpatialIndex() != null)
894
    // return true;
895
    // return false;
896
    // }
897
    //
898
    // public void setIsJoined(boolean hasJoin) {
899
    // bHasJoin = hasJoin;
900
    // }
901

    
902
    // /**
903
    // * @return Returns the spatialIndex.
904
    // */
905
    // public ISpatialIndex getISpatialIndex() {
906
    // return spatialIndex;
907
    // }
908
    // /**
909
    // * Sets the spatial index. This could be useful if, for some
910
    // * reasons, you want to work with a distinct spatial index
911
    // * (for example, a spatial index which could makes nearest
912
    // * neighbour querys)
913
    // * @param spatialIndex
914
    // */
915
    // public void setISpatialIndex(ISpatialIndex spatialIndex){
916
    // this.spatialIndex = spatialIndex;
917
    // }
918

    
919
    public void setEditing(boolean b) throws StartEditionLayerException {
920
        super.setEditing(b);
921
        if (b) {
922
            try {
923
                getFeatureStore().edit();
924
            } catch (ReadException e) {
925
                throw new StartEditionLayerException(getName(), e);
926
            } catch (DataException e) {
927
                throw new StartEditionLayerException(getName(), e);
928
            }
929
        }
930
        setSpatialCacheEnabled(b);
931
        callEditionChanged(LayerEvent.createEditionChangedEvent(this, "edition"));
932

    
933
    }
934

    
935
    /**
936
     * @deprecated Use {@link #getSpatialCache()}
937
     */
938
    public void clearSpatialCache() {
939
        spatialCache.clearAll();
940
    }
941

    
942
    /**
943
     * @deprecated Use {@link #getSpatialCache()}
944
     */
945
    public boolean isSpatialCacheEnabled() {
946
        return spatialCache.isEnabled();
947
    }
948

    
949
    /**
950
     * @deprecated Use {@link #getSpatialCache()}
951
     */
952
    public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
953
        spatialCache.setEnabled(spatialCacheEnabled);
954
    }
955

    
956
    public SpatialCache getSpatialCache() {
957
        return spatialCache;
958
    }
959

    
960
    /**
961
     * Siempre es un numero mayor de 1000
962
     * 
963
     * @param maxFeatures
964
     */
965
    public void setMaxFeaturesInEditionCache(int maxFeatures) {
966
        if (maxFeatures > spatialCache.getMaxFeatures()) {
967
            spatialCache.setMaxFeatures(maxFeatures);
968
        }
969

    
970
    }
971

    
972
    /**
973
     * This method returns a boolean that is used by the FPopMenu
974
     * to make visible the properties menu or not. It is visible by
975
     * default, and if a later don't have to show this menu only
976
     * has to override this method.
977
     * 
978
     * @return
979
     *         If the properties menu is visible (or not)
980
     */
981
    public boolean isPropertiesMenuVisible() {
982
        return true;
983
    }
984

    
985
    public void reload() throws ReloadLayerException {
986
        super.reload();
987
        try {
988
            DataManager dataManager = DALLocator.getDataManager();
989
            DataStoreParameters storeParameters;
990

    
991
            storeParameters = getFeatureStore().getParameters();
992

    
993
            DataStore dataStore = dataManager.createStore(storeParameters);
994
            setDataStore(dataStore);
995
            getFeatureStore().refresh();
996
        } catch (Exception e) {
997
            throw new ReloadLayerException(getName(), e);
998
        }
999
        // try {
1000
        // this.source.getDriver().reload();
1001
        // if (this.getLegend() == null) {
1002
        // if (this.getRecordset().getDriver() instanceof WithDefaultLegend) {
1003
        // WithDefaultLegend aux = (WithDefaultLegend)
1004
        // this.getRecordset().getDriver();
1005
        // this.setLegend((IVectorLegend) aux.getDefaultLegend());
1006
        // this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
1007
        // } else {
1008
        // this.setLegend(LegendFactory.createSingleSymbolLegend(
1009
        // this.getShapeType()));
1010
        // }
1011
        // }
1012
        //
1013
        // } catch (LegendLayerException e) {
1014
        // this.setAvailable(false);
1015
        // throw new ReloadLayerException(getName(),e);
1016
        // } catch (ReadException e) {
1017
        // this.setAvailable(false);
1018
        // throw new ReloadLayerException(getName(),e);
1019
        // }
1020

    
1021
    }
1022

    
1023
    protected void setLoadSelection(Object xml) {
1024
        // this.loadSelection = xml;
1025
    }
1026

    
1027
    protected void setLoadLegend(IVectorLegend legend) {
1028
        this.loadLegend = legend;
1029
    }
1030

    
1031
    protected void putLoadSelection() {
1032
        // if (this.loadSelection == null) return;
1033
        // try {
1034
        // this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
1035
        // } catch (ReadDriverException e) {
1036
        // throw new XMLException(e);
1037
        // }
1038
        // this.loadSelection = null;
1039

    
1040
    }
1041

    
1042
    protected void putLoadLegend() throws LegendLayerException {
1043
        if (this.loadLegend == null) {
1044
            return;
1045
        }
1046
        this.setLegend(this.loadLegend);
1047
        this.loadLegend = null;
1048
    }
1049

    
1050
    protected void cleanLoadOptions() {
1051
        this.loadLegend = null;
1052
    }
1053

    
1054
    public boolean isWritable() {
1055
        return getFeatureStore().allowWrite();
1056
    }
1057

    
1058
    public FLayer cloneLayer() throws Exception {
1059
        FLyrVect clonedLayer = new FLyrVect();
1060
        clonedLayer.setDataStore(getDataStore());
1061
        // if (isJoined()) {
1062
        // clonedLayer.setIsJoined(true);
1063
        // }
1064
        clonedLayer.setVisible(isVisible());
1065
        // clonedLayer.setISpatialIndex(getISpatialIndex());
1066
        clonedLayer.setName(getName());
1067
        clonedLayer.setCoordTrans(getCoordTrans());
1068

    
1069
        clonedLayer.setLegend((IVectorLegend) getLegend().cloneLegend());
1070

    
1071
        clonedLayer.setIsLabeled(isLabeled());
1072
        ILabelingStrategy labelingStrategy = getLabelingStrategy();
1073
        if (labelingStrategy != null) {
1074
            clonedLayer.setLabelingStrategy(labelingStrategy);
1075
        }
1076

    
1077
        return clonedLayer;
1078
    }
1079

    
1080
    protected boolean isOnePoint(AffineTransform graphicsTransform,
1081
        ViewPort viewPort,
1082
        double dpi,
1083
        CartographicSupport csSym,
1084
        Geometry geom,
1085
        int[] xyCoords) {
1086
        return isOnePoint(graphicsTransform, viewPort, geom, xyCoords)
1087
            && csSym.getCartographicSize(viewPort, dpi, geom) <= 1;
1088
    }
1089

    
1090
    private boolean isOnePoint(AffineTransform graphicsTransform,
1091
        ViewPort viewPort,
1092
        Geometry geom,
1093
        int[] xyCoords) {
1094
        boolean onePoint = false;
1095
        int type = geom.getType();
1096
        if (type == Geometry.TYPES.NULL) {
1097
            return false;
1098
        }
1099
        if (type != Geometry.TYPES.POINT && type != Geometry.TYPES.MULTIPOINT) {
1100

    
1101
            Envelope geomBounds = geom.getEnvelope();
1102

    
1103
            // ICoordTrans ct = getCoordTrans();
1104

    
1105
            // Se supone que la geometria ya esta reproyectada
1106
            // if (ct!=null) {
1107
            // // geomBounds = ct.getInverted().convert(geomBounds);
1108
            // geomBounds = geomBounds.convert(ct);
1109
            // }
1110

    
1111
            double dist1Pixel = viewPort.getDist1pixel();
1112

    
1113
            onePoint =
1114
                (geomBounds.getLength(0) <= dist1Pixel && geomBounds.getLength(1) <= dist1Pixel);
1115

    
1116
            if (onePoint) {
1117
                // avoid out of range exceptions
1118
                org.gvsig.fmap.geom.primitive.Point p;
1119
                try {
1120
                    p =
1121
                        geomManager.createPoint(geomBounds.getMinimum(0),
1122
                            geomBounds.getMinimum(1),
1123
                            SUBTYPES.GEOM2D);
1124
                    p.transform(viewPort.getAffineTransform());
1125
                    p.transform(graphicsTransform);
1126
                    xyCoords[0] = (int) p.getX();
1127
                    xyCoords[1] = (int) p.getY();
1128
                } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
1129
                    logger.error("Error creating a point", e);
1130
                }
1131

    
1132
            }
1133

    
1134
        }
1135
        return onePoint;
1136
    }
1137

    
1138
    /*
1139
     * jaume. Stuff from ILabeled.
1140
     */
1141

    
1142
    public boolean isLabeled() {
1143
        return isLabeled;
1144
    }
1145

    
1146
    public void setIsLabeled(boolean isLabeled) {
1147
        this.isLabeled = isLabeled;
1148
    }
1149

    
1150
    public ILabelingStrategy getLabelingStrategy() {
1151
        return strategy;
1152
    }
1153

    
1154
    public void setLabelingStrategy(ILabelingStrategy strategy) {
1155
        this.strategy = strategy;
1156
        if (strategy == null) {
1157
            return;
1158
        }
1159
        strategy.setLayer(this);
1160
    }
1161

    
1162
    public void drawLabels(BufferedImage image,
1163
        Graphics2D g,
1164
        ViewPort viewPort,
1165
        Cancellable cancel,
1166
        double scale,
1167
        double dpi) throws ReadException {
1168
        if (strategy != null && isWithinScale(scale)) {
1169
            strategy.draw(image, g, viewPort, cancel, dpi);
1170
        }
1171
    }
1172

    
1173
    public void printLabels(Graphics2D g,
1174
        ViewPort viewPort,
1175
        Cancellable cancel,
1176
        double scale,
1177
        PrintAttributes properties) throws ReadException {
1178
        if (strategy != null) {
1179
            strategy.print(g, viewPort, cancel, properties);
1180
        }
1181
    }
1182

    
1183
    // M?todos para el uso de HyperLinks en capas FLyerVect
1184

    
1185
    /**
1186
     * Return true, because a Vectorial Layer supports HyperLink
1187
     */
1188
    public boolean allowLinks() {
1189
        return true;
1190
    }
1191

    
1192
    /**
1193
     * Returns an instance of AbstractLinkProperties that contains the
1194
     * information
1195
     * of the HyperLink
1196
     * 
1197
     * @return Abstra
1198
     */
1199
    // public AbstractLinkProperties getLinkProperties()
1200
    // {
1201
    // return linkProperties;
1202
    // }
1203

    
1204
    /**
1205
     * Provides an array with URIs. Returns one URI by geometry that includes
1206
     * the point
1207
     * in its own geometry limits with a allowed tolerance.
1208
     * 
1209
     * @param layer
1210
     *            , the layer
1211
     * @param point
1212
     *            , the point to check that is contained or not in the
1213
     *            geometries in the layer
1214
     * @param tolerance
1215
     *            , the tolerance allowed. Allowed margin of error to detect if
1216
     *            the point
1217
     *            is contained in some geometries of the layer
1218
     * @return
1219
     * @throws ReadException
1220
     * @throws BehaviorException
1221
     */
1222
    // public URI[] getLink(Point2D point, double tolerance) throws
1223
    // ReadException
1224
    // {
1225
    // //return linkProperties.getLink(this)
1226
    // return linkProperties.getLink(this,point,tolerance);
1227
    // }
1228

    
1229
    public void load() throws LoadLayerException {
1230
        super.load();
1231
    }
1232

    
1233
    public FeatureStore getFeatureStore() {
1234
        return (FeatureStore) getDataStore();
1235
    }
1236

    
1237
    public FeatureSet queryByPoint(Point2D mapPoint,
1238
        double tol,
1239
        FeatureType featureType) throws DataException {
1240
        GeometryManager manager = GeometryLocator.getGeometryManager();
1241
        org.gvsig.fmap.geom.primitive.Point center;
1242
        try {
1243
            center =
1244
                (org.gvsig.fmap.geom.primitive.Point) manager.create(TYPES.POINT,
1245
                    SUBTYPES.GEOM2D);
1246
            center.setX(mapPoint.getX());
1247
            center.setY(mapPoint.getY());
1248
            Circle circle =
1249
                (Circle) manager.create(TYPES.CIRCLE, SUBTYPES.GEOM2D);
1250
            circle.setPoints(center, tol);
1251
            return queryByGeometry(circle, featureType);
1252
        } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
1253
            throw new CreateGeometryException(TYPES.CIRCLE, SUBTYPES.GEOM2D, e);
1254
        }
1255
    }
1256

    
1257
    public FeatureSet queryByGeometry(Geometry geom, FeatureType featureType) throws DataException {
1258
        FeatureQuery featureQuery = featureStore.createFeatureQuery();
1259
        String geomName =
1260
            featureStore.getDefaultFeatureType()
1261
                .getDefaultGeometryAttributeName();
1262
        featureQuery.setFeatureType(featureType);
1263
        IntersectsGeometryEvaluator iee =
1264
            new IntersectsGeometryEvaluator(geom,
1265
                getMapContext().getViewPort().getProjection(),
1266
                featureStore.getDefaultFeatureType(),
1267
                geomName);
1268
        featureQuery.setFilter(iee);
1269
        return getFeatureStore().getFeatureSet(featureQuery);
1270

    
1271
    }
1272

    
1273
    public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType) throws DataException {
1274
        return queryByEnvelope(envelope, featureType, null);
1275
    }
1276

    
1277
    public FeatureSet queryByEnvelope(Envelope envelope,
1278
        FeatureType featureType,
1279
        String[] names) throws DataException {
1280
        FeatureQuery featureQuery = featureStore.createFeatureQuery();
1281
        if (names == null) {
1282
            featureQuery.setFeatureType(featureType);
1283
        } else {
1284
            featureQuery.setAttributeNames(names);
1285
            featureQuery.setFeatureTypeId(featureType.getId());
1286
        }
1287
        String geomName =
1288
            featureStore.getDefaultFeatureType()
1289
                .getDefaultGeometryAttributeName();
1290
        ContainsEnvelopeEvaluator iee =
1291
            new ContainsEnvelopeEvaluator(envelope,
1292
                getMapContext().getViewPort().getProjection(),
1293
                featureStore.getDefaultFeatureType(),
1294
                geomName);
1295
        featureQuery.setFilter(iee);
1296
        return getFeatureStore().getFeatureSet(featureQuery);
1297

    
1298
    }
1299

    
1300
    public DynObjectSet getInfo(Point p, double tolerance, Cancellable cancel) throws LoadLayerException,
1301
        DataException {
1302

    
1303
        return getInfo(p, tolerance, cancel, true);
1304
    }
1305

    
1306
    public DynObjectSet getInfo(Point p,
1307
        double tolerance,
1308
        Cancellable cancel,
1309
        boolean fast) throws LoadLayerException, DataException {
1310
        Point2D infop = new Point2D.Double(p.x, p.y);
1311
        Point2D pReal = this.getMapContext().getViewPort().toMapPoint(infop);
1312
        return queryByPoint(pReal,
1313
            tolerance,
1314
            getFeatureStore().getDefaultFeatureType()).getDynObjectSet(fast);
1315
    }
1316

    
1317
    public void legendCleared(LegendClearEvent event) {
1318
        // this.updateDrawVersion(); TODO
1319
        LegendChangedEvent e =
1320
            LegendChangedEvent.createLegendChangedEvent(legend, legend);
1321
        this.callLegendChanged(e);
1322
    }
1323

    
1324
    public boolean symbolChanged(SymbolLegendEvent e) {
1325
        LegendChangedEvent ev =
1326
            LegendChangedEvent.createLegendChangedEvent(legend, legend);
1327
        this.callLegendChanged(ev);
1328
        return true;
1329
    }
1330

    
1331
    public void update(Observable observable, Object notification) {
1332
        if (observable.equals(this.featureStore)) {
1333
            if (notification instanceof FeatureStoreNotification) {
1334
                FeatureStoreNotification event =
1335
                    (FeatureStoreNotification) notification;
1336
                if (event.getType() == FeatureStoreNotification.AFTER_CANCELEDITING
1337
                    || event.getType() == FeatureStoreNotification.AFTER_DELETE
1338
                    || event.getType() == FeatureStoreNotification.AFTER_UNDO
1339
                    || event.getType() == FeatureStoreNotification.AFTER_REDO
1340
                    || event.getType() == FeatureStoreNotification.AFTER_REFRESH
1341
                    || event.getType() == FeatureStoreNotification.AFTER_UPDATE
1342
                    || event.getType() == FeatureStoreNotification.AFTER_UPDATE_TYPE
1343
                    || event.getType() == FeatureStoreNotification.SELECTION_CHANGE
1344
                    || event.getType() == FeatureStoreNotification.AFTER_INSERT) {
1345
                    this.updateDrawVersion();
1346

    
1347
                } else
1348
                    if (event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE
1349
                        || event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
1350
                        this.setAvailable(false);
1351

    
1352
                        // try {
1353
                        // reload();
1354
                        // } catch (ReloadLayerException e) {
1355
                        // this.setAvailable(false);
1356
                        // }
1357

    
1358
                    } else
1359
                        if (event.getType() == FeatureStoreNotification.AFTER_FINISHEDITING) {
1360

    
1361
                        }
1362
            }
1363

    
1364
        }
1365
        // Only if its an event from our own legend
1366
        else
1367
            // I comment this line because a legend doesn't implements the
1368
            // Observable interface.
1369
            // This code is necessary on edition.
1370
            // if (observable == getLegend()) {
1371
            if (notification instanceof FeatureDrawnNotification) {
1372
                Geometry geometry =
1373
                    ((FeatureDrawnNotification) notification).getDrawnGeometry();
1374
                spatialCache.insert(geometry.getEnvelope(), geometry);
1375
                // }
1376
            }
1377

    
1378
    }
1379

    
1380
    /*
1381
     * (non-Javadoc)
1382
     * 
1383
     * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1384
     */
1385
    public Set getMetadataChildren() {
1386
        Set ret = new TreeSet();
1387
        ret.add(this.featureStore);
1388
        return ret;
1389
    }
1390

    
1391
    /*
1392
     * (non-Javadoc)
1393
     * 
1394
     * @see org.gvsig.metadata.Metadata#getMetadataID()
1395
     */
1396
    public Object getMetadataID() throws MetadataException {
1397
        return "Layer(" + this.getName() + "):"
1398
            + this.featureStore.getMetadataID();
1399
    }
1400

    
1401
    /*
1402
     * (non-Javadoc)
1403
     * 
1404
     * @see org.gvsig.metadata.Metadata#getMetadataName()
1405
     */
1406
    public String getMetadataName() throws MetadataException {
1407
        return "Layer '" + this.getName() + "':"
1408
            + this.featureStore.getMetadataName();
1409
    }
1410

    
1411
    public GeometryType getTypeVectorLayer() throws DataException,
1412
        LocatorException,
1413
        GeometryTypeNotSupportedException,
1414
        GeometryTypeNotValidException {
1415
        // FIXME Esto deberia de pedirse a FType!!!!
1416
        FeatureStore fs = this.getFeatureStore();
1417
        FeatureType fType = fs.getDefaultFeatureType();
1418
        FeatureAttributeDescriptor attr =
1419
            fType.getAttributeDescriptor(fType.getDefaultGeometryAttributeIndex());
1420
        GeometryType geomType =
1421
            GeometryLocator.getGeometryManager()
1422
                .getGeometryType(attr.getGeometryType(),
1423
                    attr.getGeometrySubType());
1424
        return geomType;
1425
    }
1426

    
1427
    public static void registerPersistent() {
1428
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
1429
        if (manager.getDefinition(FLyrDefault.class) == null) {
1430
            FLyrDefault.registerPersistent();
1431
        }
1432
        DynStruct definition =
1433
            manager.addDefinition(FLyrVect.class,
1434
                "FLyrVect",
1435
                "FLyrVect Persistence definition",
1436
                null,
1437
                null);
1438
        definition.extend(PersistenceManager.PERSISTENCE_NAMESPACE,
1439
            "FLyrDefault");
1440

    
1441
        definition.addDynFieldObject("legend")
1442
            .setClassOfValue(IVectorLegend.class)
1443
            .setMandatory(true);
1444
        definition.addDynFieldObject("featureStore")
1445
            .setClassOfValue(FeatureStore.class)
1446
            .setMandatory(true);
1447
        definition.addDynFieldBoolean("isLabeled").setMandatory(true);
1448
        definition.addDynFieldInt("typeShape").setMandatory(true);
1449
        definition.addDynFieldObject("labelingStrategy")
1450
            .setClassOfValue(ILabelingStrategy.class)
1451
            .setMandatory(false);
1452

    
1453
    }
1454

    
1455
    protected void doDispose() throws BaseException {
1456
        dispose(featureStore);
1457
        spatialCache.clearAll();
1458
    }
1459
}