Statistics
| Revision:

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

History | View | Annotate | Download (66.7 KB)

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

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

    
137
/**
138
 * Capa b?sica Vectorial.
139
 *
140
 * @author Fernando Gonz?lez Cort?s
141
 */
142

    
143
// TODO Cuando no sea para pruebas debe no ser public
144
public class FLyrVect extends FLyrDefault implements ILabelable,
145
        ClassifiableVectorial, SingleLayer, VectorialData, RandomVectorialData,
146
        AlphanumericData, InfoByPoint, SelectionListener, IEditionListener, LegendContentsChangedListener {
147
    private static Logger logger = Logger.getLogger(FLyrVect.class.getName());
148
    /**
149
     * @deprecated Don?t use Strategy, you should be use iterators.
150
     */
151
//    public static boolean forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD = true;
152
    /**
153
     * @deprecated Don?t use Strategy, you should be use iterators.
154
     */
155
//    private boolean useStrategy=false;
156

    
157
    /** Leyenda de la capa vectorial */
158
    private IVectorLegend legend;
159
    private int typeShape = -1;
160
    private ReadableVectorial source;
161
    private SelectableDataSource sds;
162
    private SelectionSupport selectionSupport = new SelectionSupport();
163
    private SpatialCache spatialCache = new SpatialCache();
164
    private boolean spatialCacheEnabled = false;
165

    
166
    /**
167
     * An implementation of gvSIG spatial index
168
     */
169
    protected ISpatialIndex spatialIndex = null;
170
    private boolean bHasJoin = false;
171
    private XMLEntity orgXMLEntity = null;
172
    private XMLEntity loadSelection = null;
173
    private IVectorLegend loadLegend = null;
174

    
175
    //Lo a?ado. Caracter?sticas de HyperEnlace (LINK)
176
    private FLyrVectLinkProperties linkProperties=new FLyrVectLinkProperties();
177
    //private ArrayList linkProperties=null;
178

    
179
    /**
180
     * Devuelve el VectorialAdapater de la capa.
181
     *
182
     * @return VectorialAdapter.
183
     */
184
    public ReadableVectorial getSource() {
185
        if (!this.isAvailable()) return null;
186
        return source;
187
    }
188

    
189
    /**
190
     * If we use a persistent spatial index associated with this layer, and the
191
     * index is not intrisic to the layer (for example spatial databases) this
192
     * method looks for existent spatial index, and loads it.
193
     *
194
     */
195
    private void loadSpatialIndex() {
196
        //FIXME: Al abrir el indice en fichero...
197
        //?C?mo lo liberamos? un metodo Layer.shutdown()
198

    
199

    
200
        ReadableVectorial source = getSource();
201
        //REVISAR QUE PASA CON LOS DRIVERS DXF, DGN, etc.
202
        //PUES SON VECTORIALFILEADAPTER
203
        if (!(source instanceof VectorialFileAdapter)) {
204
            // we are not interested in db adapters
205
            return;
206
        }
207
        VectorialDriver driver = source.getDriver();
208
        if (!(driver instanceof BoundedShapes)) {
209
            // we dont spatially index layers that are not bounded
210
            return;
211
        }
212
        File file = ((VectorialFileAdapter) source).getFile();
213
        String fileName = file.getAbsolutePath();
214
        File sptFile = new File(fileName + ".qix");
215
        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
216
            // before to exit, look for it in temp path
217
            String tempPath = System.getProperty("java.io.tmpdir");
218
            fileName = tempPath + File.separator + sptFile.getName();
219
            sptFile = new File(fileName);
220
            // it doesnt exists, must to create
221
            if (!sptFile.exists() || (!(sptFile.length() > 0))) {
222
                return;
223
            }// if
224
        }// if
225

    
226
        try {
227
            source.start();
228
            spatialIndex = new QuadtreeGt2(FileUtils.getFileWithoutExtension(sptFile),
229
                    "NM", source.getFullExtent(), source.getShapeCount(), false);
230
            source.setSpatialIndex(spatialIndex);
231
        } catch (SpatialIndexException e) {
232
            spatialIndex = null;
233
            e.printStackTrace();
234
            return;
235
        } catch (ReadDriverException e) {
236
            spatialIndex = null;
237
            e.printStackTrace();
238
            return;
239
        }
240

    
241
    }
242

    
243
    /**
244
     * Checks if it has associated an external spatial index
245
     * (an spatial index file).
246
     *
247
     * It looks for it in main file path, or in temp system path.
248
     * If main file is rivers.shp, it looks for a file called
249
     * rivers.shp.qix.
250

251
     * @return
252
     */
253
    public boolean isExternallySpatiallyIndexed() {
254
        /*
255
         * FIXME (AZABALA): Independizar del tipo de fichero de ?ndice
256
          * con el que se trabaje (ahora mismo considera la extension .qix,
257
         * pero esto depender? del tipo de ?ndice)
258
         * */
259
        ReadableVectorial source = getSource();
260
        if (!(source instanceof VectorialFileAdapter)) {
261
            // we are not interested in db adapters.
262
            // think in non spatial dbs, like HSQLDB
263
            return false;
264
        }
265
        File file = ((VectorialFileAdapter) source).getFile();
266
        String fileName = file.getAbsolutePath();
267
        File sptFile = new File(fileName + ".qix");
268
        if (!sptFile.exists() || (!(sptFile.length() > 0))) {
269
            // before to exit, look for it in temp path
270
            // it doesnt exists, must to create
271
            String tempPath = System.getProperty("java.io.tmpdir");
272
            fileName = tempPath + File.separator + sptFile.getName();
273
            sptFile = new File(fileName);
274
            if (!sptFile.exists() || (!(sptFile.length() > 0))) {
275
                return false;
276
            }// if
277
        }// if
278
        return true;
279
    }
280

    
281
    /**
282
     * Inserta el VectorialAdapter a la capa.
283
     *
284
     * @param va
285
     *            VectorialAdapter.
286
     */
287
    public void setSource(ReadableVectorial rv) {
288
        source = rv;
289
        // azabala: we check if this layer could have a file spatial index
290
        // and load it if it exists
291
        loadSpatialIndex();
292
    }
293

    
294
    public Rectangle2D getFullExtent() throws ReadDriverException, ExpansionFileReadException {
295
            Rectangle2D rAux;
296
            source.start();
297
            rAux = (Rectangle2D)source.getFullExtent().clone();
298
            source.stop();
299

    
300
            // Si existe reproyecci?n, reproyectar el extent
301
            ICoordTrans ct = getCoordTrans();
302

    
303
            if (ct != null) {
304
                Point2D pt1 = new Point2D.Double(rAux.getMinX(), rAux.getMinY());
305
                Point2D pt2 = new Point2D.Double(rAux.getMaxX(), rAux.getMaxY());
306
                pt1 = ct.convert(pt1, null);
307
                pt2 = ct.convert(pt2, null);
308
                rAux = new Rectangle2D.Double();
309
                rAux.setFrameFromDiagonal(pt1, pt2);
310
            }
311

    
312
            //Esto es para cuando se crea una capa nueva con el fullExtent de ancho y alto 0.
313
            if (rAux.getWidth()==0 && rAux.getHeight()==0) {
314
                rAux=new Rectangle2D.Double(0,0,100,100);
315
            }
316

    
317
            return rAux;
318
    }
319

    
320
    /**
321
     * Draws using IFeatureIterator. This method will replace the old draw(...) one.
322
     * @autor jaume dominguez faus - jaume.dominguez@iver.es
323
     * @param image
324
     * @param g
325
     * @param viewPort
326
     * @param cancel
327
     * @param scale
328
     * @throws ReadDriverException
329
     */
330
    private void _draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
