Statistics
| Revision:

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

History | View | Annotate | Download (59.9 KB)

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

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

    
52
import javax.print.attribute.PrintRequestAttributeSet;
53
import javax.print.attribute.standard.PrintQuality;
54

    
55
import org.cresques.cts.ICoordTrans;
56
import org.gvsig.fmap.dal.DALLocator;
57
import org.gvsig.fmap.dal.DataManager;
58
import org.gvsig.fmap.dal.DataStore;
59
import org.gvsig.fmap.dal.DataStoreParameters;
60
import org.gvsig.fmap.dal.exception.DataException;
61
import org.gvsig.fmap.dal.exception.ReadException;
62
import org.gvsig.fmap.dal.feature.DisposableIterator;
63
import org.gvsig.fmap.dal.feature.Feature;
64
import org.gvsig.fmap.dal.feature.FeatureQuery;
65
import org.gvsig.fmap.dal.feature.FeatureSelection;
66
import org.gvsig.fmap.dal.feature.FeatureSet;
67
import org.gvsig.fmap.dal.feature.FeatureStore;
68
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
69
import org.gvsig.fmap.dal.feature.FeatureType;
70
import org.gvsig.fmap.dal.feature.exception.ConcurrentDataModificationException;
71
import org.gvsig.fmap.dal.feature.exception.CreateGeometryException;
72
import org.gvsig.fmap.geom.Geometry;
73
import org.gvsig.fmap.geom.GeometryLocator;
74
import org.gvsig.fmap.geom.GeometryManager;
75
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
76
import org.gvsig.fmap.geom.Geometry.TYPES;
77
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
78
import org.gvsig.fmap.geom.operation.DrawInts;
79
import org.gvsig.fmap.geom.operation.DrawOperationContext;
80
import org.gvsig.fmap.geom.operation.GeometryOperationException;
81
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
82
import org.gvsig.fmap.geom.primitive.Circle;
83
import org.gvsig.fmap.geom.primitive.Envelope;
84
import org.gvsig.fmap.mapcontext.MapContext;
85
import org.gvsig.fmap.mapcontext.ViewPort;
86
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
87
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
88
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
89
import org.gvsig.fmap.mapcontext.exceptions.ReprojectLayerException;
90
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
91
import org.gvsig.fmap.mapcontext.exceptions.XMLLayerException;
92
import org.gvsig.fmap.mapcontext.layers.AbstractLinkProperties;
93
import org.gvsig.fmap.mapcontext.layers.FLayer;
94
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
95
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
96
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
97
import org.gvsig.fmap.mapcontext.layers.operations.ClassifiableVectorial;
98
import org.gvsig.fmap.mapcontext.layers.operations.ILabelable;
99
import org.gvsig.fmap.mapcontext.layers.operations.InfoByPoint;
100
import org.gvsig.fmap.mapcontext.layers.operations.SingleLayer;
101
import org.gvsig.fmap.mapcontext.layers.operations.VectorialXMLItem;
102
import org.gvsig.fmap.mapcontext.layers.operations.XMLItem;
103
import org.gvsig.fmap.mapcontext.rendering.legend.IClassifiedVectorLegend;
104
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
105
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
106
import org.gvsig.fmap.mapcontext.rendering.legend.LegendFactory;
107
import org.gvsig.fmap.mapcontext.rendering.legend.SingleSymbolLegend;
108
import org.gvsig.fmap.mapcontext.rendering.legend.SymbolLegendEvent;
109
import org.gvsig.fmap.mapcontext.rendering.legend.XMLLegendException;
110
import org.gvsig.fmap.mapcontext.rendering.legend.ZSort;
111
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
112
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
113
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendContentsChangedListener;
114
import org.gvsig.fmap.mapcontext.rendering.legend.styling.AttrInTableLabelingStrategy;
115
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
116
import org.gvsig.fmap.mapcontext.rendering.legend.styling.LabelingFactory;
117
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
118
import org.gvsig.fmap.mapcontext.rendering.symbols.FSymbol;
119
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
120
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
121
import org.gvsig.tools.ToolsLocator;
122
import org.gvsig.tools.dynobject.exception.DynMethodException;
123
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
124
import org.gvsig.tools.exception.BaseException;
125
import org.gvsig.tools.observer.Observable;
126
import org.gvsig.tools.observer.Observer;
127
import org.gvsig.tools.persistence.PersistenceException;
128
import org.gvsig.tools.persistence.PersistentState;
129
import org.gvsig.tools.persistence.xmlentity.XMLEntityManager;
130
import org.gvsig.tools.persistence.xmlentity.XMLEntityState;
131
import org.gvsig.tools.task.Cancellable;
132
import org.slf4j.LoggerFactory;
133

    
134
import com.iver.utiles.NotExistInXMLEntity;
135
import com.iver.utiles.XMLEntity;
136
import com.iver.utiles.XMLException;
137

    
138
/**
139
 * Capa b?sica Vectorial.
140
 *
141
 * @author Fernando Gonz?lez Cort?s
142
 */
