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

History | View | Annotate | Download (29.2 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
        //by default, all is active, visible and avalaible
150
        /**
151
         * Status of this layer.
152
         *
153
         * @see #getFLayerStatus()
154
         * @see #setFLayerStatus(FLayerStatus)
155
         * @see #isActive()
156
         * @see #setActive(boolean)
157
         * @see #isVisible()
158
         * @see #setVisible(boolean)
159
         * @see #visibleRequired()
160
         * @see #isEditing()
161
         * @see #setEditing(boolean)
162
         * @see #isInTOC()
163
         * @see #isCachingDrawnLayers()
164
         * @see #setCachingDrawnLayers(boolean)
165
         * @see #isDirty()
166
         * @see #setDirty(boolean)
167
         * @see #isAvailable()
168
         * @see #setAvailable(boolean)
169
         * @see #isOk()
170
         * @see #isWritable()
171
         * @see #getNumErrors()
172
         * @see #getError(int)
173
         * @see #getErrors()
174
         * @see #addError(BaseException)
175
         */
176
        private FLayerStatus status = new FLayerStatus();
177
        /**
178
         * Image drawn shown in the TOC according the status of this layer.
179
         *
180
         * @see #getTocStatusImage()
181
         * @see #setTocStatusImage(Image)
182
         */
183
        private Image tocStatusImage;
184

    
185
        protected MetadataContainer metadataContainer;
186

    
187
        /**
188
         * Draw version of the context. It's used for know when de componend has
189
         * changed any visualization property
190
         *
191
         *  @see getDrawVersion
192
         *  @see updateDrawVersion
193
         */
194
        private long drawVersion= 0L;
195

    
196
        
197
        private ExtendedPropertiesHelper properties = new ExtendedPropertiesHelper();
198
        
199
        public FLyrDefault(MetadataContainer metadataContainer) {
200
                this.metadataContainer = metadataContainer;
201
        }
202

    
203
        public FLyrDefault() {
204
                this(MetadataLocator
205
                        .getMetadataManager()
206
                                .createMetadataContainer(FLayer.METADATA_DEFINITION_NAME)
207
                );
208
        }
209

    
210

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

    
242
        /*
243
         * (non-Javadoc)
244
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isActive()
245
         */
246
        public boolean isActive() {
247
                return status.active;
248
        }
249

    
250
        /*
251
         * (non-Javadoc)
252
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setName(java.lang.String)
253
         */
254
        public void setName(String name) {
255
                this.metadataContainer.setDynValue(METADATA_NAME, name);
256
                callNameChanged(LayerEvent.createNameChangedEvent(this, "name"));
257
        }
258

    
259
        /*
260
         * (non-Javadoc)
261
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getName()
262
         */
263
        public String getName() {
264
            String name = "(unknow)";
265
            try {
266
                name = (String) this.metadataContainer.getDynValue(METADATA_NAME);
267
            } catch( Throwable th) {
268
                logger.warn("Can't retrive the layer name.");
269
            }
270
            return 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
        DefaultMapContextManager mcmanager = (DefaultMapContextManager) MapContextLocator.getMapContextManager();
285
        mcmanager.notifyLoadLayer(this);
286
    }
287

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

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

    
305

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

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

    
322

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
921
        public void editionChanged(LayerEvent e) {
922

    
923
        }
924

    
925
        public void nameChanged(LayerEvent e) {
926

    
927
        }
928

    
929
        public void visibilityChanged(LayerEvent e) {
930

    
931
        }
932
        
933
        // ========================================================
934
        
935
        public void saveToState(PersistentState state) throws PersistenceException {
936
            try {
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.getExtendedProperties());
946
            } catch(PersistenceException ex) {
947
                logger.warn("Can't save to persistent state the layer '"+this.getName()+"'.");
948
                throw ex;
949
            } catch(RuntimeException ex) {
950
                logger.warn("Can't save to persistent state the layer '"+this.getName()+"'.");
951
                throw ex;
952
            }
953
        }