331
                    Cancellable cancel, double scale) throws ReadDriverException {
332
            boolean bDrawShapes = true;
333
            if (legend instanceof SingleSymbolLegend) {
334
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
335
            }
336
            Point2D offset = viewPort.getOffset();
337
            double dpi = MapContext.getScreenDPI();
338

    
339

    
340

    
341
            if (bDrawShapes) {
342
                    boolean cacheFeatures = isSpatialCacheEnabled();
343
                    SpatialCache cache = null;
344
                    if (cacheFeatures) {
345
                            getSpatialCache().clearAll();
346
                            cache = getSpatialCache();
347
                    }
348

    
349
                    try {
350
                            ArrayList<String> fieldList = new ArrayList<String>();
351

    
352
                            // fields from legend
353
                            String[] aux = null;
354

    
355
                            if (legend instanceof IClassifiedVectorLegend) {
356
                                    aux = ((IClassifiedVectorLegend) legend).getClassifyingFieldNames();
357
                                    if (aux!=null)
358
                                            for (int i = 0; i < aux.length; i++) {
359
                                                    fieldList.add(aux[i]);
360
                                            }
361
                            }
362

    
363
                            // Get the iterator over the visible features
364
                            IFeatureIterator it = getSource().getFeatureIterator(
365
                                            viewPort.getAdjustedExtent(),
366
                                            fieldList.toArray(new String[fieldList.size()]),
367
                                            viewPort.getProjection(),
368
                                            true);
369

    
370
                            ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
371

    
372
                            boolean bSymbolLevelError = false;
373

    
374
                            // if layer has map levels it will use a ZSort
375
                            boolean useZSort = zSort != null && zSort.isUsingZSort();
376

    
377
                            // -- visual FX stuff
378
                            long time = System.currentTimeMillis();
379
                            BufferedImage virtualBim;
380
                            Graphics2D virtualGraphics;
381

    
382
                            // render temporary map each screenRefreshRate milliseconds;
383
                            int screenRefreshDelay = (int) ((1D/MapControl.getDrawFrameRate())*3*1000);
384
                            BufferedImage[] imageLevels = null;
385
                            Graphics2D[] graphics = null;
386
                            if (useZSort) {
387
                                    imageLevels = new BufferedImage[zSort.getLevelCount()];
388
                                    graphics = new Graphics2D[imageLevels.length];
389
                                    for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
390
                                            imageLevels[i] = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
391
                                            graphics[i] = imageLevels[i].createGraphics();
392
                                            graphics[i].setTransform(g.getTransform());
393
                                            graphics[i].setRenderingHints(g.getRenderingHints());
394
                                    }
395
                            }
396
                            // -- end visual FX stuff
397

    
398

    
399
                            // Iteration over each feature
400
                            while ( !cancel.isCanceled() && it.hasNext()) {
401
                                    IFeature feat = it.next();
402
                                    IGeometry geom = feat.getGeometry();
403

    
404
                                    if (cacheFeatures) {
405
                                            if (cache.getMaxFeatures() >= cache.size()) {
406
                                                    // already reprojected
407
                                                    cache.insert(geom.getBounds2D(), geom);
408
                                            }
409
                                    }
410

    
411
                                    // retrieve the symbol associated to such feature
412
                                    ISymbol sym = legend.getSymbolByFeature(feat);
413

    
414
                                    if (sym == null) continue;
415

    
416
                                    //C?digo para poder acceder a los ?ndices para ver si est? seleccionado un Feature
417
                                    ReadableVectorial rv=getSource();
418
                                    int selectionIndex=-1;
419
                                    if (rv instanceof ISpatialDB){
420
                                            selectionIndex = ((ISpatialDB)rv).getRowIndexByFID(feat);
421
                                    }else{
422
                                            selectionIndex = Integer.parseInt(feat.getID());
423
                                    }
424
                                    if (selectionIndex!=-1) {
425
                                            if (selectionSupport.isSelected(selectionIndex)) {
426
                                                    sym = sym.getSymbolForSelection();
427
                                            }
428
                                    }
429

    
430
                                    // Check if this symbol is sized with CartographicSupport
431
                                    CartographicSupport csSym = null;
432
                                    int symbolType = sym.getSymbolType();
433
                                    boolean bDrawCartographicSupport = false;
434

    
435
                                    if (   symbolType == FShape.POINT
436
                                                    || symbolType == FShape.LINE
437
                                                    || sym instanceof CartographicSupport) {
438

    
439
                                            // patch
440
                                            if (!sym.getClass().equals(FSymbol.class)) {
441
                                                    csSym = (CartographicSupport) sym;
442
                                                    bDrawCartographicSupport = (csSym.getUnit() != -1);
443
                                            }
444
                                    }
445

    
446
                                    int x = -1;
447
                                    int y = -1;
448
                                    int[] xyCoords = new int[2];
449

    
450
                                    // Check if size is a pixel
451
                                    boolean onePoint = bDrawCartographicSupport ?
452
                                                    isOnePoint(g.getTransform(), viewPort, MapContext.getScreenDPI(), csSym, geom, xyCoords) :
453
                                                            isOnePoint(g.getTransform(), viewPort, geom, xyCoords);
454

    
455
//                                                    System.out.println("onePoint");
456

    
457
                                                    // Avoid out of bounds exceptions
458
                                                    if (onePoint) {
459
                                                            x = xyCoords[0];
460
                                                            y = xyCoords[1];
461
                                                            if (x<0 || y<0 || x>= viewPort.getImageWidth() || y>=viewPort.getImageHeight()) continue;
462
                                                    }
463

    
464
                                                    if (useZSort) {
465
                                                            // Check if this symbol is a multilayer
466
                                                                int[] symLevels = zSort.getLevels(sym);
467
                                                            if (sym instanceof IMultiLayerSymbol) {
468
                                                                    // if so, treat each of its layers as a single symbol
469
                                                                    // in its corresponding map level
470
                                                                    IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
471
                                                                    for (int i = 0; !cancel.isCanceled() && i < mlSym.getLayerCount(); i++) {
472
                                                                            ISymbol mySym = mlSym.getLayer(i);
473
                                                                        int symbolLevel = 0;
474
                                                                        if (symLevels != null) {
475
                                                                                symbolLevel = symLevels[i];
476
                                                                        } else {
477
                                                                                    /* an error occured when managing symbol levels.
478
                                                                                     * some of the legend changed events regarding the
479
                                                                                     * symbols did not finish satisfactory and the legend
480
                                                                                     * is now inconsistent. For this drawing, it will finish
481
                                                                                     * as it was at the bottom (level 0) but, when done, the
482
                                                                                     * ZSort will be reset to avoid app crashes. This is
483
                                                                                     * a bug that has to be fixed.
484
                                                                                     */
485
                                                                                    bSymbolLevelError = true;
486
                                                                            }
487

    
488
                                                                            if (onePoint) {
489
                                                                                    if (x<0 || y<0 || x>= imageLevels[symbolLevel].getWidth() || y>=imageLevels[symbolLevel].getHeight()) continue;
490
                                                                                    imageLevels[symbolLevel].setRGB(x, y, mySym.getOnePointRgb());
491
                                                                            } else {
492
                                                                                    if (!bDrawCartographicSupport) {
493
                                                                                            geom.drawInts(graphics[symbolLevel], viewPort, mySym, cancel);
494
                                                                                    } else {
495
                                                                                            geom.drawInts(graphics[symbolLevel], viewPort, dpi, (CartographicSupport) mySym, cancel);
496
                                                                                    }
497
                                                                            }
498
                                                                    }
499
                                                            } else {
500
                                                                    // else, just draw the symbol in its level
501
                                                                    int symbolLevel = 0;
502
                                                                    if (symLevels != null) {
503

    
504
                                                                            symbolLevel=symLevels[0];
505
                                                                    } else {
506
                                                                            /* If symLevels == null
507
                                                                             * an error occured when managing symbol levels.
508
                                                                             * some of the legend changed events regarding the
509
                                                                             * symbols did not finish satisfactory and the legend
510
                                                                             * is now inconsistent. For this drawing, it will finish
511
                                                                             * as it was at the bottom (level 0). This is
512
                                                                             * a bug that has to be fixed.
513
                                                                             */
514
//                                                                            bSymbolLevelError = true;
515
                                                                    }
516

    
517
                                                                    if (!bDrawCartographicSupport) {
518
                                                                            geom.drawInts(graphics[symbolLevel], viewPort, sym, cancel);
519
                                                                    } else {
520
                                                                            geom.drawInts(graphics[symbolLevel], viewPort, dpi, (CartographicSupport) csSym, cancel);
521
                                                                    }
522
                                                            }
523

    
524
                                                            // -- visual FX stuff
525
                                                            // Cuando el offset!=0 se est? dibujando sobre el Layout y por tanto no tiene que ejecutar el siguiente c?digo.
526
                                                            if (offset.getX()==0 && offset.getY()==0)
527
                                                                    if ((System.currentTimeMillis() - time) > screenRefreshDelay) {
528
                                                                            virtualBim = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_ARGB);
529
                                                                            virtualGraphics = virtualBim.createGraphics();
530
                                                                            virtualGraphics.drawImage(image,0,0, null);
531
                                                                            for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
532
                                                                                    virtualGraphics.drawImage(imageLevels[i],0,0, null);
533
                                                                            }
534
                                                                            g.clearRect(0, 0, image.getWidth(), image.getHeight());
535
                                                                            g.drawImage(virtualBim, 0, 0, null);
536
                                                                            time = System.currentTimeMillis();
537
                                                                    }
538
                                                            // -- end visual FX stuff
539

    
540
                                                    } else {
541
                                                            // no ZSort, so there is only a map level, symbols are
542
                                                            // just drawn.
543
                                                            if (onePoint) {
544
                                                                    if (x<0 || y<0 || x>= image.getWidth() || y>=image.getHeight()) continue;
545
                                                                    image.setRGB(x, y, sym.getOnePointRgb());
546
                                                            } else {
547
                                                                    if (!bDrawCartographicSupport) {
548
                                                                            geom.drawInts(g, viewPort, sym, cancel);
549
                                                                    } else {
550
                                                                            geom.drawInts(g, viewPort, dpi, csSym, cancel);
551
                                                                    }
552
                                                            }
553
                                                    }
554
                            }
