Statistics
| Revision:

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

History | View | Annotate | Download (54.7 KB)

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

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

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

    
56
import org.cresques.cts.ICoordTrans;
57
import org.gvsig.fmap.dal.DALLocator;
58
import org.gvsig.fmap.dal.DataManager;
59
import org.gvsig.fmap.dal.DataStore;
60
import org.gvsig.fmap.dal.DataStoreParameters;
61
import org.gvsig.fmap.dal.exception.DataException;
62
import org.gvsig.fmap.dal.exception.ReadException;
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.geom.Geometry;
71
import org.gvsig.fmap.geom.GeometryManager;
72
import org.gvsig.fmap.geom.operation.DrawInts;
73
import org.gvsig.fmap.geom.operation.DrawOperationContext;
74
import org.gvsig.fmap.geom.operation.GeometryOperationException;
75
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
76
import org.gvsig.fmap.geom.primitive.DefaultEnvelope;
77
import org.gvsig.fmap.geom.primitive.Envelope;
78
import org.gvsig.fmap.mapcontext.MapContext;
79
import org.gvsig.fmap.mapcontext.ViewPort;
80
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
81
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
82
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
83
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
84
import org.gvsig.fmap.mapcontext.exceptions.XMLLayerException;
85
import org.gvsig.fmap.mapcontext.layers.AbstractLinkProperties;
86
import org.gvsig.fmap.mapcontext.layers.FLayer;
87
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
88
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
89
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
90
import org.gvsig.fmap.mapcontext.layers.operations.ClassifiableVectorial;
91
import org.gvsig.fmap.mapcontext.layers.operations.ILabelable;
92
import org.gvsig.fmap.mapcontext.layers.operations.InfoByPoint;
93
import org.gvsig.fmap.mapcontext.layers.operations.SingleLayer;
94
import org.gvsig.fmap.mapcontext.layers.operations.VectorialXMLItem;
95
import org.gvsig.fmap.mapcontext.layers.operations.XMLItem;
96
import org.gvsig.fmap.mapcontext.rendering.legend.IClassifiedVectorLegend;
97
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
98
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
99
import org.gvsig.fmap.mapcontext.rendering.legend.LegendFactory;
100
import org.gvsig.fmap.mapcontext.rendering.legend.SingleSymbolLegend;
101
import org.gvsig.fmap.mapcontext.rendering.legend.SymbolLegendEvent;
102
import org.gvsig.fmap.mapcontext.rendering.legend.XMLLegendException;
103
import org.gvsig.fmap.mapcontext.rendering.legend.ZSort;
104
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
105
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
106
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendContentsChangedListener;
107
import org.gvsig.fmap.mapcontext.rendering.legend.styling.AttrInTableLabelingStrategy;
108
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
109
import org.gvsig.fmap.mapcontext.rendering.legend.styling.LabelingFactory;
110
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
111
import org.gvsig.fmap.mapcontext.rendering.symbols.FSymbol;
112
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
113
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
114
import org.gvsig.tools.ToolsLocator;
115
import org.gvsig.tools.dynobject.exception.DynMethodException;
116
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
117
import org.gvsig.tools.exception.BaseException;
118
import org.gvsig.tools.observer.Observable;
119
import org.gvsig.tools.observer.Observer;
120
import org.gvsig.tools.persistence.PersistenceException;
121
import org.gvsig.tools.persistence.PersistentState;
122
import org.gvsig.tools.persistence.xmlentity.XMLEntityManager;
123
import org.gvsig.tools.persistence.xmlentity.XMLEntityState;
124
import org.gvsig.tools.task.Cancellable;
125
import org.slf4j.LoggerFactory;
126

    
127
import com.iver.utiles.NotExistInXMLEntity;
128
import com.iver.utiles.XMLEntity;
129
import com.iver.utiles.XMLException;
130

    
131
/**
132
 * Capa b?sica Vectorial.
133
 *
134
 * @author Fernando Gonz?lez Cort?s
135
 */
