Statistics
| Revision:

svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / layers / FLayers.java @ 23066

History | View | Annotate | Download (53.2 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;
42

    
43
import java.awt.Graphics2D;
44
import java.awt.Point;
45
import java.awt.image.BufferedImage;
46
import java.awt.image.WritableRaster;
47
import java.util.ArrayList;
48
import java.util.Collections;
49
import java.util.Iterator;
50
import java.util.List;
51
import java.util.Vector;
52

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

    
57
import org.apache.log4j.Logger;
58
import org.cresques.cts.ICoordTrans;
59
import org.gvsig.exceptions.BaseException;
60
import org.gvsig.fmap.data.ReadException;
61
import org.gvsig.fmap.geom.primitive.Envelope;
62
import org.gvsig.fmap.mapcontext.MapContext;
63
import org.gvsig.fmap.mapcontext.Messages;
64
import org.gvsig.fmap.mapcontext.ViewPort;
65
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
66
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
67
import org.gvsig.fmap.mapcontext.layers.operations.ILabelable;
68
import org.gvsig.fmap.mapcontext.layers.operations.InfoByPoint;
69
import org.gvsig.fmap.mapcontext.layers.operations.LayerCollection;
70
import org.gvsig.fmap.mapcontext.layers.operations.LayersVisitor;
71
import org.gvsig.fmap.mapcontext.layers.operations.LayersVisitable;
72
import org.gvsig.fmap.mapcontext.layers.operations.XMLItem;
73
import org.gvsig.tools.visitor.NotSupportedOperationException;
74
import org.gvsig.tools.visitor.Visitor;
75

    
76
import com.iver.utiles.XMLEntity;
77
import com.iver.utiles.swing.threads.Cancellable;
78

    
79
/**
80
 * <p>Represents a generic collection of layers, that can be represented as a node in a tree of nodes of layers.</p>
81
 *
82
 * <p>Adapts the basic functionality implemented for a layer in the abstract class <code>FLyrDefault</code>, to
83
 *  a collection of layers, implementing, as well, specific methods for this kind of object, defined in the
84
 *  interfaces <code>VectorialData</code>, <code>LayerCollection</code>, and <code>InfoByPoint</code>.</p>
85
 *
86
 * @see FLyrDefault
87
 */
88
public class FLayers extends FLyrDefault implements LayerCollection,
89
                InfoByPoint {
90
        /**
91
         * List with all listeners registered for this kind of node.
92
         *
93
         * @see #addLayerCollectionListener(LayerCollectionListener)
94
         * @see #removeLayerCollectionListener(LayerCollectionListener)
95
         * @see #callLayerAdded(LayerCollectionEvent)
96
         * @see #callLayerAdding(LayerCollectionEvent)
97
         * @see #callLayerMoved(LayerPositionEvent)
98
         * @see #callLayerMoving(LayerPositionEvent)
99
         * @see #callLayerRemoved(LayerCollectionEvent)
100
         * @see #callLayerRemoving(LayerCollectionEvent)
101
         */
102
        protected ArrayList layerCollectionListeners = new ArrayList();
103

    
104
        /**
105
         * A synchronized list with the layers.
106
         *
107
         * @see #setAllVisibles(boolean)
108
         * @see #addLayer(FLayer)
109
         * @see #addLayer(int, FLayer)
110
         * @see #moveTo(int, int)
111
         * @see #removeLayer(FLayer)
112
         * @see #removeLayer(int)
113
         * @see #removeLayer(String)
114
         * @see #replaceLayer(String, FLayer)
115
         * @see #getVisibles()
116
         * @see #getLayer(int)
117
         * @see #getLayer(String)
118
         * @see #getLayersCount()
119
         * @see #getFullEnvelope()
120
         */
121
        protected List layers = Collections.synchronizedList(new ArrayList());
122

    
123
        /**
124
         * The model of the layer.
125
         *
126
         * @see #getMapContext()
127
         */
128
        protected MapContext fmap;
129

    
130
        /**
131
         * Useful for debug the problems during the implementation.
132
         */
133
        protected static Logger logger = Logger.getLogger(FLayers.class.getName());
134

    
135
//        /**
136
//         * Default <code>FLayers</code> constructor.
137
//         *
138
//         * @param fmap reference to the <code>MapContext</code> instance that contains this node of layers
139
//         * @param parent parent node of this one
140
//         */
141
//        public FLayers(MapContext fmap, FLayers parent) {
142
//                setParentLayer(parent);
143
//                this.fmap = fmap;
144
//        }
145

    
146
        /*
147
         * (non-Javadoc)
148
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#addLayerCollectionListener(com.iver.cit.gvsig.fmap.layers.LayerCollectionListener)
149
         */
150
        public void addLayerCollectionListener(LayerCollectionListener listener) {
151
                if (!layerCollectionListeners.contains(listener)) {
152
                        layerCollectionListeners.add(listener);
153
                }
154
        }
155

    
156
        /*
157
         * (non-Javadoc)
158
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#setAllVisibles(boolean)
159
         */
160
        public void setAllVisibles(boolean visible) {
161
                FLayer lyr;
162

    
163
                for (int i = 0; i < layers.size(); i++) {
164
                        lyr = ((FLayer) layers.get(i));
165
                        lyr.setVisible(visible);
166

    
167
                        if (lyr instanceof LayerCollection) {
168
                                ((LayerCollection) lyr).setAllVisibles(visible);
169
                        }
170
                }
171
        }
172

    
173
        /*
174
         * (non-Javadoc)
175
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#removeLayerCollectionListener(com.iver.cit.gvsig.fmap.layers.LayerCollectionListener)
176
         */
177
        public void removeLayerCollectionListener(LayerCollectionListener listener) {
178
                layerCollectionListeners.remove(listener);
179
        }
180

    
181
//        private void doAddLayer(FLayer layer) {
182
//        layers.add(layer);
183
//        layer.setParentLayer(this);
184
//        }
185

    
186
        /**
187
         * Adds a layer on an specified position in this node.
188
         *
189
         * @param pos position in the inner list where the layer will be added
190
         * @param layer a layer
191
         */
192
        private void doAddLayer(int pos,FLayer layer) {
193
                layers.add(pos,layer);
194
                layer.setParentLayer(this);
195
                if(layer.getProjection() != null && fmap != null) {
196
                        layer.setCoordTrans(layer.getProjection().getCT(fmap.getProjection()));
197
                }
198
        }
199

    
200
        /*
201
         * (non-Javadoc)
202
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#addLayer(com.iver.cit.gvsig.fmap.layers.FLayer)
203
         */
204
        public void addLayer(FLayer layer) {
205
                addLayer(layers.size(),layer);
206
        }
207

    
208
        /**
209
         * Adds a layer in an specified position in this node.
210
         *
211
         * @param layer a layer
212
         */
213
        public void addLayer(int pos,FLayer layer) {
214
                try {
215
                        //Notificamos a la capa que va a ser a?adida
216
                        //FLyrDefault layerDef = (FLyrDefault)layer;
217
                        //if (!layerDef.isUnavailable()) {
218
                        if (layer instanceof FLyrDefault) {
219
                                ((FLyrDefault)layer).wakeUp();
220
                        }
221

    
222
                        if (layer instanceof FLayers){
223
                                FLayers layers=(FLayers)layer;
224
                                fmap.addAsCollectionListener(layers);
225
                        }
226
                        callLayerAdding(LayerCollectionEvent.createLayerAddingEvent(layer));
227
                        //}
228

    
229
                        doAddLayer(pos,layer);
230

    
231
                        //if (!layerDef.isUnavailable()) {
232
                        callLayerAdded(LayerCollectionEvent.createLayerAddedEvent(layer));
233
                        //}
234
                } catch (CancelationException e) {
235
                        logger.warn(e);
236
                } catch (LoadLayerException e) {
237
                        layer.setAvailable(false);
238
                        layer.addError(e);
239
                }
240
        }
241

    
242
        /*
243
         * (non-Javadoc)
244
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#moveTo(int, int)
245
         */
246
        public void moveTo(int from, int to) throws CancelationException {
247
                int newfrom=layers.size()-from-1;
248
                int newto=layers.size()-to-1;
249
                if ( newfrom < 0 || newfrom >=layers.size() || newto < 0 || newto >= layers.size()) {
250
                        return;
251
                }
252
                FLayer aux = (FLayer) layers.get(newfrom);
253
                callLayerMoving(LayerPositionEvent.createLayerMovingEvent(aux, newfrom, newto));
254
                layers.remove(newfrom);
255
                layers.add(newto, aux);
256
                callLayerMoved(LayerPositionEvent.createLayerMovedEvent(aux, newfrom, newto));
257
        }
258

    
259
        /**
260
         * Removes an inner layer.
261
         *
262
         * @param lyr a layer
263
         */
264
        private void doRemoveLayer(FLayer lyr) {
265
                layers.remove(lyr);
266
        }
267

    
268
        /*
269
         * (non-Javadoc)
270
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#removeLayer(com.iver.cit.gvsig.fmap.layers.FLayer)
271
         */
272
        public void removeLayer(FLayer lyr) throws CancelationException {
273
                callLayerRemoving(LayerCollectionEvent.createLayerRemovingEvent(lyr));
274
                doRemoveLayer(lyr);
275
                callLayerRemoved(LayerCollectionEvent.createLayerRemovedEvent(lyr));
276
        }
277

    
278
        /*
279
         * (non-Javadoc)
280
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#removeLayer(int)
281
         */
282
        public void removeLayer(int idLayer) {
283
                FLayer lyr = (FLayer) layers.get(idLayer);
284
                callLayerRemoving(LayerCollectionEvent.createLayerRemovingEvent(lyr));
285
                layers.remove(idLayer);
286
                callLayerRemoved(LayerCollectionEvent.createLayerRemovedEvent(lyr));
287
        }
288

    
289
        /*
290
         * (non-Javadoc)
291
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#removeLayer(java.lang.String)
292
         */
293
        public void removeLayer(String layerName) {
294
                FLayer lyr;
295

    
296
                for (int i = 0; i < layers.size(); i++) {
297
                        lyr = ((FLayer) layers.get(i));
298

    
299
                        if (lyr.getName().compareToIgnoreCase(layerName) == 0) {
300
                                removeLayer(i);
301

    
302
                                break;
303
                        }
304
                }
305
        }
306

    
307
        /**
308
         * Replace a layer identified by its name, by another.
309
         *
310
         * @param layerName the name of the layer to be replaced
311
         * @param layer the new layer
312
         */
313
        public void replaceLayer(String layerName, FLayer layer) throws LoadLayerException
314
        {
315
                FLayer lyr;
316
                FLayer parent;
317
                for (int i = 0; i < layers.size(); i++) {
318
                        lyr = ((FLayer) layers.get(i));
319

    
320
                        if (lyr.getName().compareToIgnoreCase(layerName) == 0) {
321
                                parent = lyr.getParentLayer();
322
                                removeLayer(i);
323
                                if (parent != null) {
324
                                        //Notificamos a la capa que va a ser a?adida
325
                                        if (layer instanceof FLyrDefault) {
326
                                                ((FLyrDefault)layer).wakeUp();
327
                                        }
328
                                }
329

    
330
                                if (layer instanceof FLayers){
331
                                        FLayers layers=(FLayers)layer;
332
                                        fmap.addAsCollectionListener(layers);
333
                                }
334
                                callLayerAdding(LayerCollectionEvent.createLayerAddingEvent(layer));
335

    
336
                                layers.add(i,layer);
337
                                layer.setParentLayer(this);
338

    
339
                                callLayerAdded(LayerCollectionEvent.createLayerAddedEvent(layer));
340
                                break;
341
                        }
342
                }
343
        }
344

    
345
        /*
346
         * (non-Javadoc)
347
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#getVisibles()
348
         */
349
        public FLayer[] getVisibles() {
350
                ArrayList array = new ArrayList();
351
                LayersIterator iter = new LayersIterator(this) {
352
                        public boolean evaluate(FLayer layer) {
353
                                return layer.isVisible();
354
                        }
355

    
356
                };
357

    
358
                while (iter.hasNext()) {
359
                        array.add(iter.nextLayer());
360
                }
361

    
362
                return (FLayer[]) array.toArray(new FLayer[0]);
363
        }
364

    
365
        /*
366
         * (non-Javadoc)
367
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#getLayer(int)
368
         */
369
        public FLayer getLayer(int index) {
370
                return (FLayer) layers.get(index);
371
        }
372

    
373
        /*
374
         * (non-Javadoc)
375
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#getLayer(java.lang.String)
376
         */
377
        public FLayer getLayer(String layerName) {
378
                FLayer lyr;
379
                FLayer lyr2;
380
                ArrayList layerList;
381

    
382
                for (int i = 0; i < layers.size(); i++) {
383
                        lyr = ((FLayer) layers.get(i));
384

    
385
                        if (lyr.getName().compareToIgnoreCase(layerName) == 0) {
386
                                return lyr;
387
                        }
388

    
389
                        layerList = new ArrayList();
390
                        splitLayerGroup(lyr,layerList);
391
                        for(int j = 0; j<layerList.size(); j++ )
392
                        {
393
                                lyr2 = ((FLayer)layerList.get(j));
394
                                if (lyr2.getName().compareToIgnoreCase(layerName) == 0) {
395
                                        return lyr2;
396
                                }
397
                        }
398
                }
399

    
400
                return null;
401
        }
402

    
403
        /**
404
         * <p> Splits up a layer group in order to get a layer by name when there are layer groups</p>
405
         *
406
         * <p>In <code>result</code> always will be at least one layer.</p>
407
         *
408
         * @param layer the layer we are looking for
409
         * @param result an array list that will have the results of the search
410
         */
411
        private void splitLayerGroup(FLayer layer, ArrayList result)
412
        {
413
                int i;
414
                FLayers layerGroup;
415
                if (layer instanceof FLayers)
416
                {
417
                        layerGroup = (FLayers)layer;
418
                        for (i=0; i < layerGroup.getLayersCount(); i++ )
419
                        {
420
                                splitLayerGroup(layerGroup.getLayer(i),result);
421
                        }
422
                }
423
                else
424
                {
425
                        result.add(layer);
426
                }
427
        }
428

    
429
        /*
430
         * (non-Javadoc)
431
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#getLayersCount()
432
         */
433
        public int getLayersCount() {
434
                return layers.size();
435
        }
436

    
437
        /*
438
         * (non-Javadoc)
439
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#draw(java.awt.image.BufferedImage, java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort, com.iver.utiles.swing.threads.Cancellable, double)
440
         */
441
        public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
442
                        Cancellable cancel,double scale) throws ReadException {
443
                draw(image,g,viewPort,cancel, scale, null);
444
        }
445

    
446
        /**
447
         * <p>Checks all layers (each one as a sub-node of this node <i>collection of layers</i>) of this collection and draws which are visible, and dirty (in cache) or aren't in cache. If a node is
448
         *  a group of layers (<code>ComposedLayer</code>), executes it's drawn.</p>
449
         *
450
         * <p>All nodes which could group with the composed layer <code>group</code>, will be drawn together. And once the <code>
451
         * group</code> is drawn, will be set to <code>null</code>.</p>
452
         *
453
         * <p>The particular behavior depends on the kind of each layer and composed layer. And this process can be cancelled at any
454
         *  time by the shared object <code>cancel</code>.</p>
455
         *
456
         * @param image buffer used sometimes instead <code>g</code> to accelerate the draw. For example, if two points are as closed that can't be distinguished, draws only one.
457
         * @param g for rendering 2-dimensional shapes, text and images on the Java(tm) platform
458
         * @param viewPort the information for drawing the layers
459
         * @param cancel shared object that determines if this layer can continue being drawn
460
         * @param scale the scale of the view. Must be between {@linkplain FLayer#getMinScale()} and {@linkplain FLayer#getMaxScale()}.
461
         * @param group a composed layer pending to paint; if this parameter is <code>null</code>, the composed layer
462
         *  will also be drawn
463
         *
464
         * @return <code>null</code> if the layers in <code>group</code> had been drawn or were <code>null</code>; otherwise, the <code>group</code>
465
         *
466
         * @throws ReadDriverException if fails the driver reading the data.
467
         *
468
         * @see ComposedLayer#draw(BufferedImage, Graphics2D, ViewPort, Cancellable, double)
469
         */
470
        public ComposedLayer draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
471
                        Cancellable cancel,double scale, ComposedLayer group) throws ReadException {
472
                boolean bNeedRecalculateCache = false;
473
                double dpi = MapContext.getScreenDPI();
474
                ///// CHEMA ComposedLayer
475
                long tg1 = System.currentTimeMillis();
476
                ///// CHEMA ComposedLayer
477

    
478

    
479
                for (int i=0; i < layers.size(); i++) {
480
                        if (cancel.isCanceled()) {
481
                                break; // M?s que nada porque las capas raster no son interrumpibles por ahora.
482
                        }
483
                        FLayer lyr = (FLayer) layers.get(i);
484

    
485
                        if (!lyr.isVisible() || !lyr.isWithinScale(scale)) {
486
                                continue;
487
                        }
488

    
489
                        LayerDrawEvent beforeEvent = new LayerDrawEvent(lyr, g, viewPort, LayerDrawEvent.LAYER_BEFORE_DRAW);
490
                        fmap.fireLayerDrawingEvent(beforeEvent);
491
                        if ((lyr.isDirty()) || (lyr.isCachingDrawnLayers() == false)) {
492
                                bNeedRecalculateCache = true;
493
                        }
494

    
495
                        if (lyr.isVisible()) {
496

    
497
                                long t1 = System.currentTimeMillis();
498
                                // synchronized (this) {
499
                                //Sincronizaci?n del m?todo dibujar de cada Layer, esto es posible hacerlo de otra forma,
500
                                //pero de momento se queda as?, para solucionar el refresco de una misma vista que est? a?adida en el Layout.
501
                                try{
502
                                        /* if (lyr instanceof IComposedDrawing)
503
                                             {
504
                                             // Acumulamos las peticiones hasta que sea
505
                                              // otro servidor o otro tipo de capa o la ?ltima
506
                                               // Si hay que dibujar:
507
                                                lyr.draw(image, g, viewPort, cancel,scale);
508
                                                // Si hay que acumlar:
509
                                                 lyr.acumulateDrawing(antLayer);
510

511
                                                 }
512
                                                 else */
513

    
514
                                        if (lyr.isCachingDrawnLayers())
515
                                        {
516
                                                if ((bNeedRecalculateCache) || (lyr.getCacheImageDrawnLayers()==null))
517
                                                {
518
                                                        //if (bNeedRecalculateCache)
519
                                                        // {
520

    
521
                                                        ///// CHEMA ComposedLayer
522
                                                        if (group != null) {
523
                                                                //si tenemos un grupo pendiente de pintar, pintamos
524
                                                                // para que la cache sea fiable
525
                                                                group.draw(image, g, viewPort, cancel,scale);
526
                                                                group = null;
527
                                                        }
528
                                                        ///// CHEMA ComposedLayer
529

    
530

    
531

    
532

    
533

    
534
                                                        // Copiamos la imagen actual
535
                                                        BufferedImage buff = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
536
                                                        WritableRaster w = buff.getRaster();
537
                                                        image.copyData(w);
538
                                                        lyr.setCacheImageDrawnLayers(buff);
539
                                                }
540
//                                                }
541
//                                                else
542
//                                                {
543
                                                if (lyr.getCacheImageDrawnLayers() != null)
544
                                                {
545
                                                        // Previo a esto hemos tenido que fijar
546
                                                        // la imagen que queremos usar, en el
547
                                                        // prepareDrawing de FMap.
548
                                                        if (lyr.isDirty())
549
                                                        {
550

    
551

    
552
                                                                ///// CHEMA ComposedLayer
553
                                                                // Checks for draw group (ComposedLayer)
554
                                                                if (group != null) {
555
                                                                        // it's going to load a cache image,
556
                                                                        // the current draw isn't needed
557
                                                                        group = null;
558
                                                                }
559
                                                                ///// CHEMA ComposedLayer
560

    
561
                                                                g.drawImage(lyr.getCacheImageDrawnLayers(), 0, 0, null);
562
                                                        }
563
                                                }
564
//                                                }
565
                                        }
566
                                        // Si la capa est? "sucia" o alguna de las de abajo est? sucia
567
                                        // hay que volver a dibujar.
568
                                        if (lyr.isDirty() || bNeedRecalculateCache)
569
                                        {
570
                                                if (!lyr.getFLayerStatus().isDriverLoaded()){
571
                                                        continue;
572
                                        }
573
                                                ///// CHEMA ComposedLayer
574
                                                //lyr.draw(image, g, viewPort, cancel,scale);
575
                                                ///// CHEMA ComposedLayer
576

    
577
                                                // Checks for draw group (ComposedLayer)
578
                                                if (group != null) {
579
                                                        if (lyr instanceof FLayers){
580
                                                                group = ((FLayers)lyr).draw(image, g, viewPort, cancel,scale,group);
581
                                                                LayerDrawEvent afterEvent = new LayerDrawEvent(lyr, g, viewPort, LayerDrawEvent.LAYER_AFTER_DRAW);
582
                                                                fmap.fireLayerDrawingEvent(afterEvent);
583
                                                        } else {
584
                                                                //If layer can be added to the group, does it
585
                                                                if (group.canAdd(lyr)) {
586
                                                                        group.add(lyr);
587
                                                                } else {
588
                                                                        // draw the 'pending to draw' layer group
589
                                                                        group.draw(image, g, viewPort, cancel,scale);
590

    
591
                                                                        // gets a new group instance
592
                                                                        group = lyr.newComposedLayer();
593
                                                                        // if layer hasn't group, draws it inmediately
594
                                                                        if (group == null) {
595
                                                                                if (lyr instanceof FLayers){
596
                                                                                        group = ((FLayers)lyr).draw(image, g, viewPort, cancel,scale,group);
597
                                                                                } else {
598
                                                                                        lyr.draw(image, g, viewPort, cancel,scale);
599
                                                                                }
600
                                                                                LayerDrawEvent afterEvent = new LayerDrawEvent(lyr, g, viewPort, LayerDrawEvent.LAYER_AFTER_DRAW);
601
                                                                                fmap.fireLayerDrawingEvent(afterEvent);
602
                                                                        } else {
603
                                                                                // add the layer to the group
604
                                                                                group.setMapContext(fmap);
605
                                                                                group.add(lyr);
606

    
607
                                                                        }
608
                                                                }
609
                                                        }
610
                                                } else {
611
                                                        // gets a new group instance
612
                                                        group = lyr.newComposedLayer();
613
                                                        // if layer hasn't group, draws it inmediately
614
                                                        if (group == null) {
615
                                                                if (lyr instanceof FLayers){
616
                                                                        group = ((FLayers)lyr).draw(image, g, viewPort, cancel,scale,group);
617
                                                                } else {
618
                                                                        lyr.draw(image, g, viewPort, cancel,scale);
619
                                                                }
620
                                                                LayerDrawEvent afterEvent = new LayerDrawEvent(lyr, g, viewPort, LayerDrawEvent.LAYER_AFTER_DRAW);
621
                                                                fmap.fireLayerDrawingEvent(afterEvent);
622
                                                        } else {
623
                                                                // adds the layer to the group
624
                                                                group.setMapContext(fmap);
625
                                                                group.add(lyr);
626
                                                        }
627
                                                }
628
                                                ///// CHEMA ComposedLayer
629

    
630
                                                /*
631
                                                 * (Jaume)
632
                                                 * If the layer is instance of ILabelable then it may have labels.
633
                                                 */
634
                                                if (lyr instanceof ILabelable
635
                                                        && ((ILabelable) lyr).isLabeled()
636
                                                        && ((ILabelable) lyr).getLabelingStrategy() != null
637
                                                        && ((ILabelable) lyr).getLabelingStrategy().shouldDrawLabels(scale)) {
638

    
639
                                                        ///// CHEMA ComposedLayer
640
                                                        if (group != null) {
641
                                                                //si tenemos un grupo pendiente de pintar, pintamos
642
                                                                // para que se pinten correctamente las etiquetas
643
                                                                group.draw(image, g, viewPort, cancel,scale);
644
                                                                group = null;
645
                                                        }
646
                                                        ///// CHEMA ComposedLayer
647

    
648

    
649
                                                        ((ILabelable) lyr).drawLabels(image, g, viewPort, cancel, scale, dpi);
650
                                                }
651
                                                bNeedRecalculateCache = true;
652
                                        }
653
                                } catch (ReadException e){
654
                                        // fmap.callNewErrorEvent(new ErrorEvent(lyr.getName(), e));
655
                                        fmap.addLayerError("La capa " + lyr.getName() + " es err?nea.");
656
                                        lyr.addError(e);
657
                                        e.printStackTrace();
658
                                        lyr.setAvailable(false);
659
                                        // this.removeLayer(lyr);
660
                                } catch (Exception e) {
661
                                        fmap.addLayerError("La capa " + lyr.getName() + " es err?nea.");
662
                                        e.printStackTrace();
663
                                        lyr.setAvailable(false);
664
                                }
665
                                // }
666
                                long t2 = System.currentTimeMillis();
667
                                logger.info("Layer " + lyr.getName() + " "
668
                                                + (t2-t1) + " milisecs.");
669
                                lyr.setDirty(false);
670
                        }
671

    
672
                }
673
                ///// CHEMA ComposedLayer
674
                if (group != null && this.getParentLayer() == null) {
675
                        //si tenemos un grupo pendiente de pintar, pintamos
676
                        group.draw(image, g, viewPort, cancel,scale);
677
                        group = null;
678

    
679
                }
680
                ///// CHEMA ComposedLayer
681
                if (getVirtualLayers() != null) {
682
                        getVirtualLayers().draw(image, g, viewPort, cancel,scale);
683
                }
684

    
685
                long tg2 = System.currentTimeMillis();
686

    
687
                logger.debug("Draw all layer " +this.getName() + " " +
688
                                + (tg2-tg1) + " milisecs.");
689
                ///// CHEMA ComposedLayer
690
                return group;
691
                ///// CHEMA ComposedLayer
692
        }
