Statistics
| Revision:

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

History | View | Annotate | Download (69.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.geom.Rectangle2D;
48
import java.awt.image.BufferedImage;
49
import java.net.URI;
50
import java.util.ArrayList;
51
import java.util.Iterator;
52

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

    
56
import org.apache.log4j.Logger;
57
import org.cresques.cts.ICoordTrans;
58
import org.gvsig.exceptions.BaseException;
59
import org.gvsig.fmap.data.DataStore;
60
import org.gvsig.fmap.data.ReadException;
61
import org.gvsig.fmap.data.feature.Feature;
62
import org.gvsig.fmap.data.feature.FeatureCollection;
63
import org.gvsig.fmap.data.feature.FeatureStore;
64
import org.gvsig.fmap.data.feature.FeatureType;
65
import org.gvsig.fmap.data.operation.DataStoreOperationException;
66
import org.gvsig.fmap.data.operation.DataStoreOperationNotSupportedException;
67
import org.gvsig.fmap.geom.Geometry;
68
import org.gvsig.fmap.geom.GeometryManager;
69
import org.gvsig.fmap.geom.operation.DrawInts;
70
import org.gvsig.fmap.geom.operation.DrawOperationContext;
71
import org.gvsig.fmap.geom.operation.GeometryOperationException;
72
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
73
import org.gvsig.fmap.geom.operation.towkt.ToWKT;
74
import org.gvsig.fmap.geom.primitive.DefaultEnvelope;
75
import org.gvsig.fmap.geom.primitive.Envelope;
76
import org.gvsig.fmap.mapcontext.MapContext;
77
import org.gvsig.fmap.mapcontext.ViewPort;
78
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
79
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
80
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
81
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
82
import org.gvsig.fmap.mapcontext.layers.AbstractLinkProperties;
83
import org.gvsig.fmap.mapcontext.layers.FLayer;
84
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
85
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
86
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
87
import org.gvsig.fmap.mapcontext.layers.XMLException;
88
import org.gvsig.fmap.mapcontext.layers.operations.ClassifiableVectorial;
89
import org.gvsig.fmap.mapcontext.layers.operations.ILabelable;
90
import org.gvsig.fmap.mapcontext.layers.operations.InfoByPoint;
91
import org.gvsig.fmap.mapcontext.layers.operations.SingleLayer;
92
import org.gvsig.fmap.mapcontext.layers.operations.VectorialXMLItem;
93
import org.gvsig.fmap.mapcontext.layers.operations.XMLItem;
94
import org.gvsig.fmap.mapcontext.rendering.legend.IClassifiedLegend;
95
import org.gvsig.fmap.mapcontext.rendering.legend.IClassifiedVectorLegend;
96
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
97
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
98
import org.gvsig.fmap.mapcontext.rendering.legend.LegendFactory;
99
import org.gvsig.fmap.mapcontext.rendering.legend.SingleSymbolLegend;
100
import org.gvsig.fmap.mapcontext.rendering.legend.ZSort;
101
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
102
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
103
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
104
import org.gvsig.fmap.mapcontext.rendering.symbols.FSymbol;
105
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
106
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
107

    
108
import com.iver.utiles.XMLEntity;
109
import com.iver.utiles.swing.threads.Cancellable;
110

    
111
/**
112
 * Capa b?sica Vectorial.
113
 *
114
 * @author Fernando Gonz?lez Cort?s
115
 */
116

    
117
// TODO Cuando no sea para pruebas debe no ser public
118
public class FLyrVect extends FLyrDefault implements ILabelable, InfoByPoint,
119
                ClassifiableVectorial, SingleLayer {
120
    private static Logger logger = Logger.getLogger(FLyrVect.class.getName());
121

    
122
    /** Leyenda de la capa vectorial */
123
    private IVectorLegend legend;
124
    private int typeShape = -1;
125
//    private ReadableVectorial source;
126
//    private SelectableDataSource sds;
127
    private FeatureStore featureStore=null;
128
//    private SelectionSupport selectionSupport = new SelectionSupport();
129
    private SpatialCache spatialCache = new SpatialCache();
130
    private boolean spatialCacheEnabled = false;
131

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

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

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

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

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

218
     * @return
219
     */
220
//    public boolean isExternallySpatiallyIndexed() {
221
//        /*
222
//         * FIXME (AZABALA): Independizar del tipo de fichero de ?ndice
223
//          * con el que se trabaje (ahora mismo considera la extension .qix,
224
//         * pero esto depender? del tipo de ?ndice)
225
//         * */
226
//        ReadableVectorial source = getSource();
227
//        if (!(source instanceof VectorialFileAdapter)) {
228
//            // we are not interested in db adapters.
229
//            // think in non spatial dbs, like HSQLDB
230
//            return false;
231
//        }
232
//        File file = ((VectorialFileAdapter) source).getFile();
233
//        String fileName = file.getAbsolutePath();
234
//        File sptFile = new File(fileName + ".qix");
235
//        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
236
//            // before to exit, look for it in temp path
237
//            // it doesnt exists, must to create
238
//            String tempPath = System.getProperty("java.io.tmpdir");
239
//            fileName = tempPath + File.separator + sptFile.getName();
240
//            sptFile = new File(fileName);
241
//            if (!sptFile.exists() || (!(sptFile.length() > 0))) {
242
//                return false;
243
//            }// if
244
//        }// if
245
//        return true;
246
//    }
247

    
248
    /**
249
     * Inserta el VectorialAdapter a la capa.
250
     *
251
     * @param va
252
     *            VectorialAdapter.
253
     */
254
    public void setDataStore(DataStore dataStore) throws LoadLayerException {
255
        featureStore = (FeatureStore)dataStore;
256

    
257
        if (dataStore.implementsOperation("defaultLegend")) {
258
                        ILegend legend = null;
259
                        try {
260
                                legend = (ILegend) dataStore.invokeOperation("defaultLegend",
261
                                                null);
262
                        } catch (DataStoreOperationNotSupportedException e) {
263
                                throw new LoadLayerException(this.getName(), e);
264
                        } catch (DataStoreOperationException e) {
265
                                throw new LoadLayerException(this.getName(), e);
266
                        }
267

    
268
                this.setLegend((IVectorLegend) legend);
269
                } else {
270
                        try {
271
                                this.setLegend(LegendFactory.createSingleSymbolLegend(this
272
                                                .getShapeType()));
273
                        } catch (ReadException e) {
274
                                throw new LoadLayerException(this.getName(), e);
275
                        }
276
                }
277

    
278
        if (dataStore.implementsOperation("defaultLabelingStrategy")) {
279

    
280
                ILabelingStrategy labeler = null;
281
                        try {
282
                                labeler = (ILabelingStrategy) dataStore.invokeOperation(
283
                                                "defaultLabelingStrategy", null);
284
                        } catch (DataStoreOperationNotSupportedException e) {
285
                                throw new LoadLayerException(this.getName(), e);
286
                        } catch (DataStoreOperationException e) {
287
                                throw new LoadLayerException(this.getName(), e);
288
                        }
289

    
290
                if (labeler != null) {
291
                                try {
292
                                        labeler.setLayer(this);
293
                                } catch (ReadException e) {
294
                                        throw new LoadLayerException(this.getName(), e);
295
                                }
296
                                this.setLabelingStrategy(labeler);
297
                                this.setIsLabeled(true); // TODO: ac? no s'hauria de detectar si t? etiquetes?????
298
                        }
299
        }
300

    
301

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

    
307
    public Envelope getFullEnvelope() throws ReadException {
308
//            Rectangle2D rAux=null;
309
////            source.start();
310
////            rAux = (Rectangle2D)source.getFullExtent().clone();
311
////            source.stop();
312
////
313
////
314
////            // Si existe reproyecci?n, reproyectar el extent
315
////            ICoordTrans ct = getCoordTrans();
316
////
317
////            if (ct != null) {
318
////                Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
319
////                Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
320
////                pt1 = ct.convert(pt1, null);
321
////                pt2 = ct.convert(pt2, null);
322
////                rAux = new Rectangle2D.Double();
323
////                rAux.setFrameFromDiagonal(pt1, pt2);
324
////            }
325
////
326
////            //Esto es para cuando se crea una capa nueva con el fullExtent de ancho y alto 0.
327
////            if (rAux.getWidth()==0 && rAux.getHeight()==0) {
328
////                rAux=new Rectangle2D.Double(0,0,100,100);
329
////            }
330
//
331
//            return rAux;
332

    
333
           Envelope rAux;
334
                try {
335
                        rAux = (Envelope)getFeatureStore().getMetadata().get("extent");
336
                } catch (BaseException e) {
337
                        throw new ReadException(getName(),e);
338
                }
339
                        // logger.debug("source.stop()");
340
//                getSource().stop();
341
                        // Si existe reproyecci?n, reproyectar el extent
342
                ICoordTrans ct = getCoordTrans();
343
                if (ct != null) {
344
                        Point2D pt1 = new Point2D.Double(rAux.getMinimum(0), rAux.getMinimum(1));
345
                        Point2D pt2 = new Point2D.Double(rAux.getMaximum(0), rAux.getMaximum(1));
346
                        pt1 = ct.convert(pt1, null);
347
                        pt2 = ct.convert(pt2, null);
348
                        rAux = new DefaultEnvelope(2,new double[]{pt1.getX(),pt1.getY()},new double[]{pt2.getX(),pt2.getY()});//new Rectangle2D.Double();
349
                }
350
                //Esto es para cuando se crea una capa nueva con el fullExtent de ancho y alto 0.
351
                if (rAux.getMaximum(0)-rAux.getMinimum(0)==0 && rAux.getMaximum(1)-rAux.getMinimum(1)==0) {
352
                        rAux=new DefaultEnvelope(2,new double[]{0,0},new double[]{100,100});
353
                }
354
                return rAux;
355

    
356
    }
357

    
358
    /**
359
     * Draws using IFeatureIterator. This method will replace the old draw(...) one.
360
     * @autor jaume dominguez faus - jaume.dominguez@iver.es
361
     * @param image
362
     * @param g
363
     * @param viewPort
364
     * @param cancel
365
     * @param scale
366
     * @throws ReadDriverException
367
     */
368
    public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
369
                    Cancellable cancel, double scale) throws ReadException {
370
            DrawOperationContext doc=new DrawOperationContext();
371
            doc.setViewPort(viewPort);
372
            boolean bDrawShapes = true;
373
            if (legend instanceof SingleSymbolLegend) {
374
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
375
            }
376
            Point2D offset = viewPort.getOffset();
377
            double dpi = MapContext.getScreenDPI();
378

    
379

    
380

    
381
            if (bDrawShapes) {
382
                    boolean cacheFeatures = isSpatialCacheEnabled();
383
                    SpatialCache cache = null;
384
                if (cacheFeatures) {
385
                        getSpatialCache().clearAll();
386
                        cache = getSpatialCache();
387
                }
388

    
389
                    try {
390
                            ArrayList fieldList = new ArrayList();
391

    
392
                            // fields from legend
393
                            String[] aux = null;
394

    
395
                            if (legend instanceof IClassifiedVectorLegend) {
396
                                    aux = ((IClassifiedVectorLegend) legend).getClassifyingFieldNames();
397
                                    for (int i = 0; i < aux.length; i++) {
398
                                            fieldList.add(aux[i]);
399
                                    }
400
                            }
401
                            FeatureStore featureStore=getFeatureStore();
402
                            // Get the iterator over the visible features
403
                            String featureFilter = null;
404

    
405
                            if (!viewPort.getAdjustedExtent().contains((Envelope)featureStore.getMetadata().get("extent"))) {
406
                                        featureFilter=this.getDataStoreFilterForGeomerty(
407
                                                viewPort.getAdjustedExtent().getGeometry(),
408
                                                featureStore.getDefaultFeatureType().getDefaultGeometry(),
409
                                                null);
410
                                }
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().getDefaultGeometry();
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().getDefaultGeometry()};
422
                            }
423

    
424

    
425
                            FeatureCollection featureCollection=null;
426
                            featureCollection = (FeatureCollection)featureStore.getDataCollection(
427
                                            fieldNames,
428
                                            featureFilter,//filter
429
                                            null);//order
430
                            Iterator it = featureCollection.iterator();
431

    
432

    
433
//                                            viewPort.getAdjustedExtent(),
434
//                                            fieldList.toArray(new String[fieldList.size()]),
435
//                                            viewPort.getProjection(),
436
//                                            true);
437

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

    
440
                            boolean bSymbolLevelError = false;
441

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

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

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

    
466

    
467
                            // Iteration over each feature
468
                            while ( !cancel.isCanceled() && it.hasNext()) {
469
                                    Feature feat = (Feature)it.next();
470

    
471
                                    Geometry geom = (Geometry)feat.getDefaultGeometry();
472

    
473
                                    if (cacheFeatures) {
474
                                            if (cache.getMaxFeatures() >= cache.size()) {
475
                                                        // already reprojected
476
                                                        cache.insert(geom.getEnvelope(), geom);
477
                                                }
478
                                    }
479

    
480
                                    // retrieve the symbol associated to such feature
481
                                    ISymbol sym = legend.getSymbolByFeature(feat);
482
                                    if (featureStore.getSelection().contains(feat)){
483
                                            sym=sym.getSymbolForSelection();
484
                                    }
485
                                    if (sym == null) {
486
                                                continue;
487
                                        }
488

    
489
                                    //C?digo para poder acceder a los ?ndices para ver si est? seleccionado un Feature
490
//                                    ReadableVectorial rv=getSource();
491
//                                    int selectionIndex=-1;
492
//                                    if (rv instanceof ISpatialDB){
493
//                                            selectionIndex=((ISpatialDB)rv).getRowIndexByFID(feat);
494
//                                    }else{
495
//                                            selectionIndex=Integer.parseInt(feat.getID());
496
//                                    }
497
//                                    if (selectionIndex!=-1) {
498
//                                            if (selectionSupport.isSelected(selectionIndex)) {
499
//                                                sym = sym.getSymbolForSelection();
500
//                                        }
501
//                                }
502

    
503
                                    // Check if this symbol is sized with CartographicSupport
504
                                    CartographicSupport csSym = null;
505
                                    int symbolType = sym.getSymbolType();
506
                                    boolean bDrawCartographicSupport = false;
507

    
508
                                    if (   symbolType == Geometry.TYPES.POINT
509
                                                    || symbolType == Geometry.TYPES.CURVE
510
                                                    || sym instanceof CartographicSupport) {
511

    
512
                                            // patch
513
                                        if (!sym.getClass().equals(FSymbol.class)) {
514
                                                csSym = (CartographicSupport) sym;
515
                                                bDrawCartographicSupport = (csSym.getUnit() != -1);
516
                                        }
517
                                    }
518

    
519
                                    int x = -1;
520
                                    int y = -1;
521
                                    int[] xyCoords = new int[2];
522

    
523
                                    // Check if size is a pixel
524
                                    boolean onePoint = bDrawCartographicSupport ?
525
                                                    isOnePoint(g.getTransform(), viewPort, MapContext.getScreenDPI(), csSym, geom, xyCoords) :
526
                                                    isOnePoint(g.getTransform(), viewPort, geom, xyCoords);
527

    
528
                                        // Avoid out of bounds exceptions
529
                                        if (onePoint) {
530
                                                x = xyCoords[0];
531
                                                y = xyCoords[1];
532
                                                if (x<0 || y<0 || x>= viewPort.getImageWidth() || y>=viewPort.getImageHeight()) {
533
                                                        continue;
534
                                                }
535
                                        }
536

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

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

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

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

    
613
                                        } else {
614
                                                // no ZSort, so there is only a map level, symbols are
615
                                                // just drawn.
616
                                                if (onePoint) {
617
                                                        if (x<0 || y<0 || x>= image.getWidth() || y>=image.getHeight()) {
618
                                                                continue;
619
                                                        }
620
                                                        image.setRGB(x, y, sym.getOnePointRgb());
621
                                                } else {
622

    
623
                                                        if (!bDrawCartographicSupport) {
624
                                                                doc.setGraphics(g);
625
                                                                doc.setSymbol(sym);
626
                                                                doc.setCancellable(cancel);
627
                                                                geom.invokeOperation(DrawInts.CODE,doc);
628
                                                        } else {
629
                                                                doc.setGraphics(g);
630
                                                                doc.setSymbol((ISymbol)csSym);
631
                                                                doc.setCancellable(cancel);
632
                                                                doc.setDPI(dpi);
633
                                                                geom.invokeOperation(DrawInts.CODE,doc);
634
                                                        }
635
                                                }
636
                                        }
637
                            }
638

    
639
                            if (useZSort) {
640
                                    g.drawImage(image, 0, 0, null);
641
                                        g.translate(offset.getX(), offset.getY());
642
                                    for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
643
                                            g.drawImage(imageLevels[i],0,0, null);
644
                                            imageLevels[i] = null;
645
                                            graphics[i] = null;
646
                                    }
647
                                        g.translate(-offset.getX(), -offset.getY());
648
                                    imageLevels = null;
649
                                    graphics = null;
650
                            }
651
//                            it.closeIterator();
652
                            it=null;
653
                            featureCollection.dispose();
654

    
655
                            if (bSymbolLevelError) {
656
                                    ((IVectorLegend) getLegend()).setZSort(null);
657
                            }
658

    
659
                    } catch (ReadException e) {
660
                            this.setVisible(false);
661
                            this.setActive(false);
662
                            throw e;
663
                    } catch (GeometryOperationNotSupportedException e) {
664
                            this.setVisible(false);
665
                            this.setActive(false);
666
                            throw new ReadException(getName(),e);
667
                        } catch (GeometryOperationException e) {
668
                                this.setVisible(false);
669
                            this.setActive(false);
670
                            throw new ReadException(getName(),e);
671
                        } catch (BaseException e) {
672
                                this.setVisible(false);
673
                            this.setActive(false);
674
                            throw new ReadException(getName(),e);
675
                        }
