Statistics
| Revision:

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

History | View | Annotate | Download (51.2 KB)

1 34515 cordinyana
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2 21200 vcaballero
 *
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 34515 cordinyana
 *   Av. Blasco Ib??ez, 50
24 21200 vcaballero
 *   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 21888 vcaballero
import java.awt.Point;
45 21200 vcaballero
import java.awt.geom.AffineTransform;
46
import java.awt.geom.Point2D;
47
import java.awt.image.BufferedImage;
48 25920 jmvivo
import java.util.Set;
49
import java.util.TreeSet;
50 21200 vcaballero
51
import org.cresques.cts.ICoordTrans;
52 33657 cordinyana
import org.slf4j.LoggerFactory;
53
54 29272 jldominguez
import org.gvsig.compat.print.PrintAttributes;
55 26225 jmvivo
import org.gvsig.fmap.dal.DataStore;
56 24691 vcaballero
import org.gvsig.fmap.dal.exception.DataException;
57 24504 jmvivo
import org.gvsig.fmap.dal.exception.ReadException;
58 27974 jmvivo
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor;
59 26225 jmvivo
import org.gvsig.fmap.dal.feature.FeatureQuery;
60
import org.gvsig.fmap.dal.feature.FeatureSet;
61
import org.gvsig.fmap.dal.feature.FeatureStore;
62
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
63
import org.gvsig.fmap.dal.feature.FeatureType;
64 26904 jpiera
import org.gvsig.fmap.dal.feature.exception.CreateGeometryException;
65 21200 vcaballero
import org.gvsig.fmap.geom.Geometry;
66 26904 jpiera
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
67
import org.gvsig.fmap.geom.Geometry.TYPES;
68 33429 cordinyana
import org.gvsig.fmap.geom.GeometryLocator;
69
import org.gvsig.fmap.geom.GeometryManager;
70 27414 jpiera
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
71 26904 jpiera
import org.gvsig.fmap.geom.primitive.Circle;
72 21426 vcaballero
import org.gvsig.fmap.geom.primitive.Envelope;
73 27974 jmvivo
import org.gvsig.fmap.geom.type.GeometryType;
74 28091 vcaballero
import org.gvsig.fmap.geom.type.GeometryTypeNotSupportedException;
75
import org.gvsig.fmap.geom.type.GeometryTypeNotValidException;
76 30011 cordinyana
import org.gvsig.fmap.mapcontext.MapContextLocator;
77 37491 jpiera
import org.gvsig.fmap.mapcontext.MapContextManager;
78 21200 vcaballero
import org.gvsig.fmap.mapcontext.ViewPort;
79 26225 jmvivo
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
80
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
81
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
82 27620 vcaballero
import org.gvsig.fmap.mapcontext.exceptions.ReprojectLayerException;
83 26225 jmvivo
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
84 34978 fdiaz
import org.gvsig.fmap.mapcontext.exceptions.StopEditionLayerException;
85 26225 jmvivo
import org.gvsig.fmap.mapcontext.layers.FLayer;
86
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
87
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
88
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
89
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
90
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
91 30011 cordinyana
import org.gvsig.fmap.mapcontext.rendering.legend.LegendException;
92
import org.gvsig.fmap.mapcontext.rendering.legend.events.FeatureDrawnNotification;
93 21200 vcaballero
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
94 25038 jmvivo
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
95
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendContentsChangedListener;
96 30011 cordinyana
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
97 21200 vcaballero
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
98 26225 jmvivo
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
99 32880 jjdelcerro
import org.gvsig.metadata.exceptions.MetadataException;
100 24797 vcaballero
import org.gvsig.tools.ToolsLocator;
101 33429 cordinyana
import org.gvsig.tools.dynobject.DynObjectSet;
102 32880 jjdelcerro
import org.gvsig.tools.dynobject.DynStruct;
103 23303 jmvivo
import org.gvsig.tools.exception.BaseException;
104 28091 vcaballero
import org.gvsig.tools.locator.LocatorException;
105 25242 jmvivo
import org.gvsig.tools.observer.Observable;
106
import org.gvsig.tools.observer.Observer;
107 32880 jjdelcerro
import org.gvsig.tools.persistence.PersistenceManager;
108 24797 vcaballero
import org.gvsig.tools.persistence.PersistentState;
109 32880 jjdelcerro
import org.gvsig.tools.persistence.exception.PersistenceException;
110 35763 fdiaz
import org.gvsig.tools.persistence.exception.PersistenceRuntimeException;
111 25058 jmvivo
import org.gvsig.tools.task.Cancellable;
112 21200 vcaballero
113
/**
114 34515 cordinyana
 * Capa b?sica Vectorial.
115 33739 fdiaz
 *
116 34515 cordinyana
 * @author Fernando Gonz?lez Cort?s
117 21200 vcaballero
 */