693

    
694
        /*
695
         * (non-Javadoc)
696
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D, com.iver.cit.gvsig.fmap.ViewPort, com.iver.utiles.swing.threads.Cancellable, double, javax.print.attribute.PrintRequestAttributeSet)
697
         */
698
        public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintRequestAttributeSet properties)
699
        throws ReadException {
700
                this.print(g, viewPort, cancel, scale, properties, null);
701
        }
702

    
703
        /**
704
         * <p>Checks all layers (each one as a sub-node of this node <i>collection of layers</i>) of this collection and draws their requested properties. If a node is
705
         *  a group of layers (<code>ComposedLayer</code>), executes it's drawn.</p>
706
         *
707
         * <p>All nodes which could group with the composed layer <code>group</code>, will be drawn together. And once the <code>
708
         * group</code> is drawn, will be set to <code>null</code> if hasn't a parent layer.</p>
709
         *
710
         * <p>The particular implementation depends on the kind of each layer and composed layer. And this process can be cancelled at any
711
         *  time by the shared object <code>cancel</code>.</p>
712
         *
713
         * <p>According the print quality, labels will be printed in different resolution:
714
         *  <ul>
715
         *   <li><b>PrintQuality.DRAFT</b>: 72 dpi (dots per inch).</li>
716
         *   <li><b>PrintQuality.NORMAL</b>: 300 dpi (dots per inch).</li>
717
         *   <li><b>PrintQuality.HIGH</b>: 600 dpi (dots per inch).</li>
718
         *  </ul>
719
         * </p>
720
         *
721
         * @param g for rendering 2-dimensional shapes, text and images on the Java(tm) platform
722
         * @param viewPort the information for drawing the layers
723
         * @param cancel shared object that determines if this layer can continue being drawn
724
         * @param scale the scale of the view. Must be between {@linkplain FLayer#getMinScale()} and {@linkplain FLayer#getMaxScale()}.
725
         * @param properties properties that will be print
726
         * @param group a composed layer pending to paint; if this parameter is <code>null</code>, the composed layer
727
         *
728
         * @return <code>null</code> if the layers in <code>group</code> had been drawn or were <code>null</code>; otherwise, the <code>group</code>
729
         *
730
         * @see FLayer#print(Graphics2D, ViewPort, Cancellable, double, PrintRequestAttributeSet)
731
         *
732
         * @throws ReadDriverException if fails the driver reading the data.
733
         */