676

    
677

    
678
            }
679
    }
680

    
681
//           public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
682
//            Cancellable cancel, double scale) throws ReadException {
683
////            forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD = true;
684
//            if (!isUseStrategy()) {
685
//                    _draw(image, g, viewPort, cancel, scale);
686
//            } else {
687
////                    moved up to FLayers
688
////                    if (isWithinScale(scale)) {
689
//
690
//
691
//                            // Las que solo tienen etiquetado sin pintar el shape,
692
//                            // no pasamos por ellas
693
//                            boolean bDrawShapes = true;
694
//                            if (legend instanceof SingleSymbolLegend) {
695
//                                    if (legend.getDefaultSymbol().isShapeVisible() == false)
696
//                                            bDrawShapes = false;
697
//                            }
698
//                            if (bDrawShapes) {
699
//                                    Strategy strategy = StrategyManager.getStrategy(this);
700
//                                    try {
701
//                                            prepareDrawing(image, g, viewPort);
702
//                                            strategy.draw(image, g, viewPort, cancel);
703
//                                    } catch (ReadDriverException e) {
704
//                                            this.setVisible(false);
705
//                                            this.setActive(false);
706
//                                            throw e;
707
//                                    }
708
//                            }
709
//                            if (getVirtualLayers() != null) {
710
//                                    getVirtualLayers().draw(image, g, viewPort, cancel, scale);
711
//                            }
712
////                    }
713
//            }
714
//    }
715

    
716
    /**
717
     * Se llama antes de empezar a pintar.
718
     * Es ?til para preparar la cache a emplear, las leyendas, etc.
719
     * @param image
720
     * @param g
721
     * @param viewPort
722
     */
