Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libFMap / src / com / iver / cit / gvsig / fmap / layers / FLyrVect.java @ 13749

History | View | Annotate | Download (53.9 KB)

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

    
43
import java.awt.Graphics2D;
44
import java.awt.Point;
45
import java.awt.geom.Point2D;
46
import java.awt.geom.Rectangle2D;
47
import java.awt.image.BufferedImage;
48
import java.io.File;
49
import java.net.URI;
50
import java.util.ArrayList;
51

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

    
55
import org.apache.log4j.Logger;
56
import org.cresques.cts.ICoordTrans;
57

    
58
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
59
import com.hardcode.gdbms.engine.data.NoSuchTableException;
60
import com.hardcode.gdbms.engine.data.driver.DriverException;
61
import com.hardcode.gdbms.engine.instruction.FieldNotFoundException;
62
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
63
import com.iver.cit.gvsig.exceptions.layers.LegendLayerException;
64
import com.iver.cit.gvsig.exceptions.layers.ReloadLayerException;
65
import com.iver.cit.gvsig.exceptions.layers.StartEditionLayerException;
66
import com.iver.cit.gvsig.exceptions.visitors.StartWriterVisitorException;
67
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
68
import com.iver.cit.gvsig.fmap.MapContext;
69
import com.iver.cit.gvsig.fmap.ViewPort;
70
import com.iver.cit.gvsig.fmap.core.CartographicSupport;
71
import com.iver.cit.gvsig.fmap.core.FPoint2D;
72
import com.iver.cit.gvsig.fmap.core.FShape;
73
import com.iver.cit.gvsig.fmap.core.IFeature;
74
import com.iver.cit.gvsig.fmap.core.IGeometry;
75
import com.iver.cit.gvsig.fmap.core.ILabelable;
76
import com.iver.cit.gvsig.fmap.core.symbols.IMultiLayerSymbol;
77
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
78
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
79
import com.iver.cit.gvsig.fmap.drivers.IFeatureIterator;
80
import com.iver.cit.gvsig.fmap.drivers.IVectorialDatabaseDriver;
81
import com.iver.cit.gvsig.fmap.drivers.VectorialDriver;
82
import com.iver.cit.gvsig.fmap.drivers.WithDefaultLegend;
83
import com.iver.cit.gvsig.fmap.edition.AnnotationEditableAdapter;
84
import com.iver.cit.gvsig.fmap.edition.EditionEvent;
85
import com.iver.cit.gvsig.fmap.edition.ISpatialWriter;
86
import com.iver.cit.gvsig.fmap.edition.IWriteable;
87
import com.iver.cit.gvsig.fmap.edition.IWriter;
88
import com.iver.cit.gvsig.fmap.edition.VectorialEditableAdapter;
89
import com.iver.cit.gvsig.fmap.edition.VectorialEditableDBAdapter;
90
import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData;
91
import com.iver.cit.gvsig.fmap.layers.layerOperations.ClassifiableVectorial;
92
import com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint;
93
import com.iver.cit.gvsig.fmap.layers.layerOperations.RandomVectorialData;
94
import com.iver.cit.gvsig.fmap.layers.layerOperations.SingleLayer;
95
import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData;
96
import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialXMLItem;
97
import com.iver.cit.gvsig.fmap.layers.layerOperations.XMLItem;
98
import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor;
99
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
100
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
101
import com.iver.cit.gvsig.fmap.rendering.ILegend;
102
import com.iver.cit.gvsig.fmap.rendering.IVectorialLegend;
103
import com.iver.cit.gvsig.fmap.rendering.LegendChangedEvent;
104
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
105
import com.iver.cit.gvsig.fmap.rendering.SingleSymbolLegend;
106
import com.iver.cit.gvsig.fmap.rendering.ZSort;
107
import com.iver.cit.gvsig.fmap.rendering.styling.AttrInTableLabeling;
108
import com.iver.cit.gvsig.fmap.rendering.styling.ILabelingStrategy;
109
import com.iver.cit.gvsig.fmap.rendering.styling.LabelingFactory;
110
import com.iver.cit.gvsig.fmap.spatialindex.IPersistentSpatialIndex;
111
import com.iver.cit.gvsig.fmap.spatialindex.ISpatialIndex;
112
import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeGt2;
113
import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeJts;
114
import com.iver.cit.gvsig.fmap.spatialindex.SpatialIndexException;
115
import com.iver.utiles.FileUtils;
116
import com.iver.utiles.IPersistance;
117
import com.iver.utiles.NotExistInXMLEntity;
118
import com.iver.utiles.PostProcessSupport;
119
import com.iver.utiles.XMLEntity;
120
import com.iver.utiles.swing.threads.Cancellable;
121
import com.iver.utiles.swing.threads.CancellableMonitorable;
122

    
123
/**
124
 * Capa b?sica Vectorial.
125
 *
126
 * @author Fernando Gonz?lez Cort?s
127
 */
128

    
129
// TODO Cuando no sea para pruebas debe no ser public
130
public class FLyrVect extends FLyrDefault implements ILabelable,
131
        ClassifiableVectorial, SingleLayer, VectorialData, RandomVectorialData,
132
        AlphanumericData, InfoByPoint {
133
    private static Logger logger = Logger.getLogger(FLyrVect.class.getName());
134
    public static boolean forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD = true;
135

    
136
    /** Leyenda de la capa vectorial */
137
    private IVectorialLegend legend;
138
    private int typeShape = -1;
139
    private LayerChangeSupport layerChangeSupport = new LayerChangeSupport();
140
    private ReadableVectorial source;
141
    private SelectableDataSource sds;
142
    private SelectionSupport selectionSupport = new SelectionSupport();
143
    private SpatialCache spatialCache = new SpatialCache();
144
    private boolean spatialCacheEnabled = false;
145

    
146
    /**
147
     * An implementation of gvSIG spatial index
148
     */
149
    protected ISpatialIndex spatialIndex = null;
150
    private boolean bHasJoin = false;
151
    private XMLEntity orgXMLEntity = null;
152
    private XMLEntity loadSelection = null;
153
    private IVectorialLegend loadLegend = null;
154

    
155
    //Lo a?ado. Caracter?sticas de HyperEnlace (LINK)
156
    private FLyrVectLinkProperties linkProperties=new FLyrVectLinkProperties();
157
    //private ArrayList linkProperties=null;
158

    
159
    /**
160
     * Devuelve el VectorialAdapater de la capa.
161
     *
162
     * @return VectorialAdapter.
163
     */
164
    public ReadableVectorial getSource() {
165
        if (!this.isAvailable()) return null;
166
        return source;
167
    }
168

    
169
    /**
170
     * If we use a persistent spatial index associated with this layer, and the
171
     * index is not intrisic to the layer (for example spatial databases) this
172
     * method looks for existent spatial index, and loads it.
173
     *
174
     */
175
    private void loadSpatialIndex() {
176
        //FIXME: Al abrir el indice en fichero...
177
        //?C?mo lo liberamos? un metodo Layer.shutdown()
178

    
179

    
180
        ReadableVectorial source = getSource();
181
        //REVISAR QUE PASA CON LOS DRIVERS DXF, DGN, etc.
182
        //PUES SON VECTORIALFILEADAPTER
183
        if (!(source instanceof VectorialFileAdapter)) {
184
            // we are not interested in db adapters
185
            return;
186
        }
187
        VectorialDriver driver = source.getDriver();
188
        if (!(driver instanceof BoundedShapes)) {
189
            // we dont spatially index layers that are not bounded
190
            return;
191
        }
192
        File file = ((VectorialFileAdapter) source).getFile();
193
        String fileName = file.getAbsolutePath();
194
        File sptFile = new File(fileName + ".qix");
195
        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
196
            // before to exit, look for it in temp path
197
            String tempPath = System.getProperty("java.io.tmpdir");
198
            fileName = tempPath + File.separator + sptFile.getName();
199
            sptFile = new File(fileName);
200
            // it doesnt exists, must to create
201
            if (!sptFile.exists() || (!(sptFile.length() > 0))) {
202
                return;
203
            }// if
204
        }// if
205

    
206
        try {
207
            source.start();
208
            spatialIndex = new QuadtreeGt2(FileUtils.getFileWithoutExtension(sptFile),
209
                    "NM", source.getFullExtent(), source.getShapeCount(), false);
210
            source.setSpatialIndex(spatialIndex);
211
        } catch (SpatialIndexException e) {
212
            spatialIndex = null;
213
            e.printStackTrace();
214
            return;
215
        } catch (ReadDriverException e) {
216
            spatialIndex = null;
217
            e.printStackTrace();
218
            return;
219
        } catch (ExpansionFileReadException e) {
220
            spatialIndex = null;
221
            e.printStackTrace();
222
            return;
223
        }
224

    
225
    }