555

    
556
                            if (useZSort) {
557
                                    g.drawImage(image, 0, 0, null);
558
                                    g.translate(offset.getX(), offset.getY());
559
                                    for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
560
                                            g.drawImage(imageLevels[i],0,0, null);
561
                                            imageLevels[i] = null;
562
                                            graphics[i] = null;
563
                                    }
564
                                    g.translate(-offset.getX(), -offset.getY());
565
                                    imageLevels = null;
566
                                    graphics = null;
567
                            }
568
                            it.closeIterator();
569

    
570
                            if (bSymbolLevelError) {
571
                                    ((IVectorLegend) getLegend()).setZSort(null);
572
                            }
573

    
574
                    } catch (ReadDriverException e) {
575
                            this.setVisible(false);
576
                            this.setActive(false);
577
                            throw e;
578
                    }
579

    
580

    
581
            }
582
    }
583

    
584
           public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
585
            Cancellable cancel, double scale) throws ReadDriverException {
586
//            forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD = true;
587
//            if (!isUseStrategy()) {
588
                    _draw(image, g, viewPort, cancel, scale);
589
//            } else {
590
////                    moved up to FLayers
591
////                    if (isWithinScale(scale)) {
592
//
593
//
594
//                            // Las que solo tienen etiquetado sin pintar el shape,
595
//                            // no pasamos por ellas
596
//                            boolean bDrawShapes = true;
597
//                            if (legend instanceof SingleSymbolLegend) {
598
//                                    if (legend.getDefaultSymbol().isShapeVisible() == false)
599
//                                            bDrawShapes = false;
600
//                            }
601
//                            if (bDrawShapes) {
602
//                                    Strategy strategy = StrategyManager.getStrategy(this);
603
//                                    try {
604
//                                            prepareDrawing(image, g, viewPort);
605
//                                            strategy.draw(image, g, viewPort, cancel);
606
//                                    } catch (ReadDriverException e) {
607
//                                            this.setVisible(false);
608
//                                            this.setActive(false);
609
//                                            throw e;
610
//                                    }
611
//                            }
612
//                            if (getVirtualLayers() != null) {
613
//                                    getVirtualLayers().draw(image, g, viewPort, cancel, scale);
614
//                            }
615
////                    }
616
//            }
617
    }
618

    
619
    /**
620
     * Se llama antes de empezar a pintar.
621
     * Es ?til para preparar la cache a emplear, las leyendas, etc.
622
     * @param image
623
     * @param g
624
     * @param viewPort
625
     */
626
    private void prepareDrawing(BufferedImage image, Graphics2D g, ViewPort viewPort) {
627

    
628
    }
629

    
630
    public void _print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
631
                    double scale, PrintRequestAttributeSet properties) throws ReadDriverException {
632
            // TEST METHOD
633

    
634

    
635
                    /* SVN */
636

    
637
    /*        boolean bDrawShapes = true;
638
            if (legend instanceof SingleSymbolLegend) {
639
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
640
            }
641

642

643
            if (bDrawShapes) {
644
                    double dpi = 72;
645

646
                    PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
647
                    if (resolution.equals(PrintQuality.NORMAL)){
648
                            dpi = 300;
649
                    } else if (resolution.equals(PrintQuality.HIGH)){
650
                            dpi = 600;
651
                    } else if (resolution.equals(PrintQuality.DRAFT)){
652
                            dpi = 72;
653
                    }
654

655

656
                    try {
657
                            prepareDrawing(null, g, viewPort);
658
                            ArrayList<String> fieldList = new ArrayList<String>();
659
                            String[] aux;
660

661
                            // fields from legend
662
                            if (legend instanceof IClassifiedVectorLegend) {
663
                                    aux = ((IClassifiedVectorLegend) legend).
664
                                                                            getClassifyingFieldNames();
665
                                    for (int i = 0; i < aux.length; i++) {
666
                                            fieldList.add(aux[i]);
667
                                    }
668
                            }
669

670
                            // fields from labeling
671
                            if (isLabeled()) {
672
                                    aux = getLabelingStrategy().getUsedFields();
673
                                    for (int i = 0; i < aux.length; i++) {
674
                                            fieldList.add(aux[i]);
675
                                    }
676
                            }
677

678
                            ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
679

680
                            // if layer has map levels it will use a ZSort
681
                            boolean useZSort = zSort != null && zSort.isUsingZSort();
682

683

684
                            int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1;
685
                            for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) {
686
                                    // Get the iterator over the visible features
687
                                    IFeatureIterator it = getSource().getFeatureIterator(
688
                                                    viewPort.getAdjustedExtent(),
689
                                                    fieldList.toArray(new String[fieldList.size()]),
690
                                                    viewPort.getProjection(),
691
                                                    true);
692

693
                                    // Iteration over each feature
694
                                    while ( !cancel.isCanceled() && it.hasNext()) {
695
                                            IFeature feat = it.next();
696
                                            IGeometry geom = feat.getGeometry();
697

698
                                            // retreive the symbol associated to such feature
699
                                            ISymbol sym = legend.getSymbolByFeature(feat);
700

701
                                            if (useZSort) {
702
                                                    // Check if this symbol is a multilayer
703
                                                        if (sym instanceof IMultiLayerSymbol) {
704
                                                                // if so, get the layer corresponding to the current
705
                                                                // level. If none, continue to next iteration
706
                                                                IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
707
                                                                for (int i = 0; i < mlSym.getLayerCount(); i++) {
708
                                                                        ISymbol mySym = mlSym.getLayer(i);
709
                                                                        if (zSort.getSymbolLevel(mySym) == mapPass) {
710
                                                                                sym = mySym;
711
                                                                                break;
712
                                                                        }
713
                                                                        System.out.println("avoided layer "+i+"of symbol '"+mlSym.getDescription()+"' (pass "+mapPass+")");
714
                                                                }
715

716
                                                                if (sym == null) {
717
                                                                        continue;
718
                                                                }
719
                                                        } else {
720
                                                                // else, just draw the symbol in its level
721
                                                                if (zSort.getSymbolLevel(sym) != mapPass) {
722
                                                                        System.out.println("avoided single layer symbol '"+sym.getDescription()+"' (pass "+mapPass+")");
723
                                                                        continue;
724
                                                                }
725
                                                        }
726
                                            }
727

728
                                            // Check if this symbol is sized with CartographicSupport
729
                                            CartographicSupport csSym = null;
730
                                            int symbolType = sym.getSymbolType();
731
                                            boolean bDrawCartographicSupport = false;
732

733
                                            if (   symbolType == FShape.POINT
734
                                                            || symbolType == FShape.LINE
735
                                                            || sym instanceof CartographicSupport) {
736

737
                                                    csSym = (CartographicSupport) sym;
738
                                                    bDrawCartographicSupport = (csSym.getUnit() != -1);
739
                                            }
740

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

743
                                            if (!bDrawCartographicSupport) {
744
                                                    geom.drawInts(g, viewPort, sym, null);
745
                                            } else {
746
                                                    geom.drawInts(g, viewPort, dpi, (CartographicSupport) csSym);
747
                                            }
748

749
                                    }
750
                                    it.closeIterator();
751
                            }
752
                    } catch (ReadDriverException e) {
753
                            this.setVisible(false);
754
                            this.setActive(false);
755
                            throw e;
756
                    }
757
        */
758

    
759

    
760
            // TEST METHOD
761
            boolean bDrawShapes = true;
762
            if (legend instanceof SingleSymbolLegend) {
763
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
764
            }
765

    
766

    
767
            if (bDrawShapes) {
768

    
769
                    try {
770
                            double dpi = 72;
771

    
772
                            PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
773
                            if (resolution.equals(PrintQuality.NORMAL)){
774
                                    dpi = 300;
775
                            } else if (resolution.equals(PrintQuality.HIGH)){
776
                                    dpi = 600;
777
                            } else if (resolution.equals(PrintQuality.DRAFT)){
778
                                    dpi = 72;
779
                            }
780
                            ArrayList<String> fieldList = new ArrayList<String>();
781
                            String[] aux;
782

    
783
                            // fields from legend
784
                            if (legend instanceof IClassifiedVectorLegend) {
785
                                    aux = ((IClassifiedVectorLegend) legend).
786
                                    getClassifyingFieldNames();
787
                                    for (int i = 0; i < aux.length; i++) {
788
                                            fieldList.add(aux[i]);
789
                                    }
790
                            }
791
//
792
//                            // fields from labeling
793
//                            if (isLabeled()) {
794
//                                    aux = getLabelingStrategy().getUsedFields();
795
//                                    for (int i = 0; i < aux.length; i++) {
796
//                                            fieldList.add(aux[i]);
797
//                                    }
798
//                            }
799

    
800
                            ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
801

    
802
                            // if layer has map levels it will use a ZSort
803
                            boolean useZSort = zSort != null && zSort.isUsingZSort();
804

    
805

    
806
                            int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1;
807
                            for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) {
808
                                    // Get the iterator over the visible features
809
                                    IFeatureIterator it = getSource().getFeatureIterator(
810
                                                    viewPort.getAdjustedExtent(),
811
                                                    fieldList.toArray(new String[fieldList.size()]),
812
                                                    viewPort.getProjection(),
813
                                                    true);
814

    
815
                                    // Iteration over each feature
816
                                    while ( !cancel.isCanceled() && it.hasNext()) {
817
                                            IFeature feat = it.next();
818
                                            IGeometry geom = feat.getGeometry();
819

    
820
                                            // retreive the symbol associated to such feature
821
                                            ISymbol sym = legend.getSymbolByFeature(feat);
822

    
823
                                            if (useZSort) {
824
                                                        int[] symLevels = zSort.getLevels(sym);
825
                                                        if(symLevels != null){
826
                                                                // Check if this symbol is a multilayer
827
                                                                if (sym instanceof IMultiLayerSymbol) {
828
                                                                        // if so, get the layer corresponding to the current
829
                                                                        // level. If none, continue to next iteration
830
                                                                        IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
831
                                                                        for (int i = 0; i < mlSym.getLayerCount(); i++) {
832
                                                                                ISymbol mySym = mlSym.getLayer(i);
833
                                                                                if (symLevels[i] == mapPass) {
834
                                                                                        sym = mySym;
835
                                                                                        break;
836
                                                                                }
837
                                                                                System.out.println("avoided layer "+i+"of symbol '"+mlSym.getDescription()+"' (pass "+mapPass+")");
838
                                                                        }
839

    
840
                                                                        if (sym == null) {
841
                                                                                continue;
842
                                                                        }
843
                                                                } else {
844
                                                                        // else, just draw the symbol in its level
845
                                                                        if (symLevels[0] != mapPass) {
846
                                                                                System.out.println("avoided single layer symbol '"+sym.getDescription()+"' (pass "+mapPass+")");
847
                                                                                continue;
848
                                                                        }
849
                                                                }
850
                                                        }
851
                                            }
852

    
853
                                            // Check if this symbol is sized with CartographicSupport
854
                                            CartographicSupport csSym = null;
855
                                            int symbolType = sym.getSymbolType();
856
                                            boolean bDrawCartographicSupport = false;
857

    
858
                                            if (   symbolType == FShape.POINT
859
                                                            || symbolType == FShape.LINE
860
                                                            || sym instanceof CartographicSupport) {
861

    
862
                                                    csSym = (CartographicSupport) sym;
863
                                                    bDrawCartographicSupport = (csSym.getUnit() != -1);
864
                                            }
865

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

    
868
                                            if (!bDrawCartographicSupport) {
869
                                                    geom.drawInts(g, viewPort, sym, null);
870
                                            } else {
871
                                                    geom.drawInts(g, viewPort, dpi, (CartographicSupport) csSym, cancel);
872
                                            }
873

    
874
                                    }
875
                                    it.closeIterator();
876
                            }
877
                    } catch (ReadDriverException e) {
878
                            this.setVisible(false);
879
                            this.setActive(false);
880
                            throw e;
881
                    }
882
            }