118
119 33739 fdiaz
public class FLyrVect extends FLyrDefault implements VectorLayer,
120
    LegendContentsChangedListener, Observer {
121 33331 jjdelcerro
122 33739 fdiaz
    final static private org.slf4j.Logger logger =
123
        LoggerFactory.getLogger(FLyrVect.class);
124
    private final GeometryManager geomManager =
125
        GeometryLocator.getGeometryManager();
126 21200 vcaballero
127 33739 fdiaz
    /** Leyenda de la capa vectorial */
128
    private IVectorLegend legend;
129
    private int typeShape = -1;
130
    private FeatureStore featureStore = null;
131
    private SpatialCache spatialCache = new SpatialCache();
132 21200 vcaballero
133 33739 fdiaz
    /**
134
     * An implementation of gvSIG spatial index
135
     */
136
    // protected ISpatialIndex spatialIndex = null;
137
    private IVectorLegend loadLegend = null;
138 21200 vcaballero
139 33739 fdiaz
    private boolean isLabeled;
140
    protected ILabelingStrategy strategy;
141 36248 fdiaz
//        private ReprojectDefaultGeometry reprojectTransform;
142 21200 vcaballero
143 33739 fdiaz
    public FLyrVect() {
144
        super();
145
    }
146 21200 vcaballero
147 33739 fdiaz
    /**
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 36248 fdiaz
159
//    public void setCoordTrans(ICoordTrans ct) {
160
//            super.setCoordTrans(ct);
161
//            if (ct != null){
162
//                    if (this.reprojectTransform == null){
163
//                            this.reprojectTransform = new ReprojectDefaultGeometry(ct);
164
//                    } else {
165
//                            this.reprojectTransform.setCoordTrans(ct);
166
//                    }
167
//                    try {
168
//                            this.getFeatureStore().getTransforms().add(this.reprojectTransform);
169
//                    } catch (DataException e) {
170
//                            throw new RuntimeException(e);
171
//                    }
172
//            }
173
//    }
174 22207 jmvivo
175 33739 fdiaz
    /**
176
     * If we use a persistent spatial index associated with this layer, and the
177
     * index is not intrisic to the layer (for example spatial databases) this
178
     * method looks for existent spatial index, and loads it.
179
     *
180
     */
181
    // private void loadSpatialIndex() {
182
    // //FIXME: Al abrir el indice en fichero...
183 34515 cordinyana
    // //?C?mo lo liberamos? un metodo Layer.shutdown()
184 33739 fdiaz
    //
185
    //
186
    // ReadableVectorial source = getSource();
187
    // //REVISAR QUE PASA CON LOS DRIVERS DXF, DGN, etc.
188
    // //PUES SON VECTORIALFILEADAPTER
189
    // if (!(source instanceof VectorialFileAdapter)) {
190
    // // we are not interested in db adapters
191
    // return;
192
    // }
193
    // VectorialDriver driver = source.getDriver();
194
    // if (!(driver instanceof BoundedShapes)) {
195
    // // we dont spatially index layers that are not bounded
196
    // return;
197
    // }
198
    // File file = ((VectorialFileAdapter) source).getFile();
199
    // String fileName = file.getAbsolutePath();
200
    // File sptFile = new File(fileName + ".qix");
201
    // if (!sptFile.exists() || (!(sptFile.length() > 0))) {
202
    // // before to exit, look for it in temp path
203
    // String tempPath = System.getProperty("java.io.tmpdir");
204
    // fileName = tempPath + File.separator + sptFile.getName();
205
    // sptFile = new File(fileName);
206
    // // it doesnt exists, must to create
207
    // if (!sptFile.exists() || (!(sptFile.length() > 0))) {
208
    // return;
209
    // }// if
210
    // }// if
211
    //
212
    // try {
213
    // source.start();
214
    // spatialIndex = new
215
    // QuadtreeGt2(FileUtils.getFileWithoutExtension(sptFile),
216
    // "NM", source.getFullExtent(), source.getShapeCount(), false);
217
    // source.setSpatialIndex(spatialIndex);
218
    // } catch (SpatialIndexException e) {
219
    // spatialIndex = null;
220
    // e.printStackTrace();
221
    // return;
222
    // } catch (ReadDriverException e) {
223
    // spatialIndex = null;
224
    // e.printStackTrace();
225
    // return;
226
    // }
227
    //
228
    // }
229 26225 jmvivo
230 33739 fdiaz
    /**
231
     * Checks if it has associated an external spatial index
232
     * (an spatial index file).
233
     *
234
     * It looks for it in main file path, or in temp system path.
235
     * If main file is rivers.shp, it looks for a file called
236
     * rivers.shp.qix.
237
     *
238
     * @return
239
     */
240
    // public boolean isExternallySpatiallyIndexed() {
241
    // /*
242 34515 cordinyana
    // * FIXME (AZABALA): Independizar del tipo de fichero de ?ndice
243 33739 fdiaz
    // * con el que se trabaje (ahora mismo considera la extension .qix,
244 34515 cordinyana
    // * pero esto depender? del tipo de ?ndice)
245 33739 fdiaz
    // * */
246
    // ReadableVectorial source = getSource();
247
    // if (!(source instanceof VectorialFileAdapter)) {
248
    // // we are not interested in db adapters.
249
    // // think in non spatial dbs, like HSQLDB
250
    // return false;
251
    // }
252
    // File file = ((VectorialFileAdapter) source).getFile();
253
    // String fileName = file.getAbsolutePath();
254
    // File sptFile = new File(fileName + ".qix");
255
    // if (!sptFile.exists() || (!(sptFile.length() > 0))) {
256
    // // before to exit, look for it in temp path
257
    // // it doesnt exists, must to create
258
    // String tempPath = System.getProperty("java.io.tmpdir");
259
    // fileName = tempPath + File.separator + sptFile.getName();
260
    // sptFile = new File(fileName);
261
    // if (!sptFile.exists() || (!(sptFile.length() > 0))) {
262
    // return false;
263
    // }// if
264
    // }// if
265
    // return true;
266
    // }
267
    /**
268
     * Inserta el VectorialAdapter a la capa.
269
     *
270
     * @param va
271
     *            VectorialAdapter.
272
     *
273 34515 cordinyana
     * @deprecated esto deber?a se ser protected
274 33739 fdiaz
     */
275
    public void setDataStore(DataStore dataStore) throws LoadLayerException {
276
        if (this.featureStore != null && this.featureStore != dataStore) {
277
            this.featureStore.deleteObserver(this);
278
        }
279 33339 jpiera
280 33739 fdiaz
        featureStore = (FeatureStore) dataStore;
281 22207 jmvivo
282 37491 jpiera
        MapContextManager mapContextManager =
283
            MapContextLocator.getMapContextManager();
284
285
        //Set the legend
286 34303 fdiaz
        IVectorLegend legend =
287 37491 jpiera
            (IVectorLegend)mapContextManager.getLegend(dataStore);
288 22207 jmvivo
289 33739 fdiaz
        if (legend == null) {
290
            throw new LegendLayerException(this.getName());
291
        }
292 25795 jmvivo
293 34303 fdiaz
        this.setLegend(legend);
294 22207 jmvivo
295 37491 jpiera
        //Set the labeling strategy
296
        ILabelingStrategy labeler =
297
            (ILabelingStrategy) mapContextManager.getLabelingStrategy(dataStore);
298 26225 jmvivo
299 33739 fdiaz
        if (labeler != null) {
300
            labeler.setLayer(this);
301
            this.setLabelingStrategy(labeler);
302 34515 cordinyana
            this.setIsLabeled(true); // TODO: ac? no s'hauria de detectar si t?
303 33739 fdiaz
                                     // etiquetes?????
304
        }
305 22207 jmvivo
306 33739 fdiaz
        this.delegate(dataStore);
307 21200 vcaballero
308 33739 fdiaz
        dataStore.addObserver(this);
309 26313 vcaballero
310 35183 cordinyana
        ToolsLocator.getDisposableManager().bind(dataStore);
311 33739 fdiaz
    }
312 21426 vcaballero
313 33739 fdiaz
    public Envelope getFullEnvelope() throws ReadException {
314
        Envelope rAux;
315
        try {
316
            rAux = getFeatureStore().getEnvelope();
317
        } catch (BaseException e) {
318
            throw new ReadException(getName(), e);
319
        }
320 21200 vcaballero
321 33739 fdiaz
        // Esto es para cuando se crea una capa nueva con el fullExtent de ancho
322
        // y alto 0.
323 36231 fdiaz
        if (rAux == null || rAux.isEmpty() || rAux.getMaximum(0) - rAux.getMinimum(0) == 0
324 33739 fdiaz
            && rAux.getMaximum(1) - rAux.getMinimum(1) == 0) {
325
            try {
326
                rAux =
327 36219 fdiaz
                    geomManager.createEnvelope(0, 0, 90, 90, SUBTYPES.GEOM2D);
328 33739 fdiaz
            } catch (CreateEnvelopeException e) {
329
                logger.error("Error creating the envelope", e);
330
                e.printStackTrace();
331
            }
332
        }
333 34515 cordinyana
        // Si existe reproyecci?n, reproyectar el extent
334 33739 fdiaz
        ICoordTrans ct = getCoordTrans();
335 38210 cordinyana
        if (ct != null) {
336
                rAux = rAux.convert(ct);
337 33739 fdiaz
        }
338
        return rAux;
339
    }
340 26778 jmvivo
341 33739 fdiaz
    /**
342
     * Draws using IFeatureIterator. This method will replace the old draw(...)
343
     * one.
344
     *
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,
354
        Graphics2D g,
355
        ViewPort viewPort,
356
        Cancellable cancel,
357
        double scale) throws ReadException {
358 25207 jmvivo
359 33739 fdiaz
        if (legend == null) {
360
            return;
361
        }
362 21200 vcaballero
363 33739 fdiaz
        if (!this.isWithinScale(scale)) {
364
            return;
365
        }
366
        if (cancel.isCanceled()) {
367
            return;
368
        }
369 29801 vcaballero
370 33739 fdiaz
        if (spatialCache.isEnabled()) {
371
            spatialCache.clearAll();
372
            legend.addDrawingObserver(this);
373
        }
374 21200 vcaballero
375 37298 jpiera
        FeatureQuery featureQuery = null;
376 33739 fdiaz
        try {
377 37298 jpiera
            FeatureAttributeDescriptor featureAttributeDescriptor =
378
                getFeatureStore().getDefaultFeatureType().getDefaultTimeAttribute();
379
380
            if ((viewPort.getTime() != null) && (featureAttributeDescriptor != null)){
381
                featureQuery = getFeatureStore().createFeatureQuery();
382
                IntersectsTimeEvaluator intersectsTimeEvaluator =
383
                    new IntersectsTimeEvaluator(viewPort.getTime(), featureAttributeDescriptor.getName());
384
                featureQuery.addFilter(intersectsTimeEvaluator);
385
            }
386
        } catch (DataException e1) {
387
            logger.error("Impossible to get the temporal filter", e1);
388
        }
389
390
        try {
391 33739 fdiaz
            legend.draw(image,
392
                g,
393
                viewPort,
394
                cancel,
395
                scale,
396
                null,
397
                getCoordTrans(),
398 35198 jpiera
                getFeatureStore(),
399 37835 jpiera
                featureQuery);
400 21200 vcaballero
401 33739 fdiaz
        } catch (LegendException e) {
402
            this.setVisible(false);
403
            this.setActive(false);
404
            throw new ReadException(getName(), e);
405
        } finally {
406
            if (spatialCache.isEnabled()) {
407
                legend.deleteDrawingObserver(this);
408
            }
409
        }
410
    }
411 21200 vcaballero
412 33739 fdiaz
    public void print(Graphics2D g,
413
        ViewPort viewPort,
414
        Cancellable cancel,
415
        double scale,
416
        PrintAttributes properties) throws ReadException {
417
        if (!this.isWithinScale(scale)) {
418
            return;
419
        }
420
        if (cancel.isCanceled()) {
421
            return;
422
        }
423 21200 vcaballero
424 33739 fdiaz
        try {
425
            legend.print(g,
426
                viewPort,
427
                cancel,
428
                scale,
429
                null,
430
                getCoordTrans(),
431
                getFeatureStore(),
432 35198 jpiera
                null,
433 33739 fdiaz
                properties);
434 21200 vcaballero
435 33739 fdiaz
        } catch (LegendException e) {
436
            this.setVisible(false);
437
            this.setActive(false);
438
            throw new ReadException(getName(), e);
439
        }
440
    }
441 21200 vcaballero
442 33739 fdiaz
    /**
443
     * <p>
444
     * Creates an spatial index associated to this layer. The spatial index will
445
     * used the native projection of the layer, so if the layer is reprojected,
446
     * it will be ignored.
447
     * </p>
448
     *
449
     * @param cancelMonitor
450
     *            instance of CancellableMonitorable that allows
451
     *            to monitor progress of spatial index creation, and cancel the
452
     *            process
453
     */
454
    // public void createSpatialIndex(CancellableMonitorable cancelMonitor){
455 34515 cordinyana
    // // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
456 33739 fdiaz
    // // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
457
    // // para que acepten recorrer sin geometria, solo con rectangulos.
458
    //
459
    // //If this vectorial layer is based in a spatial database, the spatial
460
    // //index is already implicit. We only will index file drivers
461
    // ReadableVectorial va = getSource();
462
    // //We must think in non spatial databases, like HSQLDB
463
    // if(!(va instanceof VectorialFileAdapter)){
464
    // return;
465
    // }
466
    // if (!(va.getDriver() instanceof BoundedShapes)) {
467
    // return;
468
    // }
469
    // File file = ((VectorialFileAdapter) va).getFile();
470
    // String fileName = file.getAbsolutePath();
471
    // ISpatialIndex localCopy = null;
472
    // try {
473
    // va.start();
474
    // localCopy = new QuadtreeGt2(fileName, "NM", va.getFullExtent(),
475
    // va.getShapeCount(), true);
476
    //
477
    // } catch (SpatialIndexException e1) {
478
    // // Probably we dont have writing permissions
479
    // String directoryName = System.getProperty("java.io.tmpdir");
480
    // File newFile = new File(directoryName +
481
    // File.separator +
482
    // file.getName());
483
    // String newFileName = newFile.getName();
484
    // try {
485
    // localCopy = new QuadtreeGt2(newFileName, "NM", va.getFullExtent(),
486
    // va.getShapeCount(), true);
487
    // } catch (SpatialIndexException e) {
488
    // // if we cant build a file based spatial index, we'll build
489
    // // a pure memory spatial index
490
    // localCopy = new QuadtreeJts();
491
    // } catch (ReadException e) {
492
    // localCopy = new QuadtreeJts();
493
    // }
494
    //
495
    // } catch(Exception e){
496
    // e.printStackTrace();
497
    // }//try
498
    // BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
499
    // try {
500
    // for (int i=0; i < va.getShapeCount(); i++)
501
    // {
502
    // if(cancelMonitor != null){
503
    // if(cancelMonitor.isCanceled())
504
    // return;
505
    // cancelMonitor.reportStep();
506
    // }
507
    // Rectangle2D r = shapeBounds.getShapeBounds(i);
508
    // if(r != null)
509
    // localCopy.insert(r, i);
510
    // } // for
511
    // va.stop();
512
    // if(localCopy instanceof IPersistentSpatialIndex)
513
    // ((IPersistentSpatialIndex) localCopy).flush();
514
    // spatialIndex = localCopy;
515
    // //vectorial adapter needs a reference to the spatial index, to solve
516
    // //request for feature iteration based in spatial queries
517
    // source.setSpatialIndex(spatialIndex);
518
    // } catch (ReadException e) {
519
    // // TODO Auto-generated catch block
520
    // e.printStackTrace();
521
    // }
522
    // }
523 21200 vcaballero
524 33739 fdiaz
    // public void createSpatialIndex() {
525
    // createSpatialIndex(null);
526
    // }
527 23183 vcaballero
528 33739 fdiaz
    public void setLegend(IVectorLegend legend) throws LegendLayerException {
529
        if (this.legend == legend) {
530
            return;
531
        }
532
        if (this.legend != null && this.legend.equals(legend)) {
533
            return;
534
        }
535
        IVectorLegend oldLegend = this.legend;
536
        this.legend = legend;
537
        if (oldLegend != null) {
538
            oldLegend.removeLegendListener(this);
539
            oldLegend.deleteDrawingObserver(this);
540
        }
541
        if (legend != null) {
542
            this.legend.addDrawingObserver(this);
543
            this.legend.addLegendListener(this);
544
        }
545
        LegendChangedEvent e =
546
            LegendChangedEvent.createLegendChangedEvent(oldLegend, this.legend);
547
        e.setLayer(this);
548 38210 cordinyana
        updateDrawVersion();
549 33739 fdiaz
        callLegendChanged(e);
550
    }
551 30173 jldominguez
552 33739 fdiaz
    /**
553
     * Devuelve la Leyenda de la capa.
554
     *
555
     * @return Leyenda.
556
     */
557
    public ILegend getLegend() {
558
        return legend;
559
    }
560 30173 jldominguez
561 33739 fdiaz
    public int getShapeType() throws ReadException {
562 35763 fdiaz
            if (typeShape == -1) {
563
                    FeatureType featureType = null;
564
                    try {
565
                            if( getDataStore()!=null ){
566
                                    featureType =
567
                                            (((FeatureStore) getDataStore()).getDefaultFeatureType());
568
                            }
569
                    } catch (DataException e) {
570
                            throw new ReadException(getName(), e);
571
                    }
572
                    if( featureType!=null ){
573
                            int indexGeom = featureType.getDefaultGeometryAttributeIndex();
574
                            typeShape =
575
                                    featureType.getAttributeDescriptor(indexGeom).getGeometryType();
576
                    }
577
            }
578
            return typeShape;
579 33739 fdiaz
    }
580 30173 jldominguez
581 37328 cordinyana
    /**
582
     * Returns the layer's geometry type
583
     *
584
     * @return the geometry type
585
     *
586
     * @throws ReadException
587
     *             if there is an error getting the geometry type
588
     */
589
    public GeometryType getGeometryType() throws ReadException {
590
        FeatureType featureType = null;
591
        try {
592
            if (getDataStore() != null) {
593
                featureType =
594
                    (((FeatureStore) getDataStore()).getDefaultFeatureType());
595
            }
596
        } catch (DataException e) {
597
            throw new ReadException(getName(), e);
598
        }
599
        return featureType == null ? null : featureType
600
            .getDefaultGeometryAttribute().getGeomType();
601
    }
602
603 33739 fdiaz
    public void saveToState(PersistentState state) throws PersistenceException {
604 30173 jldominguez
605 33739 fdiaz
        if (!this.isAvailable()) {
606
            return;
607
        }
608 30173 jldominguez
609 33739 fdiaz
        super.saveToState(state);
610 30173 jldominguez
611 33739 fdiaz
        if (getLegend() != null) {
612
            state.set("legend", getLegend());
613
        }
614 28545 vcaballero
615 33739 fdiaz
        FeatureStore fst = null;
616
        fst = getFeatureStore();
617 23183 vcaballero
618 33739 fdiaz
        if (fst != null) {
619
            state.set("featureStore", fst);
620
        }
621 21200 vcaballero
622 33739 fdiaz
        state.set("isLabeled", isLabeled);
623 21200 vcaballero
624 33739 fdiaz
        if (strategy != null) {
625
            state.set("labelingStrategy", strategy);
626
        }
627 21200 vcaballero
628 33739 fdiaz
        if (getLinkProperties() != null) {
629
            state.set("linkProperties", getLinkProperties());
630
        }
631 21200 vcaballero
632 33739 fdiaz
        // state.set("bHasJoin", bHasJoin);
633
        state.set("typeShape", typeShape);
634
    }
635 21200 vcaballero
636 33739 fdiaz
    // public XMLEntity getXMLEntity() throws XMLException {
637
    //
638
    // if (!this.isAvailable() && this.orgXMLEntity != null) {
639
    // return this.orgXMLEntity;
640
    // }
641
    // XMLEntity xml = super.getXMLEntity();
642
    // if (getLegend()!=null){
643
    // XMLEntity xmlLegend=getLegend().getXMLEntity();
644
    // xmlLegend.putProperty("tagName","legend");
645
    // xml.addChild(xmlLegend);
646
    // }
647
    // try {
648
    // PersistenceManager manager = ToolsLocator.getPersistenceManager();
649
    // PersistentState stateFeatureStore=manager.getState(getFeatureStore());
650
    // stateFeatureStore.set("tagName","featureStore");
651
    // xml.addChild(((XMLEntityState)stateFeatureStore).getXMLEntity());
652
    // } catch (ReadException e) {
653
    // throw new XMLLayerException(getName(),e);
654
    // } catch (PersistenceException e) {
655
    // throw new XMLLayerException(getName(),e);
656
    // }
657
    // // properties from ILabelable
658
    // xml.putProperty("isLabeled", isLabeled);
659
    // if (strategy != null) {
660
    // XMLEntity strategyXML = strategy.getXMLEntity();
661
    // strategyXML.putProperty("tagName", "labelingStrategy");
662
    // xml.addChild(strategy.getXMLEntity());
663
    // }
664
    // xml.addChild(getLinkProperties().getXMLEntity());
665
    // return xml;
666
    // }
667 21200 vcaballero
668 33739 fdiaz
    public void loadFromState(PersistentState state) throws PersistenceException {
669 21200 vcaballero
670 33739 fdiaz
        super.loadFromState(state);
671 35763 fdiaz
        DataStore store = null;
672 33739 fdiaz
        try {
673 35763 fdiaz
                store = (DataStore) state.get("featureStore");
674
        } catch (PersistenceRuntimeException e) {
675
                        this.setAvailable(false);
676
                        return;
677
                }
678
        try {
679 33739 fdiaz
            this.setDataStore(store);
680
        } catch (LoadLayerException e) {
681
            throw new PersistenceException("While loading FLyrVect from state.",
682
                e);
683
        }
684 21200 vcaballero
685 33739 fdiaz
        IVectorLegend lgnd = (IVectorLegend) state.get("legend");
686
        try {
687
            this.setLegend(lgnd);
688
        } catch (LegendLayerException e) {
689
            throw new PersistenceException("While loading FLyrVect from state.",
690
                e);
691
        }
692 21200 vcaballero
693 33739 fdiaz
        Boolean isLbl = new Boolean(false);
694
        ILabelingStrategy lblst = null;
695 21200 vcaballero
696 33739 fdiaz
        try {
697
            isLbl = (Boolean) state.get("isLabeled");
698
            if (isLbl.booleanValue()) {
699
                lblst = (ILabelingStrategy) state.get("labelingStrategy");
700
            }
701
        } catch (Exception ex) {
702
            throw new PersistenceException("While loading FLyrVect from state.",
703
                ex);
704
        }
705 21200 vcaballero
706 33739 fdiaz
        /*
707
         * String _labelFieldName = null;
708
         * String _labelfield = null;
709
         */
710 21200 vcaballero
711 33739 fdiaz
        if (isLbl.booleanValue()) {
712
            this.setIsLabeled(true);
713
            this.setLabelingStrategy(lblst);
714
        } else {
715
            this.setIsLabeled(false);
716
            this.setLabelingStrategy(null);
717
        }
718 21200 vcaballero
719 33739 fdiaz
        // try {
720
        // linkProperties = (FLyrVectLinkProperties)
721
        // state.get("linkProperties");
722
        // } catch (PersistenceException pex) {
723
        // // not mandatory
724
        // linkProperties = null;
725
        // }
726 21200 vcaballero
727 33739 fdiaz
        // bHasJoin = state.getBoolean("bHasJoin");
728
        typeShape = state.getInt("typeShape");
729 21200 vcaballero
730 33739 fdiaz
        // try { _labelFieldName = state.getString("labelFieldName"); } catch
731
        // (PersistenceException ex) {
732
        // _labelFieldName = null;
733
        // }
734
        // try { _labelfield = state.getString("labelfield"); } catch
735
        // (PersistenceException ex) {
736
        // _labelfield = null;
737
        // }
738 21200 vcaballero
739 33739 fdiaz
        // ILabelingStrategy not implemented
740
        // if (_labelFieldName != null) {
741
        //
742
        // AttrInTableLabelingStrategy labeling = new
743
        // AttrInTableLabelingStrategy();
744
        // try {
745
        // labeling.setLayer(this);
746
        // } catch (ReadException e) {
747
        // logger.error("While setting layer to AttrInTableLabelingStrategy: " +
748
        // e.getMessage());
749
        // }
750
        // labeling.setUsesFixedSize(true);
751
        // labeling.setFixedSize(10);
752
        // labeling.setTextField(_labelFieldName);
753
        // labeling.setHeightField(state.getString("labelHeightFieldName"));
754
        // labeling.setRotationField(state.getString("labelRotationFieldName"));
755
        // setLabelingStrategy(labeling);
756
        // setIsLabeled(true);
757
        //
758
        // } else {
759
        // if (_labelfield != null) {
760
        //
761
        // AttrInTableLabelingStrategy labeling = new
762
        // AttrInTableLabelingStrategy();
763
        // try {
764
        // labeling.setLayer(this);
765
        // } catch (ReadException e) {
766
        // logger.error("While setting layer to AttrInTableLabelingStrategy: " +
767
        // e.getMessage());
768
        // }
769
        // labeling.setUsesFixedSize(true);
770
        // labeling.setFixedSize(10);
771
        // labeling.setTextField(_labelfield);
772
        // labeling.setHeightField(state.getString("labelFieldHeight"));
773
        // labeling.setRotationField(state.getString("labelFieldRotation"));
774
        // setLabelingStrategy(labeling);
775
        // setIsLabeled(true);
776
        // }
777
        // }
778 25754 vcaballero
779 33739 fdiaz
    }
780 25754 vcaballero
781 33739 fdiaz
    // public void setXMLEntity(XMLEntity xml) throws XMLException {
782
    // try {
783
    // super.setXMLEntity(xml);
784
    // XMLEntity legendXML = xml.firstChild("tagName","legend");
785
    // IVectorLegend leg = LegendFactory.createFromXML(legendXML);
786
    //
787
    // // PersistentState persistentState=new XMLEntityState(new
788
    // XMLEntityManager());
789
    // XMLEntity xmlStore=xml.firstChild("tagName","featureStore");
790
    // XMLEntityManager xmlManger = new XMLEntityManager();
791
    // PersistentState state = xmlManger.createState(xmlStore);
792
    // DataStore store = (DataStore)
793
    // ToolsLocator.getPersistenceManager().create(state);
794
    // // persistentState.createState(xmlStore);
795
    //
796
    // // DataManager dm=DALLocator.getDataManager();
797
    //
798
    // this.setDataStore(store);
799
    // /* end patch */
800
    // try {
801
    // setLegend(leg);
802
    // } catch (LegendLayerException e) {
803
    // throw new XMLLegendException(e);
804
    // }
805
    // // set properties for ILabelable
806
    //
807
    // if (xml.contains("isLabeled")
808
    // && xml.getBooleanProperty(("isLabeled"))) {
809
    // XMLEntity labelingXML = xml.firstChild("tagName", "labelingStrategy");
810
    // if (labelingXML != null){
811
    //
812
    // isLabeled = true;
813
    // try {
814
    // this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this);
815
    // } catch (NotExistInXMLEntity neXMLEX) {
816
    // // no strategy was set, just continue;
817
    // logger.warn("Reached what should be unreachable code");
818
    // }
819
    // } else {
820
    // isLabeled = false;
821
    // }
822
    // } else if (legendXML.contains("labelFieldName")||
823
    // legendXML.contains("labelfield")) {
824
    // /* (jaume) begin patch;
825
    // * for backward compatibility purposes. Since gvSIG v1.1 labeling is
826
    // * no longer managed by the Legend but by the ILabelingStrategy. The
827
    // * following allows restoring older projects' labelings.
828
    // */
829
    // String labelTextField = null;
830
    // if (legendXML.contains("labelFieldName")){
831
    // labelTextField = legendXML.getStringProperty("labelFieldName");
832
    // if (labelTextField != null) {
833
    // AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
834
    // labeling.setLayer(this);
835
    // labeling.setUsesFixedSize(true);
836
    // labeling.setFixedSize(10);
837
    // labeling.setTextField(labelTextField);
838
    // labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
839
    // labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
840
    // this.setLabelingStrategy(labeling);
841
    // this.setIsLabeled(true);
842
    // }
843
    // }else{
844
    // labelTextField = legendXML.getStringProperty("labelfield");
845
    // if (labelTextField != null) {
846
    // AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
847
    // labeling.setLayer(this);
848
    // labeling.setUsesFixedSize(true);
849
    // labeling.setFixedSize(10);
850
    // labeling.setTextField(labelTextField);
851
    // labeling.setHeightField(legendXML.getStringProperty("labelFieldHeight"));
852
    // labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
853
    // this.setLabelingStrategy(labeling);
854
    // this.setIsLabeled(true);
855
    // }
856
    // }
857
    // }else{
858
    // isLabeled = false;
859
    // }
860
    // XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
861
    // if (xmlLinkProperties != null){
862
    // getLinkProperties().setXMLEntity(xmlLinkProperties);
863
    // }
864
    // } catch (Exception e) {
865
    // e.printStackTrace();
866
    // this.setAvailable(false);
867
    // this.orgXMLEntity = xml;
868
    //
869
    // }
870
    // //
871
    //
872
    // }
873 21200 vcaballero
874 33739 fdiaz
    /**
875 34515 cordinyana
     * Sobreimplementaci?n del m?todo toString para que las bases de datos
876 33739 fdiaz
     * identifiquen la capa.
877
     *
878
     * @return DOCUMENT ME!
879
     */
880
    public String toString() {
881
        /*
882
         * Se usa internamente para que la parte de datos identifique de forma
883 34515 cordinyana
         * un?voca las tablas
884 33739 fdiaz
         */
885
        String ret = super.toString();
886 25754 vcaballero
887 33739 fdiaz
        return "layer" + ret.substring(ret.indexOf('@') + 1);
888
    }
889 21200 vcaballero
890 33739 fdiaz
    // public boolean isJoined() {
891
    // return bHasJoin;
892
    // }
893 21200 vcaballero
894 33739 fdiaz
    /**
895
     * Returns if a layer is spatially indexed
896
     *
897
     * @return if this layer has the ability to proces spatial queries without
898
     *         secuential scans.
899 34978 fdiaz
     * @throws StopEditionLayerException
900 33739 fdiaz
     */
901
    // public boolean isSpatiallyIndexed() {
902
    // ReadableVectorial source = getSource();
903
    // if (source instanceof ISpatialDB)
904
    // return true;
905
    //
906
    // //FIXME azabala
907
    // /*
908
    // * Esto es muy dudoso, y puede cambiar.
909
    // * Estoy diciendo que las que no son fichero o no son
910
    // * BoundedShapes estan indexadas. Esto es mentira, pero
911 34515 cordinyana
    // * as? quien pregunte no querr? generar el indice.
912 33739 fdiaz
    // * Esta por ver si interesa generar el indice para capas
913
    // * HSQLDB, WFS, etc.
914
    // */
915
    // if(!(source instanceof VectorialFileAdapter)){
916
    // return true;
917
    // }
918
    // if (!(source.getDriver() instanceof BoundedShapes)) {
919
    // return true;
920
    // }
921
    //
922
    // if (getISpatialIndex() != null)
923
    // return true;
924
    // return false;
925
    // }
926
    //
927
    // public void setIsJoined(boolean hasJoin) {
928
    // bHasJoin = hasJoin;
929
    // }
930 21200 vcaballero
931 33739 fdiaz
    // /**
932
    // * @return Returns the spatialIndex.
933
    // */
934
    // public ISpatialIndex getISpatialIndex() {
935
    // return spatialIndex;
936
    // }
937
    // /**
938
    // * Sets the spatial index. This could be useful if, for some
939
    // * reasons, you want to work with a distinct spatial index
940
    // * (for example, a spatial index which could makes nearest
941
    // * neighbour querys)
942
    // * @param spatialIndex
943
    // */
944
    // public void setISpatialIndex(ISpatialIndex spatialIndex){
945
    // this.spatialIndex = spatialIndex;
946
    // }
947 21200 vcaballero
948 33739 fdiaz
    public void setEditing(boolean b) throws StartEditionLayerException {
949
        super.setEditing(b);
950 34978 fdiaz
        FeatureStore fs = getFeatureStore();
951 33739 fdiaz
        if (b) {
952
            try {
953 34978 fdiaz
                fs.edit();
954 33739 fdiaz
            } catch (ReadException e) {
955
                throw new StartEditionLayerException(getName(), e);
956
            } catch (DataException e) {
957
                throw new StartEditionLayerException(getName(), e);
958
            }
959
        }
960
        setSpatialCacheEnabled(b);
961
        callEditionChanged(LayerEvent.createEditionChangedEvent(this, "edition"));
962
    }
963 21200 vcaballero
964 33739 fdiaz
    /**
965
     * @deprecated Use {@link #getSpatialCache()}
966
     */
967
    public void clearSpatialCache() {
968
        spatialCache.clearAll();
969
    }
970 21200 vcaballero
971 33739 fdiaz
    /**
972
     * @deprecated Use {@link #getSpatialCache()}
973
     */
974
    public boolean isSpatialCacheEnabled() {
975
        return spatialCache.isEnabled();
976
    }
977 21200 vcaballero
978 33739 fdiaz
    /**
979
     * @deprecated Use {@link #getSpatialCache()}
980
     */
981
    public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
982
        spatialCache.setEnabled(spatialCacheEnabled);
983
    }