136

    
137
// TODO Cuando no sea para pruebas debe no ser public
138
public class FLyrVect extends FLyrDefault implements ILabelable, InfoByPoint,
139
ClassifiableVectorial, SingleLayer, LegendContentsChangedListener,
140
Observer {
141
        final static private org.slf4j.Logger logger = LoggerFactory.getLogger(FLyrVect.class);
142
        /** Leyenda de la capa vectorial */
143
        private IVectorLegend legend;
144
        private int typeShape = -1;
145
        private FeatureStore featureStore=null;
146
        private SpatialCache spatialCache = new SpatialCache();
147
        private boolean spatialCacheEnabled = false;
148

    
149
        /**
150
         * An implementation of gvSIG spatial index
151
         */
152
        //    protected ISpatialIndex spatialIndex = null;
153
        private boolean bHasJoin = false;
154
        private XMLEntity orgXMLEntity = null;
155
        private XMLEntity loadSelection = null;
156
        private IVectorLegend loadLegend = null;
157

    
158
        //Lo a?ado. Caracter?sticas de HyperEnlace (LINK)
159
        private FLyrVectLinkProperties linkProperties=new FLyrVectLinkProperties();
160

    
161
        /**
162
         * Devuelve el VectorialAdapater de la capa.
163
         *
164
         * @return VectorialAdapter.
165
         */
166
        public DataStore getDataStore() {
167
                if (!this.isAvailable()) {
168
                        return null;
169
                }
170
                return featureStore;
171
        }
172

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

    
227
        /**
228
         * Checks if it has associated an external spatial index
229
         * (an spatial index file).
230
         *
231
         * It looks for it in main file path, or in temp system path.
232
         * If main file is rivers.shp, it looks for a file called
233
         * rivers.shp.qix.
234

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

    
277
                featureStore = (FeatureStore)dataStore;
278

    
279
                ILegend legend = null;
280
                try {
281
                        legend = (ILegend) dataStore.invokeDynMethod("defaultLegend", null);
282

    
283
                } catch (DynMethodNotSupportedException e1) {
284
                        try {
285
                                legend = LegendFactory.createSingleSymbolLegend(this
286
                                                .getShapeType());
287
                        } catch (ReadException e) {
288
                                throw new LoadLayerException(this.getName(), e);
289
                        }
290

    
291
                } catch (DynMethodException e1) {
292
                        throw new LoadLayerException(this.getName(), e1);
293
                }
294
                this.setLegend((IVectorLegend) legend);
295

    
296

    
297

    
298

    
299
                ILabelingStrategy labeler = null;
300
                try {
301
                        labeler = (ILabelingStrategy) dataStore.invokeDynMethod(
302
                                        "defaultLabelingStrategy", null);
303
                } catch (DynMethodNotSupportedException e1) {
304
                        labeler = null;
305
                } catch (DynMethodException e1) {
306
                        throw new LoadLayerException(this.getName(), e1);
307
                }
308

    
309
                if (labeler != null) {
310
                        try {
311
                                labeler.setLayer(this);
312
                        } catch (ReadException e) {
313
                                throw new LoadLayerException(this.getName(), e);
314
                        }
315
                        this.setLabelingStrategy(labeler);
316
                        this.setIsLabeled(true); // TODO: ac? no s'hauria de detectar si t? etiquetes?????
317
                }
318

    
319
                this.delegate(dataStore);
320

    
321
                dataStore.addObserver(this);
322

    
323
                // azabala: we check if this layer could have a file spatial index
324
                // and load it if it exists
325
                //        loadSpatialIndex();
326
        }
327

    
328
        public Envelope getFullEnvelope() throws ReadException {
329
                Envelope rAux;
330
                try {
331
                        rAux = getFeatureStore().getEnvelope();
332
                } catch (BaseException e) {
333
                        throw new ReadException(getName(),e);
334
                }
335
                // Si existe reproyecci?n, reproyectar el extent
336
                ICoordTrans ct = getCoordTrans();
337
                if (ct != null) {
338
                        Point2D pt1 = new Point2D.Double(rAux.getMinimum(0), rAux.getMinimum(1));
339
                        Point2D pt2 = new Point2D.Double(rAux.getMaximum(0), rAux.getMaximum(1));
340
                        pt1 = ct.convert(pt1, null);
341
                        pt2 = ct.convert(pt2, null);
342
                        rAux = new DefaultEnvelope(2,new double[]{pt1.getX(),pt1.getY()},new double[]{pt2.getX(),pt2.getY()});//new Rectangle2D.Double();
343
                }
344
                //Esto es para cuando se crea una capa nueva con el fullExtent de ancho y alto 0.
345
                if (rAux.getMaximum(0)-rAux.getMinimum(0)==0 && rAux.getMaximum(1)-rAux.getMinimum(1)==0) {
346
                        rAux=new DefaultEnvelope(2,new double[]{0,0},new double[]{100,100});
347
                }
348
                return rAux;
349

    
350
        }
351

    
352
        /**
353
         * Draws using IFeatureIterator. This method will replace the old draw(...) one.
354
         * @autor jaume dominguez faus - jaume.dominguez@iver.es
355
         * @param image
356
         * @param g
357
         * @param viewPort
358
         * @param cancel
359
         * @param scale
360
         * @throws ReadDriverException
361
         */
362
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
363
                        Cancellable cancel, double scale) throws ReadException {
364
                if (!this.isWithinScale(scale)) {
365
                        return;
366
                }
367
                if (cancel.isCanceled()) {
368
                        return;
369
                }
370
                boolean containsAll = false;
371
                Envelope viewPortEnvelope =viewPort.getAdjustedExtent();
372
                Envelope myEnvelope = this.getFullEnvelope();
373
                if (!viewPortEnvelope.contains(myEnvelope)){
374
                        if (!viewPortEnvelope.intersects(myEnvelope)){
375
                                return;
376
                        }
377
                } else {
378
                        containsAll = true;
379
                }
380
                double dpi = MapContext.getScreenDPI();
381
                DrawOperationContext doc=new DrawOperationContext();
382
                doc.setViewPort(viewPort);
383
                doc.setScale(scale);
384
                doc.setCancellable(cancel);
385
                doc.setDPI(dpi);
386
                boolean bDrawShapes = true;
387
                if (legend instanceof SingleSymbolLegend) {
388
                        bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
389
                }
390
                Point2D offset = viewPort.getOffset();
391

    
392

    
393

    
394
                if (bDrawShapes) {
395
                        if (cancel.isCanceled()) {
396
                                return;
397
                        }
398
                        boolean cacheFeatures = isSpatialCacheEnabled();
399
                        SpatialCache cache = null;
400
                        if (cacheFeatures) {
401
                                getSpatialCache().clearAll();
402
                                cache = getSpatialCache();
403
                        }
404

    
405
                        try {
406

    
407
                                FeatureSelection selection = this.featureStore
408
                                .getFeatureSelection();
409

    
410
                                FeatureStore featureStore=getFeatureStore();
411
                                String[] fieldNames=null;
412
                                if (legend instanceof IClassifiedVectorLegend){
413
                                        String[] classified=((IClassifiedVectorLegend)legend).getClassifyingFieldNames();
414
                                        fieldNames=new String[classified.length+1];
415
                                        fieldNames[0]=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
416
                                        for (int i = 1; i < fieldNames.length; i++) {
417
                                                fieldNames[i]=classified[i-1];
418
                                        }
419

    
420
                                }else{
421
                                        fieldNames=new String[]{featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName()};
422
                                }
423
                                FeatureSet featureSet=null;
424
                                FeatureQuery featureQuery=featureStore.createFeatureQuery();
425
                                featureQuery.setScale(scale);
426
                                featureQuery.setAttributeNames(fieldNames);
427
                                if (!containsAll) {
428
                                        InEnvelopeEvaluator iee = new InEnvelopeEvaluator(
429
                                                        viewPortEnvelope,
430
                                                        viewPort.getProjection(),
431
                                                        featureStore.getDefaultFeatureType(),
432
                                                        featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName());
433
                                        featureQuery.setFilter(iee);
434

    
435
                                }
436
                                featureSet = featureStore.getFeatureSet(featureQuery);
437
                                Iterator it = featureSet.fastIterator();
438

    
439
                                ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
440

    
441
                                boolean bSymbolLevelError = false;
442

    
443
                                // if layer has map levels it will use a ZSort
444
                                boolean useZSort = zSort != null && zSort.isUsingZSort();
445

    
446
                                // -- visual FX stuff
447
                                long time = System.currentTimeMillis();
448
                                BufferedImage virtualBim;
449
                                Graphics2D virtualGraphics;
450

    
451
                                if (cancel.isCanceled()) {
452
                                        return;
453
                                }
454

    
455
                                // render temporary map each screenRefreshRate milliseconds;
456
                                int screenRefreshDelay = (int) ((1D/MapContext.getDrawFrameRate())*3*1000);
457
                                BufferedImage[] imageLevels = null;
458
                                Graphics2D[] graphics = null;
459
                                if (useZSort) {
460
                                        imageLevels = new BufferedImage[zSort.getLevelCount()];
461
                                        graphics = new Graphics2D[imageLevels.length];
462
                                        for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
463
                                                imageLevels[i] = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
464
                                                graphics[i] = imageLevels[i].createGraphics();
465
                                                graphics[i].setTransform(g.getTransform());
466
                                                graphics[i].setRenderingHints(g.getRenderingHints());
467
                                        }
468
                                }
469
                                // -- end visual FX stuff
470

    
471
                                // Iteration over each feature
472
                                while (it.hasNext()) {
473
                                        if (cancel.isCanceled()) {
474
                                                return;
475
                                        }
476
                                        Feature feat = (Feature) it.next();
477

    
478
                                        Geometry geom = feat.getDefaultGeometry();
479

    
480
                                        if (cacheFeatures) {
481
                                                if (cache.getMaxFeatures() >= cache.size()) {
482
                                                        // already reprojected
483
                                                        cache.insert(geom.getEnvelope(), geom);
484
                                                }
485
                                        }
486

    
487
                                        // retrieve the symbol associated to such feature
488
                                        ISymbol sym = legend.getSymbolByFeature(feat);
489
                                        if (selection.isSelected(feat)) {
490
                                                sym=sym.getSymbolForSelection();
491
                                        }
492
                                        if (sym == null) {
493
                                                continue;
494
                                        }
495

    
496
                                        // Check if this symbol is sized with CartographicSupport
497
                                        CartographicSupport csSym = null;
498
                                        int symbolType = sym.getSymbolType();
499
                                        boolean bDrawCartographicSupport = false;
500

    
501
                                        if (   symbolType == Geometry.TYPES.POINT
502
                                                        || symbolType == Geometry.TYPES.CURVE
503
                                                        || sym instanceof CartographicSupport) {
504

    
505
                                                // patch
506
                                                if (!sym.getClass().equals(FSymbol.class)) {
507
                                                        csSym = (CartographicSupport) sym;
508
                                                        bDrawCartographicSupport = (csSym.getUnit() != -1);
509
                                                }
510
                                        }
511

    
512
                                        int x = -1;
513
                                        int y = -1;
514
                                        int[] xyCoords = new int[2];
515

    
516
                                        // Check if size is a pixel
517
                                        boolean onePoint = bDrawCartographicSupport ?
518
                                                        isOnePoint(g.getTransform(), viewPort, MapContext.getScreenDPI(), csSym, geom, xyCoords) :
519
                                                                isOnePoint(g.getTransform(), viewPort, geom, xyCoords);
520

    
521
                                                        // Avoid out of bounds exceptions
522
                                                        if (onePoint) {
523
                                                                x = xyCoords[0];
524
                                                                y = xyCoords[1];
525
                                                                if (x<0 || y<0 || x>= viewPort.getImageWidth() || y>=viewPort.getImageHeight()) {
526
                                                                        continue;
527
                                                                }
528
                                                        }
529

    
530
                                                        if (cancel.isCanceled()) {
531
                                                                return;
532
                                                        }
533

    
534
                                                        if (useZSort) {
535
                                                                // Check if this symbol is a multilayer
536
                                                                if (sym instanceof IMultiLayerSymbol) {
537
                                                                        // if so, treat each of its layers as a single symbol
538
                                                                        // in its corresponding map level
539
                                                                        IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
540
                                                                        for (int i = 0; !cancel.isCanceled() && i < mlSym.getLayerCount(); i++) {
541
                                                                                ISymbol mySym = mlSym.getLayer(i);
542
                                                                                int symbolLevel = zSort.getSymbolLevel(mySym);
543

    
544
                                                                                if (symbolLevel == -1) {
545
                                                                                        /* an error occured when managing symbol levels
546
                                                                                         * some of the legend changed events regarding the
547
                                                                                         * symbols did not finish satisfactory and the legend
548
                                                                                         * is now inconsistent. For this drawing, it will finish
549
                                                                                         * as it was at the bottom (level 0) but, when done, the
550
                                                                                         * ZSort will be reset to avoid app crashes. This is
551
                                                                                         * a bug that has to be fixed.
552
                                                                                         */
553
                                                                                        bSymbolLevelError = true;
554
                                                                                        symbolLevel=0;
555
                                                                                }
556

    
557
                                                                                if (onePoint) {
558
                                                                                        if (x<0 || y<0 || x>= imageLevels[symbolLevel].getWidth() || y>=imageLevels[symbolLevel].getHeight()) {
559
                                                                                                continue;
560
                                                                                        }
561
                                                                                        imageLevels[symbolLevel].setRGB(x, y, mySym.getOnePointRgb());
562
                                                                                } else {
563
                                                                                        if (!bDrawCartographicSupport) {
564
                                                                                                doc.setGraphics(graphics[symbolLevel]);
565
                                                                                                doc.setSymbol(mySym);
566
                                                                                                geom.invokeOperation(DrawInts.CODE,doc);
567
                                                                                        } else {
568
                                                                                                doc.setGraphics(graphics[symbolLevel]);
569
                                                                                                doc.setSymbol(mySym);
570
                                                                                                geom.invokeOperation(DrawInts.CODE,doc);
571
                                                                                        }
572
                                                                                }
573
                                                                        }
574
                                                                } else {
575
                                                                        // else, just draw the symbol in its level
576
                                                                        if (!bDrawCartographicSupport) {
577
                                                                                doc.setGraphics(graphics[zSort.getSymbolLevel(sym)]);
578
                                                                                doc.setSymbol(sym);
579
                                                                                geom.invokeOperation(DrawInts.CODE,doc);
580
                                                                        } else {
581
                                                                                doc.setGraphics(graphics[zSort.getSymbolLevel(sym)]);
582
                                                                                doc.setSymbol((ISymbol)csSym);
583
                                                                                geom.invokeOperation(DrawInts.CODE,doc);
584
                                                                        }
585
                                                                }
586

    
587
                                                                // -- visual FX stuff
588
                                                                // Cuando el offset!=0 se est? dibujando sobre el Layout y por tanto no tiene que ejecutar el siguiente c?digo.
589
                                                                if (offset.getX()==0 && offset.getY()==0) {
590
                                                                        if ((System.currentTimeMillis() - time) > screenRefreshDelay) {
591
                                                                                virtualBim = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_ARGB);
592
                                                                                virtualGraphics = virtualBim.createGraphics();
593
                                                                                virtualGraphics.drawImage(image,0,0, null);
594
                                                                                for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
595
                                                                                        virtualGraphics.drawImage(imageLevels[i],0,0, null);
596
                                                                                }
597
                                                                                g.clearRect(0, 0, image.getWidth(), image.getHeight());
598
                                                                                g.drawImage(virtualBim, 0, 0, null);
599
                                                                                time = System.currentTimeMillis();
600
                                                                        }
601
                                                                        // -- end visual FX stuff
602
                                                                }
603

    
604
                                                        } else {
605
                                                                // no ZSort, so there is only a map level, symbols are
606
                                                                // just drawn.
607
                                                                if (onePoint) {
608
                                                                        if (x<0 || y<0 || x>= image.getWidth() || y>=image.getHeight()) {
609
                                                                                continue;
610
                                                                        }
611
                                                                        image.setRGB(x, y, sym.getOnePointRgb());
612
                                                                } else {
613

    
614
                                                                        if (!bDrawCartographicSupport) {
615
                                                                                doc.setGraphics(g);
616
                                                                                doc.setSymbol(sym);
617
                                                                                geom.invokeOperation(DrawInts.CODE,doc);
618
                                                                        } else {
619
                                                                                doc.setGraphics(g);
620
                                                                                doc.setSymbol((ISymbol)csSym);
621
                                                                                geom.invokeOperation(DrawInts.CODE,doc);
622
                                                                        }
623
                                                                }
624
                                                        }
625
                                }