734
        public ComposedLayer print(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintRequestAttributeSet properties, ComposedLayer group)
735
        throws ReadException {
736
        double dpi = 72;
737

    
738
                PrintQuality resolution=(PrintQuality)properties.get(PrintQuality.class);
739
                if (resolution.equals(PrintQuality.NORMAL)){
740
                        dpi = 300;
741
                } else if (resolution.equals(PrintQuality.HIGH)){
742
                        dpi = 600;
743
                } else if (resolution.equals(PrintQuality.DRAFT)){
744
                        dpi = 72;
745
                }
746

    
747
                // TODO: A la hora de imprimir, isWithinScale falla, porque est?
748
                // calculando la escala en pantalla, no para el layout.
749
                // Revisar esto.
750

    
751
                // TODO: We have to check when we have to call the drawLabels method when exists a ComposedLayer group.
752
                for (int i=0; i < layers.size(); i++) {
753
                        FLayer lyr = (FLayer) layers.get(i);
754
                        if (!lyr.isVisible() || !lyr.isWithinScale(scale)) {
755
                                continue;
756
                        }
757

    
758
                        try{
759

    
760
                                ///// CHEMA ComposedLayer
761
                                // Checks for draw group (ComposedLayer)
762
                                if (group != null) {
763
                                        if (lyr instanceof FLayers){
764
                                                group = ((FLayers)lyr).print(g, viewPort, cancel,scale,properties,group);
765
                                        } else {
766
                                                // If layer can be added to the group, does it
767
                                                if (lyr instanceof ILabelable
768
                                                                && ((ILabelable) lyr).isLabeled()
769
                                                                && ((ILabelable) lyr).getLabelingStrategy() != null
770
                                                                && ((ILabelable) lyr).getLabelingStrategy().shouldDrawLabels(scale)) {
771
                                                        group.add(lyr);
772
                                                } else {
773
                                                        // draw the 'pending to draw' layer group
774
                                                        group.print(g,viewPort,cancel,scale,properties);
775

    
776
                                                        // gets a new group instance
777
                                                        if (lyr instanceof ILabelable
778
                                                                        && ((ILabelable) lyr).isLabeled()
779
                                                                        && ((ILabelable) lyr).getLabelingStrategy() != null
780
                                                                        && ((ILabelable) lyr).getLabelingStrategy().shouldDrawLabels(scale)) {
781
                                                                group = lyr.newComposedLayer();
782
                                                        } else {
783
                                                                group = null;
784
                                                        }
785
                                                        // if layer hasn't group, draws it inmediately
786
                                                        if (group == null) {
787
                                                                if (lyr instanceof FLayers){
788
                                                                        group = ((FLayers)lyr).print(g, viewPort, cancel,scale,properties,group);
789
                                                                } else {
790
                                                                        lyr.print(g, viewPort, cancel,scale,properties);
791
                                                                        if (lyr instanceof ILabelable
792
                                                                                        && ((ILabelable) lyr).isLabeled()
793
                                                                                        && ((ILabelable) lyr).getLabelingStrategy() != null
794
                                                                                        && ((ILabelable) lyr).getLabelingStrategy().shouldDrawLabels(scale)) {
795
                                                                                ILabelable lLayer = (ILabelable) lyr;
796
                                                                                lLayer.drawLabels(null, g, viewPort, cancel, scale, dpi);
797
                                                                        }
798
                                                                }
799
                                                        } else {
800
                                                                // add the layer to the group
801
                                                                group.setMapContext(fmap);
802
                                                                group.add(lyr);
803

    
804
                                                        }
805

    
806
                                                }
807
                                        }
808
                                } else {
809
                                        // gets a new group instance
810
                                        group = lyr.newComposedLayer();
811
                                        // if layer hasn't group, draws it inmediately
812
                                        if (group == null) {
813
                                                if (lyr instanceof FLayers){
814
                                                        group = ((FLayers)lyr).print(g, viewPort, cancel,scale,properties,group);
815
                                                } else {
816
                                                        lyr.print(g, viewPort, cancel,scale,properties);
817
                                                        if (lyr instanceof ILabelable && ((ILabelable) lyr).isLabeled()) {
818
                                                                ILabelable lLayer = (ILabelable) lyr;
819

    
820
                                                                lLayer.drawLabels(null, g, viewPort, cancel, scale, dpi);
821
                                                        }
822
                                                }
823
                                        } else {
824
                                                // add the layer to the group
825
                                                group.setMapContext(fmap);
826
                                                group.add(lyr);
827

    
828
                                        }
829
                                }
830
                                ///// CHEMA ComposedLayer
831

    
832
                        } catch (Exception e){
833
                                String mesg = Messages.getString("error_printing_layer")+" "+ lyr.getName() + ": " + e.getMessage();
834
                                fmap.addLayerError(mesg);
835
                                logger.error(mesg, e);
836
                        }
837

    
838
                }
839

    
840
                ///// CHEMA ComposedLayer
841
                if (group != null && this.getParentLayer() == null) {
842
                        //si tenemos un grupo pendiente de pintar, pintamos
843
                        group.print(g, viewPort, cancel,scale,properties);
844
                        group = null;
845

    
846
                }
847
                ///// CHEMA ComposedLayer
848

    
849
                if (getVirtualLayers() != null) {
850
                        getVirtualLayers().print( g, viewPort, cancel, scale, properties);
851
                }
852

    
853
                ///// CHEMA ComposedLayer
854
                return group;
855
                ///// CHEMA ComposedLayer
856
        }
