Statistics
| Revision:

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

History | View | Annotate | Download (55.1 KB)

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

    
43
import java.awt.Graphics2D;
44
import java.awt.Point;
45
import java.awt.geom.AffineTransform;
46
import java.awt.geom.Point2D;
47
import java.awt.image.BufferedImage;
48
import java.net.URI;
49
import java.util.Iterator;
50
import java.util.Set;
51
import java.util.TreeSet;
52

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

    
56
import org.cresques.cts.ICoordTrans;
57
import org.gvsig.fmap.dal.DALLocator;
58
import org.gvsig.fmap.dal.DataManager;
59
import org.gvsig.fmap.dal.DataStore;
60
import org.gvsig.fmap.dal.DataStoreParameters;
61
import org.gvsig.fmap.dal.exception.DataException;
62
import org.gvsig.fmap.dal.exception.ReadException;
63
import org.gvsig.fmap.dal.feature.Feature;
64
import org.gvsig.fmap.dal.feature.FeatureQuery;
65
import org.gvsig.fmap.dal.feature.FeatureSelection;
66
import org.gvsig.fmap.dal.feature.FeatureSet;
67
import org.gvsig.fmap.dal.feature.FeatureStore;
68
import org.gvsig.fmap.dal.feature.FeatureStoreNotification;
69
import org.gvsig.fmap.dal.feature.FeatureType;
70
import org.gvsig.fmap.geom.Geometry;
71
import org.gvsig.fmap.geom.GeometryManager;
72
import org.gvsig.fmap.geom.operation.DrawInts;
73
import org.gvsig.fmap.geom.operation.DrawOperationContext;
74
import org.gvsig.fmap.geom.operation.GeometryOperationException;
75
import org.gvsig.fmap.geom.operation.GeometryOperationNotSupportedException;
76
import org.gvsig.fmap.geom.primitive.DefaultEnvelope;
77
import org.gvsig.fmap.geom.primitive.Envelope;
78
import org.gvsig.fmap.mapcontext.MapContext;
79
import org.gvsig.fmap.mapcontext.ViewPort;
80
import org.gvsig.fmap.mapcontext.exceptions.LegendLayerException;
81
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
82
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
83
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
84
import org.gvsig.fmap.mapcontext.exceptions.XMLLayerException;
85
import org.gvsig.fmap.mapcontext.layers.AbstractLinkProperties;
86
import org.gvsig.fmap.mapcontext.layers.FLayer;
87
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
88
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
89
import org.gvsig.fmap.mapcontext.layers.SpatialCache;
90
import org.gvsig.fmap.mapcontext.layers.operations.ClassifiableVectorial;
91
import org.gvsig.fmap.mapcontext.layers.operations.ILabelable;
92
import org.gvsig.fmap.mapcontext.layers.operations.InfoByPoint;
93
import org.gvsig.fmap.mapcontext.layers.operations.SingleLayer;
94
import org.gvsig.fmap.mapcontext.layers.operations.VectorialXMLItem;
95
import org.gvsig.fmap.mapcontext.layers.operations.XMLItem;
96
import org.gvsig.fmap.mapcontext.rendering.legend.IClassifiedVectorLegend;
97
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
98
import org.gvsig.fmap.mapcontext.rendering.legend.IVectorLegend;
99
import org.gvsig.fmap.mapcontext.rendering.legend.LegendFactory;
100
import org.gvsig.fmap.mapcontext.rendering.legend.SingleSymbolLegend;
101
import org.gvsig.fmap.mapcontext.rendering.legend.SymbolLegendEvent;
102
import org.gvsig.fmap.mapcontext.rendering.legend.XMLLegendException;
103
import org.gvsig.fmap.mapcontext.rendering.legend.ZSort;
104
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
105
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendClearEvent;
106
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendContentsChangedListener;
107
import org.gvsig.fmap.mapcontext.rendering.legend.styling.AttrInTableLabelingStrategy;
108
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelingStrategy;
109
import org.gvsig.fmap.mapcontext.rendering.legend.styling.LabelingFactory;
110
import org.gvsig.fmap.mapcontext.rendering.symbols.CartographicSupport;
111
import org.gvsig.fmap.mapcontext.rendering.symbols.FSymbol;
112
import org.gvsig.fmap.mapcontext.rendering.symbols.IMultiLayerSymbol;
113
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
114
import org.gvsig.tools.ToolsLocator;
115
import org.gvsig.tools.dynobject.exception.DynMethodException;
116
import org.gvsig.tools.dynobject.exception.DynMethodNotSupportedException;
117
import org.gvsig.tools.exception.BaseException;
118
import org.gvsig.tools.exception.DriverException;
119
import org.gvsig.tools.observer.Observable;
120
import org.gvsig.tools.observer.Observer;
121
import org.gvsig.tools.persistence.PersistenceException;
122
import org.gvsig.tools.persistence.PersistentState;
123
import org.gvsig.tools.persistence.xmlentity.XMLEntityManager;
124
import org.gvsig.tools.persistence.xmlentity.XMLEntityState;
125
import org.gvsig.tools.task.Cancellable;
126
import org.opengis.feature.FeatureStoreEvent;
127
import org.slf4j.LoggerFactory;
128

    
129
import com.iver.utiles.NotExistInXMLEntity;
130
import com.iver.utiles.XMLEntity;
131
import com.iver.utiles.XMLException;
132

    
133
/**
134
 * Capa b?sica Vectorial.
135
 *
136
 * @author Fernando Gonz?lez Cort?s
137
 */
138

    
139
// TODO Cuando no sea para pruebas debe no ser public
140
public class FLyrVect extends FLyrDefault implements ILabelable, InfoByPoint,
141
                ClassifiableVectorial, SingleLayer, LegendContentsChangedListener,
