Statistics
| Revision:

gvsig-3d / 2.1 / trunk / org.gvsig.view3d / org.gvsig.view3d.swing / org.gvsig.view3d.swing.impl / src / main / java / org / gvsig / view3d / swing / impl / DefaultMapControl3D.java @ 511

History | View | Annotate | Download (31.2 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright ? 2007-2015 gvSIG Association
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24

    
25
package org.gvsig.view3d.swing.impl;
26

    
27
import gov.nasa.worldwind.Configuration;
28
import gov.nasa.worldwind.Factory;
29
import gov.nasa.worldwind.Model;
30
import gov.nasa.worldwind.WorldWind;
31
import gov.nasa.worldwind.avlist.AVKey;
32
import gov.nasa.worldwind.avlist.AVList;
33
import gov.nasa.worldwind.avlist.AVListImpl;
34
import gov.nasa.worldwind.awt.WorldWindowGLJPanel;
35
import gov.nasa.worldwind.globes.Earth;
36
import gov.nasa.worldwind.globes.EarthFlat;
37
import gov.nasa.worldwind.globes.ElevationModel;
38
import gov.nasa.worldwind.layers.CompassLayer;
39
import gov.nasa.worldwind.layers.Layer;
40
import gov.nasa.worldwind.layers.LayerList;
41
import gov.nasa.worldwind.layers.ScalebarLayer;
42
import gov.nasa.worldwind.layers.SkyColorLayer;
43
import gov.nasa.worldwind.layers.SkyGradientLayer;
44
import gov.nasa.worldwind.layers.StarsLayer;
45
import gov.nasa.worldwind.layers.ViewControlsLayer;
46
import gov.nasa.worldwind.layers.ViewControlsSelectListener;
47
import gov.nasa.worldwind.layers.WorldMapLayer;
48
import gov.nasa.worldwind.terrain.CompoundElevationModel;
49
import gov.nasa.worldwind.terrain.ZeroElevationModel;
50
import gov.nasa.worldwind.util.StatusBar;
51
import gov.nasa.worldwind.view.orbit.BasicOrbitView;
52
import gov.nasa.worldwind.view.orbit.FlatOrbitView;
53

    
54
import java.awt.BorderLayout;
55
import java.beans.PropertyChangeEvent;
56
import java.beans.PropertyChangeListener;
57
import java.util.ArrayList;
58
import java.util.HashMap;
59
import java.util.List;
60
import java.util.Map;
61

    
62
import javax.swing.JComponent;
63
import javax.swing.JPanel;
64

    
65
import org.gvsig.fmap.dal.exception.DataException;
66
import org.gvsig.fmap.mapcontext.MapContext;
67
import org.gvsig.fmap.mapcontext.layers.CancelationException;
68
import org.gvsig.fmap.mapcontext.layers.ExtendedPropertiesSupport;
69
import org.gvsig.fmap.mapcontext.layers.FLayer;
70
import org.gvsig.fmap.mapcontext.layers.FLayers;
71
import org.gvsig.fmap.mapcontext.layers.FLyrDefault;
72
import org.gvsig.fmap.mapcontext.layers.LayerCollectionEvent;
73
import org.gvsig.fmap.mapcontext.layers.LayerCollectionListener;
74
import org.gvsig.fmap.mapcontext.layers.LayerEvent;
75
import org.gvsig.fmap.mapcontext.layers.LayerListener;
76
import org.gvsig.fmap.mapcontext.layers.LayerPositionEvent;
77
import org.gvsig.fmap.mapcontext.layers.operations.LayersVisitor;
78
import org.gvsig.tools.exception.BaseException;
79
import org.gvsig.tools.observer.BaseNotification;
80
import org.gvsig.tools.observer.Notification;
81
import org.gvsig.tools.observer.ObservableHelper;
82
import org.gvsig.tools.observer.Observer;
83
import org.gvsig.tools.task.Cancellable;
84
import org.gvsig.tools.visitor.VisitCanceledException;
85
import org.gvsig.view3d.lib.api.View3DLocator;
86
import org.gvsig.view3d.lib.api.View3DManager;
87
import org.gvsig.view3d.lib.api.properties.LayerProperties3D;
88
import org.gvsig.view3d.lib.api.properties.RasterLayerProperties3D;
89
import org.gvsig.view3d.lib.api.properties.VectorialLayerProperties3D;
90
import org.gvsig.view3d.swing.api.MapControl3D;
91
import org.gvsig.view3d.swing.api.View3DSwingLocator;
92
import org.gvsig.view3d.swing.api.View3DSwingManager;
93
import org.gvsig.view3d.swing.api.View3DSwingManager.TYPE;
94
import org.gvsig.view3d.swing.api.properties.GeneralProperties3D;
95
import org.gvsig.view3d.swing.api.properties.MapControlProperties3D;
96
import org.gvsig.view3d.swing.impl.data.DefaultLayerConverter;
97
import org.gvsig.view3d.swing.impl.data.DefaultTiledImageLayer;
98
import org.gvsig.view3d.swing.impl.data.LayerConverter;
99
import org.slf4j.Logger;
100
import org.slf4j.LoggerFactory;
101

    
102
/**
103
 * Default implementation of {@link MapControl3D}.
104
 * 
105
 * @author <a href="mailto:lmarques@disid.com">Lluis Marques</a>
106
 */
107
@SuppressWarnings("deprecation")
108
public class DefaultMapControl3D extends JPanel implements MapControl3D {
109

    
110
    private static final long serialVersionUID = 2024899922367896097L;
111

    
112
    private static final Logger LOG = LoggerFactory
113
        .getLogger(DefaultMapControl3D.class);
114

    
115
    private Map<FLayer, Long> drawLayerStatus;
116

    
117
    private ObservableHelper observableHelper;
118

    
119
    /**
120
     * Name of gvSIG MapContext property
121
     */
122
    public static final String GVSIG_MAPCONTROL3D =
123
        "org.gvsig.view3d.swing.api.MapControl3D";
124

    
125
    /**
126
     * Name of gvSIG Layer property
127
     */
128
    public static final String GVSIG_LAYER =
129
        "org.gvsig.fmap.mapcontext.layers.FLayer";
130

    
131
    private MapContext mapContext;
132

    
133
    private MapControlProperties3D properties;
134

    
135
    private ExtendedPropertiesSupport viewProperties;
136

    
137
    private WorldWindowGLJPanel wwd;
138

    
139
    private StatusBar statusBar;
140

    
141
    private TYPE type;
142

    
143
    private Cancellable cancellable;
144

    
145
    /**
146
     * Default constructor of {@link DefaultMapControl3D}. Initializes local
147
     * fileds, sets configuration depends on {@link TYPE} and adds
148
     * <code>MapContext</code> layers.
149
     * 
150
     * @param theMapContext
151
     *            associated <code>MapContext</code>
152
     * @param type
153
     *            Type of this {@link DefaultMapControl3D}. See {@link TYPE}.
154
     * @param viewProperties
155
     *            View properties to register this <code>MapControl3D</code>
156
     */
157
    public DefaultMapControl3D(MapContext theMapContext, TYPE type,
158
        ExtendedPropertiesSupport viewProperties) {
159

    
160
        super(new BorderLayout());
161

    
162
        this.mapContext = theMapContext;
163
        this.type = type;
164
        this.cancellable = getCancellable();
165
        this.observableHelper = new ObservableHelper();
166
        this.drawLayerStatus = new HashMap<FLayer, Long>();
167
        this.viewProperties = viewProperties;
168

    
169
        // Set mode before instantiation
170
        if (type == TYPE.SPHERE) {
171
            setSpherePanelConfiguration();
172
        } else if (type == TYPE.FLAT) {
173
            setFlatPanelConfiguration();
174
        }
175

    
176
        super.add(getWwd(), BorderLayout.CENTER);
177

    
178
        super.add(getStatusBar(), BorderLayout.SOUTH);
179

    
180
        try {
181
            addGvSIGLayers(mapContext.getLayers());
182
        } catch (BaseException e) {
183
            LOG.info("Can't add MapControl layers", e);
184
        }
185

    
186
        addLayerCollectionListener(mapContext.getLayers());
187
        addLayerListener(mapContext.getLayers());
188

    
189
        setGeneral3DProperties();
190

    
191
        View3DSwingManager swingManager = View3DSwingLocator.getManager();
192
        this.properties = swingManager.getMapControl3DProperties(viewProperties);
193
        addChangePropertyListener(this.properties);
194
        setMapControl3DProperties();
195
        
196
        addVerticalExaggerationChangeProperyListener();
197
    }
198

    
199
    private void setGeneral3DProperties() {
200

    
201
        View3DSwingManager swingManager = View3DSwingLocator.getManager();
202
        GeneralProperties3D general3DProperties =
203
            swingManager.getGeneral3DProperties();
204

    
205
        this.setAtmosphereVisibility(general3DProperties
206
            .getAtmosphereVisibility());
207
        this.setMiniMapVisibility(general3DProperties.getMinimapVisibility());
208
        this.setNorthIndicatorVisibility(general3DProperties
209
            .getNorthIndicatorVisibility());
210
        this.setStarsBackgroundVisibility(general3DProperties
211
            .getStarsBackgroundVisibility());
212
        this.setScaleVisibility(general3DProperties.getScaleVisibility());
213
    }
214

    
215
    private void addChangePropertyListener(MapControlProperties3D properties) {
216
        properties.addPropertyChangeListener(new PropertyChangeListener() {
217

    
218
            public void propertyChange(PropertyChangeEvent evt) {
219

    
220
                String propertyName = evt.getPropertyName();
221

    
222
                if (MapControlProperties3D.SPHERE_VERTICAL_EXAGGERATION_PROPERTY_NAME
223
                    .equals(propertyName) && getType() == TYPE.SPHERE) {
224
                    setVerticalExaggeration((Double) evt.getNewValue());
225

    
226
                } else if (MapControlProperties3D.FLAT_VERTICAL_EXAGGERATION_PROPERTY_NAME
227
                    .equals(propertyName) && getType() == TYPE.FLAT) {
228
                    setVerticalExaggeration((Double) evt.getNewValue());
229

    
230
                } else if (MapControlProperties3D.BLUE_MARBEL_VISIBILITY_PROPERTY_NAME
231
                    .equals(propertyName)) {
232
                    boolean visibility = (Boolean) evt.getNewValue();
233
                    setBlueMarbelLayerVisibility(visibility);
234

    
235
                } else if (MapControlProperties3D.NASA_LANDSAT_VISIBILITY_PROPERTY_NAME
236
                    .equals(propertyName)) {
237
                    boolean visibility = (Boolean) evt.getNewValue();
238
                    setNasaLandsatLayerVisibility(visibility);
239

    
240
                } else if (MapControlProperties3D.DEFAULT_ELEVATION_VISIBILITY_PROPERTY_NAME
241
                    .equals(propertyName)) {
242
                    boolean visibility = (Boolean) evt.getNewValue();
243
                    setDefaultElevationVisibility(visibility);
244
                }
245
            }
246
        });
247

    
248
    }
249

    
250
    private void addLayerCollectionListener(FLayers layers) {
251

    
252
        if (layers == null) {
253
            return;
254
        }
255

    
256
        layers.addLayerCollectionListener(new LayerCollectionListener() {
257

    
258
            public void visibilityChanged(LayerCollectionEvent e)
259
                throws CancelationException {
260
            }
261

    
262
            public void layerRemoving(LayerCollectionEvent e)
263
                throws CancelationException {
264
            }
265

    
266
            public void layerRemoved(LayerCollectionEvent e) {
267
                if(properties.getAutoLayerSynchronize()){
268
                    synchronizeLayers();
269
                }
270
            }
271

    
272
            public void layerMoving(LayerPositionEvent e)
273
                throws CancelationException {
274
            }
275

    
276
            public void layerMoved(LayerPositionEvent e) {
277
                int oldPos = e.getOldPos();
278
                int newPos = e.getNewPos();
279
                FLayer layer = e.getAffectedLayer();
280

    
281
                LayerList layers = getWwd().getModel().getLayers();
282
                Layer tileImageLayer = getTileImageLayer(layer);
283
                int tiledIndex = layers.indexOf(tileImageLayer);
284

    
285
                layers.remove(tiledIndex);
286
                layers.add(tiledIndex + (newPos - oldPos), tileImageLayer);
287
            }
288

    
289
            public void layerAdding(LayerCollectionEvent e)
290
                throws CancelationException {
291
            }
292

    
293
            public void layerAdded(LayerCollectionEvent e) {
294
                FLayer affectedLayer = e.getAffectedLayer();
295
                affectedLayer.addLayerListener(getLayerListener());
296
                if(properties.getAutoLayerSynchronize()){
297
                    synchronizeLayers();
298
                }
299
            }
300
        });
301
    }
302

    
303
    private void addLayerListener(FLayer layer) {
304
        if (layer == null) {
305
            return;
306
        }
307
        layer.addLayerListener(getLayerListener());
308
    }
309

    
310
    private LayerListener getLayerListener() {
311
        return new LayerListener() {
312

    
313
            public void visibilityChanged(LayerEvent e) {
314
                if(properties.getAutoLayerSynchronize()){
315
                    FLayer layer = e.getSource();
316
                    Layer tiledImageLayer = getTileImageLayer(layer);
317
                    if (tiledImageLayer != null) {
318
                        tiledImageLayer.setEnabled(layer.isVisible());
319
                    }
320
                }
321
            }
322

    
323
            public void nameChanged(LayerEvent e) {
324
            }
325

    
326
            public void editionChanged(LayerEvent e) {
327
            }
328

    
329
            public void drawValueChanged(LayerEvent e) {
330
                MapControlProperties3D properties = getProperties();
331
                if (properties.getAutoLayerSynchronize()) {
332
                    FLayer layer = e.getSource();
333
                    if (layer.isAvailable()) {
334
                        synchronizeLayers();
335
                    }
336
                }
337
            }
338

    
339
            public void activationChanged(LayerEvent e) {
340
            }
341
        };
342
    }
343

    
344
    private void addGvSIGLayer(FLayer layer) throws DataException {
345
        LayerList layers = getWwd().getModel().getLayers();
346
        addGvSIGLayer(layer, layers.size());
347
    }
348

    
349
    private void addGvSIGLayer(FLayer layer, int index) throws DataException {
350
        LayerConverter converter = new DefaultLayerConverter();
351

    
352
        View3DManager manager = View3DLocator.getManager();
353
        LayerProperties3D layerProperties = manager.getLayerProperties(layer);
354

    
355
        if (layerProperties.getElevation() == false) {
356

    
357
            if ((layerProperties instanceof VectorialLayerProperties3D && ((VectorialLayerProperties3D) layerProperties)
358
                .getRasterized() == true)
359
                || layerProperties instanceof RasterLayerProperties3D) {
360

    
361
                Layer rasterTiledLayer = converter.convertToLayer(this, layer);
362
                rasterTiledLayer.setEnabled(layer.isVisible());
363
                getWwd().getModel().getLayers().add(index, rasterTiledLayer);
364
                drawLayerStatus.put(layer, layer.getDrawVersion());
365

    
366
            } else {
367
                return; // TODO Convert to 3D vectorial layer
368
            }
369
        } else {
370
            ElevationModel elevationModel =
371
                converter.convertToElevationModel(this, layer);
372
            CompoundElevationModel cem =
373
                (CompoundElevationModel) getWwd().getModel().getGlobe()
374
                    .getElevationModel();
375
            cem.addElevationModel(elevationModel);
376
        }
377
    }
378

    
379
    private void addGvSIGLayers(FLayers layers) throws BaseException {
380
        if (layers == null) {
381
            return;
382
        }
383

    
384
        layers.accept(new LayersVisitor() {
385

    
386
            public void visit(Object obj) throws VisitCanceledException,
387
                BaseException {
388
                throw new UnsupportedOperationException();
389

    
390
            }
391

    
392
            public void visit(FLayer layer) throws BaseException {
393

    
394
                if (layer.isAvailable()) {
395
                    addGvSIGLayer(layer);
396
                }
397
            }
398
        });
399

    
400
        getWwd().redraw();
401
    }
402
    
403
    private void setBlueMarbelLayerVisibility(boolean visibility) {
404
        
405
        if(visibility == getBlueMarbleLayerVisibility()){
406
            return;
407
        }
408
        
409
        setWWLayerVisibility("Blue Marble May 2004", visibility);
410
        getProperties().setBlueMarbleLayerVisibility(visibility);
411
    }
412
    
413
    private boolean getBlueMarbleLayerVisibility(){
414
        return isWWLayerVisible("Blue Marble May 2004");
415
    }
416

    
417
    protected void setDefaultElevationVisibility(boolean visibility) {
418
        
419
        ElevationModel elevationModel =
420
            getWwd().getModel().getGlobe().getElevationModel();
421
        CompoundElevationModel compoundElevationModel =
422
            (CompoundElevationModel) elevationModel;
423
        List<ElevationModel> elevationModels =
424
            compoundElevationModel.getElevationModels();
425
        
426
        if(visibility == getDefaultElevationModelVisiblility()){
427
            return;
428
        }
429

    
430
        if (visibility) {
431
            for (ElevationModel eModel : elevationModels) {
432
                if (eModel instanceof ZeroElevationModel) {
433
                    compoundElevationModel.removeElevationModel(eModel);
434
                    compoundElevationModel
435
                        .addElevationModel(0,getDefaultElevationModel());
436
                    return;
437
                }
438
            }
439

    
440
        } else {
441
            for (ElevationModel eModel : elevationModels) {
442
                if (eModel.getName().equals("USA 10m, World 30m, Ocean 900m")) {
443
                    compoundElevationModel.removeElevationModel(eModel);
444
                    compoundElevationModel.addElevationModel(0,
445
                        new ZeroElevationModel());
446
                    return;
447
                }
448
            }
449
        }
450
        getProperties().setDefaultElevationVisibility(visibility);
451
    }
452
    
453
    private boolean getDefaultElevationModelVisiblility(){
454
        ElevationModel elevationModel =
455
            getWwd().getModel().getGlobe().getElevationModel();
456
        CompoundElevationModel compoundElevationModel =
457
            (CompoundElevationModel) elevationModel;
458
        List<ElevationModel> elevationModels =
459
            compoundElevationModel.getElevationModels();
460
        for (ElevationModel eModel : elevationModels) {
461
            if (eModel.getName().equals("USA 10m, World 30m, Ocean 900m")) {
462
                return true;
463
            }
464
        }
465
        return false;
466
    }
467
    
468
    private ElevationModel getDefaultElevationModel(){
469
        Factory elevationFactory =
470
            (Factory) WorldWind.createConfigurationComponent(AVKey.ELEVATION_MODEL_FACTORY);
471
        String defaultModelFile = Configuration.getStringValue(AVKey.EARTH_ELEVATION_MODEL_CONFIG_FILE);
472
        
473
        CompoundElevationModel elevationModel = (CompoundElevationModel) elevationFactory.createFromConfigSource(
474
            defaultModelFile, new AVListImpl());
475
        
476
        return elevationModel.getElevationModels().get(0);
477
    }
478

    
479
    private void setNasaLandsatLayerVisibility(boolean visibility) {
480
        
481
        if(visibility == getNasaLandsatLayerVisibility()){
482
            return;
483
        }
484
        
485
        setWWLayerVisibility("i-cubed Landsat", visibility);
486
        getProperties().setNasaLandsatVisibility(visibility);
487
    }
488
    
489
    private boolean getNasaLandsatLayerVisibility(){
490
        return isWWLayerVisible("i-cubed Landsat");
491
    }
492

    
493
    @SuppressWarnings("rawtypes")
494
    private void setWWLayerVisibility(Class layerClazz, boolean visiblity) {
495
        List<Layer> layersByClass =
496
            getWwd().getModel().getLayers().getLayersByClass(layerClazz);
497

    
498
        for (Layer layer : layersByClass) {
499
            layer.setEnabled(visiblity);
500
        }
501
    };
502

    
503
    private void setWWLayerVisibility(String layerName, boolean visibilty) {
504
        Layer layer = getWwd().getModel().getLayers().getLayerByName(layerName);
505
        if (layer != null) {
506
            layer.setEnabled(visibilty);
507
        }
508
    };
509

    
510
    private void addNavigation() {
511

    
512
        ViewControlsLayer controlsLayer = new ViewControlsLayer();
513

    
514
        Model model = getWwd().getModel();
515
        model.getLayers().add(controlsLayer);
516

    
517
        getWwd().addSelectListener(
518
            new ViewControlsSelectListener(wwd, controlsLayer));
519
    }
520

    
521
    public JComponent asJComponent() {
522
        return this;
523
    }
524

    
525
    public void dispose() {
526

    
527
        Thread disposeThread = new Thread(new Runnable() {
528

    
529
            public void run() {
530
                Notification beforeDisposeNotification =
531
                    new BaseNotification(
532
                        MapControl3D.BEFORE_DISPOSE_MAPCONTEX3D_NOTIFICATION,
533
                        null);
534

    
535
                observableHelper.notifyObservers(DefaultMapControl3D.this,
536
                    beforeDisposeNotification);
537

    
538
                while (WorldWind.getRetrievalService().hasActiveTasks()) {
539
                    try {
540
                        Thread.sleep(100);
541
                    } catch (InterruptedException e) {
542
                        LOG.warn("This thread has been interrupted, dispose action can not be performed");
543
                        return;
544
                    }
545
                }
546

    
547
                disposeWwd();
548

    
549
                if (getType() == TYPE.SPHERE) {
550
                    viewProperties.getExtendedProperties().remove(
551
                        "spehereMapControl3D");
552
                } else if (getType() == TYPE.FLAT) {
553
                    viewProperties.getExtendedProperties().remove(
554
                        "flatMapControl3D");
555
                }
556

    
557
                Notification afterDisposeNotification =
558
                    new BaseNotification(
559
                        MapControl3D.AFTER_DISPOSE_MAPCONTEX3D_NOTIFICATION,
560
                        null);
561

    
562
                observableHelper.notifyObservers(DefaultMapControl3D.this,
563
                    afterDisposeNotification);
564
            }
565
        }, "Dispose World Wind thread");
566

    
567
        disposeThread.start();
568
    }
569

    
570
    public Cancellable getCancellable() {
571
        if (this.cancellable == null) {
572
            this.cancellable = new Cancellable() {
573

    
574
                private boolean cancel = false;
575

    
576
                public void setCanceled(boolean canceled) {
577
                    this.cancel = canceled;
578
                }
579

    
580
                public boolean isCanceled() {
581
                    return cancel;
582
                }
583
            };
584
        }
585

    
586
        return this.cancellable;
587
    }
588

    
589
    public MapContext getMapContext() {
590
        return this.mapContext;
591
    }
592

    
593
    private StatusBar getStatusBar() {
594
        if (statusBar == null) {
595
            statusBar = new StatusBar();
596
            this.add(statusBar, BorderLayout.PAGE_END);
597
            statusBar.setEventSource(wwd);
598
        }
599
        return statusBar;
600
    }
601

    
602
    private Layer getTileImageLayer(FLayer layer) {
603
        List<Layer> layers =
604
            getWwd().getModel().getLayers()
605
                .getLayersByClass(DefaultTiledImageLayer.class);
606
        for (Layer tiledLayer : layers) {
607
            AVList constructionParams =
608
                (AVList) tiledLayer.getValue(AVKey.CONSTRUCTION_PARAMETERS);
609
            if (constructionParams != null) {
610
                FLayer likedLayer =
611
                    (FLayer) constructionParams.getValue(GVSIG_LAYER);
612
                if (layer.equals(likedLayer)) {
613
                    return tiledLayer;
614
                }
615
            }
616
        }
617
        return null;
618
    }
619

    
620
    public TYPE getType() {
621
        return this.type;
622
    }
623

    
624
    public double getVerticalExaggeration() {
625
        return getWwd().getSceneController().getVerticalExaggeration();
626
    }
627

    
628
    protected WorldWindowGLJPanel getWwd() {
629
        if (this.wwd == null) {
630
            intializeWWPanel();
631
        }
632
        return this.wwd;
633
    }
634

    
635
    private void disposeWwd() {
636
        if (getWwd() != null) {
637
            this.wwd = null;
638
        }
639
    }
640

    
641
    public void setAtmosphereVisibility(boolean visibility) {
642
        if (getType() == TYPE.SPHERE) {
643
            setWWLayerVisibility(SkyGradientLayer.class, visibility);
644
        } else if (getType() == TYPE.FLAT) {
645
            setWWLayerVisibility(SkyColorLayer.class, visibility);
646
        }
647
    }
648

    
649
    public void setMiniMapVisibility(boolean visiblity) {
650
        setWWLayerVisibility(WorldMapLayer.class, visiblity);
651
    }
652

    
653
    public void setNorthIndicatorVisibility(boolean visibility) {
654
        setWWLayerVisibility(CompassLayer.class, visibility);
655
    }
656

    
657
    public void setScaleVisibility(boolean visibility) {
658
        setWWLayerVisibility(ScalebarLayer.class, visibility);
659
    }
660

    
661
    public void setStarsBackgroundVisibility(boolean visibility) {
662
        setWWLayerVisibility(StarsLayer.class, visibility);
663
    }
664

    
665
    private void intializeWWPanel() {
666
        wwd = new WorldWindowGLJPanel();
667

    
668
        // Create the default model as described in the current worldwind
669
        // properties.
670
        Model m =
671
            (Model) WorldWind
672
                .createConfigurationComponent(AVKey.MODEL_CLASS_NAME);
673
        getWwd().setModel(m);
674

    
675
        // Add view control layer
676
        addNavigation();
677
    }
678

    
679
    public void reloadLayers() {
680
        getWwd().getModel().getLayers().removeAll();
681

    
682
        if (this.mapContext != null && this.mapContext.getLayers() != null) {
683
            try {
684
                addGvSIGLayers(mapContext.getLayers());
685
            } catch (BaseException e) {
686
                LOG.error("Can't add MapContext layers of {}",
687
                    mapContext.getLayers(), e);
688
            }
689
        }
690
    }
691

    
692
    private void setFlatPanelConfiguration() {
693
        Configuration.setValue(AVKey.GLOBE_CLASS_NAME,
694
            EarthFlat.class.getName());
695
        Configuration.setValue(AVKey.VIEW_CLASS_NAME,
696
            FlatOrbitView.class.getName());
697
    }
698

    
699
    private void setMapControl3DProperties() {
700

    
701
        double verticalExaggeration = 0;
702
        if (getType() == TYPE.SPHERE) {
703
            verticalExaggeration =
704
                this.properties.getSphereVerticalExaggeration();
705
        } else if (getType() == TYPE.FLAT) {
706
            verticalExaggeration =
707
                this.properties.getFlatVerticalExaggeration();
708
        }
709
        setVerticalExaggeration(verticalExaggeration);
710

    
711
        boolean visibility = this.properties.getBlueMarbleLayerVisibility();
712
        setBlueMarbelLayerVisibility(visibility);
713

    
714
        visibility = this.properties.getNasaLandsatLayerVisibility();
715
        setNasaLandsatLayerVisibility(visibility);
716

    
717
        visibility = this.properties.getDefaultElevationVisibility();
718
        setDefaultElevationVisibility(visibility);
719
    }
720

    
721
    private void setSpherePanelConfiguration() {
722
        Configuration.setValue(AVKey.GLOBE_CLASS_NAME, Earth.class.getName());
723
        Configuration.setValue(AVKey.VIEW_CLASS_NAME,
724
            BasicOrbitView.class.getName());
725
    }
726

    
727
    public void setVerticalExaggeration(double verticalExaggeration) {
728
        
729
        if (getVerticalExaggeration() == verticalExaggeration) {
730
            return;
731
        }
732

    
733
        getWwd().getSceneController().setVerticalExaggeration(
734
            verticalExaggeration);
735
        
736
        if (getType() == TYPE.SPHERE) {
737
            getProperties().setSphereVerticalExaggeration(verticalExaggeration);
738
        } else if (getType() == TYPE.FLAT) {
739
            getProperties().setFlatVerticalExaggeration(verticalExaggeration);
740
        }
741
    }
742

    
743
    public synchronized void synchronizeLayers() {
744
        
745
        FLayers layers = this.mapContext.getLayers();
746
        
747
        // Remove old layers
748
        List<FLayer> layersRemoved = new ArrayList<FLayer>();
749
        for (FLayer layer : drawLayerStatus.keySet()) {
750
            if (layers.getLayer(layer.getName()) == null) {
751
                int index = removeGvSIGLayer(layer);
752
                if(index >= 0){
753
                    layersRemoved.add(layer);
754
                }
755
            }
756
        }
757
        for (FLayer fLayer : layersRemoved) {
758
            drawLayerStatus.remove(fLayer);
759
        }
760
        
761
        
762
        // Add new layers
763
        try {
764
            layers.accept(new LayersVisitor() {
765

    
766
                public void visit(Object obj) throws VisitCanceledException,
767
                    BaseException {
768
                    throw new UnsupportedOperationException();
769
                }
770

    
771
                public void visit(FLayer layer) throws BaseException {
772
                    
773
                    if(!drawLayerStatus.containsKey(layer)){
774
                        drawLayerStatus.put(layer, layer.getDrawVersion());
775
                        addGvSIGLayer(layer);
776
                    }
777
                }
778
            });
779
        } catch (BaseException e) {
780
            LOG.error("Can't synchronize layers. Can't visit layers of {}",
781
                mapContext.toString(), e);
782
        }
783
        
784
        // Update registered layers
785
        for (FLayer layer : drawLayerStatus.keySet()) {
786
            if (layer instanceof FLyrDefault) {
787
                FLyrDefault defaultLayer = (FLyrDefault) layer;
788

    
789
                if (defaultLayer.hasChangedForDrawing(drawLayerStatus
790
                    .get(layer))) {
791
                    replaceGvSIGLayer(defaultLayer);
792
                }
793
            }
794
        }
795
    }
796

    
797
    private int removeGvSIGLayer(FLayer layer) {
798
        List<Layer> loadedLayers = getWwd().getModel().getLayers();
799
        Layer tiledImageLayer = getTileImageLayer(layer);
800

    
801
        if (tiledImageLayer == null) {
802
            return -1;
803
        }
804

    
805
        int layerIndex = loadedLayers.indexOf(tiledImageLayer);
806
        getWwd().getModel().getLayers().remove(tiledImageLayer);
807
        return layerIndex;
808
    }
809

    
810
    private void replaceGvSIGLayer(FLayer layer) {
811
        // Remove layer without update drawLayerStatus map.
812
        List<Layer> loadedLayers = getWwd().getModel().getLayers();
813
        Layer tiledImageLayer = getTileImageLayer(layer);
814

    
815
        if (tiledImageLayer == null) {
816
            return;
817
        }
818

    
819
        int layerIndex = loadedLayers.indexOf(tiledImageLayer);
820
        getWwd().getModel().getLayers().remove(tiledImageLayer);
821

    
822
        // Add new layer at the same index
823
        if (layerIndex >= 0) {
824
            try {
825
                addGvSIGLayer(layer, layerIndex);
826
            } catch (DataException e) {
827
                LOG.error("Can't add {} at {}", new Object[] { layer.getName(),
828
                    layerIndex }, e);
829
            }
830
        }
831
    }
832

    
833
    public void synchronizeViewPorts() {
834
        // TODO
835
        throw new UnsupportedOperationException();
836
    }
837

    
838
    public void addObserver(Observer o) {
839
        if (observableHelper != null) {
840
            observableHelper.addObserver(o);
841
        }
842
    }
843

    
844
    public void deleteObserver(Observer o) {
845
        if (observableHelper != null) {
846
            observableHelper.deleteObserver(o);
847
        }
848

    
849
    }
850

    
851
    public void deleteObservers() {
852
        if (observableHelper != null) {
853
            observableHelper.deleteObservers();
854
        }
855
    }
856

    
857
    public boolean getAtmosphereVisibility() {
858
        if (isWWLayerVisible(SkyGradientLayer.class)
859
            || isWWLayerVisible(SkyColorLayer.class)) {
860
            return true;
861
        }
862
        return false;
863
    }
864

    
865
    public boolean getMinimapVisibility() {
866
        if (isWWLayerVisible(WorldMapLayer.class)) {
867
            return true;
868
        }
869
        return false;
870
    }
871

    
872
    public boolean getNorthIndicatorVisibility() {
873
        if (isWWLayerVisible(CompassLayer.class)) {
874
            return true;
875
        }
876
        return false;
877
    }
878

    
879
    public boolean getStarBackgroundVisibility() {
880
        if (isWWLayerVisible(StarsLayer.class)) {
881
            return true;
882
        }
883
        return false;
884
    }
885

    
886
    public boolean getScaleVisibility() {
887
        if (isWWLayerVisible(ScalebarLayer.class)) {
888
            return true;
889
        }
890
        return false;
891
    }
892

    
893
    @SuppressWarnings("rawtypes")
894
    private boolean isWWLayerVisible(Class clazz) {
895
        List<Layer> layersByClass =
896
            getWwd().getModel().getLayers().getLayersByClass(clazz);
897
        for (Layer layer : layersByClass) {
898
            return layer.isEnabled();
899
        }
900
        return false;
901
    }
902
    
903
    private boolean isWWLayerVisible(String name) {
904
        Layer layer = getWwd().getModel().getLayers().getLayerByName(name);
905
        if(layer != null){
906
            return layer.isEnabled();
907
        }
908
        return false;
909
    }
910

    
911
    public MapControlProperties3D getProperties() {
912
        return properties;
913
    }
914
    
915
    private void addVerticalExaggerationChangeProperyListener() {
916
        getWwd().getSceneController().addPropertyChangeListener(new PropertyChangeListener() {
917
            
918
            public void propertyChange(PropertyChangeEvent evt) {
919
                String propertyName = evt.getPropertyName();
920
                if(propertyName.equals(AVKey.VERTICAL_EXAGGERATION)){
921
                    Double value = (Double) evt.getNewValue();
922
                    if(getType() == TYPE.SPHERE){
923
                        getProperties().setSphereVerticalExaggeration(value);
924
                    } else if(getType() == TYPE.FLAT){
925
                        getProperties().setFlatVerticalExaggeration(value);
926
                    }
927
                }
928
            }
929
        });
930
    }
931
}