226

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

235
     * @return
236
     */
237
    public boolean isExternallySpatiallyIndexed() {
238
        /*
239
         * FIXME (AZABALA): Independizar del tipo de fichero de ?ndice
240
          * con el que se trabaje (ahora mismo considera la extension .qix,
241
         * pero esto depender? del tipo de ?ndice)
242
         * */
243
        ReadableVectorial source = getSource();
244
        if (!(source instanceof VectorialFileAdapter)) {
245
            // we are not interested in db adapters.
246
            // think in non spatial dbs, like HSQLDB
247
            return false;
248
        }
249
        File file = ((VectorialFileAdapter) source).getFile();
250
        String fileName = file.getAbsolutePath();
251
        File sptFile = new File(fileName + ".qix");
252
        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
253
            // before to exit, look for it in temp path
254
            // it doesnt exists, must to create
255
            String tempPath = System.getProperty("java.io.tmpdir");
256
            fileName = tempPath + File.separator + sptFile.getName();
257
            sptFile = new File(fileName);
258
            if (!sptFile.exists() || (!(sptFile.length() > 0))) {
259
                return false;
260
            }// if
261
        }// if
262
        return true;
263
    }
264

    
265
    /**
266
     * Inserta el VectorialAdapter a la capa.
267
     *
268
     * @param va
269
     *            VectorialAdapter.
270
     */
271
    public void setSource(ReadableVectorial rv) {
272
        source = rv;
273
        // azabala: we check if this layer could have a file spatial index
274
        // and load it if it exists
275
        loadSpatialIndex();
276
    }
277

    
278
    public Rectangle2D getFullExtent() throws ReadDriverException, ExpansionFileReadException {
279
            Rectangle2D rAux;
280
            source.start();
281
            rAux = (Rectangle2D)source.getFullExtent().clone();
282
            source.stop();
283

    
284
            // Si existe reproyecci?n, reproyectar el extent
285
            ICoordTrans ct = getCoordTrans();
286

    
287
            if (ct != null) {
288
                Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
289
                Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
290
                pt1 = ct.convert(pt1, null);
291
                pt2 = ct.convert(pt2, null);
292
                rAux = new Rectangle2D.Double();
293
                rAux.setFrameFromDiagonal(pt1, pt2);
294
            }
295

    
296
            //Esto es para cuando se crea una capa nueva con el fullExtent de ancho y alto 0.
297
            if (rAux.getWidth()==0 && rAux.getHeight()==0) {
298
                rAux=new Rectangle2D.Double(0,0,100,100);
299
            }
300

    
301
            return rAux;
302
    }
303

    
304
    /**
305
     * Draws using IFeatureIterator. This method will replace the old draw(...) one.
306
     * @autor jaume dominguez faus - jaume.dominguez@iver.es
307
     * @param image
308
     * @param g
309
     * @param viewPort
310
     * @param cancel
311
     * @param scale
312
     * @throws ReadDriverException
313
     */
314
    public void _draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