723
    private void prepareDrawing(BufferedImage image, Graphics2D g, ViewPort viewPort) {
724

    
725
    }
726

    
727
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
728
                    double scale, PrintRequestAttributeSet properties) throws ReadException {
729
            // TEST METHOD
730

    
731

    
732
                    /* SVN */
733

    
734
    /*        boolean bDrawShapes = true;
735
            if (legend instanceof SingleSymbolLegend) {
736
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
737
            }
738

739

740
            if (bDrawShapes) {
741
                    double dpi = 72;
742

743
                    PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
744
                    if (resolution.equals(PrintQuality.NORMAL)){
745
                            dpi = 300;
746
                    } else if (resolution.equals(PrintQuality.HIGH)){
747
                            dpi = 600;
748
                    } else if (resolution.equals(PrintQuality.DRAFT)){
749
                            dpi = 72;
750
                    }
751

752

753
                    try {
754
                            prepareDrawing(null, g, viewPort);
755
                            ArrayList<String> fieldList = new ArrayList<String>();
756
                            String[] aux;
757

758
                            // fields from legend
759
                            if (legend instanceof IClassifiedVectorLegend) {
760
                                    aux = ((IClassifiedVectorLegend) legend).
761
                                                                            getClassifyingFieldNames();
762
                                    for (int i = 0; i < aux.length; i++) {
763
                                            fieldList.add(aux[i]);
764
                                    }
765
                            }
766

767
                            // fields from labeling
768
                            if (isLabeled()) {
769
                                    aux = getLabelingStrategy().getUsedFields();
770
                                    for (int i = 0; i < aux.length; i++) {
771
                                            fieldList.add(aux[i]);
772
                                    }
773
                            }
774

775
                            ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
776

777
                            // if layer has map levels it will use a ZSort
778
                            boolean useZSort = zSort != null && zSort.isUsingZSort();
779

780

781
                            int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1;
782
                            for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) {
783
                                    // Get the iterator over the visible features
784
                                    IFeatureIterator it = getSource().getFeatureIterator(
785
                                                    viewPort.getAdjustedExtent(),
786
                                                    fieldList.toArray(new String[fieldList.size()]),
787
                                                    viewPort.getProjection(),
788
                                                    true);
789

790
                                    // Iteration over each feature
791
                                    while ( !cancel.isCanceled() && it.hasNext()) {
792
                                            IFeature feat = it.next();
793
                                            IGeometry geom = feat.getGeometry();
794

795
                                            // retreive the symbol associated to such feature
796
                                            ISymbol sym = legend.getSymbolByFeature(feat);
797

798
                                            if (useZSort) {
799
                                                    // Check if this symbol is a multilayer
800
                                                        if (sym instanceof IMultiLayerSymbol) {
801
                                                                // if so, get the layer corresponding to the current
802
                                                                // level. If none, continue to next iteration
803
                                                                IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
804
                                                                for (int i = 0; i < mlSym.getLayerCount(); i++) {
805
                                                                        ISymbol mySym = mlSym.getLayer(i);
806
                                                                        if (zSort.getSymbolLevel(mySym) == mapPass) {
807
                                                                                sym = mySym;
808
                                                                                break;
809
                                                                        }
810
                                                                        System.out.println("avoided layer "+i+"of symbol '"+mlSym.getDescription()+"' (pass "+mapPass+")");
811
                                                                }
812

813
                                                                if (sym == null) {
814
                                                                        continue;
815
                                                                }
816
                                                        } else {
817
                                                                // else, just draw the symbol in its level
818
                                                                if (zSort.getSymbolLevel(sym) != mapPass) {
819
                                                                        System.out.println("avoided single layer symbol '"+sym.getDescription()+"' (pass "+mapPass+")");
820
                                                                        continue;
821
                                                                }
822
                                                        }
823
                                            }
824

825
                                            // Check if this symbol is sized with CartographicSupport
826
                                            CartographicSupport csSym = null;
827
                                            int symbolType = sym.getSymbolType();
828
                                            boolean bDrawCartographicSupport = false;
829

830
                                            if (   symbolType == FShape.POINT
831
                                                            || symbolType == FShape.LINE
832
                                                            || sym instanceof CartographicSupport) {
833

834
                                                    csSym = (CartographicSupport) sym;
835
                                                    bDrawCartographicSupport = (csSym.getUnit() != -1);
836
                                            }
837

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

840
                                            if (!bDrawCartographicSupport) {
841
                                                    geom.drawInts(g, viewPort, sym, null);
842
                                            } else {
843
                                                    geom.drawInts(g, viewPort, dpi, (CartographicSupport) csSym);
844
                                            }
845

846
                                    }
847
                                    it.closeIterator();
848
                            }
849
                    } catch (ReadDriverException e) {
850
                            this.setVisible(false);
851
                            this.setActive(false);
852
                            throw e;
853
                    }
854
        */
855

    
856

    
857
            // TEST METHOD
858
            boolean bDrawShapes = true;
859
            if (legend instanceof SingleSymbolLegend) {
860
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
861
            }
862

    
863

    
864
            if (bDrawShapes) {
865

    
866
                    try {
867
                            double dpi = 72;
868

    
869
                            PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
870
                            if (resolution.equals(PrintQuality.NORMAL)){
871
                                    dpi = 300;
872
                            } else if (resolution.equals(PrintQuality.HIGH)){
873
                                    dpi = 600;
874
                            } else if (resolution.equals(PrintQuality.DRAFT)){
875
                                    dpi = 72;
876
                            }
877
//                            ArrayList fieldList = new ArrayList();
878
//                            String[] aux;
879
//
880
//                            // fields from legend
881
//                            if (legend instanceof IClassifiedVectorLegend) {
882
//                                    aux = ((IClassifiedVectorLegend) legend).
883
//                                    getClassifyingFieldNames();
884
//                                    for (int i = 0; i < aux.length; i++) {
885
//                                            fieldList.add(aux[i]);
886
//                                    }
887
//                            }
888
//
889
//                            // fields from labeling
890
//                            if (isLabeled()) {
891
//                                    aux = getLabelingStrategy().getUsedFields();
892
//                                    for (int i = 0; i < aux.length; i++) {
893
//                                            fieldList.add(aux[i]);
894
//                                    }
895
//                            }
896

    
897
                            ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
898

    
899
                            // if layer has map levels it will use a ZSort
900
                            boolean useZSort = zSort != null && zSort.isUsingZSort();
901

    
902

    
903
                            int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1;
904
                            for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) {
905
                                    // Get the iterator over the visible features
906
                                FeatureStore featureStore=getFeatureStore();
907
                                // Get the iterator over the visible features
908
                                String featureFilter = null;
909

    
910
                                if (!viewPort.getAdjustedExtent().contains((Envelope)featureStore.getMetadata().get("extent"))) {
911
                                            featureFilter=this.getDataStoreFilterForGeomerty(
912
                                                    viewPort.getAdjustedExtent().getGeometry(),
913
                                                    featureStore.getDefaultFeatureType().getDefaultGeometry(),
914
                                                    null);
915
                                    }
916
                                String[] fieldNames=null;
917
                                if (legend instanceof IClassifiedVectorLegend){
918
                                        String[] classified=((IClassifiedVectorLegend)legend).getClassifyingFieldNames();
919
                                        fieldNames=new String[classified.length+1];
920
                                        fieldNames[0]=featureStore.getDefaultFeatureType().getDefaultGeometry();
921
                                        for (int i = 1; i < fieldNames.length; i++) {
922
                                                    fieldNames[i]=classified[i-1];
923
                                            }
924

    
925
                                }else{
926
                                        fieldNames=new String[]{featureStore.getDefaultFeatureType().getDefaultGeometry()};
927
                                }
928

    
929

    
930
                                FeatureCollection featureCollection=null;
931
                                featureCollection = (FeatureCollection)featureStore.getDataCollection(
932
                                                fieldNames,
933
                                                featureFilter,//filter
934
                                                null);//order
935
                                Iterator it = featureCollection.iterator();
936

    
937
//                                                    viewPort.getAdjustedExtent(),
938
//                                                    fieldList.toArray(new String[fieldList.size()]),
939
//                                                    viewPort.getProjection(),
940
//                                                    true);
941

    
942
                                    // Iteration over each feature
943
                                    while ( !cancel.isCanceled() && it.hasNext()) {
944
                                            Feature feat = (Feature)it.next();
945
                                            Geometry geom = (Geometry)feat.getDefaultGeometry();
946

    
947
                                            // retreive the symbol associated to such feature
948
                                            ISymbol sym = legend.getSymbolByFeature(feat);
949

    
950
                                            if (useZSort) {
951
                                                    // Check if this symbol is a multilayer
952
                                                    if (sym instanceof IMultiLayerSymbol) {
953
                                                            // if so, get the layer corresponding to the current
954
                                                            // level. If none, continue to next iteration
955
                                                            IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
956
                                                            for (int i = 0; i < mlSym.getLayerCount(); i++) {
957
                                                                    ISymbol mySym = mlSym.getLayer(i);
958
                                                                    if (zSort.getSymbolLevel(mySym) == mapPass) {
959
                                                                            sym = mySym;
960
                                                                            break;
961
                                                                    }
962
                                                                    System.out.println("avoided layer "+i+"of symbol '"+mlSym.getDescription()+"' (pass "+mapPass+")");
963
                                                            }
964

    
965
                                                            if (sym == null) {
966
                                                                    continue;
967
                                                            }
968
                                                    } else {
969
                                                            // else, just draw the symbol in its level
970
                                                            if (zSort.getSymbolLevel(sym) != mapPass) {
971
                                                                    System.out.println("avoided single layer symbol '"+sym.getDescription()+"' (pass "+mapPass+")");
972
                                                                    continue;
973
                                                            }
974
                                                    }
975
                                            }
976

    
977
                                            // Check if this symbol is sized with CartographicSupport
978
                                            CartographicSupport csSym = null;
979
                                            int symbolType = sym.getSymbolType();
980
                                            boolean bDrawCartographicSupport = false;
981

    
982
                                            if (   symbolType == Geometry.TYPES.POINT
983
                                                            || symbolType == Geometry.TYPES.CURVE
984
                                                            || sym instanceof CartographicSupport) {
985

    
986
                                                    csSym = (CartographicSupport) sym;
987
                                                    bDrawCartographicSupport = (csSym.getUnit() != -1);
988
                                            }
989

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

    
992
                                            if (!bDrawCartographicSupport) {
993
                                                        DrawOperationContext doc=new DrawOperationContext();
994
                                                        doc.setGraphics(g);
995
                                                        doc.setViewPort(viewPort);
996
                                                        doc.setSymbol(sym);
997
                                                        doc.setCancellable(cancel);
998
                                                        geom.invokeOperation(DrawInts.CODE,doc);
999
                                                } else {
1000
                                                        DrawOperationContext doc=new DrawOperationContext();
1001
                                                        doc.setGraphics(g);
1002
                                                        doc.setViewPort(viewPort);
1003
                                                        doc.setSymbol((ISymbol)csSym);
1004
                                                        doc.setCancellable(cancel);
1005
                                                        doc.setDPI(dpi);
1006
                                                        geom.invokeOperation(DrawInts.CODE,doc);
1007
                                                }
1008
                                    }
1009
//                                    it.closeIterator();
1010
                                    it=null;
1011
                                    featureCollection.dispose();
1012
                            }
1013
                    } catch (ReadException e) {
1014
                            this.setVisible(false);
1015
                            this.setActive(false);
1016
                            throw e;
1017
                    } catch (GeometryOperationNotSupportedException e) {
1018
                            this.setVisible(false);
1019
                            this.setActive(false);
1020
                            throw new ReadException(getName(),e);
1021
                        } catch (GeometryOperationException e) {
1022
                                this.setVisible(false);
1023
                            this.setActive(false);
1024
                            throw new ReadException(getName(),e);
1025
                        } catch (BaseException e) {
1026
                                // TODO Auto-generated catch block
1027
                                e.printStackTrace();
1028
                        }
1029
            }
