fix(mapbox): automatically inject 'mapbox' view in overlaid mode for multi-view consistency#9947
fix(mapbox): automatically inject 'mapbox' view in overlaid mode for multi-view consistency#9947chrisgervang wants to merge 6 commits intomasterfrom
Conversation
…multi-view consistency When custom views are provided without a view with id 'mapbox', MapboxOverlay now automatically injects the default 'mapbox' view in overlaid mode, matching the behavior in interleaved mode (where getViewport() already does this fallback). This ensures consistent behavior between interleaved and overlaid modes, and allows users to only specify additional views (like minimap, ortho) without having to manually include the base map view. The bug was discovered while implementing multi-view examples in #9946. When interleaved was false (overlaid mode), the multi-view example did not render airports/arcs layers because there was no 'mapbox' view for them to render in. In interleaved mode, the same example worked because getViewport() in deck-utils falls back to creating a 'mapbox' view when not found in custom views. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
…ction - Improved multi-view documentation to explain automatic 'mapbox' view injection - Added 6 test cases covering view injection in both overlaid and interleaved modes - Tests verify that 'mapbox' view is auto-injected when not provided and that no duplicates are created when explicitly provided Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
| // Check if custom views include a view with id 'mapbox' | ||
| const views = Array.isArray(this._props.views) ? this._props.views : [this._props.views]; | ||
| const hasMapboxView = views.some((v: any) => v.id === 'mapbox'); |
- Updated setProps() to call _getViews() for both overlaid and interleaved modes - Added _getViews() call in _onAddInterleaved() to inject 'mapbox' view at initialization - Updated _handleStyleChange() to always update views on projection change, even with custom views - Extended AutoInjectMapboxView tests to verify setProps maintains view injection in both modes This ensures both overlaid and interleaved modes consistently keep user props pure while dynamically computing views at all usage points, preventing view inconsistencies when calling setProps() or when map projection changes. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
The interleavedAutoInjectMapboxView test was hanging because it called setProps() inside a render callback without waiting for async operations to complete. Added async/await pattern to match other interleaved tests.
|
I'm considering a few paths here..
|
| With that said, it is still possible to take advantage of deck's multi-view system and render a mapbox base map onto any one `MapView` of your choice by setting the `views` array and a `layerFilter` callback. | ||
|
|
||
| - To use multiple views, define a `MapView` with the id `“mapbox”`. This view will receive the state that matches the base map at each render. | ||
| - If views are provided but the array does not contain this id, then a `MapView({id: 'mapbox'})` will be inserted at the bottom of the stack. |
There was a problem hiding this comment.
For context, this is what is not true for overlaid mode that this PR aims to fix
… pollution Reduced overlaid mode tests to a single test due to WebGL context state pollution when running multiple overlaid tests sequentially. Comprehensive coverage for setProps, custom views, and duplicate prevention is maintained through interleaved mode tests which don't exhibit the same issues. See #9950 for details on the underlying WebGL context cleanup issue. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Summary
Fixes an inconsistency in
MapboxOverlaywhere custom views behave differently in interleaved vs overlaid modes.Problem
When implementing multi-view examples in #9946, we discovered that when
interleaved=false(overlaid mode), the multi-view example did not render airports/arcs layers because there was no'mapbox'view for them to render in. Ininterleaved=truemode, the same example worked fine.Root cause: In interleaved mode,
getViewport()indeck-utils.tsautomatically falls back to creating a 'mapbox' view when it's not found in custom views. However, in overlaid mode, custom views were used as-is without this fallback, creating inconsistent behavior.Solution
Added a
_getViews()helper method inMapboxOverlaythat checks if custom views include a view with id'mapbox'. If not, it automatically injects the default'mapbox'view, matching the interleaved mode behavior.This allows users to only specify additional views (like minimap, ortho) without having to manually include the base map view.
I kept the fallback within
getViewport()as a defensive measure.. it shouldn't be needed anymore, but I'm leaving this cleanup for another PR for the sake of keeping this one focused.Test Plan
Note
Medium Risk
Touches view selection and update paths (
setProps, render loop, and style/projection updates), which could affect rendering order or multi-view setups; changes are localized and backed by new tests.Overview
Fixes multi-view inconsistencies in
MapboxOverlayby always ensuring a base-map-synchronized view exists: when customviewsare provided without an id of"mapbox", a defaultMapView/GlobeViewwith id"mapbox"is auto-injected (including onsetProps, render updates, and projection/style changes).Adds tests to verify auto-injection,
setPropsbehavior, and no-duplicate behavior when an explicit"mapbox"view is supplied, and updates docs to clearly document the"mapbox"view-id convention forlayerFilterand custom view ordering.Written by Cursor Bugbot for commit 9615b35. This will update automatically on new commits. Configure here.