626

    
627
                                if (useZSort) {
628
                                        g.drawImage(image, 0, 0, null);
629
                                        g.translate(offset.getX(), offset.getY());
630
                                        for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
631
                                                g.drawImage(imageLevels[i],0,0, null);
632
                                                imageLevels[i] = null;
633
                                                graphics[i] = null;
634
                                        }
635
                                        g.translate(-offset.getX(), -offset.getY());
636
                                        imageLevels = null;
637
                                        graphics = null;
638
                                }
639
                                //                            it.closeIterator();
640
                                it=null;
641
                                featureSet.dispose();
642

    
643
                                if (bSymbolLevelError) {
644
                                        ((IVectorLegend) getLegend()).setZSort(null);
645
                                }
646

    
647
                        } catch (ReadException e) {
648
                                this.setVisible(false);
649
                                this.setActive(false);
650
                                throw e;
651
                        } catch (GeometryOperationNotSupportedException e) {
652
                                this.setVisible(false);
653
                                this.setActive(false);
654
                                throw new ReadException(getName(),e);
655
                        } catch (GeometryOperationException e) {
656
                                this.setVisible(false);
657
                                this.setActive(false);
658
                                throw new ReadException(getName(),e);
659
                        } catch (BaseException e) {
660
                                this.setVisible(false);
661
                                this.setActive(false);
662
                                throw new ReadException(getName(),e);
663
                        }
664

    
665

    
666
                }
667
        }
