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

History | View | Annotate | Download (32.7 KB)

1 40559 jjdelcerro
/**
2
 * gvSIG. Desktop Geographic Information System.
3 40435 jjdelcerro
 *
4 40559 jjdelcerro
 * Copyright (C) 2007-2013 gvSIG Association.
5 40435 jjdelcerro
 *
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 40559 jjdelcerro
 * as published by the Free Software Foundation; either version 3
9 40435 jjdelcerro
 * 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 40559 jjdelcerro
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20 40435 jjdelcerro
 *
21 40559 jjdelcerro
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23 40435 jjdelcerro
 */
24
package org.gvsig.fmap.mapcontext.layers;
25
26
import java.awt.Image;
27
import java.awt.geom.Point2D;
28 43215 jjdelcerro
import java.io.File;
29 40435 jjdelcerro
import java.net.URI;
30 42811 jjdelcerro
import java.util.HashSet;
31 40435 jjdelcerro
import java.util.List;
32
import java.util.Map;
33 42811 jjdelcerro
import java.util.Set;
34 43215 jjdelcerro
import org.apache.commons.lang3.StringUtils;
35 40435 jjdelcerro
36
import org.cresques.cts.ICoordTrans;
37
import org.cresques.cts.IProjection;
38 43215 jjdelcerro
import org.gvsig.fmap.dal.DataStore;
39 40435 jjdelcerro
import org.gvsig.fmap.dal.DataTypes;
40
import org.gvsig.fmap.dal.exception.ReadException;
41 43215 jjdelcerro
import org.gvsig.fmap.dal.serverexplorer.filesystem.FilesystemStoreParameters;
42 40435 jjdelcerro
import org.gvsig.fmap.geom.primitive.Envelope;
43
import org.gvsig.fmap.mapcontext.MapContext;
44
import org.gvsig.fmap.mapcontext.MapContextLocator;
45
import org.gvsig.fmap.mapcontext.exceptions.LoadLayerException;
46
import org.gvsig.fmap.mapcontext.exceptions.ReloadLayerException;
47
import org.gvsig.fmap.mapcontext.exceptions.StartEditionLayerException;
48 41302 jjdelcerro
import org.gvsig.fmap.mapcontext.impl.DefaultMapContextManager;
49 40435 jjdelcerro
import org.gvsig.fmap.mapcontext.layers.operations.ComposedLayer;
50 43215 jjdelcerro
import org.gvsig.fmap.mapcontext.layers.operations.SingleLayer;
51 40435 jjdelcerro
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendChangedEvent;
52
import org.gvsig.fmap.mapcontext.rendering.legend.events.listeners.LegendListener;
53
import org.gvsig.metadata.MetadataContainer;
54
import org.gvsig.metadata.MetadataLocator;
55
import org.gvsig.metadata.MetadataManager;
56
import org.gvsig.metadata.exceptions.MetadataException;
57
import org.gvsig.tools.ToolsLocator;
58
import org.gvsig.tools.dispose.impl.AbstractDisposable;
59
import org.gvsig.tools.dynobject.DynClass;
60
import org.gvsig.tools.dynobject.DynObject;
61
import org.gvsig.tools.dynobject.DynStruct;
62
import org.gvsig.tools.dynobject.exception.DynFieldNotFoundException;
63
import org.gvsig.tools.dynobject.exception.DynMethodException;
64
import org.gvsig.tools.exception.BaseException;
65
import org.gvsig.tools.persistence.PersistenceManager;
66 42293 jjdelcerro
import org.gvsig.tools.persistence.Persistent;
67 40435 jjdelcerro
import org.gvsig.tools.persistence.PersistentState;
68
import org.gvsig.tools.persistence.exception.PersistenceException;
69 41840 jjdelcerro
import org.gvsig.tools.util.Callable;
70 40435 jjdelcerro
import org.slf4j.LoggerFactory;
71
72
73
74
/**
75
 * <p>Implementation of the common characteristics of all layers: visibility, activation, name, ...</p>
76
 *
77
 * <p>Represents the definition of a basic layer, implementing {@link FLayer FLayer}, and new functionality:
78
 * <ul>
79
 *  <li>Supports transparency.
80
 *  <li>Notification of evens produced using this layer.
81
 *  <li>Can have internal virtual layers.
82
 *  <li>Can have a text layer.
83
 *  <li>Supports an strategy for visit its geometries.
84
 *  <li>Can have an image in the <i>TOC (table of contents)</i> associated to the state of this layer.
85
 * </ul>
86
 * </p>
87
 *
88
 * <p>Each graphical layer will inherit from this class and adapt to its particular logic and model according
89
 *  its nature.</p>
90
 *
91
 * @see FLayer
92
 * @see FLayerStatus
93
 */