984 21200 vcaballero
985 33739 fdiaz
    public SpatialCache getSpatialCache() {
986
        return spatialCache;
987
    }
988 21200 vcaballero
989 33739 fdiaz
    /**
990
     * Siempre es un numero mayor de 1000
991
     *
992
     * @param maxFeatures
993
     */
994
    public void setMaxFeaturesInEditionCache(int maxFeatures) {
995
        if (maxFeatures > spatialCache.getMaxFeatures()) {
996
            spatialCache.setMaxFeatures(maxFeatures);
997
        }
998 21200 vcaballero
999 33739 fdiaz
    }
1000 21200 vcaballero
1001 33739 fdiaz
    /**
1002
     * This method returns a boolean that is used by the FPopMenu
1003
     * to make visible the properties menu or not. It is visible by
1004
     * default, and if a later don't have to show this menu only
1005
     * has to override this method.
1006
     *
1007
     * @return
1008
     *         If the properties menu is visible (or not)
1009
     */
1010
    public boolean isPropertiesMenuVisible() {
1011
        return true;
1012
    }
1013 21200 vcaballero
1014 33739 fdiaz
    public void reload() throws ReloadLayerException {
1015
        super.reload();
1016
        try {
1017
            getFeatureStore().refresh();
1018
        } catch (Exception e) {
1019
            throw new ReloadLayerException(getName(), e);
1020
        }
1021
    }