668
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
669
                        double scale, PrintRequestAttributeSet properties) throws ReadException {
670
                // TEST METHOD
671
                boolean bDrawShapes = true;
672
                if (legend instanceof SingleSymbolLegend) {
673
                        bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
674
                }
675
                if (bDrawShapes) {
676
                        try {
677
                                double dpi = 72;
678

    
679
                                PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
680
                                if (resolution.equals(PrintQuality.NORMAL)){
681
                                        dpi = 300;
682
                                } else if (resolution.equals(PrintQuality.HIGH)){
683
                                        dpi = 600;
684
                                } else if (resolution.equals(PrintQuality.DRAFT)){
685
                                        dpi = 72;
686
                                }
687
                                ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
688

    
689
                                // if layer has map levels it will use a ZSort
690
                                boolean useZSort = zSort != null && zSort.isUsingZSort();
691

    
692

    
693
                                int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1;
694
                                for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) {
695
                                        // Get the iterator over the visible features
696
                                        FeatureStore featureStore=getFeatureStore();
697
                                        // Get the iterator over the visible features
698
                                        //                                String featureFilter = null;
699
                                        //
700
                                        //                                if (!viewPort.getAdjustedExtent().contains((Envelope)featureStore.getMetadata().get("extent"))) {
701
                                        //                                            featureFilter=this.getDataStoreFilterForGeomerty(
702
                                        //                                                    viewPort.getAdjustedExtent().getGeometry(),
703
                                        //                                                    featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName(),
704
                                        //                                                    null);
705
                                        //                                    }
706
                                        String[] fieldNames=null;
707
                                        if (legend instanceof IClassifiedVectorLegend){
708
                                                String[] classified=((IClassifiedVectorLegend)legend).getClassifyingFieldNames();
709
                                                fieldNames=new String[classified.length+1];
710
                                                fieldNames[0]=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
711
                                                for (int i = 1; i < fieldNames.length; i++) {
712
                                                        fieldNames[i]=classified[i-1];
713
                                                }
714

    
715
                                        }else{
716
                                                fieldNames=new String[]{featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName()};
717
                                        }
718

    
719

    
720
                                        FeatureSet featureCollection=null;
721
                                        FeatureQuery featureQuery=featureStore.createFeatureQuery();
722
                                        featureQuery.setAttributeNames(fieldNames);
723
                                        featureQuery.setScale(scale);
724
                                        //                                ??SQLJEPEvaluator evaluator=new SQLJEPEvaluator(featureFilter);
725
                                        InEnvelopeEvaluator iee=new InEnvelopeEvaluator(viewPort.getAdjustedExtent(),viewPort.getProjection(),featureStore.getDefaultFeatureType(),featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName());
726
                                        featureQuery.setFilter(iee);
727
                                        featureCollection = featureStore.getFeatureSet(featureQuery);                               Iterator it = featureCollection.iterator();
728

    
729
                                        // Iteration over each feature
730
                                        while ( !cancel.isCanceled() && it.hasNext()) {
731
                                                Feature feat = (Feature)it.next();
732
                                                Geometry geom = feat.getDefaultGeometry();
733

    
734
                                                // retreive the symbol associated to such feature
735
                                                ISymbol sym = legend.getSymbolByFeature(feat);
736

    
737
                                                if (useZSort) {
738
                                                        // Check if this symbol is a multilayer
739
                                                        if (sym instanceof IMultiLayerSymbol) {
740
                                                                // if so, get the layer corresponding to the current
741
                                                                // level. If none, continue to next iteration
742
                                                                IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
743
                                                                for (int i = 0; i < mlSym.getLayerCount(); i++) {
744
                                                                        ISymbol mySym = mlSym.getLayer(i);
745
                                                                        if (zSort.getSymbolLevel(mySym) == mapPass) {
746
                                                                                sym = mySym;
747
                                                                                break;
748
                                                                        }
749
                                                                        System.out.println("avoided layer "+i+"of symbol '"+mlSym.getDescription()+"' (pass "+mapPass+")");
750
                                                                }
751

    
752
                                                                if (sym == null) {
753
                                                                        continue;
754
                                                                }
755
                                                        } else {
756
                                                                // else, just draw the symbol in its level
757
                                                                if (zSort.getSymbolLevel(sym) != mapPass) {
758
                                                                        System.out.println("avoided single layer symbol '"+sym.getDescription()+"' (pass "+mapPass+")");
759
                                                                        continue;
760
                                                                }
761
                                                        }
762
                                                }
763

    
764
                                                // Check if this symbol is sized with CartographicSupport
765
                                                CartographicSupport csSym = null;
766
                                                int symbolType = sym.getSymbolType();
767
                                                boolean bDrawCartographicSupport = false;
768

    
769
                                                if (   symbolType == Geometry.TYPES.POINT
770
                                                                || symbolType == Geometry.TYPES.CURVE
771
                                                                || sym instanceof CartographicSupport) {
772

    
773
                                                        csSym = (CartographicSupport) sym;
774
                                                        bDrawCartographicSupport = (csSym.getUnit() != -1);
775
                                                }
776

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

    
779
                                                if (!bDrawCartographicSupport) {
780
                                                        DrawOperationContext doc=new DrawOperationContext();
781
                                                        doc.setGraphics(g);
782
                                                        doc.setViewPort(viewPort);
783
                                                        doc.setSymbol(sym);
784
                                                        doc.setCancellable(cancel);
785
                                                        geom.invokeOperation(DrawInts.CODE,doc);
786
                                                } else {
787
                                                        DrawOperationContext doc=new DrawOperationContext();
788
                                                        doc.setGraphics(g);
789
                                                        doc.setViewPort(viewPort);
790
                                                        doc.setSymbol((ISymbol)csSym);
791
                                                        doc.setCancellable(cancel);
792
                                                        doc.setDPI(dpi);
793
                                                        geom.invokeOperation(DrawInts.CODE,doc);
794
                                                }
795
                                        }
796
                                        it=null;
797
                                        featureCollection.dispose();
798
                                }
799
                        } catch (ReadException e) {
800
                                this.setVisible(false);
801
                                this.setActive(false);
802
                                throw e;
803
                        } catch (GeometryOperationNotSupportedException e) {
804
                                this.setVisible(false);
805
                                this.setActive(false);
806
                                throw new ReadException(getName(),e);
807
                        } catch (GeometryOperationException e) {
808
                                this.setVisible(false);
809
                                this.setActive(false);
810
                                throw new ReadException(getName(),e);
811
                        } catch (BaseException e) {
812
                                this.setVisible(false);
813
                                this.setActive(false);
814
                                throw new ReadException(getName(),e);
815
                        }
816
                }
817
        }
818

    
819
        /**
820
         * <p>
821
         * Creates an spatial index associated to this layer.
822
         * The spatial index will used
823
         * the native projection of the layer, so if the layer is reprojected, it will
824
         * be ignored.
825
         * </p>
826
         * @param cancelMonitor instance of CancellableMonitorable that allows
827
         * to monitor progress of spatial index creation, and cancel the process
828
         */
829
        //    public void createSpatialIndex(CancellableMonitorable cancelMonitor){
830
        //         // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
831
        //        // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
832
        //        // para que acepten recorrer sin geometria, solo con rectangulos.
833
        //
834
        //        //If this vectorial layer is based in a spatial database, the spatial
835
        //        //index is already implicit. We only will index file drivers
836
        //        ReadableVectorial va = getSource();