857

    
858
        /*
859
         * (non-Javadoc)
860
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getFullExtent()
861
         */
862
        public Envelope getFullEnvelope() {
863
                Envelope rAux = null;
864
                boolean first = true;
865

    
866

    
867
                for (Iterator iter = layers.iterator(); iter.hasNext();) {
868
                        FLayer capa = (FLayer) iter.next();
869
                        try{
870
                                if (first) {
871
                                        rAux = capa.getFullEnvelope();
872
                                        first=false;
873
                                } else {
874
                                        rAux.add(capa.getFullEnvelope());
875
                                }
876
                        }catch (Exception e) {
877
                                e.printStackTrace();//TODO hay que revisar para determinar el comportamiento que espera el usuario.
878
                        }
879
                }
880

    
881
                return rAux;
882
        }
883

    
884
        /**
885
         * Notifies all listeners associated to this collection of layers,
886
         *  that another layer is going to be added or replaced in the internal
887
         *  list of layers.
888
         *
889
         * @param e a layer collection event with the new layer
890
         */
891
        protected void callLayerAdding(LayerCollectionEvent event)
892
        throws CancelationException {
893
                ArrayList aux = (ArrayList) layerCollectionListeners.clone();
894
                for (Iterator iter = aux.iterator(); iter.hasNext();) {
895
                        ((LayerCollectionListener) iter.next()).layerAdding(event);
896
                }
897
        }
