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 @ 41302

History | View | Annotate | Download (28.3 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.impl.DefaultMapContextManager;
46
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
47
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
48
import org.gvsig.fmap.mapcontext.rendering.legend.events.listeners.LegendListener;
49
import org.gvsig.metadata.MetadataContainer;
50
import org.gvsig.metadata.MetadataLocator;
51
import org.gvsig.metadata.MetadataManager;
52
import org.gvsig.metadata.exceptions.MetadataException;
53
import org.gvsig.tools.ToolsLocator;
54
import org.gvsig.tools.dispose.impl.AbstractDisposable;
55
import org.gvsig.tools.dynobject.DynClass;
56
import org.gvsig.tools.dynobject.DynObject;
57
import org.gvsig.tools.dynobject.DynStruct;
58
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
59
import org.gvsig.tools.dynobject.exception.DynMethodException;
60
import org.gvsig.tools.exception.BaseException;
61
import org.gvsig.tools.persistence.PersistenceManager;
62
import org.gvsig.tools.persistence.PersistentState;
63
import org.gvsig.tools.persistence.exception.PersistenceException;
64
import org.slf4j.LoggerFactory;
65

    
66

    
67

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

    
95
        private LayerChangeSupport layerChangeSupport = new LayerChangeSupport();
96

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

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

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

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

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

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

    
149

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

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

    
195
        protected MetadataContainer metadataContainer;
196

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

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

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

    
217

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

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

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

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

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

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

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

    
306

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

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

    
323

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

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

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

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

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

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

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

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

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

    
473
                        listener.nameChanged(e);
474
                }
475
        }
476

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

    
489
                        listener.visibilityChanged(e);
490
                }
491
        }
492

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

    
505
                        listener.activationChanged(e);
506
                }
507
        }
508

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

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

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

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

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

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

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

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

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

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

    
716
        /*
717
         * (non-Javadoc)
718
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isOk()
719
         */
720

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

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

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

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

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

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

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

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

    
837
        /**
838
         * @see LayerChangeSupport#addLayerListener(LegendListener)
839
         */
840
        public void addLegendListener(LegendListener listener) {
841
                layerChangeSupport.addLayerListener(listener);
842
        }
843

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

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

    
864
        public void delegate(DynObject dynObject) {
865
                this.metadataContainer.delegate(dynObject);
866
        }
867

    
868
        public DynClass getDynClass() {
869
                return this.metadataContainer.getDynClass();
870
        }
871

    
872
        public Object getDynValue(String name) throws DynFieldNotFoundException {
873
                return this.metadataContainer.getDynValue(name);
874
        }
875

    
876
        public boolean hasDynValue(String name) {
877
                return this.metadataContainer.hasDynValue(name);
878
        }
879

    
880
        public void implement(DynClass dynClass) {
881
                this.metadataContainer.implement(dynClass);
882
        }
883

    
884
        public Object invokeDynMethod(int code, DynObject context)
885
        throws DynMethodException {
886
                return this.metadataContainer.invokeDynMethod(this, code, context);
887
        }
888

    
889
        public Object invokeDynMethod(String name, DynObject context)
890
        throws DynMethodException {
891
                return this.metadataContainer.invokeDynMethod(this, name, context);
892
        }
893

    
894
        public void setDynValue(String name, Object value)
895
        throws DynFieldNotFoundException {
896
                this.metadataContainer.setDynValue(name, value);
897
        }
898

    
899
        public long getDrawVersion() {
900
                return this.drawVersion;
901
        }
902

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

    
911
        public boolean hasChangedForDrawing(long value){
912
                return this.drawVersion > value;
913
        }
914

    
915
        public void activationChanged(LayerEvent e) {
916
        }
917

    
918
        public void drawValueChanged(LayerEvent e) {
919
                this.updateDrawVersion();
920
        }
921

    
922
        public void editionChanged(LayerEvent e) {
923

    
924
        }
925

    
926
        public void nameChanged(LayerEvent e) {
927

    
928
        }
929

    
930
        public void visibilityChanged(LayerEvent e) {
931

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

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

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

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

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

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

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