Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / layers / vectorial / FLyrVect.java @ 24504

History | View | Annotate | Download (52.4 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.fmap.dal.DataManager;
59
import org.gvsig.fmap.dal.DataStore;
60
import org.gvsig.fmap.dal.exception.ReadException;
61
import org.gvsig.fmap.dal.feature.Feature;
62
import org.gvsig.fmap.dal.feature.FeatureSet;
63
import org.gvsig.fmap.dal.feature.FeatureStore;
64
import org.gvsig.fmap.dal.feature.FeatureType;
65
import org.gvsig.fmap.dal.impl.DefaultDataManager;
66
import org.gvsig.fmap.dal.operation.DataStoreOperationException;
67
import org.gvsig.fmap.dal.operation.DataStoreOperationNotSupportedException;
68
import org.gvsig.fmap.geom.Geometry;
69
import org.gvsig.fmap.geom.GeometryManager;
70
import org.gvsig.fmap.geom.operation.DrawInts;
71
import org.gvsig.fmap.geom.operation.DrawOperationContext;
72
import org.gvsig.fmap.geom.operation.GeometryOperationException;
73
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
74
import org.gvsig.fmap.geom.operation.towkt.ToWKT;
75
import org.gvsig.fmap.geom.primitive.DefaultEnvelope;
76
import org.gvsig.fmap.geom.primitive.Envelope;
77
import org.gvsig.fmap.mapcontext.MapContext;
78
import org.gvsig.fmap.mapcontext.ViewPort;
79
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
80
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
81
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
82
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
83
import org.gvsig.fmap.mapcontext.exceptions.XMLLayerException;
84
import org.gvsig.fmap.mapcontext.layers.AbstractLinkProperties;
85
import org.gvsig.fmap.mapcontext.layers.FLayer;
86
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
87
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
88
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
89
import org.gvsig.fmap.mapcontext.layers.operations.ClassifiableVectorial;
90
import org.gvsig.fmap.mapcontext.layers.operations.ILabelable;
91
import org.gvsig.fmap.mapcontext.layers.operations.InfoByPoint;
92
import org.gvsig.fmap.mapcontext.layers.operations.SingleLayer;
93
import org.gvsig.fmap.mapcontext.layers.operations.VectorialXMLItem;
94
import org.gvsig.fmap.mapcontext.layers.operations.XMLItem;
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.XMLLegendException;
101
import org.gvsig.fmap.mapcontext.rendering.legend.ZSort;
102
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
103
import org.gvsig.fmap.mapcontext.rendering.legend.styling.AttrInTableLabelingStrategy;
104
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
105
import org.gvsig.fmap.mapcontext.rendering.legend.styling.LabelingFactory;
106
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
107
import org.gvsig.fmap.mapcontext.rendering.symbols.FSymbol;
108
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
109
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
110
import org.gvsig.tools.exception.BaseException;
111

    
112
import com.iver.utiles.NotExistInXMLEntity;
113
import com.iver.utiles.XMLEntity;
114
import com.iver.utiles.XMLException;
115
import com.iver.utiles.swing.threads.Cancellable;
116

    
117
/**
118
 * Capa b?sica Vectorial.
119
 *
120
 * @author Fernando Gonz?lez Cort?s
121
 */
122

    
123
// TODO Cuando no sea para pruebas debe no ser public
124
public class FLyrVect extends FLyrDefault implements ILabelable, InfoByPoint,
125
                ClassifiableVectorial, SingleLayer {
126
    private static Logger logger = Logger.getLogger(FLyrVect.class.getName());
127

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

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

    
144
    //Lo a?ado. Caracter?sticas de HyperEnlace (LINK)
145
    private FLyrVectLinkProperties linkProperties=new FLyrVectLinkProperties();
146

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

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

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

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

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

    
260
        if (dataStore.implementsOperation("defaultLegend")) {
261
                        ILegend legend = null;
262
                        try {
263
                                legend = (ILegend) dataStore.invokeOperation("defaultLegend",
264
                                                null);
265
                        } catch (DataStoreOperationNotSupportedException e) {
266
                                throw new LoadLayerException(this.getName(), e);
267
                        } catch (DataStoreOperationException e) {
268
                                throw new LoadLayerException(this.getName(), e);
269
                        }
270
                        if (legend != null) {
271
                                this.setLegend((IVectorLegend) legend);
272
                        } else {
273
                                try {
274
                                        this.setLegend(LegendFactory.createSingleSymbolLegend(this
275
                                                        .getShapeType()));
276
                                } catch (ReadException e) {
277
                                        throw new LoadLayerException(this.getName(), e);
278
                                }
279

    
280
                        }
281

    
282

    
283
                } else {
284
                        try {
285
                                this.setLegend(LegendFactory.createSingleSymbolLegend(this
286
                                                .getShapeType()));
287
                        } catch (ReadException e) {
288
                                throw new LoadLayerException(this.getName(), e);
289
                        }
290
                }
291

    
292
        if (dataStore.implementsOperation("defaultLabelingStrategy")) {
293

    
294
                ILabelingStrategy labeler = null;
295
                        try {
296
                                labeler = (ILabelingStrategy) dataStore.invokeOperation(
297
                                                "defaultLabelingStrategy", null);
298
                        } catch (DataStoreOperationNotSupportedException e) {
299
                                throw new LoadLayerException(this.getName(), e);
300
                        } catch (DataStoreOperationException e) {
301
                                throw new LoadLayerException(this.getName(), e);
302
                        }
303

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

    
315

    
316
        // azabala: we check if this layer could have a file spatial index
317
        // and load it if it exists
318
//        loadSpatialIndex();
319
    }
320

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

    
343
    }
344

    
345
    /**
346
     * Draws using IFeatureIterator. This method will replace the old draw(...) one.
347
     * @autor jaume dominguez faus - jaume.dominguez@iver.es
348
     * @param image
349
     * @param g
350
     * @param viewPort
351
     * @param cancel
352
     * @param scale
353
     * @throws ReadDriverException
354
     */
355
    public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
356
                    Cancellable cancel, double scale) throws ReadException {
357
            DrawOperationContext doc=new DrawOperationContext();
358
            doc.setViewPort(viewPort);
359
            boolean bDrawShapes = true;
360
            if (legend instanceof SingleSymbolLegend) {
361
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
362
            }
363
            Point2D offset = viewPort.getOffset();
364
            double dpi = MapContext.getScreenDPI();
365
            if (bDrawShapes) {
366
                    boolean cacheFeatures = isSpatialCacheEnabled();
367
                    SpatialCache cache = null;
368
                if (cacheFeatures) {
369
                        getSpatialCache().clearAll();
370
                        cache = getSpatialCache();
371
                }
372

    
373
                    try {
374
                            ArrayList fieldList = new ArrayList();
375

    
376
                            // fields from legend
377
                            String[] aux = null;
378

    
379
                            if (legend instanceof IClassifiedVectorLegend) {
380
                                    aux = ((IClassifiedVectorLegend) legend).getClassifyingFieldNames();
381
                                    for (int i = 0; i < aux.length; i++) {
382
                                            fieldList.add(aux[i]);
383
                                    }
384
                            }
385
                            FeatureStore featureStore=getFeatureStore();
386
                            // Get the iterator over the visible features
387
                            String featureFilter = null;
388

    
389
                            if (!viewPort.getAdjustedExtent().contains((Envelope)featureStore.getMetadata().get("extent"))) {
390
                                        featureFilter = this
391
                                                        .getDataStoreFilterForEnvelope(
392
                                                viewPort.getAdjustedExtent(),
393
                                                featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName(),
394
                                                null);
395
                                }
396
                            String[] fieldNames=null;
397
                            if (legend instanceof IClassifiedVectorLegend){
398
                                    String[] classified=((IClassifiedVectorLegend)legend).getClassifyingFieldNames();
399
                                    fieldNames=new String[classified.length+1];
400
                                    fieldNames[0]=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
401
                                    for (int i = 1; i < fieldNames.length; i++) {
402
                                                fieldNames[i]=classified[i-1];
403
                                        }
404

    
405
                            }else{
406
                                    fieldNames=new String[]{featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName()};
407
                            }
408
                            FeatureSet featureCollection=null;
409
                            featureCollection = (FeatureSet)featureStore.getDataCollection(
410
                                            fieldNames,
411
                                            featureFilter,//filter
412
                                            null);//order
413
                            Iterator it = featureCollection.iterator();
414

    
415
                            ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
416

    
417
                            boolean bSymbolLevelError = false;
418

    
419
                            // if layer has map levels it will use a ZSort
420
                            boolean useZSort = zSort != null && zSort.isUsingZSort();
421

    
422
                            // -- visual FX stuff
423
                            long time = System.currentTimeMillis();
424
                            BufferedImage virtualBim;
425
                            Graphics2D virtualGraphics;
426

    
427
                            // render temporary map each screenRefreshRate milliseconds;
428
                            int screenRefreshDelay = (int) ((1D/MapContext.getDrawFrameRate())*3*1000);
429
                            BufferedImage[] imageLevels = null;
430
                            Graphics2D[] graphics = null;
431
                            if (useZSort) {
432
                                    imageLevels = new BufferedImage[zSort.getLevelCount()];
433
                                    graphics = new Graphics2D[imageLevels.length];
434
                                    for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
435
                                            imageLevels[i] = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
436
                                            graphics[i] = imageLevels[i].createGraphics();
437
                                            graphics[i].setTransform(g.getTransform());
438
                                            graphics[i].setRenderingHints(g.getRenderingHints());
439
                                    }
440
                            }
441
                            // -- end visual FX stuff
442

    
443
                            // Iteration over each feature
444
                            while ( !cancel.isCanceled() && it.hasNext()) {
445
                                    Feature feat = (Feature)it.next();
446

    
447
                                    Geometry geom = (Geometry)feat.getDefaultGeometry();
448

    
449
                                    if (cacheFeatures) {
450
                                            if (cache.getMaxFeatures() >= cache.size()) {
451
                                                        // already reprojected
452
                                                        cache.insert(geom.getEnvelope(), geom);
453
                                                }
454
                                    }
455

    
456
                                    // retrieve the symbol associated to such feature
457
                                    ISymbol sym = legend.getSymbolByFeature(feat);
458
                                    if (featureStore.getSelection().contains(feat)){
459
                                            sym=sym.getSymbolForSelection();
460
                                    }
461
                                    if (sym == null) {
462
                                                continue;
463
                                        }
464

    
465
                                    //C?digo para poder acceder a los ?ndices para ver si est? seleccionado un Feature
466
//                                    ReadableVectorial rv=getSource();
467
//                                    int selectionIndex=-1;
468
//                                    if (rv instanceof ISpatialDB){
469
//                                            selectionIndex=((ISpatialDB)rv).getRowIndexByFID(feat);
470
//                                    }else{
471
//                                            selectionIndex=Integer.parseInt(feat.getID());
472
//                                    }
473
//                                    if (selectionIndex!=-1) {
474
//                                            if (selectionSupport.isSelected(selectionIndex)) {
475
//                                                sym = sym.getSymbolForSelection();
476
//                                        }
477
//                                }
478

    
479
                                    // Check if this symbol is sized with CartographicSupport
480
                                    CartographicSupport csSym = null;
481
                                    int symbolType = sym.getSymbolType();
482
                                    boolean bDrawCartographicSupport = false;
483

    
484
                                    if (   symbolType == Geometry.TYPES.POINT
485
                                                    || symbolType == Geometry.TYPES.CURVE
486
                                                    || sym instanceof CartographicSupport) {
487

    
488
                                            // patch
489
                                        if (!sym.getClass().equals(FSymbol.class)) {
490
                                                csSym = (CartographicSupport) sym;
491
                                                bDrawCartographicSupport = (csSym.getUnit() != -1);
492
                                        }
493
                                    }
494

    
495
                                    int x = -1;
496
                                    int y = -1;
497
                                    int[] xyCoords = new int[2];
498

    
499
                                    // Check if size is a pixel
500
                                    boolean onePoint = bDrawCartographicSupport ?
501
                                                    isOnePoint(g.getTransform(), viewPort, MapContext.getScreenDPI(), csSym, geom, xyCoords) :
502
                                                    isOnePoint(g.getTransform(), viewPort, geom, xyCoords);
503

    
504
                                        // Avoid out of bounds exceptions
505
                                        if (onePoint) {
506
                                                x = xyCoords[0];
507
                                                y = xyCoords[1];
508
                                                if (x<0 || y<0 || x>= viewPort.getImageWidth() || y>=viewPort.getImageHeight()) {
509
                                                        continue;
510
                                                }
511
                                        }
512

    
513
                                        if (useZSort) {
514
                                                // Check if this symbol is a multilayer
515
                                                if (sym instanceof IMultiLayerSymbol) {
516
                                                        // if so, treat each of its layers as a single symbol
517
                                                        // in its corresponding map level
518
                                                        IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
519
                                                        for (int i = 0; !cancel.isCanceled() && i < mlSym.getLayerCount(); i++) {
520
                                                                ISymbol mySym = mlSym.getLayer(i);
521
                                                                int symbolLevel = zSort.getSymbolLevel(mySym);
522

    
523
                                                                if (symbolLevel == -1) {
524
                                                                        /* an error occured when managing symbol levels
525
                                                                         * some of the legend changed events regarding the
526
                                                                         * symbols did not finish satisfactory and the legend
527
                                                                         * is now inconsistent. For this drawing, it will finish
528
                                                                         * as it was at the bottom (level 0) but, when done, the
529
                                                                         * ZSort will be reset to avoid app crashes. This is
530
                                                                         * a bug that has to be fixed.
531
                                                                         */
532
                                                                        bSymbolLevelError = true;
533
                                                                        symbolLevel=0;
534
                                                                }
535

    
536
                                                                if (onePoint) {
537
                                                                        if (x<0 || y<0 || x>= imageLevels[symbolLevel].getWidth() || y>=imageLevels[symbolLevel].getHeight()) {
538
                                                                                continue;
539
                                                                        }
540
                                                                        imageLevels[symbolLevel].setRGB(x, y, mySym.getOnePointRgb());
541
                                                                } else {
542
                                                                        if (!bDrawCartographicSupport) {
543
                                                                                doc.setGraphics(graphics[symbolLevel]);
544
                                                                                doc.setSymbol(mySym);
545
                                                                                doc.setCancellable(cancel);
546
                                                                                geom.invokeOperation(DrawInts.CODE,doc);
547
                                                                        } else {
548
                                                                                doc.setGraphics(graphics[symbolLevel]);
549
                                                                                doc.setSymbol(mySym);
550
                                                                                doc.setCancellable(cancel);
551
                                                                                doc.setDPI(dpi);
552
                                                                                geom.invokeOperation(DrawInts.CODE,doc);
553
                                                                        }
554
                                                                }
555
                                                        }
556
                                                } else {
557
                                                        // else, just draw the symbol in its level
558
                                                        if (!bDrawCartographicSupport) {
559
                                                                doc.setGraphics(graphics[zSort.getSymbolLevel(sym)]);
560
                                                                doc.setSymbol(sym);
561
                                                                doc.setCancellable(cancel);
562
                                                                geom.invokeOperation(DrawInts.CODE,doc);
563
                                                        } else {
564
                                                                doc.setGraphics(graphics[zSort.getSymbolLevel(sym)]);
565
                                                                doc.setSymbol((ISymbol)csSym);
566
                                                                doc.setCancellable(cancel);
567
                                                                doc.setDPI(dpi);
568
                                                                geom.invokeOperation(DrawInts.CODE,doc);
569
                                                        }
570
                                                }
571

    
572
                                                // -- visual FX stuff
573
                                                // Cuando el offset!=0 se est? dibujando sobre el Layout y por tanto no tiene que ejecutar el siguiente c?digo.
574
                                                if (offset.getX()==0 && offset.getY()==0) {
575
                                                        if ((System.currentTimeMillis() - time) > screenRefreshDelay) {
576
                                                                virtualBim = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_ARGB);
577
                                                                virtualGraphics = virtualBim.createGraphics();
578
                                                                virtualGraphics.drawImage(image,0,0, null);
579
                                                                for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
580
                                                                        virtualGraphics.drawImage(imageLevels[i],0,0, null);
581
                                                                }
582
                                                                g.clearRect(0, 0, image.getWidth(), image.getHeight());
583
                                                                g.drawImage(virtualBim, 0, 0, null);
584
                                                                time = System.currentTimeMillis();
585
                                                        }
586
                                                // -- end visual FX stuff
587
                                                }
588

    
589
                                        } else {
590
                                                // no ZSort, so there is only a map level, symbols are
591
                                                // just drawn.
592
                                                if (onePoint) {
593
                                                        if (x<0 || y<0 || x>= image.getWidth() || y>=image.getHeight()) {
594
                                                                continue;
595
                                                        }
596
                                                        image.setRGB(x, y, sym.getOnePointRgb());
597
                                                } else {
598

    
599
                                                        if (!bDrawCartographicSupport) {
600
                                                                doc.setGraphics(g);
601
                                                                doc.setSymbol(sym);
602
                                                                doc.setCancellable(cancel);
603
                                                                geom.invokeOperation(DrawInts.CODE,doc);
604
                                                        } else {
605
                                                                doc.setGraphics(g);
606
                                                                doc.setSymbol((ISymbol)csSym);
607
                                                                doc.setCancellable(cancel);
608
                                                                doc.setDPI(dpi);
609
                                                                geom.invokeOperation(DrawInts.CODE,doc);
610
                                                        }
611
                                                }
612
                                        }
613
                            }
