Statistics
| Revision:

root / branches / v2_0_0_prep / libraries / libFMap_mapcontext / src / org / gvsig / fmap / mapcontext / layers / FLyrDefault.java @ 26225

History | View | Annotate | Download (31.2 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib??ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.fmap.mapcontext.layers;
42

    
43
import java.awt.Image;
44
import java.awt.geom.Point2D;
45
import java.net.URI;
46
import java.util.ArrayList;
47
import java.util.Hashtable;
48
import java.util.Iterator;
49
import java.util.List;
50
import java.util.Map;
51
import java.util.Set;
52

    
53
import javax.swing.ImageIcon;
54

    
55
import org.cresques.cts.ICoordTrans;
56
import org.cresques.cts.IProjection;
57
import org.gvsig.fmap.crs.CRSFactory;
58
import org.gvsig.fmap.dal.exception.ReadException;
59
import org.gvsig.fmap.mapcontext.MapContext;
60
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
61
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
62
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
63
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
64
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
65
import org.gvsig.fmap.mapcontext.rendering.legend.events.listeners.LegendListener;
66
import org.gvsig.tools.ToolsLocator;
67
import org.gvsig.tools.dynobject.DelegatedDynObject;
68
import org.gvsig.tools.dynobject.DynClass;
69
import org.gvsig.tools.dynobject.DynObject;
70
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
71
import org.gvsig.tools.dynobject.exception.DynMethodException;
72
import org.gvsig.tools.exception.BaseException;
73
import org.slf4j.LoggerFactory;
74

    
75
import com.iver.utiles.IPersistence;
76
import com.iver.utiles.XMLEntity;
77
import com.iver.utiles.XMLException;
78

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

    
106
        /**
107
         * Path to the upper layer which this layer belongs.
108
         *
109
         * @see #getParentLayer()
110
         * @see #setParentLayer(FLayers)
111
         */
112
        private FLayers parentLayer = null;
113

    
114
        /**
115
         * A node in the tree of layers. Isn't used.
116
         *
117
         * @see #getVirtualLayers()
118
         * @see #setVirtualLayers(FLayers)
119
         */
120
        //        private FLayers virtualLayers = null;
121
        /**
122
         * Name for this layer, this also will be a property in the XML entity that
123
         * represents this layer.
124
         * 
125
         * @see #getName()
126
         * @see #setName(String)
127
         * 
128
         * @deprecated value stored en delegatedDynObject
129
         */
130
        private String namex;
131

    
132
        /**
133
         * Projection for this layer.
134
         * 
135
         * @see #getProjection()
136
         * @see #setProjection(IProjection)
137
         * 
138
         * @deprecated value stored en delegatedDynObject
139
         */
140
        private IProjection projectionx;
141

    
142
        /**
143
         * Transparency level of this layer in the range 0-255. By default 255.
144
         * 0   --> Transparent
145
         * 255 --> Opaque
146
         *
147
         * @see #getTransparency()
148
         * @see #setTransparency(int)
149
         */
150
        private int transparency = 255;
151

    
152
        /**
153
         * Coordinate transformation.
154
         *
155
         * @see #getCoordTrans()
156
         * @see #setCoordTrans(ICoordTrans)
157
         */
158
        private ICoordTrans ct;
159

    
160
        /**
161
         * Minimum scale, >= 0 or -1 if not defined. By default -1.
162
         *
163
         * @see #getMinScale()
164
         * @see #setMinScale(double)
165
         */
166
        private double minScale = -1; // -1 indica que no se usa
167

    
168
        /**
169
         * Maximum scale, >= 0 or -1 if not defined. By default -1.
170
         *
171
         * @see #getMaxScale()
172
         * @see #setMaxScale(double)
173
         */
174
        private double maxScale = -1;
175
        //        private boolean isInTOC = true;
176

    
177
        /**
178
         * Array list with all listeners registered to this layer.
179
         *
180
         * @see #getLayerListeners()
181
         * @see #removeLayerListener(LayerListener)
182
         * @see #callEditionChanged(LayerEvent)
183
         */
184
        protected ArrayList layerListeners = new ArrayList();
185

    
186

    
187
        /**
188
         * Hash table with the extended properties of this layer.
189
         *
190
         * @see #getProperty(Object)
191
         * @see #setProperty(Object, Object)
192
         * @see #getExtendedProperties()
193
         */
194
        private Hashtable properties = new Hashtable();
195

    
196
        //by default, all is active, visible and avalaible
197
        /**
198
         * Status of this layer.
199
         * 
200
         * @see #getFLayerStatus()
201
         * @see #setFLayerStatus(FLayerStatus)
202
         * @see #isActive()
203
         * @see #setActive(boolean)
204
         * @see #isVisible()
205
         * @see #setVisible(boolean)
206
         * @see #visibleRequired()
207
         * @see #isEditing()
208
         * @see #setEditing(boolean)
209
         * @see #isInTOC()
210
         * @see #isCachingDrawnLayers()
211
         * @see #setCachingDrawnLayers(boolean)
212
         * @see #isDirty()
213
         * @see #setDirty(boolean)
214
         * @see #isAvailable()
215
         * @see #setAvailable(boolean)
216
         * @see #isOk()
217
         * @see #isWritable()
218
         * @see #getNumErrors()
219
         * @see #getError(int)
220
         * @see #getErrors()
221
         * @see #addError(BaseException)
222
         */
223
        private FLayerStatus status = new FLayerStatus();
224
        /**
225
         * Image drawn shown in the TOC according the status of this layer.
226
         *
227
         * @see #getTocStatusImage()
228
         * @see #setTocStatusImage(Image)
229
         */
230
        private Image tocStatusImage;
231

    
232
        protected DelegatedDynObject delegatedDynObject;
233

    
234
        /**
235
         * Draw version of the context. It's used for know when de componend has
236
         * changed any visualization property
237
         *
238
         *  @see getDrawVersion
239
         *  @see updateDrawVersion
240
         */
241
        private long drawVersion= 0L;
242

    
243
        public FLyrDefault() {
244
                this.delegatedDynObject = (DelegatedDynObject) ToolsLocator
245
                .getDynObjectManager()
246
                .createDynObject(FLayer.DYNCLASS_NAME);
247
        }
248

    
249

    
250
        /*
251
         * (non-Javadoc)
252
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperty(java.lang.Object)
253
         */
254
        public Object getProperty(Object key) {
255
                return properties.get(key);
256
        }
257
        /*
258
         * (non-Javadoc)
259
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setProperty(java.lang.Object, java.lang.Object)
260
         */
261
        public void setProperty(Object key, Object val) {
262
                properties.put(key, val);
263
        }
264
        /*
265
         * (non-Javadoc)
266
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getExtendedProperties()
267
         */
268
        public Map getExtendedProperties() {
269
                return properties;
270
        }
271
        /*
272
         * (non-Javadoc)
273
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setActive(boolean)
274
         */
275
        public void setActive(boolean selected) {
276
                status.active = selected;
277
                callActivationChanged(LayerEvent.createActivationChangedEvent(this,
278
                "active"));
279
        }
280

    
281
        /*
282
         * (non-Javadoc)
283
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isActive()
284
         */
285
        public boolean isActive() {
286
                return status.active;
287
        }
288

    
289
        /*
290
         * (non-Javadoc)
291
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setName(java.lang.String)
292
         */
293
        public void setName(String name) {
294
                this.delegatedDynObject.setDynValue("name", name);
295
                callNameChanged(LayerEvent.createNameChangedEvent(this, "name"));
296
        }
297

    
298
        /*
299
         * (non-Javadoc)
300
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getName()
301
         */
302
        public String getName() {
303
                return (String) this.delegatedDynObject.getDynValue("name");
304
        }
305

    
306
        /*
307
         * (non-Javadoc)
308
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#load()
309
         */
310
        public void load() throws LoadLayerException {
311
        }
312

    
313
        /*
314
         * (non-Javadoc)
315
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setVisible(boolean)
316
         */
317
        public void setVisible(boolean visibility) {
318
                if (status.visible != visibility){
319
                        status.visible = visibility;
320
                        this.updateDrawVersion();
321

    
322
                        //                        if (this.getMapContext() != null){
323
                        //                                this.getMapContext().clearAllCachingImageDrawnLayers();
324
                        //                        }
325
                        callVisibilityChanged(LayerEvent.createVisibilityChangedEvent(this,
326
                        "visible"));
327
                }
328
        }
329

    
330

    
331
        /*
332
         * (non-Javadoc)
333
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isVisible()
334
         */
335
        public boolean isVisible() {
336
                return status.visible && status.available;
337
        }
338

    
339
        /*
340
         * (non-Javadoc)
341
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getParentLayer()
342
         */
343
        public FLayers getParentLayer() {
344
                return parentLayer;
345
        }
346

    
347

    
348
        /*
349
         * (non-Javadoc)
350
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setParentLayer(com.iver.cit.gvsig.fmap.layers.FLayers)
351
         */
352
        public void setParentLayer(FLayers root) {
353
                if (this.parentLayer != root){
354
                        this.parentLayer = root;
355
                        this.updateDrawVersion();
356
                }
357
        }
358

    
359
        /**
360
         * <p>Inserts the projection to this layer.</p>
361
         *
362
         * @param proj information about the new projection
363
         *
364
         * @see #isReprojectable()
365
         * @see #reProject(MapControl)
366
         */
367
        public void setProjection(IProjection proj) {
368
                IProjection curProj = this.getProjection();
369
                if (curProj == proj) {
370
                        return;
371
                }
372
                if (curProj != null && curProj.equals(proj)){
373
                        return;
374
                }
375
                this.updateDrawVersion();
376
                this.delegatedDynObject.setDynValue("SRS", proj);
377
                // Comprobar que la proyecci?n es la misma que la de FMap
378
                // Si no lo es, es una capa que est? reproyectada al vuelo
379
                if ((proj != null) && (getMapContext() != null)) {
380
                        if (proj != getMapContext().getProjection()) {
381
                                ICoordTrans ct = proj.getCT(getMapContext().getProjection());
382
                                setCoordTrans(ct);
383
                                logger.debug("Cambio proyecci?n: FMap con "
384
                                                + getMapContext().getProjection().getAbrev() + " y capa "
385
                                                + getName() + " con " + proj.getAbrev());
386
                        }
387
                }
388
        }
389

    
390
        /*
391
         * (non-Javadoc)
392
         * @see org.cresques.geo.Projected#getProjection()
393
         */
394
        public IProjection getProjection() {
395
                if (this.delegatedDynObject.hasDynValue("SRS")) {
396
                        return null;
397
                }
398
                return (IProjection) this.delegatedDynObject.getDynValue("SRS");
399
        }
400

    
401
        /**
402
         * <p>Changes the projection of this layer.</p>
403
         * <p>This method will be overloaded in each kind of layer, according its specific nature.</p>
404
         *
405
         * @param mapC <code>MapControl</code> instance that will reproject this layer
406
         *
407
         * @return <code>true<code> if the layer has been created calling {@link FLayers#addLayer(FLayer) FLayers#addLayer}. But returns <code>false</code>
408
         *  if the load control logic of this layer is in the reprojection method
409
         *
410
         * @see #isReprojectable()
411
         * @see #setProjection(IProjection)
412
         */
413
        public void reProject(ICoordTrans arg0) {
414
        }
415

    
416
        /**
417
         * Returns the transparency level of this layer, in the range 0-255 .
418
         *
419
         * @return the transparency level
420
         *
421
         * @see #setTransparency(int)
422
         */
423
        public int getTransparency() {
424
                return transparency;
425
        }
426

    
427
        /**
428
         * Inserts the transparency level for this layer, the range allowed is 0-255 .
429
         *
430
         * @param trans the transparency level
431
         *
432
         * @see #getTransparency()
433
         */
434
        public void setTransparency(int trans) {
435
                if (this.transparency != trans){
436
                        transparency = trans;
437
                        this.updateDrawVersion();
438
                }
439
        }
440
        /**
441
         * <p>Returns an entity that represents this layer.</p>
442
         *
443
         * <p>This XML entity has elements (properties) that represent and store information about this layer.</p>
444
         *
445
         * <p>There are two kinds of information: default properties of this layer, and extended properties (they added that weren't by default)</p>
446
         *
447
         * <p> <b>Default properties:</b>
448
         *  <ul>
449
         *   <li> className : name of this class
450
         *   <li> active : if this layer is active or not
451
         *   <li> name : name of this layer
452
         *   <li> minScale : minimum scale of this layer
453
         *   <li> maxScale : maximum scale of this layer
454
         *   <li> visible : if this layer is visible or not
455
         *   <li> proj : the projection of this layer (only if it's defined)
456
         *   <li> transparency : transparency level of this layer
457
         *   <li> isInTOC : if this layer is in the TOC or not
458
         *  </ul>
459
         * </p>
460
         *
461
         * <p> <b>Extended properties:</b> are stored as children of the tree-node returned. There are two kinds of information for a child,
462
         *  according if it's an instance of an <code>String</code> or of an object that implements the interface <code>IPersistance</code>.
463
         *
464
         *  <ul>
465
         *   <li> <i>Instance of <code>String</code>:</i>
466
         *   <ul>
467
         *    <li> className : name of the class of the object that it's the property
468
         *    <li> value : value of the property
469
         *    <li> layerPropertyName : name of the extended property of the layer
470
         *   </ul>
471
         *   <li> <i>Implements <code>IPersistance</code>:</i>
472
         *   <ul>
473
         *    <li> Information returned by the implementation of the method <code>getXMLEntity</code> of that object
474
         *    <li> className : name of the class of the object (this information could be with the information returned by
475
         *     the method <code>getXMLEntity</code> of that object
476
         *    <li> layerPropertyName : name of the extended property of the layer
477
         *   </ul>
478
         *  <ul>
479
         * </p>
480
         *
481
         * @return an XML entity with information to the current layer
482
         * @throws XMLException
483
         * @throws org.gvsig.fmap.mapcontext.layers.XMLException if there is an error obtaining the object.
484
         *
485
         * @see #setXMLEntity(XMLEntity)
486
         * @see #setXMLEntity03(XMLEntity)
487
         */
488
        public XMLEntity getXMLEntity() throws XMLException {
489
                XMLEntity xml = new XMLEntity();
490
                xml.putProperty("className", this.getClass().getName());
491

    
492
                xml.putProperty("active", status.active);
493
                xml.putProperty("name", this.getName());
494
                xml.putProperty("minScale", minScale);
495
                xml.putProperty("maxScale", maxScale);
496

    
497
                xml.putProperty("visible", status.visible);
498
                IProjection projection = this.getProjection();
499
                if (projection != null) {
500
                        xml.putProperty("proj", projection.getFullCode());
501
                }
502
                xml.putProperty("transparency", transparency);
503
                xml.putProperty("isInTOC", status.inTOC);
504

    
505
                // persist Properties hashTable
506
                Set keyset = properties.keySet();
507
                Iterator keyitr = keyset.iterator();
508
                XMLEntity xmlProperties = new XMLEntity();
509
                xmlProperties.putProperty("tagName", "properties");
510
                while (keyitr.hasNext()) {
511
                        String propName = (String)keyitr.next();
512
                        Object obj = properties.get(propName);
513
                        if (obj instanceof IPersistence)
514
                        {
515
                                IPersistence persistObj = (IPersistence)obj;
516
                                XMLEntity xmlPropObj = persistObj.getXMLEntity();
517
                                // make sure the node contains the class name
518
                                if (!xmlPropObj.contains("className")) {
519
                                        try {
520
                                                String propClassName = persistObj.getClassName();
521
                                                System.out.println("PROP CLASS NAME "+propClassName);
522
                                                xmlPropObj.putProperty("className", propClassName);
523
                                        } catch (Exception e) {
524
                                                e.printStackTrace();
525
                                        }
526
                                }
527
                                xmlPropObj.putProperty("layerPropertyName", propName);
528
                                xmlProperties.addChild(xmlPropObj);
529
                        } else if (obj instanceof String) {
530
                                XMLEntity xmlPropObj = new XMLEntity();
531
                                xmlPropObj.putProperty("className", String.class.getName());
532
                                xmlPropObj.putProperty("value",(String)obj);
533
                                xmlPropObj.putProperty("layerPropertyName", propName);
534
                                xmlProperties.addChild(xmlPropObj);
535
                        }
536
                }
537
                if (xmlProperties.getChildrenCount() > 0) {
538
                        xml.addChild(xmlProperties);
539
                }
540
                return xml;
541
        }
542

    
543
        /**
544
         * <p>Inserts information to this layer.</p>
545
         *
546
         * <p>This XML entity has elements that represent and store information about this layer.</p>
547
         *
548
         * <p>The properties are the same as the described in <code>getXMLEntity()</code>. And the properties
549
         *  <i>proj</i>,  <i>transparency</i>, <i>isInTOC</i> are optional.</p>
550
         *
551
         * <p>The property <i>numProperties</i> is optional, and only used in old projects.</p>
552
         *
553
         * @see FLyrDefault#getXMLEntity()
554
         *
555
         * @param xml an <code>XMLEntity</code> with the information
556
         *
557
         * @throws org.gvsig.fmap.mapcontext.layers.XMLException if there is an error setting the object.
558
         *
559
         * @see #getXMLEntity()
560
         */
561
        public void setXMLEntity(XMLEntity xml) throws XMLException {
562
                status.active = xml.getBooleanProperty("active");
563
                this.setName(xml.getStringProperty("name"));
564
                minScale = xml.getDoubleProperty("minScale");
565
                maxScale = xml.getDoubleProperty("maxScale");
566
                status.visible = xml.getBooleanProperty("visible");
567
                if (xml.contains("proj")) {
568
                        setProjection(CRSFactory.getCRS(xml.getStringProperty("proj")));
569
                }
570
                if (xml.contains("transparency")) {
571
                        transparency = xml.getIntProperty("transparency");
572
                }
573
                if (xml.contains("isInTOC")) {
574
                        status.inTOC = xml.getBooleanProperty("isInTOC");
575
                }
576

    
577
                // recreate Properties hashTable
578
                int xmlPropertiesPos = xml.firstIndexOfChild("childName", "properties");
579
                XMLEntity xmlProperties = null;
580
                if (xmlPropertiesPos > -1) {
581
                        xmlProperties = xml.getChild(xmlPropertiesPos);
582
                }
583

    
584
                if (xmlProperties != null) {
585

    
586
                        int numProps = xmlProperties.getChildrenCount();
587
                        Object obj;
588
                        String className;
589
                        Class classProp;
590
                        IPersistence objPersist;
591
                        for (int iProp=0; iProp<numProps; iProp++) {
592
                                XMLEntity xmlProp = xmlProperties.getChild(iProp);
593
                                try {
594
                                        className = xmlProp.getStringProperty("className");
595
                                        if (className.equals(String.class.getName())) {
596
                                                obj = xmlProp.getStringProperty("value");
597
                                        } else {
598
                                                classProp = Class.forName(className);
599
                                                obj = classProp.newInstance();
600
                                                objPersist = (IPersistence)obj;
601
                                                objPersist.setXMLEntity(xmlProp);
602

    
603
                                        }
604
                                        String propName = xmlProp.getStringProperty("layerPropertyName");
605
                                        properties.put(propName, obj);
606
                                } catch (Exception e) {
607
                                        logger.error("Layer:" + this.getName()
608
                                                        + ": Error loading properties", e);
609
                                        continue;
610
                                }
611
                        }
612
                }
613
                this.updateDrawVersion();
614
        }
615

    
616
        /*
617
         * (non-Javadoc)
618
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getMapContext()
619
         */
620
        public MapContext getMapContext() {
621
                if (getParentLayer() != null) {
622
                        return getParentLayer().getMapContext();
623
                } else {
624
                        return null;
625
                }
626
        }
627

    
628
        /*
629
         * (non-Javadoc)
630
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#addLayerListener(com.iver.cit.gvsig.fmap.layers.LayerListener)
631
         */
632
        public boolean addLayerListener(LayerListener o) {
633
                if (layerListeners.contains(o)) {
634
                        return false;
635
                }
636
                return layerListeners.add(o);
637
        }
638
        /*
639
         * (non-Javadoc)
640
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getLayerListeners()
641
         */
642
        public LayerListener[] getLayerListeners() {
643
                return (LayerListener[])layerListeners.toArray(new LayerListener[0]);
644
        }
645
        /*
646
         * (non-Javadoc)
647
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#removeLayerListener(com.iver.cit.gvsig.fmap.layers.LayerListener)
648
         */
649
        public boolean removeLayerListener(LayerListener o) {
650
                return layerListeners.remove(o);
651
        }
652
        /**
653
         *
654
         */
655
        private void callDrawValueChanged(LayerEvent e) {
656
                for (Iterator iter = layerListeners.iterator(); iter.hasNext();) {
657
                        LayerListener listener = (LayerListener) iter.next();
658

    
659
                        listener.drawValueChanged(e);
660
                }
661
        }
662
        /**
663
         * Called by the method {@linkplain #setName(String)}. Notifies all listeners associated to this layer,
664
         *  that its name has changed.
665
         *
666
         * @param e a layer event with the name of the property that has changed
667
         *
668
         * @see #setName(String)
669
         */
670
        private void callNameChanged(LayerEvent e) {
671
                for (Iterator iter = layerListeners.iterator(); iter.hasNext();) {
672
                        LayerListener listener = (LayerListener) iter.next();
673

    
674
                        listener.nameChanged(e);
675
                }
676
        }
677

    
678
        /**
679
         * Called by the method {@linkplain #setVisible(boolean)}. Notifies all listeners associated to this layer,
680
         *  that its visibility has changed.
681
         *
682
         * @param e a layer event with the name of the property that has changed
683
         *
684
         * @see #setVisible(boolean)
685
         */
686
        private void callVisibilityChanged(LayerEvent e) {
687
                for (Iterator iter = layerListeners.iterator(); iter.hasNext();) {
688
                        LayerListener listener = (LayerListener) iter.next();
689

    
690
                        listener.visibilityChanged(e);
691
                }
692
        }
693

    
694
        /**
695
         * Called by the method {@linkplain #setActive(boolean)}. Notifies all listeners associated to this layer,
696
         *  that its active state has changed.
697
         *
698
         * @param e a layer event with the name of the property that has changed
699
         *
700
         * @see #setActive(boolean)
701
         */
702
        private void callActivationChanged(LayerEvent e) {
703
                for (Iterator iter = layerListeners.iterator(); iter.hasNext();) {
704
                        LayerListener listener = (LayerListener) iter.next();
705

    
706
                        listener.activationChanged(e);
707
                }
708
        }
709

    
710
        /**
711
         * Returns the virtual layers associated to this layer.
712
         *
713
         * @return a node with the layers
714
         *
715
         * @see #setVirtualLayers(FLayers)
716
         */
717
        //        public FLayers getVirtualLayers() {
718
        //                return virtualLayers;
719
        //        }
720

    
721
        /**
722
         * Inserts virtual layers to this layer.
723
         *
724
         * @param virtualLayers a node with the layers
725
         *
726
         * @see #getVirtualLayers()
727
         */
728
        //        public void setVirtualLayers(FLayers virtualLayers) {
729
        //                this.virtualLayers = virtualLayers;
730
        //        }
731

    
732
        /**
733
         * Sets transformation coordinates for this layer.
734
         *
735
         * @param ct an object that implements the <code>ICoordTrans</code> interface, and with the transformation coordinates
736
         *
737
         * @see #getCoordTrans()
738
         */
739
        public void setCoordTrans(ICoordTrans ct) {
740
                if (this.ct == ct){
741
                        return;
742
                }
743
                if (this.ct != null && this.ct.equals(ct)){
744
                        return;
745
                }
746
                this.ct = ct;
747
                this.updateDrawVersion();
748
        }
749

    
750
        /**
751
         * Returns the transformation coordinates of this layer.
752
         *
753
         * @return an object that implements the <code>ICoordTrans</code> interface, and with the transformation coordinates
754
         *
755
         * @see #setCoordTrans(ICoordTrans)
756
         */
757
        public ICoordTrans getCoordTrans() {
758
                return ct;
759
        }
760

    
761
        /**
762
         * <p>Method called by {@link FLayers FLayers} to notify this layer that is going to be added.
763
         *  This previous notification is useful for the layers that need do something before being added. For
764
         *  example, the raster needs reopen a file that could have been closed recently.</p>
765
         */
766
        public void wakeUp() throws LoadLayerException {
767
        }
768
        /*
769
         * (non-Javadoc)
770
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getMinScale()
771
         */
772
        public double getMinScale() {
773
                return minScale;
774
        }
775

    
776
        /*
777
         * (non-Javadoc)
778
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getMaxScale()
779
         */
780
        public double getMaxScale() {
781
                return maxScale;
782
        }
783
        /*
784
         * (non-Javadoc)
785
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setMinScale(double)
786
         */
787
        public void setMinScale(double minScale) {
788
                if (this.minScale != minScale){
789
                        this.minScale = minScale;
790
                        this.updateDrawVersion();
791
                }
792
        }
793
        /*
794
         * (non-Javadoc)
795
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setMaxScale(double)
796
         */
797
        public void setMaxScale(double maxScale) {
798
                if (this.maxScale != maxScale){
799
                        this.maxScale = maxScale;
800
                        this.updateDrawVersion();
801
                }
802
        }
803
        /*
804
         * (non-Javadoc)
805
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isWithinScale(double)
806
         */
807
        public boolean isWithinScale(double scale) {
808

    
809
                boolean bVisible = true;
810
                if (getMinScale() != -1) {
811
                        if (scale < getMinScale()){
812
                                bVisible = false;
813
                        }
814
                }
815
                if (getMaxScale() != -1) {
816
                        if (scale > getMaxScale()) {
817
                                bVisible = false;
818
                        }
819
                }
820

    
821
                return bVisible;
822
        }
823
        /*
824
         * (non-Javadoc)
825
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setEditing(boolean)
826
         */
827
        public void setEditing(boolean b) throws StartEditionLayerException {
828
                status.editing = b;
829
        }
830
        /**
831
         * Called by some version of the method {@linkplain #setEditing(boolean)} overwritten. Notifies
832
         *  all listeners associated to this layer, that its edition state has changed.
833
         *
834
         * @param e a layer event with the name of the property that has changed
835
         *
836
         * @see #setEditing(boolean)
837
         */
838
        protected void callEditionChanged(LayerEvent e) {
839
                for (Iterator iter = layerListeners.iterator(); iter.hasNext();) {
840
                        LayerListener listener = (LayerListener) iter.next();
841

    
842
                        listener.editionChanged(e);
843
                }
844
        }
845
        /*
846
         * (non-Javadoc)
847
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isEditing()
848
         */
849
        public boolean isEditing() {
850
                return status.editing;
851
        }
852
        /*
853
         * (non-Javadoc)
854
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getTocImageIcon()
855
         */
856
        public ImageIcon getTocImageIcon() {
857
                return null;
858
        }
859
        /*
860
         * (non-Javadoc)
861
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isInTOC()
862
         */
863
        public boolean isInTOC() {
864
                return status.inTOC;
865
        }
866
        /*
867
         * (non-Javadoc)
868
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setInTOC(boolean)
869
         */
870
        public void setInTOC(boolean b) {
871
                status.inTOC=b;
872
        }
873
        /*
874
         * (non-Javadoc)
875
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isAvailable()
876
         */
877
        public boolean isAvailable() {
878
                return status.available;
879
        }
880
        /*
881
         * (non-Javadoc)
882
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setAvailable(boolean)
883
         */
884
        public void setAvailable(boolean available) {
885
                if (status.available != available){
886
                        status.available = available;
887
                        this.updateDrawVersion();
888
                }
889
        }
890
        /*
891
         * (non-Javadoc)
892
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#reload()
893
         */
894
        public void reload() throws ReloadLayerException {
895
                this.setAvailable(true);
896
        }
897

    
898
        /*
899
         * (non-Javadoc)
900
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getFLayerStatus()
901
         */
902
        public FLayerStatus getFLayerStatus(){
903
                return status.cloneStatus();
904
        }
905
        /*
906
         * (non-Javadoc)
907
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setFLayerStatus(com.iver.cit.gvsig.fmap.layers.FLayerStatus)
908
         */
909
        public void setFLayerStatus(FLayerStatus status){
910
                if (!this.status.equals(status)){
911
                        this.status = status;
912
                        this.updateDrawVersion();
913
                }
914
        }
915

    
916
        /*
917
         * (non-Javadoc)
918
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isOk()
919
         */
920

    
921
        public boolean isOk(){
922
                return status.isOk();
923
        }
924
        /*
925
         * (non-Javadoc)
926
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getNumErrors()
927
         */
928
        public int getNumErrors(){
929
                return status.getNumErrors();
930
        }
931

    
932
        /*
933
         * (non-Javadoc)
934
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getError(int)
935
         */
936
        public BaseException getError(int i){
937
                return status.getError(i);
938
        }
939
        /*
940
         * (non-Javadoc)
941
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getErrors()
942
         */
943
        public List getErrors(){
944
                return status.getErrors();
945
        }
946

    
947
        /*
948
         * (non-Javadoc)
949
         * 
950
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#addError(BaseException)
951
         */
952
        public void addError(BaseException exception){
953
                status.addLayerError(exception);
954
        }
955
        /*
956
         * (non-Javadoc)
957
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#visibleRequired()
958
         */
959
        public boolean visibleRequired() {
960
                return status.visible;
961
        }
962
        /*
963
         * (non-Javadoc)
964
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getInfoString()
965
         */
966
        public String getInfoString() {
967
                return null;
968
        }
969
        /*
970
         * (non-Javadoc)
971
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isWritable()
972
         */
973
        public boolean isWritable() {
974
                return status.writable;
975
        }
976

    
977
        /*
978
         * (non-Javadoc)
979
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#cloneLayer()
980
         */
981
        public FLayer cloneLayer() throws Exception {
982
                return this;
983
        }
984
        /*
985
         * (non-Javadoc)
986
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getTocStatusImage()
987
         */
988
        public Image getTocStatusImage() {
989
                return tocStatusImage;
990
        }
991

    
992
        /**
993
         * Inserts the image icon that will be shown in the TOC next to this layer, according its status.
994
         *
995
         * @param tocStatusImage the image
996
         *
997
         * @see #getTocStatusImage()
998
         */
999
        public void setTocStatusImage(Image tocStatusImage) {
1000
                this.tocStatusImage = tocStatusImage;
1001
                logger.debug("setTocStatusImage " + tocStatusImage + " sobre capa " + this.getName());
1002
        }
1003
        /*
1004
         * (non-Javadoc)
1005
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#newComposedLayer()
1006
         */
1007
        public ComposedLayer newComposedLayer() {
1008
                return null;
1009
        }
1010

    
1011
        /*
1012
         * (non-Javadoc)
1013
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#allowLinks()
1014
         */
1015
        public boolean allowLinks()
1016
        {
1017
                return false;
1018
        }
1019

    
1020
        /*
1021
         * (non-Javadoc)
1022
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getLinkProperties()
1023
         */
1024
        public AbstractLinkProperties getLinkProperties()
1025
        {
1026
                return null;
1027
        }
1028

    
1029
        /*
1030
         * (non-Javadoc)
1031
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getLink(java.awt.geom.Point2D, double)
1032
         */
1033
        public URI[] getLink(Point2D point, double tolerance) throws ReadException{
1034
                return null;
1035
        }
1036

    
1037
        /**
1038
         * @see LayerChangeSupport#addLayerListener(LegendListener)
1039
         */
1040
        public void addLegendListener(LegendListener listener) {
1041
                layerChangeSupport.addLayerListener(listener);
1042
        }
1043

    
1044
        /**
1045
         * @see LayerChangeSupport#callLegendChanged(LegendChangedEvent)
1046
         */
1047
        protected void callLegendChanged(LegendChangedEvent e) {
1048
                layerChangeSupport.callLegendChanged(e);
1049
                if(parentLayer != null) {
1050
                        parentLayer.callLegendChanged(e);
1051
                }
1052
        }
1053

    
1054
        /**
1055
         * @see LayerChangeSupport#removeLayerListener(LegendListener)
1056
         */
1057
        public void removeLegendListener(LegendListener listener) {
1058
                layerChangeSupport.removeLayerListener(listener);
1059
        }
1060
        public String getClassName() {
1061
                return this.getClass().getName();
1062
        }
1063

    
1064
        public void delegate(DynObject dynObject) {
1065
                this.delegatedDynObject.delegate(dynObject);
1066
        }
1067

    
1068
        public DynClass getDynClass() {
1069
                return this.delegatedDynObject.getDynClass();
1070
        }
1071

    
1072
        public Object getDynValue(String name) throws DynFieldNotFoundException {
1073
                return this.delegatedDynObject.getDynValue(name);
1074
        }
1075

    
1076
        public boolean hasDynValue(String name) {
1077
                return this.delegatedDynObject.hasDynValue(name);
1078
        }
1079

    
1080
        public void implement(DynClass dynClass) {
1081
                this.delegatedDynObject.implement(dynClass);
1082
        }
1083

    
1084
        public Object invokeDynMethod(int code, DynObject context)
1085
        throws DynMethodException {
1086
                return this.delegatedDynObject.invokeDynMethod(this, code, context);
1087
        }
1088

    
1089
        public Object invokeDynMethod(String name, DynObject context)
1090
        throws DynMethodException {
1091
                return this.delegatedDynObject.invokeDynMethod(this, name, context);
1092
        }
1093

    
1094
        public void setDynValue(String name, Object value)
1095
        throws DynFieldNotFoundException {
1096
                this.delegatedDynObject.setDynValue(name, value);
1097
        }
1098

    
1099
        public long getDrawVersion() {
1100
                return this.drawVersion;
1101
        }
1102

    
1103
        protected void updateDrawVersion(){
1104
                this.drawVersion++;
1105
                this.callDrawValueChanged(LayerEvent.createDrawValuesChangedEvent(this, ""));
1106
                if (this.parentLayer != null){
1107
                        this.parentLayer.updateDrawVersion();
1108
                }
1109
        }
1110

    
1111
        public boolean hasChangedForDrawing(long value){
1112
                return this.drawVersion > value;
1113
        }
1114

    
1115
        public void activationChanged(LayerEvent e) {
1116
        }
1117

    
1118
        public void drawValueChanged(LayerEvent e) {
1119
                this.updateDrawVersion();
1120
        }
1121

    
1122
        public void editionChanged(LayerEvent e) {
1123

    
1124
        }
1125

    
1126
        public void nameChanged(LayerEvent e) {
1127

    
1128
        }
1129

    
1130
        public void visibilityChanged(LayerEvent e) {
1131

    
1132
        }
1133

    
1134

    
1135
}