@deck.gl/mapbox 8.8.0-alpha.4 → 8.8.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,38 @@
1
- import {Deck, WebMercatorViewport, MapView} from '@deck.gl/core';
2
-
3
- export function getDeckInstance({map, gl, deck}) {
1
+ import {Deck, WebMercatorViewport, MapView, _flatten as flatten} from '@deck.gl/core';
2
+ import type {DeckProps, MapViewState, Layer} from '@deck.gl/core';
3
+ import type MapboxLayer from './mapbox-layer';
4
+ import type {Map} from 'mapbox-gl';
5
+
6
+ type UserData = {
7
+ isExternal: boolean;
8
+ currentViewport?: WebMercatorViewport | null;
9
+ mapboxLayers: Set<MapboxLayer<any>>;
10
+ mapboxVersion: {minor: number; major: number};
11
+ };
12
+
13
+ export function getDeckInstance({
14
+ map,
15
+ gl,
16
+ deck
17
+ }: {
18
+ map: Map & {__deck?: Deck | null};
19
+ gl: WebGLRenderingContext;
20
+ deck?: Deck;
21
+ }): Deck {
4
22
  // Only create one deck instance per context
5
23
  if (map.__deck) {
6
24
  return map.__deck;
7
25
  }
8
26
 
9
- const customRender = deck && deck.props._customRender;
27
+ const customRender = deck?.props._customRender;
10
28
 
11
- const deckProps = {
29
+ const deckProps: DeckProps = {
12
30
  useDevicePixels: true,
13
- _customRender: () => {
31
+ _customRender: (reason: string) => {
14
32
  map.triggerRepaint();
15
- if (customRender) {
16
- // customRender may be subscribed by DeckGL React component to update child props
17
- // make sure it is still called
18
- customRender();
19
- }
33
+ // customRender may be subscribed by DeckGL React component to update child props
34
+ // make sure it is still called
35
+ customRender?.(reason);
20
36
  },
21
37
  // TODO: import these defaults from a single source of truth
22
38
  parameters: {
@@ -28,10 +44,6 @@ export function getDeckInstance({map, gl, deck}) {
28
44
  depthFunc: gl.LEQUAL,
29
45
  blendEquation: gl.FUNC_ADD
30
46
  },
31
- userData: {
32
- isExternal: false,
33
- mapboxLayers: new Set()
34
- },
35
47
  views: (deck && deck.props.views) || [new MapView({id: 'mapbox'})]
36
48
  };
37
49
 
@@ -40,58 +52,62 @@ export function getDeckInstance({map, gl, deck}) {
40
52
  // block deck from setting the canvas size
41
53
  Object.assign(deckProps, {
42
54
  gl,
43
- width: false,
44
- height: false,
55
+ width: null,
56
+ height: null,
45
57
  touchAction: 'unset',
46
58
  viewState: getViewState(map)
47
59
  });
48
60
  // If using the WebGLContext created by deck (React use case), we use deck's viewState to drive the map.
49
61
  // Otherwise (pure JS use case), we use the map's viewState to drive deck.
50
- map.on('move', () => onMapMove(deck, map));
62
+ map.on('move', () => onMapMove(deck!, map));
51
63
  }
52
64
 
53
65
  if (deck) {
54
66
  deck.setProps(deckProps);
55
- deck.props.userData.isExternal = true;
67
+ (deck.userData as UserData).isExternal = true;
56
68
  } else {
57
69
  deck = new Deck(deckProps);
58
70
  map.on('remove', () => {
59
- deck.finalize();
71
+ deck!.finalize();
60
72
  map.__deck = null;
61
73
  });
62
74
  }
63
75
 
64
- deck.props.userData.mapboxVersion = getMapboxVersion(map);
76
+ (deck.userData as UserData).mapboxLayers = new Set();
77
+ (deck.userData as UserData).mapboxVersion = getMapboxVersion(map);
65
78
  map.__deck = deck;
66
79
  map.on('render', () => {
80
+ // @ts-expect-error (2445) protected property
67
81
  if (deck.layerManager) afterRender(deck, map);
68
82
  });
69
83
 
70
84
  return deck;
71
85
  }
72
86
 
73
- export function addLayer(deck, layer) {
74
- deck.props.userData.mapboxLayers.add(layer);
87
+ export function addLayer(deck: Deck, layer: MapboxLayer<any>): void {
88
+ (deck.userData as UserData).mapboxLayers.add(layer);
75
89
  updateLayers(deck);
76
90
  }
77
91
 
78
- export function removeLayer(deck, layer) {
79
- deck.props.userData.mapboxLayers.delete(layer);
92
+ export function removeLayer(deck: Deck, layer: MapboxLayer<any>): void {
93
+ (deck.userData as UserData).mapboxLayers.delete(layer);
80
94
  updateLayers(deck);
81
95
  }
82
96
 
83
- export function updateLayer(deck, layer) {
97
+ export function updateLayer(deck: Deck, layer: MapboxLayer<any>): void {
84
98
  updateLayers(deck);
85
99
  }
86
100
 
87
- export function drawLayer(deck, map, layer) {
88
- let {currentViewport} = deck.props.userData;
101
+ export function drawLayer(deck: Deck, map: Map, layer: MapboxLayer<any>): void {
102
+ let {currentViewport} = deck.userData as UserData;
89
103
  if (!currentViewport) {
90
104
  // This is the first layer drawn in this render cycle.
91
105
  // Generate viewport from the current map state.
92
106
  currentViewport = getViewport(deck, map, true);
93
- deck.props.userData.currentViewport = currentViewport;
107
+ (deck.userData as UserData).currentViewport = currentViewport;
94
108
  }
109
+
110
+ // @ts-expect-error (2445) protected property
95
111
  if (!deck.layerManager) {
96
112
  return;
97
113
  }
@@ -103,7 +119,7 @@ export function drawLayer(deck, map, layer) {
103
119
  });
104
120
  }
105
121
 
106
- export function getViewState(map) {
122
+ export function getViewState(map: Map): MapViewState & {repeat: boolean} {
107
123
  const {lng, lat} = map.getCenter();
108
124
  return {
109
125
  // Longitude returned by getCenter can be outside of [-180, 180] when zooming near the anti meridian
@@ -117,18 +133,20 @@ export function getViewState(map) {
117
133
  };
118
134
  }
119
135
 
120
- function getMapboxVersion(map) {
136
+ function getMapboxVersion(map: Map): {minor: number; major: number} {
121
137
  // parse mapbox version string
122
138
  let major = 0;
123
139
  let minor = 0;
124
- if (map.version) {
125
- [major, minor] = map.version.split('.').slice(0, 2).map(Number);
140
+ // @ts-ignore (2339) undefined property
141
+ const version: string = map.version;
142
+ if (version) {
143
+ [major, minor] = version.split('.').slice(0, 2).map(Number);
126
144
  }
127
145
  return {major, minor};
128
146
  }
129
147
 
130
- function getViewport(deck, map, useMapboxProjection = true) {
131
- const {mapboxVersion} = deck.props.userData;
148
+ function getViewport(deck: Deck, map: Map, useMapboxProjection = true): WebMercatorViewport {
149
+ const {mapboxVersion} = deck.userData as UserData;
132
150
 
133
151
  return new WebMercatorViewport(
134
152
  Object.assign(
@@ -158,13 +176,16 @@ function getViewport(deck, map, useMapboxProjection = true) {
158
176
  );
159
177
  }
160
178
 
161
- function afterRender(deck, map) {
162
- const {mapboxLayers, isExternal} = deck.props.userData;
179
+ function afterRender(deck: Deck, map: Map): void {
180
+ const {mapboxLayers, isExternal} = deck.userData as UserData;
163
181
 
164
182
  if (isExternal) {
165
183
  // Draw non-Mapbox layers
166
184
  const mapboxLayerIds = Array.from(mapboxLayers, layer => layer.id);
167
- const hasNonMapboxLayers = deck.props.layers.some(layer => !mapboxLayerIds.includes(layer.id));
185
+ const deckLayers = flatten(deck.props.layers, Boolean) as Layer[];
186
+ const hasNonMapboxLayers = deckLayers.some(
187
+ layer => layer && !mapboxLayerIds.includes(layer.id)
188
+ );
168
189
  let viewports = deck.getViewports();
169
190
  const mapboxViewportIdx = viewports.findIndex(vp => vp.id === 'mapbox');
170
191
  const hasNonMapboxViews = viewports.length > 1 || mapboxViewportIdx < 0;
@@ -186,10 +207,10 @@ function afterRender(deck, map) {
186
207
  }
187
208
 
188
209
  // End of render cycle, clear generated viewport
189
- deck.props.userData.currentViewport = null;
210
+ (deck.userData as UserData).currentViewport = null;
190
211
  }
191
212
 
192
- function onMapMove(deck, map) {
213
+ function onMapMove(deck: Deck, map: Map): void {
193
214
  deck.setProps({
194
215
  viewState: getViewState(map)
195
216
  });
@@ -199,14 +220,14 @@ function onMapMove(deck, map) {
199
220
  deck.needsRedraw({clearRedrawFlags: true});
200
221
  }
201
222
 
202
- function updateLayers(deck) {
203
- if (deck.props.userData.isExternal) {
223
+ function updateLayers(deck: Deck): void {
224
+ if ((deck.userData as UserData).isExternal) {
204
225
  return;
205
226
  }
206
227
 
207
- const layers = [];
228
+ const layers: Layer[] = [];
208
229
  let layerIndex = 0;
209
- deck.props.userData.mapboxLayers.forEach(deckLayer => {
230
+ (deck.userData as UserData).mapboxLayers.forEach(deckLayer => {
210
231
  const LayerType = deckLayer.props.type;
211
232
  const layer = new LayerType(deckLayer.props, {_offset: layerIndex++});
212
233
  layers.push(layer);
@@ -1,8 +1,23 @@
1
1
  import {getDeckInstance, addLayer, removeLayer, updateLayer, drawLayer} from './deck-utils';
2
+ import type {Map, CustomLayerInterface} from 'mapbox-gl';
3
+ import type {Deck, Layer} from '@deck.gl/core';
4
+
5
+ export type MapboxLayerProps<LayerT extends Layer> = Partial<LayerT['props']> & {
6
+ id: string;
7
+ renderingMode?: '2d' | '3d';
8
+ deck?: Deck;
9
+ };
10
+
11
+ export default class MapboxLayer<LayerT extends Layer> implements CustomLayerInterface {
12
+ id: string;
13
+ type: 'custom';
14
+ renderingMode: '2d' | '3d';
15
+ map: Map | null;
16
+ deck: Deck | null;
17
+ props: MapboxLayerProps<LayerT>;
2
18
 
3
- export default class MapboxLayer {
4
19
  /* eslint-disable no-this-before-super */
5
- constructor(props) {
20
+ constructor(props: MapboxLayerProps<LayerT>) {
6
21
  if (!props.id) {
7
22
  throw new Error('Layer must have an unique id');
8
23
  }
@@ -17,17 +32,19 @@ export default class MapboxLayer {
17
32
 
18
33
  /* Mapbox custom layer methods */
19
34
 
20
- onAdd(map, gl) {
35
+ onAdd(map: Map, gl: WebGLRenderingContext): void {
21
36
  this.map = map;
22
37
  this.deck = getDeckInstance({map, gl, deck: this.props.deck});
23
38
  addLayer(this.deck, this);
24
39
  }
25
40
 
26
- onRemove() {
27
- removeLayer(this.deck, this);
41
+ onRemove(): void {
42
+ if (this.deck) {
43
+ removeLayer(this.deck, this);
44
+ }
28
45
  }
29
46
 
30
- setProps(props) {
47
+ setProps(props: MapboxLayerProps<LayerT>) {
31
48
  // id cannot be changed
32
49
  Object.assign(this.props, props, {id: this.id});
33
50
  // safe guard in case setProps is called before onAdd
@@ -36,7 +53,7 @@ export default class MapboxLayer {
36
53
  }
37
54
  }
38
55
 
39
- render(gl, matrix) {
40
- drawLayer(this.deck, this.map, this);
56
+ render() {
57
+ drawLayer(this.deck!, this.map!, this);
41
58
  }
42
59
  }
@@ -1,24 +1,26 @@
1
- import {Deck} from '@deck.gl/core';
1
+ import {Deck, assert} from '@deck.gl/core';
2
2
  import {getViewState} from './deck-utils';
3
3
 
4
4
  import type {Map, IControl, MapMouseEvent} from 'mapbox-gl';
5
+ import type {MjolnirGestureEvent, MjolnirPointerEvent} from 'mjolnir.js';
6
+ import type {DeckProps} from '@deck.gl/core';
5
7
 
6
8
  /**
7
9
  * Implements Mapbox [IControl](https://docs.mapbox.com/mapbox-gl-js/api/markers/#icontrol) interface
8
10
  * Renders deck.gl layers over the base map and automatically synchronizes with the map's camera
9
11
  */
10
12
  export default class MapboxOverlay implements IControl {
11
- private _props: any;
12
- private _deck: Deck;
13
+ private _props: DeckProps;
14
+ private _deck?: Deck;
13
15
  private _map?: Map;
14
16
  private _container?: HTMLDivElement;
15
17
 
16
- constructor(props) {
18
+ constructor(props: DeckProps) {
17
19
  this._props = {...props};
18
20
  }
19
21
 
20
22
  /** Update (partial) props of the underlying Deck instance. */
21
- setProps(props: any): void {
23
+ setProps(props: DeckProps): void {
22
24
  Object.assign(this._props, props);
23
25
 
24
26
  if ('viewState' in this._props) {
@@ -31,7 +33,7 @@ export default class MapboxOverlay implements IControl {
31
33
  }
32
34
 
33
35
  /** Called when the control is added to a map */
34
- onAdd(map: Map) {
36
+ onAdd(map: Map): HTMLDivElement {
35
37
  this._map = map;
36
38
 
37
39
  /* global document */
@@ -62,7 +64,7 @@ export default class MapboxOverlay implements IControl {
62
64
  }
63
65
 
64
66
  /** Called when the control is removed from a map */
65
- onRemove() {
67
+ onRemove(): void {
66
68
  const map = this._map;
67
69
 
68
70
  if (map) {
@@ -75,6 +77,7 @@ export default class MapboxOverlay implements IControl {
75
77
  }
76
78
 
77
79
  this._deck?.finalize();
80
+ this._deck = undefined;
78
81
  this._map = undefined;
79
82
  this._container = undefined;
80
83
  }
@@ -84,18 +87,23 @@ export default class MapboxOverlay implements IControl {
84
87
  }
85
88
 
86
89
  /** Forwards the Deck.pickObject method */
87
- pickObject(params) {
88
- return this._deck && this._deck.pickObject(params);
90
+ pickObject(params: Parameters<Deck['pickObject']>[0]): ReturnType<Deck['pickObject']> {
91
+ assert(this._deck);
92
+ return this._deck.pickObject(params);
89
93
  }
90
94
 
91
95
  /** Forwards the Deck.pickMultipleObjects method */
92
- pickMultipleObjects(params) {
93
- return this._deck && this._deck.pickMultipleObjects(params);
96
+ pickMultipleObjects(
97
+ params: Parameters<Deck['pickMultipleObjects']>[0]
98
+ ): ReturnType<Deck['pickMultipleObjects']> {
99
+ assert(this._deck);
100
+ return this._deck.pickMultipleObjects(params);
94
101
  }
95
102
 
96
103
  /** Forwards the Deck.pickObjects method */
97
- pickObjects(params) {
98
- return this._deck && this._deck.pickObjects(params);
104
+ pickObjects(params: Parameters<Deck['pickObjects']>[0]): ReturnType<Deck['pickObjects']> {
105
+ assert(this._deck);
106
+ return this._deck.pickObjects(params);
99
107
  }
100
108
 
101
109
  /** Remove from map and releases all resources */
@@ -105,7 +113,7 @@ export default class MapboxOverlay implements IControl {
105
113
  }
106
114
  }
107
115
 
108
- _updateContainerSize = () => {
116
+ private _updateContainerSize = () => {
109
117
  if (this._map && this._container) {
110
118
  const {clientWidth, clientHeight} = this._map.getContainer();
111
119
  Object.assign(this._container.style, {
@@ -115,16 +123,17 @@ export default class MapboxOverlay implements IControl {
115
123
  }
116
124
  };
117
125
 
118
- _updateViewState = () => {
126
+ private _updateViewState = () => {
119
127
  const deck = this._deck;
120
128
  if (deck) {
129
+ // @ts-ignore (2345) map is always defined if deck is
121
130
  deck.setProps({viewState: getViewState(this._map)});
122
131
  // Redraw immediately if view state has changed
123
- deck.redraw(false);
132
+ deck.redraw();
124
133
  }
125
134
  };
126
135
 
127
- _handleMouseEvent = (event: MapMouseEvent) => {
136
+ private _handleMouseEvent = (event: MapMouseEvent) => {
128
137
  const deck = this._deck;
129
138
  if (!deck) {
130
139
  return;
@@ -143,29 +152,26 @@ export default class MapboxOverlay implements IControl {
143
152
 
144
153
  switch (event.type) {
145
154
  case 'click':
146
- // Hack: because we do not listen to pointer down, perform picking now
147
- deck._lastPointerDownInfo = deck.pickObject({
148
- ...mockEvent.offsetCenter,
149
- radius: deck.props.pickingRadius
150
- });
151
155
  mockEvent.tapCount = 1;
152
- deck._onEvent(mockEvent);
156
+ // Hack: because we do not listen to pointer down, perform picking now
157
+ deck._onPointerDown(mockEvent as MjolnirGestureEvent);
158
+ deck._onEvent(mockEvent as MjolnirGestureEvent);
153
159
  break;
154
160
 
155
161
  case 'dblclick':
156
162
  mockEvent.type = 'click';
157
163
  mockEvent.tapCount = 2;
158
- deck._onEvent(mockEvent);
164
+ deck._onEvent(mockEvent as MjolnirGestureEvent);
159
165
  break;
160
166
 
161
167
  case 'mousemove':
162
168
  mockEvent.type = 'pointermove';
163
- deck._onPointerMove(mockEvent);
169
+ deck._onPointerMove(mockEvent as MjolnirPointerEvent);
164
170
  break;
165
171
 
166
172
  case 'mouseout':
167
173
  mockEvent.type = 'pointerleave';
168
- deck._onPointerMove(mockEvent);
174
+ deck._onPointerMove(mockEvent as MjolnirPointerEvent);
169
175
  break;
170
176
 
171
177
  default:
@@ -0,0 +1,19 @@
1
+ import { Deck } from '@deck.gl/core/typed';
2
+ import type { MapViewState } from '@deck.gl/core/typed';
3
+ import type MapboxLayer from './mapbox-layer';
4
+ import type { Map } from 'mapbox-gl';
5
+ export declare function getDeckInstance({ map, gl, deck }: {
6
+ map: Map & {
7
+ __deck?: Deck | null;
8
+ };
9
+ gl: WebGLRenderingContext;
10
+ deck?: Deck;
11
+ }): Deck;
12
+ export declare function addLayer(deck: Deck, layer: MapboxLayer<any>): void;
13
+ export declare function removeLayer(deck: Deck, layer: MapboxLayer<any>): void;
14
+ export declare function updateLayer(deck: Deck, layer: MapboxLayer<any>): void;
15
+ export declare function drawLayer(deck: Deck, map: Map, layer: MapboxLayer<any>): void;
16
+ export declare function getViewState(map: Map): MapViewState & {
17
+ repeat: boolean;
18
+ };
19
+ //# sourceMappingURL=deck-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deck-utils.d.ts","sourceRoot":"","sources":["../src/deck-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,IAAI,EAAoD,MAAM,eAAe,CAAC;AACtF,OAAO,KAAK,EAAY,YAAY,EAAQ,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,WAAW,MAAM,gBAAgB,CAAC;AAC9C,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,WAAW,CAAC;AASnC,wBAAgB,eAAe,CAAC,EAC9B,GAAG,EACH,EAAE,EACF,IAAI,EACL,EAAE;IACD,GAAG,EAAE,GAAG,GAAG;QAAC,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;KAAC,CAAC;IAClC,EAAE,EAAE,qBAAqB,CAAC;IAC1B,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,GAAG,IAAI,CAgEP;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAGlE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAGrE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAErE;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAmB7E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,YAAY,GAAG;IAAC,MAAM,EAAE,OAAO,CAAA;CAAC,CAYvE"}
@@ -0,0 +1,185 @@
1
+ import { Deck, WebMercatorViewport, MapView, _flatten as flatten } from '@deck.gl/core';
2
+ export function getDeckInstance({ map, gl, deck }) {
3
+ // Only create one deck instance per context
4
+ if (map.__deck) {
5
+ return map.__deck;
6
+ }
7
+ const customRender = deck?.props._customRender;
8
+ const deckProps = {
9
+ useDevicePixels: true,
10
+ _customRender: (reason) => {
11
+ map.triggerRepaint();
12
+ // customRender may be subscribed by DeckGL React component to update child props
13
+ // make sure it is still called
14
+ customRender?.(reason);
15
+ },
16
+ // TODO: import these defaults from a single source of truth
17
+ parameters: {
18
+ depthMask: true,
19
+ depthTest: true,
20
+ blend: true,
21
+ blendFunc: [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA, gl.ONE, gl.ONE_MINUS_SRC_ALPHA],
22
+ polygonOffsetFill: true,
23
+ depthFunc: gl.LEQUAL,
24
+ blendEquation: gl.FUNC_ADD
25
+ },
26
+ views: (deck && deck.props.views) || [new MapView({ id: 'mapbox' })]
27
+ };
28
+ if (!deck || deck.props.gl === gl) {
29
+ // deck is using the WebGLContext created by mapbox
30
+ // block deck from setting the canvas size
31
+ Object.assign(deckProps, {
32
+ gl,
33
+ width: null,
34
+ height: null,
35
+ touchAction: 'unset',
36
+ viewState: getViewState(map)
37
+ });
38
+ // If using the WebGLContext created by deck (React use case), we use deck's viewState to drive the map.
39
+ // Otherwise (pure JS use case), we use the map's viewState to drive deck.
40
+ map.on('move', () => onMapMove(deck, map));
41
+ }
42
+ if (deck) {
43
+ deck.setProps(deckProps);
44
+ deck.userData.isExternal = true;
45
+ }
46
+ else {
47
+ deck = new Deck(deckProps);
48
+ map.on('remove', () => {
49
+ deck.finalize();
50
+ map.__deck = null;
51
+ });
52
+ }
53
+ deck.userData.mapboxLayers = new Set();
54
+ deck.userData.mapboxVersion = getMapboxVersion(map);
55
+ map.__deck = deck;
56
+ map.on('render', () => {
57
+ // @ts-expect-error (2445) protected property
58
+ if (deck.layerManager)
59
+ afterRender(deck, map);
60
+ });
61
+ return deck;
62
+ }
63
+ export function addLayer(deck, layer) {
64
+ deck.userData.mapboxLayers.add(layer);
65
+ updateLayers(deck);
66
+ }
67
+ export function removeLayer(deck, layer) {
68
+ deck.userData.mapboxLayers.delete(layer);
69
+ updateLayers(deck);
70
+ }
71
+ export function updateLayer(deck, layer) {
72
+ updateLayers(deck);
73
+ }
74
+ export function drawLayer(deck, map, layer) {
75
+ let { currentViewport } = deck.userData;
76
+ if (!currentViewport) {
77
+ // This is the first layer drawn in this render cycle.
78
+ // Generate viewport from the current map state.
79
+ currentViewport = getViewport(deck, map, true);
80
+ deck.userData.currentViewport = currentViewport;
81
+ }
82
+ // @ts-expect-error (2445) protected property
83
+ if (!deck.layerManager) {
84
+ return;
85
+ }
86
+ deck._drawLayers('mapbox-repaint', {
87
+ viewports: [currentViewport],
88
+ layerFilter: ({ layer: deckLayer }) => layer.id === deckLayer.id,
89
+ clearCanvas: false
90
+ });
91
+ }
92
+ export function getViewState(map) {
93
+ const { lng, lat } = map.getCenter();
94
+ return {
95
+ // Longitude returned by getCenter can be outside of [-180, 180] when zooming near the anti meridian
96
+ // https://github.com/visgl/deck.gl/issues/6894
97
+ longitude: ((lng + 540) % 360) - 180,
98
+ latitude: lat,
99
+ zoom: map.getZoom(),
100
+ bearing: map.getBearing(),
101
+ pitch: map.getPitch(),
102
+ repeat: map.getRenderWorldCopies()
103
+ };
104
+ }
105
+ function getMapboxVersion(map) {
106
+ // parse mapbox version string
107
+ let major = 0;
108
+ let minor = 0;
109
+ // @ts-ignore (2339) undefined property
110
+ const version = map.version;
111
+ if (version) {
112
+ [major, minor] = version.split('.').slice(0, 2).map(Number);
113
+ }
114
+ return { major, minor };
115
+ }
116
+ function getViewport(deck, map, useMapboxProjection = true) {
117
+ const { mapboxVersion } = deck.userData;
118
+ return new WebMercatorViewport(Object.assign({
119
+ id: 'mapbox',
120
+ x: 0,
121
+ y: 0,
122
+ width: deck.width,
123
+ height: deck.height
124
+ }, getViewState(map), useMapboxProjection
125
+ ? {
126
+ // match mapbox's projection matrix
127
+ // A change of near plane was made in 1.3.0
128
+ // https://github.com/mapbox/mapbox-gl-js/pull/8502
129
+ nearZMultiplier: (mapboxVersion.major === 1 && mapboxVersion.minor >= 3) || mapboxVersion.major >= 2
130
+ ? 0.02
131
+ : 1 / (deck.height || 1)
132
+ }
133
+ : {
134
+ // use deck.gl's own default
135
+ nearZMultiplier: 0.1
136
+ }));
137
+ }
138
+ function afterRender(deck, map) {
139
+ const { mapboxLayers, isExternal } = deck.userData;
140
+ if (isExternal) {
141
+ // Draw non-Mapbox layers
142
+ const mapboxLayerIds = Array.from(mapboxLayers, layer => layer.id);
143
+ const deckLayers = flatten(deck.props.layers, Boolean);
144
+ const hasNonMapboxLayers = deckLayers.some(layer => layer && !mapboxLayerIds.includes(layer.id));
145
+ let viewports = deck.getViewports();
146
+ const mapboxViewportIdx = viewports.findIndex(vp => vp.id === 'mapbox');
147
+ const hasNonMapboxViews = viewports.length > 1 || mapboxViewportIdx < 0;
148
+ if (hasNonMapboxLayers || hasNonMapboxViews) {
149
+ if (mapboxViewportIdx >= 0) {
150
+ viewports = viewports.slice();
151
+ viewports[mapboxViewportIdx] = getViewport(deck, map, false);
152
+ }
153
+ deck._drawLayers('mapbox-repaint', {
154
+ viewports,
155
+ layerFilter: params => (!deck.props.layerFilter || deck.props.layerFilter(params)) &&
156
+ (params.viewport.id !== 'mapbox' || !mapboxLayerIds.includes(params.layer.id)),
157
+ clearCanvas: false
158
+ });
159
+ }
160
+ }
161
+ // End of render cycle, clear generated viewport
162
+ deck.userData.currentViewport = null;
163
+ }
164
+ function onMapMove(deck, map) {
165
+ deck.setProps({
166
+ viewState: getViewState(map)
167
+ });
168
+ // Camera changed, will trigger a map repaint right after this
169
+ // Clear any change flag triggered by setting viewState so that deck does not request
170
+ // a second repaint
171
+ deck.needsRedraw({ clearRedrawFlags: true });
172
+ }
173
+ function updateLayers(deck) {
174
+ if (deck.userData.isExternal) {
175
+ return;
176
+ }
177
+ const layers = [];
178
+ let layerIndex = 0;
179
+ deck.userData.mapboxLayers.forEach(deckLayer => {
180
+ const LayerType = deckLayer.props.type;
181
+ const layer = new LayerType(deckLayer.props, { _offset: layerIndex++ });
182
+ layers.push(layer);
183
+ });
184
+ deck.setProps({ layers });
185
+ }
@@ -0,0 +1,3 @@
1
+ export { default as MapboxLayer } from './mapbox-layer';
2
+ export { default as MapboxOverlay } from './mapbox-overlay';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,OAAO,IAAI,WAAW,EAAC,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAC,OAAO,IAAI,aAAa,EAAC,MAAM,kBAAkB,CAAC"}
package/typed/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { default as MapboxLayer } from './mapbox-layer';
2
+ export { default as MapboxOverlay } from './mapbox-overlay';
@@ -0,0 +1,21 @@
1
+ import type { Map, CustomLayerInterface } from 'mapbox-gl';
2
+ import type { Deck, Layer } from '@deck.gl/core/typed';
3
+ export declare type MapboxLayerProps<LayerT extends Layer> = Partial<LayerT['props']> & {
4
+ id: string;
5
+ renderingMode?: '2d' | '3d';
6
+ deck?: Deck;
7
+ };
8
+ export default class MapboxLayer<LayerT extends Layer> implements CustomLayerInterface {
9
+ id: string;
10
+ type: 'custom';
11
+ renderingMode: '2d' | '3d';
12
+ map: Map | null;
13
+ deck: Deck | null;
14
+ props: MapboxLayerProps<LayerT>;
15
+ constructor(props: MapboxLayerProps<LayerT>);
16
+ onAdd(map: Map, gl: WebGLRenderingContext): void;
17
+ onRemove(): void;
18
+ setProps(props: MapboxLayerProps<LayerT>): void;
19
+ render(): void;
20
+ }
21
+ //# sourceMappingURL=mapbox-layer.d.ts.map