1022 21200 vcaballero
1023 33739 fdiaz
    protected void setLoadSelection(Object xml) {
1024
        // this.loadSelection = xml;
1025
    }
1026 21200 vcaballero
1027 33739 fdiaz
    protected void setLoadLegend(IVectorLegend legend) {
1028
        this.loadLegend = legend;
1029
    }
1030 21200 vcaballero
1031 33739 fdiaz
    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 21200 vcaballero
1040 33739 fdiaz
    }
1041 21200 vcaballero
1042 33739 fdiaz
    protected void putLoadLegend() throws LegendLayerException {
1043
        if (this.loadLegend == null) {
1044
            return;
1045
        }
1046
        this.setLegend(this.loadLegend);
1047
        this.loadLegend = null;
1048
    }
1049 30173 jldominguez
1050 33739 fdiaz
    protected void cleanLoadOptions() {
1051
        this.loadLegend = null;
1052
    }
1053 33619 jjdelcerro
1054 33739 fdiaz
    public boolean isWritable() {
1055
        return getFeatureStore().allowWrite();
1056
    }
1057 21200 vcaballero
1058 33739 fdiaz
    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 21200 vcaballero
1069 33739 fdiaz
        clonedLayer.setLegend((IVectorLegend) getLegend().cloneLegend());