143

    
144
// TODO Cuando no sea para pruebas debe no ser public
145
public class FLyrVect extends FLyrDefault implements ILabelable, InfoByPoint,
146
ClassifiableVectorial, SingleLayer, LegendContentsChangedListener,
147
Observer {
148
        final static private org.slf4j.Logger logger = LoggerFactory.getLogger(FLyrVect.class);
149
        private static final GeometryManager geomManager = GeometryLocator.getGeometryManager();
150
        /** Leyenda de la capa vectorial */
151
        private IVectorLegend legend;
152
        private int typeShape = -1;
153
        private FeatureStore featureStore=null;
154
        private SpatialCache spatialCache = new SpatialCache();
155
        private boolean spatialCacheEnabled = false;
156

    
157
        /**
158
         * An implementation of gvSIG spatial index
159
         */
160
        //    protected ISpatialIndex spatialIndex = null;
161
        private boolean bHasJoin = false;
162
        private XMLEntity orgXMLEntity = null;
163
        private XMLEntity loadSelection = null;
164
        private IVectorLegend loadLegend = null;
165

    
166
        //Lo a?ado. Caracter?sticas de HyperEnlace (LINK)
167
        private FLyrVectLinkProperties linkProperties=new FLyrVectLinkProperties();
168

    
169
        /**
170
         * Devuelve el VectorialAdapater de la capa.
171
         *
172
         * @return VectorialAdapter.
173
         */
174
        public DataStore getDataStore() {
175
                if (!this.isAvailable()) {
176
                        return null;
177
                }
178
                return featureStore;
179
        }
180

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

    
235
        /**
236
         * Checks if it has associated an external spatial index
237
         * (an spatial index file).
238
         *
239
         * It looks for it in main file path, or in temp system path.
240
         * If main file is rivers.shp, it looks for a file called
241
         * rivers.shp.qix.
242

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

    
285
                featureStore = (FeatureStore)dataStore;
286

    
287
                ILegend legend = null;
288
                try {
289
                        legend = (ILegend) dataStore.invokeDynMethod("defaultLegend", null);
290

    
291
                } catch (DynMethodNotSupportedException e1) {
292
                        try {
293
                                legend = LegendFactory.createSingleSymbolLegend(this
294
                                                .getShapeType());
295
                        } catch (ReadException e) {
296
                                throw new LoadLayerException(this.getName(), e);
297
                        }
298

    
299
                } catch (DynMethodException e1) {
300
                        throw new LoadLayerException(this.getName(), e1);
301
                }
302
                this.setLegend((IVectorLegend) legend);
303

    
304

    
305

    
306

    
307
                ILabelingStrategy labeler = null;
308
                try {
309
                        labeler = (ILabelingStrategy) dataStore.invokeDynMethod(
310
                                        "defaultLabelingStrategy", null);
311
                } catch (DynMethodNotSupportedException e1) {
312
                        labeler = null;
313
                } catch (DynMethodException e1) {
314
                        throw new LoadLayerException(this.getName(), e1);
315
                }
316

    
317
                if (labeler != null) {
318
                        try {
319
                                labeler.setLayer(this);
320
                        } catch (ReadException e) {
321
                                throw new LoadLayerException(this.getName(), e);
322
                        }
323
                        this.setLabelingStrategy(labeler);
324
                        this.setIsLabeled(true); // TODO: ac? no s'hauria de detectar si t? etiquetes?????
325
                }
326

    
327
                this.delegate(dataStore);
328

    
329
                dataStore.addObserver(this);
330

    
331
                // azabala: we check if this layer could have a file spatial index
332
                // and load it if it exists
333
                //        loadSpatialIndex();
334
        }
335

    
336
        public Envelope getFullEnvelope() throws ReadException {
337
                Envelope rAux;
338
                try {
339
                        rAux = getFeatureStore().getEnvelope();
340
                } catch (BaseException e) {
341
                        throw new ReadException(getName(),e);
342
                }
343

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

    
374
        }
375

    
376
        /**
377
         * Draws using IFeatureIterator. This method will replace the old draw(...) one.
378
         * @autor jaume dominguez faus - jaume.dominguez@iver.es
379
         * @param image
380
         * @param g
381
         * @param viewPort
382
         * @param cancel
383
         * @param scale
384
         * @throws ReadDriverException
385
         */
386
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
387
                        Cancellable cancel, double scale) throws ReadException {
388
                if (!this.isWithinScale(scale)) {
389
                        return;
390
                }
391
                if (cancel.isCanceled()) {
392
                        return;
393
                }
394
                boolean containsAll = false;
395
                Envelope viewPortEnvelope =viewPort.getAdjustedExtent();
396
                Envelope viewPortEnvelopeInMyProj = viewPortEnvelope;
397
                // FIXME
398
                if (this.getCoordTrans() != null) {
399
                        viewPortEnvelopeInMyProj = viewPortEnvelope
400
                                        .convert(this
401
                                        .getCoordTrans().getInverted());
402

    
403
                }
404

    
405

    
406
                Envelope myEnvelope;
407
                try {
408
                        myEnvelope = this.getFullEnvelope();
409
                } catch (ConcurrentDataModificationException e) {
410
                        cancel.setCanceled(true);
411
                        return;
412
                }
413
                if (!viewPortEnvelope.intersects(myEnvelope)){
414
                        return;
415
                }
416
                containsAll = viewPortEnvelope.contains(myEnvelope);
417
                double dpi = MapContext.getScreenDPI();
418
                DrawOperationContext doc=new DrawOperationContext();
419
                doc.setViewPort(viewPort);
420
                doc.setScale(scale);
421
                doc.setCancellable(cancel);
422
                doc.setDPI(dpi);
423
                boolean bDrawShapes = true;
424
                if (legend instanceof SingleSymbolLegend) {
425
                        bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
426
                }
427
                Point2D offset = viewPort.getOffset();
428

    
429
                if (bDrawShapes) {
430
                        if (cancel.isCanceled()) {
431
                                return;
432
                        }
433
                        boolean cacheFeatures = isSpatialCacheEnabled();
434
                        SpatialCache cache = null;
435
                        if (cacheFeatures) {
436
                                getSpatialCache().clearAll();
437
                                cache = getSpatialCache();
438
                        }
439

    
440
                        try {
441

    
442
                                FeatureSelection selection = this.featureStore
443
                                .getFeatureSelection();
444

    
445
                                FeatureStore featureStore=getFeatureStore();
446
                                String[] fieldNames=null;
447
                                if (legend instanceof IClassifiedVectorLegend){
448
                                        String[] classified=((IClassifiedVectorLegend)legend).getClassifyingFieldNames();
449
                                        fieldNames=new String[classified.length+1];
450
                                        fieldNames[0]=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
451
                                        for (int i = 1; i < fieldNames.length; i++) {
452
                                                fieldNames[i]=classified[i-1];
453
                                        }
454

    
455
                                }else{
456
                                        fieldNames=new String[]{featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName()};
457
                                }
458
                                FeatureSet featureSet=null;
459
                                FeatureQuery featureQuery=featureStore.createFeatureQuery();
460
                                featureQuery.setScale(scale);
461
                                featureQuery.setAttributeNames(fieldNames);
462
                                if (!containsAll) {
463
                                        IntersectsEnvelopeEvaluator iee = new IntersectsEnvelopeEvaluator(
464
                                                        viewPortEnvelopeInMyProj, getProjection(),
465
                                                        featureStore.getDefaultFeatureType(),
466
                                                        featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName());
467
                                        featureQuery.setFilter(iee);
468

    
469
                                }
470
                                featureSet = featureStore.getFeatureSet(featureQuery);
471
                                DisposableIterator it = featureSet.fastIterator();
472

    
473
                                ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
474

    
475
                                boolean bSymbolLevelError = false;
476

    
477
                                // if layer has map levels it will use a ZSort
478
                                boolean useZSort = zSort != null && zSort.isUsingZSort();
479

    
480
                                // -- visual FX stuff
481
                                long time = System.currentTimeMillis();
482
                                BufferedImage virtualBim;
483
                                Graphics2D virtualGraphics;
484

    
485
                                if (cancel.isCanceled()) {
486
                                        return;
487
                                }
488

    
489
                                // render temporary map each screenRefreshRate milliseconds;
490
                                int screenRefreshDelay = (int) ((1D/MapContext.getDrawFrameRate())*3*1000);
491
                                BufferedImage[] imageLevels = null;
492
                                Graphics2D[] graphics = null;
493
                                if (useZSort) {
494
                                        imageLevels = new BufferedImage[zSort.getLevelCount()];
495
                                        graphics = new Graphics2D[imageLevels.length];
496
                                        for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
497
                                                imageLevels[i] = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
498
                                                graphics[i] = imageLevels[i].createGraphics();
499
                                                graphics[i].setTransform(g.getTransform());
500
                                                graphics[i].setRenderingHints(g.getRenderingHints());
501
                                        }
502
                                }
503
                                // -- end visual FX stuff
504

    
505
                                // FIXME geometry reproject temporaly patch
506
                                // FeatureAttributeDescriptor attrGeom =
507
                                // featureStore.getDefaultFeatureType().getAttributeDescriptor(featureStore.getDefaultFeatureType().getDefaultGeometryAttributeIndex());
508
                                // ICoordTrans myct = null;
509
                                // if (!viewPort.getProjection().equals(attrGeom.getSRS())) {
510
                                // myct = viewPort.getProjection().getCT(attrGeom.getSRS());
511
                                // }
512

    
513

    
514
                                try {
515
                                        // Iteration over each feature
516
                                        while (it.hasNext()) {
517
                                                if (cancel.isCanceled()) {
518
                                                        return;
519
                                                }
520
                                                Feature feat = (Feature) it.next();
521

    
522
                                                Geometry geom = feat.getDefaultGeometry();
523

    
524
                                                if (geom.getType() == Geometry.TYPES.NULL) {
525
                                                        continue;
526
                                                }
527

    
528
                                                if (this.getCoordTrans() != null) {
529
                                                        geom = geom.cloneGeometry();
530
                                                        geom.reProject(this.getCoordTrans());
531
                                                }
532

    
533
                                                if (cacheFeatures) {
534
                                                        if (cache.getMaxFeatures() >= cache.size()) {
535
                                                                // already reprojected
536
                                                                cache.insert(geom.getEnvelope(), geom);
537
                                                        }
538
                                                }
539

    
540
                                                // retrieve the symbol associated to such feature
541
                                                ISymbol sym = legend.getSymbolByFeature(feat);
542
                                                if (selection.isSelected(feat)) {
543
                                                        sym = sym.getSymbolForSelection();
544
                                                }
545
                                                if (sym == null) {
546
                                                        continue;
547
                                                }
548

    
549
                                                // Check if this symbol is sized with
550
                                                // CartographicSupport
551
                                                CartographicSupport csSym = null;
552
                                                int symbolType = sym.getSymbolType();
553
                                                boolean bDrawCartographicSupport = false;
554

    
555
                                                if (symbolType == Geometry.TYPES.POINT
556
                                                                || symbolType == Geometry.TYPES.CURVE
557
                                                                || sym instanceof CartographicSupport) {
558

    
559
                                                        // patch
560
                                                        if (!sym.getClass().equals(FSymbol.class)) {
561
                                                                csSym = (CartographicSupport) sym;
562
                                                                bDrawCartographicSupport = (csSym.getUnit() != -1);
563
                                                        }
564
                                                }
565

    
566
                                                int x = -1;
567
                                                int y = -1;
568
                                                int[] xyCoords = new int[2];
569

    
570
                                                // Check if size is a pixel
571
                                                boolean onePoint = bDrawCartographicSupport ? isOnePoint(
572
                                                                g.getTransform(), viewPort, MapContext
573
                                                                                .getScreenDPI(), csSym, geom, xyCoords)
574
                                                                : isOnePoint(g.getTransform(), viewPort, geom,
575
                                                                                xyCoords);
576

    
577
                                                                // Avoid out of bounds exceptions
578
                                                if (onePoint) {
579
                                                        x = xyCoords[0];
580
                                                        y = xyCoords[1];
581
                                                        if (x < 0 || y < 0 || x >= viewPort.getImageWidth()
582
                                                                        || y >= viewPort.getImageHeight()) {
583
                                                                continue;
584
                                                        }
585
                                                }
586

    
587
                                                                if (cancel.isCanceled()) {
588
                                                        return;
589
                                                                }
590

    
591
                                                                if (useZSort) {
592
                                                        // Check if this symbol is a multilayer
593
                                                        int[] symLevels = zSort.getLevels(sym);
594
                                                        if (sym instanceof IMultiLayerSymbol) {
595
                                                                // if so, treat each of its layers as a single
596
                                                                // symbol
597
                                                                // in its corresponding map level
598
                                                                IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
599
                                                                for (int i = 0; !cancel.isCanceled()
600
                                                                                && i < mlSym.getLayerCount(); i++) {
601
                                                                        ISymbol mySym = mlSym.getLayer(i);
602
                                                                        int symbolLevel = 0;
603
                                                                        if (symLevels != null) {
604
                                                                                symbolLevel = symLevels[i];
605
                                                                        } else {
606
                                                                                /*
607
                                                                                 * an error occured when managing symbol
608
                                                                                 * levels some of the legend changed
609
                                                                                 * events regarding the symbols did not
610
                                                                                 * finish satisfactory and the legend is
611
                                                                                 * now inconsistent. For this drawing,
612
                                                                                 * it will finish as it was at the
613
                                                                                 * bottom (level 0) but, when done, the
614
                                                                                 * ZSort will be reset to avoid app
615
                                                                                 * crashes. This is a bug that has to be
616
                                                                                 * fixed.
617
                                                                                 */
618
                                                                                bSymbolLevelError = true;
619
                                                                        }
620

    
621
                                                                                        if (onePoint) {
622
                                                                                if (x < 0
623
                                                                                                || y < 0
624
                                                                                                || x >= imageLevels[symbolLevel]
625
                                                                                                                .getWidth()
626
                                                                                                || y >= imageLevels[symbolLevel]
627
                                                                                                                .getHeight()) {
628
                                                                                        continue;
629
                                                                                }
630
                                                                                imageLevels[symbolLevel].setRGB(x, y,
631
                                                                                                mySym.getOnePointRgb());
632
                                                                        } else {
633
                                                                                if (!bDrawCartographicSupport) {
634
                                                                                        doc
635
                                                                                                        .setGraphics(graphics[symbolLevel]);
636
                                                                                        doc.setSymbol(mySym);
637
                                                                                        geom.invokeOperation(DrawInts.CODE,
638
                                                                                                        doc);
639
                                                                                } else {
640
                                                                                        doc
641
                                                                                                        .setGraphics(graphics[symbolLevel]);
642
                                                                                        doc.setSymbol(mySym);
643
                                                                                        geom.invokeOperation(DrawInts.CODE,
644
                                                                                                        doc);
645
                                                                                }
646
                                                                        }
647
                                                                }
648
                                                        } else {
649
                                                                // else, just draw the symbol in its level
650
                                                                                int symbolLevel = 0;
651
                                                                                if (symLevels != null) {
652
                                                                                        symbolLevel = symLevels[0];
653
                                                                }
654
                                                                if (!bDrawCartographicSupport) {
655
                                                                        doc.setGraphics(graphics[symbolLevel]);
656
                                                                        doc.setSymbol(sym);
657
                                                                        geom.invokeOperation(DrawInts.CODE, doc);
658
                                                                                } else {
659
                                                                                        doc.setGraphics(graphics[symbolLevel]);
660
                                                                        doc.setSymbol((ISymbol) csSym);
661
                                                                        geom.invokeOperation(DrawInts.CODE, doc);
662
                                                                                }
663
                                                                        }
664

    
665
                                                                        // -- visual FX stuff
666
                                                        // Cuando el offset!=0 se est? dibujando sobre el
667
                                                        // Layout y por tanto no tiene que ejecutar el
668
                                                        // siguiente c?digo.
669
                                                        if (offset.getX() == 0 && offset.getY() == 0) {
670
                                                                if ((System.currentTimeMillis() - time) > screenRefreshDelay) {
671
                                                                        virtualBim = new BufferedImage(image
672
                                                                                        .getWidth(), image.getHeight(),
673
                                                                                        BufferedImage.TYPE_INT_ARGB);
674
                                                                        virtualGraphics = virtualBim
675
                                                                                        .createGraphics();
676
                                                                        virtualGraphics
677
                                                                                        .drawImage(image, 0, 0, null);
678
                                                                        for (int i = 0; !cancel.isCanceled()
679
                                                                                        && i < imageLevels.length; i++) {
680
                                                                                virtualGraphics.drawImage(
681
                                                                                                imageLevels[i], 0, 0, null);
682
                                                                                        }
683
                                                                                        g.clearRect(0, 0, image.getWidth(), image
684
                                                                                        .getHeight());
685
                                                                        g.drawImage(virtualBim, 0, 0, null);
686
                                                                        time = System.currentTimeMillis();
687
                                                                                }
688
                                                                                // -- end visual FX stuff
689
                                                                        }
690

    
691
                                                                } else {
692
                                                                        // no ZSort, so there is only a map level, symbols
693
                                                        // are
694
                                                        // just drawn.
695
                                                        if (onePoint) {
696
                                                                if (x < 0 || y < 0 || x >= image.getWidth()
697
                                                                                || y >= image.getHeight()) {
698
                                                                        continue;
699
                                                                }
700
                                                                image.setRGB(x, y, sym.getOnePointRgb());
701
                                                                        } else {
702

    
703
                                                                                if (!bDrawCartographicSupport) {
704
                                                                        doc.setGraphics(g);
705
                                                                        doc.setSymbol(sym);
706
                                                                        geom.invokeOperation(DrawInts.CODE, doc);
707
                                                                } else {
708
                                                                        doc.setGraphics(g);
709
                                                                        doc.setSymbol((ISymbol) csSym);
710
                                                                        geom.invokeOperation(DrawInts.CODE, doc);
711
                                                                                }
712
                                                                        }
713
                                                                }
714
                                        }
715
                                } catch (ConcurrentDataModificationException e) {
716
                                        cancel.setCanceled(true);
717
                                        return;
718
                                }
719

    
720
                                if (useZSort) {
721
                                        g.drawImage(image, 0, 0, null);
722
                                        g.translate(offset.getX(), offset.getY());
723
                                        for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
724
                                                g.drawImage(imageLevels[i],0,0, null);
725
                                                imageLevels[i] = null;
726
                                                graphics[i] = null;
727
                                        }
728
                                        g.translate(-offset.getX(), -offset.getY());
729
                                        imageLevels = null;
730
                                        graphics = null;
731
                                }
732
                                it.dispose();
733
                                featureSet.dispose();
734

    
735
                                if (bSymbolLevelError) {
736
                                        ((IVectorLegend) getLegend()).setZSort(null);
737
                                }
738

    
739
                        } catch (ReadException e) {
740
                                this.setVisible(false);
741
                                this.setActive(false);
742
                                throw e;
743
                        } catch (GeometryOperationNotSupportedException e) {
744
                                this.setVisible(false);
745
                                this.setActive(false);
746
                                throw new ReadException(getName(),e);
747
                        } catch (GeometryOperationException e) {
748
                                this.setVisible(false);
749
                                this.setActive(false);
750
                                throw new ReadException(getName(),e);
751
                        } catch (BaseException e) {
752
                                this.setVisible(false);
753
                                this.setActive(false);
754
                                throw new ReadException(getName(),e);
755
                        }