883
    }
884

    
885

    
886
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
887
            double scale, PrintRequestAttributeSet properties) throws ReadDriverException {
888
//            if (forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD) {
889
                    _print(g, viewPort, cancel, scale, properties);
890
//            } else {
891
////                    moved up to Flayers
892
////                    if (isVisible() && isWithinScale(scale)) {
893
//                            Strategy strategy = StrategyManager.getStrategy(this);
894
//
895
//                            strategy.print(g, viewPort, cancel, properties);
896
//                            ILabelingStrategy labeling;
897
//                            if ( (labeling = getLabelingStrategy() ) != null) {
898
//                                    // contains labels
899
//                                    labeling.print(g, viewPort, cancel, properties);
900
//                            }
901
////                    }
902
//            }
903
    }
904

    
905
    public void deleteSpatialIndex() {
906
        //must we delete possible spatial indexes files?
907
        spatialIndex = null;
908
    }
909

    
910
   /**
911
    * <p>
912
    * Creates an spatial index associated to this layer.
913
    * The spatial index will used
914
    * the native projection of the layer, so if the layer is reprojected, it will
915
    * be ignored.
916
    * </p>
917
    * @param cancelMonitor instance of CancellableMonitorable that allows
918
    * to monitor progress of spatial index creation, and cancel the process
919
    */
920
    public void createSpatialIndex(CancellableMonitorable cancelMonitor){
921
         // FJP: ESTO HABR? QUE CAMBIARLO. PARA LAS CAPAS SECUENCIALES, TENDREMOS
922
        // QUE ACCEDER CON UN WHILE NEXT. (O mejorar lo de los FeatureVisitor
923
        // para que acepten recorrer sin geometria, solo con rectangulos.
924

    
925
        //If this vectorial layer is based in a spatial database, the spatial
926
        //index is already implicit. We only will index file drivers
927
        ReadableVectorial va = getSource();
928
        //We must think in non spatial databases, like HSQLDB
929
        if(!(va instanceof VectorialFileAdapter)){
930
            return;
931
        }
932
        if (!(va.getDriver() instanceof BoundedShapes)) {
933
            return;
934
        }
935
        File file = ((VectorialFileAdapter) va).getFile();
936
        String fileName = file.getAbsolutePath();
937
        ISpatialIndex localCopy = null;
938
        try {
939
            va.start();
940
            localCopy = new QuadtreeGt2(fileName, "NM", va.getFullExtent(),
941
                    va.getShapeCount(), true);
942

    
943
        } catch (SpatialIndexException e1) {
944
            // Probably we dont have writing permissions
945
            String directoryName = System.getProperty("java.io.tmpdir");
946
            File newFile = new File(directoryName +
947
                    File.separator +
948
                    file.getName());
949
            String newFileName = newFile.getName();
950
            try {
951
                localCopy = new QuadtreeGt2(newFileName, "NM", va.getFullExtent(),
952
                        va.getShapeCount(), true);
953
            } catch (SpatialIndexException e) {
954
                // if we cant build a file based spatial index, we'll build
955
                // a pure memory spatial index
956
                localCopy = new QuadtreeJts();
957
            } catch (ReadDriverException e) {
958
                localCopy = new QuadtreeJts();
959
            }
960

    
961
        } catch(Exception e){
962
            e.printStackTrace();
963
        }//try
964
        BoundedShapes shapeBounds = (BoundedShapes) va.getDriver();
965
        try {
966
            for (int i=0; i < va.getShapeCount(); i++)
967
            {
968
                if(cancelMonitor != null){
969
                    if(cancelMonitor.isCanceled())
970
                        return;
971
                    cancelMonitor.reportStep();
972
                }
973
                Rectangle2D r = shapeBounds.getShapeBounds(i);
974
                if(r != null)
975
                    localCopy.insert(r, i);
976
            } // for
977
            va.stop();
978
            if(localCopy instanceof IPersistentSpatialIndex)
979
                ((IPersistentSpatialIndex) localCopy).flush();
980
            spatialIndex = localCopy;
981
            //vectorial adapter needs a reference to the spatial index, to solve
982
            //request for feature iteration based in spatial queries
983
            source.setSpatialIndex(spatialIndex);
984
        } catch (ReadDriverException e) {
985
            // TODO Auto-generated catch block
986
            e.printStackTrace();
987
        }
988
    }
989

    
990
    public void createSpatialIndex() {
991
        createSpatialIndex(null);
992
    }
993

    
994
    public void process(FeatureVisitor visitor, FBitSet subset)
995
            throws ReadDriverException, ExpansionFileReadException, VisitorException {
996
        Strategy s = StrategyManager.getStrategy(this);
997
        s.process(visitor, subset);
998
    }
999

    
1000
    public void process(FeatureVisitor visitor) throws ReadDriverException, VisitorException {
1001
        Strategy s = StrategyManager.getStrategy(this);
1002
        s.process(visitor);
1003
    }
1004

    
1005
    public void process(FeatureVisitor visitor, Rectangle2D rect)
1006
            throws ReadDriverException, ExpansionFileReadException, VisitorException {
1007
        Strategy s = StrategyManager.getStrategy(this);
1008
        s.process(visitor, rect);
1009
    }
1010

    
1011
    public FBitSet queryByRect(Rectangle2D rect) throws ReadDriverException, VisitorException {
1012
        Strategy s = StrategyManager.getStrategy(this);
1013

    
1014
        return s.queryByRect(rect);
1015
    }
1016

    
1017
    public FBitSet queryByPoint(Point2D p, double tolerance)
1018
            throws ReadDriverException, VisitorException {
1019
        Strategy s = StrategyManager.getStrategy(this);
1020
        return s.queryByPoint(p, tolerance);
1021
    }
1022

    
1023
    public FBitSet queryByShape(IGeometry g, int relationship)