315
                    Cancellable cancel, double scale) throws ReadDriverException {
316
//          FEATURE ITERATORS (TEST METHOD)
317
//            moved up to FLayers
318
//            if (isWithinScale(scale)) {
319

    
320
                    boolean bDrawShapes = true;
321
                    if (legend instanceof SingleSymbolLegend) {
322
                            bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
323
                    }
324

    
325
                    double dpi = MapContext.getScreenDPI();
326

    
327
                        if (bDrawShapes) {
328

    
329
                                try {
330
                                    prepareDrawing(image, g, viewPort);
331
                                    ArrayList fieldList = new ArrayList();
332

    
333
                                    // fields from legend
334
                                    String[] aux = legend.getUsedFields();
335
                                    for (int i = 0; i < aux.length; i++) {
336
                                            fieldList.add(aux[i]);
337
                                    }
338

    
339
                                    // fields from labeling
340
                                    if (isLabeled()) {
341
                                            aux = getLabelingStrategy().getUsedFields();
342
                                            for (int i = 0; i < aux.length; i++) {
343
                                                    fieldList.add(aux[i]);
344
                                            }
345
                                    }
346

    
347
                                    ZSort zSort = ((IVectorialLegend) getLegend()).getZSort();
348

    
349
                                    // if layer has map levels it will use a ZSort
350
                                    boolean useZSort = zSort != null && zSort.isUsingZSort();
351

    
352
                                    // -- visual FX stuff
353
                                    long time = System.currentTimeMillis();
354
                                    BufferedImage virtualBim;
355
                                        Graphics2D virtualGraphics;
356
                                        int screenRefreshRate = 1000; // render temporary map each screenRefreshRate milliseconds;
357
                                        BufferedImage[] imageLevels = null;
358
                                        Graphics2D[] graphics = null;
359
                                        if (useZSort) {
360
                                                imageLevels = new BufferedImage[zSort.getLevelCount()+1];
361
                                                graphics = new Graphics2D[imageLevels.length];
362
                                                for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
363
                                                        imageLevels[i] = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
364
                                                        graphics[i] = imageLevels[i].createGraphics();
365
                                                }
366
                                        }
367
                                        // -- end visual FX stuff
368

    
369
                                        // Get the iterator over the visible features
370
                                    IFeatureIterator it = getSource().getFeatureIterator(
371
                                                    viewPort.getAdjustedExtent(),
372
                                                    (String[]) fieldList.toArray(new String[fieldList.size()]),
373
                                                    viewPort.getProjection(),
374
                                                    true);
375

    
376
                                    // Iteration over each feature
377
                                    while ( !cancel.isCanceled() && it.hasNext()) {
378
                                            IFeature feat = it.next();
379
                                            IGeometry geom = feat.getGeometry();
380

    
381
                                            // retreive the symbol associated to such feature
382
                                            ISymbol sym = legend.getSymbolByFeature(feat);
383

    
384
                                            // Check if this symbol is sized with CartographicSupport
385
                                            CartographicSupport csSym = null;
386
                                            int symbolType = sym.getSymbolType();
387
                                            boolean bDrawCartographicSupport = false;
388

    
389
                                            if (   symbolType == FShape.POINT
390
                                                    || symbolType == FShape.LINE
391
                                                    || sym instanceof CartographicSupport) {
392

    
393
                                                    csSym = (CartographicSupport) sym;
394
                                                    bDrawCartographicSupport = (csSym.getUnit() != -1);
395
                                            }
396

    
397
                                            int x = -1;
398
                                            int y = -1;
399
                                            int[] xyCoords = new int[2];
400

    
401
                                            // Check if size is a pixel
402
                                            boolean onePoint = bDrawCartographicSupport ?
403
                                                            isOnePoint(viewPort, MapContext.getScreenDPI(), csSym, geom, xyCoords) :
404
                                                            isOnePoint(viewPort, geom, xyCoords);
405

    
406
                                            // Avoid out of bounds exceptions
407
                                            if (onePoint) {
408
                                                    x = xyCoords[0];
409
                                                    y = xyCoords[1];
410
                                                    if (x<0 || y<0 || x>= viewPort.getImageWidth() || y>=viewPort.getImageHeight()) continue;
411
                                            }
412

    
413
                                            if (useZSort) {
414
                                                    // Check if this symbol is a multilayer
415
                                                    if (sym instanceof IMultiLayerSymbol) {
416
                                                            // if so, treat each of its layers as a single symbol
417
                                                            // in its corresponding map level
418
                                                            IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
419
                                                            for (int i = 0; i < mlSym.getLayerCount(); i++) {
420
                                                                    ISymbol mySym = mlSym.getLayer(i);
421
                                                                    if (onePoint) {
422
                                                                            if (x<0 || y<0 || x>= imageLevels[zSort.getSymbolLevel(mySym)].getWidth() || y>=imageLevels[zSort.getSymbolLevel(mySym)].getHeight()) continue;
423
                                                                            imageLevels[zSort.getSymbolLevel(mySym)].setRGB(x, y, mySym.getOnePointRgb());
424
                                                                    } else {
425
                                                                            if (!bDrawCartographicSupport) {
426
                                                                                    geom.drawInts(graphics[zSort.getSymbolLevel(mySym)], viewPort, mySym);
427
                                                                            } else {
428
                                                                                    geom.drawInts(graphics[zSort.getSymbolLevel(mySym)], viewPort, dpi, (CartographicSupport) mySym);
429
                                                                            }
430
                                                                    }
431
                                                            }
432
                                                    } else {
433
                                                            // else, just draw the symbol in its level
434
//                                                            geom.drawInts(graphics[zSort.getSymbolLevel(sym)], viewPort, sym);
435
                                                            if (!bDrawCartographicSupport) {
436
                                                                        geom.drawInts(graphics[zSort.getSymbolLevel(sym)], viewPort, sym);
437
                                                                } else {
438
                                                                        geom.drawInts(graphics[zSort.getSymbolLevel(sym)], viewPort, dpi, (CartographicSupport) csSym);
439
                                                                }
440
                                                    }
441

    
442
                                                    // -- visual FX stuff
443
                                                    if ((System.currentTimeMillis() - time) > screenRefreshRate) {
444
                                                            virtualBim = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_ARGB);
445
                                                            virtualGraphics = virtualBim.createGraphics();
446
                                                            virtualGraphics.drawImage(image,0,0,null);
447
                                                            for (int i = 0; i < imageLevels.length; i++) {
448
                                                                    virtualGraphics.drawImage(imageLevels[i],0,0, null);
449
                                                            }
450
                                                            g.clearRect(0, 0, image.getWidth(), image.getHeight());
451
                                                            g.drawImage(virtualBim, 0, 0, null);
452
                                                            time = System.currentTimeMillis();
453

    
454
                                                    }
455
                                                    // -- end visual FX stuff
456

    
457
                                            } else {
458
                                                    // no ZSort, so there is only a map level, symbols are
459
                                                    // just drawn.
460
                                                    if (onePoint) {
461
                                                            if (x<0 || y<0 || x>= image.getWidth() || y>=image.getHeight()) continue;
462
                                                            image.setRGB(x, y, sym.getOnePointRgb());
463
                                                    } else {
464
//                                                            geom.drawInts(g, viewPort, sym);
465
                                                            if (!bDrawCartographicSupport) {
466
                                                                        geom.drawInts(g, viewPort, sym);
467
                                                                } else {
468
                                                                        geom.drawInts(g, viewPort, dpi, csSym);
469
                                                                }
470
                                                    }
471
                                            }
472
                                    }
473

    
474
                                    if (useZSort) {
475
                                            g.drawImage(image, 0, 0, null);
476
                                            for (int i = 0; i < imageLevels.length; i++) {
477
                                                    g.drawImage(imageLevels[i],0,0, null);
478
                                                    imageLevels[i] = null;
479
                                                    graphics[i] = null;
480
                                            }
481
                                            imageLevels = null;
482
                                            graphics = null;
483
                                    }
484
                                        it.closeIterator();
485
                            } catch (ReadDriverException e) {
486
                                    this.setVisible(false);
487
                                    this.setActive(false);
488
                                    throw e;
489
                            } catch (ExpansionFileReadException e) {
490
                                    this.setVisible(false);
491
                                    this.setActive(false);
492
                                }
493
                    }
494
                    if (getVirtualLayers() != null) {
495
                            getVirtualLayers().draw(image, g, viewPort, cancel, scale);
496
                    }
497
//            }
498
    }
499

    
500
    public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
501
            Cancellable cancel, double scale) throws ReadDriverException {
502
            forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD = true;
503
            if (forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD) {
504
                    _draw(image, g, viewPort, cancel, scale);
505
            } else {
506
//                    moved up to FLayers
507
//                    if (isWithinScale(scale)) {
508

    
509

    
510
                            // Las que solo tienen etiquetado sin pintar el shape,
511
                            // no pasamos por ellas
512
                            boolean bDrawShapes = true;
513
                            if (legend instanceof SingleSymbolLegend) {
514
                                    if (legend.getDefaultSymbol().isShapeVisible() == false)
515
                                            bDrawShapes = false;
516
                            }
517
                            if (bDrawShapes) {
518
                                    Strategy strategy = StrategyManager.getStrategy(this);
519
                                    try {
520
                                            prepareDrawing(image, g, viewPort);
521
                                            strategy.draw(image, g, viewPort, cancel);
522
                                    } catch (ReadDriverException e) {
523
                                            this.setVisible(false);
524
                                            this.setActive(false);
525
                                            throw e;
526
                                    }
527
                            }
528
                            if (getVirtualLayers() != null) {
529
                                    getVirtualLayers().draw(image, g, viewPort, cancel, scale);
530
                            }
531
//                    }
532
            }
533
    }
534

    
535
    /**
536
     * Se llama antes de empezar a pintar.
537
     * Es ?til para preparar la cache a emplear, las leyendas, etc.
538
     * @param image
539
     * @param g
540
     * @param viewPort
541
     */