898

    
899
        /**
900
         * Notifies all listeners associated to this collection of layers,
901
         *  that a layer is going to be removed from the internal list of layers.
902
         *
903
         * @param event a layer collection event with the layer being removed
904
         *
905
         * @throws CancelationException any exception produced during the cancellation of the driver.
906
         */
907
        protected void callLayerRemoving(LayerCollectionEvent event)
908
        throws CancelationException {
909
                ArrayList aux = (ArrayList) layerCollectionListeners.clone();
910
                for (Iterator iter = aux.iterator(); iter.hasNext();) {
911
                        ((LayerCollectionListener) iter.next()).layerRemoving(event);
912
                }
913
        }
914

    
915
        /**
916
         * Notifies all listeners associated to this collection of layers,
917
         *  that a layer is going to be moved in the internal list of layers.
918
         *
919
         * @param event a layer collection event with the layer being moved, and the initial and final positions
920
         *
921
         * @throws CancelationException any exception produced during the cancellation of the driver.
922
         */
923
        protected void callLayerMoving(LayerPositionEvent event)
924
        throws CancelationException {
925
                ArrayList aux = (ArrayList) layerCollectionListeners.clone();
926
                for (Iterator iter = aux.iterator(); iter.hasNext();) {
927
                        ((LayerCollectionListener) iter.next()).layerMoving(event);
928
                }
929
        }
930

    
931
        /**
932
         * Notifies all listeners associated to this collection of layers,
933
         *  that another layer has been added or replaced in the internal
934
         *  list of layers.
935
         *
936
         * @param e a layer collection event with the new layer
937
         */
938
        protected void callLayerAdded(LayerCollectionEvent event) {
939
                ArrayList aux = (ArrayList) layerCollectionListeners.clone();
940
                for (Iterator iter = aux.iterator(); iter.hasNext();) {
941
                        ((LayerCollectionListener) iter.next()).layerAdded(event);
942
                }
943
        }
944

    
945
        /**
946
         * Notifies all listeners associated to this collection of layers,
947
         *  that another layer has been removed from the internal list of layers.
948
         *
949
         * @param e a layer collection event with the layer removed
950
         */
951
        protected void callLayerRemoved(LayerCollectionEvent event) {
952
                ArrayList aux = (ArrayList) layerCollectionListeners.clone();
953
                for (Iterator iter = aux.iterator(); iter.hasNext();) {
954
                        ((LayerCollectionListener) iter.next()).layerRemoved(event);
955
                }
956
        }
957

    
958
        /**
959
         * Notifies all listeners associated to this collection of layers,
960
         *  that another layer has been moved in the internal list of layers.
961
         *
962
         * @param e a layer collection event with the layer moved, and the initial and final positions
963
         */
964
        protected void callLayerMoved(LayerPositionEvent event) {
965
                ArrayList aux = (ArrayList) layerCollectionListeners.clone();
966
                for (Iterator iter = aux.iterator(); iter.hasNext();) {
967
                        ((LayerCollectionListener) iter.next()).layerMoved(event);
968
                }
969
        }
970

    
971
        /**
972
         * <p>Returns an entity that represents this collection of layers stored as a tree-node with children that are also layers.</p>
973
         *
974
         * <p>The root node has the same properties that <code>FlyrDefault#getXMLEntity()</code> returns, and adds:
975
         *  <ul>
976
         *          <li> <i>numLayers</i> : number of layers of this collection (direct children of this node)
977
         *   <li> <i>LayerNames</i> : an array list with the name of the layers of this collection (direct children of this node)
978
         *    <code>FLayer.getXMLEntity()</code>
979
         *  </ul>
980
         * </p>
981
         *
982
         * <p>All XML elements returned represent the information about this layer.</p>
983
         *
984
         * @return an XML entity with information to this collection of layers
985
         * @throws org.gvsig.fmap.mapcontext.layers.XMLException if there is any error creating the XML from the layers.
986
         */
987
        public XMLEntity getXMLEntity() throws XMLException {
988
                XMLEntity xml = super.getXMLEntity();
989
                xml.putProperty("numLayers", layers.size());
990

    
991
                String[] s = new String[layers.size()];
992

    
993
                for (int i = 0; i < layers.size(); i++) {
994
                        s[i] = ((FLayer) layers.get(i)).getName();
995
                }
996

    
997
                xml.putProperty("LayerNames", s);
998

    
999
                for (int i = 0; i < layers.size(); i++) {
1000
                        try {
1001
                                xml.addChild(((FLayer) layers.get(i)).getXMLEntity());
1002
                        }catch (XMLException e) {
1003
                                e.printStackTrace();
1004
                        }
1005
                }
1006

    
1007
                return xml;
1008
        }
1009

    
1010
        /**
1011
         * <p>Inserts layers and properties to this collection of layers.</p>
1012
         *
1013
         * <p>This root node has the same properties that return <code>FlyrDefault#getXMLEntity()</code> adding:
1014
         *  <ul>
1015
         *          <li> <i>numLayers</i> : number of first-level layers of this collection
1016
         *   <li> <i>LayerNames</i> : an array list with the name of the first-level layers of this collection
1017
         *    <code>FLayer.getXMLEntity()</code>
1018
         *  </ul>
1019
         * </p>
1020
         *
1021
         * @see FLyrDefault#setXMLEntity()
1022
         * @see FLyrDefault#getXMLEntity()
1023
         * @see CopyOfFLayers#addLayerFromXML(XMLEntity, String)
1024
         *
1025
         * @param xml an <code>XMLEntity</code> with the information
1026
         *
1027
         * @throws org.gvsig.fmap.mapcontext.layers.XMLException if there is an error setting the object.
1028
         */
1029
//        public void setXMLEntity(XMLEntity xml) throws XMLException{
1030
//                super.setXMLEntity(xml);
1031
//                //LoadLayerException loadLayerException=new LoadLayerException();
1032
//                int numLayers = xml.getIntProperty("numLayers");
1033
//
1034
//                String[] s = xml.getStringArrayProperty("LayerNames");
1035
//                // try {
1036
//                fmap.clearErrors();
1037
//                for (int i = 0; i < numLayers; i++) {
1038
//                        try {
1039
//                                this.addLayerFromXML(xml.getChild(i),s[i]);
1040
//                        } catch (LoadLayerException e) {
1041
//                                throw new XMLException(e);
1042
//                        }
1043
//
1044
//
1045
//                }
1046
//        }
1047
        //        /*
