Skip to content

Commit ab5b727

Browse files
authored
fix(maplibre): Update default view once projection is known (#9794)
1 parent d4804c6 commit ab5b727

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed

modules/mapbox/src/deck-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ export function drawLayer(
184184
});
185185
}
186186

187-
function getProjection(map: Map): 'mercator' | 'globe' {
187+
export function getProjection(map: Map): 'mercator' | 'globe' {
188188
const projection = map.getProjection?.();
189189
const type =
190190
// maplibre projection spec

modules/mapbox/src/mapbox-overlay.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import {
88
getDefaultView,
99
getDeckInstance,
1010
removeDeckInstance,
11-
getDefaultParameters
11+
getDefaultParameters,
12+
getProjection
1213
} from './deck-utils';
1314

1415
import type {Map, IControl, MapMouseEvent, ControlPosition} from './types';
@@ -214,6 +215,13 @@ export default class MapboxOverlay implements IControl {
214215

215216
private _handleStyleChange = () => {
216217
resolveLayers(this._map, this._deck, this._props.layers, this._props.layers);
218+
if (!this._map) return;
219+
220+
// getProjection() returns undefined before style is loaded
221+
const projection = getProjection(this._map);
222+
if (projection && !this._props.views) {
223+
this._deck?.setProps({views: getDefaultView(this._map)});
224+
}
217225
};
218226

219227
private _updateContainerSize = () => {

test/modules/mapbox/mapbox-gl-mock/map.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ export default class Map extends Evented {
1919
this.options = options;
2020
this.version = options.version;
2121
this.style = new Style(options.style);
22+
this.projection = {
23+
type: options.projection || 'mercator'
24+
};
2225
this._controls = [];
2326
this.transform = new Transform(options);
2427
this._loaded = false;
@@ -76,6 +79,9 @@ export default class Map extends Evented {
7679
setRenderWorldCopies(value) {
7780
this.transform.renderWorldCopies = value;
7881
}
82+
getProjection() {
83+
return this.projection;
84+
}
7985

8086
addControl(control) {
8187
this._controls.push(control);

test/modules/mapbox/mapbox-overlay.spec.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import test from 'tape-promise/tape';
66

77
import {ScatterplotLayer} from '@deck.gl/layers';
88
import {MapboxOverlay} from '@deck.gl/mapbox';
9+
import {_GlobeView as GlobeView, MapView} from '@deck.gl/core';
910

1011
import {objectEqual} from './mapbox-layer.spec';
1112
import MockMapboxMap from './mapbox-gl-mock/map';
@@ -354,3 +355,40 @@ test('MapboxOverlay#interleavedFinalizeRemovesMoveHandler', t => {
354355
t.end();
355356
});
356357
});
358+
359+
const PROJECTION_TEST_CASES = [
360+
{projection: 'globe', ExpectedView: GlobeView},
361+
{projection: 'mercator', ExpectedView: MapView},
362+
{ExpectedView: MapView}
363+
];
364+
365+
for (const {projection, ExpectedView} of PROJECTION_TEST_CASES) {
366+
test(`MapboxOverlay#${projection} projection view selection`, t => {
367+
const map = new MockMapboxMap({
368+
center: {lng: -122.45, lat: 37.78},
369+
zoom: 14,
370+
projection
371+
});
372+
373+
const overlay = new MapboxOverlay({
374+
interleaved: true,
375+
layers: [new ScatterplotLayer({id: 'test-layer'})]
376+
});
377+
378+
map.addControl(overlay);
379+
380+
t.ok(overlay._deck, 'Deck instance is created');
381+
382+
map.on('render', () => {
383+
const mapboxView = overlay._deck.props.views;
384+
t.ok(
385+
mapboxView instanceof ExpectedView,
386+
`should use correct view when map has ${projection} projection`
387+
);
388+
389+
map.removeControl(overlay);
390+
t.notOk(overlay._deck, 'Deck instance is finalized');
391+
t.end();
392+
});
393+
});
394+
}

0 commit comments

Comments
 (0)