1030
    }
1031

    
1032

    
1033
//    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
1034
//            double scale, PrintRequestAttributeSet properties) throws ReadException {
1035
//            if (forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD) {
1036
//                    _print(g, viewPort, cancel, scale, properties);
1037
//            } else {
1038
////                    moved up to Flayers
1039
////                    if (isVisible() && isWithinScale(scale)) {
1040
//                            Strategy strategy = StrategyManager.getStrategy(this);
1041
//
1042
//                            strategy.print(g, viewPort, cancel, properties);
1043
//                            ILabelingStrategy labeling;
1044
//                            if ( (labeling = getLabelingStrategy() ) != null) {
1045
//                                    // contains labels
1046
//                                    labeling.print(g, viewPort, cancel, properties);
1047
//                            }
1048
////                    }
1049
//            }
1050
//    }
1051

    
1052
//    public void deleteSpatialIndex() {
1053
//        //must we delete possible spatial indexes files?
1054
//        spatialIndex = null;
1055
//    }
1056

    
1057
   /**
1058
    * <p>
1059
    * Creates an spatial index associated to this layer.
1060
    * The spatial index will used
1061
    * the native projection of the layer, so if the layer is reprojected, it will
1062
    * be ignored.
1063
    * </p>
1064
    * @param cancelMonitor instance of CancellableMonitorable that allows
1065
    * to monitor progress of spatial index creation, and cancel the process
1066
    */
