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 / FLyrDefault.java @ 40559

History | View | Annotate | Download (28 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
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.fmap.mapcontext.layers;
25

    
26
import java.awt.Image;
27
import java.awt.geom.Point2D;
28
import java.net.URI;
29
import java.util.ArrayList;
30
import java.util.Hashtable;
31
import java.util.Iterator;
32
import java.util.List;
33
import java.util.Map;
34

    
35
import org.cresques.cts.ICoordTrans;
36
import org.cresques.cts.IProjection;
37
import org.gvsig.fmap.dal.DataTypes;
38
import org.gvsig.fmap.dal.exception.ReadException;
39
import org.gvsig.fmap.geom.primitive.Envelope;
40
import org.gvsig.fmap.mapcontext.MapContext;
41
import org.gvsig.fmap.mapcontext.MapContextLocator;
42
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
43
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
44
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
45
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
46
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
47
import org.gvsig.fmap.mapcontext.rendering.legend.events.listeners.LegendListener;
48
import org.gvsig.metadata.MetadataContainer;
49
import org.gvsig.metadata.MetadataLocator;
50
import org.gvsig.metadata.MetadataManager;
51
import org.gvsig.metadata.exceptions.MetadataException;
52
import org.gvsig.tools.ToolsLocator;
53
import org.gvsig.tools.dispose.impl.AbstractDisposable;
54
import org.gvsig.tools.dynobject.DynClass;
55
import org.gvsig.tools.dynobject.DynObject;
56
import org.gvsig.tools.dynobject.DynStruct;
57
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
58
import org.gvsig.tools.dynobject.exception.DynMethodException;
59
import org.gvsig.tools.exception.BaseException;
60
import org.gvsig.tools.persistence.PersistenceManager;
61
import org.gvsig.tools.persistence.PersistentState;
62
import org.gvsig.tools.persistence.exception.PersistenceException;
63
import org.slf4j.LoggerFactory;
64

    
65

    
66

    
67
/**
68
 * <p>Implementation of the common characteristics of all layers: visibility, activation, name, ...</p>
69
 *
70
 * <p>Represents the definition of a basic layer, implementing {@link FLayer FLayer}, and new functionality:
71
 * <ul>
72
 *  <li>Supports transparency.
73
 *  <li>Notification of evens produced using this layer.
74
 *  <li>Can have internal virtual layers.
75
 *  <li>Can have a text layer.
76
 *  <li>Supports an strategy for visit its geometries.
77
 *  <li>Can have an image in the <i>TOC (table of contents)</i> associated to the state of this layer.
78
 * </ul>
79
 * </p>
80
 *
81
 * <p>Each graphical layer will inherit from this class and adapt to its particular logic and model according
82
 *  its nature.</p>
83
 *
84
 * @see FLayer
85
 * @see FLayerStatus
86
 */
87
public abstract class FLyrDefault extends AbstractDisposable implements FLayer, FLayerHidesArea,
88
                LayerListener {
89
        /**
90
         * Useful for debug the problems during the implementation.
91
         */
92
        final static private org.slf4j.Logger logger = LoggerFactory.getLogger(FLyrDefault.class);
93

    
94
        private LayerChangeSupport layerChangeSupport = new LayerChangeSupport();
95

    
96
        /**
97
         * Path to the upper layer which this layer belongs.
98
         *
99
         * @see #getParentLayer()
100
         * @see #setParentLayer(FLayers)
101
         */
102
        private FLayers parentLayer = null;
103

    
104
        /**
105
         * Transparency level of this layer in the range 0-255. By default 255.
106
         * 0   --> Transparent
107
         * 255 --> Opaque
108
         *
109
         * @see #getTransparency()
110
         * @see #setTransparency(int)
111
         */
112
        private int transparency = 255;
113

    
114
        /**
115
         * Coordinate transformation.
116
         *
117
         * @see #getCoordTrans()
118
         * @see #setCoordTrans(ICoordTrans)
119
         */
120
        private ICoordTrans ct;
121

    
122
        /**
123
         * Minimum scale, >= 0 or -1 if not defined. By default -1.
124
         *
125
         * @see #getMinScale()
126
         * @see #setMinScale(double)
127
         */
128
        private double minScale = -1; // -1 indica que no se usa
129

    
130
        /**
131
         * Maximum scale, >= 0 or -1 if not defined. By default -1.
132
         *
133
         * @see #getMaxScale()
134
         * @see #setMaxScale(double)
135
         */
136
        private double maxScale = -1;
137
        //        private boolean isInTOC = true;
138

    
139
        /**
140
         * Array list with all listeners registered to this layer.
141
         *
142
         * @see #getLayerListeners()
143
         * @see #removeLayerListener(LayerListener)
144
         * @see #callEditionChanged(LayerEvent)
145
         */
146
        protected ArrayList layerListeners = new ArrayList();
147

    
148

    
149
        /**
150
         * Hash table with the extended properties of this layer.
151
         *
152
         * @see #getProperty(Object)
153
         * @see #setProperty(Object, Object)
154
         * @see #getExtendedProperties()
155
         */
156
        private Map properties = new Hashtable();
157

    
158
        //by default, all is active, visible and avalaible
159
        /**
160
         * Status of this layer.
161
         *
162
         * @see #getFLayerStatus()
163
         * @see #setFLayerStatus(FLayerStatus)
164
         * @see #isActive()
165
         * @see #setActive(boolean)
166
         * @see #isVisible()
167
         * @see #setVisible(boolean)
168
         * @see #visibleRequired()
169
         * @see #isEditing()
170
         * @see #setEditing(boolean)
171
         * @see #isInTOC()
172
         * @see #isCachingDrawnLayers()
173
         * @see #setCachingDrawnLayers(boolean)
174
         * @see #isDirty()
175
         * @see #setDirty(boolean)
176
         * @see #isAvailable()
177
         * @see #setAvailable(boolean)
178
         * @see #isOk()
179
         * @see #isWritable()
180
         * @see #getNumErrors()
181
         * @see #getError(int)
182
         * @see #getErrors()
183
         * @see #addError(BaseException)
184
         */
185
        private FLayerStatus status = new FLayerStatus();
186
        /**
187
         * Image drawn shown in the TOC according the status of this layer.
188
         *
189
         * @see #getTocStatusImage()
190
         * @see #setTocStatusImage(Image)
191
         */
192
        private Image tocStatusImage;
193

    
194
        protected MetadataContainer metadataContainer;
195

    
196
        /**
197
         * Draw version of the context. It's used for know when de componend has
198
         * changed any visualization property
199
         *
200
         *  @see getDrawVersion
201
         *  @see updateDrawVersion
202
         */
203
        private long drawVersion= 0L;
204

    
205
        public FLyrDefault(MetadataContainer metadataContainer) {
206
                this.metadataContainer = metadataContainer;
207
        }
208

    
209
        public FLyrDefault() {
210
                this(MetadataLocator
211
                        .getMetadataManager()
212
                                .createMetadataContainer(FLayer.METADATA_DEFINITION_NAME)
213
                );
214
        }
215

    
216

    
217
        /*
218
         * (non-Javadoc)
219
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperty(java.lang.Object)
220
         */
221
        public Object getProperty(Object key) {
222
                return properties.get(key);
223
        }
224
        /*
225
         * (non-Javadoc)
226
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setProperty(java.lang.Object, java.lang.Object)
227
         */
228
        public void setProperty(Object key, Object val) {
229
                properties.put(key, val);
230
        }
231
        /*
232
         * (non-Javadoc)
233
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getExtendedProperties()
234
         */
235
        public Map getExtendedProperties() {
236
                return properties;
237
        }
238
        /*
239
         * (non-Javadoc)
240
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setActive(boolean)
241
         */
242
        public void setActive(boolean selected) {
243
                status.active = selected;
244
                callActivationChanged(LayerEvent.createActivationChangedEvent(this,
245
                "active"));
246
        }
247

    
248
        /*
249
         * (non-Javadoc)
250
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isActive()
251
         */
252
        public boolean isActive() {
253
                return status.active;
254
        }
255

    
256
        /*
257
         * (non-Javadoc)
258
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setName(java.lang.String)
259
         */
260
        public void setName(String name) {
261
                this.metadataContainer.setDynValue(METADATA_NAME, name);
262
                callNameChanged(LayerEvent.createNameChangedEvent(this, "name"));
263
        }
264

    
265
        /*
266
         * (non-Javadoc)
267
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getName()
268
         */
269
        public String getName() {
270
                return (String) this.metadataContainer.getDynValue(METADATA_NAME);
271
        }
272

    
273
        /*
274
         * (non-Javadoc)
275
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#load()
276
         */
277
        public void load() throws LoadLayerException {
278
            MetadataManager manager = MetadataLocator.getMetadataManager();
279
            try {
280
            manager.loadMetadata(this);
281
        } catch (MetadataException e) {
282
            throw new LoadLayerException("Can't load metadata." , e );
283
        }
284
        }
285

    
286
        /*
287
         * (non-Javadoc)
288
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setVisible(boolean)
289
         */
290
        public void setVisible(boolean visibility) {
291
                if (status.visible != visibility){
292
                        status.visible = visibility;
293
                        this.updateDrawVersion();
294

    
295
                        //                        if (this.getMapContext() != null){
296
                        //                                this.getMapContext().clearAllCachingImageDrawnLayers();
297
                        //                        }
298
                        callVisibilityChanged(LayerEvent.createVisibilityChangedEvent(this,
299
                        "visible"));
300
                }
301
        }
302

    
303

    
304
        /*
305
         * (non-Javadoc)
306
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isVisible()
307
         */
308
        public boolean isVisible() {
309
                return status.visible && status.available;
310
        }
311

    
312
        /*
313
         * (non-Javadoc)
314
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getParentLayer()
315
         */
316
        public FLayers getParentLayer() {
317
                return parentLayer;
318
        }
319

    
320

    
321
        /*
322
         * (non-Javadoc)
323
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setParentLayer(com.iver.cit.gvsig.fmap.layers.FLayers)
324
         */
325
        public void setParentLayer(FLayers root) {
326
                if (this.parentLayer != root){
327
                        this.parentLayer = root;
328
                        this.updateDrawVersion();
329
                }
330
        }
331

    
332
        /**
333
         * <p>Inserts the projection to this layer.</p>
334
         *
335
         * @param proj information about the new projection
336
         *
337
         * @see #isReprojectable()
338
         * @see #reProject(MapControl)
339
         */
340
        public void setProjection(IProjection proj) {
341
                IProjection curProj = this.getProjection();
342
                if (curProj == proj) {
343
                        return;
344
                }
345
                if (curProj != null && curProj.equals(proj)){
346
                        return;
347
                }
348
                this.updateDrawVersion();
349
                this.metadataContainer.setDynValue(METADATA_CRS, proj);
350
                // Comprobar que la proyecci?n es la misma que la de FMap
351
                // Si no lo es, es una capa que est? reproyectada al vuelo
352
                if ((proj != null) && (getMapContext() != null)) {
353
                        if (proj != getMapContext().getProjection()) {
354
                                ICoordTrans ct = proj.getCT(getMapContext().getProjection());
355
                                setCoordTrans(ct);
356
                                logger.debug("Cambio proyecci?n: FMap con "
357
                                                + getMapContext().getProjection().getAbrev() + " y capa "
358
                                                + getName() + " con " + proj.getAbrev());
359
                        }
360
                }
361
        }
362

    
363
        /*
364
         * (non-Javadoc)
365
         * @see org.cresques.geo.Projected#getProjection()
366
         */
367
        public IProjection getProjection() {
368
                return (IProjection) this.metadataContainer.getDynValue(METADATA_CRS);
369
        }
370

    
371
        /**
372
         * <p>Changes the projection of this layer.</p>
373
         * <p>This method will be overloaded in each kind of layer, according its specific nature.</p>
374
         *
375
         * @param mapC <code>MapControl</code> instance that will reproject this layer
376
         *
377
         * @return <code>true<code> if the layer has been created calling {@link FLayers#addLayer(FLayer) FLayers#addLayer}. But returns <code>false</code>
378
         *  if the load control logic of this layer is in the reprojection method
379
         *
380
         * @see #isReprojectable()
381
         * @see #setProjection(IProjection)
382
         */
383
        public void reProject(ICoordTrans arg0) {
384
        }
385

    
386
        /**
387
         * Returns the transparency level of this layer, in the range 0-255 .
388
         *
389
         * @return the transparency level
390
         *
391
         * @see #setTransparency(int)
392
         */
393
        public int getTransparency() {
394
                return transparency;
395
        }
396

    
397
        /**
398
         * Inserts the transparency level for this layer, the range allowed is 0-255 .
399
         *
400
         * @param trans the transparency level
401
         *
402
         * @see #getTransparency()
403
         */
404
        public void setTransparency(int trans) {
405
                if (this.transparency != trans){
406
                        transparency = trans;
407
                        this.updateDrawVersion();
408
                }
409
        }
410
        
411

    
412
        /*
413
         * (non-Javadoc)
414
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getMapContext()
415
         */
416
        public MapContext getMapContext() {
417
                if (getParentLayer() != null) {
418
                        return getParentLayer().getMapContext();
419
                } else {
420
                        return null;
421
                }
422
        }
423

    
424
        /*
425
         * (non-Javadoc)
426
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#addLayerListener(com.iver.cit.gvsig.fmap.layers.LayerListener)
427
         */
428
        public boolean addLayerListener(LayerListener o) {
429
                if (layerListeners.contains(o)) {
430
                        return false;
431
                }
432
                return layerListeners.add(o);
433
        }
434
        /*
435
         * (non-Javadoc)
436
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getLayerListeners()
437
         */
438
        public LayerListener[] getLayerListeners() {
439
                return (LayerListener[])layerListeners.toArray(new LayerListener[0]);
440
        }
441
        /*
442
         * (non-Javadoc)
443
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#removeLayerListener(com.iver.cit.gvsig.fmap.layers.LayerListener)
444
         */
445
        public boolean removeLayerListener(LayerListener o) {
446
                return layerListeners.remove(o);
447
        }
448
        /**
449
         *
450
         */
451
        private void callDrawValueChanged(LayerEvent e) {
452
                for (Iterator iter = layerListeners.iterator(); iter.hasNext();) {
453
                        LayerListener listener = (LayerListener) iter.next();
454

    
455
                        listener.drawValueChanged(e);
456
                }
457
        }
458
        /**
459
         * Called by the method {@linkplain #setName(String)}. Notifies all listeners associated to this layer,
460
         *  that its name has changed.
461
         *
462
         * @param e a layer event with the name of the property that has changed
463
         *
464
         * @see #setName(String)
465
         */
466
        private void callNameChanged(LayerEvent e) {
467
                for (Iterator iter = layerListeners.iterator(); iter.hasNext();) {
468
                        LayerListener listener = (LayerListener) iter.next();
469

    
470
                        listener.nameChanged(e);
471
                }
472
        }
473

    
474
        /**
475
         * Called by the method {@linkplain #setVisible(boolean)}. Notifies all listeners associated to this layer,
476
         *  that its visibility has changed.
477
         *
478
         * @param e a layer event with the name of the property that has changed
479
         *
480
         * @see #setVisible(boolean)
481
         */
482
        private void callVisibilityChanged(LayerEvent e) {
483
                for (Iterator iter = layerListeners.iterator(); iter.hasNext();) {
484
                        LayerListener listener = (LayerListener) iter.next();
485

    
486
                        listener.visibilityChanged(e);
487
                }
488
        }
489

    
490
        /**
491
         * Called by the method {@linkplain #setActive(boolean)}. Notifies all listeners associated to this layer,
492
         *  that its active state has changed.
493
         *
494
         * @param e a layer event with the name of the property that has changed
495
         *
496
         * @see #setActive(boolean)
497
         */
498
        private void callActivationChanged(LayerEvent e) {
499
                for (Iterator iter = layerListeners.iterator(); iter.hasNext();) {
500
                        LayerListener listener = (LayerListener) iter.next();
501

    
502
                        listener.activationChanged(e);
503
                }
504
        }
505

    
506
        /**
507
         * Returns the virtual layers associated to this layer.
508
         *
509
         * @return a node with the layers
510
         *
511
         * @see #setVirtualLayers(FLayers)
512
         */
513
        //        public FLayers getVirtualLayers() {
514
        //                return virtualLayers;
515
        //        }
516

    
517
        /**
518
         * Inserts virtual layers to this layer.
519
         *
520
         * @param virtualLayers a node with the layers
521
         *
522
         * @see #getVirtualLayers()
523
         */
524
        //        public void setVirtualLayers(FLayers virtualLayers) {
525
        //                this.virtualLayers = virtualLayers;
526
        //        }
527

    
528
        /**
529
         * Sets transformation coordinates for this layer.
530
         *
531
         * @param ct an object that implements the <code>ICoordTrans</code> interface, and with the transformation coordinates
532
         *
533
         * @see #getCoordTrans()
534
         */
535
        public void setCoordTrans(ICoordTrans ct) {
536
                if (this.ct == ct){
537
                        return;
538
                }
539
                if (this.ct != null && this.ct.equals(ct)){
540
                        return;
541
                }
542
                this.ct = ct;
543
                this.updateDrawVersion();
544
        }
545

    
546
        /**
547
         * Returns the transformation coordinates of this layer.
548
         *
549
         * @return an object that implements the <code>ICoordTrans</code> interface, and with the transformation coordinates
550
         *
551
         * @see #setCoordTrans(ICoordTrans)
552
         */
553
        public ICoordTrans getCoordTrans() {
554
                return ct;
555
        }
556

    
557
        /**
558
         * <p>Method called by {@link FLayers FLayers} to notify this layer that is going to be added.
559
         *  This previous notification is useful for the layers that need do something before being added. For
560
         *  example, the raster needs reopen a file that could have been closed recently.</p>
561
         */
562
        public void wakeUp() throws LoadLayerException {
563
        }
564
        /*
565
         * (non-Javadoc)
566
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getMinScale()
567
         */
568
        public double getMinScale() {
569
                return minScale;
570
        }
571

    
572
        /*
573
         * (non-Javadoc)
574
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getMaxScale()
575
         */
576
        public double getMaxScale() {
577
                return maxScale;
578
        }
579
        /*
580
         * (non-Javadoc)
581
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setMinScale(double)
582
         */
583
        public void setMinScale(double minScale) {
584
                if (this.minScale != minScale){
585
                        this.minScale = minScale;
586
                        this.updateDrawVersion();
587
                }
588
        }
589
        /*
590
         * (non-Javadoc)
591
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setMaxScale(double)
592
         */
593
        public void setMaxScale(double maxScale) {
594
                if (this.maxScale != maxScale){
595
                        this.maxScale = maxScale;
596
                        this.updateDrawVersion();
597
                }
598
        }
599
        /*
600
         * (non-Javadoc)
601
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isWithinScale(double)
602
         */
603
        public boolean isWithinScale(double scale) {
604

    
605
                boolean bVisible = true;
606
                if (getMinScale() != -1) {
607
                        if (scale < getMinScale()){
608
                                bVisible = false;
609
                        }
610
                }
611
                if (getMaxScale() != -1) {
612
                        if (scale > getMaxScale()) {
613
                                bVisible = false;
614
                        }
615
                }
616

    
617
                return bVisible;
618
        }
619
        /*
620
         * (non-Javadoc)
621
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setEditing(boolean)
622
         */
623
        public void setEditing(boolean b) throws StartEditionLayerException {
624
                status.editing = b;
625
        }
626
        /**
627
         * Called by some version of the method {@linkplain #setEditing(boolean)} overwritten. Notifies
628
         *  all listeners associated to this layer, that its edition state has changed.
629
         *
630
         * @param e a layer event with the name of the property that has changed
631
         *
632
         * @see #setEditing(boolean)
633
         */
634
        protected void callEditionChanged(LayerEvent e) {
635
                for (Iterator iter = layerListeners.iterator(); iter.hasNext();) {
636
                        LayerListener listener = (LayerListener) iter.next();
637

    
638
                        listener.editionChanged(e);
639
                }
640
        }
641
        /*
642
         * (non-Javadoc)
643
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isEditing()
644
         */
645
        public boolean isEditing() {
646
                return status.editing;
647
        }
648
        /*
649
         * (non-Javadoc)
650
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getTocImageIcon()
651
         */
652
        public String getTocImageIcon() {
653
                return "layer-icon";
654
        }
655
        
656
        /*
657
         * (non-Javadoc)
658
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isInTOC()
659
         */
660
        public boolean isInTOC() {
661
                return status.inTOC;
662
        }
663
        /*
664
         * (non-Javadoc)
665
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setInTOC(boolean)
666
         */
667
        public void setInTOC(boolean b) {
668
                status.inTOC=b;
669
        }
670
        /*
671
         * (non-Javadoc)
672
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isAvailable()
673
         */
674
        public boolean isAvailable() {
675
                return status.available;
676
        }
677
        /*
678
         * (non-Javadoc)
679
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setAvailable(boolean)
680
         */
681
        public void setAvailable(boolean available) {
682
                if (status.available != available){
683
                        status.available = available;
684
                        this.updateDrawVersion();
685
                }
686
        }
687
        /*
688
         * (non-Javadoc)
689
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#reload()
690
         */
691
        public void reload() throws ReloadLayerException {
692
                this.setAvailable(true);
693
        }
694

    
695
        /*
696
         * (non-Javadoc)
697
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getFLayerStatus()
698
         */
699
        public FLayerStatus getFLayerStatus(){
700
                return status.cloneStatus();
701
        }
702
        /*
703
         * (non-Javadoc)
704
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setFLayerStatus(com.iver.cit.gvsig.fmap.layers.FLayerStatus)
705
         */
706
        public void setFLayerStatus(FLayerStatus status){
707
                if (!this.status.equals(status)){
708
                        this.status = status;
709
                        this.updateDrawVersion();
710
                }
711
        }
712

    
713
        /*
714
         * (non-Javadoc)
715
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isOk()
716
         */
717

    
718
        public boolean isOk(){
719
                return status.isOk();
720
        }
721
        /*
722
         * (non-Javadoc)
723
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getNumErrors()
724
         */
725
        public int getNumErrors(){
726
                return status.getNumErrors();
727
        }
728

    
729
        /*
730
         * (non-Javadoc)
731
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getError(int)
732
         */
733
        public BaseException getError(int i){
734
                return status.getError(i);
735
        }
736
        /*
737
         * (non-Javadoc)
738
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getErrors()
739
         */
740
        public List getErrors(){
741
                return status.getErrors();
742
        }
743

    
744
        /*
745
         * (non-Javadoc)
746
         *
747
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#addError(BaseException)
748
         */
749
        public void addError(BaseException exception){
750
                status.addLayerError(exception);
751
        }
752
        /*
753
         * (non-Javadoc)
754
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#visibleRequired()
755
         */
756
        public boolean visibleRequired() {
757
                return status.visible;
758
        }
759
        /*
760
         * (non-Javadoc)
761
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getInfoString()
762
         */
763
        public String getInfoString() {
764
                return null;
765
        }
766
        /*
767
         * (non-Javadoc)
768
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isWritable()
769
         */
770
        public boolean isWritable() {
771
                return status.writable;
772
        }
773

    
774
        /*
775
         * (non-Javadoc)
776
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#cloneLayer()
777
         */
778
        public FLayer cloneLayer() throws Exception {
779
                return this;
780
        }
781
        /*
782
         * (non-Javadoc)
783
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getTocStatusImage()
784
         */
785
        public Image getTocStatusImage() {
786
                return tocStatusImage;
787
        }
788

    
789
        /**
790
         * Inserts the image icon that will be shown in the TOC next to this layer, according its status.
791
         *
792
         * @param tocStatusImage the image
793
         *
794
         * @see #getTocStatusImage()
795
         */
796
        public void setTocStatusImage(Image tocStatusImage) {
797
                this.tocStatusImage = tocStatusImage;
798
                logger.debug("setTocStatusImage " + tocStatusImage + " sobre capa " + this.getName());
799
        }
800
        /*
801
         * (non-Javadoc)
802
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#newComposedLayer()
803
         */
804
        public ComposedLayer newComposedLayer() {
805
                return null;
806
        }
807

    
808
        /*
809
         * (non-Javadoc)
810
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#allowLinks()
811
         */
812
        public boolean allowLinks()
813
        {
814
                return false;
815
        }
816

    
817
        /*
818
         * (non-Javadoc)
819
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getLinkProperties()
820
         */
821
        public AbstractLinkProperties getLinkProperties()
822
        {
823
                return null;
824
        }
825

    
826
        /*
827
         * (non-Javadoc)
828
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getLink(java.awt.geom.Point2D, double)
829
         */
830
        public URI[] getLink(Point2D point, double tolerance) throws ReadException{
831
                return null;
832
        }
833

    
834
        /**
835
         * @see LayerChangeSupport#addLayerListener(LegendListener)
836
         */
837
        public void addLegendListener(LegendListener listener) {
838
                layerChangeSupport.addLayerListener(listener);
839
        }
840

    
841
        /**
842
         * @see LayerChangeSupport#callLegendChanged(LegendChangedEvent)
843
         */
844
        protected void callLegendChanged(LegendChangedEvent e) {
845
                layerChangeSupport.callLegendChanged(e);
846
                if(parentLayer != null) {
847
                        parentLayer.callLegendChanged(e);
848
                }
849
        }
850

    
851
        /**
852
         * @see LayerChangeSupport#removeLayerListener(LegendListener)
853
         */
854
        public void removeLegendListener(LegendListener listener) {
855
                layerChangeSupport.removeLayerListener(listener);
856
        }
857
        public String getClassName() {
858
                return this.getClass().getName();
859
        }
860

    
861
        public void delegate(DynObject dynObject) {
862
                this.metadataContainer.delegate(dynObject);
863
        }
864

    
865
        public DynClass getDynClass() {
866
                return this.metadataContainer.getDynClass();
867
        }
868

    
869
        public Object getDynValue(String name) throws DynFieldNotFoundException {
870
                return this.metadataContainer.getDynValue(name);
871
        }
872

    
873
        public boolean hasDynValue(String name) {
874
                return this.metadataContainer.hasDynValue(name);
875
        }
876

    
877
        public void implement(DynClass dynClass) {
878
                this.metadataContainer.implement(dynClass);
879
        }
880

    
881
        public Object invokeDynMethod(int code, DynObject context)
882
        throws DynMethodException {
883
                return this.metadataContainer.invokeDynMethod(this, code, context);
884
        }
885

    
886
        public Object invokeDynMethod(String name, DynObject context)
887
        throws DynMethodException {
888
                return this.metadataContainer.invokeDynMethod(this, name, context);
889
        }
890

    
891
        public void setDynValue(String name, Object value)
892
        throws DynFieldNotFoundException {
893
                this.metadataContainer.setDynValue(name, value);
894
        }
895

    
896
        public long getDrawVersion() {
897
                return this.drawVersion;
898
        }
899

    
900
        protected void updateDrawVersion(){
901
                this.drawVersion++;
902
                this.callDrawValueChanged(LayerEvent.createDrawValuesChangedEvent(this, ""));
903
                if (this.parentLayer != null){
904
                        this.parentLayer.updateDrawVersion();
905
                }
906
        }
907

    
908
        public boolean hasChangedForDrawing(long value){
909
                return this.drawVersion > value;
910
        }
911

    
912
        public void activationChanged(LayerEvent e) {
913
        }
914

    
915
        public void drawValueChanged(LayerEvent e) {
916
                this.updateDrawVersion();
917
        }
918

    
919
        public void editionChanged(LayerEvent e) {
920

    
921
        }
922

    
923
        public void nameChanged(LayerEvent e) {
924

    
925
        }
926

    
927
        public void visibilityChanged(LayerEvent e) {
928

    
929
        }
930
        
931
        // ========================================================
932
        
933
        public void saveToState(PersistentState state) throws PersistenceException {
934
                state.set("parentLayer", parentLayer);
935
                state.set("status",status);
936
                state.set("minScale", minScale);
937
                state.set("maxScale", maxScale);
938
                state.set("transparency",transparency);
939
                state.set("coordTrans",ct);
940
                state.set("name", getName());
941
                state.set("crs", getProjection());
942
                state.set("properties",properties);
943
        }
944

    
945
        public void loadFromState(PersistentState state) throws PersistenceException {
946
                this.parentLayer = (FLayers) state.get("parentLayer");
947
                this.status = (FLayerStatus) state.get("status");
948
                this.minScale = state.getDouble("minScale");
949
                this.maxScale = state.getDouble("maxScale");
950
                this.transparency = state.getInt("transparency");
951
                this.ct = (ICoordTrans) state.get("coordTrans");
952

    
953
                this.setDynValue(METADATA_NAME, state.getString("name"));
954
                this.setDynValue(METADATA_CRS, state.get("crs"));
955
                
956
                this.properties = new Hashtable((Map)state.get("properties"));
957
        }
958

    
959
        public static void registerPersistent() {
960
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
961
                DynStruct definition = manager.addDefinition(
962
                                FLyrDefault.class,
963
                                "FLyrDefault",
964
                                "FLyrDefault Persistence definition",
965
                                null, 
966
                                null
967
                );
968
                definition.addDynFieldString("name").setMandatory(false);
969
                definition.addDynFieldInt("transparency").setMandatory(true);
970
                definition.addDynFieldDouble("minScale").setMandatory(true);
971
                definition.addDynFieldDouble("maxScale").setMandatory(true);
972
                definition.addDynFieldObject("crs").setClassOfValue(IProjection.class).setMandatory(false);
973
                definition.addDynFieldObject("parentLayer").setClassOfValue(FLayers.class).setMandatory(false);
974
                definition.addDynFieldObject("coordTrans").setClassOfValue(ICoordTrans.class).setMandatory(false);
975
                definition.addDynFieldObject("status").setClassOfValue(FLayerStatus.class).setMandatory(true);
976
                definition.addDynFieldMap("properties").setClassOfItems(Object.class)
977
                                .setMandatory(true);
978
        }
979

    
980
        
981
//        /**
982
//         * Splits string into an array of strings
983
//         * @param input input string
984
//         * @param sep separator string
985
//         * @return an array of strings
986
//         */
987
//        public static String[] splitString(String input, String sep) {
988
//                return Pattern.compile(sep).split(input, 0);
989
//        }
990
        
991
        public void clear() {
992
                if (metadataContainer != null) {
993
                        metadataContainer.clear();
994
                }
995
        }
996
        
997
    public String getMetadataName() throws MetadataException {
998
        return FLayer.METADATA_DEFINITION_NAME;
999
    }
1000
    
1001
        public static void registerMetadata() {
1002
                MetadataManager metadataManager = MetadataLocator.getMetadataManager();
1003

    
1004
                
1005
                DynStruct metadataDefinition = metadataManager.getDefinition(FLayer.METADATA_DEFINITION_NAME);
1006
                if (metadataDefinition == null) {
1007
                        try {
1008
                                metadataDefinition = metadataManager.addDefinition(
1009
                                                FLayer.METADATA_DEFINITION_NAME,
1010
                                                FLayer.METADATA_DEFINITION_DESCRIPTION);
1011
                                metadataDefinition.addDynField(FLayer.METADATA_NAME)
1012
                                                .setMandatory(true);
1013

    
1014
                                IProjection ipr =
1015
                                    MapContextLocator.getMapContextManager().getDefaultCRS();
1016
                                
1017
                                metadataDefinition.addDynFieldObject(FLayer.METADATA_CRS)
1018
                                                .setType(DataTypes.CRS).setMandatory(true)
1019
                                                .setDefaultFieldValue(ipr);
1020
                        } catch (MetadataException e) {
1021
                                logger.warn("Can't create metadata definition for 'Layer'", e);
1022
                        }
1023
                }
1024
        }
1025
        
1026
        public String toString() {
1027
                return super.toString() + ": " + getName();
1028
        }
1029
        
1030
        public boolean hidesThisArea(Envelope area) {
1031
                return false;
1032
        }
1033
}