614

    
615
                            if (useZSort) {
616
                                    g.drawImage(image, 0, 0, null);
617
                                        g.translate(offset.getX(), offset.getY());
618
                                    for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
619
                                            g.drawImage(imageLevels[i],0,0, null);
620
                                            imageLevels[i] = null;
621
                                            graphics[i] = null;
622
                                    }
623
                                        g.translate(-offset.getX(), -offset.getY());
624
                                    imageLevels = null;
625
                                    graphics = null;
626
                            }
627
//                            it.closeIterator();
628
                            it=null;
629
                            featureCollection.dispose();
630

    
631
                            if (bSymbolLevelError) {
632
                                    ((IVectorLegend) getLegend()).setZSort(null);
633
                            }
634

    
635
                    } catch (ReadException e) {
636
                            this.setVisible(false);
637
                            this.setActive(false);
638
                            throw e;
639
                    } catch (GeometryOperationNotSupportedException e) {
640
                            this.setVisible(false);
641
                            this.setActive(false);
642
                            throw new ReadException(getName(),e);
643
                        } catch (GeometryOperationException e) {
644
                                this.setVisible(false);
645
                            this.setActive(false);
646
                            throw new ReadException(getName(),e);
647
                        } catch (BaseException e) {
648
                                this.setVisible(false);
649
                            this.setActive(false);
650
                            throw new ReadException(getName(),e);
651
                        }