1067
//    public void createSpatialIndex(CancellableMonitorable cancelMonitor){
1068
//         // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
1069
//        // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
1070
//        // para que acepten recorrer sin geometria, solo con rectangulos.
1071
//
1072
//        //If this vectorial layer is based in a spatial database, the spatial
1073
//        //index is already implicit. We only will index file drivers
1074
//        ReadableVectorial va = getSource();
1075
//        //We must think in non spatial databases, like HSQLDB
1076
//        if(!(va instanceof VectorialFileAdapter)){
1077
//            return;
1078
//        }
1079
//        if (!(va.getDriver() instanceof BoundedShapes)) {
1080
//            return;
1081
//        }
1082
//        File file = ((VectorialFileAdapter) va).getFile();
1083
//        String fileName = file.getAbsolutePath();
1084
//        ISpatialIndex localCopy = null;
1085
//        try {
1086
//            va.start();
1087
//            localCopy = new QuadtreeGt2(fileName, "NM", va.getFullExtent(),
1088
//                    va.getShapeCount(), true);
1089
//
1090
//        } catch (SpatialIndexException e1) {
1091
//            // Probably we dont have writing permissions
1092
//            String directoryName = System.getProperty("java.io.tmpdir");
1093
//            File newFile = new File(directoryName +
1094
//                    File.separator +
1095
//                    file.getName());
1096
//            String newFileName = newFile.getName();
1097
//            try {
1098
//                localCopy = new QuadtreeGt2(newFileName, "NM", va.getFullExtent(),
1099
//                        va.getShapeCount(), true);
1100
//            } catch (SpatialIndexException e) {
1101
//                // if we cant build a file based spatial index, we'll build
1102
//                // a pure memory spatial index
1103
//                localCopy = new QuadtreeJts();
1104
//            } catch (ReadException e) {
1105
//                localCopy = new QuadtreeJts();
1106
//            }
1107
//
1108
//        } catch(Exception e){
1109
//            e.printStackTrace();
1110
//        }//try
1111
//        BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
1112
//        try {
1113
//            for (int i=0; i < va.getShapeCount(); i++)
1114
//            {
1115
//                if(cancelMonitor != null){
1116
//                    if(cancelMonitor.isCanceled())
1117
//                        return;
1118
//                    cancelMonitor.reportStep();
1119
//                }
1120
//                Rectangle2D r = shapeBounds.getShapeBounds(i);
1121
//                if(r != null)
1122
//                    localCopy.insert(r, i);
1123
//            } // for
1124
//            va.stop();
1125
//            if(localCopy instanceof IPersistentSpatialIndex)
1126
//                ((IPersistentSpatialIndex) localCopy).flush();
1127
//            spatialIndex = localCopy;
1128
//            //vectorial adapter needs a reference to the spatial index, to solve
1129
//            //request for feature iteration based in spatial queries
1130
//            source.setSpatialIndex(spatialIndex);
1131
//        } catch (ReadException e) {
1132
//            // TODO Auto-generated catch block
1133
//            e.printStackTrace();
1134
//        }
1135
//    }
1136

    
1137
//    public void createSpatialIndex() {
1138
//        createSpatialIndex(null);
1139
//    }
1140

    
1141
//    public void process(FeaturesVisitor visitor, Rectangle2D rect)
1142
//            throws ReadException {
1143
//        Strategy s = StrategyManager.getStrategy(this);
1144
//        s.process(visitor, rect);
1145
//    }
1146

    
1147
//    public FBitSet queryByRect(Rectangle2D rect) throws ReadException {
1148
//        Strategy s = StrategyManager.getStrategy(this);
1149
//
1150
//        return s.queryByRect(rect);
1151
//    }
1152

    
1153
//    public FBitSet queryByPoint(Point2D p, double tolerance)
1154
//            throws ReadException {
1155
//        Strategy s = StrategyManager.getStrategy(this);
1156
//        return s.queryByPoint(p, tolerance);
1157
//    }
1158

    
1159
//    public FBitSet queryByShape(Geometry g, int relationship)
1160
//            throws ReadException {
1161
//        Strategy s = StrategyManager.getStrategy(this);
1162
//        return s.queryByShape(g, relationship);
1163
//    }
1164

    
1165
//    public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws ReadDriverException, VisitorException {
1166
//        Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p);
1167
//        FBitSet bs = queryByPoint(pReal, tolerance);
1168
//        VectorialXMLItem[] item = new VectorialXMLItem[1];
1169
//        item[0] = new VectorialXMLItem(bs, this);
1170
//
1171
//        return item;
1172
//    }
1173

    
1174
    public void setLegend(IVectorLegend r) throws LegendLayerException {
1175
        IVectorLegend oldLegend = legend;
1176
        legend = r;
1177
        try {
1178
            legend.setFeatureStore(getFeatureStore());
1179
        } catch (ReadException e1) {
1180
            throw new LegendLayerException(getName(),e1);
1181
        }
1182
        LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
1183
                oldLegend, legend);
1184
        callLegendChanged(e);
1185
    }
1186

    
1187
    /**
1188
     * Devuelve la Leyenda de la capa.
1189
     *
1190
     * @return Leyenda.
1191
     */
1192
    public ILegend getLegend() {
1193
        return legend;
1194
    }
1195

    
1196
    /**
1197
     * Devuelve el tipo de shape que contiene la capa.
1198
     *
1199
     * @return tipo de shape.
1200
     *
1201
     * @throws DriverException
1202
     */
1203
    public int getShapeType() throws ReadException {
1204
        if (typeShape == -1) {
1205
//            getSource().start();
1206
            typeShape = ((FeatureType)((FeatureStore)getDataStore()).getFeatureTypes().get(0)).getGeometryTypes()[0];
1207
//            getSource().stop();
1208
        }
1209

    
1210
        return typeShape;
1211
    }
1212

    
1213
    public XMLEntity getXMLEntity() throws XMLException {
1214
//        if (!this.isAvailable() && this.orgXMLEntity != null) {
1215
//            return this.orgXMLEntity;
1216
//        }
1217
//        XMLEntity xml = super.getXMLEntity();
1218
//        if (getLegend()!=null)
1219
//            xml.addChild(getLegend().getXMLEntity());
1220
//        try {
1221
//            if (getRecordset()!=null)
1222
//                xml.addChild(getRecordset().getSelectionSupport().getXMLEntity());
1223
//        } catch (ReadException e1) {
1224
//            e1.printStackTrace();
1225
//            throw new XMLException(e1);
1226
//        }
1227
//        // Repongo el mismo ReadableVectorial m?s abajo para cuando se guarda el proyecto.
1228
//        ReadableVectorial rv=getSource();
1229
//        xml.putProperty("type", "vectorial");
1230
//        if (source instanceof VectorialEditableAdapter) {
1231
//            setSource(((VectorialEditableAdapter) source).getOriginalAdapter());
1232
//        }
1233
//        if (source instanceof VectorialFileAdapter) {
1234
//            xml.putProperty("type", "vectorial");
1235
//            xml.putProperty("file", ((VectorialFileAdapter) source)
1236
//                    .getFile());
1237
//            try {
1238
//                xml.putProperty("recordset-name", source.getRecordset()
1239
//                        .getName());
1240
//            } catch (ReadException e) {
1241
//                throw new XMLException(e);
1242
//            } catch (RuntimeException e) {
1243
//                e.printStackTrace();
1244
//            }
1245
//        } else if (source instanceof VectorialDBAdapter) {
1246
//            xml.putProperty("type", "vectorial");
1247
//
1248
//            IVectorialDatabaseDriver dbDriver = (IVectorialDatabaseDriver) source
1249
//                    .getDriver();
1250
//
1251
//            // Guardamos el nombre del driver para poder recuperarlo
1252
//            // con el DriverManager de Fernando.
1253
//            xml.putProperty("db", dbDriver.getName());
1254
//            try {
1255
//                xml.putProperty("recordset-name", source.getRecordset()
1256
//                        .getName());
1257
//            } catch (ReadException e) {
1258
//                throw new XMLException(e);
1259
//            } catch (RuntimeException e) {
1260
//                e.printStackTrace();
1261
//            }
1262
//            xml.addChild(dbDriver.getXMLEntity()); // Tercer child. Antes hemos
1263
//                                                    // metido la leyenda y el
1264
//                                                    // selection support
1265
//        } else if (source instanceof VectorialAdapter) {
1266
//            // Se supone que hemos hecho algo gen?rico.
1267
//            xml.putProperty("type", "vectorial");
1268
//
1269
//            VectorialDriver driver = source.getDriver();
1270
//
1271
//            // Guardamos el nombre del driver para poder recuperarlo
1272
//            // con el DriverManager de Fernando.
1273
//            xml.putProperty("other", driver.getName());
1274
//            // try {
1275
//            try {
1276
//                xml.putProperty("recordset-name", source.getRecordset()
1277
//                        .getName());
1278
//            } catch (ReadException e) {
1279
//                throw new XMLException(e);
1280
//            } catch (RuntimeException e) {
1281
//                e.printStackTrace();
1282
//            }
1283
//            if (driver instanceof IPersistence) {
1284
//                // xml.putProperty("className", driver.getClass().getName());
1285
//                    IPersistence persist = (IPersistence) driver;
1286
//                xml.addChild(persist.getXMLEntity()); // Tercer child. Antes
1287
//                                                        // hemos metido la
1288
//                                                        // leyenda y el
1289
//                                                        // selection support
1290
//            }
1291
//        }
1292
//        if (rv!=null)
1293
//            setSource(rv);
1294
//        xml.putProperty("driverName", source.getDriver().getName());
1295
//        if (bHasJoin)
1296
//            xml.putProperty("hasJoin", "true");
1297
//
1298
//        // properties from ILabelable
1299
//        xml.putProperty("isLabeled", isLabeled);
1300
//        if (strategy != null) {
1301
//            XMLEntity strategyXML = strategy.getXMLEntity();
1302
//            strategyXML.putProperty("Strategy", strategy.getClassName());
1303
//            xml.addChild(strategy.getXMLEntity());
1304
//        }
1305
//        xml.addChild(getLinkProperties().getXMLEntity());
1306
//        return xml;
1307
            return null;
1308
    }