756

    
757

    
758
                }
759
        }
760
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
761
                        double scale, PrintRequestAttributeSet properties) throws ReadException {
762
                // TEST METHOD
763
                boolean bDrawShapes = true;
764
                if (legend instanceof SingleSymbolLegend) {
765
                        bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
766
                }
767
                if (bDrawShapes) {
768
                        try {
769
                                double dpi = 72;
770

    
771
                                PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
772
                                if (resolution.equals(PrintQuality.NORMAL)){
773
                                        dpi = 300;
774
                                } else if (resolution.equals(PrintQuality.HIGH)){
775
                                        dpi = 600;
776
                                } else if (resolution.equals(PrintQuality.DRAFT)){
777
                                        dpi = 72;
778
                                }
779
                                ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
780

    
781
                                // if layer has map levels it will use a ZSort
782
                                boolean useZSort = zSort != null && zSort.isUsingZSort();
783

    
784

    
785
                                int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1;
786
                                for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) {
787
                                        // Get the iterator over the visible features
788
                                        FeatureStore featureStore=getFeatureStore();
789
                                        // Get the iterator over the visible features
790
                                        //                                String featureFilter = null;
791
                                        //
792
                                        //                                if (!viewPort.getAdjustedExtent().contains((Envelope)featureStore.getMetadata().get("extent"))) {
793
                                        //                                            featureFilter=this.getDataStoreFilterForGeomerty(
794
                                        //                                                    viewPort.getAdjustedExtent().getGeometry(),
795
                                        //                                                    featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName(),
796
                                        //                                                    null);
797
                                        //                                    }
798
                                        String[] fieldNames=null;
799
                                        if (legend instanceof IClassifiedVectorLegend){
800
                                                String[] classified=((IClassifiedVectorLegend)legend).getClassifyingFieldNames();
801
                                                fieldNames=new String[classified.length+1];
802
                                                fieldNames[0]=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
803
                                                for (int i = 1; i < fieldNames.length; i++) {
804
                                                        fieldNames[i]=classified[i-1];
805
                                                }
806

    
807
                                        }else{
808
                                                fieldNames=new String[]{featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName()};
809
                                        }
810

    
811

    
812
                                        FeatureSet featureSet=null;
813
                                        FeatureQuery featureQuery=featureStore.createFeatureQuery();
814
                                        featureQuery.setAttributeNames(fieldNames);
815
                                        featureQuery.setScale(scale);
816
                                        //                                ??SQLJEPEvaluator evaluator=new SQLJEPEvaluator(featureFilter);
817
                                        ContainsEnvelopeEvaluator iee=new ContainsEnvelopeEvaluator(viewPort.getAdjustedExtent(),viewPort.getProjection(),featureStore.getDefaultFeatureType(),featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName());
818
                                        featureQuery.setFilter(iee);
819
                                        featureSet = featureStore.getFeatureSet(featureQuery);
820
                                        DisposableIterator it = featureSet.fastIterator();
821

    
822
                                        // Iteration over each feature
823
                                        while ( !cancel.isCanceled() && it.hasNext()) {
824
                                                Feature feat = (Feature)it.next();
825
                                                Geometry geom = feat.getDefaultGeometry();
826

    
827
                                                // retreive the symbol associated to such feature
828
                                                ISymbol sym = legend.getSymbolByFeature(feat);
829
                                                if (sym == null) {
830
                                                        continue;
831
                                                }
832
                                                if (useZSort) {
833
                                                        int[] symLevels = zSort.getLevels(sym);
834
                                                        if(symLevels != null){
835

    
836
                                                                // Check if this symbol is a multilayer
837
                                                                if (sym instanceof IMultiLayerSymbol) {
838
                                                                        // if so, get the layer corresponding to the current
839
                                                                        // level. If none, continue to next iteration
840
                                                                        IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
841
                                                                        for (int i = 0; i < mlSym.getLayerCount(); i++) {
842
                                                                                ISymbol mySym = mlSym.getLayer(i);
843
                                                                                if (symLevels[i] == mapPass) {
844
                                                                                        sym = mySym;
845
                                                                                        break;
846
                                                                                }
847
                                                                                System.out.println("avoided layer "+i+"of symbol '"+mlSym.getDescription()+"' (pass "+mapPass+")");
848
                                                                        }
849

    
850
                                                                } else {
851
                                                                        // else, just draw the symbol in its level
852
                                                                        if (symLevels[0] != mapPass) {
853
                                                                                System.out.println("avoided single layer symbol '"+sym.getDescription()+"' (pass "+mapPass+")");
854
                                                                                continue;
855
                                                                        }
856
                                                                }
857
                                                        }
858
                                                }
859

    
860
                                                // Check if this symbol is sized with CartographicSupport
861
                                                CartographicSupport csSym = null;
862
                                                int symbolType = sym.getSymbolType();
863
                                                boolean bDrawCartographicSupport = false;
864

    
865
                                                if (   symbolType == Geometry.TYPES.POINT
866
                                                                || symbolType == Geometry.TYPES.CURVE
867
                                                                || sym instanceof CartographicSupport) {
868

    
869
                                                        csSym = (CartographicSupport) sym;
870
                                                        bDrawCartographicSupport = (csSym.getUnit() != -1);
871
                                                }
872

    
873
                                                System.err.println("passada "+mapPass+" pinte s?mboll "+sym.getDescription());
874

    
875
                                                if (!bDrawCartographicSupport) {
876
                                                        DrawOperationContext doc=new DrawOperationContext();
877
                                                        doc.setGraphics(g);
878
                                                        doc.setViewPort(viewPort);
879
                                                        doc.setSymbol(sym);
880
                                                        doc.setCancellable(cancel);
881
                                                        geom.invokeOperation(DrawInts.CODE,doc);
882
                                                } else {
883
                                                        DrawOperationContext doc=new DrawOperationContext();
884
                                                        doc.setGraphics(g);
885
                                                        doc.setViewPort(viewPort);
886
                                                        doc.setSymbol((ISymbol)csSym);
887
                                                        doc.setCancellable(cancel);
888
                                                        doc.setDPI(dpi);
889
                                                        geom.invokeOperation(DrawInts.CODE,doc);
890
                                                }
891
                                        }
892
                                        it.dispose();
893
                                        it=null;
894
                                        featureSet.dispose();
895
                                }
896
                        } catch (ReadException e) {
897
                                this.setVisible(false);
898
                                this.setActive(false);
899
                                throw e;
900
                        } catch (GeometryOperationNotSupportedException e) {
901
                                this.setVisible(false);
902
                                this.setActive(false);
903
                                throw new ReadException(getName(),e);
904
                        } catch (GeometryOperationException e) {
905
                                this.setVisible(false);
906
                                this.setActive(false);
907
                                throw new ReadException(getName(),e);
908
                        } catch (BaseException e) {
909
                                this.setVisible(false);
910
                                this.setActive(false);
911
                                throw new ReadException(getName(),e);
912
                        }
913
                }