1024
            throws ReadDriverException, VisitorException {
1025
        Strategy s = StrategyManager.getStrategy(this);
1026
        return s.queryByShape(g, relationship);
1027
    }
1028

    
1029
    public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws ReadDriverException, VisitorException {
1030
        Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p);
1031
        FBitSet bs = queryByPoint(pReal, tolerance);
1032
        VectorialXMLItem[] item = new VectorialXMLItem[1];
1033
        item[0] = new VectorialXMLItem(bs, this);
1034

    
1035
        return item;
1036
    }
1037

    
1038
    public void setLegend(IVectorLegend r) throws LegendLayerException {
1039
            if (this.legend == r){
1040
                    return;
1041
            }
1042
                if (this.legend != null && this.legend.equals(r)){
1043
                        return;
1044
                }
1045
        IVectorLegend oldLegend = legend;
1046
        legend = r;
1047
        try {
1048
            legend.setDataSource(getRecordset());
1049
        } catch (FieldNotFoundException e1) {
1050
            throw new LegendLayerException(getName(),e1);
1051
        } catch (ReadDriverException e1) {
1052
            throw new LegendLayerException(getName(),e1);
1053
        } finally{
1054
                this.updateDrawVersion();
1055
        }
1056
        if (oldLegend != null){
1057
                oldLegend.removeLegendListener(this);
1058
        }
1059
        if (legend != null){
1060
                legend.addLegendListener(this);
1061
        }
1062
        LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
1063
                oldLegend, legend);
1064
        callLegendChanged(e);
1065
    }
1066

    
1067
    /**
1068
     * Devuelve la Leyenda de la capa.
1069
     *
1070
     * @return Leyenda.
1071
     */
1072
    public ILegend getLegend() {
1073
        return legend;
1074
    }
1075

    
1076
    /**
1077
     * Devuelve el tipo de shape que contiene la capa.
1078
     *
1079
     * @return tipo de shape.
1080
     *
1081
     * @throws DriverException
1082
     */
1083
    public int getShapeType() throws ReadDriverException {
1084
        if (typeShape == -1) {
1085
            getSource().start();
1086
            typeShape = getSource().getShapeType();
1087
            getSource().stop();
1088
        }
1089

    
1090
        return typeShape;
1091
    }
1092

    
1093
    public XMLEntity getXMLEntity() throws XMLException {
1094
        if (!this.isAvailable() && this.orgXMLEntity != null) {
1095
            return this.orgXMLEntity;
1096
        }
1097
        XMLEntity xml = super.getXMLEntity();
1098
        if (getLegend()!=null)
1099
            xml.addChild(getLegend().getXMLEntity());
1100
        try {
1101
            if (getRecordset()!=null)
1102
                xml.addChild(getRecordset().getSelectionSupport().getXMLEntity());
1103
        } catch (ReadDriverException e1) {
1104
            e1.printStackTrace();
1105
            throw new XMLException(e1);
1106
        }
1107
        // Repongo el mismo ReadableVectorial m?s abajo para cuando se guarda el proyecto.
1108
        ReadableVectorial rv=getSource();
1109
        xml.putProperty("type", "vectorial");
1110
        if (source instanceof VectorialEditableAdapter) {
1111
            setSource(((VectorialEditableAdapter) source).getOriginalAdapter());
1112
        }
1113
        if (source instanceof VectorialFileAdapter) {
1114
            xml.putProperty("type", "vectorial");
1115
            xml.putProperty("file", ((VectorialFileAdapter) source)
1116
                    .getFile());
1117
            try {
1118
                xml.putProperty("recordset-name", source.getRecordset()
1119
                        .getName());
1120
            } catch (ReadDriverException e) {
1121
                throw new XMLException(e);
1122
            } catch (RuntimeException e) {
1123
                e.printStackTrace();
1124
            }
1125
        } else if (source instanceof VectorialDBAdapter) {
1126
            xml.putProperty("type", "vectorial");
1127

    
1128
            IVectorialDatabaseDriver dbDriver = (IVectorialDatabaseDriver) source
1129
                    .getDriver();
1130

    
1131
            // Guardamos el nombre del driver para poder recuperarlo
1132
            // con el DriverManager de Fernando.
1133
            xml.putProperty("db", dbDriver.getName());
1134
            try {
1135
                xml.putProperty("recordset-name", source.getRecordset()
1136
                        .getName());
1137
            } catch (ReadDriverException e) {
1138
                throw new XMLException(e);
1139
            } catch (RuntimeException e) {
1140
                e.printStackTrace();
1141
            }
1142
            xml.addChild(dbDriver.getXMLEntity()); // Tercer child. Antes hemos
1143
                                                    // metido la leyenda y el
1144
                                                    // selection support
1145
        } else if (source instanceof VectorialAdapter) {
1146
            // Se supone que hemos hecho algo gen?rico.
1147
            xml.putProperty("type", "vectorial");
1148

    
1149
            VectorialDriver driver = source.getDriver();
1150

    
1151
            // Guardamos el nombre del driver para poder recuperarlo
1152
            // con el DriverManager de Fernando.
1153
            xml.putProperty("other", driver.getName());
1154
            // try {
1155
            try {
1156
                xml.putProperty("recordset-name", source.getRecordset()
1157
                        .getName());
1158
            } catch (ReadDriverException e) {
1159
                throw new XMLException(e);
1160
            } catch (RuntimeException e) {
1161
                e.printStackTrace();
1162
            }
1163
            if (driver instanceof IPersistence) {
1164
                // xml.putProperty("className", driver.getClass().getName());
1165
                    IPersistence persist = (IPersistence) driver;
1166
                xml.addChild(persist.getXMLEntity()); // Tercer child. Antes
1167
                                                        // hemos metido la
1168
                                                        // leyenda y el
1169
                                                        // selection support
1170
            }
1171
        }
1172
        if (rv!=null)
1173
            setSource(rv);
1174
        xml.putProperty("driverName", source.getDriver().getName());
1175
        if (bHasJoin)
1176
            xml.putProperty("hasJoin", "true");
1177

    
1178
        // properties from ILabelable
1179
        xml.putProperty("isLabeled", isLabeled);
1180
        if (strategy != null) {
1181
            XMLEntity strategyXML = strategy.getXMLEntity();
1182
            strategyXML.putProperty("Strategy", strategy.getClassName());
1183
            xml.addChild(strategy.getXMLEntity());
1184
        }
1185
        xml.addChild(getLinkProperties().getXMLEntity());
1186
        return xml;
1187
    }
1188

    
1189
    /**
1190
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
1191
     */
1192
    public void setXMLEntity03(XMLEntity xml) throws XMLException {
1193

    
1194
        super.setXMLEntity(xml);
1195
        legend = LegendFactory.createFromXML03(xml.getChild(0));
1196

    
1197
        try {
1198
            setLegend(legend);
1199
        } catch (LegendLayerException e) {
1200
            throw new XMLException(e);
1201
        }
1202

    
1203
        try {
1204
            getRecordset().getSelectionSupport()
1205
                    .setXMLEntity03(xml.getChild(1));
1206
        } catch (ReadDriverException e) {
1207
            e.printStackTrace();
1208
        }
1209
    }
1210

    
1211
    /*
1212
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
1213
     */