652

    
653

    
654
            }
655
    }
656
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
657
                    double scale, PrintRequestAttributeSet properties) throws ReadException {
658
              // TEST METHOD
659
            boolean bDrawShapes = true;
660
            if (legend instanceof SingleSymbolLegend) {
661
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
662
            }
663
            if (bDrawShapes) {
664
                    try {
665
                            double dpi = 72;
666

    
667
                            PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
668
                            if (resolution.equals(PrintQuality.NORMAL)){
669
                                    dpi = 300;
670
                            } else if (resolution.equals(PrintQuality.HIGH)){
671
                                    dpi = 600;
672
                            } else if (resolution.equals(PrintQuality.DRAFT)){
673
                                    dpi = 72;
674
                            }
675
                            ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
676

    
677
                            // if layer has map levels it will use a ZSort
678
                            boolean useZSort = zSort != null && zSort.isUsingZSort();
679

    
680

    
681
                            int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1;
682
                            for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) {
683
                                    // Get the iterator over the visible features
684
                                FeatureStore featureStore=getFeatureStore();
685
                                // Get the iterator over the visible features
686
                                String featureFilter = null;
687

    
688
                                if (!viewPort.getAdjustedExtent().contains((Envelope)featureStore.getMetadata().get("extent"))) {
689
                                            featureFilter=this.getDataStoreFilterForGeomerty(
690
                                                    viewPort.getAdjustedExtent().getGeometry(),
691
                                                    featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName(),
692
                                                    null);
693
                                    }
694
                                String[] fieldNames=null;
695
                                if (legend instanceof IClassifiedVectorLegend){
696
                                        String[] classified=((IClassifiedVectorLegend)legend).getClassifyingFieldNames();
697
                                        fieldNames=new String[classified.length+1];
698
                                        fieldNames[0]=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
699
                                        for (int i = 1; i < fieldNames.length; i++) {
700
                                                    fieldNames[i]=classified[i-1];
701
                                            }
702

    
703
                                }else{
704
                                        fieldNames=new String[]{featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName()};
705
                                }
706

    
707

    
708
                                FeatureSet featureCollection=null;
709
                                featureCollection = (FeatureSet)featureStore.getDataCollection(
710
                                                fieldNames,
711
                                                featureFilter,//filter
712
                                                null);//order
713
                                Iterator it = featureCollection.iterator();
714

    
715
                                    // Iteration over each feature
716
                                    while ( !cancel.isCanceled() && it.hasNext()) {
717
                                            Feature feat = (Feature)it.next();
718
                                            Geometry geom = (Geometry)feat.getDefaultGeometry();
719

    
720
                                            // retreive the symbol associated to such feature
721
                                            ISymbol sym = legend.getSymbolByFeature(feat);
722

    
723
                                            if (useZSort) {
724
                                                    // Check if this symbol is a multilayer
725
                                                    if (sym instanceof IMultiLayerSymbol) {
726
                                                            // if so, get the layer corresponding to the current
727
                                                            // level. If none, continue to next iteration
728
                                                            IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
729
                                                            for (int i = 0; i < mlSym.getLayerCount(); i++) {
730
                                                                    ISymbol mySym = mlSym.getLayer(i);
731
                                                                    if (zSort.getSymbolLevel(mySym) == mapPass) {
732
                                                                            sym = mySym;
733
                                                                            break;
734
                                                                    }
735
                                                                    System.out.println("avoided layer "+i+"of symbol '"+mlSym.getDescription()+"' (pass "+mapPass+")");
736
                                                            }
737

    
738
                                                            if (sym == null) {
739
                                                                    continue;
740
                                                            }
741
                                                    } else {
742
                                                            // else, just draw the symbol in its level
743
                                                            if (zSort.getSymbolLevel(sym) != mapPass) {
744
                                                                    System.out.println("avoided single layer symbol '"+sym.getDescription()+"' (pass "+mapPass+")");
745
                                                                    continue;
746
                                                            }
747
                                                    }
748
                                            }
749

    
750
                                            // Check if this symbol is sized with CartographicSupport
751
                                            CartographicSupport csSym = null;
752
                                            int symbolType = sym.getSymbolType();
753
                                            boolean bDrawCartographicSupport = false;
754

    
755
                                            if (   symbolType == Geometry.TYPES.POINT
756
                                                            || symbolType == Geometry.TYPES.CURVE
757
                                                            || sym instanceof CartographicSupport) {
758

    
759
                                                    csSym = (CartographicSupport) sym;
760
                                                    bDrawCartographicSupport = (csSym.getUnit() != -1);
761
                                            }
762

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

    
765
                                            if (!bDrawCartographicSupport) {
766
                                                        DrawOperationContext doc=new DrawOperationContext();
767
                                                        doc.setGraphics(g);
768
                                                        doc.setViewPort(viewPort);
769
                                                        doc.setSymbol(sym);
770
                                                        doc.setCancellable(cancel);
771
                                                        geom.invokeOperation(DrawInts.CODE,doc);
772
                                                } else {
773
                                                        DrawOperationContext doc=new DrawOperationContext();
774
                                                        doc.setGraphics(g);
775
                                                        doc.setViewPort(viewPort);
776
                                                        doc.setSymbol((ISymbol)csSym);
777
                                                        doc.setCancellable(cancel);
778
                                                        doc.setDPI(dpi);
779
                                                        geom.invokeOperation(DrawInts.CODE,doc);
780
                                                }
781
                                    }
782
                                    it=null;
783
                                    featureCollection.dispose();
784
                            }
785
                    } catch (ReadException e) {
786
                            this.setVisible(false);
787
                            this.setActive(false);
788
                            throw e;
789
                    } catch (GeometryOperationNotSupportedException e) {
790
                            this.setVisible(false);
791
                            this.setActive(false);
792
                            throw new ReadException(getName(),e);
793
                        } catch (GeometryOperationException e) {
794
                                this.setVisible(false);
795
                            this.setActive(false);
796
                            throw new ReadException(getName(),e);
797
                        } catch (BaseException e) {
798
                                this.setVisible(false);
799
                            this.setActive(false);
800
                            throw new ReadException(getName(),e);
801
                        }
802
            }