94
public abstract class FLyrDefault extends AbstractDisposable implements FLayer, FLayerHidesArea,
95
                LayerListener {
96
        /**
97
         * Useful for debug the problems during the implementation.
98
         */
99
        final static private org.slf4j.Logger logger = LoggerFactory.getLogger(FLyrDefault.class);
100
101 44050 jjdelcerro
        private static final int TOL = 7;
102 40435 jjdelcerro
103 44050 jjdelcerro
        private LayerChangeSupport layerChangeSupport = new LayerChangeSupport();
104
105 41853 jjdelcerro
        /**
106
         * Flag to set the layer as a temporary layer.
107
         */
108
        private boolean temporary;
109 42877 fdiaz
110 40435 jjdelcerro
        /**
111
         * Path to the upper layer which this layer belongs.
112
         *
113
         * @see #getParentLayer()
114
         * @see #setParentLayer(FLayers)
115
         */
116
        private FLayers parentLayer = null;
117
118
        /**
119
         * Transparency level of this layer in the range 0-255. By default 255.
120
         * 0   --> Transparent
121
         * 255 --> Opaque
122
         *
123
         * @see #getTransparency()
124
         * @see #setTransparency(int)
125
         */
126
        private int transparency = 255;
127
128
        /**
129
         * Coordinate transformation.
130
         *
131
         * @see #getCoordTrans()
132
         * @see #setCoordTrans(ICoordTrans)
133
         */
134
        private ICoordTrans ct;
135
136
        /**
137
         * Minimum scale, >= 0 or -1 if not defined. By default -1.
138
         *
139
         * @see #getMinScale()
140
         * @see #setMinScale(double)
141
         */
142
        private double minScale = -1; // -1 indica que no se usa
143
144
        /**
145
         * Maximum scale, >= 0 or -1 if not defined. By default -1.
146
         *
147
         * @see #getMaxScale()
148
         * @see #setMaxScale(double)
149
         */
150
        private double maxScale = -1;
151
        //        private boolean isInTOC = true;
152
153
        /**
154
         * Array list with all listeners registered to this layer.
155
         *
156
         * @see #getLayerListeners()
157
         * @see #removeLayerListener(LayerListener)
158
         * @see #callEditionChanged(LayerEvent)
159
         */
160 42811 jjdelcerro
        protected Set<LayerListener> layerListeners = new HashSet<>();
161 40435 jjdelcerro
162
        //by default, all is active, visible and avalaible
163
        /**
164
         * Status of this layer.
165
         *
166
         * @see #getFLayerStatus()
167
         * @see #setFLayerStatus(FLayerStatus)
168
         * @see #isActive()
169
         * @see #setActive(boolean)
170
         * @see #isVisible()
171
         * @see #setVisible(boolean)
172
         * @see #visibleRequired()
173
         * @see #isEditing()
174
         * @see #setEditing(boolean)
175
         * @see #isInTOC()
176
         * @see #isCachingDrawnLayers()
177
         * @see #setCachingDrawnLayers(boolean)
178
         * @see #isDirty()
179
         * @see #setDirty(boolean)
180
         * @see #isAvailable()
181
         * @see #setAvailable(boolean)
182
         * @see #isOk()
183
         * @see #isWritable()
184
         * @see #getNumErrors()
185
         * @see #getError(int)
186
         * @see #getErrors()
187
         * @see #addError(BaseException)
188
         */
189
        private FLayerStatus status = new FLayerStatus();
190
        /**
191
         * Image drawn shown in the TOC according the status of this layer.
192
         *
193
         * @see #getTocStatusImage()
194
         * @see #setTocStatusImage(Image)
195
         */
196
        private Image tocStatusImage;
197
198
        protected MetadataContainer metadataContainer;
199
200
        /**
201
         * Draw version of the context. It's used for know when de componend has
202
         * changed any visualization property
203
         *
204
         *  @see getDrawVersion
205
         *  @see updateDrawVersion
206
         */
207
        private long drawVersion= 0L;
208
209 42877 fdiaz
210 41350 jjdelcerro
        private ExtendedPropertiesHelper properties = new ExtendedPropertiesHelper();
211 42877 fdiaz
212 40435 jjdelcerro
        public FLyrDefault(MetadataContainer metadataContainer) {
213
                this.metadataContainer = metadataContainer;
214
        }
215
216
        public FLyrDefault() {
217
                this(MetadataLocator
218
                        .getMetadataManager()
219
                                .createMetadataContainer(FLayer.METADATA_DEFINITION_NAME)
220
                );
221
        }
222
223
224
        /*
225
         * (non-Javadoc)
226
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getProperty(java.lang.Object)
227
         */
228
        public Object getProperty(Object key) {
229 41350 jjdelcerro
                return properties.getProperty(key);
230 40435 jjdelcerro
        }
231
        /*
232
         * (non-Javadoc)
233
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setProperty(java.lang.Object, java.lang.Object)
234
         */
235
        public void setProperty(Object key, Object val) {
236 41350 jjdelcerro
                properties.setProperty(key, val);
237 40435 jjdelcerro
        }
238
        /*
239
         * (non-Javadoc)
240
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getExtendedProperties()
241
         */
242
        public Map getExtendedProperties() {
243 41350 jjdelcerro
                return properties.getExtendedProperties();
244 40435 jjdelcerro
        }
245
        /*
246
         * (non-Javadoc)
247
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setActive(boolean)
248
         */
249
        public void setActive(boolean selected) {
250
                status.active = selected;
251
                callActivationChanged(LayerEvent.createActivationChangedEvent(this,
252
                "active"));
253
        }
254
255
        /*
256
         * (non-Javadoc)
257
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isActive()
258
         */
259
        public boolean isActive() {
260
                return status.active;
261
        }
262
263
        /*
264
         * (non-Javadoc)
265
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setName(java.lang.String)
266
         */
267
        public void setName(String name) {
268
                this.metadataContainer.setDynValue(METADATA_NAME, name);
269
                callNameChanged(LayerEvent.createNameChangedEvent(this, "name"));
270
        }
271 43979 omartinez
272 40435 jjdelcerro
273
        /*
274
         * (non-Javadoc)
275
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getName()
276
         */
277
        public String getName() {
278 41807 jjdelcerro
            String name = "(unknow)";
279
            try {
280
                name = (String) this.metadataContainer.getDynValue(METADATA_NAME);
281
            } catch( Throwable th) {
282
                logger.warn("Can't retrive the layer name.");
283
            }
284
            return name;
285 40435 jjdelcerro
        }
286
287
        /*
288
         * (non-Javadoc)
289
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#load()
290
         */
291 41302 jjdelcerro
    public void load() throws LoadLayerException {
292
        MetadataManager manager = MetadataLocator.getMetadataManager();
293
        try {
294 40435 jjdelcerro
            manager.loadMetadata(this);
295
        } catch (MetadataException e) {
296 41302 jjdelcerro
            throw new LoadLayerException("Can't load metadata.", e);
297 40435 jjdelcerro
        }
298 41302 jjdelcerro
        DefaultMapContextManager mcmanager = (DefaultMapContextManager) MapContextLocator.getMapContextManager();
299
        mcmanager.notifyLoadLayer(this);
300
    }
301 40435 jjdelcerro
302
        /*
303
         * (non-Javadoc)
304
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setVisible(boolean)
305
         */
306
        public void setVisible(boolean visibility) {
307 41302 jjdelcerro
                if (status.visible != visibility){
308 40435 jjdelcerro
                        status.visible = visibility;
309 41302 jjdelcerro
                        this.updateDrawVersion();
310
311
                        //                        if (this.getMapContext() != null){
312
                        //                                this.getMapContext().clearAllCachingImageDrawnLayers();
313
                        //                        }
314 40435 jjdelcerro
                        callVisibilityChanged(LayerEvent.createVisibilityChangedEvent(this,
315
                        "visible"));
316
                }
317
        }
318
319
320
        /*
321
         * (non-Javadoc)
322
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isVisible()
323
         */
324
        public boolean isVisible() {
325
                return status.visible && status.available;
326
        }
327
328
        /*
329
         * (non-Javadoc)
330
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getParentLayer()
331
         */
332
        public FLayers getParentLayer() {
333
                return parentLayer;
334
        }
335
336
337
        /*
338
         * (non-Javadoc)
339
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setParentLayer(com.iver.cit.gvsig.fmap.layers.FLayers)
340
         */
341
        public void setParentLayer(FLayers root) {
342 41302 jjdelcerro
                if (this.parentLayer != root){
343 40435 jjdelcerro
                        this.parentLayer = root;
344 41302 jjdelcerro
                        this.updateDrawVersion();
345 40435 jjdelcerro
                }
346 41302 jjdelcerro
        }
347 40435 jjdelcerro
348
        /**
349
         * <p>Inserts the projection to this layer.</p>
350
         *
351
         * @param proj information about the new projection
352
         *
353
         * @see #isReprojectable()
354
         * @see #reProject(MapControl)
355
         */
356
        public void setProjection(IProjection proj) {
357
                IProjection curProj = this.getProjection();
358
                if (curProj == proj) {
359
                        return;
360
                }
361
                if (curProj != null && curProj.equals(proj)){
362
                        return;
363
                }
364
                this.updateDrawVersion();
365
                this.metadataContainer.setDynValue(METADATA_CRS, proj);
366
                // Comprobar que la proyecci?n es la misma que la de FMap
367
                // Si no lo es, es una capa que est? reproyectada al vuelo
368
                if ((proj != null) && (getMapContext() != null)) {
369
                        if (proj != getMapContext().getProjection()) {
370
                                ICoordTrans ct = proj.getCT(getMapContext().getProjection());
371
                                setCoordTrans(ct);
372
                                logger.debug("Cambio proyecci?n: FMap con "
373
                                                + getMapContext().getProjection().getAbrev() + " y capa "
374
                                                + getName() + " con " + proj.getAbrev());
375
                        }
376
                }
377
        }
378
379
        /*
380
         * (non-Javadoc)
381
         * @see org.cresques.geo.Projected#getProjection()
382
         */
383
        public IProjection getProjection() {
384
                return (IProjection) this.metadataContainer.getDynValue(METADATA_CRS);
385
        }
386
387
        /**
388
         * <p>Changes the projection of this layer.</p>
389
         * <p>This method will be overloaded in each kind of layer, according its specific nature.</p>
390
         *
391
         * @param mapC <code>MapControl</code> instance that will reproject this layer
392
         *
393
         * @return <code>true<code> if the layer has been created calling {@link FLayers#addLayer(FLayer) FLayers#addLayer}. But returns <code>false</code>
394
         *  if the load control logic of this layer is in the reprojection method
395
         *
396
         * @see #isReprojectable()
397
         * @see #setProjection(IProjection)
398
         */
399
        public void reProject(ICoordTrans arg0) {
400
        }
401
402
        /**
403
         * Returns the transparency level of this layer, in the range 0-255 .
404
         *
405
         * @return the transparency level
406
         *
407
         * @see #setTransparency(int)
408
         */
409
        public int getTransparency() {
410
                return transparency;
411
        }
412
413
        /**
414
         * Inserts the transparency level for this layer, the range allowed is 0-255 .
415
         *
416
         * @param trans the transparency level
417
         *
418
         * @see #getTransparency()
419
         */
420
        public void setTransparency(int trans) {
421 41302 jjdelcerro
                if (this.transparency != trans){
422 40435 jjdelcerro
                        transparency = trans;
423 41302 jjdelcerro
                        this.updateDrawVersion();
424
                }
425 40435 jjdelcerro
        }
426
427 42877 fdiaz
428 40435 jjdelcerro
        /*
429
         * (non-Javadoc)
430
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getMapContext()
431
         */
432
        public MapContext getMapContext() {
433
                if (getParentLayer() != null) {
434
                        return getParentLayer().getMapContext();
435
                } else {
436
                        return null;
437
                }
438
        }
439
440
        /*
441
         * (non-Javadoc)
442
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#addLayerListener(com.iver.cit.gvsig.fmap.layers.LayerListener)
443
         */
444
        public boolean addLayerListener(LayerListener o) {
445 42811 jjdelcerro
            if( o == null ) {
446
                return true;
447
            }
448
            return layerListeners.add(o);
449 40435 jjdelcerro
        }
450
        /*
451
         * (non-Javadoc)
452
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getLayerListeners()
453
         */
454
        public LayerListener[] getLayerListeners() {
455
                return (LayerListener[])layerListeners.toArray(new LayerListener[0]);
456
        }
457
        /*
458
         * (non-Javadoc)
459
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#removeLayerListener(com.iver.cit.gvsig.fmap.layers.LayerListener)
460
         */
461
        public boolean removeLayerListener(LayerListener o) {
462
                return layerListeners.remove(o);
463
        }
464
        /**
465 41302 jjdelcerro
         *
466
         */
467
        private void callDrawValueChanged(LayerEvent e) {
468 42811 jjdelcerro
           for (LayerListener listener : this.layerListeners) {
469
               try {
470
                   listener.drawValueChanged(e);
471
               } catch (Exception ex) {
472
                   logger.warn("Error calling listener '"+listener.toString()+"'.", ex);
473
               }
474 42877 fdiaz
           }
475 41302 jjdelcerro
        }
476
        /**
477 40435 jjdelcerro
         * Called by the method {@linkplain #setName(String)}. Notifies all listeners associated to this layer,
478
         *  that its name has changed.
479
         *
480
         * @param e a layer event with the name of the property that has changed
481
         *
482
         * @see #setName(String)
483
         */
484
        private void callNameChanged(LayerEvent e) {
485 42811 jjdelcerro
           for (LayerListener listener : this.layerListeners) {
486
               try {
487
                   listener.nameChanged(e);
488
               } catch (Exception ex) {
489
                   logger.warn("Error calling listener '"+listener.toString()+"'.", ex);
490
               }
491 42877 fdiaz
           }
492 40435 jjdelcerro
        }
493
494
        /**
495
         * Called by the method {@linkplain #setVisible(boolean)}. Notifies all listeners associated to this layer,
496
         *  that its visibility has changed.
497
         *
498
         * @param e a layer event with the name of the property that has changed
499
         *
500
         * @see #setVisible(boolean)
501
         */
502
        private void callVisibilityChanged(LayerEvent e) {
503 42811 jjdelcerro
           for (LayerListener listener : this.layerListeners) {
504
               try {
505
                   listener.visibilityChanged(e);
506
               } catch (Exception ex) {
507
                   logger.warn("Error calling listener '"+listener.toString()+"'.", ex);
508
               }
509 42877 fdiaz
           }
510 40435 jjdelcerro
        }
511
512
        /**
513
         * Called by the method {@linkplain #setActive(boolean)}. Notifies all listeners associated to this layer,
514
         *  that its active state has changed.
515
         *
516
         * @param e a layer event with the name of the property that has changed
517
         *
518
         * @see #setActive(boolean)
519 42811 jjdelcerro
         */
520
       private void callActivationChanged(LayerEvent e) {
521
           for (LayerListener listener : this.layerListeners) {
522
               try {
523
                   listener.activationChanged(e);
524
               } catch (Exception ex) {
525
                   logger.warn("Error calling listener '"+listener.toString()+"'.", ex);
526
               }
527
           }
528
       }
529 40435 jjdelcerro
530
        /**
531
         * Returns the virtual layers associated to this layer.
532
         *
533
         * @return a node with the layers
534
         *
535
         * @see #setVirtualLayers(FLayers)
536
         */
537
        //        public FLayers getVirtualLayers() {
538
        //                return virtualLayers;
539
        //        }
540
541
        /**
542
         * Inserts virtual layers to this layer.
543
         *
544
         * @param virtualLayers a node with the layers
545
         *
546
         * @see #getVirtualLayers()
547
         */
548
        //        public void setVirtualLayers(FLayers virtualLayers) {
549
        //                this.virtualLayers = virtualLayers;
550
        //        }
551
552
        /**
553
         * Sets transformation coordinates for this layer.
554
         *
555
         * @param ct an object that implements the <code>ICoordTrans</code> interface, and with the transformation coordinates
556
         *
557
         * @see #getCoordTrans()
558
         */
559
        public void setCoordTrans(ICoordTrans ct) {
560 41302 jjdelcerro
                if (this.ct == ct){
561
                        return;
562
                }
563
                if (this.ct != null && this.ct.equals(ct)){
564
                        return;
565
                }
566 40435 jjdelcerro
                this.ct = ct;
567 41302 jjdelcerro
                this.updateDrawVersion();
568 40435 jjdelcerro
        }
569
570
        /**
571
         * Returns the transformation coordinates of this layer.
572
         *
573
         * @return an object that implements the <code>ICoordTrans</code> interface, and with the transformation coordinates
574
         *
575
         * @see #setCoordTrans(ICoordTrans)
576
         */
577
        public ICoordTrans getCoordTrans() {
578
                return ct;
579
        }
580
581
        /**
582
         * <p>Method called by {@link FLayers FLayers} to notify this layer that is going to be added.
583
         *  This previous notification is useful for the layers that need do something before being added. For
584
         *  example, the raster needs reopen a file that could have been closed recently.</p>
585 43271 jjdelcerro
     * @deprecated no deberia ser necesario llamar a esto, la capa debe comportarse correctamente sin necesidad de llamarlo.
586 40435 jjdelcerro
         */
587
        public void wakeUp() throws LoadLayerException {
588
        }
589
        /*
590
         * (non-Javadoc)
591
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getMinScale()
592
         */
593
        public double getMinScale() {
594
                return minScale;
595
        }
596
597
        /*
598
         * (non-Javadoc)
599
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getMaxScale()
600
         */
601
        public double getMaxScale() {
602
                return maxScale;
603
        }
604
        /*
605
         * (non-Javadoc)
606
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setMinScale(double)
607
         */
608
        public void setMinScale(double minScale) {
609
                if (this.minScale != minScale){
610
                        this.minScale = minScale;
611 41302 jjdelcerro
                        this.updateDrawVersion();
612
                }
613 40435 jjdelcerro
        }
614
        /*
615
         * (non-Javadoc)
616
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setMaxScale(double)
617
         */
618
        public void setMaxScale(double maxScale) {
619 41302 jjdelcerro
                if (this.maxScale != maxScale){
620 40435 jjdelcerro
                        this.maxScale = maxScale;
621 41302 jjdelcerro
                        this.updateDrawVersion();
622
                }
623 40435 jjdelcerro
        }
624
        /*
625
         * (non-Javadoc)
626
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isWithinScale(double)
627
         */
628
        public boolean isWithinScale(double scale) {
629
630
                boolean bVisible = true;
631
                if (getMinScale() != -1) {
632 41302 jjdelcerro
                        if (scale < getMinScale()){
633 40435 jjdelcerro
                                bVisible = false;
634
                        }
635
                }
636
                if (getMaxScale() != -1) {
637
                        if (scale > getMaxScale()) {
638
                                bVisible = false;
639
                        }
640
                }
641
642
                return bVisible;
643
        }
644
        /*
645
         * (non-Javadoc)
646
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setEditing(boolean)
647
         */
648
        public void setEditing(boolean b) throws StartEditionLayerException {
649
                status.editing = b;
650
        }
651
        /**
652
         * Called by some version of the method {@linkplain #setEditing(boolean)} overwritten. Notifies
653
         *  all listeners associated to this layer, that its edition state has changed.
654
         *
655
         * @param e a layer event with the name of the property that has changed
656
         *
657
         * @see #setEditing(boolean)
658
         */
659
        protected void callEditionChanged(LayerEvent e) {
660 42811 jjdelcerro
           for (LayerListener listener : this.layerListeners) {
661
               try {
662
                   listener.editionChanged(e);
663
               } catch (Exception ex) {
664
                   logger.warn("Error calling listener '"+listener.toString()+"'.", ex);
665
               }
666 42877 fdiaz
           }
667 42811 jjdelcerro
        }
668 42877 fdiaz
669 40435 jjdelcerro
        /*
670
         * (non-Javadoc)
671
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isEditing()
672
         */
673
        public boolean isEditing() {
674
                return status.editing;
675
        }
676
        /*
677
         * (non-Javadoc)
678
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getTocImageIcon()
679
         */
680
        public String getTocImageIcon() {
681
                return "layer-icon";
682
        }
683 42877 fdiaz
684 40435 jjdelcerro
        /*
685
         * (non-Javadoc)
686
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isInTOC()
687
         */
688
        public boolean isInTOC() {
689
                return status.inTOC;
690
        }
691
        /*
692
         * (non-Javadoc)
693
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setInTOC(boolean)
694
         */
695
        public void setInTOC(boolean b) {
696
                status.inTOC=b;
697
        }
698
        /*
699
         * (non-Javadoc)
700
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isAvailable()
701
         */
702
        public boolean isAvailable() {
703
                return status.available;
704
        }
705
        /*
706
         * (non-Javadoc)
707
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setAvailable(boolean)
708
         */
709
        public void setAvailable(boolean available) {
710 41302 jjdelcerro
                if (status.available != available){
711 40435 jjdelcerro
                        status.available = available;
712 41302 jjdelcerro
                        this.updateDrawVersion();
713
                }
714 40435 jjdelcerro
        }
715
        /*
716
         * (non-Javadoc)
717
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#reload()
718
         */
719
        public void reload() throws ReloadLayerException {
720 42877 fdiaz
            if(this.ct!=null){
721
                IProjection srcProj = this.ct.getPOrig();
722
                if(!this.getProjection().equals(srcProj)){
723
                    this.ct = this.getProjection().getCT(this.ct.getPDest());
724
                }
725
            }
726 40435 jjdelcerro
                this.setAvailable(true);
727
        }
728
729
        /*
730
         * (non-Javadoc)
731
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getFLayerStatus()
732
         */
733
        public FLayerStatus getFLayerStatus(){
734 41302 jjdelcerro
                return status.cloneStatus();
735 40435 jjdelcerro
        }
736
        /*
737
         * (non-Javadoc)
738
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#setFLayerStatus(com.iver.cit.gvsig.fmap.layers.FLayerStatus)
739
         */
740
        public void setFLayerStatus(FLayerStatus status){
741 41302 jjdelcerro
                if (!this.status.equals(status)){
742 40435 jjdelcerro
                        this.status = status;
743
                        this.updateDrawVersion();
744 41302 jjdelcerro
                }
745 40435 jjdelcerro
        }
746
747
        /*
748
         * (non-Javadoc)
749
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#isOk()
750
         */
751
752
        public boolean isOk(){
753
                return status.isOk();
754
        }
755
        /*
756
         * (non-Javadoc)
757
         * @see com.iver.cit.gvsig.fmap.layers.FLayer#getNumErrors()
758
         */
759
        public int getNumErrors(){
760
                return status.getNumErrors();
761
        }
762
763 43215 jjdelcerro
764
        @Override
765
        public Throwable getError(int i){
766 40435 jjdelcerro
                return status.getError(i);
767
        }
768 43215 jjdelcerro
769
        @Override
770
        public List<Throwable> getErrors(){
771 40435 jjdelcerro
                return status.getErrors();
772
        }
773
774 43215 jjdelcerro
    @Override
775
        public void addError(Throwable exception){
776 40435 jjdelcerro
                status.addLayerError(exception);
777
        }
778 42877 fdiaz
779 43215 jjdelcerro
        @Override
780
        public void setError(Throwable ex) {
781
                this.status.setLayerError(ex);
782
        }
783 42877 fdiaz
784 43215 jjdelcerro
        @Override
785 40435 jjdelcerro
        public boolean visibleRequired() {
786
                return status.visible;
787
        }
788 43215 jjdelcerro
789
    @Override
790 40435 jjdelcerro
        public String getInfoString() {
791 43141 jjdelcerro
            Envelope env = null;
792 43215 jjdelcerro
            DataStore store = null;
793 43141 jjdelcerro
            try {
794
                env = this.getFullEnvelope();
795
            } catch (ReadException ex) {
796
            }
797 43215 jjdelcerro
798
            try {
799
                store = ((SingleLayer)this).getDataStore();
800
            } catch(Throwable th) {
801
802
            }
803 43141 jjdelcerro
804
            LayerInformationBuilder builder = MapContextLocator.getMapContextManager().createLayerInformationBuilder();
805 43215 jjdelcerro
806
            if( store!=null ) {
807
                builder.title().labelkey("Data_source");
808
                builder.property().labelkey("Source_type").value(store.getProviderName());
809
                builder.property().labelkey("origen").value(store.getFullName());
810
                if( store.getParameters() instanceof FilesystemStoreParameters ) {
811
                    File f = ((FilesystemStoreParameters) (store.getParameters())).getFile();
812
                    if( f != null && f.exists() ) {
813
                        builder.property().labelkey("_Size").value("%d bytes", f.length());
814
                    }
815
                }
816
            }
817
818 43141 jjdelcerro
            builder.title().labelkey("_Coordenadas_geograficas");
819 43215 jjdelcerro
            if( this.isAvailable() ) {
820
                builder.envelope().value(env);
821
            }
822 43141 jjdelcerro
823
            builder.title().labelkey("_Projection");
824 43215 jjdelcerro
            if( this.isAvailable() ) {
825
                builder.property().value(this.getProjection());
826
                builder.text().asWKT(this.getProjection());
827
            }
828
829 43141 jjdelcerro
            return builder.toString();
830 40435 jjdelcerro
        }
831 43141 jjdelcerro
832 43215 jjdelcerro
        @Override
833 40435 jjdelcerro
        public boolean isWritable() {
834
                return status.writable;
835
        }
836
837 43215 jjdelcerro
        @Override
838 40435 jjdelcerro
        public FLayer cloneLayer() throws Exception {
839 43215 jjdelcerro
                logger.warn("Use of cloneLayer and this is not implemented.");
840 40435 jjdelcerro
                return this;
841
        }
842 43215 jjdelcerro
843
        @Override
844 40435 jjdelcerro
        public Image getTocStatusImage() {
845 41853 jjdelcerro
            return tocStatusImage;
846 40435 jjdelcerro
        }
847
848
        /**
849
         * Inserts the image icon that will be shown in the TOC next to this layer, according its status.
850
         *
851
         * @param tocStatusImage the image
852
         *
853
         * @see #getTocStatusImage()
854
         */
855
        public void setTocStatusImage(Image tocStatusImage) {
856
                this.tocStatusImage = tocStatusImage;
857
                logger.debug("setTocStatusImage " + tocStatusImage + " sobre capa " + this.getName());
858
        }
859 41853 jjdelcerro
860 40435 jjdelcerro
        public ComposedLayer newComposedLayer() {
861
                return null;
862
        }
863
864
        public boolean allowLinks()
865
        {
866
                return false;
867
        }
868
869
        public AbstractLinkProperties getLinkProperties()
870
        {
871
                return null;
872
        }
873
874
        public URI[] getLink(Point2D point, double tolerance) throws ReadException{
875
                return null;
876
        }
877
878
        public void addLegendListener(LegendListener listener) {
879 42811 jjdelcerro
            if( listener == null ) {
880
                return ;
881
            }
882
            layerChangeSupport.addLayerListener(listener);
883 40435 jjdelcerro
        }
884
885
        /**
886 42801 jjdelcerro
     * @param e
887 40435 jjdelcerro
         * @see LayerChangeSupport#callLegendChanged(LegendChangedEvent)
888
         */
889
        protected void callLegendChanged(LegendChangedEvent e) {
890
                layerChangeSupport.callLegendChanged(e);
891
                if(parentLayer != null) {
892
                        parentLayer.callLegendChanged(e);
893
                }
894
        }
895
896
        /**
897
         * @see LayerChangeSupport#removeLayerListener(LegendListener)
898
         */
899
        public void removeLegendListener(LegendListener listener) {
900
                layerChangeSupport.removeLayerListener(listener);
901
        }
902
        public String getClassName() {
903
                return this.getClass().getName();
904
        }
905
906
        public void delegate(DynObject dynObject) {
907
                this.metadataContainer.delegate(dynObject);
908
        }
909
910
        public DynClass getDynClass() {
911
                return this.metadataContainer.getDynClass();
912
        }
913
914
        public Object getDynValue(String name) throws DynFieldNotFoundException {
915
                return this.metadataContainer.getDynValue(name);
916
        }
917
918
        public boolean hasDynValue(String name) {
919
                return this.metadataContainer.hasDynValue(name);
920
        }
921
922
        public void implement(DynClass dynClass) {
923
                this.metadataContainer.implement(dynClass);
924
        }
925
926 42775 jjdelcerro
        public Object invokeDynMethod(int code, Object[] args)
927 40435 jjdelcerro
        throws DynMethodException {
928 42775 jjdelcerro
                return this.metadataContainer.invokeDynMethod(this, code, args);
929 40435 jjdelcerro
        }
930
931 42775 jjdelcerro
        public Object invokeDynMethod(String name, Object[] args)
932 40435 jjdelcerro
        throws DynMethodException {
933 42775 jjdelcerro
                return this.metadataContainer.invokeDynMethod(this, name, args);
934 40435 jjdelcerro
        }
935
936
        public void setDynValue(String name, Object value)
937
        throws DynFieldNotFoundException {
938
                this.metadataContainer.setDynValue(name, value);
939
        }
940
941
        public long getDrawVersion() {
942
                return this.drawVersion;
943
        }
944
945
        protected void updateDrawVersion(){
946
                this.drawVersion++;
947
                this.callDrawValueChanged(LayerEvent.createDrawValuesChangedEvent(this, ""));
948
                if (this.parentLayer != null){
949
                        this.parentLayer.updateDrawVersion();
950
                }
951
        }
952
953
        public boolean hasChangedForDrawing(long value){
954
                return this.drawVersion > value;
955
        }
956
957
        public void activationChanged(LayerEvent e) {
958
        }
959
960
        public void drawValueChanged(LayerEvent e) {
961
                this.updateDrawVersion();
962
        }
963
964
        public void editionChanged(LayerEvent e) {
965
966
        }
967
968
        public void nameChanged(LayerEvent e) {
969
970
        }
971
972
        public void visibilityChanged(LayerEvent e) {
973
974
        }
975 42877 fdiaz
976 40435 jjdelcerro
        // ========================================================
977 42877 fdiaz
978 40435 jjdelcerro
        public void saveToState(PersistentState state) throws PersistenceException {
979 41807 jjdelcerro
            try {
980 42293 jjdelcerro
                state.set("parentLayer", (Persistent)parentLayer);
981 40435 jjdelcerro
                state.set("status",status);
982
                state.set("minScale", minScale);
983
                state.set("maxScale", maxScale);
984
                state.set("transparency",transparency);
985
                state.set("coordTrans",ct);
986
                state.set("name", getName());
987
                state.set("crs", getProjection());
988 41350 jjdelcerro
                state.set("properties",properties.getExtendedProperties());
989 41807 jjdelcerro
            } catch(PersistenceException ex) {
990
                logger.warn("Can't save to persistent state the layer '"+this.getName()+"'.");
991
                throw ex;
992
            } catch(RuntimeException ex) {
993
                logger.warn("Can't save to persistent state the layer '"+this.getName()+"'.");
994
                throw ex;
995
            }
996 40435 jjdelcerro
        }
997
998 43215 jjdelcerro
        @Override
999 40435 jjdelcerro
        public void loadFromState(PersistentState state) throws PersistenceException {
1000 43215 jjdelcerro
                try {
1001
                        String name = state.getString("name");
1002
                        if( StringUtils.isEmpty(name) ) {
1003
                                name = "Unknown";
1004
                        }
1005
                        this.setDynValue(METADATA_NAME, name);
1006
                        this.setDynValue(METADATA_CRS, state.get("crs"));
1007 42877 fdiaz
1008 43215 jjdelcerro
                        this.parentLayer = (FLayers) state.get("parentLayer");
1009
                        this.status = (FLayerStatus) state.get("status");
1010
                        if( this.status == null ) {
1011
                                this.status = new FLayerStatus();
1012
                                this.setAvailable(false);
1013
                                this.addError(new RuntimeException("Can't retreieve the status of the layer."));
1014
                        }
1015
                        this.minScale = state.getDouble("minScale", -1);
1016
                        this.maxScale = state.getDouble("maxScale", -1);
1017
                        this.transparency = state.getInt("transparency", 255);
1018
                        this.ct = (ICoordTrans) state.get("coordTrans");
1019 40435 jjdelcerro
1020 43215 jjdelcerro
                        this.properties.setExtendedProperties((Map) state.get("properties"));
1021
                } catch (Exception ex) {
1022
                        logger.warn("Can't load from persietent state the layer '" + this.getName() + "'.");
1023
                        throw ex;
1024
                }
1025 41350 jjdelcerro
1026 40435 jjdelcerro
        }
1027 41840 jjdelcerro
    public static class RegisterPersistence implements Callable {
1028 40435 jjdelcerro
1029 43215 jjdelcerro
                @Override
1030
                public Object call() {
1031
                        PersistenceManager manager = ToolsLocator.getPersistenceManager();
1032
                        DynStruct definition = manager.addDefinition(
1033 40435 jjdelcerro
                                FLyrDefault.class,
1034
                                "FLyrDefault",
1035
                                "FLyrDefault Persistence definition",
1036 42877 fdiaz
                                null,
1037 40435 jjdelcerro
                                null
1038 43215 jjdelcerro
                        );
1039
                        definition.addDynFieldString("name").setMandatory(false);
1040
                        definition.addDynFieldInt("transparency").setMandatory(true);
1041
                        definition.addDynFieldDouble("minScale").setMandatory(true);
1042
                        definition.addDynFieldDouble("maxScale").setMandatory(true);
1043
                        definition.addDynFieldObject("crs").setClassOfValue(
1044
                                IProjection.class).setMandatory(false);
1045
                        definition.addDynFieldObject("parentLayer").setClassOfValue(
1046
                                FLayers.class).setMandatory(false);
1047
                        definition.addDynFieldObject("coordTrans").setClassOfValue(
1048
                                ICoordTrans.class).setMandatory(false);
1049
                        definition.addDynFieldObject("status").setClassOfValue(
1050
                                FLayerStatus.class).setMandatory(true);
1051
                        // "properties" deberia estar declarada como un "ExtendedPropertiesHelper"
1052
                        // pero por compatibilidad con proyectos viejos lo mantenemos como un
1053
                        // Map.
1054
//                        definition.addDynFieldObject("properties").setClassOfValue(
1055
//                                ExtendedPropertiesHelper.class)
1056
//                                .setMandatory(false);
1057
                        definition.addDynFieldMap("properties").setClassOfItems(Object.class)
1058 40435 jjdelcerro
                                .setMandatory(true);
1059 42877 fdiaz
1060 43215 jjdelcerro
                        return Boolean.TRUE;
1061
                }
1062 41840 jjdelcerro
    }
1063 41350 jjdelcerro
1064 42877 fdiaz
1065 40435 jjdelcerro
//        /**
1066
//         * Splits string into an array of strings
1067
//         * @param input input string
1068
//         * @param sep separator string
1069
//         * @return an array of strings
1070
//         */
1071
//        public static String[] splitString(String input, String sep) {
1072
//                return Pattern.compile(sep).split(input, 0);
1073
//        }
1074 42877 fdiaz
1075 40435 jjdelcerro
        public void clear() {
1076
                if (metadataContainer != null) {
1077
                        metadataContainer.clear();
1078
                }
1079
        }
1080 42877 fdiaz
1081 40435 jjdelcerro
    public String getMetadataName() throws MetadataException {
1082
        return FLayer.METADATA_DEFINITION_NAME;
1083
    }
1084 42877 fdiaz
1085 41840 jjdelcerro
        public static class RegisterMetadata implements Callable {
1086 40435 jjdelcerro
1087 41840 jjdelcerro
            public Object call() {
1088
                MetadataManager metadataManager = MetadataLocator.getMetadataManager();
1089 40435 jjdelcerro
1090 41840 jjdelcerro
                DynStruct metadataDefinition = metadataManager.getDefinition(FLayer.METADATA_DEFINITION_NAME);
1091
                if ( metadataDefinition == null ) {
1092
                    try {
1093
                        metadataDefinition = metadataManager.addDefinition(
1094
                                FLayer.METADATA_DEFINITION_NAME,
1095
                                FLayer.METADATA_DEFINITION_DESCRIPTION);
1096
                        metadataDefinition.addDynField(FLayer.METADATA_NAME)
1097
                                .setMandatory(true);
1098
1099
                        IProjection ipr
1100
                                = MapContextLocator.getMapContextManager().getDefaultCRS();
1101
1102
                        metadataDefinition.addDynFieldObject(FLayer.METADATA_CRS)
1103
                                .setType(DataTypes.CRS).setMandatory(true)
1104
                                .setDefaultFieldValue(ipr);
1105
                    } catch (MetadataException e) {
1106
                        logger.warn("Can't create metadata definition for 'Layer'", e);
1107
                    }
1108
                }
1109
                return Boolean.TRUE;
1110
            }
1111
        }
1112
1113 40435 jjdelcerro
        public String toString() {
1114 42651 jjdelcerro
                return this.getName();
1115 40435 jjdelcerro
        }
1116 42877 fdiaz
1117 40435 jjdelcerro
        public boolean hidesThisArea(Envelope area) {
1118
                return false;
1119
        }
1120 42877 fdiaz
1121 41853 jjdelcerro
        public boolean isTemporary() {
1122
            return this.temporary;
1123
        }
1124 42877 fdiaz
1125 41853 jjdelcerro
        public void setTemporary(boolean temporary) {
1126
            this.temporary = temporary;
1127
        }
1128 43979 omartinez
1129
        @Override
1130
        public int getDefaultTolerance() {
1131 44050 jjdelcerro
            return TOL;
1132 43979 omartinez
        }
1133 40435 jjdelcerro
}