142
                Observer {
143
        final static private org.slf4j.Logger logger = LoggerFactory.getLogger(FLyrVect.class);
144
    /** Leyenda de la capa vectorial */
145
    private IVectorLegend legend;
146
    private int typeShape = -1;
147
    private FeatureStore featureStore=null;
148
    private SpatialCache spatialCache = new SpatialCache();
149
    private boolean spatialCacheEnabled = false;
150

    
151
    /**
152
     * An implementation of gvSIG spatial index
153
     */
154
//    protected ISpatialIndex spatialIndex = null;
155
    private boolean bHasJoin = false;
156
    private XMLEntity orgXMLEntity = null;
157
    private XMLEntity loadSelection = null;
158
    private IVectorLegend loadLegend = null;
159

    
160
    //Lo a?ado. Caracter?sticas de HyperEnlace (LINK)
161
    private FLyrVectLinkProperties linkProperties=new FLyrVectLinkProperties();
162

    
163
    /**
164
     * Devuelve el VectorialAdapater de la capa.
165
     *
166
     * @return VectorialAdapter.
167
     */
168
    public DataStore getDataStore() {
169
        if (!this.isAvailable()) {
170
                        return null;
171
                }
172
        return featureStore;
173
    }
174

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

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

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

    
267
    /**
268
     * Inserta el VectorialAdapter a la capa.
269
     *
270
     * @param va
271
     *            VectorialAdapter.
272
     */
273
    public void setDataStore(DataStore dataStore) throws LoadLayerException {
274
        featureStore = (FeatureStore)dataStore;
275

    
276
        ILegend legend = null;
277
                try {
278
                        legend = (ILegend) dataStore.invokeDynMethod("defaultLegend", null);
279

    
280
                } catch (DynMethodNotSupportedException e1) {
281
                        try {
282
                                legend = LegendFactory.createSingleSymbolLegend(this
283
                                                .getShapeType());
284
                        } catch (ReadException e) {
285
                                throw new LoadLayerException(this.getName(), e);
286
                        }
287

    
288
                } catch (DynMethodException e1) {
289
                        throw new LoadLayerException(this.getName(), e1);
290
                }
291
                this.setLegend((IVectorLegend) legend);
292

    
293

    
294

    
295

    
296
                ILabelingStrategy labeler = null;
297
                try {
298
                        labeler = (ILabelingStrategy) dataStore.invokeDynMethod(
299
                                        "defaultLabelingStrategy", null);
300
                } catch (DynMethodNotSupportedException e1) {
301
                        labeler = null;
302
                } catch (DynMethodException e1) {
303
                        throw new LoadLayerException(this.getName(), e1);
304
                }
305

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

    
316

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

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

    
344
    }
345

    
346
    /**
347
     * Draws using IFeatureIterator. This method will replace the old draw(...) one.
348
     * @autor jaume dominguez faus - jaume.dominguez@iver.es
349
     * @param image
350
     * @param g
351
     * @param viewPort
352
     * @param cancel
353
     * @param scale
354
     * @throws ReadDriverException
355
     */
356
    public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
357
                    Cancellable cancel, double scale) throws ReadException {
358
            if (!this.isWithinScale(scale)) {
359
                        return;
360
                }
361
            if (cancel.isCanceled()) {
362
                        return;
363
                }
364
            boolean containsAll = false;
365
                Envelope viewPortEnvelope =viewPort.getAdjustedExtent();
366
                Envelope myEnvelope = this.getFullEnvelope();
367
                if (!viewPortEnvelope.contains(myEnvelope)){
368
                        if (!viewPortEnvelope.intersects(myEnvelope)){
369
                                return;
370
                        }
371
                } else {
372
                        containsAll = true;
373
                }
374
                double dpi = MapContext.getScreenDPI();
375
            DrawOperationContext doc=new DrawOperationContext();
376
            doc.setViewPort(viewPort);
377
            doc.setScale(scale);
378
                doc.setCancellable(cancel);
379
                doc.setDPI(dpi);
380
            boolean bDrawShapes = true;
381
            if (legend instanceof SingleSymbolLegend) {
382
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
383
            }
384
            Point2D offset = viewPort.getOffset();
385

    
386

    
387

    
388
            if (bDrawShapes) {
389
                    if (cancel.isCanceled()) {
390
                                return;
391
                        }
392
                    boolean cacheFeatures = isSpatialCacheEnabled();
393
                    SpatialCache cache = null;
394
                if (cacheFeatures) {
395
                        getSpatialCache().clearAll();
396
                        cache = getSpatialCache();
397
                }
398

    
399
                    try {
400

    
401
                            FeatureSelection selection = this.featureStore
402
                                                .getFeatureSelection();
403

    
404
                            FeatureStore featureStore=getFeatureStore();
405
                            String[] fieldNames=null;
406
                            if (legend instanceof IClassifiedVectorLegend){
407
                                    String[] classified=((IClassifiedVectorLegend)legend).getClassifyingFieldNames();
408
                                    fieldNames=new String[classified.length+1];
409
                                    fieldNames[0]=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
410
                                    for (int i = 1; i < fieldNames.length; i++) {
411
                                                fieldNames[i]=classified[i-1];
412
                                        }
413

    
414
                            }else{
415
                                    fieldNames=new String[]{featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName()};
416
                            }
417
                            FeatureSet featureSet=null;
418
                            FeatureQuery featureQuery=featureStore.createFeatureQuery();
419
                            featureQuery.setScale(scale);
420
                            featureQuery.setAttributeNames(fieldNames);
421
                            if (!containsAll) {
422
                                    InEnvelopeEvaluator iee = new InEnvelopeEvaluator(
423
                                                        viewPortEnvelope,
424
                                                    viewPort.getProjection(),
425
                                                    featureStore.getDefaultFeatureType(),
426
                                                    featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName());
427
                                    featureQuery.setFilter(iee);
428

    
429
                                }
430
                            featureSet = featureStore.getFeatureSet(featureQuery);
431
                            Iterator it = featureSet.fastIterator();
432

    
433
                            ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
434

    
435
                            boolean bSymbolLevelError = false;
436

    
437
                            // if layer has map levels it will use a ZSort
438
                            boolean useZSort = zSort != null && zSort.isUsingZSort();
439

    
440
                            // -- visual FX stuff
441
                            long time = System.currentTimeMillis();
442
                            BufferedImage virtualBim;
443
                            Graphics2D virtualGraphics;
444

    
445
                            if (cancel.isCanceled()) {
446
                                        return;
447
                                }
448

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

    
465
                            // Iteration over each feature
466
                            while (it.hasNext()) {
467
                                        if (cancel.isCanceled()) {
468
                                                return;
469
                                        }
470
                                    Feature feat = (Feature) it.next();
471

    
472
                                    Geometry geom = feat.getDefaultGeometry();
473

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

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

    
490
                                    // Check if this symbol is sized with CartographicSupport
491
                                    CartographicSupport csSym = null;
492
                                    int symbolType = sym.getSymbolType();
493
                                    boolean bDrawCartographicSupport = false;
494

    
495
                                    if (   symbolType == Geometry.TYPES.POINT
496
                                                    || symbolType == Geometry.TYPES.CURVE
497
                                                    || sym instanceof CartographicSupport) {
498

    
499
                                            // patch
500
                                        if (!sym.getClass().equals(FSymbol.class)) {
501
                                                csSym = (CartographicSupport) sym;
502
                                                bDrawCartographicSupport = (csSym.getUnit() != -1);
503
                                        }
504
                                    }
505

    
506
                                    int x = -1;
507
                                    int y = -1;
508
                                    int[] xyCoords = new int[2];
509

    
510
                                    // Check if size is a pixel
511
                                    boolean onePoint = bDrawCartographicSupport ?
512
                                                    isOnePoint(g.getTransform(), viewPort, MapContext.getScreenDPI(), csSym, geom, xyCoords) :
513
                                                    isOnePoint(g.getTransform(), viewPort, geom, xyCoords);
514

    
515
                                        // Avoid out of bounds exceptions
516
                                        if (onePoint) {
517
                                                x = xyCoords[0];
518
                                                y = xyCoords[1];
519
                                                if (x<0 || y<0 || x>= viewPort.getImageWidth() || y>=viewPort.getImageHeight()) {
520
                                                        continue;
521
                                                }
522
                                        }
523

    
524
                                        if (cancel.isCanceled()) {
525
                                                return;
526
                                        }
527

    
528
                                        if (useZSort) {
529
                                                // Check if this symbol is a multilayer
530
                                                if (sym instanceof IMultiLayerSymbol) {
531
                                                        // if so, treat each of its layers as a single symbol
532
                                                        // in its corresponding map level
533
                                                        IMultiLayerSymbol mlSym = (IMultiLayerSymbol) sym;
534
                                                        for (int i = 0; !cancel.isCanceled() && i < mlSym.getLayerCount(); i++) {
535
                                                                ISymbol mySym = mlSym.getLayer(i);
536
                                                                int symbolLevel = zSort.getSymbolLevel(mySym);
537

    
538
                                                                if (symbolLevel == -1) {
539
                                                                        /* an error occured when managing symbol levels
540
                                                                         * some of the legend changed events regarding the
541
                                                                         * symbols did not finish satisfactory and the legend
542
                                                                         * is now inconsistent. For this drawing, it will finish
543
                                                                         * as it was at the bottom (level 0) but, when done, the
544
                                                                         * ZSort will be reset to avoid app crashes. This is
545
                                                                         * a bug that has to be fixed.
546
                                                                         */
547
                                                                        bSymbolLevelError = true;
548
                                                                        symbolLevel=0;
549
                                                                }
550

    
551
                                                                if (onePoint) {
552
                                                                        if (x<0 || y<0 || x>= imageLevels[symbolLevel].getWidth() || y>=imageLevels[symbolLevel].getHeight()) {
553
                                                                                continue;
554
                                                                        }
555
                                                                        imageLevels[symbolLevel].setRGB(x, y, mySym.getOnePointRgb());
556
                                                                } else {
557
                                                                        if (!bDrawCartographicSupport) {
558
                                                                                doc.setGraphics(graphics[symbolLevel]);
559
                                                                                doc.setSymbol(mySym);
560
                                                                                geom.invokeOperation(DrawInts.CODE,doc);
561
                                                                        } else {
562
                                                                                doc.setGraphics(graphics[symbolLevel]);
563
                                                                                doc.setSymbol(mySym);
564
                                                                                geom.invokeOperation(DrawInts.CODE,doc);
565
                                                                        }
566
                                                                }
567
                                                        }
568
                                                } else {
569
                                                        // else, just draw the symbol in its level
570
                                                        if (!bDrawCartographicSupport) {
571
                                                                doc.setGraphics(graphics[zSort.getSymbolLevel(sym)]);
572
                                                                doc.setSymbol(sym);
573
                                                                geom.invokeOperation(DrawInts.CODE,doc);
574
                                                        } else {
575
                                                                doc.setGraphics(graphics[zSort.getSymbolLevel(sym)]);
576
                                                                doc.setSymbol((ISymbol)csSym);
577
                                                                geom.invokeOperation(DrawInts.CODE,doc);
578
                                                        }
579
                                                }
580

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

    
598
                                        } else {
599
                                                // no ZSort, so there is only a map level, symbols are
600
                                                // just drawn.
601
                                                if (onePoint) {
602
                                                        if (x<0 || y<0 || x>= image.getWidth() || y>=image.getHeight()) {
603
                                                                continue;
604
                                                        }
605
                                                        image.setRGB(x, y, sym.getOnePointRgb());
606
                                                } else {
607

    
608
                                                        if (!bDrawCartographicSupport) {
609
                                                                doc.setGraphics(g);
610
                                                                doc.setSymbol(sym);
611
                                                                geom.invokeOperation(DrawInts.CODE,doc);
612
                                                        } else {
613
                                                                doc.setGraphics(g);
614
                                                                doc.setSymbol((ISymbol)csSym);
615
                                                                geom.invokeOperation(DrawInts.CODE,doc);
616
                                                        }
617
                                                }
618
                                        }
619
                            }
620

    
621
                            if (useZSort) {
622
                                    g.drawImage(image, 0, 0, null);
623
                                        g.translate(offset.getX(), offset.getY());
624
                                    for (int i = 0; !cancel.isCanceled() && i < imageLevels.length; i++) {
625
                                            g.drawImage(imageLevels[i],0,0, null);
626
                                            imageLevels[i] = null;
627
                                            graphics[i] = null;
628
                                    }
629
                                        g.translate(-offset.getX(), -offset.getY());
630
                                    imageLevels = null;
631
                                    graphics = null;
632
                            }
633
//                            it.closeIterator();
634
                            it=null;
635
                            featureSet.dispose();
636

    
637
                            if (bSymbolLevelError) {
638
                                    ((IVectorLegend) getLegend()).setZSort(null);
639
                            }
640

    
641
                    } catch (ReadException e) {
642
                            this.setVisible(false);
643
                            this.setActive(false);
644
                            throw e;
645
                    } catch (GeometryOperationNotSupportedException e) {
646
                            this.setVisible(false);
647
                            this.setActive(false);
648
                            throw new ReadException(getName(),e);
649
                        } catch (GeometryOperationException e) {
650
                                this.setVisible(false);
651
                            this.setActive(false);
652
                            throw new ReadException(getName(),e);
653
                        } catch (BaseException e) {
654
                                this.setVisible(false);
655
                            this.setActive(false);
656
                            throw new ReadException(getName(),e);
657
                        }
658

    
659

    
660
            }
661
    }