914
        }
915

    
916
        /**
917
         * <p>
918
         * Creates an spatial index associated to this layer.
919
         * The spatial index will used
920
         * the native projection of the layer, so if the layer is reprojected, it will
921
         * be ignored.
922
         * </p>
923
         * @param cancelMonitor instance of CancellableMonitorable that allows
924
         * to monitor progress of spatial index creation, and cancel the process
925
         */
926
        //    public void createSpatialIndex(CancellableMonitorable cancelMonitor){
927
        //         // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
928
        //        // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
929
        //        // para que acepten recorrer sin geometria, solo con rectangulos.
930
        //
931
        //        //If this vectorial layer is based in a spatial database, the spatial
932
        //        //index is already implicit. We only will index file drivers
933
        //        ReadableVectorial va = getSource();
934
        //        //We must think in non spatial databases, like HSQLDB
935
        //        if(!(va instanceof VectorialFileAdapter)){
936
        //            return;
937
        //        }
938
        //        if (!(va.getDriver() instanceof BoundedShapes)) {
939
        //            return;
940
        //        }
941
        //        File file = ((VectorialFileAdapter) va).getFile();
942
        //        String fileName = file.getAbsolutePath();
943
        //        ISpatialIndex localCopy = null;
944
        //        try {
945
        //            va.start();
