diff --git a/src/style/style.ts b/src/style/style.ts index b73c5904e7b..8e607eefbd6 100644 --- a/src/style/style.ts +++ b/src/style/style.ts @@ -4306,6 +4306,10 @@ class Style extends Evented { this._force3DLayerUpdate(); const parameters = this._getTransitionParameters({duration: 0}); terrain.updateTransitions(parameters); + // Evaluate the terrain properties synchronously so that consumers such as + // Terrain#update can access them before the next Style#update runs (#13665). + const evaluationParameters = new EvaluationParameters(this.z || 0, {...parameters, worldview: this.map.getWorldview()}); + terrain.recalculate(evaluationParameters); } _force3DLayerUpdate() { diff --git a/test/unit/terrain/terrain.test.ts b/test/unit/terrain/terrain.test.ts index 390d4a90481..8062451d6c7 100644 --- a/test/unit/terrain/terrain.test.ts +++ b/test/unit/terrain/terrain.test.ts @@ -163,6 +163,13 @@ describe('Elevation', () => { }); }); + test('mapbox-gl-js#13665: removeSource before the first render under globe projection does not throw', async () => { + const map = createMap({projection: 'globe'}); + await waitFor(map, 'style.load'); + map.addSource('repro-src', {type: 'geojson', data: {type: 'FeatureCollection', features: []}}); + expect(() => map.removeSource('repro-src')).not.toThrowError(); + }); + test('style diff=false removes dem source', async () => { const map = createMap(); await waitFor(map, "style.load");