803
    }
804

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

    
885
//    public void createSpatialIndex() {
886
//        createSpatialIndex(null);
887
//    }
888

    
889

    
890
    public void setLegend(IVectorLegend r) throws LegendLayerException {
891
        IVectorLegend oldLegend = legend;
892
        legend = r;
893
        try {
894
            legend.setFeatureStore(getFeatureStore());
895
        } catch (ReadException e1) {
896
            throw new LegendLayerException(getName(),e1);
897
        }
898
        LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
899
                oldLegend, legend);
900
        callLegendChanged(e);
901
    }
902

    
903
    /**
904
     * Devuelve la Leyenda de la capa.
905
     *
906
     * @return Leyenda.
907
     */
908
    public ILegend getLegend() {
909
        return legend;
910
    }
911

    
912
    /**
913
     * Devuelve el tipo de shape que contiene la capa.
914
     *
915
     * @return tipo de shape.
916
     *
917
     * @throws DriverException
918
     */
919
    public int getShapeType() throws ReadException {
920
        if (typeShape == -1) {
921
            typeShape = (((FeatureStore)getDataStore()).getDefaultFeatureType()).getGeometryTypes()[0];
922
        }
923
        return typeShape;
924
    }
925

    
926
    public XMLEntity getXMLEntity() throws XMLException {
927

    
928
        if (!this.isAvailable() && this.orgXMLEntity != null) {
929
            return this.orgXMLEntity;
930
        }
931
        XMLEntity xml = super.getXMLEntity();
932
        if (getLegend()!=null){
933
            XMLEntity xmlLegend=getLegend().getXMLEntity();
934
                xmlLegend.putProperty("tagName","legend");
935
            xml.addChild(xmlLegend);
936
        }
937
        try {
938
                        XMLEntity xmlFeatureStore=getFeatureStore().getXMLEntity();
939
                        xmlFeatureStore.putProperty("tagName","featureStore");
940
                        xml.addChild(xmlFeatureStore);
941
                } catch (ReadException e) {
942
                        throw new XMLLayerException(getName(),e);
943
                }
944
        // properties from ILabelable
945
        xml.putProperty("isLabeled", isLabeled);
946
        if (strategy != null) {
947
            XMLEntity strategyXML = strategy.getXMLEntity();
948
            strategyXML.putProperty("tagName", "labelingStrategy");
949
            xml.addChild(strategy.getXMLEntity());
950
        }
951
        xml.addChild(getLinkProperties().getXMLEntity());
952
        return xml;
953
    }