946
        //            localCopy = new QuadtreeGt2(fileName, "NM", va.getFullExtent(),
947
        //                    va.getShapeCount(), true);
948
        //
949
        //        } catch (SpatialIndexException e1) {
950
        //            // Probably we dont have writing permissions
951
        //            String directoryName = System.getProperty("java.io.tmpdir");
952
        //            File newFile = new File(directoryName +
953
        //                    File.separator +
954
        //                    file.getName());
955
        //            String newFileName = newFile.getName();
956
        //            try {
957
        //                localCopy = new QuadtreeGt2(newFileName, "NM", va.getFullExtent(),
958
        //                        va.getShapeCount(), true);
959
        //            } catch (SpatialIndexException e) {
960
        //                // if we cant build a file based spatial index, we'll build
961
        //                // a pure memory spatial index
962
        //                localCopy = new QuadtreeJts();
963
        //            } catch (ReadException e) {
964
        //                localCopy = new QuadtreeJts();
965
        //            }
966
        //
967
        //        } catch(Exception e){
968
        //            e.printStackTrace();
969
        //        }//try
970
        //        BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
971
        //        try {
972
        //            for (int i=0; i < va.getShapeCount(); i++)
973
        //            {
974
        //                if(cancelMonitor != null){
975
        //                    if(cancelMonitor.isCanceled())
976
        //                        return;
977
        //                    cancelMonitor.reportStep();
978
        //                }
979
        //                Rectangle2D r = shapeBounds.getShapeBounds(i);
980
        //                if(r != null)
981
        //                    localCopy.insert(r, i);
982
        //            } // for
983
        //            va.stop();
984
        //            if(localCopy instanceof IPersistentSpatialIndex)
985
        //                ((IPersistentSpatialIndex) localCopy).flush();
986
        //            spatialIndex = localCopy;
987
        //            //vectorial adapter needs a reference to the spatial index, to solve
988
        //            //request for feature iteration based in spatial queries
989
        //            source.setSpatialIndex(spatialIndex);
990
        //        } catch (ReadException e) {
991
        //            // TODO Auto-generated catch block
992
        //            e.printStackTrace();
993
        //        }
994
        //    }
995

    
996
        //    public void createSpatialIndex() {
997
        //        createSpatialIndex(null);
998
        //    }
999

    
1000

    
1001
        public void setLegend(IVectorLegend r) throws LegendLayerException {
1002
                if (this.legend == r){
1003
                        return;
1004
                }
1005
                if (this.legend != null && this.legend.equals(r)){
1006
                        return;
1007
                }
1008
                IVectorLegend oldLegend = legend;
1009
                legend = r;
1010
                try {
1011
                        legend.setFeatureStore(getFeatureStore());
1012
                } catch (ReadException e1) {
1013
                        throw new LegendLayerException(getName(),e1);
1014
                } catch (DataException e) {
1015
                        throw new LegendLayerException(getName(),e);
1016
                } finally{
1017
                        this.updateDrawVersion();
1018
                }
1019

    
1020
                if (oldLegend != null) {
1021
                        oldLegend.removeLegendListener(this);
1022
                }
1023
                if (legend != null) {
1024
                        legend.addLegendListener(this);
1025
                }
1026

    
1027
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
1028
                                oldLegend, legend);
1029
                callLegendChanged(e);
1030
        }
1031

    
1032
        /**
1033
         * Devuelve la Leyenda de la capa.
1034
         *
1035
         * @return Leyenda.
1036
         */
1037
        public ILegend getLegend() {
1038
                return legend;
1039
        }
1040

    
1041
        /**
1042
         * Devuelve el tipo de shape que contiene la capa.
1043
         *
1044
         * @return tipo de shape.
1045
         *
1046
         * @throws ReadException
1047
         */
1048
        public int getShapeType() throws ReadException {
1049
                if (typeShape == -1) {
1050
                        FeatureType featureType;
1051
                        try {
1052
                                featureType = (((FeatureStore)getDataStore()).getDefaultFeatureType());
1053
                        } catch (DataException e) {
1054
                                throw new ReadException(getName(),e);
1055
                        }
1056
                        int indexGeom=featureType.getDefaultGeometryAttributeIndex();
1057
                        typeShape=featureType.getAttributeDescriptor(indexGeom).getGeometryType();
1058
                }
1059
                return typeShape;
1060
        }
1061

    
1062
        public XMLEntity getXMLEntity() throws XMLException {
1063

    
1064
                if (!this.isAvailable() && this.orgXMLEntity != null) {
1065
                        return this.orgXMLEntity;
1066
                }
1067
                XMLEntity xml = super.getXMLEntity();
1068
                if (getLegend()!=null){
1069
                        XMLEntity xmlLegend=getLegend().getXMLEntity();
1070
                        xmlLegend.putProperty("tagName","legend");
1071
                        xml.addChild(xmlLegend);
1072
                }
1073
                try {
1074
                        PersistentState stateFeatureStore=getFeatureStore().getState();
1075
                        stateFeatureStore.set("tagName","featureStore");
1076
                        xml.addChild(((XMLEntityState)stateFeatureStore).getXMLEntity());
1077
                } catch (ReadException e) {
1078
                        throw new XMLLayerException(getName(),e);
1079
                } catch (PersistenceException e) {
1080
                        throw new XMLLayerException(getName(),e);
1081
                }
1082
                // properties from ILabelable
1083
                xml.putProperty("isLabeled", isLabeled);
1084
                if (strategy != null) {
1085
                        XMLEntity strategyXML = strategy.getXMLEntity();
1086
                        strategyXML.putProperty("tagName", "labelingStrategy");
1087
                        xml.addChild(strategy.getXMLEntity());
1088
                }
1089
                xml.addChild(getLinkProperties().getXMLEntity());
1090
                return xml;
1091
        }
1092
        /*
1093
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
1094
         */
1095
        public void setXMLEntity(XMLEntity xml) throws XMLException {
1096
                try {
1097
                        super.setXMLEntity(xml);
1098
                        XMLEntity legendXML = xml.firstChild("tagName","legend");
1099
                        IVectorLegend leg = LegendFactory.createFromXML(legendXML);
1100
                        /* (jaume) begin patch;
1101
                         * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1102
                         * no longer managed by the Legend but by the ILabelingStrategy. The
1103
                         * following allows restoring older projects' labelings.
1104
                         */
1105
                        if (legendXML.contains("labelFieldName")) {
1106
                                String labelTextField = legendXML.getStringProperty("labelFieldName");
1107
                                if (labelTextField != null) {
1108
                                        AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
1109
                                        labeling.setLayer(this);
1110
                                        labeling.setTextField(legendXML.getStringProperty("labelFieldName"));
1111
                                        labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
1112
                                        labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
1113
                                        this.setLabelingStrategy(labeling);
1114
                                        this.setIsLabeled(true);
1115
                                }
1116
                        }
1117
                        //            PersistentState persistentState=new XMLEntityState(new XMLEntityManager());
1118
                        XMLEntity xmlStore=xml.firstChild("tagName","featureStore");
1119
                        XMLEntityManager xmlManger = new XMLEntityManager();
1120
                        PersistentState state = xmlManger.createState(xmlStore);
1121
                        DataStore store = (DataStore) ToolsLocator.getPersistenceManager().create(state);
1122
                        //            persistentState.createState(xmlStore);
1123

    
1124
                        //            DataManager dm=DALLocator.getDataManager();
1125

    
1126
                        this.setDataStore(store);
1127
                        /* end patch */
1128
                        try {
1129
                                setLegend(leg);
1130
                        } catch (LegendLayerException e) {
1131
                                throw new XMLLegendException(e);
1132
                        }
1133
                        // set properties for ILabelable
1134

    
1135
                        if (xml.contains("isLabeled")
1136
                                        && xml.getBooleanProperty(("isLabeled"))) {
1137
                                XMLEntity labelingXML = xml.firstChild("tagName", "labelingStrategy");
1138
                                if (labelingXML != null){
1139

    
1140
                                        isLabeled = true;
1141
                                        try {
1142
                                                this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this);
1143
                                        } catch (NotExistInXMLEntity neXMLEX) {
1144
                                                // no strategy was set, just continue;
1145
                                                logger.warn("Reached what should be unreachable code");
1146
                                        }
1147
                                } else {
1148
                                        isLabeled = false;
1149
                                }
1150
                        } else {
1151
                                isLabeled = false;
1152
                        }
1153
                        XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
1154
                        if (xmlLinkProperties != null){
1155
                                getLinkProperties().setXMLEntity(xmlLinkProperties);
1156
                        }
1157
                } catch (Exception e) {
1158
                        e.printStackTrace();
1159
                        this.setAvailable(false);
1160
                        this.orgXMLEntity = xml;
1161

    
1162
                }