1214
    public void setXMLEntity(XMLEntity xml) throws XMLException {
1215
        try {
1216
                    super.setXMLEntity(xml);
1217
                    XMLEntity legendXML = xml.getChild(0);
1218
                    IVectorLegend leg = LegendFactory.createFromXML(legendXML);
1219
                    /* (jaume) begin patch;
1220
                     * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1221
                     * no longer managed by the Legend but by the ILabelingStrategy. The
1222
                     * following allows restoring older projects' labelings.
1223
                     */
1224
                    if (legendXML.contains("labelFieldName")) {
1225
                            String labelTextField = legendXML.getStringProperty("labelFieldName");
1226
                            if (labelTextField != null) {
1227
                                    AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
1228
                                    labeling.setLayer(this);
1229
                                    labeling.setTextField(legendXML.getStringProperty("labelFieldName"));
1230
                                    labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
1231
                                    labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
1232
                                    this.setLabelingStrategy(labeling);
1233
                                    this.setIsLabeled(true);
1234
                            }
1235
                    }
1236
                    /* end patch */
1237
                    try {
1238
                            getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
1239
                            // JMVIVO: Esto sirve para algo????
1240
                            /*
1241
                             *  Jaume: si, para restaurar el selectable datasource cuando se
1242
                             *  clona la capa, cuando se carga de un proyecto. Si no esta ya
1243
                             *  no se puede ni hacer consultas sql, ni hacer selecciones,
1244
                             *  ni usar la mayor parte de las herramientas.
1245
                             *
1246
                             *  Lo vuelvo a poner.
1247
                             */
1248

    
1249
                            String recordsetName = xml.getStringProperty("recordset-name");
1250

    
1251
//                            SelectableDataSource sds = new SelectableDataSource(LayerFactory
1252
//                                            .getDataSourceFactory().createRandomDataSource(
1253
//                                                            recordsetName, DataSourceFactory.AUTOMATIC_OPENING));
1254

    
1255
                            LayerFactory.getDataSourceFactory().changeDataSourceName(
1256
                                            getSource().getRecordset().getName(), recordsetName);
1257
                            SelectableDataSource sds = new SelectableDataSource(LayerFactory
1258
                                            .getDataSourceFactory().createRandomDataSource(
1259
                                                            recordsetName, DataSourceFactory.AUTOMATIC_OPENING));
1260

    
1261
                    } catch (NoSuchTableException e1) {
1262
                            this.setAvailable(false);
1263
                            throw new XMLException(e1);
1264
                    } catch (ReadDriverException e1) {
1265
                            this.setAvailable(false);
1266
                            throw new XMLException(e1);
1267
                    }
1268
                    // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
1269
                    // el final
1270
                    // de la lectura del proyecto
1271
                    if (xml.contains("hasJoin")) {
1272
                            setIsJoined(true);
1273
                            PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
1274
                    } else {
1275
                            try {
1276
                                    setLegend(leg);
1277
                            } catch (LegendLayerException e) {
1278
                                    throw new XMLException(e);
1279
                            }
1280
                    }
1281

    
1282
                    //Por compatibilidad con proyectos anteriores a la 1.0
1283
                    boolean containsIsLabeled = xml.contains("isLabeled");
1284
                    if (containsIsLabeled){
1285
                            isLabeled = xml.getBooleanProperty("isLabeled");
1286
                    }
1287
                    // set properties for ILabelable
1288
                    XMLEntity labelingXML = xml.firstChild("labelingStrategy", "labelingStrategy");
1289
                    if (labelingXML!= null) {
1290
                            if(!containsIsLabeled){
1291
                                    isLabeled = true;
1292
                            }
1293
                            try {
1294
                                    this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this);
1295
                            } catch (NotExistInXMLEntity neXMLEX) {
1296
                                    // no strategy was set, just continue;
1297
                                    logger.warn("Reached what should be unreachable code");
1298
                            }
1299
                    } else {
1300
                            if(!containsIsLabeled){
1301
                                    isLabeled = false;
1302
                            }
1303
                    }
1304

    
1305
                    XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
1306
                    if (xmlLinkProperties != null){
1307
                            getLinkProperties().setXMLEntity(xmlLinkProperties);
1308
                    }
1309

    
1310
            } catch (XMLException e) {
1311
                    this.setAvailable(false);
1312
                    this.orgXMLEntity = xml;
1313
            } catch (Exception e) {
1314
                    e.printStackTrace();
1315
                    this.setAvailable(false);
1316
                    this.orgXMLEntity = xml;
1317

    
1318
            }
1319

    
1320

    
1321
    }
1322

    
1323
    public void setXMLEntityNew(XMLEntity xml) throws XMLException {
1324
        try {
1325
            super.setXMLEntity(xml);
1326

    
1327
            XMLEntity legendXML = xml.getChild(0);
1328
            IVectorLegend leg = LegendFactory.createFromXML(legendXML);
1329
            /* (jaume) begin patch;
1330
             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1331
             * no longer managed by the Legend but by the ILabelingStrategy. The
1332
             * following allows restoring older projects' labelings.
1333
             */
1334
            if (legendXML.contains("labelFieldHeight")) {
1335
                AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
1336
                labeling.setLayer(this);
1337
                labeling.setTextField(legendXML.getStringProperty("labelFieldHeight"));
1338
                labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
1339
                this.setLabelingStrategy(labeling);
1340
                this.setIsLabeled(true);
1341
              }
1342
            /* end patch */
1343
            try {
1344
                getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
1345

    
1346
                this.setLoadSelection(xml.getChild(1));
1347
            } catch (ReadDriverException e1) {
1348
                this.setAvailable(false);
1349
                throw new XMLException(e1);
1350
            }
1351
            // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
1352
            // el final
1353
            // de la lectura del proyecto
1354
            if (xml.contains("hasJoin")) {
1355
                setIsJoined(true);
1356
                PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
1357
            } else {
1358
                this.setLoadLegend(leg);
1359
            }
1360

    
1361
        } catch (XMLException e) {
1362
            this.setAvailable(false);
1363
            this.orgXMLEntity = xml;
1364
        } catch (Exception e) {
1365
            this.setAvailable(false);
1366
            this.orgXMLEntity = xml;
1367
        }
1368

    
1369

    
1370
    }
1371

    
1372

    
1373
    /**
1374
     * Sobreimplementaci?n del m?todo toString para que las bases de datos
1375
     * identifiquen la capa.
1376
     *
1377
     * @return DOCUMENT ME!
1378
     */
1379
    public String toString() {
1380
        /*
1381
         * Se usa internamente para que la parte de datos identifique de forma
1382
         * un?voca las tablas
1383
         */
1384
        String ret = super.toString();
1385

    
1386
        return "layer" + ret.substring(ret.indexOf('@') + 1);
1387
    }
1388

    
1389
    public boolean isJoined() {
1390
        return bHasJoin;
1391
    }
1392

    
1393
    /**
1394
     * Returns if a layer is spatially indexed
1395
     *
1396
     * @return if this layer has the ability to proces spatial queries without
1397
     *         secuential scans.
1398
     */
1399
    public boolean isSpatiallyIndexed() {
1400
        ReadableVectorial source = getSource();
1401
        if (source instanceof ISpatialDB)
1402
            return true;
1403

    
1404
//FIXME azabala
1405
/*
1406
 * Esto es muy dudoso, y puede cambiar.
1407
 * Estoy diciendo que las que no son fichero o no son
1408
 * BoundedShapes estan indexadas. Esto es mentira, pero
1409
 * as? quien pregunte no querr? generar el indice.
1410
 * Esta por ver si interesa generar el indice para capas
1411
 * HSQLDB, WFS, etc.
1412
 */
1413
        if(!(source instanceof VectorialFileAdapter)){
1414
            return true;
1415
        }
1416
        if (!(source.getDriver() instanceof BoundedShapes)) {
1417
            return true;
1418
        }
1419

    
1420
        if (getISpatialIndex() != null)
1421
            return true;
1422
        return false;
1423
    }
1424

    
1425
    public void setIsJoined(boolean hasJoin) {
1426
        bHasJoin = hasJoin;
1427
    }
1428

    
1429
    /**
1430
     * @return Returns the spatialIndex.
1431
     */
1432
    public ISpatialIndex getISpatialIndex() {
1433
        return spatialIndex;
1434
    }
1435
    /**
1436
     * Sets the spatial index. This could be useful if, for some
1437
     * reasons, you want to work with a distinct spatial index
1438
     * (for example, a spatial index which could makes nearest
1439
     * neighbour querys)
1440
     * @param spatialIndex
1441
     */
1442
    public void setISpatialIndex(ISpatialIndex spatialIndex){
1443
        this.spatialIndex = spatialIndex;
1444
    }
1445

    
1446
    public SelectableDataSource getRecordset() throws ReadDriverException {
1447
        if (!this.isAvailable()) return null;
1448
        if (sds == null) {
1449

    
1450
                SelectableDataSource ds = source.getRecordset();
1451

    
1452
                if (ds == null) {
1453
                    return null;
1454
                }
1455

    
1456
                sds = ds;
1457
                sds.setSelectionSupport(selectionSupport);
1458
                selectionSupport.addSelectionListener(this);
1459

    
1460
        }
1461
        return sds;
1462
    }