1070 21200 vcaballero
1071 33739 fdiaz
        clonedLayer.setIsLabeled(isLabeled());
1072
        ILabelingStrategy labelingStrategy = getLabelingStrategy();
1073
        if (labelingStrategy != null) {
1074
            clonedLayer.setLabelingStrategy(labelingStrategy);
1075
        }
1076 21200 vcaballero
1077 33739 fdiaz
        return clonedLayer;
1078
    }
1079 21200 vcaballero
1080 33739 fdiaz
    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 21200 vcaballero
1090 33739 fdiaz
    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 21200 vcaballero
1101 33739 fdiaz
            Envelope geomBounds = geom.getEnvelope();
1102 21200 vcaballero
1103 33739 fdiaz
            // ICoordTrans ct = getCoordTrans();
1104 21200 vcaballero
1105 33739 fdiaz
            // 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 21200 vcaballero
1111 33739 fdiaz
            double dist1Pixel = viewPort.getDist1pixel();
1112 21200 vcaballero
1113 33739 fdiaz
            onePoint =
1114
                (geomBounds.getLength(0) <= dist1Pixel && geomBounds.getLength(1) <= dist1Pixel);
1115 21200 vcaballero
1116 33739 fdiaz
            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 22240 jmvivo
1132 33739 fdiaz
            }