837
        //        //We must think in non spatial databases, like HSQLDB
838
        //        if(!(va instanceof VectorialFileAdapter)){
839
        //            return;
840
        //        }
841
        //        if (!(va.getDriver() instanceof BoundedShapes)) {
842
        //            return;
843
        //        }
844
        //        File file = ((VectorialFileAdapter) va).getFile();
845
        //        String fileName = file.getAbsolutePath();
846
        //        ISpatialIndex localCopy = null;
847
        //        try {
848
        //            va.start();
849
        //            localCopy = new QuadtreeGt2(fileName, "NM", va.getFullExtent(),
850
        //                    va.getShapeCount(), true);
851
        //
852
        //        } catch (SpatialIndexException e1) {
853
        //            // Probably we dont have writing permissions
854
        //            String directoryName = System.getProperty("java.io.tmpdir");
855
        //            File newFile = new File(directoryName +
856
        //                    File.separator +
857
        //                    file.getName());
858
        //            String newFileName = newFile.getName();
859
        //            try {
860
        //                localCopy = new QuadtreeGt2(newFileName, "NM", va.getFullExtent(),
861
        //                        va.getShapeCount(), true);
862
        //            } catch (SpatialIndexException e) {
863
        //                // if we cant build a file based spatial index, we'll build
864
        //                // a pure memory spatial index
865
        //                localCopy = new QuadtreeJts();
866
        //            } catch (ReadException e) {
867
        //                localCopy = new QuadtreeJts();
868
        //            }
869
        //
870
        //        } catch(Exception e){
871
        //            e.printStackTrace();
872
        //        }//try
873
        //        BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
874
        //        try {
875
        //            for (int i=0; i < va.getShapeCount(); i++)
876
        //            {
877
        //                if(cancelMonitor != null){
878
        //                    if(cancelMonitor.isCanceled())
879
        //                        return;
880
        //                    cancelMonitor.reportStep();
881
        //                }
882
        //                Rectangle2D r = shapeBounds.getShapeBounds(i);
883
        //                if(r != null)
884
        //                    localCopy.insert(r, i);
885
        //            } // for
886
        //            va.stop();
887
        //            if(localCopy instanceof IPersistentSpatialIndex)
888
        //                ((IPersistentSpatialIndex) localCopy).flush();
889
        //            spatialIndex = localCopy;
890
        //            //vectorial adapter needs a reference to the spatial index, to solve
891
        //            //request for feature iteration based in spatial queries
892
        //            source.setSpatialIndex(spatialIndex);
893
        //        } catch (ReadException e) {
894
        //            // TODO Auto-generated catch block
895
        //            e.printStackTrace();
896
        //        }
897
        //    }
898

    
899
        //    public void createSpatialIndex() {
900
        //        createSpatialIndex(null);
901
        //    }
902

    
903

    
904
        public void setLegend(IVectorLegend r) throws LegendLayerException {
905
                if (this.legend == r){
906
                        return;
907
                }
908
                if (this.legend != null && this.legend.equals(r)){
909
                        return;
910
                }
911
                IVectorLegend oldLegend = legend;
912
                legend = r;
913
                try {
914
                        legend.setFeatureStore(getFeatureStore());
915
                } catch (ReadException e1) {
916
                        throw new LegendLayerException(getName(),e1);
917
                } catch (DataException e) {
918
                        throw new LegendLayerException(getName(),e);
919
                } finally{
920
                        this.updateDrawVersion();
921
                }
922

    
923
                if (oldLegend != null) {
924
                        oldLegend.removeLegendListener(this);
925
                }
926
                if (legend != null) {
927
                        legend.addLegendListener(this);
928
                }
929

    
930
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
931
                                oldLegend, legend);
932
                callLegendChanged(e);
933
        }
934

    
935
        /**
936
         * Devuelve la Leyenda de la capa.
937
         *
938
         * @return Leyenda.
939
         */
940
        public ILegend getLegend() {
941
                return legend;
942
        }
943

    
944
        /**
945
         * Devuelve el tipo de shape que contiene la capa.
946
         *
947
         * @return tipo de shape.
948
         *
949
         * @throws ReadException
950
         */
951
        public int getShapeType() throws ReadException {
952
                if (typeShape == -1) {
953
                        FeatureType featureType;
954
                        try {
955
                                featureType = (((FeatureStore)getDataStore()).getDefaultFeatureType());
956
                        } catch (DataException e) {
957
                                throw new ReadException(getName(),e);
958
                        }
959
                        int indexGeom=featureType.getDefaultGeometryAttributeIndex();
960
                        typeShape=featureType.getAttributeDescriptor(indexGeom).getGeometryType();
961
                }
962
                return typeShape;
963
        }
964

    
965
        public XMLEntity getXMLEntity() throws XMLException {
966

    
967
                if (!this.isAvailable() && this.orgXMLEntity != null) {
968
                        return this.orgXMLEntity;
969
                }
970
                XMLEntity xml = super.getXMLEntity();
971
                if (getLegend()!=null){
972
                        XMLEntity xmlLegend=getLegend().getXMLEntity();
973
                        xmlLegend.putProperty("tagName","legend");
974
                        xml.addChild(xmlLegend);
975
                }
976
                try {
977
                        PersistentState stateFeatureStore=getFeatureStore().getState();
978
                        stateFeatureStore.set("tagName","featureStore");
979
                        xml.addChild(((XMLEntityState)stateFeatureStore).getXMLEntity());
980
                } catch (ReadException e) {
981
                        throw new XMLLayerException(getName(),e);
982
                } catch (PersistenceException e) {
983
                        throw new XMLLayerException(getName(),e);
984
                }
985
                // properties from ILabelable
986
                xml.putProperty("isLabeled", isLabeled);
987
                if (strategy != null) {
988
                        XMLEntity strategyXML = strategy.getXMLEntity();
989
                        strategyXML.putProperty("tagName", "labelingStrategy");
990
                        xml.addChild(strategy.getXMLEntity());
991
                }
992
                xml.addChild(getLinkProperties().getXMLEntity());
993
                return xml;
994
        }
995
        /*
996
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
997
         */