1463

    
1464
    public void setEditing(boolean b) throws StartEditionLayerException {
1465
        super.setEditing(b);
1466
        try {
1467
            if (b) {
1468
                VectorialEditableAdapter vea = null;
1469
                // TODO: Qu? pasa si hay m?s tipos de adapters?
1470
                // FJP: Se podr?a pasar como argumento el
1471
                // VectorialEditableAdapter
1472
                // que se quiera usar para evitar meter c?digo aqu? de este
1473
                // estilo.
1474
                if (getSource() instanceof VectorialDBAdapter) {
1475
                    vea = new VectorialEditableDBAdapter();
1476
                } else if (this instanceof FLyrAnnotation) {
1477
                    vea = new AnnotationEditableAdapter(
1478
                            (FLyrAnnotation) this);
1479
                } else {
1480
                    vea = new VectorialEditableAdapter();
1481
                }
1482
                vea.addEditionListener(this);
1483
                vea.setOriginalVectorialAdapter(getSource());
1484
//                                azo: implementations of readablevectorial need
1485
                //references of projection and spatial index
1486
                vea.setProjection(getProjection());
1487
                vea.setSpatialIndex(spatialIndex);
1488

    
1489

    
1490
                // /vea.setSpatialIndex(getSpatialIndex());
1491
                // /vea.setFullExtent(getFullExtent());
1492
                vea.setCoordTrans(getCoordTrans());
1493
                vea.startEdition(EditionEvent.GRAPHIC);
1494
                setSource(vea);
1495
                getRecordset().setSelectionSupport(
1496
                        vea.getOriginalAdapter().getRecordset()
1497
                                .getSelectionSupport());
1498

    
1499
            } else {
1500
                VectorialEditableAdapter vea = (VectorialEditableAdapter) getSource();
1501
                vea.removeEditionListener(this);
1502
                setSource(vea.getOriginalAdapter());
1503
            }
1504
            // Si tenemos una leyenda, hay que pegarle el cambiazo a su
1505
            // recordset
1506
            setRecordset(getSource().getRecordset());
1507
            if (getLegend() instanceof IVectorLegend) {
1508
                IVectorLegend ley = (IVectorLegend) getLegend();
1509
                ley.setDataSource(getSource().getRecordset());
1510
                // Esto lo pongo para evitar que al dibujar sobre un
1511
                // dxf, dwg, o dgn no veamos nada. Es debido al checkbox
1512
                // de la leyenda de textos "dibujar solo textos".
1513
//jaume
1514
//                                if (!(getSource().getDriver() instanceof IndexedShpDriver)){
1515
//                                        FSymbol symbol=new FSymbol(getShapeType());
1516
//                                        symbol.setFontSizeInPixels(false);
1517
//                                        symbol.setFont(new Font("SansSerif", Font.PLAIN, 9));
1518
//                                        Color color=symbol.getColor();
1519
//                                        int alpha=symbol.getColor().getAlpha();
1520
//                                        if (alpha>250) {
1521
//                                                symbol.setColor(new Color(color.getRed(),color.getGreen(),color.getBlue(),100));
1522
//                                        }
1523
//                                        ley.setDefaultSymbol(symbol);
1524
//                                }
1525
//jaume//
1526
                ley.useDefaultSymbol(true);
1527
            }
1528
        } catch (ReadDriverException e) {
1529
            throw new StartEditionLayerException(getName(),e);
1530
        } catch (FieldNotFoundException e) {
1531
            throw new StartEditionLayerException(getName(),e);
1532
        } catch (StartWriterVisitorException e) {
1533
            throw new StartEditionLayerException(getName(),e);
1534
        }
1535

    
1536
        setSpatialCacheEnabled(b);
1537
        callEditionChanged(LayerEvent
1538
                .createEditionChangedEvent(this, "edition"));
1539

    
1540
    }
1541

    
1542
    /**
1543
     * Para cuando haces una uni?n, sustituyes el recorset por el nuevo. De esta
1544
     * forma, podr?s poner leyendas basadas en el nuevo recordset
1545
     *
1546
     * @param newSds
1547
     */
1548
    public void setRecordset(SelectableDataSource newSds) {
1549
            // TODO: Deberiamos hacer comprobaciones del cambio
1550
        sds = newSds;
1551
        sds.setSelectionSupport(selectionSupport);
1552
                selectionSupport.addSelectionListener(this);
1553
                this.updateDrawVersion();
1554
    }
1555

    
1556
    public void clearSpatialCache()
1557
    {
1558
        spatialCache.clearAll();
1559
    }
1560

    
1561
    public boolean isSpatialCacheEnabled() {
1562
        return spatialCacheEnabled;
1563
    }
1564

    
1565
    public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
1566
        this.spatialCacheEnabled = spatialCacheEnabled;
1567
    }
1568

    
1569
    public SpatialCache getSpatialCache() {
1570
        return spatialCache;
1571
    }
1572

    
1573
    /**
1574
     * Siempre es un numero mayor de 1000
1575
     * @param maxFeatures
1576
     */
1577
    public void setMaxFeaturesInEditionCache(int maxFeatures) {
1578
        if (maxFeatures > spatialCache.maxFeatures)
1579
            spatialCache.setMaxFeatures(maxFeatures);
1580

    
1581
    }
1582

    
1583
    /**
1584
     * This method returns a boolean that is used by the FPopMenu
1585
     * to make visible the properties menu or not. It is visible by
1586
     * default, and if a later don't have to show this menu only
1587
     * has to override this method.
1588
     * @return
1589
     * If the properties menu is visible (or not)
1590
     */
1591
    public boolean isPropertiesMenuVisible(){
1592
        return true;
1593
    }
1594

    
1595
    public void reload() throws ReloadLayerException {
1596
        this.setAvailable(true);
1597
        super.reload();
1598
        this.updateDrawVersion();
1599
        try {
1600
            this.source.getDriver().reload();
1601
            if (this.getLegend() == null) {
1602
                if (this.getRecordset().getDriver() instanceof WithDefaultLegend) {
1603
                    WithDefaultLegend aux = (WithDefaultLegend) this.getRecordset().getDriver();
1604
                    this.setLegend((IVectorLegend) aux.getDefaultLegend());
1605
                    this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
1606
                } else {
1607
                    this.setLegend(LegendFactory.createSingleSymbolLegend(
1608
                            this.getShapeType()));
1609
                }
1610
            }
1611

    
1612
        } catch (LegendLayerException e) {
1613
            this.setAvailable(false);
1614
            throw new ReloadLayerException(getName(),e);
1615
        } catch (ReadDriverException e) {
1616
            this.setAvailable(false);
1617
            throw new ReloadLayerException(getName(),e);
1618
        }
1619

    
1620
    }
1621

    
1622
    protected void setLoadSelection(XMLEntity xml) {
1623
        this.loadSelection = xml;
1624
    }
1625

    
1626
    protected void setLoadLegend(IVectorLegend legend) {
1627
        this.loadLegend = legend;
1628
    }
1629

    
1630
    protected void putLoadSelection() throws XMLException {
1631
        if (this.loadSelection == null) return;
1632
        try {
1633
            this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
1634
        } catch (ReadDriverException e) {
1635
            throw new XMLException(e);
1636
        }
1637
        this.loadSelection = null;
1638

    
1639
    }
1640
    protected void putLoadLegend() throws LegendLayerException {
1641
        if (this.loadLegend == null) return;
1642
        this.setLegend(this.loadLegend);
1643
        this.loadLegend = null;
1644
    }
1645

    
1646
    protected void cleanLoadOptions() {
1647
        this.loadLegend = null;
1648
        this.loadSelection = null;
1649
    }
1650

    
1651
    public boolean isWritable() {
1652
        VectorialDriver drv = getSource().getDriver();
1653
        if (!drv.isWritable())
1654
            return false;
1655
        if (drv instanceof IWriteable)
1656
        {
1657
            IWriter writer = ((IWriteable)drv).getWriter();
1658
            if (writer != null)
1659
            {
1660
                if (writer instanceof ISpatialWriter)
1661
                    return true;
1662
            }
1663
        }
1664
        return false;
1665

    
1666
    }
1667

    
1668
    public FLayer cloneLayer() throws Exception {
1669
        FLyrVect clonedLayer = new FLyrVect();
1670
        clonedLayer.setSource(getSource());
1671
        if (isJoined()) {
1672
                        clonedLayer.setIsJoined(true);
1673
                        clonedLayer.setRecordset(getRecordset());
1674
                }
1675
        clonedLayer.setVisible(isVisible());
1676
        clonedLayer.setISpatialIndex(getISpatialIndex());
1677
        clonedLayer.setName(getName());
1678
        clonedLayer.setCoordTrans(getCoordTrans());
1679

    
1680
        clonedLayer.setLegend((IVectorLegend)getLegend().cloneLegend());
1681

    
1682
        clonedLayer.setIsLabeled(isLabeled());
1683
        clonedLayer.setLabelingStrategy(getLabelingStrategy());
1684

    
1685
        return clonedLayer;
1686
    }
1687

    
1688

    
1689
    private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, double dpi, CartographicSupport csSym, IGeometry geom, int[] xyCoords) {
1690
            return isOnePoint(graphicsTransform, viewPort, geom, xyCoords) && csSym.getCartographicSize(viewPort, dpi, (FShape)geom.getInternalShape()) <= 1;
1691
    }
1692

    
1693
    private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, IGeometry geom, int[] xyCoords) {
1694
            boolean onePoint = false;
1695
            int type=geom.getGeometryType() % FShape.Z;
1696
            if (type!=FShape.POINT && type!=FShape.MULTIPOINT && type!=FShape.NULL) {
1697

    
1698
                        Rectangle2D geomBounds = geom.getBounds2D();
1699

    
1700
                        ICoordTrans ct = getCoordTrans();
1701

    
1702
                        // Se supone que la geometria ya esta
1703
                        // repoyectada y no hay que hacer
1704
                        // ninguna transformacion
1705
//                        if (ct!=null) {
1706
////                                geomBounds = ct.getInverted().convert(geomBounds);
1707
//                                geomBounds = ct.convert(geomBounds);
1708
//                        }
1709

    
1710
                        double dist1Pixel = viewPort.getDist1pixel();
1711

    
1712
                        onePoint = (geomBounds.getWidth()  <= dist1Pixel
1713
                                         && geomBounds.getHeight() <= dist1Pixel);
1714

    
1715
                        if (onePoint) {
1716
                                // avoid out of range exceptions
1717
                                FPoint2D p = new FPoint2D(geomBounds.getMinX(), geomBounds.getMinY());
1718
                                p.transform(viewPort.getAffineTransform());
1719
                                p.transform(graphicsTransform);
1720
                                xyCoords[0] = (int) p.getX();
1721
                                xyCoords[1] = (int) p.getY();
1722

    
1723
                        }
1724

    
1725
                }
1726
            return onePoint;
1727
    }