954
    /*
955
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
956
     */
957
    public void setXMLEntity(XMLEntity xml) throws XMLException {
958
        try {
959
            super.setXMLEntity(xml);
960
            XMLEntity legendXML = xml.firstChild("tagName","legend");
961
            IVectorLegend leg = LegendFactory.createFromXML(legendXML);
962
            /* (jaume) begin patch;
963
             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
964
             * no longer managed by the Legend but by the ILabelingStrategy. The
965
             * following allows restoring older projects' labelings.
966
             */
967
            if (legendXML.contains("labelFieldName")) {
968
                    String labelTextField = legendXML.getStringProperty("labelFieldName");
969
                    if (labelTextField != null) {
970
                            AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
971
                            labeling.setLayer(this);
972
                            labeling.setTextField(legendXML.getStringProperty("labelFieldName"));
973
                            labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
974
                            labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
975
                            this.setLabelingStrategy(labeling);
976
                            this.setIsLabeled(true);
977
                    }
978
            }
979
            XMLEntity xmlStore=xml.firstChild("tagName","featureStore");
980
            DataManager dm=DefaultDataManager.getManager();
981
            this.setDataStore(dm.createStore(xmlStore));
982
                            /* end patch */
983
                            try {
984
                                    setLegend(leg);
985
                            } catch (LegendLayerException e) {
986
                                    throw new XMLLegendException(e);
987
                            }
988
                    // set properties for ILabelable
989

    
990
                    if (xml.contains("isLabeled")
991
                                        && xml.getBooleanProperty(("isLabeled"))) {
992
                            XMLEntity labelingXML = xml.firstChild("tagName", "labelingStrategy");
993
                            if (labelingXML != null){
994

    
995
                                    isLabeled = true;
996
                                    try {
997
                                            this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this);
998
                                    } catch (NotExistInXMLEntity neXMLEX) {
999
                                            // no strategy was set, just continue;
1000
                                            logger.warn("Reached what should be unreachable code");
1001
                                    }
1002
                            } else {
1003
                                        isLabeled = false;
1004
                            }
1005
                    } else {
1006
                            isLabeled = false;
1007
                    }
1008
                    XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
1009
                    if (xmlLinkProperties != null){
1010
                            getLinkProperties().setXMLEntity(xmlLinkProperties);
1011
                    }
1012
            } catch (Exception e) {
1013
                    e.printStackTrace();
1014
                    this.setAvailable(false);
1015
                    this.orgXMLEntity = xml;
1016

    
1017
            }
