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

History | View | Annotate | Download (30 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.awt.Dimension;
56
import java.beans.PropertyChangeEvent;
57
import java.beans.PropertyChangeListener;
58
import java.util.ArrayList;
59
import java.util.HashMap;
60
import java.util.List;
61
import java.util.Map;
62

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

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

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

    
109
    private static final long serialVersionUID = 2024899922367896097L;
110

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

    
114
    private Map<FLayer, Long> drawLayerStatus;
115

    
116
    private ObservableHelper observableHelper;
117

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

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

    
130
    private MapContext mapContext;
131

    
132
    private MapControlProperties3D properties;
133

    
134
    private ExtendedPropertiesSupport viewProperties;
135

    
136
    private WorldWindowGLJPanel wwd;
137

    
138
    private StatusBar statusBar;
139

    
140
    private TYPE type;
141

    
142
    private Cancellable cancellable;
143

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

    
159
        super(new BorderLayout());
160

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

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

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

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

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

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

    
188
        setGeneral3DProperties();
189

    
190
        View3DManager manager = View3DLocator.getManager();
191
        this.properties = manager.getMapControl3DProperties(viewProperties);
192
        addChangePropertyListener(this.properties);
193
        setMapControl3DProperties();
194
        
195
        addVerticalExaggerationChangeProperyListener();
196
    }