542
    private void prepareDrawing(BufferedImage image, Graphics2D g, ViewPort viewPort) {
543

    
544
    }
545

    
546
    public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
547
                    double scale, PrintRequestAttributeSet properties) throws ReadDriverException {
548
            // TEST METHOD
549

    
550
            boolean bDrawShapes = true;
551
            if (legend instanceof SingleSymbolLegend) {
552
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
553
            }
554

    
555

    
556
            if (bDrawShapes) {
557
                    double dpi = 72;
558

    
559
                    PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
560
                    if (resolution.equals(PrintQuality.NORMAL)){
561
                            dpi = 300;
562
                    } else if (resolution.equals(PrintQuality.HIGH)){
563
                            dpi = 600;
564
                    } else if (resolution.equals(PrintQuality.DRAFT)){
565
                            dpi = 72;
566
                    }
567

    
568

    
569
                    try {
570
                            prepareDrawing(null, g, viewPort);
571
                            ArrayList fieldList = new ArrayList();
572

    
573
                            // fields from legend
574
                            String[] aux = legend.getUsedFields();
575
                            for (int i = 0; i < aux.length; i++) {
576
                                    fieldList.add(aux[i]);
577
                            }
578

    
579
                            // fields from labeling
580
                            if (isLabeled()) {
581
                                    aux = getLabelingStrategy().getUsedFields();
582
                                    for (int i = 0; i < aux.length; i++) {
583
                                            fieldList.add(aux[i]);
584
                                    }
585
                            }
586

    
587
                            ZSort zSort = ((IVectorialLegend) getLegend()).getZSort();
588

    
589
                            // if layer has map levels it will use a ZSort
590
                            boolean useZSort = zSort != null && zSort.isUsingZSort();
591

    
592

    
593
                            int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1;
594
                            for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) {
595
                                    // Get the iterator over the visible features
596
                                    IFeatureIterator it = getSource().getFeatureIterator(
597
                                                    viewPort.getAdjustedExtent(),
598
                                                    (String[]) fieldList.toArray(new String[fieldList.size()]),
599
                                                    viewPort.getProjection(),
600
                                                    true);
601

    
602
                                    // Iteration over each feature
603
                                    while ( !cancel.isCanceled() && it.hasNext()) {
604
                                            IFeature feat = it.next();
605
                                            IGeometry geom = feat.getGeometry();
606

    
607
                                            // retreive the symbol associated to such feature
608
                                            ISymbol sym = legend.getSymbolByFeature(feat);
609

    
610
                                            // Check if this symbol is sized with CartographicSupport
611
                                            CartographicSupport csSym = null;
612
                                            int symbolType = sym.getSymbolType();
613
                                            boolean bDrawCartographicSupport = false;
614

    
615
                                            if (   symbolType == FShape.POINT
616
                                                            || symbolType == FShape.LINE
617
                                                            || sym instanceof CartographicSupport) {
618

    
619
                                                    csSym = (CartographicSupport) sym;
620
                                                    bDrawCartographicSupport = (csSym.getUnit() != -1);
621
                                            }
622

    
623
                                            // geom.drawInts(g, viewPort, sym);
624
                                            if (!bDrawCartographicSupport) {
625
                                                    geom.drawInts(g, viewPort, sym);
626
                                            } else {
627
                                                    geom.drawInts(g, viewPort, dpi, (CartographicSupport) csSym);
628
                                            }
629

    
630
                                    }
631
                                    it.closeIterator();
632
                            }
633
                    } catch (ReadDriverException e) {
634
                            this.setVisible(false);
635
                            this.setActive(false);
636
                            throw e;
637
                    } catch (ExpansionFileReadException e) {
638
                            this.setVisible(false);
639
                            this.setActive(false);
640
                    }
641
            }
642
            if (getVirtualLayers() != null) {
643
                    getVirtualLayers().print(g, viewPort, cancel, scale, properties);
644
            }
645
    }
646

    
647

    
648
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
649
            double scale, PrintRequestAttributeSet properties) throws ReadDriverException {
650
            if (forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD) {
651
                    _print(g, viewPort, cancel, scale, properties);
652
            } else {
653
//                    moved up to Flayers
654
//                    if (isVisible() && isWithinScale(scale)) {
655
                            Strategy strategy = StrategyManager.getStrategy(this);
656

    
657
                            strategy.print(g, viewPort, cancel, properties);
658
                            ILabelingStrategy labeling;
659
                            if ( (labeling = getLabelingStrategy() ) != null) {
660
                                    // contains labels
661
                                    labeling.print(g, viewPort, cancel, properties);
662
                            }
663
//                    }
664
            }
665
    }
666

    
667
    public void deleteSpatialIndex() {
668
        //must we delete possible spatial indexes files?
669
        spatialIndex = null;
670
    }
671

    
672
   /**
673
    * <p>
674
    * Creates an spatial index associated to this layer.
675
    * The spatial index will used
676
    * the native projection of the layer, so if the layer is reprojected, it will
677
    * be ignored.
678
    * </p>
679
    * @param cancelMonitor instance of CancellableMonitorable that allows
680
    * to monitor progress of spatial index creation, and cancel the process
681
    */
682
    public void createSpatialIndex(CancellableMonitorable cancelMonitor){
683
         // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
684
        // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
685
        // para que acepten recorrer sin geometria, solo con rectangulos.
686

    
687
        //If this vectorial layer is based in a spatial database, the spatial
688
        //index is already implicit. We only will index file drivers
689
        ReadableVectorial va = getSource();
690
        //We must think in non spatial databases, like HSQLDB
691
        if(!(va instanceof VectorialFileAdapter)){
692
            return;
693
        }
694
        if (!(va.getDriver() instanceof BoundedShapes)) {
695
            return;
696
        }
697
        File file = ((VectorialFileAdapter) va).getFile();
698
        String fileName = file.getAbsolutePath();
699
        ISpatialIndex localCopy = null;
700
        try {
701
            va.start();
702
            localCopy = new QuadtreeGt2(fileName, "NM", va.getFullExtent(),
703
                    va.getShapeCount(), true);
704

    
705
        } catch (SpatialIndexException e1) {
706
            // Probably we dont have writing permissions
707
            String directoryName = System.getProperty("java.io.tmpdir");
708
            File newFile = new File(directoryName +
709
                    File.separator +
710
                    file.getName());
711
            String newFileName = newFile.getName();
712
            try {
713
                localCopy = new QuadtreeGt2(newFileName, "NM", va.getFullExtent(),
714
                        va.getShapeCount(), true);
715
            } catch (SpatialIndexException e) {
716
                // if we cant build a file based spatial index, we'll build
717
                // a pure memory spatial index
718
                localCopy = new QuadtreeJts();
719
            } catch (ReadDriverException e) {
720
                localCopy = new QuadtreeJts();
721
            } catch (ExpansionFileReadException e) {
722
                localCopy = new QuadtreeJts();
723
            }
724

    
725
        } catch(Exception e){
726
            e.printStackTrace();
727
        }//try
728
        BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
729
        try {
730
            for (int i=0; i < va.getShapeCount(); i++)
731
            {
732
                if(cancelMonitor != null){
733
                    if(cancelMonitor.isCanceled())
734
                        return;
735
                    cancelMonitor.reportStep();
736
                }
737
                Rectangle2D r = shapeBounds.getShapeBounds(i);
738
                if(r != null)
739
                    localCopy.insert(r, i);
740
            } // for
741
            va.stop();
742
            if(localCopy instanceof IPersistentSpatialIndex)
743
                ((IPersistentSpatialIndex) localCopy).flush();
744
            spatialIndex = localCopy;
745
            //vectorial adapter needs a reference to the spatial index, to solve
746
            //request for feature iteration based in spatial queries
747
            source.setSpatialIndex(spatialIndex);
748
        } catch (ReadDriverException e) {
749
            // TODO Auto-generated catch block
750
            e.printStackTrace();
751
        } catch (ExpansionFileReadException e) {
752
            // TODO Auto-generated catch block
753
            e.printStackTrace();
754
        }
755
    }