1018
//
1019

    
1020
    }
1021

    
1022
    public void setXMLEntityNew(XMLEntity xml) throws XMLException {
1023
//        try {
1024
//            super.setXMLEntity(xml);
1025
//
1026
//            XMLEntity legendXML = xml.getChild(0);
1027
//            IVectorLegend leg = LegendFactory.createFromXML(legendXML);
1028
//            /* (jaume) begin patch;
1029
//             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1030
//             * no longer managed by the Legend but by the ILabelingStrategy. The
1031
//             * following allows restoring older projects' labelings.
1032
//             */
1033
//            if (legendXML.contains("labelFieldHeight")) {
1034
//                AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
1035
//                labeling.setLayer(this);
1036
//                labeling.setTextField(legendXML.getStringProperty("labelFieldHeight"));
1037
//                labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
1038
//                this.setLabelingStrategy(labeling);
1039
//                this.setIsLabeled(true);
1040
//              }
1041
//            /* end patch */
1042
//            try {
1043
//                getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
1044
//
1045
//                this.setLoadSelection(xml.getChild(1));
1046
//            } catch (ReadException e1) {
1047
//                this.setAvailable(false);
1048
//                throw new XMLException(e1);
1049
//            }
1050
//            // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
1051
//            // el final
1052
//            // de la lectura del proyecto
1053
//            if (xml.contains("hasJoin")) {
1054
//                setIsJoined(true);
1055
//                PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
1056
//            } else {
1057
//                this.setLoadLegend(leg);
1058
//            }
1059
//
1060
//        } catch (XMLException e) {
1061
//            this.setAvailable(false);
1062
//            this.orgXMLEntity = xml;
1063
//        } catch (Exception e) {
1064
//            this.setAvailable(false);
1065
//            this.orgXMLEntity = xml;
1066
//        }
1067

    
1068

    
1069
    }
1070

    
1071

    
1072
    /**
1073
     * Sobreimplementaci?n del m?todo toString para que las bases de datos
1074
     * identifiquen la capa.
1075
     *
1076
     * @return DOCUMENT ME!
1077
     */
1078
    public String toString() {
1079
        /*
1080
         * Se usa internamente para que la parte de datos identifique de forma
1081
         * un?voca las tablas
1082
         */
1083
        String ret = super.toString();
1084

    
1085
        return "layer" + ret.substring(ret.indexOf('@') + 1);
1086
    }
1087

    
1088
    public boolean isJoined() {
1089
        return bHasJoin;
1090
    }
1091

    
1092
    /**
1093
     * Returns if a layer is spatially indexed
1094
     *
1095
     * @return if this layer has the ability to proces spatial queries without
1096
     *         secuential scans.
1097
     */
1098
//    public boolean isSpatiallyIndexed() {
1099
//        ReadableVectorial source = getSource();
1100
//        if (source instanceof ISpatialDB)
1101
//            return true;
1102
//
1103
////FIXME azabala
1104
///*
1105
// * Esto es muy dudoso, y puede cambiar.
1106
// * Estoy diciendo que las que no son fichero o no son
1107
// * BoundedShapes estan indexadas. Esto es mentira, pero
1108
// * as? quien pregunte no querr? generar el indice.
1109
// * Esta por ver si interesa generar el indice para capas
1110
// * HSQLDB, WFS, etc.
1111
// */
1112
//        if(!(source instanceof VectorialFileAdapter)){
1113
//            return true;
1114
//        }
1115
//        if (!(source.getDriver() instanceof BoundedShapes)) {
1116
//            return true;
1117
//        }
1118
//
1119
//        if (getISpatialIndex() != null)
1120
//            return true;
1121
//        return false;
1122
//    }
1123

    
1124
    public void setIsJoined(boolean hasJoin) {
1125
        bHasJoin = hasJoin;
1126
    }
1127

    
1128
//    /**
1129
//     * @return Returns the spatialIndex.
1130
//     */
1131
//    public ISpatialIndex getISpatialIndex() {
1132
//        return spatialIndex;
1133
//    }
1134
//    /**
1135
//     * Sets the spatial index. This could be useful if, for some
1136
//     * reasons, you want to work with a distinct spatial index
1137
//     * (for example, a spatial index which could makes nearest
1138
//     * neighbour querys)
1139
//     * @param spatialIndex
1140
//     */
1141
//    public void setISpatialIndex(ISpatialIndex spatialIndex){
1142
//        this.spatialIndex = spatialIndex;
1143
//    }
1144

    
1145
    public void setEditing(boolean b) throws StartEditionLayerException {
1146
        super.setEditing(b);
1147
        try {
1148
                        getDataStore().edit();
1149
                } catch (ReadException e) {
1150
                        throw new StartEditionLayerException(getName(),e);
1151
                }
1152
        setSpatialCacheEnabled(b);
1153
        callEditionChanged(LayerEvent
1154
                .createEditionChangedEvent(this, "edition"));
1155

    
1156
    }
1157

    
1158
    public void clearSpatialCache()
1159
    {
1160
        spatialCache.clearAll();
1161
    }
1162

    
1163
    public boolean isSpatialCacheEnabled() {
1164
        return spatialCacheEnabled;
1165
    }
1166

    
1167
    public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
1168
        this.spatialCacheEnabled = spatialCacheEnabled;
1169
    }
1170

    
1171
    public SpatialCache getSpatialCache() {
1172
        return spatialCache;
1173
    }
1174

    
1175
    /**
1176
     * Siempre es un numero mayor de 1000
1177
     * @param maxFeatures
1178
     */
1179
    public void setMaxFeaturesInEditionCache(int maxFeatures) {
1180
        if (maxFeatures > spatialCache.getMaxFeatures()) {
1181
                        spatialCache.setMaxFeatures(maxFeatures);
1182
                }
1183

    
1184
    }