1309
    /*
1310
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
1311
     */
1312
    public void setXMLEntity(XMLEntity xml) throws XMLException {
1313
//        try {
1314
//                    super.setXMLEntity(xml);
1315
//                    XMLEntity legendXML = xml.getChild(0);
1316
//                    IVectorLegend leg = LegendFactory.createFromXML(legendXML);
1317
//                    /* (jaume) begin patch;
1318
//                     * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1319
//                     * no longer managed by the Legend but by the ILabelingStrategy. The
1320
//                     * following allows restoring older projects' labelings.
1321
//                     */
1322
//                    if (legendXML.contains("labelFieldName")) {
1323
//                            String labelTextField = legendXML.getStringProperty("labelFieldName");
1324
//                            if (labelTextField != null) {
1325
//                                    AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
1326
//                                    labeling.setLayer(this);
1327
//                                    labeling.setTextField(legendXML.getStringProperty("labelFieldName"));
1328
//                                    labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
1329
//                                    labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
1330
//                                    this.setLabelingStrategy(labeling);
1331
//                                    this.setIsLabeled(true);
1332
//                            }
1333
//                    }
1334
//                    /* end patch */
1335
//                    try {
1336
//                            getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
1337
//                            // JMVIVO: Esto sirve para algo????
1338
//                            String recordsetName = xml.getStringProperty("recordset-name");
1339
//
1340
//                            LayerFactory.getDataSourceFactory().changeDataSourceName(
1341
//                                            getSource().getRecordset().getName(), recordsetName);
1342
//                    } catch (NoSuchTableException e1) {
1343
//                            this.setAvailable(false);
1344
//                            throw new XMLException(e1);
1345
//                    } catch (ReadException e1) {
1346
//                            this.setAvailable(false);
1347
//                            throw new XMLException(e1);
1348
//                    }
1349
//                    // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
1350
//                    // el final
1351
//                    // de la lectura del proyecto
1352
//                    if (xml.contains("hasJoin")) {
1353
//                            setIsJoined(true);
1354
//                            PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
1355
//                    } else {
1356
//                            try {
1357
//                                    setLegend(leg);
1358
//                            } catch (LegendLayerException e) {
1359
//                                    throw new XMLException(e);
1360
//                            }
1361
//                    }
1362
//
1363
//                    // set properties for ILabelable
1364
//                    XMLEntity labelingXML = xml.firstChild("id", "LabelingStrategy");
1365
//                    if (labelingXML!= null) {
1366
//                            isLabeled = true;
1367
//                            try {
1368
//                                    this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this);
1369
//                            } catch (NotExistInXMLEntity neXMLEX) {
1370
//                                    // no strategy was set, just continue;
1371
//                                    logger.warn("Reached what should be unreachable code");
1372
//                            }
1373
//                    } else {
1374
//                            isLabeled = false;
1375
//                    }
1376
//
1377
//                    XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
1378
//                    if (xmlLinkProperties != null){
1379
//                            getLinkProperties().setXMLEntity(xmlLinkProperties);
1380
//                    }
1381
//
1382
//            } catch (XMLException e) {
1383
//                    this.setAvailable(false);
1384
//                    this.orgXMLEntity = xml;
1385
//            } catch (Exception e) {
1386
//                    e.printStackTrace();
1387
//                    this.setAvailable(false);
1388
//                    this.orgXMLEntity = xml;
1389
//
1390
//            }
1391
//
1392

    
1393
    }
1394

    
1395
    public void setXMLEntityNew(XMLEntity xml) throws XMLException {
1396
//        try {
1397
//            super.setXMLEntity(xml);
1398
//
1399
//            XMLEntity legendXML = xml.getChild(0);
1400
//            IVectorLegend leg = LegendFactory.createFromXML(legendXML);
1401
//            /* (jaume) begin patch;
1402
//             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1403
//             * no longer managed by the Legend but by the ILabelingStrategy. The
1404
//             * following allows restoring older projects' labelings.
1405
//             */
1406
//            if (legendXML.contains("labelFieldHeight")) {
1407
//                AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
1408
//                labeling.setLayer(this);
1409
//                labeling.setTextField(legendXML.getStringProperty("labelFieldHeight"));
1410
//                labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
1411
//                this.setLabelingStrategy(labeling);
1412
//                this.setIsLabeled(true);
1413
//              }
1414
//            /* end patch */
1415
//            try {
1416
//                getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
1417
//
1418
//                this.setLoadSelection(xml.getChild(1));
1419
//            } catch (ReadException e1) {
1420
//                this.setAvailable(false);
1421
//                throw new XMLException(e1);
1422
//            }
1423
//            // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
1424
//            // el final
1425
//            // de la lectura del proyecto
1426
//            if (xml.contains("hasJoin")) {
1427
//                setIsJoined(true);
1428
//                PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
1429
//            } else {
1430
//                this.setLoadLegend(leg);
1431
//            }
1432
//
1433
//        } catch (XMLException e) {
1434
//            this.setAvailable(false);
1435
//            this.orgXMLEntity = xml;
1436
//        } catch (Exception e) {
1437
//            this.setAvailable(false);
1438
//            this.orgXMLEntity = xml;
1439
//        }
1440

    
1441

    
1442
    }
1443

    
1444

    
1445
    /**
1446
     * Sobreimplementaci?n del m?todo toString para que las bases de datos
1447
     * identifiquen la capa.
1448
     *
1449
     * @return DOCUMENT ME!
1450
     */
1451
    public String toString() {
1452
        /*
1453
         * Se usa internamente para que la parte de datos identifique de forma
1454
         * un?voca las tablas
1455
         */
1456
        String ret = super.toString();
1457

    
1458
        return "layer" + ret.substring(ret.indexOf('@') + 1);
1459
    }
1460

    
1461
    public boolean isJoined() {
1462
        return bHasJoin;
1463
    }
1464

    
1465
    /**
1466
     * Returns if a layer is spatially indexed
1467
     *
1468
     * @return if this layer has the ability to proces spatial queries without
1469
     *         secuential scans.
1470
     */
1471
//    public boolean isSpatiallyIndexed() {
1472
//        ReadableVectorial source = getSource();
1473
//        if (source instanceof ISpatialDB)
1474
//            return true;
1475
//
1476
////FIXME azabala
1477
///*
1478
// * Esto es muy dudoso, y puede cambiar.
1479
// * Estoy diciendo que las que no son fichero o no son
1480
// * BoundedShapes estan indexadas. Esto es mentira, pero
1481
// * as? quien pregunte no querr? generar el indice.
1482
// * Esta por ver si interesa generar el indice para capas
1483
// * HSQLDB, WFS, etc.
1484
// */
1485
//        if(!(source instanceof VectorialFileAdapter)){
1486
//            return true;
1487
//        }
1488
//        if (!(source.getDriver() instanceof BoundedShapes)) {
1489
//            return true;
1490
//        }
1491
//
1492
//        if (getISpatialIndex() != null)
1493
//            return true;
1494
//        return false;
1495
//    }
1496

    
1497
    public void setIsJoined(boolean hasJoin) {
1498
        bHasJoin = hasJoin;
1499
    }