756

    
757
    public void createSpatialIndex() {
758
        createSpatialIndex(null);
759
    }
760

    
761
    public void process(FeatureVisitor visitor, FBitSet subset)
762
            throws ReadDriverException, ExpansionFileReadException, VisitorException {
763
        Strategy s = StrategyManager.getStrategy(this);
764
        s.process(visitor, subset);
765
    }
766

    
767
    public void process(FeatureVisitor visitor) throws ReadDriverException, VisitorException {
768
        Strategy s = StrategyManager.getStrategy(this);
769
        s.process(visitor);
770
    }
771

    
772
    public void process(FeatureVisitor visitor, Rectangle2D rect)
773
            throws ReadDriverException, ExpansionFileReadException, VisitorException {
774
        Strategy s = StrategyManager.getStrategy(this);
775
        s.process(visitor, rect);
776
    }
777

    
778
    public FBitSet queryByRect(Rectangle2D rect) throws ReadDriverException, VisitorException {
779
        Strategy s = StrategyManager.getStrategy(this);
780

    
781
        return s.queryByRect(rect);
782
    }
783

    
784
    public FBitSet queryByPoint(Point2D p, double tolerance)
785
            throws ReadDriverException, VisitorException {
786
        Strategy s = StrategyManager.getStrategy(this);
787
        return s.queryByPoint(p, tolerance);
788
    }
789

    
790
    public FBitSet queryByShape(IGeometry g, int relationship)
791
            throws ReadDriverException, VisitorException {
792
        Strategy s = StrategyManager.getStrategy(this);
793
        return s.queryByShape(g, relationship);
794
    }
795

    
796
    public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws ReadDriverException, VisitorException {
797
        Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p);
798
        FBitSet bs = queryByPoint(pReal, tolerance);
799
        VectorialXMLItem[] item = new VectorialXMLItem[1];
800
        item[0] = new VectorialXMLItem(bs, this);
801

    
802
        return item;
803
    }
804

    
805
    public void setLegend(IVectorialLegend r) throws LegendLayerException {
806
        IVectorialLegend oldLegend = legend;
807
        legend = r;
808
        try {
809
            legend.setDataSource(getRecordset());
810
        } catch (FieldNotFoundException e1) {
811
            throw new LegendLayerException(getName(),e1);
812
        } catch (ReadDriverException e1) {
813
            throw new LegendLayerException(getName(),e1);
814
        }
815
        LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
816
                oldLegend, legend);
817
        callLegendChanged(e);
818
    }
819

    
820
    /**
821
     * Devuelve la Leyenda de la capa.
822
     *
823
     * @return Leyenda.
824
     */
825
    public ILegend getLegend() {
826
        return legend;
827
    }
828

    
829
    /**
830
     * Devuelve el tipo de shape que contiene la capa.
831
     *
832
     * @return tipo de shape.
833
     *
834
     * @throws DriverException
835
     */
836
    public int getShapeType() throws ReadDriverException {
837
        if (typeShape == -1) {
838
            getSource().start();
839
            typeShape = getSource().getShapeType();
840
            getSource().stop();
841
        }
842

    
843
        return typeShape;
844
    }
845

    
846
    public XMLEntity getXMLEntity() throws XMLException {
847
        if (!this.isAvailable() && this.orgXMLEntity != null) {
848
            return this.orgXMLEntity;
849
        }
850
        XMLEntity xml = super.getXMLEntity();
851
        if (getLegend()!=null)
852
            xml.addChild(getLegend().getXMLEntity());
853
        try {
854
            if (getRecordset()!=null)
855
                xml.addChild(getRecordset().getSelectionSupport().getXMLEntity());
856
        } catch (ReadDriverException e1) {
857
            e1.printStackTrace();
858
            throw new XMLException(e1);
859
        }
860
        // Repongo el mismo ReadableVectorial m?s abajo para cuando se guarda el proyecto.
861
        ReadableVectorial rv=getSource();
862
        xml.putProperty("type", "vectorial");
863
        if (source instanceof VectorialEditableAdapter) {
864
            setSource(((VectorialEditableAdapter) source).getOriginalAdapter());
865
        }
866
        if (source instanceof VectorialFileAdapter) {
867
            xml.putProperty("type", "vectorial");
868
            xml.putProperty("file", ((VectorialFileAdapter) source)
869
                    .getFile());
870
            try {
871
                xml.putProperty("recordset-name", source.getRecordset()
872
                        .getName());
873
            } catch (ReadDriverException e) {
874
                throw new XMLException(e);
875
            } catch (RuntimeException e) {
876
                e.printStackTrace();
877
            }
878
        } else if (source instanceof VectorialDBAdapter) {
879
            xml.putProperty("type", "vectorial");
880

    
881
            IVectorialDatabaseDriver dbDriver = (IVectorialDatabaseDriver) source
882
                    .getDriver();
883

    
884
            // Guardamos el nombre del driver para poder recuperarlo
885
            // con el DriverManager de Fernando.
886
            xml.putProperty("db", dbDriver.getName());
887
            try {
888
                xml.putProperty("recordset-name", source.getRecordset()
889
                        .getName());
890
            } catch (ReadDriverException e) {
891
                throw new XMLException(e);
892
            } catch (RuntimeException e) {
893
                e.printStackTrace();
894
            }
895
            xml.addChild(dbDriver.getXMLEntity()); // Tercer child. Antes hemos
896
                                                    // metido la leyenda y el
897
                                                    // selection support
898
        } else if (source instanceof VectorialAdapter) {
899
            // Se supone que hemos hecho algo gen?rico.
900
            xml.putProperty("type", "vectorial");
901

    
902
            VectorialDriver driver = source.getDriver();
903

    
904
            // Guardamos el nombre del driver para poder recuperarlo
905
            // con el DriverManager de Fernando.
906
            xml.putProperty("other", driver.getName());
907
            // try {
908
            try {
909
                xml.putProperty("recordset-name", source.getRecordset()
910
                        .getName());
911
            } catch (ReadDriverException e) {
912
                throw new XMLException(e);
913
            } catch (RuntimeException e) {
914
                e.printStackTrace();
915
            }
916
            if (driver instanceof IPersistance) {
917
                // xml.putProperty("className", driver.getClass().getName());
918
                IPersistance persist = (IPersistance) driver;
919
                xml.addChild(persist.getXMLEntity()); // Tercer child. Antes
920
                                                        // hemos metido la
921
                                                        // leyenda y el
922
                                                        // selection support
923
            }
924
        }
925
        if (rv!=null)
926
            setSource(rv);
927
        xml.putProperty("driverName", source.getDriver().getName());
928
        if (bHasJoin)
929
            xml.putProperty("hasJoin", "true");
930

    
931
        // properties from ILabelable
932
        xml.putProperty("isLabeled", isLabeled);
933
        if (strategy != null) {
934
            XMLEntity strategyXML = strategy.getXMLEntity();
935
            strategyXML.putProperty("Strategy", strategy.getClassName());
936
            xml.addChild(strategy.getXMLEntity());
937
        }
938
        xml.addChild(getLinkProperties().getXMLEntity());
939
        return xml;
940
    }