1185

    
1186
    /**
1187
     * This method returns a boolean that is used by the FPopMenu
1188
     * to make visible the properties menu or not. It is visible by
1189
     * default, and if a later don't have to show this menu only
1190
     * has to override this method.
1191
     * @return
1192
     * If the properties menu is visible (or not)
1193
     */
1194
    public boolean isPropertiesMenuVisible(){
1195
        return true;
1196
    }
1197

    
1198
    public void reload() throws ReloadLayerException {
1199
        super.reload();
1200
//        try {
1201
//            this.source.getDriver().reload();
1202
//            if (this.getLegend() == null) {
1203
//                if (this.getRecordset().getDriver() instanceof WithDefaultLegend) {
1204
//                    WithDefaultLegend aux = (WithDefaultLegend) this.getRecordset().getDriver();
1205
//                    this.setLegend((IVectorLegend) aux.getDefaultLegend());
1206
//                    this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
1207
//                } else {
1208
//                    this.setLegend(LegendFactory.createSingleSymbolLegend(
1209
//                            this.getShapeType()));
1210
//                }
1211
//            }
1212
//
1213
//        } catch (LegendLayerException e) {
1214
//            this.setAvailable(false);
1215
//            throw new ReloadLayerException(getName(),e);
1216
//        } catch (ReadException e) {
1217
//            this.setAvailable(false);
1218
//            throw new ReloadLayerException(getName(),e);
1219
//        }
1220

    
1221
    }
1222

    
1223
    protected void setLoadSelection(XMLEntity xml) {
1224
        this.loadSelection = xml;
1225
    }
1226

    
1227
    protected void setLoadLegend(IVectorLegend legend) {
1228
        this.loadLegend = legend;
1229
    }
1230

    
1231
    protected void putLoadSelection() throws XMLException {
1232
//        if (this.loadSelection == null) return;
1233
//        try {
1234
//            this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
1235
//        } catch (ReadDriverException e) {
1236
//            throw new XMLException(e);
1237
//        }
1238
//        this.loadSelection = null;
1239

    
1240
    }
1241
    protected void putLoadLegend() throws LegendLayerException {
1242
        if (this.loadLegend == null) {
1243
                        return;
1244
                }
1245
        this.setLegend(this.loadLegend);
1246
        this.loadLegend = null;
1247
    }
1248

    
1249
    protected void cleanLoadOptions() {
1250
        this.loadLegend = null;
1251
        this.loadSelection = null;
1252
    }
1253

    
1254
    public boolean isWritable() {
1255
        return getDataStore().allowWrite();
1256
    }
1257

    
1258
    public FLayer cloneLayer() throws Exception {
1259
        FLyrVect clonedLayer = new FLyrVect();
1260
        clonedLayer.setDataStore(getDataStore());
1261
        if (isJoined()) {
1262
                        clonedLayer.setIsJoined(true);
1263
                }
1264
        clonedLayer.setVisible(isVisible());
1265
//        clonedLayer.setISpatialIndex(getISpatialIndex());
1266
        clonedLayer.setName(getName());
1267
        clonedLayer.setCoordTrans(getCoordTrans());
1268

    
1269
        clonedLayer.setLegend((IVectorLegend)getLegend().cloneLegend());
1270

    
1271
        clonedLayer.setIsLabeled(isLabeled());
1272
        clonedLayer.setLabelingStrategy(getLabelingStrategy());
1273

    
1274
        return clonedLayer;
1275
    }
1276

    
1277

    
1278
    private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, double dpi, CartographicSupport csSym, Geometry geom, int[] xyCoords) {
1279
            return isOnePoint(graphicsTransform, viewPort, geom, xyCoords) && csSym.getCartographicSize(viewPort, dpi, geom) <= 1;
1280
    }
1281

    
1282
    private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, Geometry geom, int[] xyCoords) {
1283
            boolean onePoint = false;
1284
            int type=geom.getType() % Geometry.TYPES.Z;
1285
            if (type!=Geometry.TYPES.POINT && type!=Geometry.TYPES.MULTIPOINT) {
1286

    
1287
                        Rectangle2D geomBounds = geom.getBounds2D();
1288

    
1289
                        ICoordTrans ct = getCoordTrans();
1290

    
1291
                        if (ct!=null) {
1292
//                                geomBounds = ct.getInverted().convert(geomBounds);
1293
                                geomBounds = ct.convert(geomBounds);
1294
                        }
1295

    
1296
                        double dist1Pixel = viewPort.getDist1pixel();
1297

    
1298
                        onePoint = (geomBounds.getWidth()  <= dist1Pixel
1299
                                         && geomBounds.getHeight() <= dist1Pixel);
1300

    
1301
                        if (onePoint) {
1302
                                // avoid out of range exceptions
1303
                                org.gvsig.fmap.geom.primitive.Point2D p = new org.gvsig.fmap.geom.primitive.Point2D(geomBounds.getMinX(), geomBounds.getMinY());
1304
                                p.transform(viewPort.getAffineTransform());
1305
                                p.transform(graphicsTransform);
1306
                                xyCoords[0] = (int) p.getX();
1307
                                xyCoords[1] = (int) p.getY();
1308

    
1309
                        }
1310

    
1311
                }
1312
            return onePoint;
1313
    }
1314
    /*
1315
     * jaume. Stuff from ILabeled.
1316
     */
1317
    private boolean isLabeled;
1318
    protected ILabelingStrategy strategy;
1319

    
1320
    public boolean isLabeled() {
1321
        return isLabeled;
1322
    }
1323

    
1324
    public void setIsLabeled(boolean isLabeled) {
1325
        this.isLabeled = isLabeled;
1326
    }
1327

    
1328
    public ILabelingStrategy getLabelingStrategy() {
1329
        return strategy;
1330
    }
1331

    
1332
    public void setLabelingStrategy(ILabelingStrategy strategy) {
1333
        this.strategy = strategy;
1334
    }
