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

History | View | Annotate | Download (28.7 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

    
196
    private void setGeneral3DProperties() {
197

    
198
        View3DManager manager = View3DLocator.getManager();
199
        GeneralProperties3D general3DProperties =
200
            manager.getGeneral3DProperties();
201

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

    
212
    private void addChangePropertyListener(MapControlProperties3D properties) {
213
        properties.addPropertyChangeListener(new PropertyChangeListener() {
214

    
215
            public void propertyChange(PropertyChangeEvent evt) {
216

    
217
                String propertyName = evt.getPropertyName();
218

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

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

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

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

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

    
245
    }
246

    
247
    private void addLayerCollectionListener(FLayers layers) {
248

    
249
        if (layers == null) {
250
            return;
251
        }
252

    
253
        layers.addLayerCollectionListener(new LayerCollectionListener() {
254

    
255
            public void visibilityChanged(LayerCollectionEvent e)
256
                throws CancelationException {
257
            }
258

    
259
            public void layerRemoving(LayerCollectionEvent e)
260
                throws CancelationException {
261
            }
262

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

    
269
            public void layerMoving(LayerPositionEvent e)
270
                throws CancelationException {
271
            }
272

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

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

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

    
286
            public void layerAdding(LayerCollectionEvent e)
287
                throws CancelationException {
288
            }
289

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

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

    
307
    private LayerListener getLayerListener() {
308
        return new LayerListener() {
309

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

    
320
            public void nameChanged(LayerEvent e) {
321
            }
322

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

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

    
336
            public void activationChanged(LayerEvent e) {
337
            }
338
        };
339
    }
340

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

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

    
349
        View3DManager manager = View3DLocator.getManager();
350
        LayerProperties3D layerProperties = manager.getLayerProperties(layer);
351

    
352
        if (layerProperties.getElevation() == false) {
353

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

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

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

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

    
381
        layers.accept(new LayersVisitor() {
382

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

    
387
            }
388

    
389
            public void visit(FLayer layer) throws BaseException {
390

    
391
                if (layer.isAvailable()) {
392
                    addGvSIGLayer(layer);
393
                }
394
            }
395
        });
396

    
397
        getWwd().redraw();
398
    }
399

    
400
    protected void setBlueMarbelLayerVisibility(boolean visibility) {
401
        setWWLayerVisibility("Blue Marble May 2004", visibility);
402
    }
403

    
404
    protected void setDefaultElevationVisibility(boolean visibility) {
405

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

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

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

    
446
    protected void setNasaLandsatLayerVisibility(boolean visibility) {
447
        setWWLayerVisibility("i-cubed Landsat", visibility);
448
    }
449

    
450
    @SuppressWarnings("rawtypes")
451
    private void setWWLayerVisibility(Class layerClazz, boolean visiblity) {
452
        List<Layer> layersByClass =
453
            getWwd().getModel().getLayers().getLayersByClass(layerClazz);
454

    
455
        for (Layer layer : layersByClass) {
456
            layer.setEnabled(visiblity);
457
        }
458
    };
459

    
460
    private void setWWLayerVisibility(String layerName, boolean visibilty) {
461
        Layer layer = getWwd().getModel().getLayers().getLayerByName(layerName);
462
        if (layer != null) {
463
            layer.setEnabled(visibilty);
464
        }
465
    };
466

    
467
    private void addNavigation() {
468

    
469
        ViewControlsLayer controlsLayer = new ViewControlsLayer();
470

    
471
        Model model = getWwd().getModel();
472
        model.getLayers().add(controlsLayer);
473

    
474
        getWwd().addSelectListener(
475
            new ViewControlsSelectListener(wwd, controlsLayer));
476
    }
477

    
478
    public JComponent asJComponent() {
479
        return this;
480
    }
481

    
482
    public void dispose() {
483

    
484
        Thread disposeThread = new Thread(new Runnable() {
485

    
486
            public void run() {
487
                Notification beforeDisposeNotification =
488
                    new BaseNotification(
489
                        MapControl3D.BEFORE_DISPOSE_MAPCONTEX3D_NOTIFICATION,
490
                        null);
491

    
492
                observableHelper.notifyObservers(DefaultMapControl3D.this,
493
                    beforeDisposeNotification);
494

    
495
                while (WorldWind.getRetrievalService().hasActiveTasks()) {
496
                    try {
497
                        Thread.sleep(100);
498
                    } catch (InterruptedException e) {
499
                        LOG.warn("This thread has been interrupted, dispose action can not be performed");
500
                        return;
501
                    }
502
                }
503

    
504
                disposeWwd();
505

    
506
                if (getType() == TYPE.SPHERE) {
507
                    viewProperties.getExtendedProperties().remove(
508
                        "spehereMapControl3D");
509
                } else if (getType() == TYPE.FLAT) {
510
                    viewProperties.getExtendedProperties().remove(
511
                        "flatMapControl3D");
512
                }
513

    
514
                Notification afterDisposeNotification =
515
                    new BaseNotification(
516
                        MapControl3D.AFTER_DISPOSE_MAPCONTEX3D_NOTIFICATION,
517
                        null);
518

    
519
                observableHelper.notifyObservers(DefaultMapControl3D.this,
520
                    afterDisposeNotification);
521
            }
522
        }, "Dispose World Wind thread");
523

    
524
        disposeThread.start();
525
    }
526

    
527
    public Cancellable getCancellable() {
528
        if (this.cancellable == null) {
529
            this.cancellable = new Cancellable() {
530

    
531
                private boolean cancel = false;
532

    
533
                public void setCanceled(boolean canceled) {
534
                    this.cancel = canceled;
535
                }
536

    
537
                public boolean isCanceled() {
538
                    return cancel;
539
                }
540
            };
541
        }
542

    
543
        return this.cancellable;
544
    }
545

    
546
    public MapContext getMapContext() {
547
        return this.mapContext;
548
    }
549

    
550
    private StatusBar getStatusBar() {
551
        if (statusBar == null) {
552
            statusBar = new StatusBar();
553
            this.add(statusBar, BorderLayout.PAGE_END);
554
            statusBar.setEventSource(wwd);
555
        }
556
        return statusBar;
557
    }
558

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

    
577
    public TYPE getType() {
578
        return this.type;
579
    }
580

    
581
    public double getVerticalExaggeration() {
582
        return getWwd().getSceneController().getVerticalExaggeration();
583
    }
584

    
585
    protected WorldWindowGLJPanel getWwd() {
586
        if (this.wwd == null) {
587
            intializeWWPanel();
588
        }
589
        return this.wwd;
590
    }
591

    
592
    private void disposeWwd() {
593
        if (getWwd() != null) {
594
            this.wwd = null;
595
        }
596
    }
597

    
598
    public void setAtmosphereVisibility(boolean visibility) {
599
        if (getType() == TYPE.SPHERE) {
600
            setWWLayerVisibility(SkyGradientLayer.class, visibility);
601
        } else if (getType() == TYPE.FLAT) {
602
            setWWLayerVisibility(SkyColorLayer.class, visibility);
603
        }
604
    }
605

    
606
    public void setMiniMapVisibility(boolean visiblity) {
607
        setWWLayerVisibility(WorldMapLayer.class, visiblity);
608
    }
609

    
610
    public void setNorthIndicatorVisibility(boolean visibility) {
611
        setWWLayerVisibility(CompassLayer.class, visibility);
612
    }
613

    
614
    public void setScaleVisibility(boolean visibility) {
615
        setWWLayerVisibility(ScalebarLayer.class, visibility);
616
    }
617

    
618
    public void setStarsBackgroundVisibility(boolean visibility) {
619
        setWWLayerVisibility(StarsLayer.class, visibility);
620
    }
621

    
622
    private void intializeWWPanel() {
623
        wwd = new WorldWindowGLJPanel();
624

    
625
        View3DManager manager = View3DLocator.getManager();
626
        GeneralProperties3D general3dProperties =
627
            manager.getGeneral3DProperties();
628
        wwd.setPreferredSize(new Dimension(general3dProperties
629
            .getDefaultViewWidht(), general3dProperties.getDefaultViewHeight()));
630

    
631
        // Create the default model as described in the current worldwind
632
        // properties.
633
        Model m =
634
            (Model) WorldWind
635
                .createConfigurationComponent(AVKey.MODEL_CLASS_NAME);
636
        getWwd().setModel(m);
637

    
638
        // Add view control layer
639
        addNavigation();
640
    }
641

    
642
    public void reloadLayers() {
643
        getWwd().getModel().getLayers().removeAll();
644

    
645
        if (this.mapContext != null && this.mapContext.getLayers() != null) {
646
            try {
647
                addGvSIGLayers(mapContext.getLayers());
648
            } catch (BaseException e) {
649
                LOG.error("Can't add MapContext layers of {}",
650
                    mapContext.getLayers(), e);
651
            }
652
        }
653
    }
654

    
655
    private void setFlatPanelConfiguration() {
656
        Configuration.setValue(AVKey.GLOBE_CLASS_NAME,
657
            EarthFlat.class.getName());
658
        Configuration.setValue(AVKey.VIEW_CLASS_NAME,
659
            FlatOrbitView.class.getName());
660
    }
661

    
662
    private void setMapControl3DProperties() {
663

    
664
        double verticalExaggeration = 0;
665
        if (getType() == TYPE.SPHERE) {
666
            verticalExaggeration =
667
                this.properties.getSphereVerticalExaggeration();
668
        } else if (getType() == TYPE.FLAT) {
669
            verticalExaggeration =
670
                this.properties.getFlatVerticalExaggeration();
671
        }
672
        setVerticalExaggeration(verticalExaggeration);
673

    
674
        boolean visibility = this.properties.getBlueMarbleLayerVisibility();
675
        setBlueMarbelLayerVisibility(visibility);
676

    
677
        visibility = this.properties.getNasaLandsatLayerVisibility();
678
        setNasaLandsatLayerVisibility(visibility);
679

    
680
        visibility = this.properties.getDefaultElevationVisibility();
681
        setDefaultElevationVisibility(visibility);
682
    }
683

    
684
    private void setSpherePanelConfiguration() {
685
        Configuration.setValue(AVKey.GLOBE_CLASS_NAME, Earth.class.getName());
686
        Configuration.setValue(AVKey.VIEW_CLASS_NAME,
687
            BasicOrbitView.class.getName());
688
    }
689

    
690
    public void setVerticalExaggeration(double verticalExaggeration) {
691
        getWwd().getSceneController().setVerticalExaggeration(
692
            verticalExaggeration);
693
    }
694

    
695
    public synchronized void synchronizeLayers() {
696
        
697
        FLayers layers = this.mapContext.getLayers();
698
        
699
        // Remove old layers
700
        List<FLayer> layersRemoved = new ArrayList<FLayer>();
701
        for (FLayer layer : drawLayerStatus.keySet()) {
702
            if (layers.getLayer(layer.getName()) == null) {
703
                int index = removeGvSIGLayer(layer);
704
                if(index >= 0){
705
                    layersRemoved.add(layer);
706
                }
707
            }
708
        }
709
        for (FLayer fLayer : layersRemoved) {
710
            drawLayerStatus.remove(fLayer);
711
        }
712
        
713
        
714
        // Add new layers
715
        try {
716
            layers.accept(new LayersVisitor() {
717

    
718
                public void visit(Object obj) throws VisitCanceledException,
719
                    BaseException {
720
                    throw new UnsupportedOperationException();
721
                }
722

    
723
                public void visit(FLayer layer) throws BaseException {
724
                    
725
                    if(!drawLayerStatus.containsKey(layer)){
726
                        drawLayerStatus.put(layer, layer.getDrawVersion());
727
                        addGvSIGLayer(layer);
728
                    }
729
                }
730
            });
731
        } catch (BaseException e) {
732
            LOG.error("Can't synchronize layers. Can't visit layers of {}",
733
                mapContext.toString(), e);
734
        }
735
        
736
        // Update registered layers
737
        for (FLayer layer : drawLayerStatus.keySet()) {
738
            if (layer instanceof FLyrDefault) {
739
                FLyrDefault defaultLayer = (FLyrDefault) layer;
740

    
741
                if (defaultLayer.hasChangedForDrawing(drawLayerStatus
742
                    .get(layer))) {
743
                    replaceGvSIGLayer(defaultLayer);
744
                }
745
            }
746
        }
747
    }
748

    
749
    private int removeGvSIGLayer(FLayer layer) {
750
        List<Layer> loadedLayers = getWwd().getModel().getLayers();
751
        Layer tiledImageLayer = getTileImageLayer(layer);
752

    
753
        if (tiledImageLayer == null) {
754
            return -1;
755
        }
756

    
757
        int layerIndex = loadedLayers.indexOf(tiledImageLayer);
758
        getWwd().getModel().getLayers().remove(tiledImageLayer);
759
        return layerIndex;
760
    }
761

    
762
    private void replaceGvSIGLayer(FLayer layer) {
763
        // Remove layer without update drawLayerStatus map.
764
        List<Layer> loadedLayers = getWwd().getModel().getLayers();
765
        Layer tiledImageLayer = getTileImageLayer(layer);
766

    
767
        if (tiledImageLayer == null) {
768
            return;
769
        }
770

    
771
        int layerIndex = loadedLayers.indexOf(tiledImageLayer);
772
        getWwd().getModel().getLayers().remove(tiledImageLayer);
773

    
774
        // Add new layer at the same index
775
        if (layerIndex >= 0) {
776
            try {
777
                addGvSIGLayer(layer, layerIndex);
778
            } catch (DataException e) {
779
                LOG.error("Can't add {} at {}", new Object[] { layer.getName(),
780
                    layerIndex }, e);
781
            }
782
        }
783
    }
784

    
785
    public void synchronizeViewPorts() {
786
        // TODO
787
        throw new UnsupportedOperationException();
788
    }
789

    
790
    public void addObserver(Observer o) {
791
        if (observableHelper != null) {
792
            observableHelper.addObserver(o);
793
        }
794
    }
795

    
796
    public void deleteObserver(Observer o) {
797
        if (observableHelper != null) {
798
            observableHelper.deleteObserver(o);
799
        }
800

    
801
    }
802

    
803
    public void deleteObservers() {
804
        if (observableHelper != null) {
805
            observableHelper.deleteObservers();
806
        }
807
    }
808

    
809
    public boolean getAtmosphereVisibility() {
810
        if (isWWLayerVisible(SkyGradientLayer.class)
811
            || isWWLayerVisible(SkyColorLayer.class)) {
812
            return true;
813
        }
814
        return false;
815
    }
816

    
817
    public boolean getMinimapVisibility() {
818
        if (isWWLayerVisible(WorldMapLayer.class)) {
819
            return true;
820
        }
821
        return false;
822
    }
823

    
824
    public boolean getNorthIndicatorVisibility() {
825
        if (isWWLayerVisible(CompassLayer.class)) {
826
            return true;
827
        }
828
        return false;
829
    }
830

    
831
    public boolean getStarBackgroundVisibility() {
832
        if (isWWLayerVisible(StarsLayer.class)) {
833
            return true;
834
        }
835
        return false;
836
    }
837

    
838
    public boolean getScaleVisibility() {
839
        if (isWWLayerVisible(ScalebarLayer.class)) {
840
            return true;
841
        }
842
        return false;
843
    }
844

    
845
    @SuppressWarnings("rawtypes")
846
    private boolean isWWLayerVisible(Class clazz) {
847
        List<Layer> layersByClass =
848
            getWwd().getModel().getLayers().getLayersByClass(clazz);
849
        for (Layer layer : layersByClass) {
850
            return layer.isEnabled();
851
        }
852
        return false;
853
    }
854

    
855
    public MapControlProperties3D getProperties() {
856
        return properties;
857
    }
858
}