998
        public void setXMLEntity(XMLEntity xml) throws XMLException {
999
                try {
1000
                        super.setXMLEntity(xml);
1001
                        XMLEntity legendXML = xml.firstChild("tagName","legend");
1002
                        IVectorLegend leg = LegendFactory.createFromXML(legendXML);
1003
                        /* (jaume) begin patch;
1004
                         * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1005
                         * no longer managed by the Legend but by the ILabelingStrategy. The
1006
                         * following allows restoring older projects' labelings.
1007
                         */
1008
                        if (legendXML.contains("labelFieldName")) {
1009
                                String labelTextField = legendXML.getStringProperty("labelFieldName");
1010
                                if (labelTextField != null) {
1011
                                        AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
1012
                                        labeling.setLayer(this);
1013
                                        labeling.setTextField(legendXML.getStringProperty("labelFieldName"));
1014
                                        labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
1015
                                        labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
1016
                                        this.setLabelingStrategy(labeling);
1017
                                        this.setIsLabeled(true);
1018
                                }
1019
                        }
1020
                        //            PersistentState persistentState=new XMLEntityState(new XMLEntityManager());
1021
                        XMLEntity xmlStore=xml.firstChild("tagName","featureStore");
1022
                        XMLEntityManager xmlManger = new XMLEntityManager();
1023
                        PersistentState state = xmlManger.createState(xmlStore);
1024
                        DataStore store = (DataStore) ToolsLocator.getPersistenceManager().create(state);
1025
                        //            persistentState.createState(xmlStore);
1026

    
1027
                        //            DataManager dm=DALLocator.getDataManager();
1028

    
1029
                        this.setDataStore(store);
1030
                        /* end patch */
1031
                        try {
1032
                                setLegend(leg);
1033
                        } catch (LegendLayerException e) {
1034
                                throw new XMLLegendException(e);
1035
                        }
1036
                        // set properties for ILabelable
1037

    
1038
                        if (xml.contains("isLabeled")
1039
                                        && xml.getBooleanProperty(("isLabeled"))) {
1040
                                XMLEntity labelingXML = xml.firstChild("tagName", "labelingStrategy");
1041
                                if (labelingXML != null){
1042

    
1043
                                        isLabeled = true;
1044
                                        try {
1045
                                                this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this);
1046
                                        } catch (NotExistInXMLEntity neXMLEX) {
1047
                                                // no strategy was set, just continue;
1048
                                                logger.warn("Reached what should be unreachable code");
1049
                                        }
1050
                                } else {
1051
                                        isLabeled = false;
1052
                                }
1053
                        } else {
1054
                                isLabeled = false;
1055
                        }
1056
                        XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
1057
                        if (xmlLinkProperties != null){
1058
                                getLinkProperties().setXMLEntity(xmlLinkProperties);
1059
                        }
1060
                } catch (Exception e) {
1061
                        e.printStackTrace();
1062
                        this.setAvailable(false);
1063
                        this.orgXMLEntity = xml;
1064

    
1065
                }
1066
                //
1067

    
1068
        }
1069

    
1070
        public void setXMLEntityNew(XMLEntity xml) throws XMLException {
1071
                //        try {
1072
                //            super.setXMLEntity(xml);
1073
                //
1074
                //            XMLEntity legendXML = xml.getChild(0);
1075
                //            IVectorLegend leg = LegendFactory.createFromXML(legendXML);
1076
                //            /* (jaume) begin patch;
1077
                //             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1078
                //             * no longer managed by the Legend but by the ILabelingStrategy. The
1079
                //             * following allows restoring older projects' labelings.
1080
                //             */
1081
                //            if (legendXML.contains("labelFieldHeight")) {
1082
                //                AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
1083
                //                labeling.setLayer(this);
1084
                //                labeling.setTextField(legendXML.getStringProperty("labelFieldHeight"));
1085
                //                labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
1086
                //                this.setLabelingStrategy(labeling);
1087
                //                this.setIsLabeled(true);
1088
                //              }
1089
                //            /* end patch */
1090
                //            try {
1091
                //                getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
1092
                //
1093
                //                this.setLoadSelection(xml.getChild(1));
1094
                //            } catch (ReadException e1) {
1095
                //                this.setAvailable(false);
1096
                //                throw new XMLException(e1);
1097
                //            }
1098
                //            // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
1099
                //            // el final
1100
                //            // de la lectura del proyecto
1101
                //            if (xml.contains("hasJoin")) {
1102
                //                setIsJoined(true);
1103
                //                PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
1104
                //            } else {
1105
                //                this.setLoadLegend(leg);
1106
                //            }
1107
                //
1108
                //        } catch (XMLException e) {
1109
                //            this.setAvailable(false);
1110
                //            this.orgXMLEntity = xml;
1111
                //        } catch (Exception e) {
1112
                //            this.setAvailable(false);
1113
                //            this.orgXMLEntity = xml;
1114
                //        }
1115

    
1116

    
1117
        }
1118

    
1119

    
1120
        /**
1121
         * Sobreimplementaci?n del m?todo toString para que las bases de datos
1122
         * identifiquen la capa.
1123
         *
1124
         * @return DOCUMENT ME!
1125
         */
1126
        public String toString() {
1127
                /*
1128
                 * Se usa internamente para que la parte de datos identifique de forma
1129
                 * un?voca las tablas
1130
                 */
1131
                String ret = super.toString();
1132

    
1133
                return "layer" + ret.substring(ret.indexOf('@') + 1);
1134
        }
1135

    
1136
        public boolean isJoined() {
1137
                return bHasJoin;
1138
        }
1139

    
1140
        /**
1141
         * Returns if a layer is spatially indexed
1142
         *
1143
         * @return if this layer has the ability to proces spatial queries without
1144
         *         secuential scans.
1145
         */
1146
        //    public boolean isSpatiallyIndexed() {
1147
        //        ReadableVectorial source = getSource();
1148
        //        if (source instanceof ISpatialDB)
1149
        //            return true;
1150
        //
1151
        ////FIXME azabala
1152
        ///*
1153
        // * Esto es muy dudoso, y puede cambiar.
1154
        // * Estoy diciendo que las que no son fichero o no son
1155
        // * BoundedShapes estan indexadas. Esto es mentira, pero
1156
        // * as? quien pregunte no querr? generar el indice.
1157
        // * Esta por ver si interesa generar el indice para capas
1158
        // * HSQLDB, WFS, etc.
1159
        // */
1160
        //        if(!(source instanceof VectorialFileAdapter)){
1161
        //            return true;
1162
        //        }
1163
        //        if (!(source.getDriver() instanceof BoundedShapes)) {
1164
        //            return true;
1165
        //        }
1166
        //
1167
        //        if (getISpatialIndex() != null)
1168
        //            return true;
1169
        //        return false;
1170
        //    }
1171

    
1172
        public void setIsJoined(boolean hasJoin) {
1173
                bHasJoin = hasJoin;
1174
        }
1175

    
1176
        //    /**
1177
        //     * @return Returns the spatialIndex.
1178
        //     */
1179
        //    public ISpatialIndex getISpatialIndex() {
1180
        //        return spatialIndex;
1181
        //    }
1182
        //    /**
1183
        //     * Sets the spatial index. This could be useful if, for some
1184
        //     * reasons, you want to work with a distinct spatial index
1185
        //     * (for example, a spatial index which could makes nearest
1186
        //     * neighbour querys)
1187
        //     * @param spatialIndex
1188
        //     */
1189
        //    public void setISpatialIndex(ISpatialIndex spatialIndex){
1190
        //        this.spatialIndex = spatialIndex;
1191
        //    }
1192

    
1193
        public void setEditing(boolean b) throws StartEditionLayerException {
1194
                super.setEditing(b);
1195
                if (b){
1196
                        try {
1197
                                getFeatureStore().edit();
1198
                        } catch (ReadException e) {
1199
                                throw new StartEditionLayerException(getName(),e);
1200
                        } catch (DataException e) {
1201
                                throw new StartEditionLayerException(getName(),e);
1202
                        }
1203
                }
1204
                setSpatialCacheEnabled(b);
1205
                callEditionChanged(LayerEvent
1206
                                .createEditionChangedEvent(this, "edition"));
1207

    
1208
        }
1209

    
1210
        public void clearSpatialCache()
1211
        {
1212
                spatialCache.clearAll();
1213
        }
1214

    
1215
        public boolean isSpatialCacheEnabled() {
1216
                return spatialCacheEnabled;
1217
        }
1218

    
1219
        public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
1220
                this.spatialCacheEnabled = spatialCacheEnabled;
1221
        }
1222

    
1223
        public SpatialCache getSpatialCache() {
1224
                return spatialCache;
1225
        }