941

    
942
    /**
943
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
944
     */
945
    public void setXMLEntity03(XMLEntity xml) throws XMLException {
946

    
947
        super.setXMLEntity(xml);
948
        legend = LegendFactory.createFromXML03(xml.getChild(0));
949

    
950
        try {
951
            setLegend(legend);
952
        } catch (LegendLayerException e) {
953
            throw new XMLException(e);
954
        }
955

    
956
        try {
957
            getRecordset().getSelectionSupport()
958
                    .setXMLEntity03(xml.getChild(1));
959
        } catch (ReadDriverException e) {
960
            e.printStackTrace();
961
        }
962
    }
963

    
964
    /*
965
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
966
     */
967
    public void setXMLEntity(XMLEntity xml) throws XMLException {
968
        try {
969
            super.setXMLEntity(xml);
970
            XMLEntity legendXML = xml.getChild(0);
971
            IVectorialLegend leg = LegendFactory.createFromXML(legendXML);
972
            /* (jaume) begin patch;
973
             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
974
             * no longer managed by the Legend but by the ILabelingStrategy. The
975
             * following allows restoring older projects' labelings.
976
             */
977
            if (legendXML.contains("labelFieldName")) {
978
                String labelTextField = legendXML.getStringProperty("labelFieldName");
979
                if (labelTextField != null) {
980
                    AttrInTableLabeling labeling = new AttrInTableLabeling();
981
                    labeling.setLayer(this);
982
                    labeling.setTextField(legendXML.getStringProperty("labelFieldName"));
983
                    labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
984
                    labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
985
                    this.setLabelingStrategy(labeling);
986
                    this.setIsLabeled(true);
987
                }
988
              }
989
            /* end patch */
990
            try {
991
                getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
992
                // JMVIVO: Esto sirve para algo????
993
                String recordsetName = xml.getStringProperty("recordset-name");
994

    
995
                LayerFactory.getDataSourceFactory().changeDataSourceName(
996
                        getSource().getRecordset().getName(), recordsetName);
997
            } catch (NoSuchTableException e1) {
998
                this.setAvailable(false);
999
                throw new XMLException(e1);
1000
            } catch (ReadDriverException e1) {
1001
                this.setAvailable(false);
1002
                throw new XMLException(e1);
1003
            }
1004
            // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
1005
            // el final
1006
            // de la lectura del proyecto
1007
            if (xml.contains("hasJoin")) {
1008
                setIsJoined(true);
1009
                PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
1010
            } else {
1011
                try {
1012

    
1013
                    setLegend(leg);
1014
                } catch (LegendLayerException e) {
1015
                    throw new XMLException(e);
1016
                }
1017
            }
1018

    
1019
            // set properties for ILabelable
1020
            for (int i = 0; i < xml.getChildrenCount(); i++) {
1021
                try {
1022
                    if (xml.getChild(i).contains("Strategy")) {
1023
                        XMLEntity xmlStrategy = xml.getChild(i);
1024
                        this.strategy = LabelingFactory.createStrategyFromXML(xmlStrategy.getChild(0));
1025
                    }
1026
                } catch (NotExistInXMLEntity neXMLEX) {
1027
                    // no strategy was set, just continue;
1028
                    logger.warn("Reached what should be unreachable code");
1029
                }
1030
            }
1031

    
1032
            XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
1033
            if (xmlLinkProperties != null){
1034
                     getLinkProperties().setXMLEntity(xmlLinkProperties);
1035
            }
1036

    
1037
        } catch (XMLException e) {
1038
            this.setAvailable(false);
1039
            this.orgXMLEntity = xml;
1040
        } catch (Exception e) {
1041
            e.printStackTrace();
1042
            this.setAvailable(false);
1043
            this.orgXMLEntity = xml;
1044

    
1045
        }
1046

    
1047

    
1048
    }
1049

    
1050
    public void setXMLEntityNew(XMLEntity xml) throws XMLException {
1051
        try {
1052
            super.setXMLEntity(xml);
1053

    
1054
            XMLEntity legendXML = xml.getChild(0);
1055
            IVectorialLegend leg = LegendFactory.createFromXML(legendXML);
1056
            /* (jaume) begin patch;
1057
             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1058
             * no longer managed by the Legend but by the ILabelingStrategy. The
1059
             * following allows restoring older projects' labelings.
1060
             */
1061
            if (legendXML.contains("labelFieldHeight")) {
1062
                AttrInTableLabeling labeling = new AttrInTableLabeling();
1063
                labeling.setLayer(this);
1064
                labeling.setTextField(legendXML.getStringProperty("labelFieldHeight"));
1065
                labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
1066
                this.setLabelingStrategy(labeling);
1067
                this.setIsLabeled(true);
1068
              }
1069
            /* end patch */
1070
            try {
1071
                getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
1072

    
1073
                this.setLoadSelection(xml.getChild(1));
1074
            } catch (ReadDriverException e1) {
1075
                this.setAvailable(false);
1076
                throw new XMLException(e1);
1077
            }
1078
            // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
1079
            // el final
1080
            // de la lectura del proyecto
1081
            if (xml.contains("hasJoin")) {
1082
                setIsJoined(true);
1083
                PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
1084
            } else {
1085
                this.setLoadLegend(leg);
1086
            }
1087

    
1088
        } catch (XMLException e) {
1089
            this.setAvailable(false);
1090
            this.orgXMLEntity = xml;
1091
        } catch (Exception e) {
1092
            this.setAvailable(false);
1093
            this.orgXMLEntity = xml;
1094
        }
1095

    
1096

    
1097
    }
1098

    
1099
    /**
1100
     * A?ade un LegendListener a la lista de Listeners.
1101
     *
1102
     * @param listener
1103
     *            LegendListener.
1104
     */
1105
    public void addLegendListener(LegendListener listener) {
1106
        layerChangeSupport.addLayerListener(listener);
1107
    }
1108

    
1109
    /**
1110
     * Llamada al m?todo callLegendChanged de los listener.
1111
     *
1112
     * @param e
1113
     *            Evento.
1114
     */
1115
    private void callLegendChanged(LegendChangedEvent e) {
1116
        layerChangeSupport.callLegendChanged(e);
1117
    }
1118

    
1119
    /**
1120
     * Borra un LegendListener de la lista de Listeners
1121
     *
1122
     * @param listener
1123
     *            LegendListener.
1124
     */
1125
    public void removeLegendListener(LegendListener listener) {
1126
        layerChangeSupport.removeLayerListener(listener);
1127
    }