1048
        //         * (non-Javadoc)
1049
        //         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor, com.iver.cit.gvsig.fmap.layers.FBitSet)
1050
        //         */
1051
        //        public void process(FeaturesVisitor visitor, FeatureCollection collection)
1052
        //        throws ReadException{
1053
        //                for (Iterator iter = layers.iterator(); iter.hasNext();) {
1054
        //                        FLayer layer = (FLayer) iter.next();
1055
        //
1056
        //                        if (layer instanceof VectorialData) {
1057
        //                                ((VectorialData) layer).process(visitor, collection);
1058
        //                        }
1059
        //                }
1060
        //        }
1061
        //
1062
        //        /*
1063
        //         * (non-Javadoc)
1064
        //         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor)
1065
        //         */
1066
        //        public void process(FeaturesVisitor visitor)
1067
        //        throws ReadException {
1068
        //                for (Iterator iter = layers.iterator(); iter.hasNext();) {
1069
        //                        FLayer layer = (FLayer) iter.next();
1070
        //
1071
        //                        if (layer instanceof FLayers){
1072
        //                                FLayers lyrs=(FLayers)layer;
1073
        //                                for (int i=0;i<lyrs.getLayersCount();i++){
1074
        //                                        FLayer lyr=lyrs.getLayer(i);
1075
        //                                        if (lyr.isActive()) {
1076
        //                                                if (lyr instanceof VectorialData) {
1077
        //                                                        ((VectorialData) lyr).process(visitor);
1078
        //                                                }
1079
        //                                        }
1080
        //                                }
1081
        //                        }
1082
        //                        if (layer.isActive()) {
1083
        //                                if (layer instanceof VectorialData) {
1084
        //                                        ((VectorialData) layer).process(visitor);
1085
        //                                }
1086
        //                        }
1087
        //                }
1088
        //        }
1089
        /*
1090
         * (non-Javadoc)
1091
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData#process(com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor, java.awt.geom.Rectangle2D)
1092
         */
1093
//        public void process(FeaturesVisitor visitor, Rectangle2D rect) throws ReadException {
1094
//                for (Iterator iter = layers.iterator(); iter.hasNext();) {
1095
//                        FLayer layer = (FLayer) iter.next();
1096
//
1097
//                        if (layer.isActive()) {
1098
//                                if (layer instanceof VectorialData) {
1099
//                                        ((VectorialData) layer).process(visitor, rect);
1100
//                                }
1101
//                        }
1102
//                }
1103
//
1104
//        }
1105
        /*
1106
         * (non-Javadoc)
1107
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#getMapContext()
1108
         */
1109
        public MapContext getMapContext() {
1110
                return fmap;
1111
        }
1112
        /*
1113
         * (non-Javadoc)
1114
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setCoordTrans(org.cresques.cts.ICoordTrans)
1115
         */
1116
        public void setCoordTrans(ICoordTrans ct) {
1117
                super.setCoordTrans(ct);
1118

    
1119
                for (Iterator iter = layers.iterator(); iter.hasNext();) {
1120
                        FLayer layer = (FLayer) iter.next();
1121
                        layer.setCoordTrans(ct);
1122
                }
1123
        }
1124
        /*
1125
         * (non-Javadoc)
1126
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#setAllActives(boolean)
1127
         */
1128
        public void setAllActives(boolean active) {
1129
                FLayer lyr;
1130

    
1131
                for (int i = 0; i < layers.size(); i++) {
1132
                        lyr = ((FLayer) layers.get(i));
1133
                        lyr.setActive(active);
1134

    
1135
                        if (lyr instanceof LayerCollection) {
1136
                                ((LayerCollection) lyr).setAllActives(active);
1137
                        }
1138
                }
1139
        }
1140

    
1141
        /*
1142
         * (non-Javadoc)
1143
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#getActives()
1144
         */
1145
        public FLayer[] getActives() {
1146
                ArrayList ret = new ArrayList();
1147
                LayersIterator it = new LayersIterator(this) {
1148

    
1149
                        public boolean evaluate(FLayer layer) {
1150
                                return layer.isActive();
1151
                        }
1152

    
1153
                };
1154

    
1155
                while (it.hasNext())
1156
                {
1157
                        ret.add(it.next());
1158
                }
1159
                return (FLayer[]) ret.toArray(new FLayer[0]);
1160
        }
1161

    
1162
        /*
1163
         * (non-Javadoc)
1164
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#getMinScale()
1165
         */
1166
        public double getMinScale() {
1167
                return -1; // La visibilidad o no la controla cada capa
1168
                // dentro de una colecci?n
1169
        }
1170
        /*
1171
         * (non-Javadoc)
1172
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#getMaxScale()
1173
         */
1174
        public double getMaxScale() {
1175
                return -1;
1176
        }
1177
        /*
1178
         * (non-Javadoc)
1179
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setMinScale(double)
1180
         */
1181
        public void setMinScale(double minScale)
1182
        {
1183
                for (Iterator iter = layers.iterator(); iter.hasNext();) {
1184
                        FLayer lyr = (FLayer) iter.next();
1185
                        lyr.setMinScale(minScale);
1186
                }
1187
        }
1188
        /*
1189
         * (non-Javadoc)
1190
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setMaxScale(double)
1191
         */
1192
        public void setMaxScale(double maxScale)
1193
        {
1194
                for (Iterator iter = layers.iterator(); iter.hasNext();) {
1195
                        FLayer lyr = (FLayer) iter.next();
1196
                        lyr.setMinScale(maxScale);
1197
                }
1198
        }
1199
        /*
1200
         * (non-Javadoc)
1201
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setActive(boolean)
1202
         */
1203
        public void setActive(boolean b){
1204
                super.setActive(b);
1205
                for (int i=0;i<layers.size();i++){
1206
                        ((FLayer)layers.get(i)).setActive(b);
1207
                }
1208
        }
1209
        /* (non-Javadoc)
1210
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#addLayerListener(com.iver.cit.gvsig.fmap.layers.LayerListener)
1211
         */
1212
        public boolean addLayerListener(LayerListener o) {
1213
                for (int i = 0; i < layers.size(); i++) {
1214
                        ((FLayer) layers.get(i)).addLayerListener(o);
1215
                }
1216
                return true;
1217
        }
1218
        /*
1219
         * (non-Javadoc)
1220
         * @see com.iver.cit.gvsig.fmap.layers.layerOperations.InfoByPoint#getInfo(java.awt.Point, double, com.iver.utiles.swing.threads.Cancellable)
1221
         */
1222
        public XMLItem[] getInfo(Point p, double tolerance, Cancellable cancel) throws ReadException, LoadLayerException {
1223
                int i;
1224
                Vector items = new Vector();
1225
                FLayer layer;
1226
                XMLItem[] aux;
1227
                for (i = 0; i < this.layers.size(); i++){
1228
                        layer = (FLayer)layers.get(i);
1229
                        if (layer instanceof InfoByPoint){
1230
                                InfoByPoint queryable_layer = (InfoByPoint) layer;
1231
                                aux = queryable_layer.getInfo(p, tolerance, null);
1232
                                if (!(queryable_layer instanceof FLayers)){
1233
                                        for(int j = 0; j < aux.length; j++){
1234
                                                items.add(aux[j]);
1235
                                        }
1236
                                }
1237
                        }
1238
                }
1239
                return (XMLItem[])items.toArray(new XMLItem[0]);
1240

    
1241
//        for (i = 0; i < this.layers.size(); i++){
1242
//        FLayer laCapa = (FLayer) layers.get(i);
1243
//        if (laCapa instanceof FLyrVect){
1244
//        }
1245
//        else if (laCapa instanceof RasterOperations) {
1246
//        try {
1247
//        RasterOperations layer = (RasterOperations) laCapa;
1248
//        sb.append(layer.getInfo(p, tolerance));
1249
//        } catch (DriverException e) {
1250
//        e.printStackTrace();
1251
//        }
1252
//        }
1253
//        else if (laCapa instanceof InfoByPoint) {
1254
//        try {
1255
//        InfoByPoint layer = (InfoByPoint) laCapa;
1256
//        sb.append(layer.getInfo(p, tolerance));
1257
//        } catch (DriverException e) {
1258
//        e.printStackTrace();
1259
//        }
1260
//        }
1261
//        }
1262

    
1263
        }
