Statistics
| Revision:

svn-gvsig-desktop / import / ext3D / branches / ext3D_v1.1 / lib3DMap / src / com / iver / ai2 / gvsig3d / map3d / MapContext3D.java @ 15490

History | View | Annotate | Download (35.3 KB)

1
package com.iver.ai2.gvsig3d.map3d;
2

    
3
import java.awt.Component;
4
import java.awt.Dimension;
5
import java.awt.Point;
6
import java.awt.geom.Rectangle2D;
7
import java.io.File;
8
import java.util.ArrayList;
9

    
10
import javax.swing.JOptionPane;
11

    
12
import org.cresques.cts.ICoordTrans;
13
import org.cresques.cts.IProjection;
14
import org.gvsig.cacheservice.TileNum;
15

    
16
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
17
import com.iver.ai2.gvsig3d.cacheservices.FLayerCacheService;
18
import com.iver.ai2.gvsig3d.cacheservices.VectorCacheService;
19
import com.iver.ai2.gvsig3d.map3d.layers.FLayers3D;
20
import com.iver.ai2.gvsig3d.map3d.layers.Layer3DProps;
21
import com.iver.andami.PluginServices;
22
import com.iver.cit.gvsig.AddLayer;
23
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
24
import com.iver.cit.gvsig.fmap.MapContext;
25
import com.iver.cit.gvsig.fmap.ViewPort;
26
import com.iver.cit.gvsig.fmap.layers.FLayer;
27
import com.iver.cit.gvsig.fmap.layers.FLayers;
28
import com.iver.cit.gvsig.fmap.layers.FLyrDefault;
29
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
30
import com.iver.cit.gvsig.fmap.layers.FLyrWCS;
31
import com.iver.cit.gvsig.fmap.layers.GraphicLayer;
32
import com.iver.cit.gvsig.fmap.layers.LayerEvent;
33
import com.iver.cit.gvsig.fmap.layers.LayerListener;
34
import com.iver.cit.gvsig.fmap.layers.LegendListener;
35
import com.iver.cit.gvsig.fmap.layers.SingleLayerIterator;
36
import com.iver.cit.gvsig.fmap.layers.XMLException;
37
import com.iver.cit.gvsig.fmap.layers.layerOperations.Classifiable;
38
import com.iver.cit.gvsig.fmap.rendering.ILegend;
39
import com.iver.cit.gvsig.fmap.rendering.IVectorLegend;
40
import com.iver.cit.gvsig.fmap.rendering.LegendChangedEvent;
41
import com.iver.utiles.XMLEntity;
42

    
43
import es.upv.ai2.libjosg.Node;
44
import es.upv.ai2.libjosg.Vec3;
45
import es.upv.ai2.libjosg.planets.Planet;
46
import es.upv.ai2.libjosg.planets.PlanetViewer;
47
import es.upv.ai2.libjosg.planets.RequestLayerListener;
48
import es.upv.ai2.libjosg.planets.TileCreatedListener;
49
import es.upv.ai2.libjosg.planets.TileEvent;
50
import es.upv.ai2.libjosg.planets.Planet.PlanetType;
51
import es.upv.ai2.libjosg.viewer.Camera;
52
import es.upv.ai2.libjosg.viewer.IViewerContainer;
53

    
54
public class MapContext3D extends MapContext implements TileCreatedListener,
55
                RequestLayerListener, LayerListener, LegendListener {
56

    
57
        // JOSG library objects
58
        private Planet m_planet;
59

    
60
        private IViewerContainer m_canvas3d;
61
        
62
        private PlanetViewer planetViewer;
63

    
64
        // separate lists for image, elevation and vector layers
65
        private ArrayList m_layerLists = new ArrayList();
66

    
67
        private IProjection m_viewProjection;
68

    
69
        private float verticalExageration;
70

    
71
        private boolean m_bEmptyView = true;
72

    
73
        private boolean m_bListenToLegend = true;
74

    
75
        private boolean m_bLoading = false;
76

    
77
        // private Rectangle2D extentAux;
78

    
79
        // private ViewPort3D vport;
80

    
81
        public MapContext3D(ViewPort vp) {
82
                super(vp);
83

    
84
                ArrayList textureLayers = new ArrayList();
85
                ArrayList elevationLayers = new ArrayList();
86
                ArrayList vectorLayers = new ArrayList();
87
                m_layerLists.add(textureLayers);
88
                m_layerLists.add(elevationLayers);
89
                m_layerLists.add(vectorLayers);
90

    
91
                // extentAux = new Rectangle2D.Double(-180.0, 90.0, 180.0, -90.0);
92
        }
93

    
94
        public MapContext3D(FLayers fLayers, ViewPort vp) {
95
                super(fLayers, vp);
96

    
97
                ArrayList textureLayers = new ArrayList();
98
                ArrayList elevationLayers = new ArrayList();
99
                ArrayList vectorLayers = new ArrayList();
100
                m_layerLists.add(textureLayers);
101
                m_layerLists.add(elevationLayers);
102
                m_layerLists.add(vectorLayers);
103

    
104
                // extentAux = new Rectangle2D.Double(-180.0, 90.0, 180.0, -90.0);
105
        }
106

    
107
        public void setPlanet(Planet planet) {
108
                if (planet == m_planet)
109
                        return;
110

    
111
                m_planet = planet;
112

    
113
                // add layers to planet
114

    
115
                for (int iType = 0; iType < 3; iType++) {
116
                        ArrayList layerList = (ArrayList) m_layerLists.get(iType);
117
                        for (int iLayer = 0; iLayer < layerList.size(); iLayer++) {
118

    
119
                                FLayer layer = (FLayer) layerList.get(iLayer);
120
                                Layer3DProps props = getLayer3DProps(layer);
121
                                props.setPlanetOrder(props.getTocOrder());
122
                                addLayerToPlanet(layer, props.getPlanetOrder(), false);
123

    
124
                                // Layer active or not
125
                                if (props.getType() == Layer3DProps.layer3DImage) {
126
                                        m_planet.setEnabledTextureLayer(props.getPlanetOrder(),
127
                                                        layer.isVisible());
128
                                }
129
                                if (props.getType() == Layer3DProps.layer3DElevation) {
130
                                        m_planet.setEnabledHeightfieldLayer(0, layer.isVisible());
131
                                }
132
                        }
133
                        if (iType == Layer3DProps.layer3DElevation && layerList.size() > 0)
134
                                m_planet.invalidateHeightfieldLayer(0);
135
                }
136
        }
137

    
138
        public Planet getPlanet() {
139
                return m_planet;
140
        }
141

    
142
        public void setViewer(IViewerContainer canvas) {
143
                m_canvas3d = canvas;
144
                this.planetViewer = (PlanetViewer)m_canvas3d.getOSGViewer();
145
        }
146

    
147
        public IProjection getViewProjection() {
148
                return m_viewProjection;
149
        }
150

    
151
        public void setViewProjection(IProjection projection) {
152
                m_viewProjection = projection;
153
        }
154

    
155
        public IViewerContainer getCanvas3d() {
156
                return m_canvas3d;
157
        }
158

    
159
//        public void setCanvas3d(IViewerContainer m_canvas3d) {
160
//                this.m_canvas3d = m_canvas3d;
161
//                
162
//        }
163

    
164
        public float getVerticalExageration() {
165
                return verticalExageration;
166
        }
167

    
168
        public void setVerticalExageration(float verticalExageration) {
169
                this.verticalExageration = verticalExageration;
170
        }
171

    
172
        public void setLoading(boolean bLoading) {
173
                m_bLoading = bLoading;
174
        }
175

    
176
        public FLayers getNewGroupLayer(FLayers parent) {
177
                return new FLayers3D(this, parent, getViewPort());
178
        }
179

    
180
        /** * LAYER CHANGES called by FLayers3D ** */
181

    
182
        public void layerMoved(FLayers3D parent, FLayer layer, int oldPos,
183
                        int newPos) {
184

    
185
                if (layer instanceof FLayers) {
186
                        FLayers group = (FLayers) layer;
187
                        if (newPos > oldPos) {
188
                                for (int iChild = group.getLayersCount() - 1; iChild >= 0; iChild--)
189
                                        layerMoved((FLayers3D) group, group.getLayer(iChild),
190
                                                        oldPos, newPos);
191
                        } else {
192
                                for (int iChild = 0; iChild < group.getLayersCount(); iChild++)
193
                                        layerMoved((FLayers3D) group, group.getLayer(iChild),
194
                                                        oldPos, newPos);
195
                        }
196
                        return;
197
                }
198

    
199
                Layer3DProps props3D = getLayer3DProps(layer);
200
                if (props3D.getType() != Layer3DProps.layer3DImage)
201
                        return;
202

    
203
                refreshLayerOrder();
204

    
205
                ArrayList layerList = (ArrayList) m_layerLists.get(props3D.getType());
206

    
207
                // This will be more complex when we have multiple planets
208
                int currentPlanetOrder = props3D.getPlanetOrder();
209
                int newPlanetOrder = props3D.getTocOrder();
210
                if (currentPlanetOrder != newPlanetOrder) {
211
                        m_planet.reorderTextureLayer(currentPlanetOrder, newPlanetOrder);
212
                        // update planet order for all layers
213
                        for (int iLayer = 0; iLayer < layerList.size(); iLayer++) {
214
                                FLayer eachLayer = (FLayer) layerList.get(iLayer);
215
                                Layer3DProps eachProps3D = getLayer3DProps(eachLayer);
216
                                int currentPlanetOrderI = eachProps3D.getPlanetOrder();
217
                                if (currentPlanetOrder < newPlanetOrder) { // layer moves 'up'
218
                                        if (currentPlanetOrderI > currentPlanetOrder
219
                                                        && currentPlanetOrderI <= newPlanetOrder)
220
                                                eachProps3D.setPlanetOrder(currentPlanetOrderI - 1);
221
                                } else { // layer moves 'down'
222
                                        if (currentPlanetOrderI < currentPlanetOrder
223
                                                        && currentPlanetOrderI >= newPlanetOrder)
224
                                                eachProps3D.setPlanetOrder(currentPlanetOrderI + 1);
225
                                }
226
                        }
227
                        props3D.setPlanetOrder(newPlanetOrder);
228
                }
229

    
230
                // reorder all which may have changed in internal layer list
231
                ArrayList sortedLayers = new ArrayList(layerList.size());
232
                for (int iLayer = 0; iLayer < layerList.size(); iLayer++)
233
                        sortedLayers.add(null);
234

    
235
                for (int iLayer = 0; iLayer < layerList.size(); iLayer++) {
236
                        FLayer eachLayer = (FLayer) layerList.get(iLayer);
237
                        Layer3DProps eachProps3D = getLayer3DProps(eachLayer);
238
                        int newOrder = eachProps3D.getTocOrder();
239
                        sortedLayers.set(newOrder, eachLayer);
240
                }
241
                m_layerLists.set(props3D.getType(), sortedLayers);
242

    
243
                PrintDebugLayers();
244
                // REPAINTING VIEWER
245
                if (m_canvas3d != null)
246
                        m_canvas3d.repaint();
247
        }
248

    
249
        public void layerAdded(FLayers3D parent, FLayer layer) {
250

    
251
                // to add group layers to 3D, just add recursively child data layers
252
                if (layer instanceof FLayers) {
253
                        FLayers group = (FLayers) layer;
254
                        for (int iChild = 0; iChild < group.getLayersCount(); iChild++) {
255
                                layerAdded((FLayers3D) group, group.getLayer(iChild));
256
                        }
257
                        getLayer3DProps(layer).setHooked(true);
258
                        return;
259
                }
260

    
261
                if (layer instanceof Classifiable) {
262
                        Classifiable legendLyr = (Classifiable) layer;
263
                        legendLyr.addLegendListener((LegendListener) this);
264
                }
265
                layer.addLayerListener((LayerListener) this);
266

    
267
                // LINEAS COMETADAS PARA Q NO PREGUNTE DOS VECES QUE SI QUEREMOS REPROYECTAR LA CAPA
268
                // SI SE COMENTA LAS LINEAS CUANDO SE COPIA Y PEGA UNA CAPA NO PREGUNTA SI QUEREMOS REPROJECTAR
269
//                if (!m_bLoading)
270
//                        checkProjection(layer, getViewPort().getProjection());
271

    
272
                int order = addLayerByType(layer);
273
                if (order == -1) {
274
                        // an error has been generated
275
                        parent.removeLayer(layer);
276
                        return;
277
                }
278

    
279
                if (!m_bLoading)
280
                        addLayerToPlanet(layer, order, true);
281

    
282
                // Only do this the first time to add layer
283
                ArrayList layerListI = (ArrayList) m_layerLists
284
                                .get(Layer3DProps.layer3DImage);
285
                ArrayList layerListV = (ArrayList) m_layerLists
286
                                .get(Layer3DProps.layer3DVector);
287

    
288
                if (m_bEmptyView && !m_bLoading) {
289
                        if (!((layerListI.size() == 1) && (layerListV.size() == 0))
290
                                        || !((layerListI.size() == 0) && (layerListV.size() == 1))) {
291
                                try {
292
                                        zoomToExtent(layer.getFullExtent());
293
                                } catch (ExpansionFileReadException e) {
294
                                        e.printStackTrace();
295
                                } catch (ReadDriverException e) {
296
                                        e.printStackTrace();
297
                                }
298
                                m_bEmptyView = false;
299
                        }
300
                }
301

    
302
                PrintDebugLayers();
303
        }
304

    
305
        public void layerRemoved(FLayers3D parent, FLayer layer) {
306

    
307
                // to remove group layers to 3D, just remove recursively child data
308
                // layers
309
                if (layer instanceof FLayers) {
310
                        FLayers group = (FLayers) layer;
311
                        for (int iChild = 0; iChild < group.getLayersCount(); iChild++) {
312
                                layerRemoved((FLayers3D) group, group.getLayer(iChild));
313
                        }
314
                        getLayer3DProps(layer).setHooked(false);
315
                        return;
316
                }
317

    
318
                if (layer instanceof Classifiable) {
319
                        Classifiable legendLyr = (Classifiable) layer;
320
                        legendLyr.removeLegendListener((LegendListener) this);
321
                }
322
                layer.removeLayerListener((LayerListener) this);
323

    
324
                int order = removeLayerByType(layer);
325
                if (order == -1)
326
                        return;
327

    
328
                Layer3DProps props3D = getLayer3DProps(layer);
329

    
330
                if (props3D.getType() == Layer3DProps.layer3DVector) {
331
                        DeleteVectors(layer, props3D);
332
                } else if (props3D.getType() == Layer3DProps.layer3DImage) {
333
                        m_planet.removeTextureLayer(props3D.getPlanetOrder());
334
                        ArrayList layerList = (ArrayList) m_layerLists.get(props3D
335
                                        .getType());
336

    
337
                        for (int iLayer = 0; iLayer < layerList.size(); iLayer++) {
338
                                FLayer eachLayer = (FLayer) layerList.get(iLayer);
339
                                Layer3DProps eachProps3D = getLayer3DProps(eachLayer);
340
                                if (eachProps3D.getPlanetOrder() > props3D.getPlanetOrder())
341
                                        eachProps3D
342
                                                        .setPlanetOrder(eachProps3D.getPlanetOrder() - 1);
343
                        }
344
                        props3D.setPlanetOrder(-1);
345
                } else if (props3D.getType() == Layer3DProps.layer3DElevation) {
346
                        m_planet.removeHeightfieldLayer(order);
347
                }
348

    
349
                // REPAINTING VIEWER
350
                if (m_canvas3d != null)
351
                        m_canvas3d.repaint();
352

    
353
                ArrayList layerListI = (ArrayList) m_layerLists
354
                                .get(Layer3DProps.layer3DImage);
355
                ArrayList layerListV = (ArrayList) m_layerLists
356
                                .get(Layer3DProps.layer3DVector);
357
                // All layers are removed
358
                if ((layerListI.size() == 0) && (layerListV.size() == 0)) {
359
                        m_bEmptyView = true;
360
                }
361

    
362
                PrintDebugLayers();
363
        }
364

    
365
        /**
366
         * DOCUMENT ME!
367
         * 
368
         * @param e
369
         *            DOCUMENT ME!
370
         */
371
        public void legendChanged(LegendChangedEvent e) {
372

    
373
                if (!m_bListenToLegend)
374
                        return;
375

    
376
                IVectorLegend newLegend = (IVectorLegend) e.getNewLegend();
377
                // find layer whose legend changed
378
                FLayer found = null;
379
                SingleLayerIterator lyrIterator = new SingleLayerIterator(layers);
380
                while (lyrIterator.hasNext()) {
381
                        FLayer lyr = lyrIterator.next();
382
                        if (lyr instanceof Classifiable) {
383
                                Classifiable classLyr = (Classifiable) lyr;
384
                                ILegend legend = classLyr.getLegend();
385
                                if (legend instanceof IVectorLegend) {
386
                                        if ((IVectorLegend) legend == newLegend) {
387
                                                found = lyr;
388
                                                break;
389
                                        }
390
                                }
391
                        }
392
                }
393

    
394
                if (found != null) {
395
                        Layer3DProps props3D = getLayer3DProps(found);
396
                        refreshLayerInPlanet(props3D, true);
397
                        m_bListenToLegend = false;
398
                        props3D.VerifyLegend(m_planet);
399
                        m_bListenToLegend = true;
400
                        // REPAINTING VIWER
401
                        if (m_canvas3d != null)
402
                                m_canvas3d.repaint();
403
                }
404
        }
405

    
406
        public void visibilityChanged(LayerEvent e) {
407
                FLayer lyr = e.getSource();
408

    
409
                Layer3DProps props3D = getLayer3DProps(lyr);
410

    
411
                if (props3D.getType() == Layer3DProps.layer3DVector) {
412
                        refreshLayerVectorsVisibility(lyr);
413
                } else {
414
                        refreshLayerVisibility(lyr);
415
                }
416
                m_canvas3d.repaint();
417
        }
418

    
419
        private void refreshLayerVisibility(FLayer layer) {
420

    
421
                Layer3DProps props3D = getLayer3DProps(layer);
422
                if (props3D.getType() == Layer3DProps.layer3DImage) {
423
                        m_planet.setEnabledTextureLayer(props3D.getPlanetOrder(), layer
424
                                        .isVisible());
425
                }
426
                if (props3D.getType() == Layer3DProps.layer3DElevation) {
427
                        m_planet.setEnabledHeightfieldLayer(0, layer.isVisible());
428
                }
429
                // REPAINTING VIEWER
430
                if (m_canvas3d != null)
431
                        m_canvas3d.repaint();
432
        }
433

    
434
        private void refreshLayerVectorsVisibility(FLayer lyr) {
435
                if (m_planet == null || m_viewProjection == null)
436
                        return;
437

    
438
                Layer3DProps props3D = getLayer3DProps(lyr);
439

    
440
                VectorCacheService cacheService = (VectorCacheService) props3D
441
                                .getCacheService();
442
                if (cacheService != null) {
443
                        // use VectorCacheService to add features to planet
444
                        cacheService.refreshFeaturesToPlanet(lyr.isVisible());
445
                }
446

    
447
        }
448

    
449
        public void activationChanged(LayerEvent e) {
450
                // TODO Implement this method
451
        }
452

    
453
        public void nameChanged(LayerEvent e) {
454
                // TODO Implement this method
455
        }
456

    
457
        public void editionChanged(LayerEvent e) {
458
                // TODO Implement this method
459
        }
460

    
461
        public void refreshLayerInPlanet(Layer3DProps props, boolean bRemoveCache) {
462
                if (props == null)
463
                        return;
464

    
465
                if (m_planet == null)
466
                        return; // view not opened yet
467

    
468
                // clear cache
469

    
470
                if (bRemoveCache) {
471
                        String layerCacheDir = Layer3DProps.m_cacheDir + "/"
472
                                        + m_planet.getPlanetName() + "/" + props.getCacheName();
473
                        removeCache(layerCacheDir);
474
                }
475

    
476
                // refresh layer in planet
477

    
478
                int type = props.getType();
479
                if (type == Layer3DProps.layer3DImage) {
480
                        int order = props.getPlanetOrder();
481
                        // m_planet.refreshTextureInfo(order);
482
                        m_planet.invalidateTextureLayer(order);
483
                } else if (type == Layer3DProps.layer3DElevation) {
484
                        m_planet.invalidateHeightfieldLayer(0);
485
                } else if (type == Layer3DProps.layer3DVector) {
486
                        invalidateVectorLayer(props);
487
                }
488

    
489
                // REPAINTING VIEWER
490
                if (m_canvas3d != null)
491
                        m_canvas3d.repaint();
492
        }
493

    
494
        private void invalidateVectorLayer(Layer3DProps props) {
495
                // TODO Auto-generated method stub
496
                if (m_planet == null || m_viewProjection == null)
497
                        return;
498

    
499
                VectorCacheService cacheService = (VectorCacheService) props
500
                                .getCacheService();
501
                if (cacheService != null) {
502
                        // use VectorCacheService to add features to planet
503
                        cacheService.RefreshFeaturesToPlanet();
504
                }
505
        }
506

    
507
        private boolean removeCache(String folder) {
508
                File dir = new File(folder);
509
                if (dir.isDirectory()) {
510
                        String[] children = dir.list();
511
                        for (int i = 0; i < children.length; i++) {
512
                                boolean success = removeCache(folder + "/" + children[i]);
513
                                // Do not interrupt if it can't delete one file
514
                                // if (!success) {
515
                                // return false;
516
                                // }
517
                        }
518
                }
519

    
520
                // The directory is now empty so delete it
521
                return dir.delete();
522
        }
523

    
524
        protected Layer3DProps getLayer3DProps(FLayer layer) {
525
                Layer3DProps props3D = Layer3DProps.getLayer3DProps(layer);
526
                if (props3D == null) {
527
                        props3D = new Layer3DProps();
528
                        props3D.setLayer(layer);
529
                        props3D.initCacheName(m_planet.getType(), m_viewProjection);
530
                        FLyrDefault baseLayer = (FLyrDefault) layer;
531
                        baseLayer.setProperty("3DLayerExtension", props3D);
532
                        props3D.setVerticalEx(this.getVerticalExageration());
533
                } else {
534
                        if (m_bLoading)
535
                                props3D.setChooseType(false);
536
                        props3D.setLayer(layer);
537
                }
538

    
539
                return props3D;
540
        }
541

    
542
        private void addLayerToPlanet(FLayer layer, int order, boolean bVerifyLegend) {
543
                Layer3DProps props3D = getLayer3DProps(layer);
544
                if (props3D.getType() == Layer3DProps.layer3DVector)
545
                        CreateVectors(layer, props3D); // special case for now without
546
                // disk cache
547
                else {
548
                        Rectangle2D layerExtent = null;
549
                        try {
550
                                layerExtent = layer.getFullExtent();
551
                        } catch (ExpansionFileReadException e) {
552
                                e.printStackTrace();
553
                        } catch (ReadDriverException e) {
554
                                e.printStackTrace();
555
                        }
556
                        if (layerExtent == null) { // hack for missing extents
557
                                if (m_planet.getType() == PlanetType.GEOCENTRIC)
558
                                        layerExtent = new Rectangle2D.Double(-180.0, -90.0, 360.0,
559
                                                        180.0);
560
                                else
561
                                        layerExtent = new Rectangle2D.Double(-20000000.0,
562
                                                        -10000000.0, 40000000.0, 20000000.0);
563
                                // TODO toggle comment because this code use WCS extension. When WCS extension runs correctly uncoment!!!
564
                                
565
                                if (layer instanceof FLyrWCS)
566
                                        ((FLyrWCS) layer).setFullExtent(layerExtent);
567
                                /**/
568
                        }
569
                        if (props3D.getType() == Layer3DProps.layer3DElevation)
570
                                m_planet.addHeightfieldLayer(layerExtent, 3);
571
                        else if (props3D.getType() == Layer3DProps.layer3DImage) {
572
                                m_planet.addTextureLayer(layerExtent, 0);
573
                                ArrayList imageList = (ArrayList) m_layerLists
574
                                                .get(Layer3DProps.layer3DImage);
575
                                int currentOrder = imageList.size() - 1;
576
                                if (currentOrder != order) { // had to be added to non-last
577
                                                                                                // position
578
                                        m_planet.reorderTextureLayer(currentOrder, order);
579
                                        for (int iLayer = 0; iLayer < imageList.size(); iLayer++) {
580
                                                FLayer eachLayer = (FLayer) imageList.get(iLayer);
581
                                                Layer3DProps eachProps3D = getLayer3DProps(eachLayer);
582
                                                if (eachProps3D.getPlanetOrder() >= order)
583
                                                        eachProps3D.setPlanetOrder(eachProps3D
584
                                                                        .getPlanetOrder() + 1);
585
                                        }
586
                                }
587
                                props3D.setPlanetOrder(order);
588
                        }
589
                        // REPAINTING VIEWER
590
                        if (m_canvas3d != null)
591
                                m_canvas3d.repaint();
592

    
593
                        if (bVerifyLegend) {
594
                                m_bListenToLegend = false;
595
                                props3D.VerifyLegend(m_planet);
596
                                m_bListenToLegend = true;
597
                        }
598
                }
599
        }
600

    
601
        private void refreshLayerOrder() {
602
                int typeOrder[] = new int[3];
603
                typeOrder[Layer3DProps.layer3DImage] = 0;
604
                typeOrder[Layer3DProps.layer3DElevation] = 0;
605
                typeOrder[Layer3DProps.layer3DVector] = 0;
606

    
607
                SingleLayerIterator lyrIterator = new SingleLayerIterator(layers);
608
                while (lyrIterator.hasNext()) {
609
                        FLayer lyr = lyrIterator.next();
610
                        Layer3DProps props3D = getLayer3DProps(lyr);
611
                        int type = props3D.getType();
612
                        // stores new order in properties 3D, but doesn't reorder internal
613
                        // layer lists
614
                        props3D.setTocOrder(typeOrder[type]);
615
                        typeOrder[type] += 1;
616
                }
617
        }
618

    
619
        private int addLayerByType(FLayer layer) {
620
                int resultOrder = -1;
621

    
622
                int typeOrder[] = new int[3];
623
                typeOrder[Layer3DProps.layer3DImage] = 0;
624
                typeOrder[Layer3DProps.layer3DElevation] = 0;
625
                typeOrder[Layer3DProps.layer3DVector] = 0;
626

    
627
                SingleLayerIterator lyrIterator = new SingleLayerIterator(layers);
628
                while (lyrIterator.hasNext()) {
629
                        FLayer lyr = lyrIterator.next();
630
                        Layer3DProps props3D = getLayer3DProps(lyr);
631
                        int type = props3D.getType();
632
                        // in pilot, limit to 1 the number of elevation layers
633
                        if (type == Layer3DProps.layer3DElevation && typeOrder[type] == 1) {
634
                                JOptionPane.showMessageDialog((Component) PluginServices
635
                                                .getMainFrame(), PluginServices.getText(this,
636
                                                "Only_one_elevation_messg"), PluginServices.getText(
637
                                                this, "Only_one_elevation_title"),
638
                                                JOptionPane.INFORMATION_MESSAGE);
639
                                return -1; // error value
640
                        }
641

    
642
                        // stores new order in properties 3D, but doesn't reorder internal
643
                        // layer lists
644
                        props3D.setTocOrder(typeOrder[type]);
645
                        typeOrder[type] += 1;
646

    
647
                        if (layer == lyr) {
648
                                resultOrder = props3D.getTocOrder();
649
                                ArrayList layerList = (ArrayList) m_layerLists.get(type);
650
                                if (resultOrder == layerList.size()
651
                                                || layerList.get(resultOrder) != layer)
652
                                        layerList.add(resultOrder, layer);
653
                        }
654
                }
655

    
656
                return resultOrder;
657
        }
658

    
659
        private int removeLayerByType(FLayer layer) {
660

    
661
                Layer3DProps props3D = getLayer3DProps(layer);
662
                ArrayList layerList = (ArrayList) m_layerLists.get(props3D.getType());
663
                int currentOrder = props3D.getTocOrder();
664
                if (currentOrder == -1)
665
                        return -1;
666

    
667
                layerList.remove(currentOrder);
668

    
669
                for (int i = currentOrder; i < layerList.size(); i++) {
670
                        FLayer lyrAux = (FLayer) layerList.get(i);
671
                        Layer3DProps props3DAux = getLayer3DProps(lyrAux);
672
                        props3DAux.setTocOrder(i);
673
                }
674
                return currentOrder;
675
        }
676

    
677
        private void CreateVectors(FLayer layer, Layer3DProps props3D) {
678
                if (m_planet == null || m_viewProjection == null)
679
                        return;
680

    
681
                VectorCacheService cacheService = (VectorCacheService) props3D
682
                                .getCacheService();
683
                if (cacheService == null) {
684
                        cacheService = new VectorCacheService(m_canvas3d, m_planet, props3D
685
                                        .getCacheName(), layer, m_viewProjection);
686
                        cacheService.setCacheRootDir(Layer3DProps.m_cacheDir);
687
                        props3D.setCacheService(cacheService);
688
                }
689

    
690
                // use VectorCacheService to add features to planet
691
                cacheService.AddFeaturesToPlanet();
692
        }
693

    
694
        private void DeleteVectors(FLayer layer, Layer3DProps props3D) {
695
                if (m_planet == null || m_viewProjection == null)
696
                        return;
697

    
698
                VectorCacheService cacheService = (VectorCacheService) props3D
699
                                .getCacheService();
700
                if (cacheService != null) {
701
                        // use VectorCacheService to delete features to planet
702
                        cacheService.DeleteFeaturesToPlanet();
703
                }
704
        }
705

    
706
        /**
707
         * Sets the given zoom extent to the view
708
         * 
709
         * @param extent
710
         *            The extent to zoom to.
711
         */
712
        public void zoomToExtent(Rectangle2D geoExtent) {
713
                double maxHeight = 0.0;
714

    
715
                // Getting extent positions
716
                double minLat = geoExtent.getMinY();
717
                double maxLat = geoExtent.getMaxY();
718
                double cenLon = geoExtent.getCenterX();
719
                double cenLat = geoExtent.getCenterY();
720

    
721
                double elevation = 0;
722

    
723
                // calculate altitude
724
                double avLat = 0;
725
                if (minLat > 0.0 || maxLat < 0.0)
726
                        avLat = Math.min(Math.abs(minLat), Math.abs(maxLat));
727
                double avLon = Math.min(180.0, geoExtent.getWidth());
728

    
729
                double planetRadius = m_planet.getRadiusEquatorial();
730
                double radiusLat = planetRadius * Math.cos(Math.toRadians(avLat));
731
                double deltaLon = Math.sqrt(2 * radiusLat * radiusLat
732
                                * (1 - Math.cos(Math.toRadians(avLon))));
733
                double deltaLat = Math.sqrt(2 * planetRadius * planetRadius
734
                                * (1 - Math.cos(Math.toRadians(geoExtent.getHeight()))));
735

    
736
                double zoomFactor = 1.0;
737
                elevation = (Math.max(deltaLon, deltaLat) * zoomFactor) + maxHeight;
738

    
739
                // Calculate XYZ positions for camera.
740

    
741
                int planetType = this.m_planet.getType();
742

    
743
                Vec3 eye = new Vec3();
744
                Vec3 center = new Vec3();
745
                Vec3 up = new Vec3();
746
                // Calculate positions for PLAIN MODE.
747
                if (planetType == PlanetType.PROJECTED) {
748

    
749
                        double difx = (geoExtent.getMaxX() - geoExtent.getX()) / 1.2d;
750
                        double dify = (geoExtent.getMaxY() - geoExtent.getY()) / 1.2d;
751
                        double height;
752

    
753
                        height = Math.sqrt(difx * difx + dify * dify);
754

    
755
                        // EYE
756
                        eye.setX(cenLon);
757
                        eye.setY(cenLat);
758
                        eye.setZ(height);
759
                        // eye.setZ(5000000 * 4.6);
760
                        // CENTER
761
                        center.setX(cenLon);
762
                        center.setY(cenLat);
763
                        center.setZ(0.0);
764
                        // UP
765
                        up.setX(0.0);
766
                        up.setY(1.0);
767
                        up.setZ(0.0);
768
                } else
769
                // Calculate positions for SPHERICAL MODE.
770
                if (planetType == PlanetType.PROJECTED) {
771
                        // EYE
772
                        Vec3 aux = new Vec3(cenLat, cenLon, elevation);
773
                        eye = m_planet.convertLatLongHeightToXYZ(aux);
774
                        // CENTER
775
                        center.setX(0.0);
776
                        center.setY(0.0);
777
                        center.setZ(0.0);
778
                        // UP
779
                        up.setX(0.0);
780
                        up.setY(0.0);
781
                        up.setZ(1.0);
782
                }
783
                Camera cam = new Camera();
784
                cam.setViewByLookAt(eye, center, up);
785

    
786
                // UtilCoord.imprimeCamara(cam);
787

    
788
                planetViewer.setCamera(cam);
789
                // REPAINTING VIEWER
790
                if (m_canvas3d != null)
791
                        m_canvas3d.repaint();
792

    
793
        }
794

    
795
        // Makes sure layer's projection is the same as MapContext's
796

    
797
        private void checkProjection(FLayer lyr, IProjection viewProj) {
798
                if (lyr instanceof FLyrVect) {
799
                        FLyrVect lyrVect = (FLyrVect) lyr;
800
                        IProjection proj = lyr.getProjection();
801
                        // Make sure projection is the same than the view
802
                        if (proj == null) {
803
                                // 
804
                                lyrVect.setProjection(viewProj);
805
                                return;
806
                        }
807
                        if (lyr instanceof FLyrVect) {
808
                                // Comprobar que la projecci?n es la misma que la vista
809
                                if (proj == null) {
810
                                        // SUPONEMOS que la capa est? en la proyecci?n que
811
                                        // estamos pidiendo (que ya es mucho suponer, ya).
812
                                        lyrVect.setProjection(getViewPort().getProjection());
813
                                        return;
814
                                }
815
                                int option = JOptionPane.YES_OPTION;
816
                                if (proj != getViewPort().getProjection()) {
817
                                        option = JOptionPane.showConfirmDialog(
818
                                                        (Component) PluginServices.getMainFrame(),
819
                                                        PluginServices.getText(AddLayer.class,
820
                                                                        "reproyectar_aviso")
821
                                                                        + "\n"
822
                                                                        + PluginServices.getText(AddLayer.class,
823
                                                                                        "Capa") + ": " + lyrVect.getName(),
824
                                                        PluginServices.getText(AddLayer.class,
825
                                                                        "reproyectar_pregunta"),
826
                                                        JOptionPane.YES_NO_OPTION);
827

    
828
                                        if (option != JOptionPane.OK_OPTION) {
829
                                                return;
830
                                        }
831

    
832
                                        ICoordTrans ct = proj.getCT(getViewPort().getProjection());
833
                                        lyrVect.setCoordTrans(ct);
834
                                        System.err.println("coordTrans = " + proj.getAbrev() + " "
835
                                                        + getViewPort().getProjection().getAbrev());
836
                                }
837
                        }
838

    
839
                        /*******************************************************************
840
                         * Version compatible con 1.0.2 y no con el HEAD
841
                         */
842

    
843
                        // if (proj != viewProj) {
844
                        // int option = JOptionPane.YES_OPTION;
845
                        // if (!CRSFactory.doesRigurousTransformations()) {
846
                        // option = JOptionPane.showConfirmDialog(null, PluginServices
847
                        // .getText(this, "reproyectar_aviso"), PluginServices
848
                        // .getText(this, "reproyectar_pregunta"),
849
                        // JOptionPane.YES_NO_OPTION);
850
                        // }
851
                        //
852
                        // if (option == JOptionPane.NO_OPTION) {
853
                        // return;
854
                        // } else {
855
                        // ICoordTrans ct = proj.getCT(viewProj);
856
                        // lyrVect.setCoordTrans(ct);
857
                        // System.err.println("coordTrans = " + proj.getAbrev() + " "
858
                        // + viewProj.getAbrev());
859
                        // }
860
                        // }
861
                }
862
        }
863

    
864
        /** * CALLBACKS for Tiles ** */
865

    
866
        public void tileCreated(TileEvent evt) {
867
                int textureStage = 0;
868
                int MDTStage = 0;
869

    
870
                SingleLayerIterator lyrIterator = new SingleLayerIterator(layers);
871
                while (lyrIterator.hasNext()) {
872
                        FLayer lyr = lyrIterator.next();
873

    
874
                        Layer3DProps props3D = getLayer3DProps(lyr);
875
                        int dataType = props3D.getType();
876

    
877
                        if (lyr.isVisible()) { // if (true) {
878
                                if (dataType == Layer3DProps.layer3DVector)
879
                                        continue; // get/create cache service
880
                                FLayerCacheService cacheService = (FLayerCacheService) props3D
881
                                                .getCacheService();
882
                                if (cacheService == null) {
883
                                        cacheService = new FLayerCacheService(m_planet, props3D
884
                                                        .getCacheName(), lyr, m_viewProjection);
885
                                        cacheService.setCacheRootDir(Layer3DProps.m_cacheDir);
886
                                        props3D.setCacheService(cacheService);
887
                                }
888

    
889
                                Point tileIndices = new Point(evt.getX(), evt.getY());
890
                                TileNum tileNum = new TileNum(evt.getLevel(), tileIndices);
891

    
892
                                String tileFileName;
893

    
894
                                if (cacheService.intersectsLayer(tileNum)) { // extent test
895
                                        try {
896
                                                tileFileName = cacheService.getTileAsFName(tileNum);
897
                                        } catch (Exception e) {
898
                                                return;
899
                                        }
900

    
901
                                        if (dataType == Layer3DProps.layer3DImage) {
902
                                                // float opacity = 1.0f;
903
                                                String fileExtension = "png";
904
                                                m_planet.setTexture(evt.getTilePagedLod(),
905
                                                                tileFileName, textureStage);
906
                                                m_planet.setTextureOpacityLayer(textureStage, props3D
907
                                                                .getOpacity());
908
                                                textureStage++;
909
                                        } else if (dataType == Layer3DProps.layer3DElevation) {
910
                                                String fileExtension = "tif";
911
                                                m_planet.setHeightfield(evt.getTilePagedLod(),
912
                                                                tileFileName, MDTStage);
913
                                                m_planet.setVerticalExaggerationLayer(MDTStage, props3D
914
                                                                .getVerticalEx());
915
                                                MDTStage++;
916
                                        }
917
                                } else { // no intersection
918
                                        if (dataType == Layer3DProps.layer3DImage) {
919
                                                m_planet.setTexture(evt.getTilePagedLod(), "",
920
                                                                textureStage++);
921
                                        }
922
                                        if (dataType == Layer3DProps.layer3DElevation) {
923
                                                m_planet.setHeightfield(evt.getTilePagedLod(), "",
924
                                                                MDTStage);
925
                                        }
926
                                }
927
                        } else {
928
                                if (dataType == Layer3DProps.layer3DImage) {
929
                                        textureStage++;
930
                                }
931
                                if (dataType == Layer3DProps.layer3DElevation) {
932
                                        MDTStage++;
933
                                }
934
                        } // REPAINTING VIEWER
935
                        if (m_canvas3d != null)
936
                                m_canvas3d.repaint();
937
                }
938
        }
939

    
940
        public void requestMDTLayer(TileEvent evt) {
941

    
942
                // TODO : All this method are not tested
943
                // ignore for now
944

    
945
                /* ********** UNCOMENT FOR TEST IT *************************** */
946
                int order = evt.getRequestedLayer();
947
                ArrayList imageLayers = (ArrayList) m_layerLists
948
                                .get(Layer3DProps.layer3DElevation);
949
                FLayer layer = (FLayer) imageLayers.get(order);
950
                if ((layer == null) || (!layer.isVisible()))
951
                        return;
952

    
953
                Layer3DProps props3D = getLayer3DProps(layer);
954
                // get/create cache service
955
                FLayerCacheService cacheService = (FLayerCacheService) props3D
956
                                .getCacheService();
957
                if (cacheService == null) {
958
                        cacheService = new FLayerCacheService(m_planet, props3D
959
                                        .getCacheName(), layer, m_viewProjection);
960
                        cacheService.setCacheRootDir(Layer3DProps.m_cacheDir);
961
                        props3D.setCacheService(cacheService);
962
                }
963

    
964
                int dataType = props3D.getType();
965
                Point tileIndices = new Point(evt.getX(), evt.getY());
966
                TileNum tileNum = new TileNum(evt.getLevel(), tileIndices);
967

    
968
                String tileFileName;
969

    
970
                if (cacheService.intersectsLayer(tileNum)) { // extent test
971
                        try {
972
                                tileFileName = cacheService.getTileAsFName(tileNum);
973
                        } catch (Exception e) {
974
                                return;
975
                        }
976

    
977
                        if (dataType == Layer3DProps.layer3DElevation) {
978
                                String fileExtension = "tif";
979
                                // evt.getTilePagedLod().setHeightField(tileFileName,
980
                                // fileExtension, order);
981
                                m_planet.setHeightfield(evt.getTilePagedLod(), tileFileName,
982
                                                order);
983
                                // m_planet.setVerticalExaggeration(order,
984
                                // ((ProjectView3D) this.m_viewProjection)
985
                                // .getVerticalExaggeration());
986
                                m_planet.setVerticalExaggerationLayer(order, props3D
987
                                                .getVerticalEx());
988

    
989
                        }
990
                } else { // no intersection for elevation layer
991
                        // This code are not correctly for elevation layer
992
                        if (dataType == Layer3DProps.layer3DImage) {
993
                                m_planet.setHeightfield(evt.getTilePagedLod(), "", order);
994
                                // evt.getTilePagedLod().setHeightField("", "", order);
995
                        }
996
                }
997

    
998
                // REPAINTING VIEWWER
999
                if (m_canvas3d != null)
1000
                        m_canvas3d.repaint();
1001

    
1002
        }
1003

    
1004
        public void requestTextureLayer(TileEvent evt) {
1005

    
1006
                int order = evt.getRequestedLayer();
1007
                ArrayList imageLayers = (ArrayList) m_layerLists
1008
                                .get(Layer3DProps.layer3DImage);
1009

    
1010
                // if there are not one layer return
1011
                if (imageLayers.size() == 0)
1012
                        return;
1013
                FLayer layer = (FLayer) imageLayers.get(order);
1014
                if ((layer == null) || (!layer.isVisible()))
1015
                        return;
1016

    
1017
                Layer3DProps props3D = getLayer3DProps(layer);
1018
                // get/create cache service
1019
                FLayerCacheService cacheService = (FLayerCacheService) props3D
1020
                                .getCacheService();
1021
                if (cacheService == null) {
1022
                        cacheService = new FLayerCacheService(m_planet, props3D
1023
                                        .getCacheName(), layer, m_viewProjection);
1024
                        cacheService.setCacheRootDir(Layer3DProps.m_cacheDir);
1025
                        props3D.setCacheService(cacheService);
1026
                }
1027

    
1028
                int dataType = props3D.getType();
1029
                Point tileIndices = new Point(evt.getX(), evt.getY());
1030
                TileNum tileNum = new TileNum(evt.getLevel(), tileIndices);
1031

    
1032
                String tileFileName;
1033

    
1034
                if (cacheService.intersectsLayer(tileNum)) { // extent test
1035
                        try {
1036
                                tileFileName = cacheService.getTileAsFName(tileNum);
1037
                        } catch (Exception e) {
1038
                                return;
1039
                        }
1040

    
1041
                        if (dataType == Layer3DProps.layer3DImage) {
1042
                                // float opacity = 1.0f;
1043
                                String fileExtension = "png";
1044
                                // @TODO:aplicar texturas al planeta
1045
                                // evt.getTilePagedLod().setTexture(tileFileName, fileExtension,
1046
                                // order);
1047
                                m_planet.setTexture(evt.getTilePagedLod(), tileFileName, order);
1048
                                m_planet.setTextureOpacityLayer(order, props3D.getOpacity());
1049
                        }
1050
                        /*
1051
                         * else { String fileExtension = "tif";
1052
                         * evt.getTilePagedLod().setHeightField(tileFileName,
1053
                         * fileExtension); }
1054
                         */
1055
                } else { // no intersection
1056
                        if (dataType == Layer3DProps.layer3DImage) {
1057
                                m_planet.setTexture(evt.getTilePagedLod(), "", order);
1058
                                // evt.getTilePagedLod().setTexture("", "", order);
1059
                        }
1060
                }
1061

    
1062
                // REPAINTING VIEWWER
1063
                if (m_canvas3d != null)
1064
                        m_canvas3d.repaint();
1065
        }
1066

    
1067
        private void PrintDebugLayers() {
1068
                System.out.println("===========================");
1069
                for (int iList = 0; iList < 3; iList++) {
1070
                        ArrayList layerList = (ArrayList) m_layerLists.get(iList);
1071
                        System.out.println("===== List " + iList + "=====");
1072
                        for (int iLayer = 0; iLayer < layerList.size(); iLayer++) {
1073
                                FLayer layer = (FLayer) layerList.get(iLayer);
1074
                                System.out.println("  Layer " + layer.getName());
1075
                                Layer3DProps props3D = getLayer3DProps(layer);
1076
                                System.out.println("    Type " + props3D.getType());
1077
                                System.out.println("    TOC Order " + props3D.getTocOrder());
1078
                                System.out.println("    Planet Order "
1079
                                                + props3D.getPlanetOrder());
1080
                        }
1081
                }
1082
        }
1083

    
1084
        /**
1085
         * Crea un nuevo MapContext(3D) a partir del XMLEntity.
1086
         * 
1087
         * @param xml
1088
         *            XMLEntity
1089
         * 
1090
         * @return Nuevo MapContext3D.
1091
         * 
1092
         * @throws XMLException
1093
         */
1094
        public static MapContext createFromXML(XMLEntity xml) throws XMLException {
1095
                ViewPort3D vp = (ViewPort3D) ViewPort3D.createFromXML(xml.getChild(0));
1096

    
1097
                FLayers layers = new FLayers3D(null, null, vp);
1098
                layers.setXMLEntity(xml.getChild(1));
1099

    
1100
                MapContext fmap = layers.getMapContext();
1101

    
1102
                return fmap;
1103
        }
1104

    
1105
        public static MapContext createFromXML03(XMLEntity xml) throws XMLException {
1106
                ViewPort vp = ViewPort.createFromXML03(xml.getChild(0));
1107

    
1108
                FLayers layers = new FLayers3D(null, null, vp);
1109
                layers.setXMLEntity03(xml.getChild(1));
1110

    
1111
                MapContext fmap = layers.getMapContext();
1112

    
1113
                return fmap;
1114
        }
1115

    
1116
        public GraphicLayer getGraphicsLayer() {
1117
                GraphicLayer3D gra3D = new GraphicLayer3D(this.planetViewer, getPlanet());
1118
                return gra3D;
1119
        }
1120

    
1121
        public Node getSpecialNode() {
1122
                return planetViewer.getSpecialNode(0);
1123
        }
1124

    
1125
        public ViewPort getViewPort() {
1126

    
1127

    
1128
                ViewPort3D vp = (ViewPort3D) super.getViewPort();
1129

    
1130

    
1131
                if (m_canvas3d != null) 
1132
                        vp.setImageSize(new Dimension(planetViewer.getWidth(), planetViewer
1133
                                        .getHeight()));
1134
                vp.setPlanet(this.getPlanet());
1135
                vp.setViewer(this.m_canvas3d);
1136

    
1137
                return vp;
1138
        }
1139

    
1140
        /**
1141
         * M?todo de conveniencia que se usa provisionalmente para solicitar un
1142
         * refresco de todo lo que dependa del FMap (MapContext). Esto provocar? un
1143
         * evento de cambio de orden de capas que obligar? a redibujar todo lo que
1144
         * depende de FMap (TOC, MapControl, FFrameView, etc).
1145
         */
1146
        public void invalidate() {
1147
                ViewPort3D vp = (ViewPort3D) super.getViewPort();
1148
                if (vp.getDirty()) {
1149
                        vp.setDirty(false);
1150
                        // extentAux = vport.getExtent();
1151
                        this.zoomToExtent(vp.getExtent());
1152
                        // System.out.println("extend seleccionado: \n Centro: "
1153
                        // + extentAux.getCenterX() + "\n Alto: " + extentAux.getHeight()
1154
                        // + "\n Ancho: " + extentAux.getWidth());
1155
                }
1156
                // super.invalidate();
1157

    
1158
                m_canvas3d.repaint();
1159
        }
1160
}