33// Copyright (c) vis.gl contributors
44
55import { test , expect } from 'vitest' ;
6- import { MapView } from '@deck.gl/core' ;
6+ import { COORDINATE_SYSTEM , _GlobeView as GlobeView , MapView } from '@deck.gl/core' ;
77import { TerrainLayer } from '@deck.gl/geo-layers' ;
88import { testInitializeLayerAsync } from '@deck.gl/test-utils/vitest' ;
99import { TruncatedConeGeometry } from '@luma.gl/engine' ;
@@ -26,6 +26,12 @@ const TEST_VIEWPORT = new MapView().makeViewport({
2626 viewState : { longitude : 0 , latitude : 0 , zoom : 0 }
2727} ) ;
2828
29+ const TEST_GLOBE_VIEWPORT = new GlobeView ( ) . makeViewport ( {
30+ width : 100 ,
31+ height : 100 ,
32+ viewState : { longitude : 0 , latitude : 0 , zoom : 0 }
33+ } ) ;
34+
2935function createTestMesh ( ) {
3036 const mesh = new TruncatedConeGeometry ( {
3137 topRadius : 1 ,
@@ -125,3 +131,86 @@ test('TerrainLayer#isLoaded waits for elevation and texture in tiled mode', asyn
125131 expect ( layer . isLoaded , 'tiled terrain layer is loaded after both resources resolve' ) . toBe ( true ) ;
126132 handle ?. finalize ( ) ;
127133} ) ;
134+
135+ test ( 'TerrainLayer fetches tiles at correct zoom levels for different zoomOffset values' , async ( ) => {
136+ // Create a viewport at zoom 3 to test various zoomOffset values
137+ const viewportZoom3 = new MapView ( ) . makeViewport ( {
138+ width : 100 ,
139+ height : 100 ,
140+ viewState : { longitude : 0 , latitude : 0 , zoom : 3 }
141+ } ) ;
142+
143+ const testCases = [
144+ { zoomOffset : - 1 , expectedZ : 2 , description : 'zoomOffset: -1 (lower detail)' } ,
145+ { zoomOffset : 0 , expectedZ : 3 , description : 'zoomOffset: 0 (normal)' } ,
146+ { zoomOffset : 1 , expectedZ : 4 , description : 'zoomOffset: +1 (higher detail)' }
147+ ] ;
148+
149+ for ( const testCase of testCases ) {
150+ const fetchedUrls : { elevation : string [ ] ; texture : string [ ] } = {
151+ elevation : [ ] ,
152+ texture : [ ]
153+ } ;
154+
155+ const layer = new TerrainLayer ( {
156+ id : `terrain-zoom-offset-${ testCase . zoomOffset } ` ,
157+ elevationData : 'https://example.com/elevation/{z}/{x}/{y}.png' ,
158+ texture : 'https://example.com/texture/{z}/{x}/{y}.png' ,
159+ zoomOffset : testCase . zoomOffset ,
160+ minZoom : 0 ,
161+ maxZoom : 6 ,
162+ fetch : ( url , { propName} ) => {
163+ if ( propName === 'elevationData' ) {
164+ fetchedUrls . elevation . push ( url ) ;
165+ } else if ( propName === 'texture' ) {
166+ fetchedUrls . texture . push ( url ) ;
167+ }
168+ return Promise . resolve ( createTestMesh ( ) ) ;
169+ }
170+ } ) ;
171+
172+ const handle = await testInitializeLayerAsync ( {
173+ layer,
174+ viewport : viewportZoom3 ,
175+ finalize : false
176+ } ) ;
177+
178+ await sleep ( ) ;
179+
180+ // Verify tiles are fetched at the expected zoom level for both elevation and texture
181+ const expectedZoomPath = `/${ testCase . expectedZ } /` ;
182+ expect (
183+ fetchedUrls . elevation . some ( url => url . includes ( expectedZoomPath ) ) ,
184+ `${ testCase . description } : elevation tiles fetched at z=${ testCase . expectedZ } `
185+ ) . toBe ( true ) ;
186+ expect (
187+ fetchedUrls . texture . some ( url => url . includes ( expectedZoomPath ) ) ,
188+ `${ testCase . description } : texture tiles fetched at z=${ testCase . expectedZ } `
189+ ) . toBe ( true ) ;
190+
191+ handle ?. finalize ( ) ;
192+ }
193+ } ) ;
194+
195+ test ( 'TerrainLayer renders tiled Martini meshes in lng/lat coordinates on GlobeView' , async ( ) => {
196+ const layer = new TerrainLayer ( {
197+ id : 'terrain-tiled-globe' ,
198+ elevationData : 'https://example.com/elevation/{z}/{x}/{y}.png' ,
199+ minZoom : 0 ,
200+ maxZoom : 0 ,
201+ fetch : ( ) => Promise . resolve ( createTestMesh ( ) )
202+ } ) ;
203+
204+ const handle = await testInitializeLayerAsync ( {
205+ layer,
206+ viewport : TEST_GLOBE_VIEWPORT ,
207+ finalize : false
208+ } ) ;
209+
210+ const tileLayer = layer . getSubLayers ( ) [ 0 ] ;
211+ const meshLayer = tileLayer . getSubLayers ( ) [ 0 ] ;
212+ expect ( meshLayer . props . coordinateSystem , 'Globe terrain mesh uses lng/lat' ) . toBe (
213+ COORDINATE_SYSTEM . LNGLAT
214+ ) ;
215+ handle ?. finalize ( ) ;
216+ } ) ;
0 commit comments