Statistics
| Revision:

root / branches / gvSIG_19_ext3D_osgVP_2_2_0 / libraries / lib3DMap / src / org / gvsig / gvsig3d / map3d / MapContext3D.java @ 31732

History | View | Annotate | Download (35.4 KB)

1
package org.gvsig.gvsig3d.map3d;
2

    
3
import java.awt.Dimension;
4
import java.awt.Graphics2D;
5
import java.awt.Point;
6
import java.awt.geom.AffineTransform;
7
import java.awt.geom.Rectangle2D;
8
import java.awt.image.BufferedImage;
9
import java.awt.image.ImagingOpException;
10
import java.awt.image.RenderedImage;
11
import java.io.File;
12
import java.io.IOException;
13
import java.util.Hashtable;
14
import java.util.Iterator;
15
import java.util.Timer;
16
import java.util.Vector;
17

    
18
import javax.print.attribute.PrintRequestAttributeSet;
19

    
20
import org.apache.log4j.Logger;
21
import org.cresques.cts.IProjection;
22
import org.gvsig.cacheservice.TileNum;
23
import org.gvsig.gvsig3d.cacheservices.FLayerCacheService;
24
import org.gvsig.gvsig3d.cacheservices.OSGCacheService;
25
import org.gvsig.gvsig3d.cacheservices.VectorCacheService;
26
import org.gvsig.gvsig3d.drivers.GvsigDriverOSG;
27
import org.gvsig.gvsig3d.map3d.layers.FLayers3D;
28
import org.gvsig.osgvp.core.osg.Image;
29
import org.gvsig.osgvp.core.osg.Matrix;
30
import org.gvsig.osgvp.core.osg.Node;
31
import org.gvsig.osgvp.core.osg.Vec3;
32
import org.gvsig.osgvp.core.osg.Vec4;
33
import org.gvsig.osgvp.exceptions.image.ImageConversionException;
34
import org.gvsig.osgvp.exceptions.node.ChildIndexOutOfBoundsExceptions;
35
import org.gvsig.osgvp.exceptions.node.NodeException;
36
import org.gvsig.osgvp.terrain.DataLoader;
37
import org.gvsig.osgvp.terrain.Extent;
38
import org.gvsig.osgvp.terrain.HeightfieldLayer;
39
import org.gvsig.osgvp.terrain.JavaDataDriver;
40
import org.gvsig.osgvp.terrain.Layer;
41
import org.gvsig.osgvp.terrain.LayerManager;
42
import org.gvsig.osgvp.terrain.RasterLayer;
43
import org.gvsig.osgvp.terrain.RequestDataEvent;
44
import org.gvsig.osgvp.terrain.Terrain;
45
import org.gvsig.osgvp.terrain.TerrainViewer;
46
import org.gvsig.osgvp.terrain.UpdateDataEvent;
47
import org.gvsig.osgvp.terrain.VectorLayer;
48
import org.gvsig.osgvp.terrain.Terrain.CoordinateSystemType;
49
import org.gvsig.osgvp.viewer.Camera;
50
import org.gvsig.osgvp.viewer.IViewerContainer;
51
import org.gvsig.osgvp.viewer.PrintUtilities;
52

    
53
import com.hardcode.driverManager.Driver;
54
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
55
import com.iver.ai2.gvsig3d.map3d.layers.Layer3DProps;
56
import com.iver.andami.PluginServices;
57
import com.iver.andami.messages.NotificationManager;
58
import com.iver.andami.ui.mdiManager.IWindow;
59
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
60
import com.iver.cit.gvsig.fmap.MapContext;
61
import com.iver.cit.gvsig.fmap.ViewPort;
62
import com.iver.cit.gvsig.fmap.layers.FBitSet;
63
import com.iver.cit.gvsig.fmap.layers.FLayer;
64
import com.iver.cit.gvsig.fmap.layers.FLayers;
65
import com.iver.cit.gvsig.fmap.layers.FLyrDefault;
66
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
67
import com.iver.cit.gvsig.fmap.layers.FLyrWCS;
68
import com.iver.cit.gvsig.fmap.layers.GraphicLayer;
69
import com.iver.cit.gvsig.fmap.layers.LayerEvent;
70
import com.iver.cit.gvsig.fmap.layers.LayerListener;
71
import com.iver.cit.gvsig.fmap.layers.LegendChangedEvent;
72
import com.iver.cit.gvsig.fmap.layers.SelectableDataSource;
73
import com.iver.cit.gvsig.fmap.layers.SelectionEvent;
74
import com.iver.cit.gvsig.fmap.layers.SelectionListener;
75
import com.iver.cit.gvsig.fmap.layers.SelectionSupport;
76
import com.iver.cit.gvsig.fmap.layers.SingleLayerIterator;
77
import com.iver.cit.gvsig.fmap.layers.XMLException;
78
import com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable;
79
import com.iver.cit.gvsig.fmap.rendering.LegendListener;
80
import com.iver.cit.gvsig.project.documents.view.gui.BaseView;
81
import com.iver.utiles.XMLEntity;
82
import com.iver.utiles.swing.threads.Cancellable;
83

    
84
public class MapContext3D extends MapContext implements DataLoader,
85
                LayerListener, LegendListener, SelectionListener {
86

    
87
        // JOSG library objects
88
        private Terrain _terrain;
89
        private IViewerContainer _canvas3d;
90
        private TerrainViewer _terrainViewer;
91
        private LayerManager _terrainLayerManager;
92
        private JavaDataDriver _terrainDataManager = null;
93

    
94
        private Hashtable<FLayer, Layer> _terrainFLayerMap = new Hashtable<FLayer, Layer>();
95
        private Hashtable<String, FLayer> _terrainLayerMap = new Hashtable<String, FLayer>();
96

    
97
        private IProjection _viewProjection;
98
        private boolean _bEmptyView = true;
99
        private boolean _bListenToLegend = true;
100
        private boolean _bLoading = false;
101
        private TerrainViewer _canvasoff = null;
102
        private boolean _renewCanvasOff = false;
103
        private static Logger _logger = Logger.getLogger(MapContext3D.class
104
                        .getName());
105
        TerrainViewer _printViewer = null;
106
        Layer _testRasterLayer = null;
107

    
108
        private boolean visibilityChange = false;
109

    
110
        @Override
111
        public void draw(BufferedImage image, Graphics2D g, Cancellable cancel,
112
                        double scale) throws ReadDriverException {
113

    
114
                double x = getViewPort().getOffset().getX();
115
                double y = getViewPort().getOffset().getY();
116
                double w = image.getWidth();
117
                double h = image.getHeight();
118

    
119
                if (_canvasoff == null) {
120
                        try {
121
                                _canvasoff = new TerrainViewer();
122
                                _canvasoff.setUpViewerInBackground(0, 0, 512, 512);
123
                                _canvasoff
124
                                                .addTerrain(((TerrainViewer) _canvas3d.getOSGViewer())
125
                                                                .getTerrain(0));
126
                                _canvasoff.addFeature((((TerrainViewer) _canvas3d
127
                                                .getOSGViewer()).getFeatures()));
128
                                Vec4 color = ((TerrainViewer) _canvas3d.getOSGViewer())
129
                                                .getClearColor();
130
                                _canvasoff.setClearColor(color.x(), color.y(), color.z(), color
131
                                                .w());
132
                                this.setRenewCanvasOff(false);
133
                        } catch (NodeException e) {
134
                                // TODO Auto-generated catch block
135
                                e.printStackTrace();
136
                        }
137

    
138
                }
139

    
140
                Camera refCam = _canvas3d.getOSGViewer().getCamera();
141
                Matrix refView = refCam.getViewMatrix();
142
                Matrix refProy = refCam.getProjectionMatrix();
143
                Matrix.Perspective pers = refProy.getPerspective();
144
                Camera viewCam = new Camera();
145
                viewCam.setProjectionMatrixAsPerspective(pers.fovy, w / h, pers.zNear,
146
                                pers.zFar);
147
                viewCam.setViewMatrix(refView);
148
                _canvasoff.setViewport(0, 0, (int) w, (int) h);
149
                _canvasoff.setCamera(viewCam);
150
                _canvasoff.takeScreenshotToMemory();
151
                _canvasoff.frame();
152

    
153
                Image OSGimage = _canvasoff.getScreenshotImage();
154

    
155
                BufferedImage img = null;
156
                try {
157
                        img = OSGimage.getBufferedImage();
158
                } catch (ImageConversionException e1) {
159
                        // TODO Auto-generated catch block
160
                        e1.printStackTrace();
161
                } catch (IOException e1) {
162
                        // TODO Auto-generated catch block
163
                        e1.printStackTrace();
164
                }
165

    
166
                double scalex = w / img.getWidth(null);
167
                double scaley = h / img.getHeight(null);
168
                try {
169
                        AffineTransform xform = AffineTransform.getScaleInstance(scalex,
170
                                        scaley);
171
                        AffineTransform xpos = AffineTransform.getTranslateInstance(x, y);
172
                        xpos.concatenate(xform);
173
                        g.drawRenderedImage(img, xpos);
174
                } catch (ImagingOpException e) {
175
                        NotificationManager.addError("Dibujando FFramePicture", e);
176
                }
177

    
178
        }
179

    
180
        public void print(Graphics2D g, double scale, PrintRequestAttributeSet arg2)
181
                        throws ReadDriverException {
182

    
183
                int x = (int) getViewPort().getOffset().getX();
184
                int y = (int) getViewPort().getOffset().getY();
185
                int w = (int) g.getClipBounds().getWidth();
186
                int h = (int) g.getClipBounds().getHeight();
187
                System.err.println("x " + x + "; y " + y + "; w " + w + "; h" + h);
188

    
189
                Camera viewerCam = _canvas3d.getOSGViewer().getCamera();
190
                BufferedImage s = null;
191

    
192
                try {
193
                        int minw = (int) w / 10;
194
                        int minh = (int) h / 10;
195
                        System.out.println("minw" + minw + " minh" + minh);
196

    
197
                        _printViewer = new TerrainViewer();
198
                        _printViewer.addTerrain(((TerrainViewer) _canvas3d.getOSGViewer())
199
                                        .getTerrain(0));
200
                        _printViewer.addFeature((((TerrainViewer) _canvas3d.getOSGViewer())
201
                                        .getFeatures()));
202
                        Vec4 color = ((TerrainViewer) _canvas3d.getOSGViewer())
203
                                        .getClearColor();
204
                        _printViewer.setClearColor(color.x(), color.y(), color.z(), color
205
                                        .w());
206
                        _printViewer.setUpViewerInBackground(0, 0, minw, minh);
207

    
208
                        PrintUtilities util = new PrintUtilities();
209
                        util.setViewer(_printViewer);
210
                        s = util.getHighResolutionImage(viewerCam, w, h);
211

    
212
                        RenderedImage render = s;
213
                } catch (NodeException e1) {
214
                        // TODO Auto-generated catch block
215
                        e1.printStackTrace();
216
                }
217

    
218
                double scalex = w / s.getWidth(null);
219
                double scaley = h / s.getHeight(null);
220
                try {
221
                        AffineTransform xform = AffineTransform.getScaleInstance(scalex,
222
                                        scaley);
223
                        AffineTransform xpos = AffineTransform.getTranslateInstance(x, y);
224
                        xpos.concatenate(xform);
225
                        g.drawRenderedImage(s, xpos);
226
                        // g.drawRenderedImage(img, new AffineTransform());
227
                } catch (ImagingOpException e) {
228
                        NotificationManager.addError("Dibujando FFramePicture", e);
229
                }
230
                _printViewer.releaseGLContext();
231
                _printViewer.dispose();
232
                System.gc();
233
        }
234

    
235
        public MapContext3D(ViewPort vp) {
236
                super(vp);
237
        }
238

    
239
        public MapContext3D(FLayers fLayers, ViewPort vp) {
240
                super(fLayers, vp);
241
        }
242

    
243
        public void setTerrain(Terrain terrain) {
244
                if (_terrain == terrain)
245
                        return;
246

    
247
                _terrain = terrain;
248

    
249
                // add layers to terrain necessary when we are loading
250
                addCurrentLayers();
251
        }
252

    
253
        public Terrain getTerrain() {
254
                return _terrain;
255
        }
256

    
257
        public void setDataManager(JavaDataDriver manager) {
258
                _terrainDataManager = manager;
259
                _terrainDataManager.setDataLoader(this);
260
        }
261

    
262
        public JavaDataDriver getDataManager() {
263
                return _terrainDataManager;
264
        }
265

    
266
        public void setLayerManager(LayerManager manager) {
267
                _terrainLayerManager = manager;
268
        }
269

    
270
        public LayerManager getLayerManager() {
271
                return _terrainLayerManager;
272
        }
273

    
274
        public void setViewer(IViewerContainer canvas) {
275
                _canvas3d = canvas;
276
                _terrainViewer = (TerrainViewer) _canvas3d.getOSGViewer();
277
        }
278

    
279
        public IProjection getViewProjection() {
280
                return _viewProjection;
281
        }
282

    
283
        public void setViewProjection(IProjection projection) {
284
                _viewProjection = projection;
285
        }
286

    
287
        public IViewerContainer getCanvas3d() {
288
                return _canvas3d;
289
        }
290

    
291
        public void setLoading(boolean bLoading) {
292
                _bLoading = bLoading;
293
        }
294

    
295
        public FLayers getNewGroupLayer(FLayers parent) {
296
                return new FLayers3D(this, parent, getViewPort());
297
        }
298

    
299
        /** * LAYER CHANGES called by FLayers3D ** */
300

    
301
        public synchronized void layerMoved(FLayers3D parent, FLayer layer, int oldPos,
302
                        int newPos) {
303

    
304
                if (layer instanceof FLayers) {
305
                        FLayers group = (FLayers) layer;
306
                        if (newPos > oldPos) {
307
                                for (int iChild = group.getLayersCount() - 1; iChild >= 0; iChild--)
308
                                        layerMoved((FLayers3D) group, group.getLayer(iChild),
309
                                                        oldPos, newPos);
310
                        } else {
311
                                for (int iChild = 0; iChild < group.getLayersCount(); iChild++)
312
                                        layerMoved((FLayers3D) group, group.getLayer(iChild),
313
                                                        oldPos, newPos);
314
                        }
315
                        return;
316
                }
317

    
318
                Layer3DProps props3D = getLayer3DProps(layer);
319
                int type = props3D.getType();
320

    
321
                // Now reorder in layer manager only for terrain layer types
322
                if ((type == Layer3DProps.layer3DOSG)
323
                                || ((type == Layer3DProps.layer3DVector)))
324
                        return;
325

    
326
                // Obtain the old position in the layer
327
                Layer terrainLayer = _terrainFLayerMap.get(layer);
328
                Vector<Integer> terrainOldPos = _terrainLayerManager
329
                                .getOrder(terrainLayer);
330

    
331
                int terrainNewPos = 0;
332
                // Compute the new position.
333
                SingleLayerIterator lyrIterator = new SingleLayerIterator(layers);
334
                while (lyrIterator.hasNext()) {
335
                        FLayer auxLayer = lyrIterator.next();
336
                        if (auxLayer == layer)
337
                                break;
338
                        Layer3DProps auxProps3D = getLayer3DProps(auxLayer);
339
                        if ((auxProps3D.getType() != Layer3DProps.layer3DOSG)
340
                                        && (auxProps3D.getType() != Layer3DProps.layer3DVector)) {
341
                                terrainNewPos++;
342
                        }
343

    
344
                }
345

    
346
                if ((terrainOldPos == null) || (terrainOldPos.size() == 0))
347
                        return;
348
                if (terrainOldPos.get(0) != terrainNewPos)
349
                        _terrainLayerManager.moveLayer(terrainOldPos.get(0), terrainNewPos);
350

    
351
                System.out.println("En el toc antes era el " + oldPos + " y ahora el "
352
                                + newPos);
353
                System.out.println("En el terrain antes era el " + terrainOldPos
354
                                + " y ahora el " + terrainNewPos);
355

    
356
                PrintDebugLayers();
357
        }
358

    
359
        public void layerAdded(FLayers3D parent, FLayer layer) {
360

    
361
                // to add group layers to 3D, just add recursively child data layers
362
                if (layer instanceof FLayers) {
363
                        FLayers group = (FLayers) layer;
364
                        for (int iChild = 0; iChild < group.getLayersCount(); iChild++) {
365
                                layerAdded((FLayers3D) group, group.getLayer(iChild));
366
                        }
367
                        getLayer3DProps(layer).setHooked(true);
368
                        return;
369
                }
370

    
371
                if (layer instanceof Classifiable) {
372
                        Classifiable legendLyr = (Classifiable) layer;
373
                        // legendLyr.addLegendListener((LegendListener) this);
374
                        this.addLayerListener(this);
375
                }
376
                layer.addLayerListener((LayerListener) this);
377

    
378
                // listener to manage the selection for the layers
379
                if (layer.getClass().equals(FLyrVect.class)) {
380
                        FLyrVect lyr = (FLyrVect) layer;
381
                        try {
382
                                SelectableDataSource recordSet = lyr.getRecordset();
383
                                if (recordSet != null) {
384
                                        SelectionSupport selectionSupport = recordSet
385
                                                        .getSelectionSupport();
386
                                        selectionSupport.addSelectionListener(this);
387
                                }
388
                        } catch (ReadDriverException e) {
389
                                // TODO Auto-generated catch block
390
                                e.printStackTrace();
391
                        }
392
                }
393

    
394
                if (!_bLoading)
395
                        addLayerToTerrain(layer, true);
396

    
397
                // Only do this the first time to add layer
398
                if (_bEmptyView && !_bLoading) {
399
                        if (layers.getLayersCount() > 0) {
400
                                try {
401
                                        zoomToExtent(layer.getFullExtent());
402
                                } catch (ExpansionFileReadException e) {
403
                                        e.printStackTrace();
404
                                } catch (ReadDriverException e) {
405
                                        e.printStackTrace();
406
                                }
407
                                _bEmptyView = false;
408
                        }
409
                }
410

    
411
                PrintDebugLayers();
412
        }
413

    
414
        public void layerRemoved(FLayers3D parent, FLayer layer) {
415

    
416
                // to remove group layers to 3D, just remove recursively child data
417
                // layers
418
                if (layer instanceof FLayers) {
419
                        FLayers group = (FLayers) layer;
420
                        for (int iChild = 0; iChild < group.getLayersCount(); iChild++) {
421
                                layerRemoved((FLayers3D) group, group.getLayer(iChild));
422
                        }
423
                        getLayer3DProps(layer).setHooked(false);
424
                        return;
425
                }
426

    
427
                if (layer instanceof Classifiable) {
428
                        Classifiable legendLyr = (Classifiable) layer;
429
                        legendLyr.removeLegendListener((LegendListener) this);
430
                }
431

    
432
                layer.removeLayerListener((LayerListener) this);
433

    
434
                removeLayerToTerrain(layer);
435

    
436
                // All layers are removed
437
                if (layers.getLayersCount() == 0) {
438
                        _bEmptyView = true;
439
                }
440

    
441
                PrintDebugLayers();
442
        }
443

    
444
        /**
445
         * DOCUMENT ME!
446
         * 
447
         * @param e
448
         *            DOCUMENT ME!
449
         */
450
        public void legendChanged(LegendChangedEvent e) {
451

    
452
                if (!_bListenToLegend)
453
                        return;
454
                if ((e == null) && (!visibilityChange)) {
455

    
456
                        // find layer whose legend changed
457
                        FLayer found = null;
458
                        SingleLayerIterator lyrIterator = new SingleLayerIterator(layers);
459
                        while (lyrIterator.hasNext()) {
460
                                FLayer lyr = lyrIterator.next();
461
                                if (lyr instanceof FLyrVect) {
462
                                        FLyrVect lyrVect = (FLyrVect) lyr;
463
                                        long newDrawVersion = lyrVect.getDrawVersion();
464
                                        Layer3DProps props3D = getLayer3DProps(lyrVect);
465
                                        if (newDrawVersion != props3D.drawVersion) {
466
                                                props3D.drawVersion = lyrVect.getDrawVersion();
467
                                                refreshLayerInTerrain(props3D, true);
468
                                                _bListenToLegend = false;
469
                                                props3D.VerifyLegend(_terrain.getTerrainName());
470
                                                _bListenToLegend = true;
471
                                        }
472
                                }
473
                        }
474

    
475
                        IWindow f = PluginServices.getMDIManager().getActiveWindow();
476
                        if (f instanceof BaseView) {
477
                                BaseView view3D = (BaseView) f;
478
                                view3D.getTOC().refresh();
479
                        }
480
                }
481
                visibilityChange = false;
482
        }
483

    
484
        public void visibilityChanged(LayerEvent e) {
485
                FLayer lyr = e.getSource();
486

    
487
                Layer3DProps props3D = getLayer3DProps(lyr);
488

    
489
                if (props3D.getType() == Layer3DProps.layer3DVector) {
490
                        refreshLayerVectorsVisibility(lyr);
491
                } else if (props3D.getType() == Layer3DProps.layer3DOSG) {
492
                        refreshLayer3DOSGVisibility(lyr);
493
                } else {
494
                        refreshLayerVisibility(lyr);
495
                }
496
                visibilityChange = true;
497
        }
498

    
499
        private void refreshLayer3DOSGVisibility(FLayer lyr) {
500
                if (_terrain == null || _viewProjection == null)
501
                        return;
502

    
503
                Layer3DProps props3D = getLayer3DProps(lyr);
504

    
505
                OSGCacheService cacheService = (OSGCacheService) props3D
506
                                .getCacheService();
507
                if (cacheService != null) {
508
                        // use VectorCacheService to add features to terrain
509
                        cacheService.refreshFeaturesToTerrain(lyr.isVisible());
510
                }
511

    
512
        }
513

    
514
        private void refreshLayerVisibility(FLayer layer) {
515

    
516
                Layer terrainLayer = _terrainFLayerMap.get(layer);
517
                terrainLayer.setEnabled(layer.isVisible());
518
                _terrainLayerManager.updateLayers();
519

    
520
        }
521

    
522
        private void refreshLayerVectorsVisibility(FLayer lyr) {
523
                if (_terrain == null || _viewProjection == null)
524
                        return;
525

    
526
                Layer3DProps props3D = getLayer3DProps(lyr);
527

    
528
                VectorCacheService cacheService = (VectorCacheService) props3D
529
                                .getCacheService();
530
                if (cacheService != null) {
531
                        // use VectorCacheService to add features to terrain
532
                        cacheService.refreshFeaturesToTerrain(lyr.isVisible());
533
                }
534

    
535
        }
536

    
537
        public void activationChanged(LayerEvent e) {
538
                // TODO Implement this method
539
        }
540

    
541
        public void nameChanged(LayerEvent e) {
542
                // TODO Implement this method
543
        }
544

    
545
        public void editionChanged(LayerEvent e) {
546
                // TODO Implement this method
547

    
548
        }
549

    
550
        public void refreshLayerInTerrain(Layer3DProps props, boolean bRemoveCache) {
551
                if (props == null)
552
                        return;
553

    
554
                if (_terrain == null)
555
                        return; // view not opened yet
556

    
557
                // clear cache
558

    
559
                if (bRemoveCache) {
560
                        String layerCacheDir = Layer3DProps.m_cacheDir + "/"
561
                                        + _terrain.getTerrainName() + "/" + props.getCacheName();
562
                        removeCache(layerCacheDir);
563
                }
564

    
565
                // refresh layer in terrain
566
                int type = props.getType();
567
                if ((type == Layer3DProps.layer3DImage)||(type == Layer3DProps.layer3DElevation)||
568
                                (type == Layer3DProps.layer3DVectorMR)) {
569
                        _terrainLayerManager.invalidateLayer(props.getTerrainLayer());
570
                } else if (type == Layer3DProps.layer3DVector) {
571
                        invalidateVectorLayer(props);
572
                }
573
        }
574

    
575
        private void invalidateVectorLayer(Layer3DProps props) {
576
                // TODO Auto-generated method stub
577
                if (_terrain == null || _viewProjection == null)
578
                        return;
579

    
580
                VectorCacheService cacheService = (VectorCacheService) props
581
                                .getCacheService();
582
                if (cacheService != null) {
583
                        // use VectorCacheService to add features to terrain
584
                        cacheService.refreshFeaturesToTerrain();
585
                }
586
        }
587

    
588
        private boolean removeCache(String folder) {
589
                File dir = new File(folder);
590
                if (dir.isDirectory()) {
591
                        String[] children = dir.list();
592
                        for (int i = 0; i < children.length; i++) {
593
                                boolean success = removeCache(folder + "/" + children[i]);
594
                                // Do not interrupt if it can't delete one file
595
                                // if (!success) {
596
                                // return false;
597
                                // }
598
                        }
599
                }
600

    
601
                // The directory is now empty so delete it
602
                return dir.delete();
603
        }
604

    
605
        protected Layer3DProps getLayer3DProps(FLayer layer) {
606

    
607
                Layer3DProps props3D = Layer3DProps.getLayer3DProps(layer);
608

    
609
                // Create instance of props for osg layers.
610
                if (props3D == null) {
611
                        props3D = new Layer3DProps();
612
                        if (layer instanceof FLyrVect) {
613
                                FLyrVect nLayer = (FLyrVect) layer;
614
                                Driver driver;
615
                                try {
616
                                        driver = nLayer.getRecordset().getDriver();
617
                                        if (driver instanceof GvsigDriverOSG) {
618
                                                props3D.setChooseType(false);
619
                                        }
620
                                } catch (ReadDriverException e) {
621
                                        // TODO Auto-generated catch block
622
                                        e.printStackTrace();
623
                                }
624

    
625
                        }
626
                        // Set the properties
627
                        props3D.setLayer(layer);
628

    
629
                        props3D.initCacheName(_terrain.getCoordinateSystemType(),
630
                                        _viewProjection, Terrain.CoordinateSystemType.GEOCENTRIC);
631
                        FLyrDefault baseLayer = (FLyrDefault) layer;
632
                        baseLayer.setProperty("3DLayerExtension", props3D);
633
                } else {
634
                        if (_bLoading)
635
                                props3D.setChooseType(false);
636
                        props3D.setLayer(layer);
637
                }
638

    
639
                return props3D;
640
        }
641

    
642
        public void addCurrentLayers() {
643
                SingleLayerIterator lyrIterator = new SingleLayerIterator(layers);
644
                while (lyrIterator.hasNext()) {
645
                        FLayer layer = lyrIterator.next();
646
                        Layer3DProps props = getLayer3DProps(layer);
647
                        // props.setTerrainOrder(props.getTocOrder());
648
                        addLayerToTerrain(layer, false);
649
                }
650
        }
651

    
652
        public synchronized void addLayerToTerrain(FLayer layer, boolean bVerifyLegend) {
653
                Layer3DProps props3D = getLayer3DProps(layer);
654

    
655
                if (props3D.getType() == Layer3DProps.layer3DVector) {
656
                        CreateVectors(layer, props3D); // special case for now without
657
                        // disk cache
658
                } else if (props3D.getType() == Layer3DProps.layer3DOSG) {
659
                        CreateOSGLayer(layer, props3D);
660
                } else {
661
                        Rectangle2D layerExtent = null;
662
                        try {
663
                                layerExtent = layer.getFullExtent();
664
                        } catch (ExpansionFileReadException e) {
665
                                e.printStackTrace();
666
                        } catch (ReadDriverException e) {
667
                                e.printStackTrace();
668
                        }
669
                        if (layerExtent == null) { // hack for missing extents
670
                                if (_terrain.getCoordinateSystemType() == Terrain.CoordinateSystemType.GEOCENTRIC)
671
                                        layerExtent = new Rectangle2D.Double(-180.0, -90.0, 360.0,
672
                                                        180.0);
673
                                else
674
                                        layerExtent = new Rectangle2D.Double(-20000000.0,
675
                                                        -10000000.0, 40000000.0, 20000000.0);
676
                                // TODO toggle comment because this code use WCS extension. When
677
                                // WCS extension runs correctly uncoment!!!
678

    
679
                                if (layer instanceof FLyrWCS)
680
                                        ((FLyrWCS) layer).setFullExtent(layerExtent);
681
                        }
682

    
683
                        Extent extent = null;
684
                        if (_terrain.getCoordinateSystemType() == CoordinateSystemType.PROJECTED) {
685
                                extent = new Extent(layerExtent.getMinX(), layerExtent
686
                                                .getMinY(), layerExtent.getMaxX(), layerExtent
687
                                                .getMaxY());
688
                        } else {
689
                                extent = new Extent(Math.toRadians(layerExtent.getMinX()), Math
690
                                                .toRadians(layerExtent.getMinY()), Math
691
                                                .toRadians(layerExtent.getMaxX()), Math
692
                                                .toRadians(layerExtent.getMaxY()));
693
                        }
694

    
695
                        if (props3D.getType() == Layer3DProps.layer3DImage) {
696
                                RasterLayer rlayer = new RasterLayer();
697
                                rlayer.setEnabled(layer.isVisible());
698
                                rlayer.setExtent(extent);
699
                                rlayer.setOpacity(props3D.getOpacity());
700
                                rlayer.setDataDriver(_terrainDataManager);
701
                                _terrainLayerManager.addLayer(rlayer);
702
                                _terrainFLayerMap.put(layer, rlayer);
703
                                _terrainLayerMap.put(rlayer.getLayerID(), layer);
704
                                props3D.setTerrainLayer(rlayer);
705
                        } else if (props3D.getType() == Layer3DProps.layer3DElevation) {
706
                                HeightfieldLayer hlayer = new HeightfieldLayer();
707
                                hlayer.setEnabled(layer.isVisible());
708
                                hlayer.setExtent(extent);
709
                                hlayer.setVerticalExaggeration(props3D.getVerticalEx());
710
                                hlayer.setDataDriver(_terrainDataManager);
711
                                _terrainLayerManager.addLayer(hlayer);
712
                                _terrainFLayerMap.put(layer, hlayer);
713
                                _terrainLayerMap.put(hlayer.getLayerID(), layer);
714
                                props3D.setTerrainLayer(hlayer);
715
                        } else if (props3D.getType() == Layer3DProps.layer3DVectorMR) {
716
                                VectorLayer vlayer = new VectorLayer();
717
                                vlayer.setEnabled(true);
718
                                vlayer.setExtent(extent);
719
                                vlayer.setDensity(1.0f);
720
                                vlayer.setDataDriver(_terrainDataManager);
721
                                _terrainLayerManager.addLayer(vlayer);
722
                                _terrainFLayerMap.put(layer, vlayer);
723
                                _terrainLayerMap.put(vlayer.getLayerID(), layer);
724
                                props3D.setTerrainLayer(vlayer);
725
                        }
726

    
727
                        if (bVerifyLegend) {
728
                                _bListenToLegend = false;
729
                                props3D.VerifyLegend(_terrain.getTerrainName());
730
                                _bListenToLegend = true;
731
                        }
732
                }
733
        }
734

    
735
        private void CreateOSGLayer(FLayer layer, Layer3DProps props3D) {
736
                if (_terrain == null || _viewProjection == null)
737
                        return;
738

    
739
                OSGCacheService cacheService = (OSGCacheService) props3D
740
                                .getCacheService();
741
                if (cacheService == null) {
742
                        cacheService = new OSGCacheService(_canvas3d, _terrain, props3D
743
                                        .getCacheName(), layer, _viewProjection);
744
                        cacheService.setCacheRootDir(Layer3DProps.m_cacheDir);
745
                        props3D.setCacheService(cacheService);
746
                }
747

    
748
                // use VectorCacheService to add features to planet
749
                cacheService.AddFeaturesToTerrain();
750

    
751
        }
752

    
753
        @Override
754
        public XMLEntity getXMLEntity() throws XMLException {
755
                // TODO Auto-generated method stub
756
                XMLEntity xml = super.getXMLEntity();
757

    
758
                SingleLayerIterator lyrIterator = new SingleLayerIterator(layers);
759
                while (lyrIterator.hasNext()) {
760
                        FLayer lyr = lyrIterator.next();
761
                        Layer3DProps props3D = getLayer3DProps(lyr);
762
                        int type = props3D.getType();
763
                        if (type == Layer3DProps.layer3DOSG) {
764

    
765
                                OSGCacheService cacheService = (OSGCacheService) props3D
766
                                                .getCacheService();
767
                                if (cacheService != null) {
768
                                        // use VectorCacheService to add features to planet
769
                                        if (props3D.isEditing()) {
770
                                                // TODO: PONER AKI EL CODIGO DE SALVAR
771
                                        }
772
                                }
773
                        }
774
                }
775

    
776
                return xml;
777

    
778
        }
779

    
780
        private void CreateVectors(FLayer layer, Layer3DProps props3D) {
781
                if (_terrain == null || _viewProjection == null)
782
                        return;
783

    
784
                VectorCacheService cacheService = (VectorCacheService) props3D
785
                                .getCacheService();
786
                if (cacheService == null) {
787
                        cacheService = new VectorCacheService(_canvas3d, _terrain, props3D
788
                                        .getCacheName(), layer, _viewProjection);
789
                        cacheService.setCacheRootDir(Layer3DProps.m_cacheDir);
790
                        props3D.setCacheService(cacheService);
791
                }
792

    
793
                // use VectorCacheService to add features to terrain
794
                cacheService.addFeaturesToTerrain();
795
        }
796

    
797
        private void DeleteVectors(FLayer layer, Layer3DProps props3D) {
798
                if (_terrain == null || _viewProjection == null)
799
                        return;
800

    
801
                VectorCacheService cacheService = (VectorCacheService) props3D
802
                                .getCacheService();
803
                if (cacheService != null) {
804
                        // use VectorCacheService to delete features to terrain
805
                        cacheService.deleteFeaturesToTerrain();
806
                }
807
        }
808

    
809
        /**
810
         * Sets the given zoom extent to the view
811
         * 
812
         * @param extent
813
         *            The extent to zoom to.
814
         */
815
        public void zoomToExtent(Rectangle2D geoExtent) {
816
                double maxHeight = 0.0;
817

    
818
                // Getting extent positions
819
                double minLat = geoExtent.getMinY();
820
                double maxLat = geoExtent.getMaxY();
821
                double cenLon = geoExtent.getCenterX();
822
                double cenLat = geoExtent.getCenterY();
823

    
824
                double elevation = 0;
825

    
826
                // calculate altitude
827
                double avLat = 0;
828
                if (minLat > 0.0 || maxLat < 0.0)
829
                        avLat = Math.min(Math.abs(minLat), Math.abs(maxLat));
830
                double avLon = Math.min(180.0, geoExtent.getWidth());
831

    
832
                double terrainRadius = _terrain.getRadiusEquatorial();
833
                double radiusLat = terrainRadius * Math.cos(Math.toRadians(avLat));
834
                double deltaLon = Math.sqrt(2 * radiusLat * radiusLat
835
                                * (1 - Math.cos(Math.toRadians(avLon))));
836
                double deltaLat = Math.sqrt(2 * terrainRadius * terrainRadius
837
                                * (1 - Math.cos(Math.toRadians(geoExtent.getHeight()))));
838

    
839
                double zoomFactor = 1.5;
840
                elevation = (Math.max(deltaLon, deltaLat) * zoomFactor) + maxHeight;
841

    
842
                // Calculate XYZ positions for camera.
843

    
844
                int terrainType = _terrain.getCoordinateSystemType();
845

    
846
                Vec3 eye = new Vec3();
847
                Vec3 center = new Vec3();
848
                Vec3 up = new Vec3();
849
                // Calculate positions for PLAIN MODE.
850
                if (terrainType == Terrain.CoordinateSystemType.PROJECTED) {
851

    
852
                        double difx = (geoExtent.getMaxX() - geoExtent.getX()) / 1.2d;
853
                        double dify = (geoExtent.getMaxY() - geoExtent.getY()) / 1.2d;
854
                        double height;
855

    
856
                        height = Math.sqrt(difx * difx + dify * dify);
857
                        double fullWindowFactor = 1.7;
858
                        // EYE
859
                        eye.setX(cenLon);
860
                        eye.setY(cenLat);
861
                        eye.setZ(height * fullWindowFactor);
862
                        // CENTER
863
                        center.setX(cenLon);
864
                        center.setY(cenLat);
865
                        center.setZ(0.0);
866
                        // UP
867
                        up.setX(0.0);
868
                        up.setY(1.0);
869
                        up.setZ(0.0);
870
                } else
871
                // Calculate positions for SPHERICAL MODE.
872
                if (terrainType == Terrain.CoordinateSystemType.GEOCENTRIC) {
873
                        // EYE
874
                        Vec3 aux = new Vec3(cenLat, cenLon, elevation);
875
                        eye = _terrain.convertLatLongHeightToXYZ(aux);
876
                        // CENTER
877
                        center.setX(0.0);
878
                        center.setY(0.0);
879
                        center.setZ(0.0);
880
                        // UP
881
                        up.setX(0.0);
882
                        up.setY(0.0);
883
                        up.setZ(1.0);
884
                }
885
                Camera cam = new Camera();
886
                cam.setViewByLookAt(eye, center, up);
887

    
888
                _terrainViewer.setCamera(cam);
889

    
890
        }
891

    
892
        private void PrintDebugLayers() {
893
                if (_terrainLayerManager != null) {
894
                        System.out.println("===========================");
895
                        System.out.println("Total terrain layers: "
896
                                        + _terrainLayerManager.getNumLayers());
897
                        System.out.println("===========================");
898
                }
899
                SingleLayerIterator lyrIterator = new SingleLayerIterator(layers);
900
                int pos = 0;
901
                while (lyrIterator.hasNext()) {
902
                        FLayer layer = lyrIterator.next();
903
                        System.out.println("  Layer " + layer.getName());
904
                        Layer3DProps props3D = getLayer3DProps(layer);
905
                        System.out.println("    Type " + props3D.getType());
906
                        System.out.println("    Order " + pos);
907
                        pos++;
908
                }
909
        }
910

    
911
        /**
912
         * Crea un nuevo MapContext(3D) a partir del XMLEntity.
913
         * 
914
         * @param xml
915
         *            XMLEntity
916
         * 
917
         * @return Nuevo MapContext3D.
918
         * 
919
         * @throws XMLException
920
         */
921
        public static MapContext createFromXML(XMLEntity xml) throws XMLException {
922
                ViewPort3D vp = (ViewPort3D) ViewPort3D.createFromXML(xml.getChild(0));
923

    
924
                FLayers layers = new FLayers3D(null, null, vp);
925
                layers.setXMLEntity(xml.getChild(1));
926

    
927
                MapContext fmap = layers.getMapContext();
928

    
929
                return fmap;
930
        }
931

    
932
        public static MapContext createFromXML03(XMLEntity xml) throws XMLException {
933
                ViewPort vp = ViewPort.createFromXML03(xml.getChild(0));
934

    
935
                FLayers layers = new FLayers3D(null, null, vp);
936
                layers.setXMLEntity03(xml.getChild(1));
937

    
938
                MapContext fmap = layers.getMapContext();
939

    
940
                return fmap;
941
        }
942

    
943
        public GraphicLayer getGraphicsLayer() {
944
                GraphicLayer3D gra3D = new GraphicLayer3D(_terrainViewer, getTerrain());
945
                return gra3D;
946
        }
947

    
948
        public Node getSpecialNode() {
949
                Node specialNode = null;
950
                try {
951
                        specialNode = _terrainViewer.getFeature(0);
952
                } catch (ChildIndexOutOfBoundsExceptions e) {
953
                        _logger.error("Command: " + "Error child index out of bound.", e);
954
                }
955
                return specialNode;
956
        }
957

    
958
        public ViewPort getViewPort() {
959

    
960
                ViewPort3D vp = (ViewPort3D) super.getViewPort();
961

    
962
                if (_canvas3d != null)
963
                        vp.setImageSize(new Dimension(_terrainViewer.getWidth(),
964
                                        _terrainViewer.getHeight()));
965
                vp.setTerrain(this.getTerrain());
966
                vp.setViewer(this._canvas3d);
967

    
968
                return vp;
969
        }
970

    
971
        /**
972
         * M�todo de conveniencia que se usa provisionalmente para solicitar un
973
         * refresco de todo lo que dependa del FMap (MapContext). Esto provocar�
974
         * un evento de cambio de orden de capas que obligar� a redibujar todo lo
975
         * que depende de FMap (TOC, MapControl, FFrameView, etc).
976
         */
977

    
978
        /*
979
         * public void invalidate() { ViewPort3D vp = (ViewPort3D)
980
         * super.getViewPort(); if (vp.getDirty()) { vp.setDirty(false); } FLayer[]
981
         * selectedExtent = getLayers().getActives();
982
         * 
983
         * if (selectedExtent.length > 0) { for (int i = 0; i <
984
         * selectedExtent.length; i++) { if (selectedExtent[0].isAvailable()) {
985
         * 
986
         * FLayer lyr3D = selectedExtent[i]; Layer3DProps layer3DProps =
987
         * Layer3DProps .getLayer3DProps(lyr3D);
988
         * 
989
         * Layer terrainLayer = _terrainFLayerMap.get(lyr3D); float opacity =
990
         * (((FLyrDefault) lyr3D).getTransparency()) / (float) 255; if()
991
         * //_terrain.setTextureOpacityLayer(order, opacity); } }
992
         * 
993
         * } }
994
         */
995

    
996
        public void selectionChanged(SelectionEvent e) {
997
                // TODO Auto-generated method stub
998
                SingleLayerIterator lyrIterator = new SingleLayerIterator(layers);
999
                while (lyrIterator.hasNext()) {
1000
                        FLayer layer = lyrIterator.next();
1001
                        Layer3DProps props3D = getLayer3DProps(layer);
1002
                        if (props3D.getType() != Layer3DProps.layer3DOSG) {
1003
                                if (layer.getClass().equals(FLyrVect.class)) {
1004
                                        FLyrVect lyr = (FLyrVect) layer;
1005

    
1006
                                        FBitSet selection = null;
1007
                                        try {
1008
                                                selection = lyr.getRecordset().getSelectionSupport()
1009
                                                                .getSelection();
1010
                                        } catch (ReadDriverException e1) {
1011
                                                // TODO Auto-generated catch block
1012
                                                e1.printStackTrace();
1013
                                        }
1014

    
1015
                                        if ((selection.cardinality() == 0)
1016
                                                        || (!(selection.isEmpty()))) {
1017
                                                Layer3DProps props = Layer3DProps
1018
                                                                .getLayer3DProps(layer);
1019
                                                refreshLayerInTerrain(props, true);
1020
                                                if (layer instanceof FLyrVect) {
1021
                                                        FLyrVect fvect = (FLyrVect) layer;
1022
                                                        props.drawVersion = fvect.getDrawVersion();
1023
                                                }
1024
                                        }
1025
                                }
1026
                        }
1027
                }
1028
        }
1029

    
1030
        public synchronized void removeLayerToTerrain(FLayer layer) {
1031
                // TODO Auto-generated method stub
1032
                Layer3DProps props3D = getLayer3DProps(layer);
1033

    
1034
                if (props3D.getType() == Layer3DProps.layer3DVector) {
1035
                        DeleteVectors(layer, props3D);
1036
                } else if (props3D.getType() == Layer3DProps.layer3DOSG) {
1037
                        DeleteOSGLayer(layer, props3D);
1038
                } else {
1039
                        Layer terrainLayer = _terrainFLayerMap.get(layer);
1040
                        if (terrainLayer != null) {
1041
                                _terrainLayerMap.remove(terrainLayer.getLayerID());
1042
                                _terrainFLayerMap.remove(layer);
1043

    
1044
                                _terrainLayerManager.removeLayer(terrainLayer);
1045
                        }
1046
                }
1047

    
1048
        }
1049

    
1050
        private void DeleteOSGLayer(FLayer layer, Layer3DProps props3D) {
1051
                if (_terrain == null || _viewProjection == null)
1052
                        return;
1053

    
1054
                OSGCacheService cacheService = (OSGCacheService) props3D
1055
                                .getCacheService();
1056
                if (cacheService != null) {
1057
                        // use VectorCacheService to delete features to terrain
1058
                        cacheService.DeleteFeaturesToTerrain();
1059
                }
1060
        }
1061

    
1062
        public boolean isRenewCanvasOff() {
1063
                return _renewCanvasOff;
1064
        }
1065

    
1066
        public void setRenewCanvasOff(boolean renewCanvasOff) {
1067
                _renewCanvasOff = renewCanvasOff;
1068
        }
1069

    
1070
        public void drawValueChanged(LayerEvent arg0) {
1071
                // TODO Auto-generated method stub
1072

    
1073
        }
1074

    
1075
        public UpdateDataEvent loadData(RequestDataEvent rde) {
1076

    
1077
                if (_terrainLayerMap.size() == 0)
1078
                        return null;
1079
                if (rde == null)
1080
                        return null;
1081
                if (rde.getExtent() == null)
1082
                        return null;
1083
                if (rde.getLayer() == null)
1084
                        return null;
1085
                if (rde.getLayerManager() == null)
1086
                        return null;
1087

    
1088
                UpdateDataEvent ude = new UpdateDataEvent();
1089
                ude.copyDataFromRequest(rde);
1090
                
1091

    
1092
                String layerID = rde.getLayer().getLayerID();
1093
                FLayer layer = (FLayer) _terrainLayerMap.get(layerID);
1094
                if (layer == null)
1095
                        return null;
1096
                if (!layer.isVisible())
1097
                        return null;
1098

    
1099
                Layer3DProps props3D = getLayer3DProps(layer);
1100

    
1101
                // get/create cache service
1102
                FLayerCacheService cacheService = (FLayerCacheService) props3D
1103
                                .getCacheService();
1104
                if (cacheService == null) {
1105
                        cacheService = new FLayerCacheService(_terrain, props3D
1106
                                        .getCacheName(), layer, _viewProjection);
1107
                        cacheService.setCacheRootDir(Layer3DProps.m_cacheDir);
1108
                        props3D.setCacheService(cacheService);
1109
                }
1110

    
1111
                int dataType = props3D.getType();
1112
                Point tileIndices = new Point(rde.getTileX(), rde.getTileY());
1113
                TileNum tileNum = new TileNum(rde.getTileLevel(), tileIndices);
1114

    
1115
                String tileFileName = "";
1116

    
1117
                double minX, minY, width, height;
1118

    
1119
                if (_terrain.getCoordinateSystemType() == CoordinateSystemType.PROJECTED) {
1120
                        minX = rde.getExtent().xMin();
1121
                        minY = rde.getExtent().yMin();
1122
                        width = rde.getExtent().xMax() - rde.getExtent().xMin();
1123
                        height = rde.getExtent().yMax() - rde.getExtent().yMin();
1124
                } else {
1125
                        minX = Math.toDegrees(rde.getExtent().xMin());
1126
                        minY = Math.toDegrees(rde.getExtent().yMin());
1127
                        width = Math.toDegrees(rde.getExtent().xMax()
1128
                                        - rde.getExtent().xMin());
1129
                        height = Math.toDegrees(rde.getExtent().yMax()
1130
                                        - rde.getExtent().yMin());
1131
                }
1132
                boolean failData = false;
1133

    
1134
                Rectangle2D extent = new Rectangle2D.Double(minX, minY, width, height);
1135
                if (cacheService.intersectsLayer(extent)) { // extent test
1136
                        try {
1137
                                tileFileName = cacheService.getTileAsFName(tileNum, extent);
1138
                                if(tileFileName == null)
1139
                                        failData = true;
1140
                        } catch (Exception e) {
1141
                                failData = true;
1142
                                NotificationManager.addInfo("Problem reading tile:" + tileNum, e);
1143
                                e.printStackTrace();
1144
                        }
1145

    
1146
                        if (failData) {
1147
                                return null;
1148
                                //ude.setFailData();
1149
                        } else {
1150
                                switch (dataType) {
1151
                                case Layer3DProps.layer3DImage:
1152
                                        ude.setRasterData(tileFileName, "gdal");
1153
                                        break;
1154
                                case Layer3DProps.layer3DElevation:
1155
                                        ude.setHeightfieldData(tileFileName, "gdal");
1156
                                        break;
1157
                                case Layer3DProps.layer3DVectorMR:
1158
                                        ude.setVectorData(tileFileName, "osg");
1159
                                        break;
1160
                                }
1161
                        }
1162
                }
1163

    
1164
                return ude;
1165
        }
1166
}