1500

    
1501
//    /**
1502
//     * @return Returns the spatialIndex.
1503
//     */
1504
//    public ISpatialIndex getISpatialIndex() {
1505
//        return spatialIndex;
1506
//    }
1507
//    /**
1508
//     * Sets the spatial index. This could be useful if, for some
1509
//     * reasons, you want to work with a distinct spatial index
1510
//     * (for example, a spatial index which could makes nearest
1511
//     * neighbour querys)
1512
//     * @param spatialIndex
1513
//     */
1514
//    public void setISpatialIndex(ISpatialIndex spatialIndex){
1515
//        this.spatialIndex = spatialIndex;
1516
//    }
1517

    
1518
//    public SelectableDataSource getRecordset() throws ReadException {
1519
//        if (!this.isAvailable()) return null;
1520
//        if (sds == null) {
1521
//
1522
//                SelectableDataSource ds = source.getRecordset();
1523
//
1524
//                if (ds == null) {
1525
//                    return null;
1526
//                }
1527
//
1528
//                sds = ds;
1529
//                sds.setSelectionSupport(selectionSupport);
1530
//
1531
//        }
1532
//        return sds;
1533
//    }
1534

    
1535
    public void setEditing(boolean b) throws StartEditionLayerException {
1536
        super.setEditing(b);
1537
        try {
1538
                        getDataStore().startEditing();
1539
                } catch (ReadException e) {
1540
                        throw new StartEditionLayerException(getName(),e);
1541
                }
1542
//        try {
1543
//            if (b) {
1544
//                VectorialEditableAdapter vea = null;
1545
//                // TODO: Qu? pasa si hay m?s tipos de adapters?
1546
//                // FJP: Se podr?a pasar como argumento el
1547
//                // VectorialEditableAdapter
1548
//                // que se quiera usar para evitar meter c?digo aqu? de este
1549
//                // estilo.
1550
//                if (getSource() instanceof VectorialDBAdapter) {
1551
//                    vea = new VectorialEditableDBAdapter();
1552
//                } else if (this instanceof FLyrAnnotation) {
1553
//                    vea = new AnnotationEditableAdapter(
1554
//                            (FLyrAnnotation) this);
1555
//                } else {
1556
//                    vea = new VectorialEditableAdapter();
1557
//                }
1558
//                vea.setOriginalVectorialAdapter(getSource());
1559
////                                azo: implementations of readablevectorial need
1560
//                //references of projection and spatial index
1561
//                vea.setProjection(getProjection());
1562
//                vea.setSpatialIndex(spatialIndex);
1563
//
1564
//
1565
//                // /vea.setSpatialIndex(getSpatialIndex());
1566
//                // /vea.setFullExtent(getFullExtent());
1567
//                vea.setCoordTrans(getCoordTrans());
1568
//                vea.startEdition(EditionEvent.GRAPHIC);
1569
//                setSource(vea);
1570
//                getRecordset().setSelectionSupport(
1571
//                        vea.getOriginalAdapter().getRecordset()
1572
//                                .getSelectionSupport());
1573
//
1574
//            } else {
1575
//                VectorialEditableAdapter vea = (VectorialEditableAdapter) getSource();
1576
//                setSource(vea.getOriginalAdapter());
1577
//            }
1578
//            // Si tenemos una leyenda, hay que pegarle el cambiazo a su
1579
//            // recordset
1580
//            setRecordset(getSource().getRecordset());
1581
//            if (getLegend() instanceof IVectorLegend) {
1582
//                IVectorLegend ley = (IVectorLegend) getLegend();
1583
//                ley.setDataSource(getSource().getRecordset());
1584
//                // Esto lo pongo para evitar que al dibujar sobre un
1585
//                // dxf, dwg, o dgn no veamos nada. Es debido al checkbox
1586
//                // de la leyenda de textos "dibujar solo textos".
1587
////jaume
1588
////                                if (!(getSource().getDriver() instanceof IndexedShpDriver)){
1589
////                                        FSymbol symbol=new FSymbol(getShapeType());
1590
////                                        symbol.setFontSizeInPixels(false);
1591
////                                        symbol.setFont(new Font("SansSerif", Font.PLAIN, 9));
1592
////                                        Color color=symbol.getColor();
1593
////                                        int alpha=symbol.getColor().getAlpha();
1594
////                                        if (alpha>250) {
1595
////                                                symbol.setColor(new Color(color.getRed(),color.getGreen(),color.getBlue(),100));
1596
////                                        }
1597
////                                        ley.setDefaultSymbol(symbol);
1598
////                                }
1599
////jaume//
1600
//                ley.useDefaultSymbol(true);
1601
//            }
1602
//        } catch (ReadDriverException e) {
1603
//            throw new StartEditionLayerException(getName(),e);
1604
//        } catch (FieldNotFoundException e) {
1605
//            throw new StartEditionLayerException(getName(),e);
1606
//        } catch (StartWriterVisitorException e) {
1607
//            throw new StartEditionLayerException(getName(),e);
1608
//        }
1609

    
1610
        setSpatialCacheEnabled(b);
1611
        callEditionChanged(LayerEvent
1612
                .createEditionChangedEvent(this, "edition"));
1613

    
1614
    }
1615

    
1616
    /**
1617
     * Para cuando haces una uni?n, sustituyes el recorset por el nuevo. De esta
1618
     * forma, podr?s poner leyendas basadas en el nuevo recordset
1619
     *
1620
     * @param newSds
1621
     */
1622
//    public void setRecordset(SelectableDataSource newSds) {
1623
//        sds = newSds;
1624
//        sds.setSelectionSupport(selectionSupport);
1625
//    }
1626

    
1627
    public void clearSpatialCache()
1628
    {
1629
        spatialCache.clearAll();
1630
    }
1631

    
1632
    public boolean isSpatialCacheEnabled() {
1633
        return spatialCacheEnabled;
1634
    }
1635

    
1636
    public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
1637
        this.spatialCacheEnabled = spatialCacheEnabled;
1638
    }
1639

    
1640
    public SpatialCache getSpatialCache() {
1641
        return spatialCache;
1642
    }
1643

    
1644
    /**
1645
     * Siempre es un numero mayor de 1000
1646
     * @param maxFeatures
1647
     */
1648
    public void setMaxFeaturesInEditionCache(int maxFeatures) {
1649
        if (maxFeatures > spatialCache.getMaxFeatures()) {
1650
                        spatialCache.setMaxFeatures(maxFeatures);
1651
                }
1652

    
1653
    }
1654

    
1655
    /**
1656
     * This method returns a boolean that is used by the FPopMenu
1657
     * to make visible the properties menu or not. It is visible by
1658
     * default, and if a later don't have to show this menu only
1659
     * has to override this method.
1660
     * @return
1661
     * If the properties menu is visible (or not)
1662
     */
1663
    public boolean isPropertiesMenuVisible(){
1664
        return true;
1665
    }
1666

    
1667
    public void reload() throws ReloadLayerException {
1668
        this.setAvailable(true);
1669
        super.reload();
1670
//        try {
1671
//            this.source.getDriver().reload();
1672
//            if (this.getLegend() == null) {
1673
//                if (this.getRecordset().getDriver() instanceof WithDefaultLegend) {
1674
//                    WithDefaultLegend aux = (WithDefaultLegend) this.getRecordset().getDriver();
1675
//                    this.setLegend((IVectorLegend) aux.getDefaultLegend());
1676
//                    this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
1677
//                } else {
1678
//                    this.setLegend(LegendFactory.createSingleSymbolLegend(
1679
//                            this.getShapeType()));
1680
//                }
1681
//            }
1682
//
1683
//        } catch (LegendLayerException e) {
1684
//            this.setAvailable(false);
1685
//            throw new ReloadLayerException(getName(),e);
1686
//        } catch (ReadException e) {
1687
//            this.setAvailable(false);
1688
//            throw new ReloadLayerException(getName(),e);
1689
//        }
1690

    
1691
    }
1692

    
1693
    protected void setLoadSelection(XMLEntity xml) {
1694
        this.loadSelection = xml;
1695
    }
1696

    
1697
    protected void setLoadLegend(IVectorLegend legend) {
1698
        this.loadLegend = legend;
1699
    }
1700

    
1701
    protected void putLoadSelection() throws XMLException {
1702
//        if (this.loadSelection == null) return;
1703
//        try {
1704
//            this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
1705
//        } catch (ReadDriverException e) {
1706
//            throw new XMLException(e);
1707
//        }
1708
//        this.loadSelection = null;
1709

    
1710
    }
1711
    protected void putLoadLegend() throws LegendLayerException {
1712
        if (this.loadLegend == null) {
1713
                        return;
1714
                }
1715
        this.setLegend(this.loadLegend);
1716
        this.loadLegend = null;
1717
    }
1718

    
1719
    protected void cleanLoadOptions() {
1720
        this.loadLegend = null;
1721
        this.loadSelection = null;
1722
    }
1723

    
1724
    public boolean isWritable() {
1725
        return getDataStore().isEditable();
1726
//            VectorialDriver drv = getSource().getDriver();
1727
//        if (!drv.isWritable())
1728
//            return false;
1729
//        if (drv instanceof IWriteable)
1730
//        {
1731
//            IWriter writer = ((IWriteable)drv).getWriter();
1732
//            if (writer != null)
1733
//            {
1734
//                if (writer instanceof ISpatialWriter)
1735
//                    return true;
1736
//            }
1737
//        }
1738
//        return false;
1739

    
1740
    }