1133 24711 vcaballero
1134 33739 fdiaz
        }
1135
        return onePoint;
1136
    }
1137 24711 vcaballero
1138 33739 fdiaz
    /*
1139
     * jaume. Stuff from ILabeled.
1140
     */
1141 27267 vcaballero
1142 33739 fdiaz
    public boolean isLabeled() {
1143
        return isLabeled;
1144
    }
1145 24711 vcaballero
1146 33739 fdiaz
    public void setIsLabeled(boolean isLabeled) {
1147
        this.isLabeled = isLabeled;
1148
    }
1149 33429 cordinyana
1150 33739 fdiaz
    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 38210 cordinyana
        updateDrawVersion();
1161 33739 fdiaz
    }
1162
1163
    public void drawLabels(BufferedImage image,
1164
        Graphics2D g,
1165
        ViewPort viewPort,
1166
        Cancellable cancel,
1167
        double scale,
1168
        double dpi) throws ReadException {
1169
        if (strategy != null && isWithinScale(scale)) {
1170
            strategy.draw(image, g, viewPort, cancel, dpi);
1171
        }
1172
    }
1173
1174
    public void printLabels(Graphics2D g,
1175
        ViewPort viewPort,
1176
        Cancellable cancel,
1177
        double scale,
1178
        PrintAttributes properties) throws ReadException {
1179
        if (strategy != null) {
1180
            strategy.print(g, viewPort, cancel, properties);
1181
        }
1182
    }