1264

    
1265
        /*
1266
         * (non-Javadoc)
1267
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#getTocImageIcon()
1268
         */
1269
        public ImageIcon getTocImageIcon() {
1270
                return new ImageIcon(MapContext.class.getResource("images/layerGroup.png"));
1271
        }
1272
        /*
1273
         * (non-Javadoc)
1274
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#isDirty()
1275
         */
1276
        public boolean isDirty() {
1277
                for (Iterator iter = layers.iterator(); iter.hasNext();) {
1278
                        FLayer lyr = (FLayer) iter.next();
1279
                        if (lyr.isDirty()) {
1280
                                return true;
1281
                        }
1282
                }
1283
                return false;
1284
        }
1285
        /*
1286
         * (non-Javadoc)
1287
         * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setDirty(boolean)
1288
         */
1289
        public void setDirty(boolean dirty) {
1290
                for (Iterator iter = layers.iterator(); iter.hasNext();) {
1291
                        FLayer lyr = (FLayer) iter.next();
1292
                        lyr.setDirty(dirty);
1293
                }
1294

    
1295
        }
1296

    
1297
        /**
1298
         * <p>Adds the layer with the information in an XML entity and the specified name, to this collection of layers. And
1299
         *  returns <code>true</code> if there hasn't been errors.</p>
1300
         *
1301
         * @see CopyOfFLayers#addLayerFromXML(XMLEntity, String)
1302
         *
1303
         * @param xml tree-node structure with information about layers
1304
         * @param name name of the layer to add
1305
         * @return <code>true</code> if there were no errors adding the layer, <code>false</code> otherwise
1306
         *
1307
         * @throws LoadLayerException if fails loading this layer.
1308
         */
1309
//        public boolean addLayerFromXMLEntity(XMLEntity xml, String name) throws LoadLayerException {
1310
//                fmap.clearErrors();
1311
//                this.addLayerFromXML(xml,name);
1312
//
1313
//                return (fmap.getLayersError().size() == 0);
1314
//
1315
//        }
1316

    
1317
        /**
1318
         * <p>Adds the layer with the information in an XML entity and the specified name, to this collection of layers.</p>
1319
         *
1320
         * <p>This method really executes the addition, considering the kind of layer (<code>FLyrVect</code>,
1321
         *  <code>FLyrAnnotation</code>, <code>FLyrRaster</code>, a collection of layers (<code>FLayers</code>),
1322
         *  or another kind of layer (<code>FLayer</code>)), and the driver in the layer.</p>
1323
         *
1324
         * @param xml tree-node structure with information about layers
1325
         * @param name name of the layer to add
1326
         *
1327
         * @throws LoadLayerException if fails loading this layer.
1328
         */
1329
//        private void addLayerFromXML(XMLEntity xml, String name) throws LoadLayerException {
1330
//        FLayer layer = null;
1331
//
1332
//        try {
1333
//                if (name == null) name = xml.getName();
1334
//
1335
//
1336
//                String className = xml.getStringProperty("className");
1337
//                //TODO VCN FLyrAnnotation es un parche para no tener que duplicar todo el c?digo de aq? y de los diferentes m?todos de LayerFactory,
1338
//                //ya que los drivers de una FLyrAnnotation no sabemos cual es puede ser cualquier Driver Vectorial.
1339
//                if (className.equals(FLyrVect.class.getName()) || className.equals(FLyrAnnotation.class.getName())) {
1340
//                        String type = xml.getStringProperty("type");
1341
//                        if ("vectorial".equals(type)){
1342
//                                //String recordsetName = xml.getChild(i).getStringProperty("recordset-name");
1343
//                                IProjection proj = null;
1344
//                                if (xml.contains("proj")) {
1345
//                                        proj = CRSFactory.getCRS(xml.getStringProperty("proj"));
1346
//                                }
1347
//                                else
1348
//                                {
1349
//                                        proj = this.getMapContext().getViewPort().getProjection();
1350
//                                }
1351
//                                if (xml.contains("file")) {
1352
//                                        Driver d;
1353
//                                        try {
1354
//                                                d = LayerFactory.getDM().getDriver(xml.getStringProperty("driverName"));
1355
//                                        } catch (DriverLoadException e1) {
1356
//                                                throw new DriverLayerException(name,e1);
1357
//                                        }
1358
//                                        layer = LayerFactory.createLayer(name, (VectorialFileDriver) d,
1359
//                                                        new File(xml.getStringProperty("file")),
1360
//                                                        proj);
1361
//
1362
//
1363
//                                }
1364
//                                if (xml.contains("db")) {
1365
//
1366
//                                        String driverName = xml.getStringProperty("db");
1367
//                                        IVectorialDatabaseDriver driver;
1368
//                                        try {
1369
//                                                driver = (IVectorialDatabaseDriver) LayerFactory.getDM().getDriver(driverName);
1370
//                                                //Hay que separar la carga de los datos del XMLEntity del load.
1371
//                                                driver.setXMLEntity(xml.getChild(2));
1372
//
1373
//                                                boolean loadOk = false;
1374
//                                                ((DefaultJDBCDriver)driver).load();
1375
//                                                if (((DefaultJDBCDriver)driver).getConnection() != null) {
1376
//                                                        loadOk = true;
1377
//                                                }
1378
//                                                layer = LayerFactory.createDBLayer(driver, name, proj);
1379
//                                                if (!loadOk) {
1380
//                                                        layer.setAvailable(false);
1381
//                                                }
1382
//
1383
//                                        } catch (DriverLoadException e) {
1384
//                                                throw new DriverLayerException(name,e);
1385
//                                        } catch (XMLException e) {
1386
//                                                throw new DriverLayerException(name,e);
1387
//                                        } catch (ReadException e) {
1388
//                                                throw new DriverLayerException(name,e);
1389
//                                        }
1390
//
1391
//                                }
1392
//                                // Clases con algun driver gen?rico creado por otro
1393
//                                // programador
1394
//                                if (xml.contains("other")) {
1395
//
1396
//                                        String driverName = xml.getStringProperty("other");
1397
//                                        VectorialDriver driver = null;
1398
//                                        try {
1399
//                                                driver = (VectorialDriver) LayerFactory.getDM().getDriver(driverName);
1400
//                                        } catch (DriverLoadException e) {
1401
//                                                // Si no existe ese driver, no pasa nada.
1402
//                                                // Puede que el desarrollador no quiera que
1403
//                                                // aparezca en el cuadro de di?logo y ha metido
1404
//                                                // el jar con sus clases en nuestro directorio lib.
1405
//                                                // Intentamos cargar esa clase "a pelo".
1406
//                                                if (xml.getChild(2).contains("className"))
1407
//                                                {
1408
//                                                        String className2 = xml.getChild(2).getStringProperty("className");
1409
//                                                        try {
1410
//                                                                driver = (VectorialDriver) Class.forName(className2).newInstance();
1411
//                                                        } catch (Exception e1) {
1412
//                                                                throw new DriverLayerException(name,e);
1413
//                                                        }
1414
//                                                }
1415
//                                        } catch (NullPointerException npe) {
1416
//                                                // Si no existe ese driver, no pasa nada.
1417
//                                                // Puede que el desarrollador no quiera que
1418
//                                                // aparezca en el cuadro de di?logo y ha metido
1419
//                                                // el jar con sus clases en nuestro directorio lib.
1420
//                                                // Intentamos cargar esa clase "a pelo".
1421
//                                                if (xml.getChild(2).contains("className"))
1422
//                                                {
1423
//                                                        String className2 = xml.getChild(2).getStringProperty("className");
1424
//                                                        try {
1425
//                                                                driver = (VectorialDriver) Class.forName(className2).newInstance();
1426
//                                                        } catch (Exception e1) {
1427
//                                                                throw new DriverLayerException(name,e1);
1428
//                                                        }
1429
//                                                }
1430
//                                        }
1431
//                                        if (driver instanceof IPersistence)
1432
//                                        {
1433
//                                                IPersistence persist = (IPersistence) driver;
1434
//                                                persist.setXMLEntity(xml.getChild(2));
1435
//                                        }
1436
//                                        layer = LayerFactory.createLayer(name, driver, proj);
1437
//                                }
1438
//
1439
//                        }
1440
//
1441
//                        //TODO VCN FLyrAnnotation es un parche para no tener que duplicar todo el c?digo de aq? y de los diferentes m?todos de LayerFactory,
1442
//                        //ya que los drivers de una FLyrAnnotation no sabemos cual es puede ser cualquier Driver Vectorial.
1443
//                        if (className.equals(FLyrAnnotation.class.getName())){
1444
//                                layer=FLyrAnnotation.createLayerFromVect((FLyrVect)layer);
1445
//                        }
1446
//
1447
//
1448
//                        layer.setXMLEntity(xml);
1449
//
1450
//                } else {
1451
//                        Class clase = LayerFactory.getLayerClassForLayerClassName(className);
1452
//                        layer = (FLayer) clase.newInstance();
1453
//                        if (clase.isAssignableFrom(FLayers.class)) {
1454
//                                ((FLayers)layer).setMapContext(getMapContext());
1455
//                                ((FLayers)layer).setParentLayer(this);
1456
////                                layer = new FLayers(getMapContext(),this);
1457
//                                layer.setXMLEntity(xml);
1458
//                        } else {
1459
//                                // Capas Nuevas (externas)
1460
//                                layer.setName(name);
1461
//                                layer.setXMLEntity(xml);
1462
//                                layer.load();
1463
//                        }
1464
//                }
1465
//                this.addLayer(layer);
1466
//                logger.debug("layer: "+ layer.getName() +" loaded");
1467
//                // Comprobar que la proyecci?n es la misma que la de FMap
1468
//                // Si no lo es, es una capa que est? reproyectada al vuelo
1469
//                IProjection proj = layer.getProjection();
1470
//                if ((proj != null))
1471
//                        if (!proj.getFullCode().equals(getMapContext().getProjection().getFullCode()))
1472
//                        {
1473
//                                ICoordTrans ct = proj.getCT(getMapContext().getProjection());
1474
//                                // TODO: REVISAR CON LUIS
1475
//                                // Se lo fijamos a todas, luego cada una que se reproyecte
1476
//                                // si puede, o que no haga nada
1477
//
1478
//                                layer.setCoordTrans(ct);
1479
//                        }
1480
//        } catch (XMLException e) {
1481
//                fmap.addLayerError(xml.getStringProperty("name"));
1482
//                throw new LoadLayerException(name,e);
1483
//        } catch (ClassNotFoundException e) {
1484
//                fmap.addLayerError(xml.getStringProperty("name"));
1485
//                throw new LoadLayerException(name,e);
1486
//        } catch (InstantiationException e) {
1487
//                fmap.addLayerError(xml.getStringProperty("name"));
1488
//                throw new LoadLayerException(name,e);
1489
//        } catch (IllegalAccessException e) {
1490
//                fmap.addLayerError(xml.getStringProperty("name"));
1491
//                throw new LoadLayerException(name,e);
1492
//        } catch (ReadException e) {
1493
//                fmap.addLayerError(xml.getStringProperty("name"));
1494
//                throw new LoadLayerException(name,e);
1495
//        } catch (LoadLayerException e){
1496
//                fmap.addLayerError(xml.getStringProperty("name"));
1497
//                throw e;
1498
//        }
1499
//        }
1500

    
1501
        /**
1502
         * <p>Sets the <code>MapContext</code> that contains this layer node.</p>
1503
         *
1504
         * @param mapContext the <code>MapContext</code> that contains this layer node
1505
         */