1128

    
1129
    /**
1130
     * Sobreimplementaci?n del m?todo toString para que las bases de datos
1131
     * identifiquen la capa.
1132
     *
1133
     * @return DOCUMENT ME!
1134
     */
1135
    public String toString() {
1136
        /*
1137
         * Se usa internamente para que la parte de datos identifique de forma
1138
         * un?voca las tablas
1139
         */
1140
        String ret = super.toString();
1141

    
1142
        return "layer" + ret.substring(ret.indexOf('@') + 1);
1143
    }
1144

    
1145
    public boolean isJoined() {
1146
        return bHasJoin;
1147
    }
1148

    
1149
    /**
1150
     * Returns if a layer is spatially indexed
1151
     *
1152
     * @return if this layer has the ability to proces spatial queries without
1153
     *         secuential scans.
1154
     */
1155
    public boolean isSpatiallyIndexed() {
1156
        ReadableVectorial source = getSource();
1157
        if (source instanceof ISpatialDB)
1158
            return true;
1159

    
1160
//FIXME azabala
1161
/*
1162
 * Esto es muy dudoso, y puede cambiar.
1163
 * Estoy diciendo que las que no son fichero o no son
1164
 * BoundedShapes estan indexadas. Esto es mentira, pero
1165
 * as? quien pregunte no querr? generar el indice.
1166
 * Esta por ver si interesa generar el indice para capas
1167
 * HSQLDB, WFS, etc.
1168
 */
1169
        if(!(source instanceof VectorialFileAdapter)){
1170
            return true;
1171
        }
1172
        if (!(source.getDriver() instanceof BoundedShapes)) {
1173
            return true;
1174
        }
1175

    
1176
        if (getISpatialIndex() != null)
1177
            return true;
1178
        return false;
1179
    }
1180

    
1181
    public void setIsJoined(boolean hasJoin) {
1182
        bHasJoin = hasJoin;
1183
    }
1184

    
1185
    /**
1186
     * @return Returns the spatialIndex.
1187
     */
1188
    public ISpatialIndex getISpatialIndex() {
1189
        return spatialIndex;
1190
    }
1191
    /**
1192
     * Sets the spatial index. This could be useful if, for some
1193
     * reasons, you want to work with a distinct spatial index
1194
     * (for example, a spatial index which could makes nearest
1195
     * neighbour querys)
1196
     * @param spatialIndex
1197
     */
1198
    public void setISpatialIndex(ISpatialIndex spatialIndex){
1199
        this.spatialIndex = spatialIndex;
1200
    }
1201

    
1202
    public SelectableDataSource getRecordset() throws ReadDriverException {
1203
        if (!this.isAvailable()) return null;
1204
        if (sds == null) {
1205

    
1206
                SelectableDataSource ds = source.getRecordset();
1207

    
1208
                if (ds == null) {
1209
                    return null;
1210
                }
1211

    
1212
                sds = ds;
1213
                sds.setSelectionSupport(selectionSupport);
1214

    
1215
        }
1216
        return sds;
1217
    }
1218

    
1219
    public void setEditing(boolean b) throws StartEditionLayerException {
1220
        super.setEditing(b);
1221
        try {
1222
            if (b) {
1223
                VectorialEditableAdapter vea = null;
1224
                // TODO: Qu? pasa si hay m?s tipos de adapters?
1225
                // FJP: Se podr?a pasar como argumento el
1226
                // VectorialEditableAdapter
1227
                // que se quiera usar para evitar meter c?digo aqu? de este
1228
                // estilo.
1229
                if (getSource() instanceof VectorialDBAdapter) {
1230
                    vea = new VectorialEditableDBAdapter();
1231
                } else if (this instanceof FLyrAnnotation) {
1232
                    vea = new AnnotationEditableAdapter(
1233
                            (FLyrAnnotation) this);
1234
                } else {
1235
                    vea = new VectorialEditableAdapter();
1236
                }
1237
                vea.setOriginalVectorialAdapter(getSource());
1238
//                                azo: implementations of readablevectorial need
1239
                //references of projection and spatial index
1240
                vea.setProjection(getProjection());
1241
                vea.setSpatialIndex(spatialIndex);
1242

    
1243

    
1244
                // /vea.setSpatialIndex(getSpatialIndex());
1245
                // /vea.setFullExtent(getFullExtent());
1246
                vea.setCoordTrans(getCoordTrans());
1247
                vea.startEdition(EditionEvent.GRAPHIC);
1248
                setSource(vea);
1249
                getRecordset().setSelectionSupport(
1250
                        vea.getOriginalAdapter().getRecordset()
1251
                                .getSelectionSupport());
1252

    
1253
            } else {
1254
                VectorialEditableAdapter vea = (VectorialEditableAdapter) getSource();
1255
                setSource(vea.getOriginalAdapter());
1256
            }
1257
            // Si tenemos una leyenda, hay que pegarle el cambiazo a su
1258
            // recordset
1259
            setRecordset(getSource().getRecordset());
1260
            if (getLegend() instanceof IVectorialLegend) {
1261
                IVectorialLegend ley = (IVectorialLegend) getLegend();
1262
                ley.setDataSource(getSource().getRecordset());
1263
                // Esto lo pongo para evitar que al dibujar sobre un
1264
                // dxf, dwg, o dgn no veamos nada. Es debido al checkbox
1265
                // de la leyenda de textos "dibujar solo textos".
1266
//jaume
1267
//                                if (!(getSource().getDriver() instanceof IndexedShpDriver)){
1268
//                                        FSymbol symbol=new FSymbol(getShapeType());
1269
//                                        symbol.setFontSizeInPixels(false);
1270
//                                        symbol.setFont(new Font("SansSerif", Font.PLAIN, 9));
1271
//                                        Color color=symbol.getColor();
1272
//                                        int alpha=symbol.getColor().getAlpha();
1273
//                                        if (alpha>250) {
1274
//                                                symbol.setColor(new Color(color.getRed(),color.getGreen(),color.getBlue(),100));
1275
//                                        }
1276
//                                        ley.setDefaultSymbol(symbol);
1277
//                                }
1278
//jaume//
1279
                ley.useDefaultSymbol(true);
1280
            }
1281
        } catch (ReadDriverException e) {
1282
            throw new StartEditionLayerException(getName(),e);
1283
        } catch (FieldNotFoundException e) {
1284
            throw new StartEditionLayerException(getName(),e);
1285
        } catch (StartWriterVisitorException e) {
1286
            throw new StartEditionLayerException(getName(),e);
1287
        }
1288

    
1289
        setSpatialCacheEnabled(b);
1290
        callEditionChanged(LayerEvent
1291
                .createEditionChangedEvent(this, "edition"));
1292

    
1293
    }
1294

    
1295
    /**
1296
     * Para cuando haces una uni?n, sustituyes el recorset por el nuevo. De esta
1297
     * forma, podr?s poner leyendas basadas en el nuevo recordset
1298
     *
1299
     * @param newSds
1300
     */
1301
    public void setRecordset(SelectableDataSource newSds) {
1302
        sds = newSds;
1303
        sds.setSelectionSupport(selectionSupport);
1304
    }
1305

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

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

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

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

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

    
1331
    }
