@@ -4,22 +4,43 @@ import {
44 PerspectiveCamera ,
55} from 'three' ;
66import { TilesRenderer , GlobeControls , EnvironmentControls } from '3d-tiles-renderer' ;
7- import { TilesFadePlugin , UpdateOnChangePlugin , WMTSCapabilitiesLoader , WMTSTilesPlugin } from '3d-tiles-renderer/plugins' ;
7+ import { TilesFadePlugin , UpdateOnChangePlugin , WMTSTilesPlugin } from '3d-tiles-renderer/plugins' ;
88import { GUI } from 'three/examples/jsm/libs/lil-gui.module.min.js' ;
99
10- const url = window . location . hash . replace ( / ^ # / , '' ) || 'https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/wmts.cgi?SERVICE=WMTS&request=GetCapabilities' ;
11- const compatibleCRSList = [ 'EPSG:4326' , 'EPSG:3857' ] ;
10+ const SOURCES = {
11+ 'NASA GIBS' : {
12+ url : 'https://gibs.earthdata.nasa.gov/wmts/epsg4326/best/wmts.cgi' ,
13+ layer : 'MODIS_Terra_CorrectedReflectance_TrueColor' ,
14+ tileMatrixSet : '250m' ,
15+ style : 'default' ,
16+ projection : 'EPSG:4326' ,
17+ tileDimension : 512 ,
18+ levels : 9 ,
19+ dimensions : { TIME : '2013-06-16' } ,
20+ } ,
21+ 'ArcGIS World Imagery' : {
22+ url : 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer/WMTS' ,
23+ layer : 'World_Imagery' ,
24+ tileMatrixSet : 'default028mm' ,
25+ projection : 'EPSG:3857' ,
26+ format : 'image/jpeg' ,
27+ levels : 19 ,
28+ } ,
29+ } ;
1230
1331let controls , scene , renderer ;
1432let tiles , camera , gui ;
15- let params , capabilities ;
33+
34+ const params = {
35+ planar : false ,
36+ source : 'NASA GIBS' ,
37+ } ;
1638
1739init ( ) ;
1840render ( ) ;
1941
2042function init ( ) {
2143
22- // renderer
2344 renderer = new WebGLRenderer ( { antialias : true } ) ;
2445 renderer . setPixelRatio ( window . devicePixelRatio ) ;
2546 renderer . setSize ( window . innerWidth , window . innerHeight ) ;
@@ -28,120 +49,23 @@ function init() {
2849
2950 document . body . appendChild ( renderer . domElement ) ;
3051
31- // scene
3252 scene = new Scene ( ) ;
3353
34- // set up cameras and ortho / perspective transition
3554 camera = new PerspectiveCamera ( 60 , window . innerWidth / window . innerHeight , 0.001 , 10000 ) ;
3655
37- // update the capabilities file
38- updateCapabilities ( ) ;
56+ buildGUI ( ) ;
57+ rebuildTiles ( ) ;
3958
40- // events
4159 onWindowResize ( ) ;
4260 window . addEventListener ( 'resize' , onWindowResize , false ) ;
43- window . addEventListener ( 'hashchange' , ( ) => location . reload ( ) ) ;
4461
4562}
4663
47- async function updateCapabilities ( ) {
48-
49- // load the capabilities file
50- capabilities = await new WMTSCapabilitiesLoader ( ) . loadAsync ( url ) ;
51-
52- // use a default overlay
53- let defaultLayer = 'MODIS_Terra_CorrectedReflectance_TrueColor' ;
54-
55- if ( ! capabilities . layers . find ( l => l . identifier === defaultLayer ) ) {
56-
57- defaultLayer = capabilities . layers . find ( l =>
58- l . tileMatrixSets . some ( tms => compatibleCRSList . includes ( tms . supportedCRS ) )
59- ) . identifier ;
60-
61- }
62-
63- // set up the parameters
64- params = {
65- layer : defaultLayer ,
66- style : null ,
67- tileMatrixSet : null ,
68- planar : false ,
69- dimensions : { } ,
70- } ;
71-
72- rebuildGUI ( ) ;
73- rebuildTiles ( ) ;
74-
75- }
76-
77- function rebuildGUI ( ) {
78-
79- if ( gui ) {
80-
81- gui . destroy ( ) ;
82-
83- }
84-
85- params . style = null ;
86- params . tileMatrixSet = null ;
87- params . dimensions = { } ;
88-
89- // initialize the layer settings
90- const layer = capabilities . layers . find ( l => l . identifier === params . layer ) ;
91- params . style = layer . styles . find ( s => s . isDefault ) ?. identifier || layer . styles [ 0 ] . identifier ;
92- const compatibleTileMatrixSet = layer . tileMatrixSets . find ( tms => compatibleCRSList . includes ( tms . supportedCRS ) ) ;
93- params . tileMatrixSet = compatibleTileMatrixSet ? compatibleTileMatrixSet . identifier : layer . tileMatrixSets [ 0 ] . identifier ;
94-
95- // update the ui
96- const abstract = capabilities . serviceIdentification . abstract ;
97- document . getElementById ( 'info' ) . innerHTML =
98- '<b>' + capabilities . serviceIdentification . title + '</b>' + ( abstract ? '<br/>' + abstract : '' ) +
99- '<br/>' + layer . title ;
100-
64+ function buildGUI ( ) {
10165
10266 gui = new GUI ( ) ;
10367 gui . add ( params , 'planar' ) . onChange ( rebuildTiles ) ;
104- gui . add ( params , 'layer' , capabilities . layers . map ( l => l . identifier ) ) . onChange ( ( ) => {
105-
106- rebuildGUI ( url ) ;
107- rebuildTiles ( ) ;
108-
109- } ) ;
110- gui . add ( params , 'tileMatrixSet' , layer . tileMatrixSets . map ( tms => tms . identifier ) ) . onChange ( rebuildTiles ) ;
111- gui . add ( params , 'style' , layer . styles . map ( s => s . identifier ) ) . onChange ( rebuildTiles ) ;
112-
113- // create the UI for dimensions
114- for ( const key in layer . dimensions ) {
115-
116- const dim = layer . dimensions [ key ] ;
117- params . dimensions [ dim . identifier ] = layer . dimensions [ key ] . defaultValue ;
118-
119- // Note that NASA GIBS uses a custom notation for time
120- // https://www.earthdata.nasa.gov/news/blog/wmts-time-dimensions-restful-access
121- let values = dim . values ;
122- if ( dim . identifier === 'Time' && / g i b s .e a r t h d a t a / . test ( url ) ) {
123-
124- values = values . flatMap ( v => {
125-
126- const tokens = v . split ( / \/ / g ) ;
127- tokens . pop ( ) ;
128- return tokens ;
129-
130- } ) ;
131-
132- if ( / ^ M O D I S _ T e r r a / . test ( params . layer ) ) {
133-
134- // NOTE: this is a good full-ranged time to use with a full set of data typically used by GIBs for demos
135- values . push ( '2013-06-16' ) ;
136- params . dimensions [ dim . identifier ] = '2013-06-16' ;
137-
138- }
139-
140- }
141-
142- gui . add ( params . dimensions , dim . identifier , values ) . onChange ( rebuildTiles ) ;
143-
144- }
68+ gui . add ( params , 'source' , Object . keys ( SOURCES ) ) . onChange ( rebuildTiles ) ;
14569
14670}
14771
@@ -160,23 +84,22 @@ function rebuildTiles() {
16084
16185 }
16286
163- // tiles
87+ const sourceConfig = SOURCES [ params . source ] ;
88+
16489 tiles = new TilesRenderer ( ) ;
16590 tiles . registerPlugin ( new TilesFadePlugin ( ) ) ;
16691 tiles . registerPlugin ( new UpdateOnChangePlugin ( ) ) ;
16792 tiles . registerPlugin ( new WMTSTilesPlugin ( {
16893 shape : params . planar ? 'planar' : 'ellipsoid' ,
16994 center : true ,
170- capabilities,
171- ...params ,
95+ ...sourceConfig ,
17296 } ) ) ;
17397
17498 tiles . setCamera ( camera ) ;
17599 scene . add ( tiles . group ) ;
176100
177101 if ( params . planar ) {
178102
179- // create the controls
180103 controls = new EnvironmentControls ( scene , camera , renderer . domElement ) ;
181104 controls . enableDamping = true ;
182105 controls . minDistance = 1e-4 ;
@@ -187,17 +110,14 @@ function rebuildTiles() {
187110 controls . camera . position . set ( 0 , 0 , 2 ) ;
188111 controls . camera . quaternion . identity ( ) ;
189112
190- // reset the camera
191113 camera . near = 1e-4 ;
192114 camera . far = 10 ;
193115 camera . updateProjectionMatrix ( ) ;
194116
195117 } else {
196118
197- // init tiles
198119 tiles . group . rotation . x = - Math . PI / 2 ;
199120
200- // create the controls
201121 controls = new GlobeControls ( scene , camera , renderer . domElement ) ;
202122 controls . setEllipsoid ( tiles . ellipsoid , tiles . group ) ;
203123 controls . enableDamping = true ;
0 commit comments