662
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
663
                    double scale, PrintRequestAttributeSet properties) throws ReadException {
664
              // TEST METHOD
665
            boolean bDrawShapes = true;
666
            if (legend instanceof SingleSymbolLegend) {
667
                    bDrawShapes = legend.getDefaultSymbol().isShapeVisible();
668
            }
669
            if (bDrawShapes) {
670
                    try {
671
                            double dpi = 72;
672

    
673
                            PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
674
                            if (resolution.equals(PrintQuality.NORMAL)){
675
                                    dpi = 300;
676
                            } else if (resolution.equals(PrintQuality.HIGH)){
677
                                    dpi = 600;
678
                            } else if (resolution.equals(PrintQuality.DRAFT)){
679
                                    dpi = 72;
680
                            }
681
                            ZSort zSort = ((IVectorLegend) getLegend()).getZSort();
682

    
683
                            // if layer has map levels it will use a ZSort
684
                            boolean useZSort = zSort != null && zSort.isUsingZSort();
685

    
686

    
687
                            int mapLevelCount = (useZSort) ? zSort.getLevelCount() : 1;
688
                            for (int mapPass = 0; mapPass < mapLevelCount; mapPass++) {
689
                                    // Get the iterator over the visible features
690
                                FeatureStore featureStore=getFeatureStore();
691
                                // Get the iterator over the visible features
692
//                                String featureFilter = null;
693
//
694
//                                if (!viewPort.getAdjustedExtent().contains((Envelope)featureStore.getMetadata().get("extent"))) {
695
//                                            featureFilter=this.getDataStoreFilterForGeomerty(
696
//                                                    viewPort.getAdjustedExtent().getGeometry(),
697
//                                                    featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName(),
698
//                                                    null);
699
//                                    }
700
                                String[] fieldNames=null;
701
                                if (legend instanceof IClassifiedVectorLegend){
702
                                        String[] classified=((IClassifiedVectorLegend)legend).getClassifyingFieldNames();
703
                                        fieldNames=new String[classified.length+1];
704
                                        fieldNames[0]=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
705
                                        for (int i = 1; i < fieldNames.length; i++) {
706
                                                    fieldNames[i]=classified[i-1];
707
                                            }
708

    
709
                                }else{
710
                                        fieldNames=new String[]{featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName()};
711
                                }
712

    
713

    
714
                                FeatureSet featureCollection=null;
715
                                FeatureQuery featureQuery=featureStore.createFeatureQuery();
716
                                featureQuery.setAttributeNames(fieldNames);
717
                                featureQuery.setScale(scale);
718
//                                ??SQLJEPEvaluator evaluator=new SQLJEPEvaluator(featureFilter);
719
                                InEnvelopeEvaluator iee=new InEnvelopeEvaluator(viewPort.getAdjustedExtent(),viewPort.getProjection(),featureStore.getDefaultFeatureType(),featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName());
720
                                featureQuery.setFilter(iee);
721
                                featureCollection = featureStore.getFeatureSet(featureQuery);                               Iterator it = featureCollection.iterator();
722

    
723
                                    // Iteration over each feature
724
                                    while ( !cancel.isCanceled() && it.hasNext()) {
725
                                            Feature feat = (Feature)it.next();
726
                                            Geometry geom = feat.getDefaultGeometry();
727

    
728
                                            // retreive the symbol associated to such feature
729
                                            ISymbol sym = legend.getSymbolByFeature(feat);
730

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

    
746
                                                            if (sym == null) {
747
                                                                    continue;
748
                                                            }
749
                                                    } else {
750
                                                            // else, just draw the symbol in its level
751
                                                            if (zSort.getSymbolLevel(sym) != mapPass) {
752
                                                                    System.out.println("avoided single layer symbol '"+sym.getDescription()+"' (pass "+mapPass+")");
753
                                                                    continue;
754
                                                            }
755
                                                    }
756
                                            }
757

    
758
                                            // Check if this symbol is sized with CartographicSupport
759
                                            CartographicSupport csSym = null;
760
                                            int symbolType = sym.getSymbolType();
761
                                            boolean bDrawCartographicSupport = false;
762

    
763
                                            if (   symbolType == Geometry.TYPES.POINT
764
                                                            || symbolType == Geometry.TYPES.CURVE
765
                                                            || sym instanceof CartographicSupport) {
766

    
767
                                                    csSym = (CartographicSupport) sym;
768
                                                    bDrawCartographicSupport = (csSym.getUnit() != -1);
769
                                            }
770

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

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

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

    
893
//    public void createSpatialIndex() {
894
//        createSpatialIndex(null);
895
//    }
896

    
897

    
898
    public void setLegend(IVectorLegend r) throws LegendLayerException {
899
        IVectorLegend oldLegend = legend;
900
        legend = r;
901
        try {
902
            legend.setFeatureStore(getFeatureStore());
903
        } catch (ReadException e1) {
904
            throw new LegendLayerException(getName(),e1);
905
        } catch (DataException e) {
906
                 throw new LegendLayerException(getName(),e);
907
                }
908

    
909
        if (oldLegend != null) {
910
                        oldLegend.removeLegendListener(this);
911
                }
912
                if (legend != null) {
913
                        legend.addLegendListener(this);
914
                }
915

    
916
        LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
917
                oldLegend, legend);
918
        callLegendChanged(e);
919
    }
920

    
921
    /**
922
     * Devuelve la Leyenda de la capa.
923
     *
924
     * @return Leyenda.
925
     */
926
    public ILegend getLegend() {
927
        return legend;
928
    }
929

    
930
    /**
931
     * Devuelve el tipo de shape que contiene la capa.
932
     *
933
     * @return tipo de shape.
934
     *
935
     * @throws DriverException
936
     */
937
    public int getShapeType() throws ReadException {
938
        if (typeShape == -1) {
939
                FeatureType featureType;
940
                        try {
941
                                featureType = (((FeatureStore)getDataStore()).getDefaultFeatureType());
942
                        } catch (DataException e) {
943
                                throw new ReadException(getName(),e);
944
                        }
945
                int indexGeom=featureType.getDefaultGeometryAttributeIndex();
946
                typeShape=featureType.getAttributeDescriptor(indexGeom).getGeometryType();
947
        }
948
        return typeShape;
949
    }
950

    
951
    public XMLEntity getXMLEntity() throws XMLException {
952

    
953
        if (!this.isAvailable() && this.orgXMLEntity != null) {
954
            return this.orgXMLEntity;
955
        }
956
        XMLEntity xml = super.getXMLEntity();
957
        if (getLegend()!=null){
958
            XMLEntity xmlLegend=getLegend().getXMLEntity();
959
                xmlLegend.putProperty("tagName","legend");
960
            xml.addChild(xmlLegend);
961
        }
962
        try {
963
                        PersistentState stateFeatureStore=getFeatureStore().getState();
964
                        stateFeatureStore.set("tagName","featureStore");
965
                        xml.addChild(((XMLEntityState)stateFeatureStore).getXMLEntity());
966
                } catch (ReadException e) {
967
                        throw new XMLLayerException(getName(),e);
968
                } catch (PersistenceException e) {
969
                        throw new XMLLayerException(getName(),e);
970
                }
971
        // properties from ILabelable
972
        xml.putProperty("isLabeled", isLabeled);
973
        if (strategy != null) {
974
            XMLEntity strategyXML = strategy.getXMLEntity();
975
            strategyXML.putProperty("tagName", "labelingStrategy");
976
            xml.addChild(strategy.getXMLEntity());
977
        }
978
        xml.addChild(getLinkProperties().getXMLEntity());
979
        return xml;
980
    }
981
    /*
982
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setXMLEntity(com.iver.utiles.XMLEntity)
983
     */
984
    public void setXMLEntity(XMLEntity xml) throws XMLException {
985
        try {
986
            super.setXMLEntity(xml);
987
            XMLEntity legendXML = xml.firstChild("tagName","legend");
988
            IVectorLegend leg = LegendFactory.createFromXML(legendXML);
989
            /* (jaume) begin patch;
990
             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
991
             * no longer managed by the Legend but by the ILabelingStrategy. The
992
             * following allows restoring older projects' labelings.
993
             */
994
            if (legendXML.contains("labelFieldName")) {
995
                    String labelTextField = legendXML.getStringProperty("labelFieldName");
996
                    if (labelTextField != null) {
997
                            AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
998
                            labeling.setLayer(this);
999
                            labeling.setTextField(legendXML.getStringProperty("labelFieldName"));
1000
                            labeling.setHeightField(legendXML.getStringProperty("labelHeightFieldName"));
1001
                            labeling.setRotationField(legendXML.getStringProperty("labelRotationFieldName"));
1002
                            this.setLabelingStrategy(labeling);
1003
                            this.setIsLabeled(true);
1004
                    }
1005
            }
1006
//            PersistentState persistentState=new XMLEntityState(new XMLEntityManager());
1007
            XMLEntity xmlStore=xml.firstChild("tagName","featureStore");
1008
            XMLEntityManager xmlManger = new XMLEntityManager();
1009
            PersistentState state = xmlManger.createState(xmlStore);
1010
            DataStore store = (DataStore) ToolsLocator.getPersistenceManager().create(state);
1011
//            persistentState.createState(xmlStore);
1012

    
1013
//            DataManager dm=DALLocator.getDataManager();
1014

    
1015
            this.setDataStore(store);
1016
                            /* end patch */
1017
                            try {
1018
                                    setLegend(leg);
1019
                            } catch (LegendLayerException e) {
1020
                                    throw new XMLLegendException(e);
1021
                            }
1022
                    // set properties for ILabelable
1023

    
1024
                    if (xml.contains("isLabeled")
1025
                                        && xml.getBooleanProperty(("isLabeled"))) {
1026
                            XMLEntity labelingXML = xml.firstChild("tagName", "labelingStrategy");
1027
                            if (labelingXML != null){
1028

    
1029
                                    isLabeled = true;
1030
                                    try {
1031
                                            this.strategy = LabelingFactory.createStrategyFromXML(labelingXML, this);
1032
                                    } catch (NotExistInXMLEntity neXMLEX) {
1033
                                            // no strategy was set, just continue;
1034
                                            logger.warn("Reached what should be unreachable code");
1035
                                    }
1036
                            } else {
1037
                                        isLabeled = false;
1038
                            }
1039
                    } else {
1040
                            isLabeled = false;
1041
                    }
1042
                    XMLEntity xmlLinkProperties=xml.firstChild("typeChild","linkProperties");
1043
                    if (xmlLinkProperties != null){
1044
                            getLinkProperties().setXMLEntity(xmlLinkProperties);
1045
                    }
1046
            } catch (Exception e) {
1047
                    e.printStackTrace();
1048
                    this.setAvailable(false);
1049
                    this.orgXMLEntity = xml;
1050

    
1051
            }
1052
//
1053

    
1054
    }
1055

    
1056
    public void setXMLEntityNew(XMLEntity xml) throws XMLException {
1057
//        try {
1058
//            super.setXMLEntity(xml);
1059
//
1060
//            XMLEntity legendXML = xml.getChild(0);
1061
//            IVectorLegend leg = LegendFactory.createFromXML(legendXML);
1062
//            /* (jaume) begin patch;
1063
//             * for backward compatibility purposes. Since gvSIG v1.1 labeling is
1064
//             * no longer managed by the Legend but by the ILabelingStrategy. The
1065
//             * following allows restoring older projects' labelings.
1066
//             */
1067
//            if (legendXML.contains("labelFieldHeight")) {
1068
//                AttrInTableLabelingStrategy labeling = new AttrInTableLabelingStrategy();
1069
//                labeling.setLayer(this);
1070
//                labeling.setTextField(legendXML.getStringProperty("labelFieldHeight"));
1071
//                labeling.setRotationField(legendXML.getStringProperty("labelFieldRotation"));
1072
//                this.setLabelingStrategy(labeling);
1073
//                this.setIsLabeled(true);
1074
//              }
1075
//            /* end patch */
1076
//            try {
1077
//                getRecordset().getSelectionSupport().setXMLEntity(xml.getChild(1));
1078
//
1079
//                this.setLoadSelection(xml.getChild(1));
1080
//            } catch (ReadException e1) {
1081
//                this.setAvailable(false);
1082
//                throw new XMLException(e1);
1083
//            }
1084
//            // Si tiene una uni?n, lo marcamos para que no se cree la leyenda hasta
1085
//            // el final
1086
//            // de la lectura del proyecto
1087
//            if (xml.contains("hasJoin")) {
1088
//                setIsJoined(true);
1089
//                PostProcessSupport.addToPostProcess(this, "setLegend", leg, 1);
1090
//            } else {
1091
//                this.setLoadLegend(leg);
1092
//            }
1093
//
1094
//        } catch (XMLException e) {
1095
//            this.setAvailable(false);
1096
//            this.orgXMLEntity = xml;
1097
//        } catch (Exception e) {
1098
//            this.setAvailable(false);
1099
//            this.orgXMLEntity = xml;
1100
//        }
1101

    
1102

    
1103
    }
1104

    
1105

    
1106
    /**
1107
     * Sobreimplementaci?n del m?todo toString para que las bases de datos
1108
     * identifiquen la capa.
1109
     *
1110
     * @return DOCUMENT ME!
1111
     */
1112
    public String toString() {
1113
        /*
1114
         * Se usa internamente para que la parte de datos identifique de forma
1115
         * un?voca las tablas
1116
         */
1117
        String ret = super.toString();
1118

    
1119
        return "layer" + ret.substring(ret.indexOf('@') + 1);
1120
    }
1121

    
1122
    public boolean isJoined() {
1123
        return bHasJoin;
1124
    }
1125

    
1126
    /**
1127
     * Returns if a layer is spatially indexed
1128
     *
1129
     * @return if this layer has the ability to proces spatial queries without
1130
     *         secuential scans.
1131
     */
1132
//    public boolean isSpatiallyIndexed() {
1133
//        ReadableVectorial source = getSource();
1134
//        if (source instanceof ISpatialDB)
1135
//            return true;
1136
//
1137
////FIXME azabala
1138
///*
1139
// * Esto es muy dudoso, y puede cambiar.
1140
// * Estoy diciendo que las que no son fichero o no son
1141
// * BoundedShapes estan indexadas. Esto es mentira, pero
1142
// * as? quien pregunte no querr? generar el indice.
1143
// * Esta por ver si interesa generar el indice para capas
1144
// * HSQLDB, WFS, etc.
1145
// */
1146
//        if(!(source instanceof VectorialFileAdapter)){
1147
//            return true;
1148
//        }
1149
//        if (!(source.getDriver() instanceof BoundedShapes)) {
1150
//            return true;
1151
//        }
1152
//
1153
//        if (getISpatialIndex() != null)
1154
//            return true;
1155
//        return false;
1156
//    }
1157

    
1158
    public void setIsJoined(boolean hasJoin) {
1159
        bHasJoin = hasJoin;
1160
    }
1161

    
1162
//    /**
1163
//     * @return Returns the spatialIndex.
1164
//     */
1165
//    public ISpatialIndex getISpatialIndex() {
1166
//        return spatialIndex;
1167
//    }
1168
//    /**
1169
//     * Sets the spatial index. This could be useful if, for some
1170
//     * reasons, you want to work with a distinct spatial index
1171
//     * (for example, a spatial index which could makes nearest
1172
//     * neighbour querys)
1173
//     * @param spatialIndex
1174
//     */
1175
//    public void setISpatialIndex(ISpatialIndex spatialIndex){
1176
//        this.spatialIndex = spatialIndex;
1177
//    }
1178

    
1179
    public void setEditing(boolean b) throws StartEditionLayerException {
1180
        super.setEditing(b);
1181
        if (b){
1182
                try {
1183
                        getFeatureStore().edit();
1184
                } catch (ReadException e) {
1185
                        throw new StartEditionLayerException(getName(),e);
1186
                } catch (DataException e) {
1187
                        throw new StartEditionLayerException(getName(),e);
1188
                }
1189
        }
1190
        setSpatialCacheEnabled(b);
1191
        callEditionChanged(LayerEvent
1192
                .createEditionChangedEvent(this, "edition"));
1193

    
1194
    }
1195

    
1196
    public void clearSpatialCache()
1197
    {
1198
        spatialCache.clearAll();
1199
    }
1200

    
1201
    public boolean isSpatialCacheEnabled() {
1202
        return spatialCacheEnabled;
1203
    }
1204

    
1205
    public void setSpatialCacheEnabled(boolean spatialCacheEnabled) {
1206
        this.spatialCacheEnabled = spatialCacheEnabled;
1207
    }
1208

    
1209
    public SpatialCache getSpatialCache() {
1210
        return spatialCache;
1211
    }
1212

    
1213
    /**
1214
     * Siempre es un numero mayor de 1000
1215
     * @param maxFeatures
1216
     */
1217
    public void setMaxFeaturesInEditionCache(int maxFeatures) {
1218
        if (maxFeatures > spatialCache.getMaxFeatures()) {
1219
                        spatialCache.setMaxFeatures(maxFeatures);
1220
                }
1221

    
1222
    }
1223

    
1224
    /**
1225
     * This method returns a boolean that is used by the FPopMenu
1226
     * to make visible the properties menu or not. It is visible by
1227
     * default, and if a later don't have to show this menu only
1228
     * has to override this method.
1229
     * @return
1230
     * If the properties menu is visible (or not)
1231
     */
1232
    public boolean isPropertiesMenuVisible(){
1233
        return true;
1234
    }
1235

    
1236
    public void reload() throws ReloadLayerException {
1237
            super.reload();
1238
            try {
1239
                    DataManager dataManager=DALLocator.getDataManager();
1240
                    DataStoreParameters storeParameters;
1241

    
1242
                    storeParameters = getFeatureStore().getParameters();
1243

    
1244
                    DataStore dataStore=dataManager.createStore(storeParameters);
1245
                    setDataStore(dataStore);
1246
                    getFeatureStore().refresh();
1247
            } catch (ReadException e) {
1248
                    throw new ReloadLayerException(getName(),e);
1249
            }catch (LoadLayerException e) {
1250
                    throw new ReloadLayerException(getName(),e);
1251
            } catch (DataException e) {
1252
                    throw new ReloadLayerException(getName(),e);
1253
            }
1254
//        try {
1255
//            this.source.getDriver().reload();
1256
//            if (this.getLegend() == null) {
1257
//                if (this.getRecordset().getDriver() instanceof WithDefaultLegend) {
1258
//                    WithDefaultLegend aux = (WithDefaultLegend) this.getRecordset().getDriver();
1259
//                    this.setLegend((IVectorLegend) aux.getDefaultLegend());
1260
//                    this.setLabelingStrategy(aux.getDefaultLabelingStrategy());
1261
//                } else {
1262
//                    this.setLegend(LegendFactory.createSingleSymbolLegend(
1263
//                            this.getShapeType()));
1264
//                }
1265
//            }
1266
//
1267
//        } catch (LegendLayerException e) {
1268
//            this.setAvailable(false);
1269
//            throw new ReloadLayerException(getName(),e);
1270
//        } catch (ReadException e) {
1271
//            this.setAvailable(false);
1272
//            throw new ReloadLayerException(getName(),e);
1273
//        }
1274

    
1275

    
1276
    }
1277

    
1278
    protected void setLoadSelection(XMLEntity xml) {
1279
        this.loadSelection = xml;
1280
    }
1281

    
1282
    protected void setLoadLegend(IVectorLegend legend) {
1283
        this.loadLegend = legend;
1284
    }
1285

    
1286
    protected void putLoadSelection() throws XMLException {
1287
//        if (this.loadSelection == null) return;
1288
//        try {
1289
//            this.getRecordset().getSelectionSupport().setXMLEntity(this.loadSelection);
1290
//        } catch (ReadDriverException e) {
1291
//            throw new XMLException(e);
1292
//        }
1293
//        this.loadSelection = null;
1294

    
1295
    }
1296
    protected void putLoadLegend() throws LegendLayerException {
1297
        if (this.loadLegend == null) {
1298
                        return;
1299
                }
1300
        this.setLegend(this.loadLegend);
1301
        this.loadLegend = null;
1302
    }
1303

    
1304
    protected void cleanLoadOptions() {
1305
        this.loadLegend = null;
1306
        this.loadSelection = null;
1307
    }
1308

    
1309
    public boolean isWritable() {
1310
        try {
1311
                        return getFeatureStore().allowWrite();
1312
                } catch (ReadException e) {
1313
                        e.printStackTrace();
1314
                }
1315
                return false;
1316
    }
1317

    
1318
    public FLayer cloneLayer() throws Exception {
1319
        FLyrVect clonedLayer = new FLyrVect();
1320
        clonedLayer.setDataStore(getDataStore());
1321
        if (isJoined()) {
1322
                        clonedLayer.setIsJoined(true);
1323
                }
1324
        clonedLayer.setVisible(isVisible());
1325
//        clonedLayer.setISpatialIndex(getISpatialIndex());
1326
        clonedLayer.setName(getName());
1327
        clonedLayer.setCoordTrans(getCoordTrans());
1328

    
1329
        clonedLayer.setLegend((IVectorLegend)getLegend().cloneLegend());
1330

    
1331
        clonedLayer.setIsLabeled(isLabeled());
1332
        clonedLayer.setLabelingStrategy(getLabelingStrategy());
1333

    
1334
        return clonedLayer;
1335
    }
1336

    
1337

    
1338
    private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, double dpi, CartographicSupport csSym, Geometry geom, int[] xyCoords) {
1339
            return isOnePoint(graphicsTransform, viewPort, geom, xyCoords) && csSym.getCartographicSize(viewPort, dpi, geom) <= 1;
1340
    }
1341

    
1342
    private boolean isOnePoint(AffineTransform graphicsTransform, ViewPort viewPort, Geometry geom, int[] xyCoords) {
1343
            boolean onePoint = false;
1344
            int type=geom.getType() % Geometry.TYPES.Z;
1345
            if (type!=Geometry.TYPES.POINT && type!=Geometry.TYPES.MULTIPOINT) {
1346

    
1347
                        Envelope geomBounds = geom.getEnvelope();
1348

    
1349
                        ICoordTrans ct = getCoordTrans();
1350

    
1351
                        if (ct!=null) {
1352
//                                geomBounds = ct.getInverted().convert(geomBounds);
1353
                                geomBounds = geomBounds.convert(ct);
1354
                        }
1355

    
1356
                        double dist1Pixel = viewPort.getDist1pixel();
1357

    
1358
                        onePoint = (geomBounds.getLength(0)  <= dist1Pixel
1359
                                         && geomBounds.getLength(1) <= dist1Pixel);
1360

    
1361
                        if (onePoint) {
1362
                                // avoid out of range exceptions
1363
                                org.gvsig.fmap.geom.primitive.Point2D p = new org.gvsig.fmap.geom.primitive.Point2D(geomBounds.getMinimum(0), geomBounds.getMinimum(1));
1364
                                p.transform(viewPort.getAffineTransform());
1365
                                p.transform(graphicsTransform);
1366
                                xyCoords[0] = (int) p.getX();
1367
                                xyCoords[1] = (int) p.getY();
1368

    
1369
                        }
1370

    
1371
                }
1372
            return onePoint;
1373
    }
1374
    /*
1375
     * jaume. Stuff from ILabeled.
1376
     */
1377
    private boolean isLabeled;
1378
    protected ILabelingStrategy strategy;
1379

    
1380
    public boolean isLabeled() {
1381
        return isLabeled;
1382
    }
1383

    
1384
    public void setIsLabeled(boolean isLabeled) {
1385
        this.isLabeled = isLabeled;
1386
    }
1387

    
1388
    public ILabelingStrategy getLabelingStrategy() {
1389
        return strategy;
1390
    }
1391

    
1392
    public void setLabelingStrategy(ILabelingStrategy strategy) {
1393
        this.strategy = strategy;
1394
        try {
1395
                        strategy.setLayer(this);
1396
                } catch (ReadException e) {
1397
                        // TODO Auto-generated catch block
1398
                        e.printStackTrace();
1399
                }
1400

    
1401
    }
1402

    
1403
    public void drawLabels(BufferedImage image, Graphics2D g, ViewPort viewPort,
1404
                    Cancellable cancel, double scale, double dpi) throws ReadException {
1405
        if (strategy!=null && isWithinScale(scale)) {
1406
                strategy.draw(image, g, viewPort, cancel, dpi);
1407
        }
1408
    }
1409

    
1410
    //M?todos para el uso de HyperLinks en capas FLyerVect
1411

    
1412
    /**
1413
     * Return true, because a Vectorial Layer supports HyperLink
1414
     */
1415
    public boolean allowLinks()
1416
    {
1417
            return true;
1418
    }
1419

    
1420
    /**
1421
         * Returns an instance of AbstractLinkProperties that contains the information
1422
         * of the HyperLink
1423
         * @return Abstra
1424
         */
1425
    public AbstractLinkProperties getLinkProperties()
1426
    {
1427
            return linkProperties;
1428
    }
1429

    
1430
    /**
1431
         * Provides an array with URIs. Returns one URI by geometry that includes the point
1432
         * in its own geometry limits with a allowed tolerance.
1433
         * @param layer, the layer
1434
         * @param point, the point to check that is contained or not in the geometries in the layer
1435
         * @param tolerance, the tolerance allowed. Allowed margin of error to detect if the  point
1436
         *                 is contained in some geometries of the layer
1437
         * @return
1438
     * @throws ReadException
1439
     * @throws BehaviorException
1440
         */
1441
    public URI[] getLink(Point2D point, double tolerance) throws ReadException
1442
    {
1443
            //return linkProperties.getLink(this)
1444
            return linkProperties.getLink(this,point,tolerance);
1445
    }
1446

    
1447
        public void load() throws LoadLayerException {
1448
                super.load();
1449
        }
1450

    
1451
        public FeatureStore getFeatureStore() throws ReadException {
1452
                return (FeatureStore)getDataStore();
1453
        }
1454

    
1455
        public FeatureSet queryByPoint(Point2D mapPoint, double tol, FeatureType featureType) throws DataException {
1456
                Geometry geom = GeometryManager.getInstance().getGeometryFactory()
1457
                                .createCircle(mapPoint, tol);
1458

    
1459
                return queryByGeometry(geom, featureType);
1460
//                return queryByEnvelope(geom.getEnvelope(), featureType);
1461
        }
1462

    
1463

    
1464
        public FeatureSet queryByGeometry(Geometry geom, FeatureType featureType) throws DataException {
1465
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
1466
                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
1467
                featureQuery.setFeatureType(featureType);
1468
                IntersectsGeometryEvaluator iee=new IntersectsGeometryEvaluator(geom,getMapContext().getViewPort().getProjection(),featureStore.getDefaultFeatureType(),geomName);
1469
                featureQuery.setFilter(iee);
1470
                return getFeatureStore().getFeatureSet(featureQuery);
1471

    
1472
        }
1473

    
1474
        public FeatureSet queryByEnvelope(Envelope envelope, FeatureType featureType)
1475
                        throws DataException {
1476
                FeatureQuery featureQuery=featureStore.createFeatureQuery();
1477
                String geomName=featureStore.getDefaultFeatureType().getDefaultGeometryAttributeName();
1478
                featureQuery.setFeatureType(featureType);
1479
                InEnvelopeEvaluator iee=new InEnvelopeEvaluator(envelope,getMapContext().getViewPort().getProjection(),featureStore.getDefaultFeatureType(),geomName);
1480
                featureQuery.setFilter(iee);
1481
                return getFeatureStore().getFeatureSet(featureQuery);
1482

    
1483
        }
1484

    
1485
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws LoadLayerException, DataException {
1486
                Point2D pReal = this.getMapContext().getViewPort().toMapPoint(p);
1487
        FeatureSet featureCollection=null;
1488
                try {
1489
                        featureCollection = queryByPoint(pReal, tolerance, getFeatureStore().getDefaultFeatureType());
1490
                } catch (DataException e) {
1491
                        // TODO Auto-generated catch block
1492
                        e.printStackTrace();
1493
                }
1494
        VectorialXMLItem[] item = new VectorialXMLItem[1];
1495
        item[0] = new VectorialXMLItem(featureCollection, this);
1496

    
1497
        return item;
1498
        }
1499

    
1500
        public void legendCleared(LegendClearEvent event) {
1501
                // this.updateDrawVersion(); TODO
1502
                LegendChangedEvent e = LegendChangedEvent.createLegendChangedEvent(
1503
                                legend, legend);
1504
                this.callLegendChanged(e);
1505
        }
1506

    
1507
        public boolean symbolChanged(SymbolLegendEvent e) {
1508
                LegendChangedEvent ev = LegendChangedEvent.createLegendChangedEvent(
1509
                                legend, legend);
1510
                this.callLegendChanged(ev);
1511
                return true;
1512
        }
1513

    
1514
        public void update(Observable observable, Object notification) {
1515
                if (observable.equals(this.featureStore)) {
1516
                        if (notification instanceof FeatureStoreEvent) {
1517
                                FeatureStoreNotification event = (FeatureStoreNotification) notification;
1518
                                if (event.getType() == FeatureStoreNotification.SELECTION_CHANGE) {
1519
                                        //TODO!!!
1520

    
1521

    
1522
                                } else if (event.getType() == FeatureStoreNotification.AFTER_FINISHEDITING
1523
                                                || event.getType() == FeatureStoreNotification.TRANSFORM_CHANGE
1524
                                                || event.getType() == FeatureStoreNotification.RESOURCE_CHANGED) {
1525
                                        try {
1526
                                                reload();
1527
                                        } catch (ReloadLayerException e) {
1528
                                                this.setAvailable(false);
1529
                                        }
1530
                                }
1531

    
1532
                        }
1533

    
1534
                }
1535

    
1536
        }
1537

    
1538
        /*
1539
         * (non-Javadoc)
1540
         * 
1541
         * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1542
         */
1543
        public Set getMetadataChildren() {
1544
                Set ret = new TreeSet();
1545
                ret.add(this.featureStore);
1546
                return ret;
1547
        }
1548

    
1549
        /*
1550
         * (non-Javadoc)
1551
         * 
1552
         * @see org.gvsig.metadata.Metadata#getMetadataID()
1553
         */
1554
        public Object getMetadataID() {
1555
                return "Layer(" + this.getName() + "):"
1556
                                + this.featureStore.getMetadataID();
1557
        }
1558

    
1559
        /*
1560
         * (non-Javadoc)
1561
         * 
1562
         * @see org.gvsig.metadata.Metadata#getMetadataName()
1563
         */
1564
        public String getMetadataName() {
1565
                return "Layer '" + this.getName() + "':"
1566
                                + this.featureStore.getMetadataName();
1567
        }
1568

    
1569
 }