1163
                //
1164

    
1165
        }
1166

    
1167
        public void setXMLEntityNew(XMLEntity xml) throws XMLException {
1168
                //        try {
1169
                //            super.setXMLEntity(xml);
1170
                //
1171
                //            XMLEntity legendXML = xml.getChild(0);
1172
                //            IVectorLegend leg = LegendFactory.createFromXML(legendXML);
1173
                //            /* (jaume) begin patch;
1174
                //             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1175
                //             * no longer managed by the Legend but by the ILabelingStrategy. The
1176
                //             * following allows restoring older projects' labelings.
1177
                //             */
1178
                //            if (legendXML.contains("labelFieldHeight")) {
1179
                //                AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
1180
                //                labeling.setLayer(this);
1181
                //                labeling.setTextField(legendXML.getStringProperty("labelFieldHeight"));
1182
                //                labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
1183
                //                this.setLabelingStrategy(labeling);
1184
                //                this.setIsLabeled(true);
1185
                //              }
1186
                //            /* end patch */
1187
                //            try {
1188
                //                getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
1189
                //
1190
                //                this.setLoadSelection(xml.getChild(1));
1191
                //            } catch (ReadException e1) {
1192
                //                this.setAvailable(false);
1193
                //                throw new XMLException(e1);
1194
                //            }
1195
                //            // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
1196
                //            // el final
1197
                //            // de la lectura del proyecto
1198
                //            if (xml.contains("hasJoin")) {
1199
                //                setIsJoined(true);
1200
                //                PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
1201
                //            } else {
1202
                //                this.setLoadLegend(leg);
1203
                //            }
1204
                //
1205
                //        } catch (XMLException e) {
1206
                //            this.setAvailable(false);
1207
                //            this.orgXMLEntity = xml;
1208
                //        } catch (Exception e) {
1209
                //            this.setAvailable(false);
1210
                //            this.orgXMLEntity = xml;
1211
                //        }
1212

    
1213

    
1214
        }
1215

    
1216

    
1217
        /**
1218
         * Sobreimplementaci?n del m?todo toString para que las bases de datos
1219
         * identifiquen la capa.
1220
         *
1221
         * @return DOCUMENT ME!
1222
         */
1223
        public String toString() {
1224
                /*
1225
                 * Se usa internamente para que la parte de datos identifique de forma
1226
                 * un?voca las tablas
1227
                 */
1228
                String ret = super.toString();
1229

    
1230
                return "layer" + ret.substring(ret.indexOf('@') + 1);
1231
        }
1232

    
1233
        public boolean isJoined() {
1234
                return bHasJoin;
1235
        }
1236

    
1237
        /**
1238
         * Returns if a layer is spatially indexed
1239
         *
1240
         * @return if this layer has the ability to proces spatial queries without
1241
         *         secuential scans.
1242
         */
1243
        //    public boolean isSpatiallyIndexed() {
1244
        //        ReadableVectorial source = getSource();
1245
        //        if (source instanceof ISpatialDB)
1246
        //            return true;
1247
        //
1248
        ////FIXME azabala
1249
        ///*
1250
        // * Esto es muy dudoso, y puede cambiar.
1251
        // * Estoy diciendo que las que no son fichero o no son
1252
        // * BoundedShapes estan indexadas. Esto es mentira, pero
1253
        // * as? quien pregunte no querr? generar el indice.
1254
        // * Esta por ver si interesa generar el indice para capas
1255
        // * HSQLDB, WFS, etc.
1256
        // */
1257
        //        if(!(source instanceof VectorialFileAdapter)){
1258
        //            return true;
1259
        //        }
1260
        //        if (!(source.getDriver() instanceof BoundedShapes)) {
1261
        //            return true;
1262
        //        }
1263
        //
1264
        //        if (getISpatialIndex() != null)
1265
        //            return true;
1266
        //        return false;
1267
        //    }
1268

    
1269
        public void setIsJoined(boolean hasJoin) {
1270
                bHasJoin = hasJoin;
1271
        }
1272

    
1273
        //    /**
1274
        //     * @return Returns the spatialIndex.
1275
        //     */
1276
        //    public ISpatialIndex getISpatialIndex() {
1277
        //        return spatialIndex;
1278
        //    }
1279
        //    /**
1280
        //     * Sets the spatial index. This could be useful if, for some
1281
        //     * reasons, you want to work with a distinct spatial index
1282
        //     * (for example, a spatial index which could makes nearest
1283
        //     * neighbour querys)
1284
        //     * @param spatialIndex
1285
        //     */
1286
        //    public void setISpatialIndex(ISpatialIndex spatialIndex){
1287
        //        this.spatialIndex = spatialIndex;
1288
        //    }
1289

    
1290
        public void setEditing(boolean b) throws StartEditionLayerException {
1291
                super.setEditing(b);
1292
                if (b){
1293
                        try {
1294
                                getFeatureStore().edit();
1295
                        } catch (ReadException e) {
1296
                                throw new StartEditionLayerException(getName(),e);
1297
                        } catch (DataException e) {
1298
                                throw new StartEditionLayerException(getName(),e);
1299
                        }
1300
                }
1301
                setSpatialCacheEnabled(b);
1302
                callEditionChanged(LayerEvent
1303
                                .createEditionChangedEvent(this, "edition"));
1304

    
1305
        }
1306

    
1307
        public void clearSpatialCache()
1308
        {
1309
                spatialCache.clearAll();
1310
        }
1311

    
1312
        public boolean isSpatialCacheEnabled() {
1313
                return spatialCacheEnabled;
1314
        }
1315

    
1316
        public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
1317
                this.spatialCacheEnabled = spatialCacheEnabled;
1318
        }
1319

    
1320
        public SpatialCache getSpatialCache() {
1321
                return spatialCache;
1322
        }
1323

    
1324
        /**
1325
         * Siempre es un numero mayor de 1000
1326
         * @param maxFeatures
1327
         */
1328
        public void setMaxFeaturesInEditionCache(int maxFeatures) {
1329
                if (maxFeatures > spatialCache.getMaxFeatures()) {
1330
                        spatialCache.setMaxFeatures(maxFeatures);
1331
                }
1332

    
1333
        }
1334

    
1335
        /**
1336
         * This method returns a boolean that is used by the FPopMenu
1337
         * to make visible the properties menu or not. It is visible by
1338
         * default, and if a later don't have to show this menu only
1339
         * has to override this method.
1340
         * @return
1341
         * If the properties menu is visible (or not)
1342
         */
1343
        public boolean isPropertiesMenuVisible(){
1344
                return true;
1345
        }
1346

    
1347
        public void reload() throws ReloadLayerException {
1348
                super.reload();
1349
                try {
1350
                        DataManager dataManager=DALLocator.getDataManager();
1351
                        DataStoreParameters storeParameters;
1352

    
1353
                        storeParameters = getFeatureStore().getParameters();
1354

    
1355
                        DataStore dataStore=dataManager.createStore(storeParameters);
1356
                        setDataStore(dataStore);
1357
                        getFeatureStore().refresh();
1358
                } catch (Exception e) {
1359
                        throw new ReloadLayerException(getName(),e);
1360
                }
1361
                //        try {
1362
                //            this.source.getDriver().reload();
1363
                //            if (this.getLegend() == null) {
1364
                //                if (this.getRecordset().getDriver() instanceof WithDefaultLegend) {
1365
                //                    WithDefaultLegend aux = (WithDefaultLegend) this.getRecordset().getDriver();
1366
                //                    this.setLegend((IVectorLegend) aux.getDefaultLegend());
1367
                //                    this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
1368
                //                } else {
1369
                //                    this.setLegend(LegendFactory.createSingleSymbolLegend(
1370
                //                            this.getShapeType()));
1371
                //                }
1372
                //            }
1373
                //
1374
                //        } catch (LegendLayerException e) {
1375
                //            this.setAvailable(false);
1376
                //            throw new ReloadLayerException(getName(),e);
1377
                //        } catch (ReadException e) {
1378
                //            this.setAvailable(false);
1379
                //            throw new ReloadLayerException(getName(),e);
1380
                //        }
1381

    
1382

    
1383
        }