1335

    
1336
    public void drawLabels(BufferedImage image, Graphics2D g, ViewPort viewPort,
1337
                    Cancellable cancel, double scale, double dpi) throws ReadException {
1338
        if (strategy!=null && isWithinScale(scale)) {
1339
                strategy.draw(image, g, viewPort, cancel, dpi);
1340
        }
1341
    }
1342

    
1343
    //M?todos para el uso de HyperLinks en capas FLyerVect
1344

    
1345
    /**
1346
     * Return true, because a Vectorial Layer supports HyperLink
1347
     */
1348
    public boolean allowLinks()
1349
    {
1350
            return true;
1351
    }
1352

    
1353
    /**
1354
         * Returns an instance of AbstractLinkProperties that contains the information
1355
         * of the HyperLink
1356
         * @return Abstra
1357
         */
1358
    public AbstractLinkProperties getLinkProperties()
1359
    {
1360
            return linkProperties;
1361
    }
1362

    
1363
    /**
1364
         * Provides an array with URIs. Returns one URI by geometry that includes the point
1365
         * in its own geometry limits with a allowed tolerance.
1366
         * @param layer, the layer
1367
         * @param point, the point to check that is contained or not in the geometries in the layer
1368
         * @param tolerance, the tolerance allowed. Allowed margin of error to detect if the  point
1369
         *                 is contained in some geometries of the layer
1370
         * @return
1371
     * @throws ReadException
1372
     * @throws BehaviorException
1373
         */
1374
    public URI[] getLink(Point2D point, double tolerance) throws ReadException
1375
    {
1376
            //return linkProperties.getLink(this)
1377
            return linkProperties.getLink(this,point,tolerance);
1378
    }
1379

    
1380
        public void load() throws LoadLayerException {
1381
                super.load();
1382
        }
1383

    
1384
        public FeatureStore getFeatureStore() throws ReadException {
1385
                return (FeatureStore)getDataStore();
1386
        }
1387

    
1388
        public FeatureSet queryByPoint(Point2D mapPoint, double tol, FeatureType featureType) throws ReadException {
1389
                Geometry geom = GeometryManager.getInstance().getGeometryFactory()
1390
                                .createCircle(mapPoint, tol);
1391

    
1392
//                return queryByGeometry(geom, featureType);
1393
                return queryByEnvelope(geom.getEnvelope(), featureType);
1394
        }
1395

    
1396

    
1397
        public FeatureSet queryByGeometry(Geometry geom, FeatureType featureType) throws ReadException {
1398
                try {
1399
                        return (FeatureSet)
1400
                                getFeatureStore().getDataCollection(
1401
                                        featureType,
1402
                                        getDataStoreFilterForGeomerty(
1403
                                                        geom,
1404
                                                        featureType.getDefaultGeometryAttributeName(),
1405
                                                        null),
1406
                                        null);
1407
                } catch (GeometryOperationNotSupportedException e) {
1408
                        throw new ReadException("queryByGeometry", e);
1409
                } catch (GeometryOperationException e) {
1410
                        throw new ReadException("queryByGeometry", e);
1411
                }
1412

    
1413
        }
1414

    
1415
        /*
1416
         * TODO Este metodo es de utilidad. Sacarlo de aqui?
1417
         */
1418
        public String getDataStoreFilterForGeomerty(Geometry geom,
1419
                        String geomAttributeName, String srs) throws ReadException,
1420
                        GeometryOperationException,
1421
                        GeometryOperationNotSupportedException {
1422
                String txtGeom;
1423

    
1424
                txtGeom = (String) geom.invokeOperation(ToWKT.CODE, null);
1425

    
1426
                if (srs == null) {
1427
                        try {
1428
                                srs = (String) getFeatureStore().getMetadata().get("srs");
1429
                        } catch (BaseException e) {
1430
                                throw new ReadException("getDataStoreFilterForGeomerty", e);
1431
                        }
1432
                }
1433

    
1434

    
1435
                return " intersects(GeomFromText('" + txtGeom + "', " + "'" + srs + "'"
1436
                                + "), " + geomAttributeName + ") ";
1437
        }
1438

    
1439
        /*
1440
         * TODO Este metodo es de utilidad. Sacarlo de aqui?
1441
         */
1442
        public String getDataStoreFilterForEnvelope(Envelope envelope,
1443
                        String geomAttributeName, String srs) throws ReadException,
1444
                        GeometryOperationException, GeometryOperationNotSupportedException {
1445
                String txtGeom;
1446

    
1447
                txtGeom = (String) envelope.getGeometry().invokeOperation(ToWKT.CODE,
1448
                                null);
1449

    
1450
                if (srs == null) {
1451
                        try {
1452
                                srs = (String) getFeatureStore().getMetadata().get("srs");
1453
                        } catch (BaseException e) {
1454
                                throw new ReadException("getDataStoreFilterForGeomerty", e);
1455
                        }
1456
                }
1457

    
1458
                return " intersects(GeomFromText('" + txtGeom + "', " + "'" + srs + "'"
1459
                                + "), boundary(" + geomAttributeName + ")) ";
1460
        }
1461

    
1462
        public FeatureSet queryByEnvelope(Envelope rect, FeatureType featureType)
1463
                        throws ReadException {
1464
                try {
1465
                        return (FeatureSet) getFeatureStore().getDataCollection(
1466
                                        featureType,
1467
                                        getDataStoreFilterForEnvelope(rect, featureType
1468
                                                        .getDefaultGeometryAttributeName(), null), null);
1469
                } catch (GeometryOperationNotSupportedException e) {
1470
                        throw new ReadException("queryByGeometry", e);
1471
                } catch (GeometryOperationException e) {
1472
                        throw new ReadException("queryByGeometry", e);
1473
                }
1474
        }
1475

    
1476
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws ReadException, LoadLayerException {
1477
                Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p);
1478
        FeatureSet featureCollection = queryByPoint(pReal, tolerance, getFeatureStore().getDefaultFeatureType());
1479
        VectorialXMLItem[] item = new VectorialXMLItem[1];
1480
        item[0] = new VectorialXMLItem(featureCollection, this);
1481

    
1482
        return item;
1483
        }
1484
 }