197

    
198
    private void setGeneral3DProperties() {
199

    
200
        View3DManager manager = View3DLocator.getManager();
201
        GeneralProperties3D general3DProperties =
202
            manager.getGeneral3DProperties();
203

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

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

    
217
            public void propertyChange(PropertyChangeEvent evt) {
218

    
219
                String propertyName = evt.getPropertyName();
220

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

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

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

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

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

    
247
    }
248

    
249
    private void addLayerCollectionListener(FLayers layers) {
250

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

    
255
        layers.addLayerCollectionListener(new LayerCollectionListener() {
256

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
383
        layers.accept(new LayersVisitor() {
384

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

    
389
            }
390

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

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

    
399
        getWwd().redraw();
400
    }
401

    
402
    protected void setBlueMarbelLayerVisibility(boolean visibility) {
403
        getProperties().setBlueMarbleLayerVisibility(visibility);
404
        setWWLayerVisibility("Blue Marble May 2004", visibility);
405
    }
406

    
407
    protected void setDefaultElevationVisibility(boolean visibility) {
408

    
409
        ElevationModel elevationModel =
410
            getWwd().getModel().getGlobe().getElevationModel();
411
        CompoundElevationModel compoundElevationModel =
412
            (CompoundElevationModel) elevationModel;
413
        List<ElevationModel> elevationModels =
414
            compoundElevationModel.getElevationModels();
415

    
416
        if (visibility) {
417
            for (ElevationModel eModel : elevationModels) {
418
                if (eModel instanceof ZeroElevationModel) {
419
                    compoundElevationModel.removeElevationModel(eModel);
420
                    compoundElevationModel
421
                        .addElevationModel(getDefaultElevationModel());
422
                    return;
423
                }
424
            }
425

    
426
        } else {
427
            for (ElevationModel eModel : elevationModels) {
428
                if (eModel.getName().equals("USA 10m, World 30m, Ocean 900m")) {
429
                    compoundElevationModel.removeElevationModel(eModel);
430
                    compoundElevationModel.addElevationModel(0,
431
                        new ZeroElevationModel());
432
                    return;
433
                }
434
            }
435
        }
436
        getProperties().setDefaultElevationVisibility(visibility);
437
    }
438
    
439
    private ElevationModel getDefaultElevationModel(){
440
        Factory elevationFactory =
441
            (Factory) WorldWind.createConfigurationComponent(AVKey.ELEVATION_MODEL_FACTORY);
442
        String defaultModelFile = Configuration.getStringValue(AVKey.EARTH_ELEVATION_MODEL_CONFIG_FILE);
443
        
444
        CompoundElevationModel elevationModel = (CompoundElevationModel) elevationFactory.createFromConfigSource(
445
            defaultModelFile, new AVListImpl());
446
        
447
        return elevationModel.getElevationModels().get(0);
448
    }
449

    
450
    protected void setNasaLandsatLayerVisibility(boolean visibility) {
451
        getProperties().setNasaLandsatVisibility(visibility);
452
        setWWLayerVisibility("i-cubed Landsat", visibility);
453
    }
454

    
455
    @SuppressWarnings("rawtypes")
456
    private void setWWLayerVisibility(Class layerClazz, boolean visiblity) {
457
        List<Layer> layersByClass =
458
            getWwd().getModel().getLayers().getLayersByClass(layerClazz);
459

    
460
        for (Layer layer : layersByClass) {
461
            layer.setEnabled(visiblity);
462
        }
463
    };
464

    
465
    private void setWWLayerVisibility(String layerName, boolean visibilty) {
466
        Layer layer = getWwd().getModel().getLayers().getLayerByName(layerName);
467
        if (layer != null) {
468
            layer.setEnabled(visibilty);
469
        }
470
    };
471

    
472
    private void addNavigation() {
473

    
474
        ViewControlsLayer controlsLayer = new ViewControlsLayer();
475

    
476
        Model model = getWwd().getModel();
477
        model.getLayers().add(controlsLayer);
478

    
479
        getWwd().addSelectListener(
480
            new ViewControlsSelectListener(wwd, controlsLayer));
481
    }
482

    
483
    public JComponent asJComponent() {
484
        return this;
485
    }
486

    
487
    public void dispose() {
488

    
489
        Thread disposeThread = new Thread(new Runnable() {
490

    
491
            public void run() {
492
                Notification beforeDisposeNotification =
493
                    new BaseNotification(
494
                        MapControl3D.BEFORE_DISPOSE_MAPCONTEX3D_NOTIFICATION,
495
                        null);
496

    
497
                observableHelper.notifyObservers(DefaultMapControl3D.this,
498
                    beforeDisposeNotification);
499

    
500
                while (WorldWind.getRetrievalService().hasActiveTasks()) {
501
                    try {
502
                        Thread.sleep(100);
503
                    } catch (InterruptedException e) {
504
                        LOG.warn("This thread has been interrupted, dispose action can not be performed");
505
                        return;
506
                    }
507
                }
508

    
509
                disposeWwd();
510

    
511
                if (getType() == TYPE.SPHERE) {
512
                    viewProperties.getExtendedProperties().remove(
513
                        "spehereMapControl3D");
514
                } else if (getType() == TYPE.FLAT) {
515
                    viewProperties.getExtendedProperties().remove(
516
                        "flatMapControl3D");
517
                }
518

    
519
                Notification afterDisposeNotification =
520
                    new BaseNotification(
521
                        MapControl3D.AFTER_DISPOSE_MAPCONTEX3D_NOTIFICATION,
522
                        null);
523

    
524
                observableHelper.notifyObservers(DefaultMapControl3D.this,
525
                    afterDisposeNotification);
526
            }
527
        }, "Dispose World Wind thread");
528

    
529
        disposeThread.start();
530
    }
531

    
532
    public Cancellable getCancellable() {
533
        if (this.cancellable == null) {
534
            this.cancellable = new Cancellable() {
535

    
536
                private boolean cancel = false;
537

    
538
                public void setCanceled(boolean canceled) {
539
                    this.cancel = canceled;
540
                }
541

    
542
                public boolean isCanceled() {
543
                    return cancel;
544
                }
545
            };
546
        }
547

    
548
        return this.cancellable;
549
    }
550

    
551
    public MapContext getMapContext() {
552
        return this.mapContext;
553
    }
554

    
555
    private StatusBar getStatusBar() {
556
        if (statusBar == null) {
557
            statusBar = new StatusBar();
558
            this.add(statusBar, BorderLayout.PAGE_END);
559
            statusBar.setEventSource(wwd);
560
        }
561
        return statusBar;
562
    }
563

    
564
    private Layer getTileImageLayer(FLayer layer) {
565
        List<Layer> layers =
566
            getWwd().getModel().getLayers()
567
                .getLayersByClass(DefaultTiledImageLayer.class);
568
        for (Layer tiledLayer : layers) {
569
            AVList constructionParams =
570
                (AVList) tiledLayer.getValue(AVKey.CONSTRUCTION_PARAMETERS);
571
            if (constructionParams != null) {
572
                FLayer likedLayer =
573
                    (FLayer) constructionParams.getValue(GVSIG_LAYER);
574
                if (layer.equals(likedLayer)) {
575
                    return tiledLayer;
576
                }
577
            }
578
        }
579
        return null;
580
    }
581

    
582
    public TYPE getType() {
583
        return this.type;
584
    }
585

    
586
    public double getVerticalExaggeration() {
587
        return getWwd().getSceneController().getVerticalExaggeration();
588
    }
589

    
590
    protected WorldWindowGLJPanel getWwd() {
591
        if (this.wwd == null) {
592
            intializeWWPanel();
593
        }
594
        return this.wwd;
595
    }
596

    
597
    private void disposeWwd() {
598
        if (getWwd() != null) {
599
            this.wwd = null;
600
        }
601
    }
602

    
603
    public void setAtmosphereVisibility(boolean visibility) {
604
        if (getType() == TYPE.SPHERE) {
605
            setWWLayerVisibility(SkyGradientLayer.class, visibility);
606
        } else if (getType() == TYPE.FLAT) {
607
            setWWLayerVisibility(SkyColorLayer.class, visibility);
608
        }
609
    }
610

    
611
    public void setMiniMapVisibility(boolean visiblity) {
612
        setWWLayerVisibility(WorldMapLayer.class, visiblity);
613
    }
614

    
615
    public void setNorthIndicatorVisibility(boolean visibility) {
616
        setWWLayerVisibility(CompassLayer.class, visibility);
617
    }
618

    
619
    public void setScaleVisibility(boolean visibility) {
620
        setWWLayerVisibility(ScalebarLayer.class, visibility);
621
    }
622

    
623
    public void setStarsBackgroundVisibility(boolean visibility) {
624
        setWWLayerVisibility(StarsLayer.class, visibility);
625
    }
626

    
627
    private void intializeWWPanel() {
628
        wwd = new WorldWindowGLJPanel();
629

    
630
        View3DManager manager = View3DLocator.getManager();
631
        GeneralProperties3D general3dProperties =
632
            manager.getGeneral3DProperties();
633
        wwd.setPreferredSize(new Dimension(general3dProperties
634
            .getDefaultViewWidht(), general3dProperties.getDefaultViewHeight()));
635

    
636
        // Create the default model as described in the current worldwind
637
        // properties.
638
        Model m =
639
            (Model) WorldWind
640
                .createConfigurationComponent(AVKey.MODEL_CLASS_NAME);
641
        getWwd().setModel(m);
642

    
643
        // Add view control layer
644
        addNavigation();
645
    }
646

    
647
    public void reloadLayers() {
648
        getWwd().getModel().getLayers().removeAll();
649

    
650
        if (this.mapContext != null && this.mapContext.getLayers() != null) {
651
            try {
652
                addGvSIGLayers(mapContext.getLayers());
653
            } catch (BaseException e) {
654
                LOG.error("Can't add MapContext layers of {}",
655
                    mapContext.getLayers(), e);
656
            }
657
        }
658
    }
659

    
660
    private void setFlatPanelConfiguration() {
661
        Configuration.setValue(AVKey.GLOBE_CLASS_NAME,
662
            EarthFlat.class.getName());
663
        Configuration.setValue(AVKey.VIEW_CLASS_NAME,
664
            FlatOrbitView.class.getName());
665
    }
666

    
667
    private void setMapControl3DProperties() {
668

    
669
        double verticalExaggeration = 0;
670
        if (getType() == TYPE.SPHERE) {
671
            verticalExaggeration =
672
                this.properties.getSphereVerticalExaggeration();
673
        } else if (getType() == TYPE.FLAT) {
674
            verticalExaggeration =
675
                this.properties.getFlatVerticalExaggeration();
676
        }
677
        setVerticalExaggeration(verticalExaggeration);
678

    
679
        boolean visibility = this.properties.getBlueMarbleLayerVisibility();
680
        setBlueMarbelLayerVisibility(visibility);
681

    
682
        visibility = this.properties.getNasaLandsatLayerVisibility();
683
        setNasaLandsatLayerVisibility(visibility);
684

    
685
        visibility = this.properties.getDefaultElevationVisibility();
686
        setDefaultElevationVisibility(visibility);
687
    }
688

    
689
    private void setSpherePanelConfiguration() {
690
        Configuration.setValue(AVKey.GLOBE_CLASS_NAME, Earth.class.getName());
691
        Configuration.setValue(AVKey.VIEW_CLASS_NAME,
692
            BasicOrbitView.class.getName());
693
    }
694

    
695
    public void setVerticalExaggeration(double verticalExaggeration) {
696
        
697
        if (getVerticalExaggeration() == verticalExaggeration) {
698
            return;
699
        }
700

    
701
        getWwd().getSceneController().setVerticalExaggeration(
702
            verticalExaggeration);
703
        
704
        if (getType() == TYPE.SPHERE) {
705
            getProperties().setSphereVerticalExaggeration(verticalExaggeration);
706
        } else if (getType() == TYPE.FLAT) {
707
            getProperties().setFlatVerticalExaggeration(verticalExaggeration);
708
        }
709
    }
710

    
711
    public synchronized void synchronizeLayers() {
712
        
713
        FLayers layers = this.mapContext.getLayers();
714
        
715
        // Remove old layers
716
        List<FLayer> layersRemoved = new ArrayList<FLayer>();
717
        for (FLayer layer : drawLayerStatus.keySet()) {
718
            if (layers.getLayer(layer.getName()) == null) {
719
                int index = removeGvSIGLayer(layer);
720
                if(index >= 0){
721
                    layersRemoved.add(layer);
722
                }
723
            }
724
        }
725
        for (FLayer fLayer : layersRemoved) {
726
            drawLayerStatus.remove(fLayer);
727
        }
728
        
729
        
730
        // Add new layers
731
        try {
732
            layers.accept(new LayersVisitor() {
733

    
734
                public void visit(Object obj) throws VisitCanceledException,
735
                    BaseException {
736
                    throw new UnsupportedOperationException();
737
                }
738

    
739
                public void visit(FLayer layer) throws BaseException {
740
                    
741
                    if(!drawLayerStatus.containsKey(layer)){
742
                        drawLayerStatus.put(layer, layer.getDrawVersion());
743
                        addGvSIGLayer(layer);
744
                    }
745
                }
746
            });
747
        } catch (BaseException e) {
748
            LOG.error("Can't synchronize layers. Can't visit layers of {}",
749
                mapContext.toString(), e);
750
        }
751
        
752
        // Update registered layers
753
        for (FLayer layer : drawLayerStatus.keySet()) {
754
            if (layer instanceof FLyrDefault) {
755
                FLyrDefault defaultLayer = (FLyrDefault) layer;
756

    
757
                if (defaultLayer.hasChangedForDrawing(drawLayerStatus
758
                    .get(layer))) {
759
                    replaceGvSIGLayer(defaultLayer);
760
                }
761
            }
762
        }
763
    }
764

    
765
    private int removeGvSIGLayer(FLayer layer) {
766
        List<Layer> loadedLayers = getWwd().getModel().getLayers();
767
        Layer tiledImageLayer = getTileImageLayer(layer);
768

    
769
        if (tiledImageLayer == null) {
770
            return -1;
771
        }
772

    
773
        int layerIndex = loadedLayers.indexOf(tiledImageLayer);
774
        getWwd().getModel().getLayers().remove(tiledImageLayer);
775
        return layerIndex;
776
    }
777

    
778
    private void replaceGvSIGLayer(FLayer layer) {
779
        // Remove layer without update drawLayerStatus map.
780
        List<Layer> loadedLayers = getWwd().getModel().getLayers();
781
        Layer tiledImageLayer = getTileImageLayer(layer);
782

    
783
        if (tiledImageLayer == null) {
784
            return;
785
        }
786

    
787
        int layerIndex = loadedLayers.indexOf(tiledImageLayer);
788
        getWwd().getModel().getLayers().remove(tiledImageLayer);
789

    
790
        // Add new layer at the same index
791
        if (layerIndex >= 0) {
792
            try {
793
                addGvSIGLayer(layer, layerIndex);
794
            } catch (DataException e) {
795
                LOG.error("Can't add {} at {}", new Object[] { layer.getName(),
796
                    layerIndex }, e);
797
            }
798
        }
799
    }
800

    
801
    public void synchronizeViewPorts() {
802
        // TODO
803
        throw new UnsupportedOperationException();
804
    }
805

    
806
    public void addObserver(Observer o) {
807
        if (observableHelper != null) {
808
            observableHelper.addObserver(o);
809
        }
810
    }
811

    
812
    public void deleteObserver(Observer o) {
813
        if (observableHelper != null) {
814
            observableHelper.deleteObserver(o);
815
        }
816

    
817
    }
818

    
819
    public void deleteObservers() {
820
        if (observableHelper != null) {
821
            observableHelper.deleteObservers();
822
        }
823
    }
824

    
825
    public boolean getAtmosphereVisibility() {
826
        if (isWWLayerVisible(SkyGradientLayer.class)
827
            || isWWLayerVisible(SkyColorLayer.class)) {
828
            return true;
829
        }
830
        return false;
831
    }
832

    
833
    public boolean getMinimapVisibility() {
834
        if (isWWLayerVisible(WorldMapLayer.class)) {
835
            return true;
836
        }
837
        return false;
838
    }
839

    
840
    public boolean getNorthIndicatorVisibility() {
841
        if (isWWLayerVisible(CompassLayer.class)) {
842
            return true;
843
        }
844
        return false;
845
    }
846

    
847
    public boolean getStarBackgroundVisibility() {
848
        if (isWWLayerVisible(StarsLayer.class)) {
849
            return true;
850
        }
851
        return false;
852
    }
853

    
854
    public boolean getScaleVisibility() {
855
        if (isWWLayerVisible(ScalebarLayer.class)) {
856
            return true;
857
        }
858
        return false;
859
    }
860

    
861
    @SuppressWarnings("rawtypes")
862
    private boolean isWWLayerVisible(Class clazz) {
863
        List<Layer> layersByClass =
864
            getWwd().getModel().getLayers().getLayersByClass(clazz);
865
        for (Layer layer : layersByClass) {
866
            return layer.isEnabled();
867
        }
868
        return false;
869
    }
870

    
871
    public MapControlProperties3D getProperties() {
872
        return properties;
873
    }
874
    
875
    private void addVerticalExaggerationChangeProperyListener() {
876
        getWwd().getSceneController().addPropertyChangeListener(new PropertyChangeListener() {
877
            
878
            public void propertyChange(PropertyChangeEvent evt) {
879
                String propertyName = evt.getPropertyName();
880
                if(propertyName.equals(AVKey.VERTICAL_EXAGGERATION)){
881
                    Double value = (Double) evt.getNewValue();
882
                    if(getType() == TYPE.SPHERE){
883
                        getProperties().setSphereVerticalExaggeration(value);
884
                    } else if(getType() == TYPE.FLAT){
885
                        getProperties().setFlatVerticalExaggeration(value);
886
                    }
887
                }
888
            }
889
        });
890
    }
891
}