954

    
955
        public void loadFromState(PersistentState state) throws PersistenceException {
956
            try {
957
                this.setDynValue(METADATA_NAME, state.getString("name"));
958
                this.setDynValue(METADATA_CRS, state.get("crs"));
959
                
960
                this.parentLayer = (FLayers) state.get("parentLayer");
961
                this.status = (FLayerStatus) state.get("status");
962
                this.minScale = state.getDouble("minScale");
963
                this.maxScale = state.getDouble("maxScale");
964
                this.transparency = state.getInt("transparency");
965
                this.ct = (ICoordTrans) state.get("coordTrans");
966

    
967
                this.properties.setExtendedProperties(new Hashtable((Map)state.get("properties")));
968
            } catch(PersistenceException ex) {
969
                logger.warn("Can't load from persietent state the layer '"+this.getName()+"'.");
970
                throw ex;
971
            } catch(RuntimeException ex) {
972
                logger.warn("Can't load from persietent state the layer '"+this.getName()+"'.");
973
                throw ex;
974
            }
975

    
976
        }
977

    
978
        public static void registerPersistent() {
979
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
980
                DynStruct definition = manager.addDefinition(
981
                                FLyrDefault.class,
982
                                "FLyrDefault",
983
                                "FLyrDefault Persistence definition",
984
                                null, 
985
                                null
986
                );
987
                definition.addDynFieldString("name").setMandatory(false);
988
                definition.addDynFieldInt("transparency").setMandatory(true);
989
                definition.addDynFieldDouble("minScale").setMandatory(true);
990
                definition.addDynFieldDouble("maxScale").setMandatory(true);
991
                definition.addDynFieldObject("crs").setClassOfValue(IProjection.class).setMandatory(false);
992
                definition.addDynFieldObject("parentLayer").setClassOfValue(FLayers.class).setMandatory(false);
993
                definition.addDynFieldObject("coordTrans").setClassOfValue(ICoordTrans.class).setMandatory(false);
994
                definition.addDynFieldObject("status").setClassOfValue(FLayerStatus.class).setMandatory(true);
995
                definition.addDynFieldMap("properties").setClassOfItems(Object.class)
996
                                .setMandatory(true);
997

    
998
        }
999

    
1000
        
1001
//        /**
1002
//         * Splits string into an array of strings
1003
//         * @param input input string
1004
//         * @param sep separator string
1005
//         * @return an array of strings
1006
//         */
1007
//        public static String[] splitString(String input, String sep) {
1008
//                return Pattern.compile(sep).split(input, 0);
1009
//        }
1010
        
1011
        public void clear() {
1012
                if (metadataContainer != null) {
1013
                        metadataContainer.clear();
1014
                }
1015
        }
1016
        
1017
    public String getMetadataName() throws MetadataException {
1018
        return FLayer.METADATA_DEFINITION_NAME;
1019
    }
1020
    
1021
        public static void registerMetadata() {
1022
                MetadataManager metadataManager = MetadataLocator.getMetadataManager();
1023

    
1024
                
1025
                DynStruct metadataDefinition = metadataManager.getDefinition(FLayer.METADATA_DEFINITION_NAME);
1026
                if (metadataDefinition == null) {
1027
                        try {
1028
                                metadataDefinition = metadataManager.addDefinition(
1029
                                                FLayer.METADATA_DEFINITION_NAME,
1030
                                                FLayer.METADATA_DEFINITION_DESCRIPTION);
1031
                                metadataDefinition.addDynField(FLayer.METADATA_NAME)
1032
                                                .setMandatory(true);
1033

    
1034
                                IProjection ipr =
1035
                                    MapContextLocator.getMapContextManager().getDefaultCRS();
1036
                                
1037
                                metadataDefinition.addDynFieldObject(FLayer.METADATA_CRS)
1038
                                                .setType(DataTypes.CRS).setMandatory(true)
1039
                                                .setDefaultFieldValue(ipr);
1040
                        } catch (MetadataException e) {
1041
                                logger.warn("Can't create metadata definition for 'Layer'", e);
1042
                        }
1043
                }
1044
        }
1045
        
1046
        public String toString() {
1047
                return super.toString() + ": " + getName();
1048
        }
1049
        
1050
        public boolean hidesThisArea(Envelope area) {
1051
                return false;
1052
        }
1053
}