From 3d52ef83315aa2a1f69f2833715045250eb5cbf9 Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Wed, 16 Jul 2025 11:37:13 +0200 Subject: [PATCH 1/5] First iteration of fix --- modules/mapbox/src/mapbox-overlay.ts | 63 ++++++++++++++++++++-------- modules/react/src/deckgl.ts | 7 +++- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/modules/mapbox/src/mapbox-overlay.ts b/modules/mapbox/src/mapbox-overlay.ts index 1621de8e04a..9958566bf02 100644 --- a/modules/mapbox/src/mapbox-overlay.ts +++ b/modules/mapbox/src/mapbox-overlay.ts @@ -90,16 +90,30 @@ export default class MapboxOverlay implements IControl { }); this._container = container; - this._deck = new Deck({ - ...this._props, - parent: container, - parameters: {...getDefaultParameters(map, false), ...this._props.parameters}, - views: this._props.views || getDefaultView(map), - viewState: getViewState(map) - }); + // Defer deck creation until map is loaded to avoid race condition with projection initialization + const createDeck = () => { + if (this._deck) return; // Already created + + this._deck = new Deck({ + ...this._props, + parent: container, + parameters: {...getDefaultParameters(map, false), ...this._props.parameters}, + views: this._props.views || getDefaultView(map), + viewState: getViewState(map) + }); + }; + + // Create deck immediately if map style is already loaded, otherwise wait for load event + if (map.isStyleLoaded()) { + createDeck(); + } else { + map.once('load', createDeck); + } map.on('resize', this._updateContainerSize); map.on('render', this._updateViewState); + // Listen for projection changes to update the view + map.on('style.load', this._updateViewState); map.on('mousedown', this._handleMouseEvent); map.on('dragstart', this._handleMouseEvent); map.on('drag', this._handleMouseEvent); @@ -121,17 +135,30 @@ export default class MapboxOverlay implements IControl { 'Incompatible basemap library. See: https://deck.gl/docs/api-reference/mapbox/overview#compatibility' )(); } - this._deck = getDeckInstance({ - map, - gl, - deck: new Deck({ - ...this._props, - gl - }) - }); + + // Defer deck creation until map is loaded to avoid race condition with projection initialization + const createDeck = () => { + if (this._deck) return; // Already created + + this._deck = getDeckInstance({ + map, + gl, + deck: new Deck({ + ...this._props, + gl + }) + }); + resolveLayers(map, this._deck, [], this._props.layers); + }; + + // Create deck immediately if map style is already loaded, otherwise wait for load event + if (map.isStyleLoaded()) { + createDeck(); + } else { + map.once('load', createDeck); + } map.on('styledata', this._handleStyleChange); - resolveLayers(map, this._deck, [], this._props.layers); return document.createElement('div'); } @@ -213,7 +240,9 @@ export default class MapboxOverlay implements IControl { } private _handleStyleChange = () => { - resolveLayers(this._map, this._deck, this._props.layers, this._props.layers); + if (this._deck && this._map) { + resolveLayers(this._map, this._deck, this._props.layers, this._props.layers); + } }; private _updateContainerSize = () => { diff --git a/modules/react/src/deckgl.ts b/modules/react/src/deckgl.ts index c60e1486785..3bd757bfbdd 100644 --- a/modules/react/src/deckgl.ts +++ b/modules/react/src/deckgl.ts @@ -214,8 +214,13 @@ function DeckGLWithRef( } // Force initial render if Deck is initialized + // Defer initial render to next frame to avoid race conditions with map initialization if (thisRef.deck?.isInitialized) { - thisRef.deck.redraw('Initial render'); + requestAnimationFrame(() => { + if (thisRef.deck?.isInitialized) { + thisRef.deck.redraw('Initial render'); + } + }); } }); From b4f5300d3236c238f4b395a14f247171a0eccfe1 Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Wed, 16 Jul 2025 11:43:01 +0200 Subject: [PATCH 2/5] Tidy --- modules/mapbox/src/mapbox-overlay.ts | 26 +++++++------------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/modules/mapbox/src/mapbox-overlay.ts b/modules/mapbox/src/mapbox-overlay.ts index 9958566bf02..e738aad1cf2 100644 --- a/modules/mapbox/src/mapbox-overlay.ts +++ b/modules/mapbox/src/mapbox-overlay.ts @@ -90,25 +90,13 @@ export default class MapboxOverlay implements IControl { }); this._container = container; - // Defer deck creation until map is loaded to avoid race condition with projection initialization - const createDeck = () => { - if (this._deck) return; // Already created - - this._deck = new Deck({ - ...this._props, - parent: container, - parameters: {...getDefaultParameters(map, false), ...this._props.parameters}, - views: this._props.views || getDefaultView(map), - viewState: getViewState(map) - }); - }; - - // Create deck immediately if map style is already loaded, otherwise wait for load event - if (map.isStyleLoaded()) { - createDeck(); - } else { - map.once('load', createDeck); - } + this._deck = new Deck({ + ...this._props, + parent: container, + parameters: {...getDefaultParameters(map, false), ...this._props.parameters}, + views: this._props.views || getDefaultView(map), + viewState: getViewState(map) + }); map.on('resize', this._updateContainerSize); map.on('render', this._updateViewState); From 36e936749a117b4dff3b5766422c026139ee889f Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Wed, 16 Jul 2025 11:49:13 +0200 Subject: [PATCH 3/5] More tidy --- modules/mapbox/src/mapbox-overlay.ts | 6 +----- modules/react/src/deckgl.ts | 7 +------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/modules/mapbox/src/mapbox-overlay.ts b/modules/mapbox/src/mapbox-overlay.ts index e738aad1cf2..c3f6178c37a 100644 --- a/modules/mapbox/src/mapbox-overlay.ts +++ b/modules/mapbox/src/mapbox-overlay.ts @@ -100,8 +100,6 @@ export default class MapboxOverlay implements IControl { map.on('resize', this._updateContainerSize); map.on('render', this._updateViewState); - // Listen for projection changes to update the view - map.on('style.load', this._updateViewState); map.on('mousedown', this._handleMouseEvent); map.on('dragstart', this._handleMouseEvent); map.on('drag', this._handleMouseEvent); @@ -228,9 +226,7 @@ export default class MapboxOverlay implements IControl { } private _handleStyleChange = () => { - if (this._deck && this._map) { - resolveLayers(this._map, this._deck, this._props.layers, this._props.layers); - } + resolveLayers(this._map, this._deck, this._props.layers, this._props.layers); }; private _updateContainerSize = () => { diff --git a/modules/react/src/deckgl.ts b/modules/react/src/deckgl.ts index 3bd757bfbdd..c60e1486785 100644 --- a/modules/react/src/deckgl.ts +++ b/modules/react/src/deckgl.ts @@ -214,13 +214,8 @@ function DeckGLWithRef( } // Force initial render if Deck is initialized - // Defer initial render to next frame to avoid race conditions with map initialization if (thisRef.deck?.isInitialized) { - requestAnimationFrame(() => { - if (thisRef.deck?.isInitialized) { - thisRef.deck.redraw('Initial render'); - } - }); + thisRef.deck.redraw('Initial render'); } }); From 38ffb883ab7daebb2d619097546b161a339c779b Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Wed, 16 Jul 2025 12:13:37 +0200 Subject: [PATCH 4/5] Remove comments --- modules/mapbox/src/mapbox-overlay.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/mapbox/src/mapbox-overlay.ts b/modules/mapbox/src/mapbox-overlay.ts index c3f6178c37a..6b4646a8fd9 100644 --- a/modules/mapbox/src/mapbox-overlay.ts +++ b/modules/mapbox/src/mapbox-overlay.ts @@ -124,8 +124,7 @@ export default class MapboxOverlay implements IControl { // Defer deck creation until map is loaded to avoid race condition with projection initialization const createDeck = () => { - if (this._deck) return; // Already created - + if (this._deck) return; this._deck = getDeckInstance({ map, gl, @@ -137,7 +136,6 @@ export default class MapboxOverlay implements IControl { resolveLayers(map, this._deck, [], this._props.layers); }; - // Create deck immediately if map style is already loaded, otherwise wait for load event if (map.isStyleLoaded()) { createDeck(); } else { From 8d2cf1bf54c7d9241fee7713058494979fa0e08e Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Wed, 16 Jul 2025 12:42:20 +0200 Subject: [PATCH 5/5] Avoid crash --- modules/mapbox/src/mapbox-overlay.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/mapbox/src/mapbox-overlay.ts b/modules/mapbox/src/mapbox-overlay.ts index 6b4646a8fd9..6f73d48e2f4 100644 --- a/modules/mapbox/src/mapbox-overlay.ts +++ b/modules/mapbox/src/mapbox-overlay.ts @@ -136,7 +136,7 @@ export default class MapboxOverlay implements IControl { resolveLayers(map, this._deck, [], this._props.layers); }; - if (map.isStyleLoaded()) { + if (typeof map.isStyleLoaded === 'function' && map.isStyleLoaded()) { createDeck(); } else { map.once('load', createDeck);