Statistics
| Revision:

gvsig-3d / 2.1 / branches / org.gvsig.view3d_vector_and_extrusion_2.3 / org.gvsig.view3d / org.gvsig.view3d / org.gvsig.view3d.swing / org.gvsig.view3d.swing.impl / src / main / java / org / gvsig / view3d / swing / impl / DefaultMapControl3D.java @ 734

History | View | Annotate | Download (29.9 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 java.awt.BorderLayout;
28
import java.beans.PropertyChangeEvent;
29
import java.beans.PropertyChangeListener;
30
import java.util.List;
31

    
32
import javax.swing.JComponent;
33
import javax.swing.JPanel;
34

    
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

    
38
import org.gvsig.fmap.mapcontext.MapContext;
39
import org.gvsig.fmap.mapcontext.layers.ExtendedPropertiesSupport;
40
import org.gvsig.fmap.mapcontext.layers.FLayer;
41
import org.gvsig.fmap.mapcontext.layers.FLayers;
42
import org.gvsig.fmap.mapcontext.layers.operations.LayersVisitor;
43
import org.gvsig.tools.exception.BaseException;
44
import org.gvsig.tools.observer.BaseNotification;
45
import org.gvsig.tools.observer.Notification;
46
import org.gvsig.tools.observer.ObservableHelper;
47
import org.gvsig.tools.observer.Observer;
48
import org.gvsig.tools.task.Cancellable;
49
import org.gvsig.tools.visitor.VisitCanceledException;
50
import org.gvsig.view3d.lib.api.View3DLocator;
51
import org.gvsig.view3d.lib.api.View3DManager;
52
import org.gvsig.view3d.lib.api.loadingmodes.NwwLoaderFactory;
53
import org.gvsig.view3d.lib.api.properties.ElevationLayerProperties3D;
54
import org.gvsig.view3d.lib.api.properties.LayerProperties3D;
55
import org.gvsig.view3d.swing.api.MapControl3D;
56
import org.gvsig.view3d.swing.api.View3DSwingLocator;
57
import org.gvsig.view3d.swing.api.View3DSwingManager;
58
import org.gvsig.view3d.swing.api.View3DSwingManager.TYPE;
59
import org.gvsig.view3d.swing.api.exceptions.ConversionLayerException;
60
import org.gvsig.view3d.swing.api.properties.GeneralProperties3D;
61
import org.gvsig.view3d.swing.api.properties.MapControlProperties3D;
62
import org.gvsig.view3d.swing.impl.layers.DefaultLayerConverter;
63
import org.gvsig.view3d.swing.impl.layers.LayerConverter;
64

    
65
import gov.nasa.worldwind.Configuration;
66
import gov.nasa.worldwind.Factory;
67
import gov.nasa.worldwind.Model;
68
import gov.nasa.worldwind.WorldWind;
69
import gov.nasa.worldwind.avlist.AVKey;
70
import gov.nasa.worldwind.avlist.AVListImpl;
71
import gov.nasa.worldwind.awt.WorldWindowGLJPanel;
72
import gov.nasa.worldwind.globes.Earth;
73
import gov.nasa.worldwind.globes.EarthFlat;
74
import gov.nasa.worldwind.globes.ElevationModel;
75
import gov.nasa.worldwind.layers.CompassLayer;
76
import gov.nasa.worldwind.layers.Layer;
77
import gov.nasa.worldwind.layers.LayerList;
78
import gov.nasa.worldwind.layers.ScalebarLayer;
79
import gov.nasa.worldwind.layers.SkyColorLayer;
80
import gov.nasa.worldwind.layers.SkyGradientLayer;
81
import gov.nasa.worldwind.layers.StarsLayer;
82
import gov.nasa.worldwind.layers.ViewControlsLayer;
83
import gov.nasa.worldwind.layers.ViewControlsSelectListener;
84
import gov.nasa.worldwind.layers.WorldMapLayer;
85
import gov.nasa.worldwind.terrain.CompoundElevationModel;
86
import gov.nasa.worldwind.terrain.ZeroElevationModel;
87
import gov.nasa.worldwind.util.Logging;
88
import gov.nasa.worldwind.util.StatusBar;
89
import gov.nasa.worldwind.view.orbit.BasicOrbitView;
90
import gov.nasa.worldwind.view.orbit.FlatOrbitView;
91

    
92
/**
93
 * Default implementation of {@link MapControl3D}.
94
 *
95
 * @author <a href="mailto:lmarques@disid.com">Lluis Marques</a>
96
 */
97
@SuppressWarnings("deprecation")
98
public class DefaultMapControl3D extends JPanel implements MapControl3D {
99

    
100
    private static final long serialVersionUID = 2024899922367896097L;
101

    
102
    private static final Logger LOG = LoggerFactory.getLogger(DefaultMapControl3D.class);
103

    
104
    private DefaultSynchronizer synchronizer;
105

    
106
    private ObservableHelper observableHelper;
107

    
108
    private MapContext mapContext;
109

    
110
    private MapControlProperties3D properties;
111

    
112
    private ExtendedPropertiesSupport viewProperties;
113

    
114
    private WorldWindowGLJPanel wwd;
115

    
116
    private PropertyChangeListener verticalExaggerationPropertyListener;
117

    
118
    private PropertyChangeListener propertiesChangeListener;
119

    
120
    private StatusBar statusBar;
121

    
122
    private TYPE type;
123

    
124
    private Cancellable cancellable;
125

    
126
    /**
127
     * Default constructor of {@link DefaultMapControl3D}. Initializes local
128
     * fileds, sets configuration depends on {@link TYPE} and adds
129
     * <code>MapContext</code> layers.
130
     *
131
     * @param theMapContext
132
     *            associated <code>MapContext</code>
133
     * @param type
134
     *            Type of this {@link DefaultMapControl3D}. See {@link TYPE}.
135
     * @param viewProperties
136
     *            View properties to register this <code>MapControl3D</code>
137
     */
138
    public DefaultMapControl3D(MapContext theMapContext, TYPE type, ExtendedPropertiesSupport viewProperties) {
139

    
140
        super(new BorderLayout());
141

    
142
        this.mapContext = theMapContext;
143
        this.type = type;
144
        this.cancellable = getCancellable();
145
        this.observableHelper = new ObservableHelper();
146
        this.viewProperties = viewProperties;
147
        
148

    
149
        // Set mode before instantiation
150
        if (type == TYPE.SPHERE) {
151
            setSpherePanelConfiguration();
152
        } else if (type == TYPE.FLAT) {
153
            setFlatPanelConfiguration();
154
        }
155

    
156
        View3DSwingManager swingManager = View3DSwingLocator.getManager();
157
        this.properties = swingManager.getMapControl3DProperties(viewProperties);
158

    
159
        // Set pre configurations before instance WWD component
160
        preConfiguration();
161

    
162
        // Instance WWD component
163
        getWwd();
164

    
165
//        this.synchronizer = new DefaultSynchronizer(this, this.mapContext, getWwd());
166

    
167
        // Set post configurations after instance WWD component
168
        postConfiguration();
169

    
170
        super.add(getWwd(), BorderLayout.CENTER);
171

    
172
        super.add(getStatusBar(), BorderLayout.SOUTH);
173

    
174
        this.synchronizer = new DefaultSynchronizer(this, this.mapContext, getWwd());
175

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

    
183
    private void preConfiguration() {
184

    
185
            // WWD Mode
186
            if (type == TYPE.SPHERE) {
187
                setSpherePanelConfiguration();
188
            } else if (type == TYPE.FLAT) {
189
                setFlatPanelConfiguration();
190
            }
191

    
192
            // Enable or disable anaglyph mode
193
            setAnaglyphMode(this.properties.getAnaglyphMode());
194
        }
195

    
196
    private void postConfiguration() {
197
        setGeneral3DProperties();
198

    
199
        this.properties.addPropertyChangeListener(getPropertiesChangeListener());
200
        setMapControl3DProperties();
201

    
202
        getWwd().getSceneController().addPropertyChangeListener(
203
            getVerticalExaggerationPropertyListener());
204

    
205
        getWwd().getView().getViewInputHandler().setStopOnFocusLost(false);
206
    }
207

    
208
    private PropertyChangeListener getPropertiesChangeListener() {
209
        if (this.propertiesChangeListener == null) {
210
            this.propertiesChangeListener = new PropertyChangeListener() {
211

    
212
                public void propertyChange(PropertyChangeEvent evt) {
213

    
214
                    String propertyName = evt.getPropertyName();
215

    
216
                    if (MapControlProperties3D.SPHERE_VERTICAL_EXAGGERATION_PROPERTY_NAME.equals(propertyName)
217
                        && getType() == TYPE.SPHERE) {
218
                        setVerticalExaggeration((Double) evt.getNewValue());
219

    
220
                    } else if (MapControlProperties3D.FLAT_VERTICAL_EXAGGERATION_PROPERTY_NAME.equals(propertyName)
221
                        && getType() == TYPE.FLAT) {
222
                        setVerticalExaggeration((Double) evt.getNewValue());
223

    
224
                    } else if (MapControlProperties3D.BLUE_MARBEL_VISIBILITY_PROPERTY_NAME.equals(propertyName)) {
225
                        boolean visibility = (Boolean) evt.getNewValue();
226
                        setBlueMarbelLayerVisibility(visibility);
227

    
228
                    } else if (MapControlProperties3D.NASA_LANDSAT_VISIBILITY_PROPERTY_NAME.equals(propertyName)) {
229
                        boolean visibility = (Boolean) evt.getNewValue();
230
                        setNasaLandsatLayerVisibility(visibility);
231

    
232
                    } else if (MapControlProperties3D.DEFAULT_ELEVATION_VISIBILITY_PROPERTY_NAME.equals(propertyName)) {
233
                        boolean visibility = (Boolean) evt.getNewValue();
234
                        setDefaultElevationVisibility(visibility);
235
                    }
236
                }
237
            };
238

    
239
        }
240
        return this.propertiesChangeListener;
241
    }
242

    
243
    private PropertyChangeListener getVerticalExaggerationPropertyListener() {
244
        if (this.verticalExaggerationPropertyListener == null) {
245
            this.verticalExaggerationPropertyListener = new PropertyChangeListener() {
246

    
247
                public void propertyChange(PropertyChangeEvent evt) {
248
                    String propertyName = evt.getPropertyName();
249
                    if (propertyName.equals(AVKey.VERTICAL_EXAGGERATION)) {
250
                        Double value = (Double) evt.getNewValue();
251
                        if (getType() == TYPE.SPHERE) {
252
                            getProperties().setSphereVerticalExaggeration(value);
253
                        } else if (getType() == TYPE.FLAT) {
254
                            getProperties().setFlatVerticalExaggeration(value);
255
                        }
256
                    }
257
                }
258
            };
259
        }
260
        return this.verticalExaggerationPropertyListener;
261
    }
262

    
263
    private void setAnaglyphMode(boolean flag) {
264
        if (flag) {
265
            System.setProperty("gov.nasa.worldwind.stereo.mode", "redblue");
266
        } else {
267
            System.setProperty("gov.nasa.worldwind.stereo.mode", "");
268
        }
269
    }
270

    
271
    private void setGeneral3DProperties() {
272

    
273
        View3DSwingManager swingManager = View3DSwingLocator.getManager();
274
        GeneralProperties3D general3DProperties = swingManager.getGeneral3DProperties();
275

    
276
        this.setAtmosphereVisibility(general3DProperties.getAtmosphereVisibility());
277
        this.setMiniMapVisibility(general3DProperties.getMinimapVisibility());
278
        this.setNorthIndicatorVisibility(general3DProperties.getNorthIndicatorVisibility());
279
        this.setStarsBackgroundVisibility(general3DProperties.getStarsBackgroundVisibility());
280
        this.setScaleVisibility(general3DProperties.getScaleVisibility());
281
    }
282

    
283
//    private void addChangePropertyListener(MapControlProperties3D properties) {
284
//        properties.addPropertyChangeListener(new PropertyChangeListener() {
285
//
286
//            public void propertyChange(PropertyChangeEvent evt) {
287
//
288
//                String propertyName = evt.getPropertyName();
289
//
290
//                if (MapControlProperties3D.SPHERE_VERTICAL_EXAGGERATION_PROPERTY_NAME.equals(propertyName)
291
//                    && getType() == TYPE.SPHERE) {
292
//                    setVerticalExaggeration((Double) evt.getNewValue());
293
//
294
//                } else if (MapControlProperties3D.FLAT_VERTICAL_EXAGGERATION_PROPERTY_NAME.equals(propertyName)
295
//                    && getType() == TYPE.FLAT) {
296
//                    setVerticalExaggeration((Double) evt.getNewValue());
297
//
298
//                } else if (MapControlProperties3D.BLUE_MARBEL_VISIBILITY_PROPERTY_NAME.equals(propertyName)) {
299
//                    boolean visibility = (Boolean) evt.getNewValue();
300
//                    setBlueMarbelLayerVisibility(visibility);
301
//
302
//                } else if (MapControlProperties3D.NASA_LANDSAT_VISIBILITY_PROPERTY_NAME.equals(propertyName)) {
303
//                    boolean visibility = (Boolean) evt.getNewValue();
304
//                    setNasaLandsatLayerVisibility(visibility);
305
//
306
//                } else if (MapControlProperties3D.DEFAULT_ELEVATION_VISIBILITY_PROPERTY_NAME.equals(propertyName)) {
307
//                    boolean visibility = (Boolean) evt.getNewValue();
308
//                    setDefaultElevationVisibility(visibility);
309
//                }
310
//            }
311
//        });
312
//
313
//    }
314

    
315
    protected void addGvSIGLayer(FLayer layer) throws ConversionLayerException {
316
        LayerList layers = getWwd().getModel().getLayers();
317
        addGvSIGLayer(layer, layers.size());
318
    }
319

    
320
    protected void addGvSIGLayer(FLayer layer, int index) throws ConversionLayerException {
321

    
322
        LayerConverter converter = new DefaultLayerConverter();
323

    
324
        View3DManager manager = View3DLocator.getManager();
325
        NwwLoaderFactory layerLoadingFactory = manager.getLayerLoadingFactory(layer);
326
        LayerProperties3D layerProperties = manager.getLayerProperties(layer, layerLoadingFactory);
327

    
328
        if (layerProperties instanceof ElevationLayerProperties3D) {
329
            // elevation layers are particular ones
330
            ElevationLayerProperties3D new_name = (ElevationLayerProperties3D) layerProperties;
331
            ElevationModel elevationModel = converter.convertToElevationModel(this, layer);
332
            this.synchronizer.registerLayer(layer, elevationModel);
333
            CompoundElevationModel cem = (CompoundElevationModel) getWwd().getModel().getGlobe().getElevationModel();
334
            cem.addElevationModel(elevationModel);
335
        } else {
336
            // for any other case a Layer object is created
337
            Layer nwwLayer = converter.convertToLayer(this, layer);
338
            nwwLayer.setEnabled(layer.isVisible());
339
            this.synchronizer.registerLayer(layer, nwwLayer);
340
            getWwd().getModel().getLayers().add(index, nwwLayer);
341
        }
342
    }
343

    
344
//    private boolean isValidLayer(FLayer layer) {
345
//
346
//        // Checks if layer envelope is valid or not.
347
//        GeometryManager geoManager = GeometryLocator.getGeometryManager();
348
//        double[] degreesArray = Sector.FULL_SPHERE.asDegreesArray();
349
//        Envelope fullSphereEnvelope = null;
350
//
351
//        try {
352
//            fullSphereEnvelope = geoManager.createEnvelope(degreesArray[2], degreesArray[0], degreesArray[3],
353
//                degreesArray[1], SUBTYPES.GEOM2D);
354
//
355
//            Envelope fullEnvelope = layer.getFullEnvelope();
356
//            // return fullSphereEnvelope.contains(fullEnvelope);
357
//
358
//            return (fullEnvelope.getMinimum(1) >= -90 & fullEnvelope.getMinimum(1) <= 90
359
//                && fullEnvelope.getMaximum(1) >= -90 & fullEnvelope.getMaximum(1) <= 90);
360
//        } catch (CreateEnvelopeException e) {
361
//            LOG.error("Can't create envelope with this parameters {} {} {} {} {}",
362
//                new Object[] { degreesArray[2], degreesArray[3], degreesArray[0], degreesArray[1], SUBTYPES.GEOM2D });
363
//            return false;
364
//        } catch (ReadException e) {
365
//            LOG.error("Can't get envelope of {}. Can't determinate if layer is valid or not.");
366
//            return false;
367
//        }
368
//    }
369

    
370
    private void addGvSIGLayers(FLayers layers) throws BaseException {
371
        if (layers == null) {
372
            return;
373
        }
374

    
375
        layers.accept(new LayersVisitor() {
376

    
377
            public void visit(Object obj) throws VisitCanceledException, BaseException {
378
                throw new UnsupportedOperationException();
379

    
380
            }
381

    
382
            public void visit(FLayer layer) throws BaseException {
383

    
384
                if (layer.isAvailable()) {
385
                    addGvSIGLayer(layer);
386
                }
387
            }
388
        });
389

    
390
        getWwd().redraw();
391
    }
392

    
393
    private void setBlueMarbelLayerVisibility(boolean visibility) {
394

    
395
        if (visibility == getBlueMarbleLayerVisibility()) {
396
            return;
397
        }
398

    
399
        setWWLayerVisibility("Blue Marble May 2004", visibility);
400
        getProperties().setBlueMarbleLayerVisibility(visibility);
401
    }
402

    
403
    private boolean getBlueMarbleLayerVisibility() {
404
        return isWWLayerVisible("Blue Marble May 2004");
405
    }
406

    
407
    protected void setDefaultElevationVisibility(boolean visibility) {
408

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

    
413
        if (visibility == getDefaultElevationModelVisiblility()) {
414
            return;
415
        }
416

    
417
        if (visibility) {
418
            for (ElevationModel eModel : elevationModels) {
419
                if (eModel instanceof ZeroElevationModel) {
420
                    compoundElevationModel.removeElevationModel(eModel);
421
                    compoundElevationModel.addElevationModel(0, 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, new ZeroElevationModel());
431
                    return;
432
                }
433
            }
434
        }
435
        getProperties().setDefaultElevationVisibility(visibility);
436
    }
437

    
438
    private boolean getDefaultElevationModelVisiblility() {
439
        ElevationModel elevationModel = getWwd().getModel().getGlobe().getElevationModel();
440
        CompoundElevationModel compoundElevationModel = (CompoundElevationModel) elevationModel;
441
        List<ElevationModel> elevationModels = compoundElevationModel.getElevationModels();
442
        for (ElevationModel eModel : elevationModels) {
443
            if (eModel.getName().equals("USA 10m, World 30m, Ocean 900m")) {
444
                return true;
445
            }
446
        }
447
        return false;
448
    }
449

    
450
    private ElevationModel getDefaultElevationModel() {
451
        Factory elevationFactory = (Factory) WorldWind.createConfigurationComponent(AVKey.ELEVATION_MODEL_FACTORY);
452
        String defaultModelFile = Configuration.getStringValue(AVKey.EARTH_ELEVATION_MODEL_CONFIG_FILE);
453

    
454
        CompoundElevationModel elevationModel =
455
            (CompoundElevationModel) elevationFactory.createFromConfigSource(defaultModelFile, new AVListImpl());
456

    
457
        return elevationModel.getElevationModels().get(0);
458
    }
459

    
460
    private void setNasaLandsatLayerVisibility(boolean visibility) {
461

    
462
        if (visibility == getNasaLandsatLayerVisibility()) {
463
            return;
464
        }
465

    
466
        setWWLayerVisibility("i-cubed Landsat", visibility);
467
        getProperties().setNasaLandsatVisibility(visibility);
468
    }
469

    
470
    private boolean getNasaLandsatLayerVisibility() {
471
        return isWWLayerVisible("i-cubed Landsat");
472
    }
473

    
474
    @SuppressWarnings("rawtypes")
475
    private void setWWLayerVisibility(Class layerClazz, boolean visiblity) {
476
        List<Layer> layersByClass = getWwd().getModel().getLayers().getLayersByClass(layerClazz);
477

    
478
        for (Layer layer : layersByClass) {
479
            layer.setEnabled(visiblity);
480
        }
481
    };
482

    
483
    private void setWWLayerVisibility(String layerName, boolean visibilty) {
484
        Layer layer = getWwd().getModel().getLayers().getLayerByName(layerName);
485
        if (layer != null) {
486
            layer.setEnabled(visibilty);
487
        }
488
    };
489

    
490
    private void addNavigation() {
491

    
492
        ViewControlsLayer controlsLayer = new ViewControlsLayer();
493

    
494
        Model model = getWwd().getModel();
495
        model.getLayers().add(controlsLayer);
496

    
497
        getWwd().addSelectListener(new ViewControlsSelectListener(wwd, controlsLayer));
498
    }
499

    
500
    public JComponent asJComponent() {
501
        return this;
502
    }
503

    
504
    public void dispose() {
505

    
506
        Thread disposeThread = new Thread(new Runnable() {
507

    
508
            public void run() {
509
                Notification beforeDisposeNotification =
510
                    new BaseNotification(MapControl3D.BEFORE_DISPOSE_MAPCONTEX3D_NOTIFICATION, null);
511

    
512
                observableHelper.notifyObservers(DefaultMapControl3D.this, beforeDisposeNotification);
513

    
514
//                while (WorldWind.getRetrievalService().hasActiveTasks()) {
515
//                    try {
516
//                        Thread.sleep(100);
517
//                    } catch (InterruptedException e) {
518
//                        LOG.warn("This thread has been interrupted, dispose action can not be performed");
519
//                        return;
520
//                    }
521
//                }
522

    
523

    
524
                if (beforeDisposeNotification.isCanceled()) {
525
                    LOG.warn("Dispose action canceled by some observer");
526
                    return;
527
                }
528

    
529
                if(WorldWind.getRetrievalService().hasActiveTasks()){
530
                    WorldWind.getRetrievalService().shutdown(true);
531
                }
532

    
533
                if(WorldWind.getRemoteRetrievalService().hasActiveTasks()){
534
                    WorldWind.getRemoteRetrievalService().shutdown(true);
535
                                 }
536

    
537
                // Remove change properties listener
538
                getWwd().getSceneController().removePropertyChangeListener(
539
                    getVerticalExaggerationPropertyListener());
540
                properties.removePropertyChangeListener(getPropertiesChangeListener());
541

    
542
                // Dispose WWD component
543

    
544
                disposeWwd();
545

    
546
                // Remove properties from view
547
                if (getType() == TYPE.SPHERE) {
548
                    viewProperties.getExtendedProperties().remove("sphereMapControl3D");
549
                } else if (getType() == TYPE.FLAT) {
550
                    viewProperties.getExtendedProperties().remove("flatMapControl3D");
551
                }
552

    
553
                synchronizer.dispose();
554
                synchronizer = null;
555
                properties = null;
556
                mapContext = null;
557

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

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

    
565
        disposeThread.start();
566
    }
567

    
568
    public Cancellable getCancellable() {
569
        if (this.cancellable == null) {
570
            this.cancellable = new Cancellable() {
571

    
572
                private boolean cancel = false;
573

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

    
578
                public boolean isCanceled() {
579
                    return cancel;
580
                }
581
            };
582
        }
583

    
584
        return this.cancellable;
585
    }
586

    
587
    public MapContext getMapContext() {
588
        return this.mapContext;
589
    }
590

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

    
600
    public TYPE getType() {
601
        return this.type;
602
    }
603

    
604
    public double getVerticalExaggeration() {
605
        return getWwd().getSceneController().getVerticalExaggeration();
606
    }
607

    
608
    private WorldWindowGLJPanel getWwd() {
609
        if (this.wwd == null) {
610
            intializeWWPanel();
611
        }
612
        return this.wwd;
613
    }
614

    
615
    private void disposeWwd() {
616
        if (getWwd() != null) {
617
            this.wwd = null;
618
        }
619
    }
620

    
621
    public void setAtmosphereVisibility(boolean visibility) {
622
        if (getType() == TYPE.SPHERE) {
623
            setWWLayerVisibility(SkyGradientLayer.class, visibility);
624
        } else if (getType() == TYPE.FLAT) {
625
            setWWLayerVisibility(SkyColorLayer.class, visibility);
626
        }
627
    }
628

    
629
    public void setMiniMapVisibility(boolean visiblity) {
630
        setWWLayerVisibility(WorldMapLayer.class, visiblity);
631
    }
632

    
633
    public void setNorthIndicatorVisibility(boolean visibility) {
634
        setWWLayerVisibility(CompassLayer.class, visibility);
635
    }
636

    
637
    public void setScaleVisibility(boolean visibility) {
638
        setWWLayerVisibility(ScalebarLayer.class, visibility);
639
    }
640

    
641
    public void setStarsBackgroundVisibility(boolean visibility) {
642
        setWWLayerVisibility(StarsLayer.class, visibility);
643
    }
644

    
645
    private void intializeWWPanel() {
646
        wwd = new WorldWindowGLJPanel();
647

    
648
        // Create the default model as described in the current worldwind
649
        // properties.
650
        Model m = (Model) WorldWind.createConfigurationComponent(AVKey.MODEL_CLASS_NAME);
651
        getWwd().setModel(m);
652

    
653
        // Add view control layer
654
        addNavigation();
655
    }
656

    
657
    public void reloadLayers() {
658
        getWwd().getModel().getLayers().removeAll();
659

    
660
        Model auxModel = (Model) WorldWind.createConfigurationComponent(AVKey.MODEL_CLASS_NAME);
661
        this.wwd.getModel().setLayers(auxModel.getLayers());
662
        setGeneral3DProperties();
663
        setMapControl3DProperties();
664
        addNavigation();
665
        if (this.mapContext != null && this.mapContext.getLayers() != null) {
666
            try {
667
                addGvSIGLayers(mapContext.getLayers());
668
            } catch (BaseException e) {
669
                LOG.error("Can't add MapContext layers of {}", mapContext.getLayers(), e);
670
            }
671
        }
672
    }
673

    
674
    private void setFlatPanelConfiguration() {
675
        Configuration.setValue(AVKey.GLOBE_CLASS_NAME, EarthFlat.class.getName());
676
        Configuration.setValue(AVKey.VIEW_CLASS_NAME, FlatOrbitView.class.getName());
677
    }
678

    
679
    private void setMapControl3DProperties() {
680

    
681
        double verticalExaggeration = 0;
682
        if (getType() == TYPE.SPHERE) {
683
            verticalExaggeration = this.properties.getSphereVerticalExaggeration();
684
        } else if (getType() == TYPE.FLAT) {
685
            verticalExaggeration = this.properties.getFlatVerticalExaggeration();
686
        }
687
        setVerticalExaggeration(verticalExaggeration);
688

    
689
        boolean visibility = this.properties.getBlueMarbleLayerVisibility();
690
        setBlueMarbelLayerVisibility(visibility);
691

    
692
        visibility = this.properties.getNasaLandsatLayerVisibility();
693
        setNasaLandsatLayerVisibility(visibility);
694

    
695
        visibility = this.properties.getDefaultElevationVisibility();
696
        setDefaultElevationVisibility(visibility);
697

    
698

    
699
        boolean anaglyphMode = this.properties.getAnaglyphMode();
700
        if (anaglyphMode) {
701

    
702
        }
703
    }
704

    
705
    private void setSpherePanelConfiguration() {
706
        Configuration.setValue(AVKey.GLOBE_CLASS_NAME, Earth.class.getName());
707
        Configuration.setValue(AVKey.VIEW_CLASS_NAME, BasicOrbitView.class.getName());
708
    }
709

    
710
    private void setVerticalExaggeration(double verticalExaggeration) {
711

    
712
        if (getVerticalExaggeration() == verticalExaggeration) {
713
            return;
714
        }
715

    
716
        getWwd().getSceneController().setVerticalExaggeration(verticalExaggeration);
717

    
718
        if (getType() == TYPE.SPHERE) {
719
            getProperties().setSphereVerticalExaggeration(verticalExaggeration);
720
        } else if (getType() == TYPE.FLAT) {
721
            getProperties().setFlatVerticalExaggeration(verticalExaggeration);
722
        }
723
    }
724

    
725
//    public void synchronizeLayers() {
726
//        this.synchronizer.synchronizeLayers();
727
//    }
728

    
729
    public void synchronizeViewPorts() {
730
        this.synchronizer.synchronizeViewPorts();
731
    }
732

    
733
    public void addObserver(Observer o) {
734
        if (observableHelper != null) {
735
            observableHelper.addObserver(o);
736
        }
737
    }
738

    
739
    public void deleteObserver(Observer o) {
740
        if (observableHelper != null) {
741
            observableHelper.deleteObserver(o);
742
        }
743

    
744
    }
745

    
746
    public void deleteObservers() {
747
        if (observableHelper != null) {
748
            observableHelper.deleteObservers();
749
        }
750
    }
751

    
752
    public boolean getAtmosphereVisibility() {
753
        if (isWWLayerVisible(SkyGradientLayer.class) || isWWLayerVisible(SkyColorLayer.class)) {
754
            return true;
755
        }
756
        return false;
757
    }
758

    
759
    public boolean getMinimapVisibility() {
760
        if (isWWLayerVisible(WorldMapLayer.class)) {
761
            return true;
762
        }
763
        return false;
764
    }
765

    
766
    public boolean getNorthIndicatorVisibility() {
767
        if (isWWLayerVisible(CompassLayer.class)) {
768
            return true;
769
        }
770
        return false;
771
    }
772

    
773
    public boolean getStarBackgroundVisibility() {
774
        if (isWWLayerVisible(StarsLayer.class)) {
775
            return true;
776
        }
777
        return false;
778
    }
779

    
780
    public boolean getScaleVisibility() {
781
        if (isWWLayerVisible(ScalebarLayer.class)) {
782
            return true;
783
        }
784
        return false;
785
    }
786

    
787
    @SuppressWarnings("rawtypes")
788
    private boolean isWWLayerVisible(Class clazz) {
789
        List<Layer> layersByClass = getWwd().getModel().getLayers().getLayersByClass(clazz);
790
        for (Layer layer : layersByClass) {
791
            return layer.isEnabled();
792
        }
793
        return false;
794
    }
795

    
796
    private boolean isWWLayerVisible(String name) {
797
        Layer layer = getWwd().getModel().getLayers().getLayerByName(name);
798
        if (layer != null) {
799
            return layer.isEnabled();
800
        }
801
        return false;
802
    }
803

    
804
    public MapControlProperties3D getProperties() {
805
        return properties;
806
    }
807

    
808
//    private void addVerticalExaggerationChangeProperyListener() {
809
//        getWwd().getSceneController().addPropertyChangeListener(new PropertyChangeListener() {
810
//
811
//            public void propertyChange(PropertyChangeEvent evt) {
812
//                String propertyName = evt.getPropertyName();
813
//                if (propertyName.equals(AVKey.VERTICAL_EXAGGERATION)) {
814
//                    Double value = (Double) evt.getNewValue();
815
//                    if (getType() == TYPE.SPHERE) {
816
//                        getProperties().setSphereVerticalExaggeration(value);
817
//                    } else if (getType() == TYPE.FLAT) {
818
//                        getProperties().setFlatVerticalExaggeration(value);
819
//                    }
820
//                }
821
//            }
822
//        });
823
//    }
824

    
825
//    public void setViewPortEnvelope(Envelope envelope) {
826
//        this.synchronizer.setViewPortEnvelope(envelope);
827
//    }
828

    
829
    @Override
830
    public Object getUnderLineComponent() {
831
        return this.getWwd();
832
    }
833
}