PageSourceSearch

https://agsattrack.com/js/classes/views/3dview.js

js agsattrack.com collected 2026-09-25 22:31:11 UTC 58,826 bytes, 1,501 lines download raw bytes

1/*
2Copyright 2013 Alex Greenland
3
4   Licensed under the Apache License, Version 2.0 (the "License");
5   you may not use this file except in compliance with the License.
6   You may obtain a copy of the License at
7
8       http://www.apache.org/licenses/LICENSE-2.0
9
10   Unless required by applicable law or agreed to in writing, software
11   distributed under the License is distributed on an "AS IS" BASIS,
12   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   See the License for the specific language governing permissions and
14   limitations under the License.
15 */
16
17/* Options for JS Lint http://www.jslint.com/
18* 
19* Last Checked: 09/03/2014
20* 
21*/
22/*jslint white: true, nomen: true */
23/*global document, jQuery, AGSatTrack, AGSETTINGS, AGIMAGES, AGUTIL, AGVIEWS, AGWINDOWMANAGER, AGOBSERVER, Cesium, console */
24
25var AG3DVIEW = function(element) {
26    'use strict';
27
28    var ellipsoid =null;
29    var canvas = null;
30    var scene = null;
31    var cb = null;
32    var observerBillboards = null;
33    var _cityBillboards = null;
34    var _cityLabels = null;
35    var _observerLabels = null;
36    var _observerCircles = null;
37    var _render = false;
38    var satBillboards = null;
39    var planetsBillboards = null;
40    var _satNameLabels = null;
41    var orbitLines = null;
42    var selectedLines = null;
43    var passLines = null;
44    var footprintCircle = null;
45    var clock = null;
46    var _follow = false;
47    var _followFromObserver = false;
48    var _showview = false;
49    var TILE_PROVIDERS = null;
50    var _skyAtmosphere;
51    var _skybox;
52    var _fps = null;
53    var _labels = null;
54    var _mousePosLabel = null;
55    var _showMousePos = false;
56    var _element;
57    var _showSatLabels = true;
58    var _singleSat;
59    var _mode;
60    var _settings = AGSETTINGS.getViewSettings('threed');
61    var _currentProvider = 'staticimage';
62    var _showBlackMarble = false;
63    var _blackMarble = null;
64    var _blackMarbleOpacity = 2;
65    var _blackMarbleBrightness = 2;
66    
67    var _homeLocationCircle = null;
68    var _mutualLocationCircle = null;
69    
70    var _footprintPolygons = [];
71                
72    var satImages;
73                    
74    if (typeof element === 'undefined') {
75        _element = '3d';    
76    } else {
77        _element = element;
78    }
79        
80    /*
81    jQuery(window).resize(function() {
82        if (canvas === null) {
83            return;
84        }
85        var height = jQuery('.layout-panel-center').innerHeight();
86        var width = jQuery('.layout-panel-center').innerWidth();
87
88        if (canvas.width === width && canvas.height === height) {
89            return;
90        }
91
92        canvas.width = width;
93        canvas.height = height;
94
95        scene.camera.frustum.aspectRatio = width / height;
96    });
97      */
98    function resize(width, height) {
99        if (typeof width === 'undefined' || typeof height === 'undefined') {
100            var parent = jQuery('#'+_element);
101            width = parent.width();
102            height = parent.height();
103        }
104
105        if (width !== 0 && height !== 0) {
106            canvas.width = width;
107            canvas.height = height;
108
109            scene.camera.frustum.aspectRatio = width / height;
110        }          
111    }
112
113    jQuery(document).bind('agsattrack.show3dlocationinfo',
114            function(e) {
115                if (_render) {
116                    showLocationWindow();
117                }
118            }); 
119            
120    jQuery(document).bind('agsattrack.settingssaved',
121            function(e, observer) {
122                if (AGSETTINGS.getHaveWebGL()) {
123                    _settings = AGSETTINGS.getViewSettings('threed');
124                    TILE_PROVIDERS.staticimage.provider =  new Cesium.SingleTileImageryProvider({
125                        url : 'images/maps/' + _settings.staticimage
126                    });
127                    if (_currentProvider === 'staticimage') {
128                        setProvider(_currentProvider);
129                    }
130                    setupSatelliteImages();
131                    createSatellites();
132                    plotObservers();
133                    setTerrainProvider(_settings.useTerrainProvider);
134                    if (AGSETTINGS.getViewSettings('threed').showCities) {
135                        jQuery('#3d-show-cities').setState(true);
136                        plotCities();
137                    } else {
138                        jQuery('#3d-show-cities').setState(false);
139                        clearCities();
140                    }                    
141                }
142            }); 
143       
144       
145
146    jQuery(document).bind('agsattrack.locationAvailable',
147            function(e, observer) {
148                if (AGSETTINGS.getHaveWebGL()) {
149                    plotObservers();
150                    plotMutualCircles();
151                }
152            }); 
153                            
154    jQuery(document).bind('agsattrack.locationUpdated',
155            function(e, observer) {
156                if (AGSETTINGS.getHaveWebGL()) {
157                    plotObservers();
158                    plotMutualCircles();
159                }
160            });    
161
162    jQuery(document).bind('agsattrack.resetview',
163            function(e, observer) {
164                if (_render) {
165                    if (AGSETTINGS.getHaveWebGL()) {
166                        _followFromObserver = false;
167                        _follow = false;
168                        AGSatTrack.getTles().resetAll();
169                        plotObservers();
170                        plotMutualCircles();
171                        updateSatellites();
172                    }
173                }
174            }); 
175
176
177
178    jQuery(document).bind('agsattrack.blackmarbleopacity',
179            function(e, state) {
180                if (AGSETTINGS.getHaveWebGL()) {
181                    _blackMarbleOpacity = parseInt(state.value,10);
182                    setBlackMarbleOpacity();
183                }
184            }); 
185                
186     jQuery(document).bind('agsattrack.blackmarblebrightness',
187            function(e, state) {
188                if (AGSETTINGS.getHaveWebGL()) {
189                    _blackMarbleBrightness = parseInt(state.value,10);
190                    setBlackMarbleBrightness();
191                }
192            });               
193                
194                        
195    jQuery(document).bind('agsattrack.showblackmarble',
196            function(e, state) {
197                if (AGSETTINGS.getHaveWebGL()) {
198                    _showBlackMarble = state;
199                    setProvider(_currentProvider);
200                }
201            }); 
202                            
203    jQuery(document).bind('agsattrack.showsatlabels',
204            function(e, state) {
205                if (AGSETTINGS.getHaveWebGL()) {
206                    _showSatLabels = state;
207                    createSatelliteLabels();
208                }
209            });    
210
211    jQuery(document).bind('agsattrack.setfootprinttype',
212            function(e, state) {
213                if (AGSETTINGS.getHaveWebGL()) {
214                    _settings.fillFootprints = state;
215                    drawFootprint();
216                }
217            });  
218
219    jQuery(document).bind('agsattrack.setssp',
220            function(e, state) {
221                if (AGSETTINGS.getHaveWebGL()) {
222                    _settings.showGroundSSP = state;
223                    setupOrbit();
224                }
225            });                 
226
227    jQuery(document).bind('agsattrack.showmutuallocations',
228            function(e, state) {
229                if (AGSETTINGS.getHaveWebGL()) {
230                    AGSETTINGS.setMutualObserverEnabled(state);
231                    plotMutualCircles();
232                }
233            });
234                
235
236    jQuery(document).bind('agsattrack.followsatelliteview',
237            function(e, follow) {
238                if (AGSETTINGS.getHaveWebGL()) {
239                    _showview = follow;
240                    if (_render) {
241                        plotObservers();
242                        updateSatellites();
243                    }                    
244                }
245            });
246                
247    jQuery(document).bind('agsattrack.followsatellite',
248            function(e, follow) {
249                if (AGSETTINGS.getHaveWebGL()) {
250                    _follow = follow;
251                    if (_render) {
252                        plotObservers();
253                        updateSatellites();
254                    }                    
255                }
256            });
257    
258    jQuery(document).bind('agsattrack.followsatelliteobs',
259            function(e, follow) {
260                if (AGSETTINGS.getHaveWebGL()) {
261                    _followFromObserver = follow;
262                    if (_render) {
263                        plotObservers();
264                        updateSatellites();
265                    }                    
266                }
267            });    
268
269    jQuery(document).bind('agsattrack.showatmosphere',
270            function(e, state) {
271                if (AGSETTINGS.getHaveWebGL()) {
272                    if (state) {
273                        scene.skyAtmosphere = _skyAtmosphere;    
274                    } else {
275                        scene.skyAtmosphere = undefined;    
276                    }
277                }
278            });
279
280    jQuery(document).bind('agsattrack.showskybox',
281            function(e, state) {
282                if (AGSETTINGS.getHaveWebGL()) {
283                    if (state) {
284                        scene.skyBox = _skybox;
285                    } else {
286                        scene.skyBox = undefined;                           
287                    }
288                }
289            });
290            
291    jQuery(document).bind('agsattrack.showfps',
292            function(e, state) {
293                if (AGSETTINGS.getHaveWebGL()) {
294                    if (state) {
295                    //    _fps = new Cesium.PerformanceDisplay();                         
296                   //     scene.primitives.add(_fps);    
297                        scene.debugShowFramesPerSecond = true;
298                    } else {
299//                        scene.primitives.remove(_fps);                               
300                        scene.debugShowFramesPerSecond = false;
301                    }
302                }
303            });            
304                
305    jQuery(document).bind('agsattrack.showmousepos',
306            function(e, state) {
307                if (AGSETTINGS.getHaveWebGL()) {
308                    _showMousePos = state;
309                }
310            }); 
311                
312    /**
313     * Listen for any changes in the tile provider.
314     */
315    jQuery(document).bind(
316            'agsattrack.changetile',
317            function(event, provider) {
318                if (AGSETTINGS.getHaveWebGL()) {
319                    if (scene.mode !== Cesium.SceneMode.MORPHING) {
320                        setProvider(provider);
321                    }
322                }
323            });
324
325    jQuery(document).bind('agsattrack.satsselectedcomplete', function() {
326        if (_render && _mode !== AGVIEWS.modes.SINGLE) {
327            if (AGSETTINGS.getHaveWebGL()) {        
328                createSatellites();
329                plotMutualCircles();
330            }
331        }
332    });
333
334    jQuery(document).bind('agsattrack.updatesatdata',
335            function(event, selected) {
336                if (_render) {
337                    if (AGSETTINGS.getHaveWebGL()) { 
338                        updateSatellites();
339                    }
340                }
341            });
342
343    /**
344     * Listen for requests to change the view.
345     */
346    jQuery(document).bind('agsattrack.change3dview', function(event, view) {      
347        if (AGSETTINGS.getHaveWebGL()) {
348            setView(view);
349        }
350    });
351
352    jQuery(document).bind('agsattrack.showterrain', function(event, state) {
353        if (AGSETTINGS.getHaveWebGL()) {
354            setTerrainProvider(state);
355        }
356    });    
357
358    jQuery(document).bind('agsattrack.showcities', function(event, state) {
359        if (AGSETTINGS.getHaveWebGL()) {
360            if (state) {
361                plotCities();    
362            } else {
363                clearCities();
364            }
365        }
366    });  
367        
368    function showLocationWindow() {
369        AGWINDOWMANAGER.showWindow('dx');     
370    }
371    
372    function setView(view) {   
373        if (scene.mode !== Cesium.SceneMode.MORPHING) {
374            switch (view) {
375            case 'twod':
376                scene.morphTo2D();
377                jQuery('#3d-projection').setTitle('Views', '<br /> 2d view' );
378                setButtonsState(false);
379                break;
380            case 'twopointfived':
381                scene.morphToColumbusView();
382                jQuery('#3d-projection').setTitle('Views', '<br /> 2.5d view' ); 
383                setButtonsState(false);
384                break;
385            case 'threed':
386                scene.morphTo3D();
387                jQuery('#3d-projection').setTitle('Views', '<br /> 3d view' );                     
388                setButtonsState(true);
389                break;
390            }
391        }
392    }
393    
394    function setButtonsState(state) {
395        if (state) {
396            jQuery('#3d-sat-finder').combo('enable');
397            jQuery('#3d-follow-obs').enable();
398            jQuery('#3d-follow-sat').enable();
399            jQuery('#3d-skybox').enable();
400            jQuery('#3d-atmosphere').enable();
401        } else {
402            jQuery('#3d-sat-finder').combo('disable');
403            jQuery('#3d-follow-obs').disable();
404            jQuery('#3d-follow-sat').disable();
405            jQuery('#3d-skybox').disable();
406            jQuery('#3d-atmosphere').disable();
407        }
408    }
409    
410    function setProvider(provider) {
411        if (typeof TILE_PROVIDERS[provider] !== 'undefined') {
412            cb.imageryLayers.removeAll();
413            cb.imageryLayers.addImageryProvider(TILE_PROVIDERS[provider].provider);
414            jQuery('#3d-provider').setTitle('Provider', '<br />' + TILE_PROVIDERS[provider].toolbarTitle );
415            _currentProvider = provider;        
416        }
417        
418        if (_showBlackMarble) {
419            _blackMarble = cb.imageryLayers.addImageryProvider(new Cesium.TileMapServiceImageryProvider({
420                url : '//cesiumjs.org/tilesets/imagery/blackmarble',
421                maximumLevel : 8,
422                credit : 'Black Marble imagery courtesy NASA Earth Observatory'
423            }));
424            _blackMarble.alpha = _blackMarbleOpacity / 10; // 0.0 is transparent.  1.0 is opaque.
425            _blackMarble.brightness = _blackMarbleBrightness;
426        }
427    } 
428    
429    function setBlackMarbleOpacity() {
430        if (_blackMarble !== null) {
431            _blackMarble.alpha = _blackMarbleOpacity / 10;
432        }
433    }
434
435    function setBlackMarbleBrightness() {
436        if (_blackMarble !== null) {        
437            _blackMarble.brightness = _blackMarbleBrightness;
438        }
439    }
440                        
441    function clearCities() {
442        _cityBillboards.removeAll();    
443        _cityLabels.removeAll();    
444    }
445    
446    function plotCities() {
447        AGDATAMANAGER.getData('locations', function(data){
448            clearCities();
449            var populationLimit = AGSETTINGS.getViewSettings('threed').cityPopulation;
450            var label;            
451            for ( var i = 0; i < data.length; i++) {
452                if (data[i].pop >= populationLimit) {
453                    _cityBillboards.add({
454                        position : ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(data[i].lon, data[i].lat)),
455                        image : AGIMAGES.getImage('citybullet')                                         
456                    });
457                    
458                    label = _cityLabels.add({
459                        position  : ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(data[i].lon, data[i].lat)),
460                        text      : '   ' + data[i].shortname + ' (' + data[i].prefix + ')',
461                        font      : AGSETTINGS.getViewSettings('threed').cityFontSize + 'px Arial',
462                        fillColor : Cesium.Color.fromCssColorString('#'+AGSETTINGS.getViewSettings('threed').cityLabelColour)
463                    }); 
464                    label.translucencyByDistance = new Cesium.NearFarScalar(20.5e2, 1.0, 30.0e6, 0.0);
465                }
466            }              
467        }, false);        
468    }
469     
470    /**
471     * Plot the observers.
472     */
473    function plotObservers() {
474        var observers = null;
475        var observer = null;
476        observerBillboards.removeAll();
477        _observerLabels.removeAll();       
478        observers = AGSatTrack.getObservers();
479        for ( var i = 0; i < observers.length; i++) {
480            observer = observers[i];
481            if (observer.isReady() && observer.getEnabled()) { 
482                observerBillboards.add({
483                    position : ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(observer.getLon(), observer.getLat())),
484                    image : AGIMAGES.getImage('home')                                          
485                });
486                
487                _observerLabels.add({
488                    position  : ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(observer.getLon(), observer.getLat())),
489                    text      : '   ' + observer.getName(),
490                    font      : '12px Helvetica',
491                    fillColor : { red : 0.0, blue : 0.0, green : 0.0, alph
491a : 1.0 }
492                });                
493            }
494        }
495        
496        observer = AGSatTrack.getObserver(AGOBSERVER.types.HOME);
497        if (typeof observer !== 'undefined') {
498            if (observer.isReady()) {
499                var target = ellipsoid
500                        .cartographicToCartesian(Cesium.Cartographic
501                                .fromDegrees(observer.getLon(), observer
502                                        .getLat()));
503                var eye = ellipsoid
504                        .cartographicToCartesian(Cesium.Cartographic
505                                .fromDegrees(observer.getLon(), observer
506                                        .getLat(), 1e7));
507                var up = new Cesium.Cartesian3(0, 0, 1);
508                scene.camera.lookAt(eye, target, up);
509            }
510        }
511
512    }
513
514    function plotMutualCircles() {
515        var observer;
516        _settings.fillMutual = true;
517        var primitives = scene.primitives;        
518        _observerCircles.removeAll();
519        if (_homeLocationCircle !==  null) {
520            primitives.remove(_homeLocationCircle);
521        }
522        if (_mutualLocationCircle !== null) {
523            primitives.remove(_mutualLocationCircle);
524        }
525        if (AGSETTINGS.getMutualObserverEnabled()) {
526            var following = AGSatTrack.getFollowing();
527            if (following !== null) {                
528                if (_settings.fillMutual) {
529                    observer = AGSatTrack.getObserver(AGOBSERVER.types.HOME);            
530                    _homeLocationCircle = new Cesium.Polygon();
531
532                    _homeLocationCircle.material.uniforms.color = {
533                      red   : 0.0,
534                      green : 0.0,
535                      blue  : 0.0,
536                      alpha : 0.3
537                    };       
538                    _homeLocationCircle.setPositions(
539                            Cesium.Shapes.computeCircleBoundary(
540                                    ellipsoid,
541                                    ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(observer.getLon(), observer.getLat())),
542                                    following.get('footprint') * 500));
543                    primitives.add(_homeLocationCircle);
544                    primitives.lowerToBottom(_homeLocationCircle);
545                       
546                       
547                       
548                    observer = AGSatTrack.getObserver(AGOBSERVER.types.MUTUAL);            
549                    _mutualLocationCircle = new Cesium.Polygon();
550
551                    _mutualLocationCircle.material.uniforms.color = {
552                      red   : 0.0,
553                      green : 0.0,
554                      blue  : 0.0,
555                      alpha : 0.3
556                    };       
557                    _mutualLocationCircle.setPositions(
558                            Cesium.Shapes.computeCircleBoundary(
559                                    ellipsoid,
560                                    ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(observer.getLon(), observer.getLat())),
561                                    following.get('footprint') * 500));
562                    primitives.add(_mutualLocationCircle);
563                    primitives.lowerToBottom(_mutualLocationCircle);                    
564
565                } else {
566                    var footPrint = _observerCircles.add();   
567                    observer = AGSatTrack.getObserver(AGOBSERVER.types.HOME);            
568                    footPrint.setPositions(Cesium.Shapes.computeCircleBoundary(ellipsoid, ellipsoid
569                            .cartographicToCartesian(new Cesium.Cartographic.fromDegrees(
570                                    observer.getLon(), observer.getLat())),
571                            following.get('footprint') * 500));
572                            
573                    footPrint = _observerCircles.add();   
574                    observer = AGSatTrack.getObserver(AGOBSERVER.types.MUTUAL);            
575                    footPrint.setPositions(Cesium.Shapes.computeCircleBoundary(ellipsoid, ellipsoid
576                            .cartographicToCartesian(new Cesium.Cartographic.fromDegrees(
577                                    observer.getLon(), observer.getLat())),
578                            following.get('footprint') * 500));                      
579                }
580            }  
581        }     
582    }
583    
584    /**
585     * Render the scene.
586     * 
587     * There is a NASTY hack in here to stop Cesium messing up when tabs are
588     * switched
589     */
590    var _debugCounter = 0;     
591    function renderScene() {
592        
593        (function tick() {
594            if (_render) {
595                if (AGSETTINGS.getDebugLevel() > 0) {                
596                    _debugCounter++;
597                    if (_debugCounter > 100) {
598                        _debugCounter = 0;
599                        //console.log('3d Animate');
600                    }
601                }                 
602                scene.initializeFrame();
603                scene.render();
604                Cesium.requestAnimationFrame(tick);
605            }
606        }());
607        
608    }
609    
610    function createSatelliteLabels() {
611        var satellites = AGSatTrack.getSatellites();
612        var cpos = 0;
613        var labelVisible = true;
614        var now = new Cesium.JulianDate();
615                
616        var okToCreate = false;
617        
618        if (_mode !== AGVIEWS.modes.SINGLE) {
619            satellites = AGSatTrack.getSatellites();
620            okToCreate = true;
621        } else {
622            if (_singleSat !== null) {
623                okToCreate = true;
624                satellites = [_singleSat];
625            }    
626        }
627        
628     //   _satNameLabels.modelMatrix = Cesium.Matrix4.fromRotationTranslation(
629      //      Cesium.Transforms.computeTemeToPseudoFixedMatrix(now),
630     //       Cesium.Cartesian3.ZERO);
631                
632        _satNameLabels.removeAll();
633        if (okToCreate) {
634            for ( var i = 0; i < satellites.length; i++) {
635                if (satellites[i].isDisplaying()) {
636                    labelVisible = true;
637                    if (!_showSatLabels) {
638                        labelVisible = false;
639                        if (satellites[i].getSelected())  {
640                            labelVisible = true;    
641                        }
642                    }
643                    
644                    var lat = satellites[i].get('latitude');
645                    var lon = satellites[i].get('longitude');
646                    var alt = satellites[i].get('altitude');
647                    
648                    if (lat === undefined) {
649                        lat = 0;
650                        lon = 0;
651                        alt = 0;
652                    }
653                    cpos = new Cesium.Cartesian3(satellites[i].get('x'), satellites[i].get('y'), satellites[i].get('z'));
654                    cpos = Cesium.Cartesian3.multiplyByScalar(cpos, 1000, cpos);               
655                    cpos = Cesium.Cartesian3.multiplyByScalar(cpos, 30/1000+1, cpos); 
656                    cpos = Cesium.Cartesian3.fromDegrees(lon, lat, alt*1000);
657                    cpos = Cesium.Cartesian3.multiplyByScalar(cpos, 30/1000+1, cpos); 
658
659                                
660                    var satLabel = _satNameLabels.add({
661                      show : labelVisible,
662                      position : cpos,
663                      text : satellites[i].getName(),
664                      font : _settings.unselectedLabelSize + 'px sans-serif',
665                      fillColor : Cesium.Color.fromCssColorString('#'+_settings.unselectedLabelColour),
666                      outlineColor : _settings.unselectedLabelColour,
667                      style : Cesium.LabelStyle.FILL,
668                      scale : 1.0,
669                      translucencyByDistance: new Cesium.NearFarScalar(15.5e2, 1.0, 40.0e6, 0.0)
670                    });
671
672                    if (satellites[i].getSelected()) {
673                        satLabel.font = _settings.selectedLabelSize + 'px sans-serif';
674                        satLabel.fillColor = Cesium.Color.fromCssColorString('#'+_settings.selectedLabelColour);
675                    } else {
676                        satLabel.font = _settings.unselectedLabelSize + 'px sans-serif';
677                        satLabel.fillColor = Cesium.Color.fromCssColorString('#'+_settings.unselectedLabelColour);
678                    }
679                    satLabel.satelliteindex = i;
680                }
681            }
682        } 
683    }
684    
685    function setupSatelliteImages() {
686        var satUnselected = 'satellite' + _settings.unselectedIcon + _settings.unselectedIconSize;
687        var satSelected = 'satellite' + _settings.selectedIcon + _settings.selectedIconSize;
688
689        var satUnselectedGrey = 'satellitegrey' + _settings.unselectedIcon + _settings.unselectedIconSize;
690        var satSelectedGrey = 'satellitegrey' + _settings.selectedIcon + _settings.selectedIconSize;
691                    
692        satImages = [
693            AGIMAGES.getImage(satUnselected),
694            AGIMAGES.getImage(satSelected),
695            AGIMAGES.getImage('iss16'),
696            AGIMAGES.getImage('iss32'),
697            AGIMAGES.getImage(satUnselectedGrey),
698            AGIMAGES.getImage(satSelectedGrey)
699        ];        
700    }    
701    
702    function createSatellites() {
703        var billboard;
704        var now = new Cesium.JulianDate();
705        var cpos = 0;
706        var satellites;
707        var okToCreate = false;
708        
709        if (_mode !== AGVIEWS.modes.SINGLE) {
710            satellites = AGSatTrack.getSatellites();
711            okToCreate = true;
712        } else {
713            if (_singleSat !== null) {
714                okToCreate = true;
715                satellites = [_singleSat];
716            }    
717        }
718
719        var satdata = [];
720        for ( var i = 0; i < satellites.length; i++) {
721            var satObject = {
722                value : satellites[i].getCatalogNumber(),
723                text : satellites[i].getName()
724            };
725            satdata.push(satObject);
726        }            
727        jQuery('#3d-sat-finder').combobox('loadData',satdata );
728                
729        satBillboards.removeAll();
730
731        if (okToCreate) {
732     //       satBillboards.modelMatrix = Cesium.Matrix4.fromRotationTranslation(
733     //               Cesium.Transforms.computeTemeToPseudoFixedMatrix(now),
734    //                Cesium.Cartesian3.ZERO);        
735
736            for (i = 0; i < satellites.length; i++) {
737                if (satellites[i].isDisplaying()) {
738                    cpos = new Cesium.Cartesian3(satellites[i].get('x'), satellites[i].get('y'), satellites[i].get('z'));              
739
740                    var lon = satellites[i].get('longitude');
741                    var lat = satellites[i].get('latitude');
742                    var alt = satellites[i].get('altitude');
743
744                    if (lon === undefined) {
745                        lon = 0;
746                        lat = 0;
747                        alt = 0;
748                    }
749                    cpos = Cesium.Cartesian3.fromDegrees(lon, lat, alt*1000);
750
751                    cpos = Cesium.Cartesian3.multiplyByScalar(cpos, 1000, cpos);               
752                    if (satellites[i].getCatalogNumber() === '25544') {
753                        billboard = satBillboards.add({
754                            image: satImages[2],
755                            position : cpos,
756                            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
757                            verticalOrigin: Cesium.VerticalOrigin.CENTER                                               
758                        });
759                    } else {
760                        billboard = satBillboards.add({
761                            image: satImages[0],
762                            position : cpos                   
763                        });                        
764                    }
765                    billboard.satelliteName = satellites[i].getName();
766                    billboard.satelliteCatalogId = satellites[i].getCatalogNumber();
767                    billboard.satelliteindex = i;
768                }
769            }
770            scene.primitives.add(satBillboards);
771        }
772        createSatelliteLabels();
773    }
774
775    function updateSatellites() {
776        var now = new Cesium.JulianDate();
777        var newpos, bb;
778        var following = AGSatTrack.getFollowing();
779        var target;
780        var up = new Cesium.Cartesian3();
781        var satellites;
782        var okToUpdate = false;
783        var eye;
784            
785        if (_mode !== AGVIEWS.modes.SINGLE) {
786            satellites = AGSatTrack.getSatellites();
787            okToUpdate = true;
788        } else {
789            if (_singleSat !== null) {
790                satellites = [_singleSat];    
791                okToUpdate = true;
792            }
793        }
794
795    //    satBillboards.modelMatrix = Cesium.Matrix4.fromRotationTranslation(
796    //        Cesium.Transforms.computeTemeToPseudoFixedMatrix(now),
797   //         Cesium.Cartesian3.ZERO);
798    //    _satNameLabels.modelMatrix = Cesium.Matrix4.fromRotationTranslation(
799    //        Cesium.Transforms.computeTemeToPseudoFixedMatrix(now),
800    //        Cesium.Cartesian3.ZERO);        
801        for ( var i = 0; i < satBillboards.length; i++) {
802
803            bb = satBillboards.get(i);
804     
805            var offset = 4;
806            var visibility = satellites[bb.satelliteindex].get('visibility');
807            if ( visibility === 'Daylight' || visibility === 'Visible') {
808                offset = 0;
809            }
810
811            if (satellites[bb.satelliteindex].getSelected()) {
812                if (satellites[i].getCatalogNumber() === '25544') {
813                    bb.image = satImages[3];    
814                } else {
815                    bb.image = satImages[1 + offset];    
816                }
817            } else {
818                if (satellites[i].getCatalogNumber() === '25544') {
819                    bb.image = satImages[2];    
820                } else {
821                    bb.image = satImages[0 + offset];;    
822                }   
823            }
824                        
825    //        newpos = new Cesium.Cartesian3(satellites[bb.satelliteindex].get('x'), satellites[bb.satelliteindex].get('y'), satellites[bb.satelliteindex].get('z'));
826
827            newpos = Cesium.Cartesian3.fromDegrees(satellites[bb.satelliteindex].get('longitude'), satellites[bb.satelliteindex].get('latitude'), satellites[bb.satelliteindex].get('altitude')*1000);
828
829          //  newpos = Cesium.Cartesian3.multiplyByScalar(newpos, 1000, newpos);
830            
831
832            
833            bb.position = newpos;
834           
835            newpos = Cesium.Cartesian3.multiplyByScalar(newpos, 30/1000+1, newpos);            
836      
837            var satLabel = _satNameLabels.get(i);
838            if (satellites[bb.satelliteindex].getSelected()) {
839                satLabel.font = _settings.selectedLabelSize + 'px sans-serif';
840                satLabel.fillColor = Cesium.Color.fromCssColorString('#'+_settings.selectedLabelColour);
841            } else {
842                satLabel.font = _settings.unselectedLabelSize + 'px sans-serif';
843                satLabel.fillColor = Cesium.Color.fromCssColorString('#'+_settings.unselectedLabelColour);
844            }
845            satLabel.position = newpos; 
846
847        }
848        
849        if (following !== null && (_follow || _followFromObserver || _showview)) {
850            var observer = AGSatTrack.getObserver(AGOBSERVER.types.HOME);
851
852            if (_showview) {
853                target = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(following.get('longitude'), following.get('latitude'), 0));   
854                eye = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(following.get('longitude'), following.get('latitude'), (following.get('altitude')*1000)));
855                up = Cesium.Cartesian3.normalize(eye, up);              
856            } else {
857                if (_followFromObserver) {
858                    var height = AGSETTINGS.getViewSettings('threed').followHeightObs;
859                    if (height === undefined) {
860                        height = 50;
861                    }
862                    eye = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(observer.getLon(), observer.getLat(), 100));
863                    target = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(following.get('longitude'), following.get('latitude'), (following.get('altitude')*1000)+parseInt(height,10)));
864                    up = Cesium.Cartesian3.normalize(eye, up);                                
865                } else {
866                    var height = AGSETTINGS.getViewSettings('threed').followHeight;
867                    if (height === undefined) {
868                        height = 50;
869                    }
870                    target = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(observer.getLon(), observer.getLat(), 100));
871                    eye = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(following.get('longitude'), following.get('latitude'), (following.get('altitude')*1000)+parseInt(height,10)));
872                    up = Cesium.Cartesian3.normalize(eye, up);
873                }
874            }
875            scene.camera.lookAt(eye, target, up);                                      
876        }
877                
878        setupOrbit();
879    }
880
881    function drawFootprint() {
882        var circle;
883        var color = Cesium.Color.WHITE;;
884        var footPrint;
885        var i;
886
887        var primitives = scene.primitives;
888        for (i=0;i<_footprintPolygons.length;i++) {
889            primitives.remove(_footprintPolygons[i]);  
890        }
891        footprintCircle.removeAll();
892        var selected = AGSatTrack.getTles().getSelected();
893        for (i = 0; i < selected.length; i++) {
894            if (_settings.fillFootprints) {
895
896
897                if (selected[i].get('elevation') >= AGSETTINGS.getAosEl()) {
898                    color = new Cesium.Color({
899                      red   : 0.0,
900                      green : 0.5,
901                      blue  : 0.0,
902                      alpha : 0.4
903                    });
904                } else {
905                    color = new Cesium.Color({
906                      red   : 0.5,
907                      green : 0.0,
908                      blue  : 0.0,
909                      alpha : 0.4
910                    });
911                }        
912                
913                var circleGeometry = new Cesium.CircleGeometry({
914                    center : Cesium.Cartesian3.fromDegrees(selected[i].get('longitude'), selected[i].get('latitude')),
915                    radius : selected[i].get('footprint') * 500,
916                    vertexFormat : Cesium.PerInstanceColorAppearance.VERTEX_FORMAT
917                });
918                var redCircleInstance = new Cesium.GeometryInstance({
919                    geometry : circleGeometry,
920                    attributes : {
921                        color : Cesium.ColorGeometryInstanceAttribute.fromColor(color)
922                    }
923                });
924                var circle = new Cesium.Primitive({
925                    geometryInstances: [redCircleInstance],
926                    appearance: new Cesium.PerInstanceColorAppearance({
927                        closed: true
928                    })
929                })
930                scene.primitives.add(circle);
931                _footprintPolygons.push(circle);                
932                primitives.add(circle);
933                primitives.lowerToBottom(circle);
934            } else {
935                footPrint = footprintCircle.add();
936                if (selected[i].get('elevation') >= AGSETTINGS.getAosEl()) {
937                    color = Cesium.Color.GREEN;
938                } else {
939                    color = Cesium.Color.RED;
940                }
941                
942
943                
944                var circleOutlineGeometry = new Cesium.CircleOutlineGeometry({
945                    center : Cesium.Cartesian3.fromDegrees(selected[i].get('longitude'), selected[i].get('latitude')),
946//                    center:  new Cesium.Cartesian3(selected[i].get('x'), selected[i].get('y'), selected[i].get('z')),
947                    radius : (selected[i].get('footprint') * 1000) / 2
948                });
949                var circleOutlineInstance = new Cesium.GeometryInstance({
950                    geometry : circleOutlineGeometry,
951                    attributes : {
952                        color : Cesium.ColorGeometryInstanceAttribute.fromColor(color)
953                    }
954                });
955       
956      // var now = new Cesium.JulianDate();         
957       // var mm = Cesium.Matrix4.fromRotationTranslation(
958        //        Cesium.Transforms.computeTemeToPseudoFixedMatrix(now),
959         //       Cesium.Cartesian3.ZERO);
960                                
961                circle = new Cesium.Primitive({
962                    geometryInstances : [circleOutlineInstance],
963                    appearance : new Cesium.PerInstanceColorAppearance({
964                        flat : true,
965                        renderState : {
966                            lineWidth : Math.min(3.0, scene.maximumAliasedLineWidth)
967                        }
968                    })//,
969                 //   modelMatrix: mm
970                })
971                scene.primitives.add(circle);
972                _footprintPolygons.push(circle);              
973            }
974
975        }
976
977    }
978
979    function satelliteClickDetails(scene) {
980        var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
981
982        handler.setInputAction(function(click) {
983            var pickedObject = scene.pick(click.position);
984            if (pickedObject) {
985                var selected = pickedObject.primitive.satelliteCatalogId;
986                jQuery(document).trigger('agsattrack.satclicked', {catalogNumber: selected});
987            }
988        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
989    }
990
991    function mouseMoveDetails(scene, ellipsoid) {
992        var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
993        handler.setInputAction(function(movement) {
994
995            ShowCameraPosition();
996            
997            if (_showMousePos) {
998                var cartesian = scene.camera.pickEllipsoid(movement.endPosition, ellipsoid);
999                if (cartesian && !isNaN(cartesian.x)) {
1000                    var cartographic = ellipsoid.cartesianToCartographic(cartesian);
1001                    _mousePosLabel.show = true;
1002                    var lon = Cesium.Math.toDegrees(cartographic.longitude).toFixed(2);
1003                    var lat = Cesium.Math.toDegrees(cartographic.latitude).toFixed(2);
1004
1005                    _mousePosLabel.text = '(' + AGUTIL.convertDecDegLon(lon, false) + ', ' + AGUTIL.convertDecDegLat(lat, false) + ')';
1006                    _mousePosLabel.position = cartesian;
1007                } else {
1008                    _mousePosLabel.text = '';
1009                }
1010            }
1011        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
1012        
1013        handler.setInputAction(function(movement) {
1014            ShowCameraPosition();
1015        }, Cesium.ScreenSpaceEventType.WHEEL);        
1016    }
1017    
1018    function ShowCameraPosition() {
1019        var cameraCartographic = ellipsoid.cartesianToCartographic(scene.camera.position);            
1020        var cameraAlt = cameraCartographic.height;                
1021        cameraAlt = (cameraAlt / 1000).toFixed(0);
1022        var cameraLon = Cesium.Math.toDegrees(cameraCartographic.longitude).toFixed(2);
1023        var cameraLat = Cesium.Math.toDegrees(cameraCartographic.latitude).toFixed(2);
1024        jQuery('#camera-pos').html('<strong>Lat:</strong>&nbsp;' + AGUTIL.convertDecDegLat(cameraLat, false) + '<br><strong>Lon:</strong>&nbsp;' + AGUTIL.convertDecDegLon(cameraLon, false) + '<br><strong>Alt:</strong>&nbsp;' + cameraAlt + 'Km');
1025    }
1026        
1027    function resetOrbit() {
1028        orbitLines.removeAll();
1029        passLines.removeAll();
1030        footprintCircle.removeAll();
1031    }
1032
1033    function setupOrbit() {
1034        resetOrbit();
1035        var selected = AGSatTrack.getTles().getSelected();
1036        for (var i=0; i< selected.length; i++) {
1037            addOrbitLine(selected[i]);    
1038        }
1039        drawFootprint();
1040    }
1041    
1042    function plotLine(cartPoints, colour, polylineCollection, width, showSsp) {
1043        var pos;
1044        var points = [];
1045        var selectedPoints = [];
1046        var lastPos;
1047        var now = new Cesium.JulianDate();
1048        var cartographic;
1049        var target;
1050        var _material = null;
1051        
1052    //    polylineCollection.modelMatrix = Cesium.Matrix4.fromRotationTranslation(
1053    //            Cesium.Transforms.computeTemeToPseudoFixedMatrix(now),
1054    //            Cesium.Cartesian3.ZERO);
1055      
1056
1057        lastPos = cartPoints[0];
1058        for ( var i = 0; i < cartPoints.length; i++) {
1059            if (checkOkToPlot(lastPos, cartPoints[i])) {
1060                pos = new Cesium.Cartesian3(cartPoints[i].x, cartPoints[i].y, cartPoints[i].z);
1061pos = Cesium.Cartesian3.fromDegrees(cartPoints[i].lon, cartPoints[i].lat, cartPoints[i].alt*1000);
1062
1063       //         pos = Cesium.Cartesian3.multiplyByScalar(pos, 1000, pos);
1064                points.push(pos);
1065                
1066                switch (colour) {
1067                    case 'red':
1068                        _material = Cesium.Material.fromType('Color');
1069                        _material.uniforms.color = {red : 1.0, green : 0.0, blue : 0.0, alpha : 1.0};                
1070                        break;
1071                    
1072                    case 'green':
1073                        _material = Cesium.Material.fromType('Color');
1074                        _material.uniforms.color = {red : 0.0, green : 1.0, blue : 0.0, alpha : 1.0};                          
1075                        break;
1076                }
1077                        
1078                /**
1079                * Add the lines from satelite point to ssp
1080                */
1081                if (showSsp && _settings.showGroundSSP) {
1082                    selectedPoints = [];
1083                    selectedPoints.push(pos);
1084                    cartographic = ellipsoid.cartesianToCartographic(pos);
1085                    target = ellipsoid.cartographicToCartesian(new Cesium.Cartographic(cartographic.longitude, cartographic.latitude, 0));                       selectedPoints.push(target);
1086                    polylineCollection.add({
1087                        positions : selectedPoints,
1088                        width : 1,
1089                        material : _material
1090                    });
1091                }
1092                
1093            }
1094            lastPos = cartPoints[i];
1095        } 
1096        
1097        switch (colour) {
1098            case 'red':
1099                _material = Cesium.Material.fromType('Color');
1100                _material.uniforms.color = {red : 1.0, green : 0.0, blue : 0.0, alpha : 1.0};                
1101                break;
1102            
1103            case 'green':
1104                _material = Cesium.Material.fromType('Color');
1105                _material.uniforms.color = {red : 0.0, green : 1.0, blue : 0.0, alpha : 1.0};                
1106                break;
1107        }
1108                        
1109        polylineCollection.add({
1110            positions : points,
1111            width : width,
1112            material : _material
1113        });
1114                                          
1115    }
1116    
1117    /**
1118    * Check a point is ok to plot, i.e. its more than 'range' units away from the last point
1119    */
1120    function checkOkToPlot(lastPos, pos) {
1121        var result = false;
1122        var range = 5;
1123        
1124        if (Math.abs(lastPos.x - pos.x) > range || Math.abs(lastPos.y - pos.y) > range || Math.abs(lastPos.z - pos.z) > range ) {
1125            result = true;
1126        }
1127        return result;  
1128    }
1129       
1130    function addOrbitLine(sat) {    
1131        var orbit = sat.getOrbitData();
1132        
1133        if (typeof orbit !== 'undefined' && typeof orbit.points[0] !== 'undefined') {
1134            if (sat.isGeostationary() && sat.get('elevation') > 0) {
1135                plotLine(orbit.points, 'green', passLines, 1, false);
1136            } else {
1137                var pass = sat.getNextPass();
1138                plotLine(orbit.points, 'red', passLines, 1, false);
1139                if (parseInt(sat.get('orbitnumber'),10) === parseInt(pass.orbitNumber,10)) {
1140                    plotLine(pass.pass, 'green', passLines, 2, true);
1141                }
1142            }
1143        }
1144        
1145        /*
1146        if (typeof (orbit[0]) !== 'undefined') {
1147
1148            var now = new Cesium.JulianDate();
1149            orbitLines.modelMatrix = Cesium.Matrix4.fromRotationTranslation(
1150                    Cesium.Transforms.computeTemeToPseudoFixedMatrix(now),
1151                    Cesium.Cartesian3.ZERO);
1152            passLines.modelMatrix = Cesium.Matrix4.fromRotationTranslation(
1153                    Cesium.Transforms.computeTemeToPseudoFixedMatrix(now),
1154                    Cesium.Cartesian3.ZERO);
1155                    
1156            var points = [];
1157            var pointsAOS = [];
1158            for ( var i = 0; i < orbit.length; i++) {
1159                pos = new Cesium.Cartesian3(orbit[i].x, orbit[i].y, orbit[i].z)
1160                pos = Cesium.Cartesian3.multiplyByScalar(pos, 1000);
1161                points.push(pos);
1162                
1163                if (orbit[i].el >= AGSETTINGS.getAosEl()) {
1164                    pos = new Cesium.Cartesian3(orbit[i].x, orbit[i].y, orbit[i].z)
1165                    pos = Cesium.Cartesian3.multiplyByScalar(pos, 1000);
1166                    pointsAOS.push(pos);
1167                    plottingAos = true;
1168                }
1169                
1170                if (plottingAos && orbit[i].el <= AGSETTINGS.getAosEl()) {
1171                    plottingAos = false;
1172                    passLines.add({
1173                        positions : pointsAOS,
1174                        width : 3,
1175                        color : Cesium.Color.GREEN
1176                    });
1177                    pointsAOS = [];
1178                }
1179                
1180                
1181            }
1182            
1183        //    var segments = Cesium.PolylinePipeline.wrapLongitude(ellipsoid, points);
1184        //    for (var i=0; i < segments.length; i++) {
1185
1186            if (plottingAos) {
1187                passLines.add({
1188                    positions : pointsAOS,
1189                    width : 3,
1190                    color : Cesium.Color.GREEN
1191                });
1192            }        
1193      
1194                orbitLines.add({
1195                    positions : points,
1196                    width : 1,
1197                    color : Cesium.Color.RED
1198                });
1199      
1200        //    }
1201
1202
1203        }
1204*/
1205    }
1206
1207    function disableInput(scene) {
1208        var controller = scene.screenSpaceCameraController;
1209        controller.enableTranslate = false;
1210        controller.enableZoom = false;
1211        controller.enableRotate = false;
1212        controller.enableTilt = false;
1213        controller.enableLook = false;
1214    }
1215
1216    function enableInput(scene) {
1217        var controller = scene.screenSpaceCameraController;
1218        controller.enableTranslate = true;
1219        controller.enableZoom = true;
1220        controller.enableRotate = true;
1221        controller.enableTilt = true;
1222        controller.enableLook = true;
1223    }
1224    
1225    function setTerrainProvider(useTerrainProvider) {
1226        var terrainProvider;
1227        
1228        //if (useTerrainProvider) {
1229        //    terrainProvider = new Cesium.CesiumTerrainProvider({
1230        //        url : '//assets.agi.com/stk-terrain/world',
1231        //        requestVertexNormals: true
1232        //    });
1233        //} else {
1234            terrainProvider = new Cesium.EllipsoidTerrainProvider({
1235                ellipsoid : Cesium.Ellipsoid.WGS84
1236            });    
1237       // }
1238
1239        var centralBody = scene.Globe;
1240        scene.terrainProvider = terrainProvider;
1241        jQuery('#3d-show-terrain').setButtonState(useTerrainProvider);
1242    }
1243               
1244    function init3DView() {
1245        
1246        setupSatelliteImages();
1247        
1248        ellipsoid = Cesium.Ellipsoid.WGS84;
1249        cb = new Cesium.Globe(ellipsoid);
1250        observerBillboards = new Cesium.BillboardCollection();
1251        satBillboards = new Cesium.BillboardCollection();
1252        planetsBillboards = new Cesium.BillboardCollection();
1253        orbitLines = new Cesium.PolylineCollection();
1254        selectedLines = new Cesium.PolylineCollection();
1255        passLines = new Cesium.PolylineCollection();
1256        footprintCircle = new Cesium.PolylineCollection();
1257        _observerCircles = new Cesium.PolylineCollection();
1258        clock = new Cesium.Clock();
1259        _satNameLabels = new Cesium.LabelCollection();
1260        _observerLabels = new Cesium.LabelCollection();
1261        _cityBillboards = new Cesium.BillboardCollection();
1262        _cityLabels = new Cesium.LabelCollection();
1263        
1264        var bingAPIKey = AGUTIL.getBingAPIKey();
1265
1266        TILE_PROVIDERS = {
1267            'bing' : {
1268                provider : new Cesium.BingMapsImageryProvider({
1269                    url : 'http://dev.virtualearth.net',
1270                    key : bingAPIKey,
1271                    mapStyle : Cesium.BingMapsStyle.AERIAL
1272                }),
1273                toolbarTitle : 'Bing Maps'                       
1274            },
1275            'staticimage' : { 
1276                provider : new Cesium.SingleTileImageryProvider({
1277                    url : 'images/maps/' + _settings.staticimage
1278                }),
1279                toolbarTitle : 'Static Image'
1280            },
1281            'arcgis' : {
1282                provider : new Cesium.ArcGisMapServerImageryProvider(
1283                    {url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer'//,
1284                  //  proxy: new Cesium.DefaultProxy('http://cesium.agi.com/proxy/')
1285                }),
1286                toolbarTitle : 'Arc Gis'                
1287            }/*,
1288            'naturalearth' : {
1289                provider : new Cesium.TileMapServiceImageryProvider(
1290                    {url: '//cesiumjs.org/tilesets/imagery/naturalearthii'
1291                }),
1292                toolbarTitle : 'Natural Earth'                  
1293            },
1294            'blackmarble' : {
1295                provider : new Cesium.TileMapServiceImageryProvider(
1296                    {url: '//cesiumjs.org/tilesets/imagery/blackmarble'
1297                }),
1298                toolbarTitle : 'Black Marble'                  
1299            }     */        
1300        };         
1301           
1302        canvas = jQuery('<canvas/>', {
1303            'id' : 'glCanvas'+_element,
1304            'class' : 'fullsize'
1305        }).appendTo('#'+_element)[0];
1306
1307        scene = new Cesium.Scene({
1308            canvas: canvas
1309        });
1310      
1311      /*  
1312        switch (_settings.view) {
1313            case 'twod':
1314                scene.mode = Cesium.SceneMode.SCENE2D
1315                jQuery('#3d-projection').setTitle('Views', '<br /> 2d view' ); 
1316                break;
1317            case 'twopointfived':
1318                scene.mode = Cesium.SceneMode.COLUMBUS_VIEW
1319                jQuery('#3d-projection').setTitle('Views', '<br /> 2.5d view' ); 
1320                break;
1321            case 'threed':
1322                scene.mode = Cesium.SceneMode.SCENE3D
1323                jQuery('#3d-projection').setTitle('Views', '<br /> 3d view' );                     
1324                break;
1325        }        
1326        */
1327
1328        setProvider(_settings.provider);
1329
1330        cb.showSkyAtmosphere = true;
1331        
1332        cb.enableLighting  = true;
1333        
1334        scene.globe = cb;
1335
1336        setTerrainProvider(_settings.useTerrainProvider);
1337                
1338        _skyAtmosphere = new Cesium.SkyAtmosphere();
1339        scene.skyAtmosphere = _skyAtmosphere;
1340        
1341        var imageryUrl = 'images/';
1342        _skybox = new Cesium.SkyBox({
1343            sources : {
1344              positiveX : 'images/spacebook/Version2_dark_px.jpg',
1345              negativeX : 'images/spacebook/Version2_dark_mx.jpg',
1346              positiveY : 'images/spacebook/Version2_dark_py.jpg',
1347              negativeY : 'images/spacebook/Version2_dark_my.jpg',
1348              positiveZ : 'images/spacebook/Version2_dark_pz.jpg',
1349              negativeZ : 'images/spacebook/Version2_dark_mz.jpg'
1350            }
1351        });                        
1352        scene.skyBox = _skybox;
1353        
1354        _labels = new Cesium.LabelCollection(undefined);        
1355        _mousePosLabel = _labels.add({
1356            font : '14px sans-serif',
1357            fillColor : 'black',
1358            outlineColor : 'black',
1359            style : Cesium.LabelStyle.FILL
1360        });
1361        scene.primitives.add(_satNameLabels);
1362
1363        scene.sun = new Cesium.Sun();
1364        scene.moon = new Cesium.Moon();
1365                
1366        satelliteClickDetails(scene);
1367        mouseMoveDetails(scene, ellipsoid);
1368        scene.primitives.add(orbitLines);
1369        scene.primitives.add(selectedLines);
1370        scene.primitives.add(passLines);
1371        scene.primitives.add(footprintCircle);
1372        scene.primitives.add(_labels);
1373        scene.primitives.add(planetsBillboards);
1374        scene.primitives.add(observerBillboards);
1375        scene.primitives.add(_observerLabels);
1376        scene.primitives.add(_observerCircles);
1377        scene.primitives.add(_cityBillboards);
1378        scene.primitives.add(_cityLabels);
1379        
1380        jQuery(window).trigger('resize');
1381        
1382        plotObservers();
1383        
1384        if (AGSETTINGS.getViewSettings('threed').showCities) {
1385            jQuery('#3d-show-cities').setState(true);
1386            plotCities();
1387        } else {
1388            jQuery('#3d-show-cities').setState(false);
1389        }
1390        
1391        jQuery('#3d-provider').setTitle('Provider', '<br />' + TILE_PROVIDERS[_currentProvider].toolbarTitle ); 
1392        jQuery('#3d-projection').setTitle('Views', '<br /> 3d view' ); 
1393                
1394        jQuery('#3d-sat-finder').combobox({
1395            onSelect : function(record){
1396                var sat = AGSatTrack.getSatelliteByName(record.value);
1397                jQuery(document).trigger('agsattrack.satclicked', {catalogNumber: record.value});
1398
1399                var pos = Cesium.Cartesian3.fromDegrees(sat.get('longitude'), sat.get('latitude'), (sat.get('altitude')*1000)+1000000);
1400                 
1401                disableInput(scene);
1402                var flight = scene.camera.flyTo({
1403                    destination : pos,
1404                    complete : function() {
1405                        enableInput(scene);
1406                    }
1407                });
1408            }
1409        });
1410        
1411      //  jQuery('#bmopacityslider').jqxSlider('setValue', _blackMarbleOpacity);
1412      //  jQuery('#bmbrightnessslider').jqxSlider('setValue', _blackMarbleBrightness);
1413            
1414       // var inspector = new Cesium.CesiumInspector('inspector', scene);
1415        
1416    }
1417    
1418    /**
1419    * Disable 3d view if there is no WebGL support
1420    */
1421    function initNo3DView() {
1422        /**
1423        * Add a sorry message to the view
1424        */
1425        jQuery('<div style="padding:20px"><img src="/images/ie.jpg" width=128 style="float:left" /><h1>3D View Not Supported</h1><p>Sorry the 3D view is not supported in your browser.</p><p>Recent versions of Chrome, Firefox, and Safari are supported. Internet Explorer is supported by using the <a target="_blank" href="http://www.google.com/chromeframe">Chrome Frame plugin</a>, which is a one-time install that does not require admin rights</p></div>', {
1426            'id' : 'glCanvas',
1427            'class' : 'fullsize'
1428        }).appendTo('#3d');
1429
1430        /**
1431        * Disable all of the toolbar buttons                
1432        */
1433        jQuery('#satview3d').hide();
1434        jQuery('#3d-view-reset').disable();
1435        jQuery('#3d-projection').disable();
1436        jQuery('#3d-provider').disable();
1437        jQuery('#3d-follow').disable();
1438    }
1439    
1440    return {
1441        startRender : function() {
1442            if (AGSETTINGS.getHaveWebGL()) {
1443                _render = true;
1444                resize();
1445                renderScene();
1446                createSatellites();
1447            }
1448        },
1449
1450        stopRender : function() {
1451            _render = false;
1452        },
1453
1454        destroy : function() {
1455            _render = false;
1456            jQuery('#'+_element).html('');    
1457        },
1458                
1459        resizeView : function(width, height) {
1460            if (AGSETTINGS.getHaveWebGL()) {
1461                resize(width, height);     
1462            }
1463        },
1464        
1465        reDraw : function() {
1466            
1467        },
1468             
1469        init : function(mode) {
1470            if (AGSETTINGS.getHaveWebGL()) {
1471                if (typeof mode === 'undefined') {
1472                    mode = AGVIEWS.modes.DEFAULT;    
1473                }
1474                _mode = mode;                
1475                init3DView();
1476            }
1477        },
1478        
1479        reset : function() {
1480            _singleSat = null;
1481            createSatellites();
1482            updateSatellites();              
1483        },
1484        
1485        postInit : function() {
1486            if (!AGSETTINGS.getHaveWebGL()) {
1487                initNo3DView();
1488            }            
1489        },
1490        
1491        setSingleSat : function(satellite) {
1492            _singleSat = satellite;
1493            createSatellites();
1494            updateSatellites();            
1495        },
1496        
1497        setPassToShow : function(passToShow) {
1498        }
1499                
1500    };
1501};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.