1506
        public void setMapContext(MapContext mapContext) {
1507
                this.fmap = mapContext;
1508
        }
1509

    
1510
        /**
1511
         * <p>Creates a new layer of the same class as the property <i>className</i> of the XML, after, adds the XML entity to that layer
1512
         *  and loads the layer. Then, adds the layer to this collection of layers, and if there is a projection defined,
1513
         *  inserts the transformation coordinates to the layer.</p>
1514
         *
1515
         * <p>If the new layer is an instance of <code>FLyrVect</code>, and has a label field, creates a label layer on the layer.</p>
1516
         *
1517
         * @param xml tree-node structure with information about layers
1518
         * @param name name of the layer to add
1519
         */
1520
        private void addLayerFromXMLNew(XMLEntity xml, String name) {
1521
//                FLayer layer = null;
1522
//
1523
//
1524
//                try {
1525
//                        String className = xml.getStringProperty("className");
1526
//                        Class clazz = Class.forName(className);
1527
//                        if (clazz.isAssignableFrom(FLayers.class)) {
1528
//                                layer = (FLayer) clazz.newInstance();
1529
//                                ((FLayers)layer).setMapContext(getMapContext());
1530
//                                ((FLayers)layer).setParentLayer(this);
1531
//        //                if (className.equals((FLayers.class.getName()))){
1532
//        //                        layer = new FLayers(getMapContext(),this);
1533
//                        } else {
1534
//        //                        Por compatibilidad
1535
//                                if (className.equals(FLyrVect.class.getName())) {
1536
//                                        if (xml.contains("file")) {
1537
//                                                layer = new FLayerFileVectorial();
1538
//                                        } else if (xml.contains("db")) {
1539
//                                                try {
1540
//                                                        layer = (FLayer)((ExtensionPoint)ExtensionPointsSingleton.getInstance().get("Layers")).create("com.iver.cit.gvsig.fmap.layers.FLayerJDBCVectorial");
1541
//                                                } catch (Exception e) {
1542
//                                                        throw new XMLException(new Exception("No se tiene registrada la capa de tipo JDBC"));
1543
//                                                }
1544
//                                                //className = FLayerJDBCVectorial.class.getName();
1545
//                                        } else if (xml.contains("other")){
1546
//                                                layer = new FLayerGenericVectorial();
1547
//                                        } else {
1548
//                                                throw new XMLException(new Exception("Capa vectorial de tipo no reconocido"));
1549
//                                        }
1550
//        //                                Fin por compatibilidad
1551
//                                } else {
1552
//                                        try {
1553
//                                                layer = (FLayer)(((ExtensionPoint)ExtensionPointsSingleton.getInstance().get("Layers")).create(className));
1554
//                                        } catch (Exception e) {
1555
//                                                //puende que no este registrada como punto de extension
1556
//                                                Class clase = Class.forName(className);
1557
//                                                layer = (FLayer) clase.newInstance();
1558
//                                                // FIXME: Hacemos algo aqui o dejamos que suba el error?
1559
//                                        }
1560
//                                }
1561
//
1562
//                        }
1563
//                        layer.setXMLEntity(xml);
1564
//                        if (name != null) layer.setName(name);
1565
//                        layer.load();
1566
//
1567
//                        this.addLayer(layer);
1568
//                        logger.debug("layer: "+ layer.getName() +" loaded");
1569
//                        // Comprobar que la proyecci?n es la misma que la de FMap
1570
//                        // Si no lo es, es una capa que est? reproyectada al vuelo
1571
//                        IProjection proj = layer.getProjection();
1572
//                        if ((proj != null))
1573
//                                if (proj != getMapContext().getProjection())
1574
//                                {
1575
//                                        ICoordTrans ct = proj.getCT(getMapContext().getProjection());
1576
//                                        // TODO: REVISAR CON LUIS
1577
//                                        // Se lo fijamos a todas, luego cada una que se reproyecte
1578
//                                        // si puede, o que no haga nada
1579
//                                        layer.setCoordTrans(ct);
1580
//
1581
//                                }
1582
//                }catch (Exception e) {
1583
//                        fmap.addLayerError(xml.getStringProperty("name"));
1584
//                        logger.debug(Messages.getString("could_not_load_layer")+": "+xml.getStringProperty("name") + ".\n"
1585
//                                        +Messages.getString("reason")+":", e);
1586
//                }
1587
        }
1588

    
1589
        public void accept(Visitor visitor) throws BaseException {
1590
                throw new NotSupportedOperationException(visitor, this);
1591
        }
1592

    
1593
        public void accept(LayersVisitor visitor) throws BaseException {
1594
                for (int i = 0; i < this.getLayersCount(); i++) {
1595
                        FLayer layer = this.getLayer(i);
1596
                        if (layer instanceof LayersVisitable) {
1597
                                ((LayersVisitable) layer).accept(visitor);
1598
                        } else {
1599
                                visitor.visit(layer);
1600
                        }
1601
                }
1602
        }
1603

    
1604

    
1605
}