1384

    
1385
        protected void setLoadSelection(XMLEntity xml) {
1386
                this.loadSelection = xml;
1387
        }
1388

    
1389
        protected void setLoadLegend(IVectorLegend legend) {
1390
                this.loadLegend = legend;
1391
        }
1392

    
1393
        protected void putLoadSelection() throws XMLException {
1394
                //        if (this.loadSelection == null) return;
1395
                //        try {
1396
                //            this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
1397
                //        } catch (ReadDriverException e) {
1398
                //            throw new XMLException(e);
1399
                //        }
1400
                //        this.loadSelection = null;
1401

    
1402
        }
1403
        protected void putLoadLegend() throws LegendLayerException {
1404
                if (this.loadLegend == null) {
1405
                        return;
1406
                }
1407
                this.setLegend(this.loadLegend);
1408
                this.loadLegend = null;
1409
        }
1410

    
1411
        protected void cleanLoadOptions() {
1412
                this.loadLegend = null;
1413
                this.loadSelection = null;
1414
        }
1415

    
1416
        public boolean isWritable() {
1417
                try {
1418
                        return getFeatureStore().allowWrite();
1419
                } catch (ReadException e) {
1420
                        e.printStackTrace();
1421
                }
1422
                return false;
1423
        }
1424

    
1425
        public FLayer cloneLayer() throws Exception {
1426
                FLyrVect clonedLayer = new FLyrVect();
1427
                clonedLayer.setDataStore(getDataStore());
1428
                if (isJoined()) {
1429
                        clonedLayer.setIsJoined(true);
1430
                }
1431
                clonedLayer.setVisible(isVisible());
1432
                //        clonedLayer.setISpatialIndex(getISpatialIndex());
1433
                clonedLayer.setName(getName());
1434
                clonedLayer.setCoordTrans(getCoordTrans());
1435

    
1436
                clonedLayer.setLegend((IVectorLegend)getLegend().cloneLegend());
1437

    
1438
                clonedLayer.setIsLabeled(isLabeled());
1439
                ILabelingStrategy labelingStrategy=getLabelingStrategy();
1440
        if (labelingStrategy!=null) {
1441
                        clonedLayer.setLabelingStrategy(labelingStrategy);
1442
                }
1443

    
1444
                return clonedLayer;
1445
        }
1446

    
1447

    
1448
        private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, double dpi, CartographicSupport csSym, Geometry geom, int[] xyCoords) {
1449
                return isOnePoint(graphicsTransform, viewPort, geom, xyCoords) && csSym.getCartographicSize(viewPort, dpi, geom) <= 1;
1450
        }
1451

    
1452
        private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, Geometry geom, int[] xyCoords) {
1453
                boolean onePoint = false;
1454
                int type=geom.getType();
1455
                if (type == Geometry.TYPES.NULL) {
1456
                        return false;
1457
                }
1458
                if (type!=Geometry.TYPES.POINT && type!=Geometry.TYPES.MULTIPOINT) {
1459

    
1460
                        Envelope geomBounds = geom.getEnvelope();
1461

    
1462
                        ICoordTrans ct = getCoordTrans();
1463

    
1464
                        // Se supone que la geometria ya esta reproyectada
1465
                        // if (ct!=null) {
1466
                        // // geomBounds = ct.getInverted().convert(geomBounds);
1467
                        // geomBounds = geomBounds.convert(ct);
1468
                        // }
1469

    
1470
                        double dist1Pixel = viewPort.getDist1pixel();
1471

    
1472
                        onePoint = (geomBounds.getLength(0)  <= dist1Pixel
1473
                                        && geomBounds.getLength(1) <= dist1Pixel);
1474

    
1475
                        if (onePoint) {
1476
                                // avoid out of range exceptions
1477
                                org.gvsig.fmap.geom.primitive.Point p;
1478
                                try {
1479
                                        p = geomManager.createPoint(geomBounds.getMinimum(0), geomBounds.getMinimum(1), SUBTYPES.GEOM2D);
1480
                                        p.transform(viewPort.getAffineTransform());
1481
                                        p.transform(graphicsTransform);
1482
                                        xyCoords[0] = (int) p.getX();
1483
                                        xyCoords[1] = (int) p.getY();
1484
                                } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
1485
                                        logger.error("Error creating a point", e);
1486
                                }
1487

    
1488
                        }
1489

    
1490
                }
1491
                return onePoint;
1492
        }
1493
        /*
1494
         * jaume. Stuff from ILabeled.
1495
         */
1496
        private boolean isLabeled;
1497
        protected ILabelingStrategy strategy;
1498

    
1499
        public boolean isLabeled() {
1500
                return isLabeled;
1501
        }
1502

    
1503
        public void setIsLabeled(boolean isLabeled) {
1504
                this.isLabeled = isLabeled;
1505
        }
1506

    
1507
        public ILabelingStrategy getLabelingStrategy() {
1508
                return strategy;
1509
        }
1510

    
1511
        public void setLabelingStrategy(ILabelingStrategy strategy) {
1512
                this.strategy = strategy;
1513
                try {
1514
                        strategy.setLayer(this);
1515
                } catch (ReadException e) {
1516
                        // TODO Auto-generated catch block
1517
                        e.printStackTrace();
1518
                }
1519

    
1520
        }
1521

    
1522
        public void drawLabels(BufferedImage image, Graphics2D g, ViewPort viewPort,
1523
                        Cancellable cancel, double scale, double dpi) throws ReadException {
1524
                if (strategy!=null && isWithinScale(scale)) {
1525
                        strategy.draw(image, g, viewPort, cancel, dpi);
1526
                }
1527
        }
1528

    
1529
        public void printLabels(Graphics2D g, ViewPort viewPort,
1530
                        Cancellable cancel, double scale,
1531
                        PrintRequestAttributeSet properties) throws ReadException {
1532
                if (strategy != null) {
1533
                        strategy.print(g, viewPort, cancel, properties);
1534
                }
1535
        }
1536
        //M?todos para el uso de HyperLinks en capas FLyerVect
1537

    
1538
        /**
1539
         * Return true, because a Vectorial Layer supports HyperLink
1540
         */
1541
        public boolean allowLinks()
1542
        {
1543
                return true;
1544
        }
1545

    
1546
        /**
1547
         * Returns an instance of AbstractLinkProperties that contains the information
1548
         * of the HyperLink
1549
         * @return Abstra
1550
         */
1551
        public AbstractLinkProperties getLinkProperties()
1552
        {
1553
                return linkProperties;
1554
        }
1555

    
1556
        /**
1557
         * Provides an array with URIs. Returns one URI by geometry that includes the point
1558
         * in its own geometry limits with a allowed tolerance.
1559
         * @param layer, the layer
1560
         * @param point, the point to check that is contained or not in the geometries in the layer
1561
         * @param tolerance, the tolerance allowed. Allowed margin of error to detect if the  point
1562
         *                 is contained in some geometries of the layer
1563
         * @return
1564
         * @throws ReadException
1565
         * @throws BehaviorException
1566
         */
1567
        public URI[] getLink(Point2D point, double tolerance) throws ReadException
1568
        {
1569
                //return linkProperties.getLink(this)
1570
                return linkProperties.getLink(this,point,tolerance);
1571
        }
1572

    
1573
        public void load() throws LoadLayerException {
1574
                super.load();
1575
        }
1576

    
1577
        public FeatureStore getFeatureStore() throws ReadException {
1578
                return (FeatureStore)getDataStore();
1579
        }
