Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.mapcontext / org.gvsig.fmap.mapcontext.api / src / main / java / org / gvsig / fmap / mapcontext / layers / FLayers.java @ 42287

History | View | Annotate | Download (53.7 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License as published by the Free Software
8
 * Foundation; either version 3 of the License, or (at your option) any later
9
 * version.
10
 *
11
 * This program is distributed in the hope that it will be useful, but WITHOUT
12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
14
 * details.
15
 *
16
 * You should have received a copy of the GNU General Public License along with
17
 * this program; if not, write to the Free Software Foundation, Inc., 51
18
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us at info AT
21
 * gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.fmap.mapcontext.layers;
24

    
25
import java.awt.Graphics2D;
26
import java.awt.Point;
27
import java.awt.image.BufferedImage;
28
import java.util.ArrayList;
29
import java.util.Collections;
30
import java.util.Iterator;
31
import java.util.List;
32
import java.util.Set;
33
import java.util.TreeSet;
34

    
35
import org.cresques.cts.ICoordTrans;
36
import org.cresques.cts.IProjection;
37
import org.slf4j.Logger;
38
import org.slf4j.LoggerFactory;
39

    
40
import org.gvsig.compat.print.PrintAttributes;
41
import org.gvsig.fmap.dal.exception.DataException;
42
import org.gvsig.fmap.dal.exception.ReadException;
43
import org.gvsig.fmap.geom.primitive.Envelope;
44
import org.gvsig.fmap.mapcontext.MapContext;
45
import org.gvsig.fmap.mapcontext.MapContextRuntimeException;
46
import org.gvsig.fmap.mapcontext.Messages;
47
import org.gvsig.fmap.mapcontext.ViewPort;
48
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
49
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
50
import org.gvsig.fmap.mapcontext.layers.operations.InfoByPoint;
51
import org.gvsig.fmap.mapcontext.layers.operations.LayerCollection;
52
import org.gvsig.fmap.mapcontext.layers.operations.LayerNotFoundInCollectionException;
53
import org.gvsig.fmap.mapcontext.layers.operations.LayersVisitable;
54
import org.gvsig.fmap.mapcontext.layers.operations.LayersVisitor;
55
import org.gvsig.fmap.mapcontext.rendering.legend.styling.ILabelable;
56
import org.gvsig.metadata.exceptions.MetadataException;
57
import org.gvsig.tools.ToolsLocator;
58
import org.gvsig.tools.dispose.Disposable;
59
import org.gvsig.tools.dynobject.DynObjectSet;
60
import org.gvsig.tools.dynobject.DynStruct;
61
import org.gvsig.tools.dynobject.impl.MultiDynObjectSet;
62
import org.gvsig.tools.exception.BaseException;
63
import org.gvsig.tools.persistence.PersistenceManager;
64
import org.gvsig.tools.persistence.PersistentState;
65
import org.gvsig.tools.persistence.exception.PersistenceException;
66
import org.gvsig.tools.task.Cancellable;
67
import org.gvsig.tools.util.Callable;
68
import org.gvsig.tools.visitor.NotSupportedOperationException;
69
import org.gvsig.tools.visitor.VisitCanceledException;
70
import org.gvsig.tools.visitor.Visitor;
71

    
72
/**
73
 * <p>
74
 * Represents a generic collection of layers, that can be represented as a node
75
 * in a tree of nodes of layers.</p>
76
 *
77
 * <p>
78
 * Adapts the basic functionality implemented for a layer in the abstract class
79
 * <code>FLyrDefault</code>, to a collection of layers, implementing, as well,
80
 * specific methods for this kind of object, defined in the interfaces
81
 * <code>VectorialData</code>, <code>LayerCollection</code>, and
82
 * <code>InfoByPoint</code>.</p>
83
 *
84
 * @see FLyrDefault
85
 */
86
public class FLayers extends FLyrDefault implements LayerCollection,
87
        InfoByPoint {
88

    
89
    /**
90
     * List with all listeners registered for this kind of node.
91
     *
92
     * @see #addLayerCollectionListener(LayerCollectionListener)
93
     * @see #removeLayerCollectionListener(LayerCollectionListener)
94
     * @see #callLayerAdded(LayerCollectionEvent)
95
     * @see #callLayerAdding(LayerCollectionEvent)
96
     * @see #callLayerMoved(LayerPositionEvent)
97
     * @see #callLayerMoving(LayerPositionEvent)
98
     * @see #callLayerRemoved(LayerCollectionEvent)
99
     * @see #callLayerRemoving(LayerCollectionEvent)
100
     */
101
    protected ArrayList layerCollectionListeners = null;
102

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

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

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

    
134
    public FLayers() {
135
        super();
136
        layerCollectionListeners = new ArrayList();
137
        layers = Collections.synchronizedList(new ArrayList());
138

    
139
        logger = LoggerFactory.getLogger(FLayers.class);
140
    }
141
    /*
142
     * (non-Javadoc)
143
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#addLayerCollectionListener(com.iver.cit.gvsig.fmap.layers.LayerCollectionListener)
144
     */
145

    
146
    public void addLayerCollectionListener(LayerCollectionListener listener) {
147
        if (!layerCollectionListeners.contains(listener)) {
148
            layerCollectionListeners.add(listener);
149
        }
150
    }
151

    
152
    /*
153
     * (non-Javadoc)
154
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#setAllVisibles(boolean)
155
     */
156
    public void setAllVisibles(boolean visible) {
157
        FLayer lyr;
158

    
159
        for (int i = 0; i < layers.size(); i++) {
160
            lyr = ((FLayer) layers.get(i));
161
            lyr.setVisible(visible);
162

    
163
            if (lyr instanceof LayerCollection) {
164
                ((LayerCollection) lyr).setAllVisibles(visible);
165
            }
166
        }
167
    }
168

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

    
177
    /**
178
     * Adds a layer on an specified position in this node.
179
     *
180
     * @param pos position in the inner list where the layer will be added
181
     * @param layer a layer
182
     */
183
    private void doAddLayer(int pos, FLayer layer) {
184
        layers.add(pos, layer);
185
        ToolsLocator.getDisposableManager().bind(layer);
186
        layer.setParentLayer(this);
187
        IProjection layerProj = layer.getProjection();
188
        if (layerProj != null && fmap != null) {
189
            IProjection mapContextProj = fmap.getProjection();
190
                        // TODO REVISAR ESTO !!!!
191
            // Esta condici?n puede que no fuese exacta para todos los casos
192
            if (!layerProj.getAbrev().equals(mapContextProj.getAbrev())) {
193
                ICoordTrans ct = layerProj.getCT(mapContextProj);
194
                layer.setCoordTrans(ct);
195
            } else {
196
                layer.setCoordTrans(null);
197
            }
198
        }
199
        this.updateDrawVersion();
200
    }
201

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

    
208
        MapContext mco = this.getMapContext();
209

    
210
        if (mco != null) {
211
            /*
212
             * Get order manager from map context
213
             */
214
            int position = mco.getOrderManager().getPosition(this, layer);
215
            addLayer(position, layer);
216
        } else {
217
            /*
218
             * This happens when FLayers object is not in a
219
             * map context, so no order manager is available.
220
             */
221
            addLayer(layers.size(), layer);
222
        }
223
    }
224

    
225
    /**
226
     * Adds a layer in an specified position in this node.
227
     *
228
     * @param layer a layer
229
     */
230
    public void addLayer(int pos, FLayer layer) {
231
        try {
232
            //Notificamos a la capa que va a ser a?adida
233
            if (layer instanceof FLyrDefault) {
234
                ((FLyrDefault) layer).wakeUp();
235
            }
236

    
237
            if (layer instanceof FLayers) {
238
                FLayers layers = (FLayers) layer;
239
                fmap.addAsCollectionListener(layers);
240
            }
241
            callLayerAdding(LayerCollectionEvent.createLayerAddingEvent(layer));
242

    
243
            doAddLayer(pos, layer);
244

    
245
            callLayerAdded(LayerCollectionEvent.createLayerAddedEvent(layer));
246
        } catch (CancelationException e) {
247
            logger.warn(e.getMessage());
248
        } catch (LoadLayerException e) {
249
            layer.setAvailable(false);
250
            layer.addError(e);
251
        }
252
    }
253

    
254
    /*
255
     * (non-Javadoc)
256
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#moveTo(int, int)
257
     */
258
    public void moveTo(int from, int to) throws CancelationException {
259
        int newfrom = layers.size() - from - 1;
260
        int newto = layers.size() - to - 1;
261
        if (newfrom < 0 || newfrom >= layers.size() || newto < 0 || newto >= layers.size()) {
262
            return;
263
        }
264
        FLayer aux = (FLayer) layers.get(newfrom);
265
        callLayerMoving(LayerPositionEvent.createLayerMovingEvent(aux, newfrom, newto));
266
        layers.remove(newfrom);
267
        layers.add(newto, aux);
268
        this.updateDrawVersion();
269
        callLayerMoved(LayerPositionEvent.createLayerMovedEvent(aux, newfrom, newto));
270
    }
271

    
272
    /**
273
     * Removes an inner layer.
274
     *
275
     * @param lyr a layer
276
     */
277
    private void doRemoveLayer(FLayer lyr) {
278
        layers.remove(lyr);
279
        lyr.dispose();
280
        this.updateDrawVersion();
281
    }
282

    
283
    /*
284
     * (non-Javadoc)
285
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#removeLayer(com.iver.cit.gvsig.fmap.layers.FLayer)
286
     */
287
    public void removeLayer(FLayer lyr) throws CancelationException {
288
        callLayerRemoving(LayerCollectionEvent.createLayerRemovingEvent(lyr));
289
        doRemoveLayer(lyr);
290
        callLayerRemoved(LayerCollectionEvent.createLayerRemovedEvent(lyr));
291
    }
292

    
293
    /*
294
     * (non-Javadoc)
295
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#removeLayer(int)
296
     */
297
    public void removeLayer(int idLayer) {
298
        FLayer lyr = (FLayer) layers.get(idLayer);
299
        callLayerRemoving(LayerCollectionEvent.createLayerRemovingEvent(lyr));
300
        this.doRemoveLayer(lyr);
301
//                layers.remove(idLayer);
302
//                this.updateDrawVersion();
303
        callLayerRemoved(LayerCollectionEvent.createLayerRemovedEvent(lyr));
304
    }
305

    
306
    /*
307
     * (non-Javadoc)
308
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#removeLayer(java.lang.String)
309
     */
310
    public void removeLayer(String layerName) {
311
        FLayer lyr;
312

    
313
        for (int i = 0; i < layers.size(); i++) {
314
            lyr = ((FLayer) layers.get(i));
315

    
316
            if (lyr.getName().compareToIgnoreCase(layerName) == 0) {
317
                removeLayer(i);
318

    
319
                break;
320
            }
321
        }
322
    }
323

    
324
    /**
325
     * Replace a layer identified by its name, by another.
326
     *
327
     * @param layerName the name of the layer to be replaced
328
     * @param layer the new layer
329
     * @deprecated use {@link FLayers#replaceLayer(FLayer, FLayer)}
330
     */
331
    public void replaceLayer(String layerName, FLayer layer) throws LoadLayerException {
332
        replaceLayer(getLayer(layerName), layer);
333
    }
334

    
335
    /**
336
     * Replace a layer by another layer. It search recursively by all the
337
     * ILayerCollection nodes
338
     *
339
     * @param layer the layer to be replaced
340
     * @param newLayer the new layer
341
     */
342
    public void replaceLayer(FLayer layer, FLayer newLayer) throws LoadLayerException {
343
        replaceLayer(this, layer, newLayer);
344
    }
345

    
346
    /**
347
     * Replace a layer by other layer. It search recursively by all the
348
     * ILayerCollection nodes
349
     *
350
     * @param parentLayer the parent layer
351
     * @param layer the layer to be replaced
352
     * @param newLayer the new layer
353
     * @throws LoadLayerException
354
     */
355
    private void replaceLayer(FLayers parentLayer, FLayer layer, FLayer newLayer) throws LoadLayerException {
356
        FLayer lyr;
357
        for (int i = 0; i < parentLayer.getLayersCount(); i++) {
358
            lyr = ((FLayer) parentLayer.getLayer(i));
359
            if (lyr.equals(layer)) {
360
                parentLayer.removeLayer(i);
361
                parentLayer.addLayer(i, newLayer);
362
                break;
363
            }
364
            if (lyr instanceof LayerCollection) {
365
                replaceLayer((FLayers) lyr, layer, newLayer);
366
            }
367
        }
368
    }
369

    
370
    /*
371
     * (non-Javadoc)
372
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#getVisibles()
373
     */
374
    public FLayer[] getVisibles() {
375
        ArrayList array = new ArrayList();
376
        LayersIterator iter = new LayersIterator(this) {
377
            public boolean evaluate(FLayer layer) {
378
                return layer.isVisible();
379
            }
380

    
381
        };
382

    
383
        while (iter.hasNext()) {
384
            array.add(iter.nextLayer());
385
        }
386

    
387
        return (FLayer[]) array.toArray(new FLayer[0]);
388
    }
389

    
390
    /*
391
     * (non-Javadoc)
392
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#getLayer(int)
393
     */
394
    public FLayer getLayer(int index) {
395
        return (FLayer) layers.get(index);
396
    }
397

    
398
    /*
399
     * (non-Javadoc)
400
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#getLayer(java.lang.String)
401
     */
402
    public FLayer getLayer(String layerName) {
403
        FLayer lyr;
404
        FLayer lyr2;
405
        ArrayList layerList;
406

    
407
        for (int i = 0; i < layers.size(); i++) {
408
            lyr = ((FLayer) layers.get(i));
409

    
410
            if (lyr.getName().compareToIgnoreCase(layerName) == 0) {
411
                return lyr;
412
            }
413

    
414
            layerList = new ArrayList();
415
            splitLayerGroup(lyr, layerList);
416
            for (int j = 0; j < layerList.size(); j++) {
417
                lyr2 = ((FLayer) layerList.get(j));
418
                if (lyr2.getName().compareToIgnoreCase(layerName) == 0) {
419
                    return lyr2;
420
                }
421
            }
422
        }
423

    
424
        return null;
425
    }
426

    
427
    /**
428
     * <p>
429
     * Splits up a layer group in order to get a layer by name when there are
430
     * layer groups</p>
431
     *
432
     * <p>
433
     * In <code>result</code> always will be at least one layer.</p>
434
     *
435
     * @param layer the layer we are looking for
436
     * @param result an array list that will have the results of the search
437
     */
438
    private void splitLayerGroup(FLayer layer, ArrayList result) {
439
        int i;
440
        FLayers layerGroup;
441
        if (layer instanceof FLayers) {
442
            layerGroup = (FLayers) layer;
443
            for (i = 0; i < layerGroup.getLayersCount(); i++) {
444
                splitLayerGroup(layerGroup.getLayer(i), result);
445
            }
446
        } else {
447
            result.add(layer);
448
        }
449
    }
450

    
451
    /*
452
     * (non-Javadoc)
453
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#getLayersCount()
454
     */
455
    public int getLayersCount() {
456
        return layers.size();
457
    }
458

    
459
    /*
460
     * (non-Javadoc)
461
     * @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)
462
     */
463
    public void draw(BufferedImage image, Graphics2D g, ViewPort viewPort,
464
            Cancellable cancel, double scale) throws ReadException {
465
        // FIXME Arreglar este error
466
        throw new RuntimeException("Esto no deberia de llamarse");
467
    }
468

    
469
    /*
470
     * (non-Javadoc)
471
     *
472
     * @see com.iver.cit.gvsig.fmap.layers.FLayer#print(java.awt.Graphics2D,
473
     * com.iver.cit.gvsig.fmap.ViewPort,
474
     * com.iver.utiles.swing.threads.Cancellable, double,
475
     * javax.print.attribute.PrintAttributes)
476
     */
477
    public void print(Graphics2D g, ViewPort viewPort, Cancellable cancel,
478
            double scale, PrintAttributes properties)
479
            throws ReadException {
480
        throw new RuntimeException("No deberia pasar por aqui");
481
    }
482

    
483
    public void print_old(Graphics2D g, ViewPort viewPort, Cancellable cancel,
484
            double scale, PrintAttributes properties)
485
            throws ReadException {
486
        this.print_old(g, viewPort, cancel, scale, properties, null);
487
    }
488

    
489
    /**
490
     * <p>
491
     * Checks all layers (each one as a sub-node of this node <i>collection of
492
     * layers</i>) of this collection and draws their requested properties. If a
493
     * node is a group of layers (<code>ComposedLayer</code>), executes it's
494
     * drawn.</p>
495
     *
496
     * <p>
497
     * All nodes which could group with the composed layer <code>group</code>,
498
     * will be drawn together. And once the <code>
499
     * group</code> is drawn, will be set to <code>null</code> if hasn't a
500
     * parent layer.</p>
501
     *
502
     * <p>
503
     * The particular implementation depends on the kind of each layer and
504
     * composed layer. And this process can be cancelled at any time by the
505
     * shared object <code>cancel</code>.</p>
506
     *
507
     * <p>
508
     * According the print quality, labels will be printed in different
509
     * resolution:
510
     * <ul>
511
     * <li><b>PrintQuality.DRAFT</b>: 72 dpi (dots per inch).</li>
512
     * <li><b>PrintQuality.NORMAL</b>: 300 dpi (dots per inch).</li>
513
     * <li><b>PrintQuality.HIGH</b>: 600 dpi (dots per inch).</li>
514
     * </ul>
515
     * </p>
516
     *
517
     * @param g for rendering 2-dimensional shapes, text and images on the
518
     * Java(tm) platform
519
     * @param viewPort the information for drawing the layers
520
     * @param cancel shared object that determines if this layer can continue
521
     * being drawn
522
     * @param scale the scale of the view. Must be between
523
     * {@linkplain FLayer#getMinScale()} and {@linkplain FLayer#getMaxScale()}.
524
     * @param properties properties that will be print
525
     * @param group a composed layer pending to paint; if this parameter is
526
     * <code>null</code>, the composed layer
527
     *
528
     * @return <code>null</code> if the layers in <code>group</code> had been
529
     * drawn or were <code>null</code>; otherwise, the <code>group</code>
530
     *
531
     * @see FLayer#print(Graphics2D, ViewPort, Cancellable, double,
532
     * PrintAttributes)
533
     *
534
     * @throws ReadDriverException if fails the driver reading the data.
535
     */
536
    public ComposedLayer print_old(Graphics2D g, ViewPort viewPort, Cancellable cancel, double scale, PrintAttributes properties, ComposedLayer group)
537
            throws ReadException {
538
        double dpi = 72;
539

    
540
        int resolution = properties.getPrintQuality();
541
        if (resolution == PrintAttributes.PRINT_QUALITY_NORMAL) {
542
            dpi = 300;
543
        } else if (resolution == PrintAttributes.PRINT_QUALITY_HIGH) {
544
            dpi = 600;
545
        } else if (resolution == PrintAttributes.PRINT_QUALITY_DRAFT) {
546
            dpi = 72;
547
        }
548

    
549
                // TODO: A la hora de imprimir, isWithinScale falla, porque est?
550
        // calculando la escala en pantalla, no para el layout.
551
        // Revisar esto.
552
        // TODO: We have to check when we have to call the drawLabels method when exists a ComposedLayer group.
553
        for (int i = 0; i < layers.size(); i++) {
554
            FLayer lyr = (FLayer) layers.get(i);
555
            if (!lyr.isVisible() || !lyr.isWithinScale(scale)) {
556
                continue;
557
            }
558

    
559
            try {
560

    
561
                                ///// CHEMA ComposedLayer
562
                // Checks for draw group (ComposedLayer)
563
                if (group != null) {
564
                    if (lyr instanceof FLayers) {
565
                        group = ((FLayers) lyr).print_old(g, viewPort, cancel, scale, properties, group);
566
                    } else {
567
                        // If layer can be added to the group, does it
568
                        if (lyr instanceof ILabelable
569
                                && ((ILabelable) lyr).isLabeled()
570
                                && ((ILabelable) lyr).getLabelingStrategy() != null
571
                                && ((ILabelable) lyr).getLabelingStrategy().shouldDrawLabels(scale)) {
572
                            group.add(lyr);
573
                        } else {
574
                            // draw the 'pending to draw' layer group
575
                            group.print(g, viewPort, cancel, scale, properties);
576

    
577
                            // gets a new group instance
578
                            if (lyr instanceof ILabelable
579
                                    && ((ILabelable) lyr).isLabeled()
580
                                    && ((ILabelable) lyr).getLabelingStrategy() != null
581
                                    && ((ILabelable) lyr).getLabelingStrategy().shouldDrawLabels(scale)) {
582
                                group = lyr.newComposedLayer();
583
                            } else {
584
                                group = null;
585
                            }
586
                            // if layer hasn't group, draws it inmediately
587
                            if (group == null) {
588
                                if (lyr instanceof FLayers) {
589
                                    group = ((FLayers) lyr).print_old(g, viewPort, cancel, scale, properties, group);
590
                                } else {
591
                                    lyr.print(g, viewPort, cancel, scale, properties);
592
                                    if (lyr instanceof ILabelable
593
                                            && ((ILabelable) lyr).isLabeled()
594
                                            && ((ILabelable) lyr).getLabelingStrategy() != null
595
                                            && ((ILabelable) lyr).getLabelingStrategy().shouldDrawLabels(scale)) {
596
                                        ILabelable lLayer = (ILabelable) lyr;
597
                                        lLayer.drawLabels(null, g, viewPort, cancel, scale, dpi);
598
                                    }
599
                                }
600
                            } else {
601
                                // add the layer to the group
602
                                group.setMapContext(fmap);
603
                                group.add(lyr);
604

    
605
                            }
606

    
607
                        }
608
                    }
609
                } else {
610
                    // gets a new group instance
611
                    group = lyr.newComposedLayer();
612
                    // if layer hasn't group, draws it inmediately
613
                    if (group == null) {
614
                        if (lyr instanceof FLayers) {
615
                            group = ((FLayers) lyr).print_old(g, viewPort, cancel, scale, properties, group);
616
                        } else {
617
                            lyr.print(g, viewPort, cancel, scale, properties);
618
                            if (lyr instanceof ILabelable && ((ILabelable) lyr).isLabeled()) {
619
                                ILabelable lLayer = (ILabelable) lyr;
620

    
621
                                lLayer.drawLabels(null, g, viewPort, cancel, scale, dpi);
622
                            }
623
                        }
624
                    } else {
625
                        // add the layer to the group
626
                        group.setMapContext(fmap);
627
                        group.add(lyr);
628

    
629
                    }
630
                }
631
                ///// CHEMA ComposedLayer
632

    
633
            } catch (Exception e) {
634
                String mesg = Messages.getString("error_printing_layer") + " " + lyr.getName() + ": " + e.getMessage();
635
                fmap.addLayerError(mesg);
636
                logger.error(mesg, e);
637
            }
638

    
639
        }
640

    
641
        ///// CHEMA ComposedLayer
642
        if (group != null && this.getParentLayer() == null) {
643
            //si tenemos un grupo pendiente de pintar, pintamos
644
            group.print(g, viewPort, cancel, scale, properties);
645
            group = null;
646

    
647
        }
648
                ///// CHEMA ComposedLayer
649

    
650
                //                if (getVirtualLayers() != null) {
651
        //                        getVirtualLayers().print( g, viewPort, cancel, scale, properties);
652
        //                }
653
        ///// CHEMA ComposedLayer
654
        return group;
655
        ///// CHEMA ComposedLayer
656
    }
657

    
658
    /*
659
     * (non-Javadoc)
660
     * @see com.iver.cit.gvsig.fmap.layers.FLayer#getFullExtent()
661
     */
662
    public Envelope getFullEnvelope() {
663
        Envelope rAux = null;
664
        boolean first = true;
665

    
666
        for (Iterator iter = layers.iterator(); iter.hasNext();) {
667
            FLayer capa = (FLayer) iter.next();
668
            try {
669
                if (first) {
670
                    rAux = (Envelope) capa.getFullEnvelope().clone();
671
                    first = false;
672
                } else {
673
                    rAux.add(capa.getFullEnvelope());
674
                }
675
            } catch (Exception e) {
676
                e.printStackTrace();//TODO hay que revisar para determinar el comportamiento que espera el usuario.
677
            }
678
        }
679

    
680
        return rAux;
681
    }
682

    
683
    /**
684
     * Notifies all listeners associated to this collection of layers, that
685
     * another layer is going to be added or replaced in the internal list of
686
     * layers.
687
     *
688
     * @param e a layer collection event with the new layer
689
     */
690
    protected void callLayerAdding(LayerCollectionEvent event)
691
            throws CancelationException {
692
        ArrayList aux = (ArrayList) layerCollectionListeners.clone();
693
        for (Iterator iter = aux.iterator(); iter.hasNext();) {
694
            ((LayerCollectionListener) iter.next()).layerAdding(event);
695
        }
696
    }
697

    
698
    /**
699
     * Notifies all listeners associated to this collection of layers, that a
700
     * layer is going to be removed from the internal list of layers.
701
     *
702
     * @param event a layer collection event with the layer being removed
703
     *
704
     * @throws CancelationException any exception produced during the
705
     * cancellation of the driver.
706
     */
707
    protected void callLayerRemoving(LayerCollectionEvent event)
708
            throws CancelationException {
709
        ArrayList aux = (ArrayList) layerCollectionListeners.clone();
710
        for (Iterator iter = aux.iterator(); iter.hasNext();) {
711
            ((LayerCollectionListener) iter.next()).layerRemoving(event);
712
        }
713
    }
714

    
715
    /**
716
     * Notifies all listeners associated to this collection of layers, that a
717
     * layer is going to be moved in the internal list of layers.
718
     *
719
     * @param event a layer collection event with the layer being moved, and the
720
     * initial and final positions
721
     *
722
     * @throws CancelationException any exception produced during the
723
     * cancellation of the driver.
724
     */
725
    protected void callLayerMoving(LayerPositionEvent event)
726
            throws CancelationException {
727
        ArrayList aux = (ArrayList) layerCollectionListeners.clone();
728
        for (Iterator iter = aux.iterator(); iter.hasNext();) {
729
            ((LayerCollectionListener) iter.next()).layerMoving(event);
730
        }
731
    }
732

    
733
    /**
734
     * Notifies all listeners associated to this collection of layers, that
735
     * another layer has been added or replaced in the internal list of layers.
736
     *
737
     * @param e a layer collection event with the new layer
738
     */
739
    protected void callLayerAdded(LayerCollectionEvent event) {
740
        ArrayList aux = (ArrayList) layerCollectionListeners.clone();
741
        for (Iterator iter = aux.iterator(); iter.hasNext();) {
742
            ((LayerCollectionListener) iter.next()).layerAdded(event);
743
        }
744
    }
745

    
746
    /**
747
     * Notifies all listeners associated to this collection of layers, that
748
     * another layer has been removed from the internal list of layers.
749
     *
750
     * @param e a layer collection event with the layer removed
751
     */
752
    protected void callLayerRemoved(LayerCollectionEvent event) {
753
        ArrayList aux = (ArrayList) layerCollectionListeners.clone();
754
        for (Iterator iter = aux.iterator(); iter.hasNext();) {
755
            ((LayerCollectionListener) iter.next()).layerRemoved(event);
756
        }
757
    }
758

    
759
    /**
760
     * Notifies all listeners associated to this collection of layers, that
761
     * another layer has been moved in the internal list of layers.
762
     *
763
     * @param e a layer collection event with the layer moved, and the initial
764
     * and final positions
765
     */
766
    protected void callLayerMoved(LayerPositionEvent event) {
767
        ArrayList aux = (ArrayList) layerCollectionListeners.clone();
768
        for (Iterator iter = aux.iterator(); iter.hasNext();) {
769
            ((LayerCollectionListener) iter.next()).layerMoved(event);
770
        }
771
    }
772

    
773
    public void saveToState(PersistentState state) throws PersistenceException {
774

    
775
        super.saveToState(state);
776

    
777
        state.set("mapContext", fmap);
778

    
779
        List layersToSave = new ArrayList();
780
        Iterator iter = this.layers.iterator();
781
        while (iter.hasNext()) {
782
            FLayer layer = (FLayer) iter.next();
783
            if (!layer.isTemporary()) {
784
                layersToSave.add(layer);
785
            }
786
        }
787
        state.set("layers", layersToSave);
788
    }
789

    
790
    public void loadFromState(PersistentState state) throws PersistenceException {
791

    
792
        super.loadFromState(state);
793

    
794
        setMapContext((MapContext) state.get("mapContext"));
795
        Iterator iter = state.getIterator("layers");
796
        while (iter.hasNext()) {
797
            FLayer item = (FLayer) iter.next();
798
            layers.add(item);
799
        }
800
    }
801

    
802
    /*
803
     * (non-Javadoc)
804
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#getMapContext()
805
     */
806
    public MapContext getMapContext() {
807
        return fmap;
808
    }
809

    
810
    /*
811
     * I don't think this implementation makes any sense.
812
     * We can group layers with different transformations,
813
     * we cannot set the ICoordTrans for all (?)
814
     * 
815
     public void setCoordTrans(ICoordTrans ct) {
816
     super.setCoordTrans(ct);
817

818
     for (Iterator iter = layers.iterator(); iter.hasNext();) {
819
     FLayer layer = (FLayer) iter.next();
820
     layer.setCoordTrans(ct);
821
     }
822
     }
823
     */
824
    /*
825
     * (non-Javadoc)
826
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#setAllActives(boolean)
827
     */
828
    public void setAllActives(boolean active) {
829
        FLayer lyr;
830

    
831
        for (int i = 0; i < layers.size(); i++) {
832
            lyr = ((FLayer) layers.get(i));
833
            lyr.setActive(active);
834

    
835
            if (lyr instanceof LayerCollection) {
836
                ((LayerCollection) lyr).setAllActives(active);
837
            }
838
        }
839
    }
840

    
841
    /*
842
     * (non-Javadoc)
843
     * @see com.iver.cit.gvsig.fmap.layers.layerOperations.LayerCollection#getActives()
844
     */
845
    public FLayer[] getActives() {
846
        ArrayList ret = new ArrayList();
847
        LayersIterator it = new LayersIterator(this) {
848

    
849
            public boolean evaluate(FLayer layer) {
850
                return layer.isActive();
851
            }
852

    
853
        };
854

    
855
        while (it.hasNext()) {
856
            ret.add(it.next());
857
        }
858
        return (FLayer[]) ret.toArray(new FLayer[0]);
859
    }
860

    
861
    /*
862
     * (non-Javadoc)
863
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#getMinScale()
864
     */
865
    public double getMinScale() {
866
        return -1; // La visibilidad o no la controla cada capa
867
        // dentro de una colecci?n
868
    }
869
    /*
870
     * (non-Javadoc)
871
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#getMaxScale()
872
     */
873

    
874
    public double getMaxScale() {
875
        return -1;
876
    }
877
    /*
878
     * (non-Javadoc)
879
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setMinScale(double)
880
     */
881

    
882
    public void setMinScale(double minScale) {
883
        for (Iterator iter = layers.iterator(); iter.hasNext();) {
884
            FLayer lyr = (FLayer) iter.next();
885
            lyr.setMinScale(minScale);
886
        }
887
    }
888
    /*
889
     * (non-Javadoc)
890
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setMaxScale(double)
891
     */
892

    
893
    public void setMaxScale(double maxScale) {
894
        for (Iterator iter = layers.iterator(); iter.hasNext();) {
895
            FLayer lyr = (FLayer) iter.next();
896
            lyr.setMinScale(maxScale);
897
        }
898
    }
899
    /*
900
     * (non-Javadoc)
901
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#setActive(boolean)
902
     */
903

    
904
    public void setActive(boolean b) {
905
        super.setActive(b);
906
        for (int i = 0; i < layers.size(); i++) {
907
            ((FLayer) layers.get(i)).setActive(b);
908
        }
909
    }
910
    /* (non-Javadoc)
911
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#addLayerListener(com.iver.cit.gvsig.fmap.layers.LayerListener)
912
     */
913

    
914
    public boolean addLayerListener(LayerListener o) {
915
        for (int i = 0; i < layers.size(); i++) {
916
            ((FLayer) layers.get(i)).addLayerListener(o);
917
        }
918
        return true;
919
    }
920

    
921
    public DynObjectSet getInfo(Point p, double tolerance,
922
            Cancellable cancel) throws LoadLayerException, DataException {
923
        return getInfo(this.getMapContext().getViewPort().convertToMapPoint(p), tolerance);
924
    }
925

    
926
    public DynObjectSet getInfo(Point p, double tolerance, Cancellable cancel,
927
            boolean fast) throws LoadLayerException, DataException {
928
        return getInfo(this.getMapContext().getViewPort().convertToMapPoint(p), tolerance);
929
    }
930

    
931
    public DynObjectSet getInfo(org.gvsig.fmap.geom.primitive.Point p,
932
            double tolerance) throws LoadLayerException, DataException {
933
        int i;
934
        FLayer layer;
935
        List res = new ArrayList();
936
        for (i = 0; i < this.layers.size(); i++) {
937
            layer = (FLayer) layers.get(i);
938
            if (layer instanceof InfoByPoint) {
939
                InfoByPoint queryable_layer = (InfoByPoint) layer;
940
                res.add(queryable_layer.getInfo(p, tolerance));
941
            }
942
        }
943
        DynObjectSet[] innerSets
944
                = (DynObjectSet[]) res.toArray(new DynObjectSet[res.size()]);
945
        return new MultiDynObjectSet(innerSets);
946
    }
947

    
948
    /*
949
     * (non-Javadoc)
950
     * @see com.iver.cit.gvsig.fmap.layers.FLyrDefault#getTocImageIcon()
951
     */
952
    public String getTocImageIcon() {
953
        return "layer-icon-group";
954
    }
955

    
956
    /**
957
     * <p>
958
     * Adds the layer with the information in an XML entity and the specified
959
     * name, to this collection of layers. And returns <code>true</code> if
960
     * there hasn't been errors.</p>
961
     *
962
     * @see CopyOfFLayers#addLayerFromXML(XMLEntity, String)
963
     *
964
     * @param xml tree-node structure with information about layers
965
     * @param name name of the layer to add
966
     * @return <code>true</code> if there were no errors adding the layer,
967
     * <code>false</code> otherwise
968
     *
969
     * @throws LoadLayerException if fails loading this layer.
970
     */
971
        //        public boolean addLayerFromXMLEntity(XMLEntity xml, String name) throws LoadLayerException {
972
    //                fmap.clearErrors();
973
    //                this.addLayerFromXML(xml,name);
974
    //
975
    //                return (fmap.getLayersError().size() == 0);
976
    //
977
    //        }
978
//        /**
979
//         * <p>Adds the layer with the information in an XML entity and the specified name, to this collection of layers.</p>
980
//         *
981
//         * <p>This method really executes the addition, considering the kind of layer (<code>FLyrVect</code>,
982
//         *  <code>FLyrAnnotation</code>, <code>FLyrRaster</code>, a collection of layers (<code>FLayers</code>),
983
//         *  or another kind of layer (<code>FLayer</code>)), and the driver in the layer.</p>
984
//         *
985
//         * @param xml tree-node structure with information about layers
986
//         * @param name name of the layer to add
987
//         *
988
//         * @throws LoadLayerException if fails loading this layer.
989
//         */
990
//        private void addLayerFromXML(XMLEntity xml, String name) throws LoadLayerException {
991
//                FLayer layer = null;
992
//
993
//                try {
994
//                        if (name == null) {
995
//                                name = xml.getName();
996
//                        }
997
//
998
//
999
//                        String className = xml.getStringProperty("className");
1000
//                        Class clase = Class.forName(className);
1001
//                        layer = (FLayer) clase.newInstance();
1002
//                        if (FLayers.class.isAssignableFrom(clase)) {
1003
//                                ((FLayers)layer).setMapContext(getMapContext());
1004
//                                ((FLayers)layer).setParentLayer(this);
1005
//                                //                        layer = new FLayers(getMapContext(),this);
1006
//                                layer.setXMLEntity(xml);
1007
//                        } else {
1008
//                                // Capas Nuevas (externas)
1009
//                                layer.setName(name);
1010
//                                layer.setXMLEntity(xml);
1011
//                                layer.load();
1012
//                        }
1013
//
1014
//                        //                //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,
1015
//                        //                //ya que los drivers de una FLyrAnnotation no sabemos cual es puede ser cualquier Driver Vectorial.
1016
//                        //                if (className.equals(FLyrVect.class.getName())){// || className.equals(FLyrAnnotation.class.getName())) {
1017
//                        //                        String type = xml.getStringProperty("type");
1018
//                        //                        if ("vectorial".equals(type)){
1019
//                        //                                //String recordsetName = xml.getChild(i).getStringProperty("recordset-name");
1020
//                        //                                IProjection proj = null;
1021
//                        //                                if (xml.contains("proj")) {
1022
//                        //                                        proj = CRSFactory.getCRS(xml.getStringProperty("proj"));
1023
//                        //                                }
1024
//                        //                                else
1025
//                        //                                {
1026
//                        //                                        proj = this.getMapContext().getViewPort().getProjection();
1027
//                        //                                }
1028
//                        //                                if (xml.contains("file")) {
1029
//                        //                                        Driver d;
1030
//                        //                                        try {
1031
//                        //                                                d = LayerFactory.getDM().getDriver(xml.getStringProperty("driverName"));
1032
//                        //                                        } catch (DriverLoadException e1) {
1033
//                        //                                                throw new DriverLayerException(name,e1);
1034
//                        //                                        }
1035
//                        //                                        layer = LayerFactory.createLayer(name, (VectorialFileDriver) d,
1036
//                        //                                                        new File(xml.getStringProperty("file")),
1037
//                        //                                                        proj);
1038
//                        //
1039
//                        //
1040
//                        //                                }
1041
//                        //                                if (xml.contains("db")) {
1042
//                        //
1043
//                        //                                        String driverName = xml.getStringProperty("db");
1044
//                        //                                        IVectorialDatabaseDriver driver;
1045
//                        //                                        try {
1046
//                        //                                                driver = (IVectorialDatabaseDriver) LayerFactory.getDM().getDriver(driverName);
1047
//                        //                                                //Hay que separar la carga de los datos del XMLEntity del load.
1048
//                        //                                                driver.setXMLEntity(xml.getChild(2));
1049
//                        //
1050
//                        //                                                boolean loadOk = false;
1051
//                        //                                                ((DefaultJDBCDriver)driver).load();
1052
//                        //                                                if (((DefaultJDBCDriver)driver).getConnection() != null) {
1053
//                        //                                                        loadOk = true;
1054
//                        //                                                }
1055
//                        //                                                layer = LayerFactory.createDBLayer(driver, name, proj);
1056
//                        //                                                if (!loadOk) {
1057
//                        //                                                        layer.setAvailable(false);
1058
//                        //                                                }
1059
//                        //
1060
//                        //                                        } catch (DriverLoadException e) {
1061
//                        //                                                throw new DriverLayerException(name,e);
1062
//                        //                                        } catch (XMLException e) {
1063
//                        //                                                throw new DriverLayerException(name,e);
1064
//                        //                                        } catch (ReadException e) {
1065
//                        //                                                throw new DriverLayerException(name,e);
1066
//                        //                                        }
1067
//                        //
1068
//                        //                                }
1069
//                        //                                // Clases con algun driver gen?rico creado por otro
1070
//                        //                                // programador
1071
//                        //                                if (xml.contains("other")) {
1072
//                        //
1073
//                        //                                        String driverName = xml.getStringProperty("other");
1074
//                        //                                        VectorialDriver driver = null;
1075
//                        //                                        try {
1076
//                        //                                                driver = (VectorialDriver) LayerFactory.getDM().getDriver(driverName);
1077
//                        //                                        } catch (DriverLoadException e) {
1078
//                        //                                                // Si no existe ese driver, no pasa nada.
1079
//                        //                                                // Puede que el desarrollador no quiera que
1080
//                        //                                                // aparezca en el cuadro de di?logo y ha metido
1081
//                        //                                                // el jar con sus clases en nuestro directorio lib.
1082
//                        //                                                // Intentamos cargar esa clase "a pelo".
1083
//                        //                                                if (xml.getChild(2).contains("className"))
1084
//                        //                                                {
1085
//                        //                                                        String className2 = xml.getChild(2).getStringProperty("className");
1086
//                        //                                                        try {
1087
//                        //                                                                driver = (VectorialDriver) Class.forName(className2).newInstance();
1088
//                        //                                                        } catch (Exception e1) {
1089
//                        //                                                                throw new DriverLayerException(name,e);
1090
//                        //                                                        }
1091
//                        //                                                }
1092
//                        //                                        } catch (NullPointerException npe) {
1093
//                        //                                                // Si no existe ese driver, no pasa nada.
1094
//                        //                                                // Puede que el desarrollador no quiera que
1095
//                        //                                                // aparezca en el cuadro de di?logo y ha metido
1096
//                        //                                                // el jar con sus clases en nuestro directorio lib.
1097
//                        //                                                // Intentamos cargar esa clase "a pelo".
1098
//                        //                                                if (xml.getChild(2).contains("className"))
1099
//                        //                                                {
1100
//                        //                                                        String className2 = xml.getChild(2).getStringProperty("className");
1101
//                        //                                                        try {
1102
//                        //                                                                driver = (VectorialDriver) Class.forName(className2).newInstance();
1103
//                        //                                                        } catch (Exception e1) {
1104
//                        //                                                                throw new DriverLayerException(name,e1);
1105
//                        //                                                        }
1106
//                        //                                                }
1107
//                        //                                        }
1108
//                        //                                        if (driver instanceof IPersistence)
1109
//                        //                                        {
1110
//                        //                                                IPersistence persist = (IPersistence) driver;
1111
//                        //                                                persist.setXMLEntity(xml.getChild(2));
1112
//                        //                                        }
1113
//                        //                                        layer = LayerFactory.createLayer(name, driver, proj);
1114
//                        //                                }
1115
//                        //
1116
//                        //                        }
1117
//                        //
1118
//                        //                        //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,
1119
//                        //                        //ya que los drivers de una FLyrAnnotation no sabemos cual es puede ser cualquier Driver Vectorial.
1120
//                        //                        if (className.equals(FLyrAnnotation.class.getName())){
1121
//                        //                                layer=FLyrAnnotation.createLayerFromVect((FLyrVect)layer);
1122
//                        //                        }
1123
//                        //
1124
//                        //
1125
//                        //                        layer.setXMLEntity(xml);
1126
//                        //
1127
//                        //                } else {
1128
//                        //                        Class clase = LayerFactory.getLayerClassForLayerClassName(className);
1129
//                        //                        layer = (FLayer) clase.newInstance();
1130
//                        //                        if (clase.isAssignableFrom(FLayers.class)) {
1131
//                        //                                ((FLayers)layer).setMapContext(getMapContext());
1132
//                        //                                ((FLayers)layer).setParentLayer(this);
1133
//                        ////                                layer = new FLayers(getMapContext(),this);
1134
//                        //                                layer.setXMLEntity(xml);
1135
//                        //                        } else {
1136
//                        //                                // Capas Nuevas (externas)
1137
//                        //                                layer.setName(name);
1138
//                        //                                layer.setXMLEntity(xml);
1139
//                        //                                layer.load();
1140
//                        //                        }
1141
//                        //                }
1142
//                        this.addLayer(layer);
1143
//                        logger.debug("layer: "+ layer.getName() +" loaded");
1144
//                        // Comprobar que la proyecci?n es la misma que la de FMap
1145
//                        // Si no lo es, es una capa que est? reproyectada al vuelo
1146
//                        IProjection proj = layer.getProjection();
1147
//                        if ((proj != null)) {
1148
//                                if (!proj.getFullCode().equals(getMapContext().getProjection().getFullCode()))
1149
//                                {
1150
//                                        ICoordTrans ct = proj.getCT(getMapContext().getProjection());
1151
//                                        // TODO: REVISAR CON LUIS
1152
//                                        // Se lo fijamos a todas, luego cada una que se reproyecte
1153
//                                        // si puede, o que no haga nada
1154
//
1155
//                                        layer.setCoordTrans(ct);
1156
//                                }
1157
//                        }
1158
//                } catch (XMLException e) {
1159
//                        fmap.addLayerError(xml.getStringProperty("name"));
1160
//                        throw new LoadLayerException(name,e);
1161
//                } catch (ClassNotFoundException e) {
1162
//                        fmap.addLayerError(xml.getStringProperty("name"));
1163
//                        throw new LoadLayerException(name,e);
1164
//                } catch (InstantiationException e) {
1165
//                        fmap.addLayerError(xml.getStringProperty("name"));
1166
//                        throw new LoadLayerException(name,e);
1167
//                } catch (IllegalAccessException e) {
1168
//                        fmap.addLayerError(xml.getStringProperty("name"));
1169
//                        throw new LoadLayerException(name,e);
1170
//                } catch (LoadLayerException e){
1171
//                        fmap.addLayerError(xml.getStringProperty("name"));
1172
//                        throw e;
1173
//                }
1174
//        }
1175
    /**
1176
     * <p>
1177
     * Sets the <code>MapContext</code> that contains this layer node.</p>
1178
     *
1179
     * @param mapContext the <code>MapContext</code> that contains this layer
1180
     * node
1181
     */
1182
    public void setMapContext(MapContext mapContext) {
1183
        this.fmap = mapContext;
1184
    }
1185

    
1186
//        /**
1187
//         * <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
1188
//         *  and loads the layer. Then, adds the layer to this collection of layers, and if there is a projection defined,
1189
//         *  inserts the transformation coordinates to the layer.</p>
1190
//         *
1191
//         * <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>
1192
//         *
1193
//         * @param xml tree-node structure with information about layers
1194
//         * @param name name of the layer to add
1195
//         */
1196
//        private void addLayerFromXMLNew(XMLEntity xml, String name) {
1197
//                //                FLayer layer = null;
1198
//                //
1199
//                //
1200
//                //                try {
1201
//                //                        String className = xml.getStringProperty("className");
1202
//                //                        Class clazz = Class.forName(className);
1203
//                //                        if (clazz.isAssignableFrom(FLayers.class)) {
1204
//                //                                layer = (FLayer) clazz.newInstance();
1205
//                //                                ((FLayers)layer).setMapContext(getMapContext());
1206
//                //                                ((FLayers)layer).setParentLayer(this);
1207
//                //        //                if (className.equals((FLayers.class.getName()))){
1208
//                //        //                        layer = new FLayers(getMapContext(),this);
1209
//                //                        } else {
1210
//                //        //                        Por compatibilidad
1211
//                //                                if (className.equals(FLyrVect.class.getName())) {
1212
//                //                                        if (xml.contains("file")) {
1213
//                //                                                layer = new FLayerFileVectorial();
1214
//                //                                        } else if (xml.contains("db")) {
1215
//                //                                                try {
1216
//                //                                                        layer = (FLayer)((ExtensionPoint)ExtensionPointsSingleton.getInstance().get("Layers")).create("com.iver.cit.gvsig.fmap.layers.FLayerJDBCVectorial");
1217
//                //                                                } catch (Exception e) {
1218
//                //                                                        throw new XMLException(new Exception("No se tiene registrada la capa de tipo JDBC"));
1219
//                //                                                }
1220
//                //                                                //className = FLayerJDBCVectorial.class.getName();
1221
//                //                                        } else if (xml.contains("other")){
1222
//                //                                                layer = new FLayerGenericVectorial();
1223
//                //                                        } else {
1224
//                //                                                throw new XMLException(new Exception("Capa vectorial de tipo no reconocido"));
1225
//                //                                        }
1226
//                //        //                                Fin por compatibilidad
1227
//                //                                } else {
1228
//                //                                        try {
1229
//                //                                                layer = (FLayer)(((ExtensionPoint)ExtensionPointsSingleton.getInstance().get("Layers")).create(className));
1230
//                //                                        } catch (Exception e) {
1231
//                //                                                //puende que no este registrada como punto de extension
1232
//                //                                                Class clase = Class.forName(className);
1233
//                //                                                layer = (FLayer) clase.newInstance();
1234
//                //                                                // FIXME: Hacemos algo aqui o dejamos que suba el error?
1235
//                //                                        }
1236
//                //                                }
1237
//                //
1238
//                //                        }
1239
//                //                        layer.setXMLEntity(xml);
1240
//                //                        if (name != null) layer.setName(name);
1241
//                //                        layer.load();
1242
//                //
1243
//                //                        this.addLayer(layer);
1244
//                //                        logger.debug("layer: "+ layer.getName() +" loaded");
1245
//                //                        // Comprobar que la proyecci?n es la misma que la de FMap
1246
//                //                        // Si no lo es, es una capa que est? reproyectada al vuelo
1247
//                //                        IProjection proj = layer.getProjection();
1248
//                //                        if ((proj != null))
1249
//                //                                if (proj != getMapContext().getProjection())
1250
//                //                                {
1251
//                //                                        ICoordTrans ct = proj.getCT(getMapContext().getProjection());
1252
//                //                                        // TODO: REVISAR CON LUIS
1253
//                //                                        // Se lo fijamos a todas, luego cada una que se reproyecte
1254
//                //                                        // si puede, o que no haga nada
1255
//                //                                        layer.setCoordTrans(ct);
1256
//                //
1257
//                //                                }
1258
//                //                }catch (Exception e) {
1259
//                //                        fmap.addLayerError(xml.getStringProperty("name"));
1260
//                //                        logger.debug(Messages.getString("could_not_load_layer")+": "+xml.getStringProperty("name") + ".\n"
1261
//                //                                        +Messages.getString("reason")+":", e);
1262
//                //                }
1263
//        }
1264
    public void accept(Visitor visitor) throws BaseException {
1265
        for (int i = 0; i < this.getLayersCount(); i++) {
1266
            FLayer layer = this.getLayer(i);
1267
            try {
1268
                if (layer instanceof LayersVisitable) {
1269
                    ((LayersVisitable) layer).accept(visitor);
1270
                } else {
1271
                    visitor.visit(layer);
1272
                }
1273
            } catch (VisitCanceledException ex) {
1274
                break;
1275
            }
1276
        }
1277
    }
1278

    
1279
    public void accept(LayersVisitor visitor) throws BaseException {
1280
        for (int i = 0; i < this.getLayersCount(); i++) {
1281
            FLayer layer = this.getLayer(i);
1282
            if (layer instanceof LayersVisitable) {
1283
                ((LayersVisitable) layer).accept(visitor);
1284
            } else {
1285
                visitor.visit(layer);
1286
            }
1287
        }
1288
    }
1289

    
1290
    /*
1291
     * (non-Javadoc)
1292
     *
1293
     * @see org.gvsig.metadata.Metadata#getMetadataID()
1294
     */
1295
    public Object getMetadataID() throws MetadataException {
1296
        StringBuffer strb = new StringBuffer();
1297
        strb.append("Layers(");
1298
        strb.append(this.getName());
1299
        strb.append("):{");
1300
        Iterator iter = this.layers.iterator();
1301
        while (iter.hasNext()) {
1302
            strb.append(((FLayer) iter.next()).getMetadataID());
1303
            strb.append(",");
1304
        }
1305
        strb.append("}");
1306
        return strb.toString();
1307

    
1308
    }
1309

    
1310
    /*
1311
     * (non-Javadoc)
1312
     *
1313
     * @see org.gvsig.metadata.Metadata#getMetadataChildren()
1314
     */
1315
    public Set getMetadataChildren() {
1316
        Set ret = new TreeSet();
1317
        Iterator iter = this.layers.iterator();
1318
        while (iter.hasNext()) {
1319
            ret.add(iter.next());
1320
        }
1321
        return ret;
1322
    }
1323

    
1324
    /*
1325
     * (non-Javadoc)
1326
     *
1327
     * @see org.gvsig.metadata.Metadata#getMetadataName()
1328
     */
1329
    public String getMetadataName() throws MetadataException {
1330
        StringBuffer strb = new StringBuffer();
1331
        strb.append("Layer Group '");
1332
        strb.append(this.getName());
1333
        strb.append("': {");
1334
        Iterator iter = this.layers.iterator();
1335
        while (iter.hasNext()) {
1336
            strb.append(((FLayer) iter.next()).getMetadataName());
1337
            strb.append(",");
1338
        }
1339
        strb.append("}");
1340
        return strb.toString();
1341
    }
1342

    
1343
    public void beginDraw(Graphics2D g, ViewPort viewPort) {
1344
        LayerDrawEvent beforeEvent = new LayerDrawEvent(this, g, viewPort, LayerDrawEvent.LAYER_BEFORE_DRAW);
1345
        fmap.fireLayerDrawingEvent(beforeEvent);
1346
    }
1347

    
1348
    public void endDraw(Graphics2D g, ViewPort viewPort) {
1349
        LayerDrawEvent afterEvent = new LayerDrawEvent(this, g, viewPort, LayerDrawEvent.LAYER_AFTER_DRAW);
1350
        fmap.fireLayerDrawingEvent(afterEvent);
1351
    }
1352

    
1353
    public static class RegisterPersistence implements Callable {
1354

    
1355
        public Object call() {
1356

    
1357
            PersistenceManager manager = ToolsLocator.getPersistenceManager();
1358
            DynStruct definition = manager.addDefinition(
1359
                    FLayers.class,
1360
                    "FLayers",
1361
                    "FLayers Persistence definition",
1362
                    null,
1363
                    null
1364
            );
1365
            definition.extend(PersistenceManager.PERSISTENCE_NAMESPACE, "FLyrDefault");
1366

    
1367
            definition.addDynFieldObject("mapContext").setClassOfValue(MapContext.class).setMandatory(true);
1368
            definition.addDynFieldList("layers").setClassOfItems(FLayer.class).setMandatory(true);
1369

    
1370
            return Boolean.TRUE;
1371
        }
1372
    }
1373

    
1374
    protected void doDispose() throws BaseException {
1375
        if (layers != null) {
1376
            for (int i = 0; i < layers.size(); i++) {
1377
                dispose((Disposable) layers.get(i));
1378
            }
1379
        }
1380
    }
1381

    
1382
    public void move(FLayer layer, LayerCollection group, int where, FLayer adjoiningLayer) throws LayerNotFoundInCollectionException {
1383

    
1384
        callLayerRemoving(LayerCollectionEvent.createLayerRemovingEvent(layer));
1385
        group.addLayer(layer, where, adjoiningLayer);
1386
        removeLayer(layer);
1387
        this.updateDrawVersion();
1388
        callLayerRemoved(LayerCollectionEvent.createLayerRemovedEvent(layer));
1389

    
1390
    }
1391

    
1392
    public void join(FLayer layer, LayerCollection group) {
1393
        try {
1394
            layers.remove(layer);
1395
            group.addLayer(layer, END, null);
1396
            this.updateDrawVersion();
1397
        } catch (LayerNotFoundInCollectionException e) {
1398
            throw new MapContextRuntimeException(e);
1399
        }
1400
    }
1401

    
1402
    public void move(FLayer layer, LayerCollection group) {
1403
        try {
1404
            move(layer, group, END, null);
1405
        } catch (LayerNotFoundInCollectionException e) {
1406
            throw new MapContextRuntimeException(e);
1407
        }
1408
    }
1409

    
1410
    public void addLayer(FLayer layer, int where, FLayer adjoiningLayer)
1411
            throws LayerNotFoundInCollectionException {
1412

    
1413
        switch (where) {
1414
            case BEGIN:
1415
                addLayer(0, layer);
1416
                break;
1417
            case BEFORE:
1418
                if (adjoiningLayer != null) {
1419
                    if (this.layers.contains(adjoiningLayer)) {
1420
                        for (int i = 0; i < this.getLayersCount(); i++) {
1421
                            if (adjoiningLayer == this.getLayer(i)) {
1422
                                addLayer(i, layer);
1423
                                break;
1424
                            }
1425
                        }
1426
                    } else {
1427
                        throw new LayerNotFoundInCollectionException(adjoiningLayer, this);
1428
                    }
1429
                } else {
1430
                    addLayer(0, layer);
1431
                }
1432
                break;
1433
            case AFTER:
1434
                if (adjoiningLayer != null) {
1435
                    if (this.layers.contains(adjoiningLayer)) {
1436
                        for (int i = 0; i < this.getLayersCount(); i++) {
1437
                            if (adjoiningLayer == this.getLayer(i)) {
1438
                                addLayer(i + 1, layer);
1439
                                break;
1440
                            }
1441
                        }
1442
                    } else {
1443
                        throw new LayerNotFoundInCollectionException(adjoiningLayer, this);
1444
                    }
1445
                } else {
1446
                    this.addLayer(layer);
1447
                }
1448
                break;
1449
            default: // By default add layer an the end of the collection
1450
                this.addLayer(layer);
1451
                break;
1452
        }
1453

    
1454
    }
1455

    
1456
}