1183
1184 34515 cordinyana
    // M?todos para el uso de HyperLinks en capas FLyerVect
1185 33739 fdiaz
1186
    /**
1187
     * Return true, because a Vectorial Layer supports HyperLink
1188
     */
1189
    public boolean allowLinks() {
1190
        return true;
1191
    }
1192
1193
    /**
1194
     * Returns an instance of AbstractLinkProperties that contains the
1195
     * information
1196
     * of the HyperLink
1197
     *
1198
     * @return Abstra
1199
     */
1200
    // public AbstractLinkProperties getLinkProperties()
1201
    // {
1202
    // return linkProperties;
1203
    // }
1204
1205
    /**
1206
     * Provides an array with URIs. Returns one URI by geometry that includes
1207
     * the point
1208
     * in its own geometry limits with a allowed tolerance.
1209
     *
1210
     * @param layer
1211
     *            , the layer
1212
     * @param point
1213
     *            , the point to check that is contained or not in the
1214
     *            geometries in the layer
1215
     * @param tolerance
1216
     *            , the tolerance allowed. Allowed margin of error to detect if
1217
     *            the point
1218
     *            is contained in some geometries of the layer
1219
     * @return
1220
     * @throws ReadException
1221
     * @throws BehaviorException
1222
     */
1223
    // public URI[] getLink(Point2D point, double tolerance) throws
1224
    // ReadException
1225
    // {
1226
    // //return linkProperties.getLink(this)
1227
    // return linkProperties.getLink(this,point,tolerance);
1228
    // }
1229
1230
    public void load() throws LoadLayerException {
1231
        super.load();
1232
    }
1233
1234
    public FeatureStore getFeatureStore() {
1235
        return (FeatureStore) getDataStore();
1236
    }
1237
1238 35485 jjdelcerro
    /**
1239
     * @deprecated use instead {@link #queryByPoint(org.gvsig.fmap.geom.primitive.Point, double, FeatureType)}
1240
     */
1241 33739 fdiaz
    public FeatureSet queryByPoint(Point2D mapPoint,
1242
        double tol,
1243
        FeatureType featureType) throws DataException {
1244 35485 jjdelcerro
        logger.warn("Deprecated use of queryByPoint.");
1245 33739 fdiaz
        GeometryManager manager = GeometryLocator.getGeometryManager();
1246
        org.gvsig.fmap.geom.primitive.Point center;
1247
        try {
1248
            center =
1249
                (org.gvsig.fmap.geom.primitive.Point) manager.create(TYPES.POINT,
1250
                    SUBTYPES.GEOM2D);
1251
            center.setX(mapPoint.getX());
1252
            center.setY(mapPoint.getY());
1253
            Circle circle =
1254
                (Circle) manager.create(TYPES.CIRCLE, SUBTYPES.GEOM2D);
1255
            circle.setPoints(center, tol);
1256
            return queryByGeometry(circle, featureType);
1257
        } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
1258
            throw new CreateGeometryException(TYPES.CIRCLE, SUBTYPES.GEOM2D, e);
1259
        }
1260
    }
1261
1262 35485 jjdelcerro
    public FeatureSet queryByPoint(org.gvsig.fmap.geom.primitive.Point point,
1263
        double tol,
1264
        FeatureType featureType) throws DataException {
1265
        GeometryManager manager = GeometryLocator.getGeometryManager();
1266
        try {
1267
            Circle circle =
1268
                (Circle) manager.create(TYPES.CIRCLE, SUBTYPES.GEOM2D);
1269
            circle.setPoints(point, tol);
1270
            return queryByGeometry(circle, featureType);
1271
        } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
1272
            throw new CreateGeometryException(TYPES.CIRCLE, SUBTYPES.GEOM2D, e);
1273
        }
1274
    }
1275
1276 33739 fdiaz
    public FeatureSet queryByGeometry(Geometry geom, FeatureType featureType) throws DataException {
1277
        FeatureQuery featureQuery = featureStore.createFeatureQuery();
1278
        String geomName =
1279
            featureStore.getDefaultFeatureType()
1280
                .getDefaultGeometryAttributeName();
1281
        featureQuery.setFeatureType(featureType);
1282
        IntersectsGeometryEvaluator iee =
1283
            new IntersectsGeometryEvaluator(geom,
1284
                getMapContext().getViewPort().getProjection(),
1285
                featureStore.getDefaultFeatureType(),
1286
                geomName);
1287
        featureQuery.setFilter(iee);
1288
        return getFeatureStore().getFeatureSet(featureQuery);
1289
1290
    }
1291
1292 35753 jpiera
    /**
1293
     * It return the {@link FeatureSet} that intersects with the envelope.
1294
     * @param envelope
1295
     *          envelope that defines the area for the query.
1296
     * @param featureType
1297
     *          only the features with this feature type are used in
1298
     *          the query.
1299
     * @return
1300
     *          the set of features that intersect with the envelope.
1301
     * @throws DataException
1302
     */
1303 33739 fdiaz
    public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType) throws DataException {
1304
        return queryByEnvelope(envelope, featureType, null);
1305
    }
1306
1307 35753 jpiera
    /**
1308
     * It return the {@link FeatureSet} that intersects with the envelope.
1309
     * @param envelope
1310
     *          envelope that defines the area for the query.
1311
     * @param featureType
1312
     *          only the features with this feature type are used in
1313
     *          the query.
1314
     * @param names
1315
     *          the feature attributes that have to be checked.
1316
     * @return
1317
     *          the set of features that intersect with the envelope.
1318
     * @throws DataException
1319
     */
1320 33739 fdiaz
    public FeatureSet queryByEnvelope(Envelope envelope,
1321
        FeatureType featureType,
1322
        String[] names) throws DataException {
1323
        FeatureQuery featureQuery = featureStore.createFeatureQuery();
1324
        if (names == null) {
1325
            featureQuery.setFeatureType(featureType);
1326
        } else {
1327
            featureQuery.setAttributeNames(names);
1328
            featureQuery.setFeatureTypeId(featureType.getId());
1329
        }
1330
        String geomName =
1331 37298 jpiera
            featureStore.getDefaultFeatureType()
1332 33739 fdiaz
                .getDefaultGeometryAttributeName();
1333 35753 jpiera
        IntersectsGeometryEvaluator iee =
1334
            new IntersectsGeometryEvaluator(envelope.getGeometry(),
1335 33739 fdiaz
                getMapContext().getViewPort().getProjection(),
1336
                featureStore.getDefaultFeatureType(),
1337
                geomName);
1338
        featureQuery.setFilter(iee);
1339
        return getFeatureStore().getFeatureSet(featureQuery);
1340
1341
    }