1226

    
1227
        /**
1228
         * Siempre es un numero mayor de 1000
1229
         * @param maxFeatures
1230
         */
1231
        public void setMaxFeaturesInEditionCache(int maxFeatures) {
1232
                if (maxFeatures > spatialCache.getMaxFeatures()) {
1233
                        spatialCache.setMaxFeatures(maxFeatures);
1234
                }
1235

    
1236
        }
1237

    
1238
        /**
1239
         * This method returns a boolean that is used by the FPopMenu
1240
         * to make visible the properties menu or not. It is visible by
1241
         * default, and if a later don't have to show this menu only
1242
         * has to override this method.
1243
         * @return
1244
         * If the properties menu is visible (or not)
1245
         */
1246
        public boolean isPropertiesMenuVisible(){
1247
                return true;
1248
        }
1249

    
1250
        public void reload() throws ReloadLayerException {
1251
                super.reload();
1252
                try {
1253
                        DataManager dataManager=DALLocator.getDataManager();
1254
                        DataStoreParameters storeParameters;
1255

    
1256
                        storeParameters = getFeatureStore().getParameters();
1257

    
1258
                        DataStore dataStore=dataManager.createStore(storeParameters);
1259
                        setDataStore(dataStore);
1260
                        getFeatureStore().refresh();
1261
                } catch (ReadException e) {
1262
                        throw new ReloadLayerException(getName(),e);
1263
                }catch (LoadLayerException e) {
1264
                        throw new ReloadLayerException(getName(),e);
1265
                } catch (DataException e) {
1266
                        throw new ReloadLayerException(getName(),e);
1267
                }
1268
                //        try {
1269
                //            this.source.getDriver().reload();
1270
                //            if (this.getLegend() == null) {
1271
                //                if (this.getRecordset().getDriver() instanceof WithDefaultLegend) {
1272
                //                    WithDefaultLegend aux = (WithDefaultLegend) this.getRecordset().getDriver();
1273
                //                    this.setLegend((IVectorLegend) aux.getDefaultLegend());
1274
                //                    this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
1275
                //                } else {
1276
                //                    this.setLegend(LegendFactory.createSingleSymbolLegend(
1277
                //                            this.getShapeType()));
1278
                //                }
1279
                //            }
1280
                //
1281
                //        } catch (LegendLayerException e) {
1282
                //            this.setAvailable(false);
1283
                //            throw new ReloadLayerException(getName(),e);
1284
                //        } catch (ReadException e) {
1285
                //            this.setAvailable(false);
1286
                //            throw new ReloadLayerException(getName(),e);
1287
                //        }
1288

    
1289

    
1290
        }
1291

    
1292
        protected void setLoadSelection(XMLEntity xml) {
1293
                this.loadSelection = xml;
1294
        }
1295

    
1296
        protected void setLoadLegend(IVectorLegend legend) {
1297
                this.loadLegend = legend;
1298
        }
1299

    
1300
        protected void putLoadSelection() throws XMLException {
1301
                //        if (this.loadSelection == null) return;
1302
                //        try {
1303
                //            this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
1304
                //        } catch (ReadDriverException e) {
1305
                //            throw new XMLException(e);
1306
                //        }
1307
                //        this.loadSelection = null;
1308

    
1309
        }
1310
        protected void putLoadLegend() throws LegendLayerException {
1311
                if (this.loadLegend == null) {
1312
                        return;
1313
                }
1314
                this.setLegend(this.loadLegend);
1315
                this.loadLegend = null;
1316
        }
1317

    
1318
        protected void cleanLoadOptions() {
1319
                this.loadLegend = null;
1320
                this.loadSelection = null;
1321
        }
1322

    
1323
        public boolean isWritable() {
1324
                try {
1325
                        return getFeatureStore().allowWrite();
1326
                } catch (ReadException e) {
1327
                        e.printStackTrace();
1328
                }
1329
                return false;
1330
        }
1331

    
1332
        public FLayer cloneLayer() throws Exception {
1333
                FLyrVect clonedLayer = new FLyrVect();
1334
                clonedLayer.setDataStore(getDataStore());
1335
                if (isJoined()) {
1336
                        clonedLayer.setIsJoined(true);
1337
                }
1338
                clonedLayer.setVisible(isVisible());
1339
                //        clonedLayer.setISpatialIndex(getISpatialIndex());
1340
                clonedLayer.setName(getName());
1341
                clonedLayer.setCoordTrans(getCoordTrans());
1342

    
1343
                clonedLayer.setLegend((IVectorLegend)getLegend().cloneLegend());
1344

    
1345
                clonedLayer.setIsLabeled(isLabeled());
1346
                clonedLayer.setLabelingStrategy(getLabelingStrategy());
1347

    
1348
                return clonedLayer;
1349
        }
1350

    
1351

    
1352
        private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, double dpi, CartographicSupport csSym, Geometry geom, int[] xyCoords) {
1353
                return isOnePoint(graphicsTransform, viewPort, geom, xyCoords) && csSym.getCartographicSize(viewPort, dpi, geom) <= 1;
1354
        }
1355

    
1356
        private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, Geometry geom, int[] xyCoords) {
1357
                boolean onePoint = false;
1358
                int type=geom.getType() % Geometry.TYPES.Z;
1359
                if (type!=Geometry.TYPES.POINT && type!=Geometry.TYPES.MULTIPOINT) {
1360

    
1361
                        Envelope geomBounds = geom.getEnvelope();
1362

    
1363
                        ICoordTrans ct = getCoordTrans();
1364

    
1365
                        if (ct!=null) {
1366
                                //                                geomBounds = ct.getInverted().convert(geomBounds);
1367
                                geomBounds = geomBounds.convert(ct);
1368
                        }
1369

    
1370
                        double dist1Pixel = viewPort.getDist1pixel();
1371

    
1372
                        onePoint = (geomBounds.getLength(0)  <= dist1Pixel
1373
                                        && geomBounds.getLength(1) <= dist1Pixel);
1374

    
1375
                        if (onePoint) {
1376
                                // avoid out of range exceptions
1377
                                org.gvsig.fmap.geom.primitive.Point2D p = new org.gvsig.fmap.geom.primitive.Point2D(geomBounds.getMinimum(0), geomBounds.getMinimum(1));
1378
                                p.transform(viewPort.getAffineTransform());
1379
                                p.transform(graphicsTransform);
1380
                                xyCoords[0] = (int) p.getX();
1381
                                xyCoords[1] = (int) p.getY();
1382

    
1383
                        }
1384

    
1385
                }
1386
                return onePoint;
1387
        }
1388
        /*
1389
         * jaume. Stuff from ILabeled.
1390
         */
1391
        private boolean isLabeled;
1392
        protected ILabelingStrategy strategy;
1393

    
1394
        public boolean isLabeled() {
1395
                return isLabeled;
1396
        }
1397

    
1398
        public void setIsLabeled(boolean isLabeled) {
1399
                this.isLabeled = isLabeled;
1400
        }
1401

    
1402
        public ILabelingStrategy getLabelingStrategy() {
1403
                return strategy;
1404
        }
1405

    
1406
        public void setLabelingStrategy(ILabelingStrategy strategy) {
1407
                this.strategy = strategy;
1408
                try {
1409
                        strategy.setLayer(this);
1410
                } catch (ReadException e) {
1411
                        // TODO Auto-generated catch block
1412
                        e.printStackTrace();
1413
                }
1414

    
1415
        }