1741

    
1742
    public FLayer cloneLayer() throws Exception {
1743
        FLyrVect clonedLayer = new FLyrVect();
1744
        clonedLayer.setDataStore(getDataStore());
1745
        if (isJoined()) {
1746
                        clonedLayer.setIsJoined(true);
1747
//                        clonedLayer.setRecordset(getRecordset());
1748
                }
1749
        clonedLayer.setVisible(isVisible());
1750
//        clonedLayer.setISpatialIndex(getISpatialIndex());
1751
        clonedLayer.setName(getName());
1752
        clonedLayer.setCoordTrans(getCoordTrans());
1753

    
1754
        clonedLayer.setLegend((IVectorLegend)getLegend().cloneLegend());
1755

    
1756
        clonedLayer.setIsLabeled(isLabeled());
1757
        clonedLayer.setLabelingStrategy(getLabelingStrategy());
1758

    
1759
        return clonedLayer;
1760
    }
1761

    
1762

    
1763
    private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, double dpi, CartographicSupport csSym, Geometry geom, int[] xyCoords) {
1764
            return isOnePoint(graphicsTransform, viewPort, geom, xyCoords) && csSym.getCartographicSize(viewPort, dpi, null) <= 1;
1765
    }
1766

    
1767
    private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, Geometry geom, int[] xyCoords) {
1768
            boolean onePoint = false;
1769
            int type=geom.getType() % Geometry.TYPES.Z;
1770
            if (type!=Geometry.TYPES.POINT && type!=Geometry.TYPES.MULTIPOINT) {
1771

    
1772
                        Rectangle2D geomBounds = geom.getBounds2D();
1773

    
1774
                        ICoordTrans ct = getCoordTrans();
1775

    
1776
                        if (ct!=null) {
1777
//                                geomBounds = ct.getInverted().convert(geomBounds);
1778
                                geomBounds = ct.convert(geomBounds);
1779
                        }
1780

    
1781
                        double dist1Pixel = viewPort.getDist1pixel();
1782

    
1783
                        onePoint = (geomBounds.getWidth()  <= dist1Pixel
1784
                                         && geomBounds.getHeight() <= dist1Pixel);
1785

    
1786
                        if (onePoint) {
1787
                                // avoid out of range exceptions
1788
                                org.gvsig.fmap.geom.primitive.Point2D p = new org.gvsig.fmap.geom.primitive.Point2D(geomBounds.getMinX(), geomBounds.getMinY());
1789
                                p.transform(viewPort.getAffineTransform());
1790
                                p.transform(graphicsTransform);
1791
                                xyCoords[0] = (int) p.getX();
1792
                                xyCoords[1] = (int) p.getY();
1793

    
1794
                        }
1795

    
1796
                }
1797
            return onePoint;
1798
    }
1799
    /*
1800
     * jaume. Stuff from ILabeled.
1801
     */
1802
    private boolean isLabeled;
1803
    protected ILabelingStrategy strategy;
1804

    
1805
    public boolean isLabeled() {
1806
        return isLabeled;
1807
    }
1808

    
1809
    public void setIsLabeled(boolean isLabeled) {
1810
        this.isLabeled = isLabeled;
1811
    }
1812

    
1813
    public ILabelingStrategy getLabelingStrategy() {
1814
        return strategy;
1815
    }
1816

    
1817
    public void setLabelingStrategy(ILabelingStrategy strategy) {
1818
        this.strategy = strategy;
1819
    }
1820

    
1821
    public void drawLabels(BufferedImage image, Graphics2D g, ViewPort viewPort,
1822
                    Cancellable cancel, double scale, double dpi) throws ReadException {
1823
        if (strategy!=null && isWithinScale(scale)) {
1824
                strategy.draw(image, g, viewPort, cancel, dpi);
1825
        }
1826
    }
1827

    
1828

    
1829

    
1830
    //M?todos para el uso de HyperLinks en capas FLyerVect
1831

    
1832
    /**
1833
     * Return true, because a Vectorial Layer supports HyperLink
1834
     */
1835
    public boolean allowLinks()
1836
    {
1837
            return true;
1838
    }
1839

    
1840
    /**
1841
         * Returns an instance of AbstractLinkProperties that contains the information
1842
         * of the HyperLink
1843
         * @return Abstra
1844
         */
1845
    public AbstractLinkProperties getLinkProperties()
1846
    {
1847
            return linkProperties;
1848
    }
1849

    
1850
    /**
1851
         * Provides an array with URIs. Returns one URI by geometry that includes the point
1852
         * in its own geometry limits with a allowed tolerance.
1853
         * @param layer, the layer
1854
         * @param point, the point to check that is contained or not in the geometries in the layer
1855
         * @param tolerance, the tolerance allowed. Allowed margin of error to detect if the  point
1856
         *                 is contained in some geometries of the layer
1857
         * @return
1858
     * @throws ReadException
1859
     * @throws BehaviorException
1860
         */
1861
    public URI[] getLink(Point2D point, double tolerance) throws ReadException
1862
    {
1863
            //return linkProperties.getLink(this)
1864
            return linkProperties.getLink(this,point,tolerance);
1865
    }
1866
//    /**
1867
//     * @deprecated Don?t use Strategy, you should be use iterators.
1868
//     */
1869
//        public boolean isUseStrategy() {
1870
//                return useStrategy;
1871
//        }
1872
//        /**
1873
//     * @deprecated Don?t use Strategy, you should be use iterators.
1874
//     */
1875
//        public void setUseStrategy(boolean useStrategy) {
1876
//                this.useStrategy = useStrategy;
1877
//        }
1878

    
1879
        public void load() throws LoadLayerException {
1880
                super.load();
1881
//                useStrategy=forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD;
1882
        }
1883

    
1884
        public FeatureStore getFeatureStore() throws ReadException {
1885
                return (FeatureStore)getDataStore();
1886
        }
1887

    
1888
        public FeatureCollection queryByPoint(Point2D mapPoint, double tol, FeatureType featureType) throws ReadException {
1889
//                double halfTol=tol*0.5;
1890
//                Envelope envelope=new DefaultEnvelope(mapPoint.getX()-halfTol,mapPoint.getY()-halfTol,mapPoint.getX()+halfTol,mapPoint.getY()+halfTol);
1891
//                return queryByEnvelope(envelope);
1892
                Geometry geom = GeometryManager.getInstance().getGeometryFactory()
1893
                                .createCircle(mapPoint, tol);
1894

    
1895
                return queryByGeometry(geom, featureType);
1896
        }
1897

    
1898

    
1899
        public FeatureCollection queryByGeometry(Geometry geom, FeatureType featureType) throws ReadException {
1900
                try {
1901
                        return (FeatureCollection)
1902
                                getFeatureStore().getDataCollection(
1903
                                        featureType,
1904
                                        getDataStoreFilterForGeomerty(
1905
                                                        geom,
1906
                                                        featureType.getDefaultGeometry(),
1907
                                                        null),
1908
                                        null);
1909
                } catch (GeometryOperationNotSupportedException e) {
1910
                        throw new ReadException("queryByGeometry", e);
1911
                } catch (GeometryOperationException e) {
1912
                        throw new ReadException("queryByGeometry", e);
1913
                }
1914

    
1915
        }
1916

    
1917
        /*
1918
         * TODO Este metodo es de utilidad. Sacarlo de aqui?
1919
         */
1920
        public String getDataStoreFilterForGeomerty(Geometry geom,
1921
                        String geomFileName, String srs) throws ReadException,
1922
                        GeometryOperationException,
1923
                        GeometryOperationNotSupportedException {
1924
                String txtGeom;
1925

    
1926
                txtGeom = (String) geom.invokeOperation(ToWKT.CODE, null);
1927

    
1928
                if (srs == null) {
1929
                        try {
1930
                                srs = (String) getFeatureStore().getMetadata().get("srs");
1931
                        } catch (BaseException e) {
1932
                                throw new ReadException("getDataStoreFilterForGeomerty", e);
1933
                        }
1934
                }
1935

    
1936

    
1937
                return " intersects(GeomFromText('" + txtGeom + "', " + "'" + srs + "'"
1938
                                + "), " + geomFileName + ") ";
1939
        }
1940

    
1941
        public FeatureCollection queryByEnvelope(Envelope rect, FeatureType featureType)
1942
                        throws ReadException {
1943
                return this.queryByGeometry(rect.getGeometry(),featureType);
1944
        }
1945

    
1946
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws ReadException, LoadLayerException {
1947
                Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p);
1948
        FeatureCollection featureCollection = queryByPoint(pReal, tolerance, getFeatureStore().getDefaultFeatureType());
1949
        VectorialXMLItem[] item = new VectorialXMLItem[1];
1950
        item[0] = new VectorialXMLItem(featureCollection, this);
1951

    
1952
        return item;
1953
        }
1954
 }