1342
1343
    public DynObjectSet getInfo(Point p, double tolerance, Cancellable cancel) throws LoadLayerException,
1344
        DataException {
1345
1346 33657 cordinyana
        return getInfo(p, tolerance, cancel, true);
1347
    }
1348
1349 33739 fdiaz
    public DynObjectSet getInfo(Point p,
1350
        double tolerance,
1351
        Cancellable cancel,
1352 33657 cordinyana
        boolean fast) throws LoadLayerException, DataException {
1353
        Point2D infop = new Point2D.Double(p.x, p.y);
1354
        Point2D pReal = this.getMapContext().getViewPort().toMapPoint(infop);
1355 33739 fdiaz
        return queryByPoint(pReal,
1356
            tolerance,
1357
            getFeatureStore().getDefaultFeatureType()).getDynObjectSet(fast);
1358 33657 cordinyana
    }
1359 25038 jmvivo
1360 35485 jjdelcerro
    public DynObjectSet getInfo(org.gvsig.fmap.geom.primitive.Point p,
1361
        double tolerance) throws LoadLayerException, DataException {
1362 35627 fdiaz
        return queryByPoint(p,tolerance, getFeatureStore().getDefaultFeatureType()).getDynObjectSet(false);
1363 35485 jjdelcerro
    }
1364
1365 33739 fdiaz
    public void legendCleared(LegendClearEvent event) {
1366 38210 cordinyana
        this.updateDrawVersion();
1367 33739 fdiaz
        LegendChangedEvent e =
1368
            LegendChangedEvent.createLegendChangedEvent(legend, legend);
1369
        this.callLegendChanged(e);
1370
    }
1371 25038 jmvivo
1372 33739 fdiaz
    public boolean symbolChanged(SymbolLegendEvent e) {
1373 38210 cordinyana
        this.updateDrawVersion();
1374 33739 fdiaz
        LegendChangedEvent ev =
1375
            LegendChangedEvent.createLegendChangedEvent(legend, legend);
1376
        this.callLegendChanged(ev);
1377
        return true;
1378
    }
1379 25242 jmvivo
1380 33739 fdiaz
    public void update(Observable observable, Object notification) {
1381
        if (observable.equals(this.featureStore)) {
1382
            if (notification instanceof FeatureStoreNotification) {
1383
                FeatureStoreNotification event =
1384
                    (FeatureStoreNotification) notification;
1385
                if (event.getType() == FeatureStoreNotification.AFTER_CANCELEDITING
1386
                    || event.getType() == FeatureStoreNotification.AFTER_DELETE
1387
                    || event.getType() == FeatureStoreNotification.AFTER_UNDO
1388
                    || event.getType() == FeatureStoreNotification.AFTER_REDO
1389
                    || event.getType() == FeatureStoreNotification.AFTER_REFRESH
1390
                    || event.getType() == FeatureStoreNotification.AFTER_UPDATE
1391
                    || event.getType() == FeatureStoreNotification.AFTER_UPDATE_TYPE
1392
                    || event.getType() == FeatureStoreNotification.SELECTION_CHANGE
1393
                    || event.getType() == FeatureStoreNotification.AFTER_INSERT) {
1394
                    this.updateDrawVersion();
1395 25242 jmvivo
1396 35184 jpiera
                } else if (event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE){
1397
                    //If a transform has to be applied, try to reload the layer.
1398
                    try {
1399
                        reload();
1400
                    } catch (ReloadLayerException e) {
1401 33739 fdiaz
                        this.setAvailable(false);
1402 35184 jpiera
                    }
1403
                } else if (event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
1404
                    this.setAvailable(false);
1405
                } else         if (event.getType() == FeatureStoreNotification.AFTER_FINISHEDITING) {
1406
                    this.setAvailable(true);
1407
                }
1408 33739 fdiaz
            }
1409
        }
1410
        // Only if its an event from our own legend
1411
        else
1412
            // I comment this line because a legend doesn't implements the
1413
            // Observable interface.
1414
            // This code is necessary on edition.
1415
            // if (observable == getLegend()) {
1416
            if (notification instanceof FeatureDrawnNotification) {
1417
                Geometry geometry =
1418
                    ((FeatureDrawnNotification) notification).getDrawnGeometry();
1419
                spatialCache.insert(geometry.getEnvelope(), geometry);
1420
                // }
1421
            }
1422 25920 jmvivo
1423 33739 fdiaz
    }
1424 25920 jmvivo
1425 33739 fdiaz
    /*
1426
     * (non-Javadoc)
1427
     *
1428
     * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1429
     */
1430
    public Set getMetadataChildren() {
1431
        Set ret = new TreeSet();
1432
        ret.add(this.featureStore);
1433
        return ret;
1434
    }
1435 27988 jmvivo
1436 33739 fdiaz
    /*
1437
     * (non-Javadoc)
1438
     *
1439
     * @see org.gvsig.metadata.Metadata#getMetadataID()
1440
     */
1441
    public Object getMetadataID() throws MetadataException {
1442
        return "Layer(" + this.getName() + "):"
1443
            + this.featureStore.getMetadataID();
1444
    }
1445 26313 vcaballero
1446 34488 cmartin
1447 30173 jldominguez
1448 33739 fdiaz
    public GeometryType getTypeVectorLayer() throws DataException,
1449
        LocatorException,
1450
        GeometryTypeNotSupportedException,
1451
        GeometryTypeNotValidException {
1452
        // FIXME Esto deberia de pedirse a FType!!!!
1453
        FeatureStore fs = this.getFeatureStore();
1454
        FeatureType fType = fs.getDefaultFeatureType();
1455
        FeatureAttributeDescriptor attr =
1456
            fType.getAttributeDescriptor(fType.getDefaultGeometryAttributeIndex());
1457
        GeometryType geomType =
1458
            GeometryLocator.getGeometryManager()
1459
                .getGeometryType(attr.getGeometryType(),
1460
                    attr.getGeometrySubType());
1461
        return geomType;
1462
    }
1463 30173 jldominguez
1464 33739 fdiaz
    public static void registerPersistent() {
1465
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
1466
        if (manager.getDefinition(FLyrDefault.class) == null) {
1467
            FLyrDefault.registerPersistent();
1468
        }
1469
        DynStruct definition =
1470
            manager.addDefinition(FLyrVect.class,
1471
                "FLyrVect",
1472
                "FLyrVect Persistence definition",
1473
                null,
1474
                null);
1475
        definition.extend(PersistenceManager.PERSISTENCE_NAMESPACE,
1476
            "FLyrDefault");
1477
1478
        definition.addDynFieldObject("legend")
1479
            .setClassOfValue(IVectorLegend.class)
1480
            .setMandatory(true);
1481
        definition.addDynFieldObject("featureStore")
1482
            .setClassOfValue(FeatureStore.class)
1483
            .setMandatory(true);
1484
        definition.addDynFieldBoolean("isLabeled").setMandatory(true);
1485
        definition.addDynFieldInt("typeShape").setMandatory(true);
1486
        definition.addDynFieldObject("labelingStrategy")
1487
            .setClassOfValue(ILabelingStrategy.class)
1488
            .setMandatory(false);
1489
1490
    }
1491
1492
    protected void doDispose() throws BaseException {
1493
        dispose(featureStore);
1494
        spatialCache.clearAll();
1495
    }
1496
}