1580

    
1581
        public FeatureSet queryByPoint(Point2D mapPoint, double tol, FeatureType featureType) throws DataException {
1582
                GeometryManager manager = GeometryLocator.getGeometryManager();
1583
                org.gvsig.fmap.geom.primitive.Point center;
1584
                try {
1585
                        center = (org.gvsig.fmap.geom.primitive.Point)manager.create(TYPES.POINT, SUBTYPES.GEOM2D);
1586
                        center.setX(mapPoint.getX());
1587
                        center.setY(mapPoint.getY());
1588
                        Circle circle = (Circle)manager.create(TYPES.CIRCLE, SUBTYPES.GEOM2D);
1589
                        circle.setPoints(center, tol);
1590
                        return queryByGeometry(circle, featureType);
1591
                } catch (org.gvsig.fmap.geom.exception.CreateGeometryException e) {
1592
                        throw new CreateGeometryException(TYPES.CIRCLE, SUBTYPES.GEOM2D, e);
1593
                }
1594
        }
1595

    
1596

    
1597
        public FeatureSet queryByGeometry(Geometry geom, FeatureType featureType) throws DataException {
1598
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
1599
                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
1600
                featureQuery.setFeatureType(featureType);
1601
                IntersectsGeometryEvaluator iee=new IntersectsGeometryEvaluator(geom,getMapContext().getViewPort().getProjection(),featureStore.getDefaultFeatureType(),geomName);
1602
                featureQuery.setFilter(iee);
1603
                return getFeatureStore().getFeatureSet(featureQuery);
1604

    
1605
        }
1606

    
1607
        public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType)
1608
        throws DataException {
1609
                return queryByEnvelope(envelope, featureType, null);
1610
        }
1611

    
1612
        public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType, String[] names)
1613
        throws DataException {
1614
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
1615
                if (names==null){
1616
                        featureQuery.setFeatureType(featureType);
1617
                }else{
1618
                        featureQuery.setAttributeNames(names);
1619
                        featureQuery.setFeatureTypeId(featureType.getId());
1620
                }
1621
                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
1622
                ContainsEnvelopeEvaluator iee=new ContainsEnvelopeEvaluator(envelope,getMapContext().getViewPort().getProjection(),featureStore.getDefaultFeatureType(),geomName);
1623
                featureQuery.setFilter(iee);
1624
                return getFeatureStore().getFeatureSet(featureQuery);
1625

    
1626
        }
1627
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws LoadLayerException, DataException {
1628
                Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p);
1629
                FeatureSet featureCollection=null;
1630
                try {
1631
                        featureCollection = queryByPoint(pReal, tolerance, getFeatureStore().getDefaultFeatureType());
1632
                } catch (DataException e) {
1633
                        // TODO Auto-generated catch block
1634
                        e.printStackTrace();
1635
                }
1636
                VectorialXMLItem[] item = new VectorialXMLItem[1];
1637
                item[0] = new VectorialXMLItem(featureCollection, this);
1638

    
1639
                return item;
1640
        }
1641

    
1642
        public void legendCleared(LegendClearEvent event) {
1643
                // this.updateDrawVersion(); TODO
1644
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
1645
                                legend, legend);
1646
                this.callLegendChanged(e);
1647
        }
1648

    
1649
        public boolean symbolChanged(SymbolLegendEvent e) {
1650
                LegendChangedEvent ev = LegendChangedEvent.createLegendChangedEvent(
1651
                                legend, legend);
1652
                this.callLegendChanged(ev);
1653
                return true;
1654
        }
1655

    
1656
        public void update(Observable observable, Object notification) {
1657
                if (observable.equals(this.featureStore)) {
1658
                        if (notification instanceof FeatureStoreNotification) {
1659
                                FeatureStoreNotification event = (FeatureStoreNotification) notification;
1660
                                if (event.getType() == FeatureStoreNotification.AFTER_CANCELEDITING
1661
                                                || event.getType() == FeatureStoreNotification.AFTER_DELETE
1662
                                                || event.getType() == FeatureStoreNotification.AFTER_UNDO
1663
                                                || event.getType() == FeatureStoreNotification.AFTER_REDO
1664
                                                || event.getType() == FeatureStoreNotification.AFTER_REFRESH
1665
                                                || event.getType() == FeatureStoreNotification.AFTER_UPDATE
1666
                                                || event.getType() == FeatureStoreNotification.AFTER_UPDATE_TYPE
1667
                                                || event.getType() == FeatureStoreNotification.SELECTION_CHANGE
1668
                                                || event.getType() == FeatureStoreNotification.AFTER_INSERT) {
1669
                                        this.updateDrawVersion();
1670

    
1671
                                } else if (event.getType() == FeatureStoreNotification.AFTER_FINISHEDITING
1672
                                                || event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE
1673
                                                || event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
1674
                                        this.setAvailable(false);
1675

    
1676
                                        //                                        try {
1677
                                        //                                                reload();
1678
                                        //                                        } catch (ReloadLayerException e) {
1679
                                        //                                                this.setAvailable(false);
1680
                                        //                                        }
1681
                                }
1682

    
1683
                        }
1684

    
1685
                }
1686

    
1687
        }
1688

    
1689
        /*
1690
         * (non-Javadoc)
1691
         *
1692
         * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1693
         */
1694
        public Set getMetadataChildren() {
1695
                Set ret = new TreeSet();
1696
                ret.add(this.featureStore);
1697
                return ret;
1698
        }
1699

    
1700
        /*
1701
         * (non-Javadoc)
1702
         *
1703
         * @see org.gvsig.metadata.Metadata#getMetadataID()
1704
         */
1705
        public Object getMetadataID() {
1706
                return "Layer(" + this.getName() + "):"
1707
                + this.featureStore.getMetadataID();
1708
        }
1709

    
1710
        /*
1711
         * (non-Javadoc)
1712
         *
1713
         * @see org.gvsig.metadata.Metadata#getMetadataName()
1714
         */
1715
        public String getMetadataName() {
1716
                return "Layer '" + this.getName() + "':"
1717
                + this.featureStore.getMetadataName();
1718
        }
1719
        public String getTypeVectorLayer() throws DataException {
1720
                // FIXME Esto deberia de pedirse a FType!!!!
1721
                String typeString="";
1722
                int typeShape = this.getShapeType();
1723
                FeatureStore fs = this.getFeatureStore();
1724

    
1725
                Geometry geom = null;
1726
                FeatureSet set=fs.getFeatureSet();
1727
                DisposableIterator iter = set.fastIterator();
1728
                if (iter.hasNext()) {
1729
                        Feature feature = (Feature) iter.next();
1730
                        geom = feature.getDefaultGeometry();
1731
                }
1732
                iter.dispose();
1733
                set.dispose();
1734
                if (Geometry.TYPES.GEOMETRY==typeShape){
1735
                        if (geom != null) {
1736
                                int subtype = geom.getGeometryType().getSubType();
1737
                                if (subtype == SUBTYPES.GEOM2D){
1738
                                        typeString="Geometries2D";
1739
                                }else if (subtype == SUBTYPES.GEOM2DZ){
1740
                                        typeString="Geometries2DZ";
1741
                                }else if (subtype == SUBTYPES.GEOM3D){
1742
                                        typeString="Geometries3D";
1743
                                }else if (subtype == SUBTYPES.GEOM2DM){
1744
                                        typeString="Geometries2DM";
1745
                                }
1746
                        }
1747
                }else{
1748
                        if (geom != null) {
1749
                                int type = geom.getType();
1750
                                int subType = geom.getGeometryType().getSubType();
1751
                                if (Geometry.TYPES.POINT == type){
1752
                                        typeString="Point";
1753
                                } else if (Geometry.TYPES.SURFACE == type){
1754
                                        typeString="Line";
1755
                                } else if (Geometry.TYPES.SOLID == type){
1756
                                        typeString="Polygon";
1757
                                } else if (Geometry.TYPES.MULTIPOINT == type){
1758
                                        typeString="MultiPint";
1759
                                }
1760
                                if (Geometry.SUBTYPES.GEOM2D  == subType){
1761
                                        typeString=typeString + "2D";
1762
                                } else if (Geometry.SUBTYPES.GEOM2DZ  == subType){
1763
                                        typeString=typeString + "2DZ";
1764
                                } else if (Geometry.SUBTYPES.GEOM3D  == subType){
1765
                                        typeString=typeString + "3D";
1766
                                } else if (Geometry.SUBTYPES.GEOM2DM  == subType){
1767
                                        typeString=typeString + "2DM";
1768
                                }
1769

    
1770
                                return typeString;
1771
                        }
1772
                }
1773
                return "";
1774
        }
1775

    
1776
}