1728
    /*
1729
     * jaume. Stuff from ILabeled.
1730
     */
1731
    private boolean isLabeled;
1732
    private ILabelingStrategy strategy;
1733

    
1734
    public boolean isLabeled() {
1735
        return isLabeled;
1736
    }
1737

    
1738
    public void setIsLabeled(boolean isLabeled) {
1739
        this.isLabeled = isLabeled;
1740
    }
1741

    
1742
    public ILabelingStrategy getLabelingStrategy() {
1743
        return strategy;
1744
    }
1745

    
1746
    public void setLabelingStrategy(ILabelingStrategy strategy) {
1747
        this.strategy = strategy;
1748
        try {
1749
                        strategy.setLayer(this);
1750
                } catch (ReadDriverException e) {
1751
                        // TODO Auto-generated catch block
1752
                        e.printStackTrace();
1753
                }
1754
    }
1755

    
1756
    public void drawLabels(BufferedImage image, Graphics2D g, ViewPort viewPort,
1757
                    Cancellable cancel, double scale, double dpi) throws ReadDriverException {
1758
        if (strategy!=null && isWithinScale(scale)) {
1759
                strategy.draw(image, g, viewPort, cancel, dpi);
1760
        }
1761
    }
1762
    public void printLabels(Graphics2D g, ViewPort viewPort,
1763
                    Cancellable cancel, double scale, PrintRequestAttributeSet properties) throws ReadDriverException {
1764
        if (strategy!=null) {
1765
                strategy.print(g, viewPort, cancel, properties);
1766
        }
1767
    }
1768

    
1769

    
1770
    //M?todos para el uso de HyperLinks en capas FLyerVect
1771

    
1772
    /**
1773
     * Return true, because a Vectorial Layer supports HyperLink
1774
     */
1775
    public boolean allowLinks()
1776
    {
1777
            return true;
1778
    }
1779

    
1780
    /**
1781
         * Returns an instance of AbstractLinkProperties that contains the information
1782
         * of the HyperLink
1783
         * @return Abstra
1784
         */
1785
    public AbstractLinkProperties getLinkProperties()
1786
    {
1787
            return linkProperties;
1788
    }
1789

    
1790
    /**
1791
         * Provides an array with URIs. Returns one URI by geometry that includes the point
1792
         * in its own geometry limits with a allowed tolerance.
1793
         * @param layer, the layer
1794
         * @param point, the point to check that is contained or not in the geometries in the layer
1795
         * @param tolerance, the tolerance allowed. Allowed margin of error to detect if the  point
1796
         *                 is contained in some geometries of the layer
1797
         * @return
1798
         */
1799
    public URI[] getLink(Point2D point, double tolerance)
1800
    {
1801
            //return linkProperties.getLink(this)
1802
            return linkProperties.getLink(this,point,tolerance);
1803
    }
1804
//    /**
1805
//     * @deprecated Don?t use Strategy, you should be use iterators.
1806
//     */
1807
//        public boolean isUseStrategy() {
1808
//                return useStrategy;
1809
//        }
1810
//        /**
1811
//     * @deprecated Don?t use Strategy, you should be use iterators.
1812
//     */
1813
//        public void setUseStrategy(boolean useStrategy) {
1814
//                this.useStrategy = useStrategy;
1815
//        }
1816
//
1817
//        @Override
1818
//        public void load() throws LoadLayerException {
1819
//                super.load();
1820
//                useStrategy=forTestOnlyVariableUseIterators_REMOVE_THIS_FIELD;
1821
//        }
1822

    
1823
        public void selectionChanged(SelectionEvent e) {
1824
                this.updateDrawVersion();
1825
        }
1826

    
1827
        public void afterFieldEditEvent(AfterFieldEditEvent e) {
1828
                this.updateDrawVersion();
1829
        }
1830

    
1831
        public void afterRowEditEvent(IRow feat, AfterRowEditEvent e) {
1832
                this.updateDrawVersion();
1833

    
1834
        }
1835

    
1836
        public void beforeFieldEditEvent(BeforeFieldEditEvent e) {
1837

    
1838
        }
1839

    
1840
        public void beforeRowEditEvent(IRow feat, BeforeRowEditEvent e) {
1841

    
1842
        }
1843

    
1844
        public void processEvent(EditionEvent e) {
1845
                if (e.getChangeType()== e.ROW_EDITION){
1846
                        this.updateDrawVersion();
1847
                }
1848

    
1849
        }
1850

    
1851
        public void legendCleared(LegendClearEvent event) {
1852
                this.updateDrawVersion();
1853
        LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
1854
                legend, legend);
1855
        this.callLegendChanged(e);
1856
        }
1857

    
1858
        public boolean symbolChanged(SymbolLegendEvent e) {
1859
                this.updateDrawVersion();
1860
        LegendChangedEvent event = LegendChangedEvent.createLegendChangedEvent(
1861
                legend, legend);
1862
        this.callLegendChanged(event);
1863
        return true;
1864
        }
1865
        public String getTypeStringVectorLayer() throws ReadDriverException {
1866
                String typeString="";
1867
                int typeShape=((FLyrVect)this).getShapeType();
1868
                if (FShape.MULTI==typeShape){
1869
                        ReadableVectorial rv=((FLyrVect)this).getSource();
1870
                        if (rv.getShapeCount()>0){
1871
                                if ((rv.getShape(0).getGeometryType() & FShape.Z) == FShape.Z){
1872
                                        typeString="Geometries3D";
1873
                                }else{
1874
                                        typeString="Geometries2D";
1875
                                 }
1876
                         }
1877
                }else{
1878
                        ReadableVectorial rv=((FLyrVect)this).getSource();
1879
                        if (rv.getShapeCount()>0){
1880
                                int type=rv.getShape(0).getGeometryType();
1881
                                if (FShape.POINT == type){
1882
                                        typeString="Point2D";
1883
                                } else if (FShape.LINE == type){
1884
                                        typeString="Line2D";
1885
                                } else if (FShape.POLYGON == type){
1886
                                        typeString="Polygon2D";
1887
                                } else if (FShape.MULTIPOINT == type){
1888
                                        typeString="MultiPint2D";
1889
                                } else if ((FShape.POINT | FShape.Z)  == type ){
1890
                                        typeString="Point3D";
1891
                                } else if ((FShape.LINE | FShape.Z)  == type ){
1892
                                        typeString="Line3D";
1893
                                } else if ((FShape.POLYGON | FShape.Z)  == type ){
1894
                                        typeString="Polygon3D";
1895
                                } else if ((FShape.MULTIPOINT | FShape.Z)  == type ){
1896
                                        typeString="MultiPoint3D";
1897
                                } else if ((FShape.POINT | FShape.M)  == type ){
1898
                                        typeString="PointM";
1899
                                } else if ((FShape.LINE | FShape.M)  == type ){
1900
                                        typeString="LineM";
1901
                                } else if ((FShape.POLYGON | FShape.M)  == type ){
1902
                                        typeString="PolygonM";
1903
                                } else if ((FShape.MULTIPOINT | FShape.M)  == type ){
1904
                                        typeString="MultiPointM";
1905
                                } else if ((FShape.MULTI | FShape.M)  == type ){
1906
                                        typeString="M";
1907
                                }
1908
                        }
1909
                        return typeString;
1910
                }
1911
                return "";
1912
        }
1913
        public int getTypeIntVectorLayer() throws ReadDriverException {
1914
                int typeInt=0;
1915
                int typeShape=((FLyrVect)this).getShapeType();
1916
                if (FShape.MULTI==typeShape){
1917
                        ReadableVectorial rv=((FLyrVect)this).getSource();
1918
                        if (rv.getShapeCount()>0){
1919
                                if ((rv.getShape(0).getGeometryType() & FShape.Z) == FShape.Z){
1920
                                        typeInt=FShape.MULTI | FShape.Z;
1921
                                }else{
1922
                                        typeInt=FShape.MULTI;
1923
                                }
1924
                        }
1925
                }else{
1926
                        ReadableVectorial rv=((FLyrVect)this).getSource();
1927
                        if (rv.getShapeCount()>0){
1928
                                int type=rv.getShape(0).getGeometryType();
1929
                                typeInt=type;
1930
                        }
1931
                        return typeInt;
1932
                }
1933
                return typeInt;
1934
        }
1935
 }