Statistics
| Revision:

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

History | View | Annotate | Download (51.3 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.data.DataManager;
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.exceptions.XMLLayerException;
83
import org.gvsig.fmap.mapcontext.layers.AbstractLinkProperties;
84
import org.gvsig.fmap.mapcontext.layers.FLayer;
85
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
86
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
87
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
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.IClassifiedVectorLegend;
95
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
96
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
97
import org.gvsig.fmap.mapcontext.rendering.legend.LegendFactory;
98
import org.gvsig.fmap.mapcontext.rendering.legend.SingleSymbolLegend;
99
import org.gvsig.fmap.mapcontext.rendering.legend.XMLLegendException;
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.AttrInTableLabelingStrategy;
103
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
104
import org.gvsig.fmap.mapcontext.rendering.legend.styling.LabelingFactory;
105
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
106
import org.gvsig.fmap.mapcontext.rendering.symbols.FSymbol;
107
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
108
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
109
import org.gvsig.tools.exception.BaseException;
110

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

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

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

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

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

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

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

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

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

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

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

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

    
279
                        }
280

    
281

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

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

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

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

    
314

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

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

    
342
    }
343

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

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

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

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

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

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

    
413
                            ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
414

    
415
                            boolean bSymbolLevelError = false;
416

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

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

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

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

    
445
                                    Geometry geom = (Geometry)feat.getDefaultGeometry();
446

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

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

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

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

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

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

    
493
                                    int x = -1;
494
                                    int y = -1;
495
                                    int[] xyCoords = new int[2];
496

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

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

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

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

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

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

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

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

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

    
629
                            if (bSymbolLevelError) {
630
                                    ((IVectorLegend) getLegend()).setZSort(null);
631
                            }
632

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

    
651

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

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

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

    
678

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

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

    
701
                                }else{
702
                                        fieldNames=new String[]{featureStore.getDefaultFeatureType().getDefaultGeometry()};
703
                                }
704

    
705

    
706
                                FeatureCollection featureCollection=null;
707
                                featureCollection = (FeatureCollection)featureStore.getDataCollection(
708
                                                fieldNames,
709
                                                featureFilter,//filter
710
                                                null);//order
711
                                Iterator it = featureCollection.iterator();
712

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

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

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

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

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

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

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

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

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

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

    
883
//    public void createSpatialIndex() {
884
//        createSpatialIndex(null);
885
//    }
886

    
887

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

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

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

    
924
    public XMLEntity getXMLEntity() throws XMLException {
925

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

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

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

    
1015
            }
1016
//
1017

    
1018
    }
1019

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

    
1066

    
1067
    }
1068

    
1069

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

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

    
1086
    public boolean isJoined() {
1087
        return bHasJoin;
1088
    }
1089

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

    
1122
    public void setIsJoined(boolean hasJoin) {
1123
        bHasJoin = hasJoin;
1124
    }
1125

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

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

    
1154
    }
1155

    
1156
    public void clearSpatialCache()
1157
    {
1158
        spatialCache.clearAll();
1159
    }
1160

    
1161
    public boolean isSpatialCacheEnabled() {
1162
        return spatialCacheEnabled;
1163
    }
1164

    
1165
    public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
1166
        this.spatialCacheEnabled = spatialCacheEnabled;
1167
    }
1168

    
1169
    public SpatialCache getSpatialCache() {
1170
        return spatialCache;
1171
    }
1172

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

    
1182
    }
1183

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

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

    
1219
    }
1220

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

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

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

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

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

    
1252
    public boolean isWritable() {
1253
        return getDataStore().isEditable();
1254
    }
1255

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

    
1267
        clonedLayer.setLegend((IVectorLegend)getLegend().cloneLegend());
1268

    
1269
        clonedLayer.setIsLabeled(isLabeled());
1270
        clonedLayer.setLabelingStrategy(getLabelingStrategy());
1271

    
1272
        return clonedLayer;
1273
    }
1274

    
1275

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

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

    
1285
                        Rectangle2D geomBounds = geom.getBounds2D();
1286

    
1287
                        ICoordTrans ct = getCoordTrans();
1288

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

    
1294
                        double dist1Pixel = viewPort.getDist1pixel();
1295

    
1296
                        onePoint = (geomBounds.getWidth()  <= dist1Pixel
1297
                                         && geomBounds.getHeight() <= dist1Pixel);
1298

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

    
1307
                        }
1308

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

    
1318
    public boolean isLabeled() {
1319
        return isLabeled;
1320
    }
1321

    
1322
    public void setIsLabeled(boolean isLabeled) {
1323
        this.isLabeled = isLabeled;
1324
    }
1325

    
1326
    public ILabelingStrategy getLabelingStrategy() {
1327
        return strategy;
1328
    }
1329

    
1330
    public void setLabelingStrategy(ILabelingStrategy strategy) {
1331
        this.strategy = strategy;
1332
    }
1333

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

    
1341
    //M?todos para el uso de HyperLinks en capas FLyerVect
1342

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

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

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

    
1378
        public void load() throws LoadLayerException {
1379
                super.load();
1380
        }
1381

    
1382
        public FeatureStore getFeatureStore() throws ReadException {
1383
                return (FeatureStore)getDataStore();
1384
        }
1385

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

    
1390
                return queryByGeometry(geom, featureType);
1391
        }
1392

    
1393

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

    
1410
        }
1411

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

    
1421
                txtGeom = (String) geom.invokeOperation(ToWKT.CODE, null);
1422

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

    
1431

    
1432
                return " intersects(GeomFromText('" + txtGeom + "', " + "'" + srs + "'"
1433
                                + "), " + geomFileName + ") ";
1434
        }
1435

    
1436
        public FeatureCollection queryByEnvelope(Envelope rect, FeatureType featureType)
1437
                        throws ReadException {
1438
                return this.queryByGeometry(rect.getGeometry(),featureType);
1439
        }
1440

    
1441
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws ReadException, LoadLayerException {
1442
                Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p);
1443
        FeatureCollection featureCollection = queryByPoint(pReal, tolerance, getFeatureStore().getDefaultFeatureType());
1444
        VectorialXMLItem[] item = new VectorialXMLItem[1];
1445
        item[0] = new VectorialXMLItem(featureCollection, this);
1446

    
1447
        return item;
1448
        }
1449
 }