1332

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

    
1345
    public void reload() throws ReloadLayerException {
1346
        this.setAvailable(true);
1347
        super.reload();
1348
        try {
1349
            this.source.getDriver().reload();
1350
            if (this.getLegend() == null) {
1351
                if (this.getRecordset().getDriver() instanceof WithDefaultLegend) {
1352
                    WithDefaultLegend aux = (WithDefaultLegend) this.getRecordset().getDriver();
1353
                    this.setLegend((IVectorialLegend) aux.getDefaultLegend());
1354
                    this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
1355
                } else {
1356
                    this.setLegend(LegendFactory.createSingleSymbolLegend(
1357
                            this.getShapeType()));
1358
                }
1359
            }
1360

    
1361
        } catch (LegendLayerException e) {
1362
            this.setAvailable(false);
1363
            throw new ReloadLayerException(getName(),e);
1364
        } catch (ReadDriverException e) {
1365
            this.setAvailable(false);
1366
            throw new ReloadLayerException(getName(),e);
1367
        }
1368

    
1369
    }
1370

    
1371
    protected void setLoadSelection(XMLEntity xml) {
1372
        this.loadSelection = xml;
1373
    }
1374

    
1375
    protected void setLoadLegend(IVectorialLegend legend) {
1376
        this.loadLegend = legend;
1377
    }
1378

    
1379
    protected void putLoadSelection() throws XMLException {
1380
        if (this.loadSelection == null) return;
1381
        try {
1382
            this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
1383
        } catch (ReadDriverException e) {
1384
            throw new XMLException(e);
1385
        }
1386
        this.loadSelection = null;
1387

    
1388
    }
1389
    protected void putLoadLegend() throws LegendLayerException {
1390
        if (this.loadLegend == null) return;
1391
        this.setLegend(this.loadLegend);
1392
        this.loadLegend = null;
1393
    }
1394

    
1395
    protected void cleanLoadOptions() {
1396
        this.loadLegend = null;
1397
        this.loadSelection = null;
1398
    }
1399

    
1400
    public boolean isWritable() {
1401
        VectorialDriver drv = getSource().getDriver();
1402
        if (!drv.isWritable())
1403
            return false;
1404
        if (drv instanceof IWriteable)
1405
        {
1406
            IWriter writer = ((IWriteable)drv).getWriter();
1407
            if (writer != null)
1408
            {
1409
                if (writer instanceof ISpatialWriter)
1410
                    return true;
1411
            }
1412
        }
1413
        return false;
1414

    
1415
    }
1416

    
1417
    public FLayer cloneLayer() throws Exception {
1418
        FLyrVect clonedLayer = new FLyrVect();
1419
        clonedLayer.setSource(getSource());
1420
        if (isJoined()) {
1421
                        clonedLayer.setIsJoined(true);
1422
                        clonedLayer.setRecordset(getRecordset());
1423
                }
1424
        clonedLayer.setVisible(isVisible());
1425
        clonedLayer.setISpatialIndex(getISpatialIndex());
1426
        clonedLayer.setName(getName());
1427
        clonedLayer.setCoordTrans(getCoordTrans());
1428

    
1429
        clonedLayer.setLegend((IVectorialLegend)getLegend().cloneLegend());
1430

    
1431
        clonedLayer.setIsLabeled(isLabeled());
1432
        clonedLayer.setLabelingStrategy(getLabelingStrategy());
1433

    
1434
        return clonedLayer;
1435
    }
1436

    
1437

    
1438
    private boolean isOnePoint(ViewPort viewPort, double dpi, CartographicSupport csSym, IGeometry geom, int[] xyCoords) {
1439
            return isOnePoint(viewPort, geom, xyCoords) && csSym.getCartographicSize(viewPort, dpi, null) <= 1;
1440
    }
1441

    
1442
    private boolean isOnePoint(ViewPort viewPort, IGeometry geom, int[] xyCoords) {
1443
            boolean onePoint = false;
1444
            if (geom.getGeometryType()!=FShape.POINT) {
1445

    
1446
                        Rectangle2D geomBounds = geom.getBounds2D();
1447

    
1448
                        ICoordTrans ct = getCoordTrans();
1449

    
1450
                        if (ct!=null) {
1451
                                geomBounds = ct.getInverted().convert(geomBounds);
1452
                        }
1453

    
1454
                        double dist1Pixel = viewPort.getDist1pixel();
1455

    
1456
                        onePoint = (geomBounds.getWidth()  <= dist1Pixel
1457
                                         && geomBounds.getHeight() <= dist1Pixel);
1458

    
1459
                        if (onePoint) {
1460
                                // avoid out of range exceptions
1461
                                FPoint2D p = new FPoint2D(geomBounds.getMinX(), geomBounds.getMinY());
1462
                                p.transform(viewPort.getAffineTransform());
1463
                                xyCoords[0] = (int) p.getX();
1464
                                xyCoords[1] = (int) p.getY();
1465

    
1466
                        }
1467

    
1468
                } 
1469
            return onePoint;
1470
    }
1471
    /*
1472
     * jaume. Stuff from ILabeled.
1473
     */
1474
    private boolean isLabeled;
1475
    private ILabelingStrategy strategy;
1476

    
1477
    public boolean isLabeled() {
1478
        return isLabeled;
1479
    }
1480

    
1481
    public void setIsLabeled(boolean isLabeled) {
1482
        this.isLabeled = isLabeled;
1483
    }
1484

    
1485
    public ILabelingStrategy getLabelingStrategy() {
1486
        return strategy;
1487
    }
1488

    
1489
    public void setLabelingStrategy(ILabelingStrategy strategy) {
1490
        this.strategy = strategy;
1491
    }
1492

    
1493
    public void drawLabels(BufferedImage image, Graphics2D g, ViewPort viewPort,
1494
                    Cancellable cancel, double scale) throws ReadDriverException {
1495
        if (isWithinScale(scale)) {
1496
                strategy.draw(image, g, viewPort, cancel);
1497
        }
1498
    }
1499

    
1500

    
1501

    
1502
    //M?todos para el uso de HyperLinks en capas FLyerVect
1503

    
1504
    /**
1505
     * Return true, because a Vectorial Layer supports HyperLink
1506
     */
1507
    public boolean allowLinks()
1508
    {
1509
            return true;
1510
    }
1511

    
1512
    /**
1513
         * Returns an instance of AbstractLinkProperties that contains the information
1514
         * of the HyperLink
1515
         * @return Abstra
1516
         */
1517
    public AbstractLinkProperties getLinkProperties()
1518
    {
1519
            return linkProperties;
1520
    }
1521

    
1522
    /**
1523
         * Provides an array with URIs. Returns one URI by geometry that includes the point
1524
         * in its own geometry limits with a allowed tolerance.
1525
         * @param layer, the layer
1526
         * @param point, the point to check that is contained or not in the geometries in the layer
1527
         * @param tolerance, the tolerance allowed. Allowed margin of error to detect if the  point
1528
         *                 is contained in some geometries of the layer
1529
         * @return
1530
         */
1531
    public URI[] getLink(Point2D point, double tolerance)
1532
    {
1533
            //return linkProperties.getLink(this)
1534
            return linkProperties.getLink(this,point,tolerance);
1535
    }
1536

    
1537
 }