1416

    
1417
        public void drawLabels(BufferedImage image, Graphics2D g, ViewPort viewPort,
1418
                        Cancellable cancel, double scale, double dpi) throws ReadException {
1419
                if (strategy!=null && isWithinScale(scale)) {
1420
                        strategy.draw(image, g, viewPort, cancel, dpi);
1421
                }
1422
        }
1423

    
1424
        public void printLabels(Graphics2D g, ViewPort viewPort,
1425
                        Cancellable cancel, double scale,
1426
                        PrintRequestAttributeSet properties) throws ReadException {
1427
                if (strategy != null) {
1428
                        strategy.print(g, viewPort, cancel, properties);
1429
                }
1430
        }
1431
        //M?todos para el uso de HyperLinks en capas FLyerVect
1432

    
1433
        /**
1434
         * Return true, because a Vectorial Layer supports HyperLink
1435
         */
1436
        public boolean allowLinks()
1437
        {
1438
                return true;
1439
        }
1440

    
1441
        /**
1442
         * Returns an instance of AbstractLinkProperties that contains the information
1443
         * of the HyperLink
1444
         * @return Abstra
1445
         */
1446
        public AbstractLinkProperties getLinkProperties()
1447
        {
1448
                return linkProperties;
1449
        }
1450

    
1451
        /**
1452
         * Provides an array with URIs. Returns one URI by geometry that includes the point
1453
         * in its own geometry limits with a allowed tolerance.
1454
         * @param layer, the layer
1455
         * @param point, the point to check that is contained or not in the geometries in the layer
1456
         * @param tolerance, the tolerance allowed. Allowed margin of error to detect if the  point
1457
         *                 is contained in some geometries of the layer
1458
         * @return
1459
         * @throws ReadException
1460
         * @throws BehaviorException
1461
         */
1462
        public URI[] getLink(Point2D point, double tolerance) throws ReadException
1463
        {
1464
                //return linkProperties.getLink(this)
1465
                return linkProperties.getLink(this,point,tolerance);
1466
        }
1467

    
1468
        public void load() throws LoadLayerException {
1469
                super.load();
1470
        }
1471

    
1472
        public FeatureStore getFeatureStore() throws ReadException {
1473
                return (FeatureStore)getDataStore();
1474
        }
1475

    
1476
        public FeatureSet queryByPoint(Point2D mapPoint, double tol, FeatureType featureType) throws DataException {
1477
                Geometry geom = GeometryManager.getInstance().getGeometryFactory()
1478
                .createCircle(mapPoint, tol);
1479

    
1480
                return queryByGeometry(geom, featureType);
1481
                //                return queryByEnvelope(geom.getEnvelope(), featureType);
1482
        }
1483

    
1484

    
1485
        public FeatureSet queryByGeometry(Geometry geom, FeatureType featureType) throws DataException {
1486
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
1487
                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
1488
                featureQuery.setFeatureType(featureType);
1489
                IntersectsGeometryEvaluator iee=new IntersectsGeometryEvaluator(geom,getMapContext().getViewPort().getProjection(),featureStore.getDefaultFeatureType(),geomName);
1490
                featureQuery.setFilter(iee);
1491
                return getFeatureStore().getFeatureSet(featureQuery);
1492

    
1493
        }
1494

    
1495
        public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType)
1496
        throws DataException {
1497
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
1498
                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
1499
                featureQuery.setFeatureType(featureType);
1500
                InEnvelopeEvaluator iee=new InEnvelopeEvaluator(envelope,getMapContext().getViewPort().getProjection(),featureStore.getDefaultFeatureType(),geomName);
1501
                featureQuery.setFilter(iee);
1502
                return getFeatureStore().getFeatureSet(featureQuery);
1503

    
1504
        }
1505

    
1506
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws LoadLayerException, DataException {
1507
                Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p);
1508
                FeatureSet featureCollection=null;
1509
                try {
1510
                        featureCollection = queryByPoint(pReal, tolerance, getFeatureStore().getDefaultFeatureType());
1511
                } catch (DataException e) {
1512
                        // TODO Auto-generated catch block
1513
                        e.printStackTrace();
1514
                }
1515
                VectorialXMLItem[] item = new VectorialXMLItem[1];
1516
                item[0] = new VectorialXMLItem(featureCollection, this);
1517

    
1518
                return item;
1519
        }
1520

    
1521
        public void legendCleared(LegendClearEvent event) {
1522
                // this.updateDrawVersion(); TODO
1523
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
1524
                                legend, legend);
1525
                this.callLegendChanged(e);
1526
        }
1527

    
1528
        public boolean symbolChanged(SymbolLegendEvent e) {
1529
                LegendChangedEvent ev = LegendChangedEvent.createLegendChangedEvent(
1530
                                legend, legend);
1531
                this.callLegendChanged(ev);
1532
                return true;
1533
        }
1534

    
1535
        public void update(Observable observable, Object notification) {
1536
                if (observable.equals(this.featureStore)) {
1537
                        if (notification instanceof FeatureStoreNotification) {
1538
                                FeatureStoreNotification event = (FeatureStoreNotification) notification;
1539
                                if (event.getType() == FeatureStoreNotification.AFTER_CANCELEDITING
1540
                                                || event.getType() == FeatureStoreNotification.AFTER_DELETE
1541
                                                || event.getType() == FeatureStoreNotification.AFTER_UNDO
1542
                                                || event.getType() == FeatureStoreNotification.AFTER_REDO
1543
                                                || event.getType() == FeatureStoreNotification.AFTER_REFRESH
1544
                                                || event.getType() == FeatureStoreNotification.AFTER_UPDATE
1545
                                                || event.getType() == FeatureStoreNotification.AFTER_UPDATE_TYPE
1546
                                                || event.getType() == FeatureStoreNotification.SELECTION_CHANGE
1547
                                                || event.getType() == FeatureStoreNotification.AFTER_INSERT) {
1548
                                        this.updateDrawVersion();
1549

    
1550
                                } else if (event.getType() == FeatureStoreNotification.AFTER_FINISHEDITING
1551
                                                || event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE
1552
                                                || event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
1553
                                        this.setAvailable(false);
1554

    
1555
                                        //                                        try {
1556
                                        //                                                reload();
1557
                                        //                                        } catch (ReloadLayerException e) {
1558
                                        //                                                this.setAvailable(false);
1559
                                        //                                        }
1560
                                }
1561

    
1562
                        }
1563

    
1564
                }
1565

    
1566
        }
1567

    
1568
        /*
1569
         * (non-Javadoc)
1570
         * 
1571
         * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1572
         */
1573
        public Set getMetadataChildren() {
1574
                Set ret = new TreeSet();
1575
                ret.add(this.featureStore);
1576
                return ret;
1577
        }
1578

    
1579
        /*
1580
         * (non-Javadoc)
1581
         * 
1582
         * @see org.gvsig.metadata.Metadata#getMetadataID()
1583
         */
1584
        public Object getMetadataID() {
1585
                return "Layer(" + this.getName() + "):"
1586
                + this.featureStore.getMetadataID();
1587
        }
1588

    
1589
        /*
1590
         * (non-Javadoc)
1591
         * 
1592
         * @see org.gvsig.metadata.Metadata#getMetadataName()
1593
         */
1594
        public String getMetadataName() {
1595
                return "Layer '" + this.getName() + "':"
1596
                + this.featureStore.getMetadataName();
1597
        }
1598

    
1599
}