@deck.gl/mapbox 9.0.0-beta.1 → 9.0.0-beta.10

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.
Files changed (47) hide show
  1. package/{typed → dist}/deck-utils.d.ts +2 -2
  2. package/dist/deck-utils.d.ts.map +1 -0
  3. package/dist/deck-utils.js +266 -0
  4. package/dist/dist.dev.js +777 -151
  5. package/dist/index.cjs +549 -0
  6. package/dist/index.cjs.map +7 -0
  7. package/dist/index.d.ts +3 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +1 -0
  10. package/{typed → dist}/mapbox-layer.d.ts +1 -1
  11. package/{typed → dist}/mapbox-layer.d.ts.map +1 -1
  12. package/dist/mapbox-layer.js +37 -0
  13. package/{typed → dist}/mapbox-overlay.d.ts.map +1 -1
  14. package/dist/mapbox-overlay.js +227 -0
  15. package/dist/resolve-layers.js +74 -0
  16. package/dist.min.js +1 -2
  17. package/package.json +16 -8
  18. package/src/deck-utils.ts +1 -1
  19. package/src/index.ts +0 -1
  20. package/src/mapbox-layer.ts +1 -1
  21. package/src/mapbox-overlay.ts +12 -5
  22. package/dist/es5/deck-utils.js +0 -300
  23. package/dist/es5/deck-utils.js.map +0 -1
  24. package/dist/es5/index.js +0 -24
  25. package/dist/es5/index.js.map +0 -1
  26. package/dist/es5/mapbox-layer.js +0 -72
  27. package/dist/es5/mapbox-layer.js.map +0 -1
  28. package/dist/es5/mapbox-overlay.js +0 -302
  29. package/dist/es5/mapbox-overlay.js.map +0 -1
  30. package/dist/es5/resolve-layers.js +0 -137
  31. package/dist/es5/resolve-layers.js.map +0 -1
  32. package/dist/esm/deck-utils.js +0 -263
  33. package/dist/esm/deck-utils.js.map +0 -1
  34. package/dist/esm/index.js +0 -3
  35. package/dist/esm/index.js.map +0 -1
  36. package/dist/esm/mapbox-layer.js +0 -54
  37. package/dist/esm/mapbox-layer.js.map +0 -1
  38. package/dist/esm/mapbox-overlay.js +0 -272
  39. package/dist/esm/mapbox-overlay.js.map +0 -1
  40. package/dist/esm/resolve-layers.js +0 -77
  41. package/dist/esm/resolve-layers.js.map +0 -1
  42. package/typed/deck-utils.d.ts.map +0 -1
  43. package/typed/index.d.ts +0 -4
  44. package/typed/index.d.ts.map +0 -1
  45. /package/{typed → dist}/mapbox-overlay.d.ts +0 -0
  46. /package/{typed → dist}/resolve-layers.d.ts +0 -0
  47. /package/{typed → dist}/resolve-layers.d.ts.map +0 -0
@@ -1,12 +1,12 @@
1
1
  import { Deck } from '@deck.gl/core';
2
2
  import type { DeckProps, MapViewState } from '@deck.gl/core';
3
- import type MapboxLayer from './mapbox-layer';
3
+ import type MapboxLayer from "./mapbox-layer.js";
4
4
  import type { Map } from 'mapbox-gl';
5
5
  export declare function getDeckInstance({ map, gl, deck }: {
6
6
  map: Map & {
7
7
  __deck?: Deck | null;
8
8
  };
9
- gl: WebGLRenderingContext;
9
+ gl: WebGL2RenderingContext;
10
10
  deck?: Deck;
11
11
  }): Deck;
12
12
  export declare function removeDeckInstance(map: 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,EAAC,SAAS,EAAE,YAAY,EAAQ,MAAM,eAAe,CAAC;AAClE,OAAO,KAAK,WAAW,0BAAuB;AAC9C,OAAO,KAAK,EAAC,GAAG,EAAC,MAAM,WAAW,CAAC;AAiBnC,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,sBAAsB,CAAC;IAC3B,IAAI,CAAC,EAAE,IAAI,CAAC;CACb,GAAG,IAAI,CAiEP;AAeD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,GAAG,GAAG;IAAC,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;CAAC,QAGnE;AAED,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,aAkBvD;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,CAsB7E;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,GAAG,GAAG,YAAY,GAAG;IACrD,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CA6BA"}
@@ -0,0 +1,266 @@
1
+ import { Deck, WebMercatorViewport, MapView, _flatten as flatten } from '@deck.gl/core';
2
+ import { lngLatToWorld, unitsPerMeter } from '@math.gl/web-mercator';
3
+ import { GL } from '@luma.gl/constants';
4
+ // Mercator constants
5
+ const TILE_SIZE = 512;
6
+ const DEGREES_TO_RADIANS = Math.PI / 180;
7
+ // Create an interleaved deck instance.
8
+ export function getDeckInstance({ map, gl, deck }) {
9
+ // Only create one deck instance per context
10
+ if (map.__deck) {
11
+ return map.__deck;
12
+ }
13
+ // Only initialize certain props once per context
14
+ const customRender = deck?.props._customRender;
15
+ const onLoad = deck?.props.onLoad;
16
+ const deckProps = getInterleavedProps({
17
+ ...deck?.props,
18
+ _customRender: () => {
19
+ map.triggerRepaint();
20
+ // customRender may be subscribed by DeckGL React component to update child props
21
+ // make sure it is still called
22
+ // Hack - do not pass a redraw reason here to prevent the React component from clearing the context
23
+ // Rerender will be triggered by MapboxLayer's render()
24
+ customRender?.('');
25
+ }
26
+ });
27
+ let deckInstance;
28
+ if (!deck || deck.props.gl === gl) {
29
+ // If deck isn't defined (Internal MapboxLayer use case),
30
+ // or if deck is defined and is using the WebGLContext created by mapbox (MapboxOverlay and External MapboxLayer use case),
31
+ // block deck from setting the canvas size, and use the map's viewState to drive deck.
32
+ // Otherwise, we use deck's viewState to drive the map.
33
+ Object.assign(deckProps, {
34
+ gl,
35
+ width: null,
36
+ height: null,
37
+ touchAction: 'unset',
38
+ viewState: getViewState(map)
39
+ });
40
+ if (deck?.isInitialized) {
41
+ watchMapMove(deck, map);
42
+ }
43
+ else {
44
+ deckProps.onLoad = () => {
45
+ onLoad?.();
46
+ watchMapMove(deckInstance, map);
47
+ };
48
+ }
49
+ }
50
+ if (deck) {
51
+ deckInstance = deck;
52
+ deck.setProps(deckProps);
53
+ deck.userData.isExternal = true;
54
+ }
55
+ else {
56
+ deckInstance = new Deck(deckProps);
57
+ map.on('remove', () => {
58
+ removeDeckInstance(map);
59
+ });
60
+ }
61
+ deckInstance.userData.mapboxLayers = new Set();
62
+ // (deckInstance.userData as UserData).mapboxVersion = getMapboxVersion(map);
63
+ map.__deck = deckInstance;
64
+ map.on('render', () => {
65
+ if (deckInstance.isInitialized)
66
+ afterRender(deckInstance, map);
67
+ });
68
+ return deckInstance;
69
+ }
70
+ function watchMapMove(deck, map) {
71
+ const _handleMapMove = () => {
72
+ if (deck.isInitialized) {
73
+ // call view state methods
74
+ onMapMove(deck, map);
75
+ }
76
+ else {
77
+ // deregister itself when deck is finalized
78
+ map.off('move', _handleMapMove);
79
+ }
80
+ };
81
+ map.on('move', _handleMapMove);
82
+ }
83
+ export function removeDeckInstance(map) {
84
+ map.__deck?.finalize();
85
+ map.__deck = null;
86
+ }
87
+ export function getInterleavedProps(currProps) {
88
+ const nextProps = {
89
+ ...currProps,
90
+ // TODO: import these defaults from a single source of truth
91
+ parameters: {
92
+ depthMask: true,
93
+ depthTest: true,
94
+ blend: true,
95
+ blendFunc: [770, 771, 1, 771],
96
+ polygonOffsetFill: true,
97
+ depthFunc: 515,
98
+ blendEquation: 32774,
99
+ ...currProps.parameters
100
+ },
101
+ views: currProps.views || [new MapView({ id: 'mapbox' })]
102
+ };
103
+ return nextProps;
104
+ }
105
+ export function addLayer(deck, layer) {
106
+ deck.userData.mapboxLayers.add(layer);
107
+ updateLayers(deck);
108
+ }
109
+ export function removeLayer(deck, layer) {
110
+ deck.userData.mapboxLayers.delete(layer);
111
+ updateLayers(deck);
112
+ }
113
+ export function updateLayer(deck, layer) {
114
+ updateLayers(deck);
115
+ }
116
+ export function drawLayer(deck, map, layer) {
117
+ let { currentViewport } = deck.userData;
118
+ let clearStack = false;
119
+ if (!currentViewport) {
120
+ // This is the first layer drawn in this render cycle.
121
+ // Generate viewport from the current map state.
122
+ currentViewport = getViewport(deck, map, true);
123
+ deck.userData.currentViewport = currentViewport;
124
+ clearStack = true;
125
+ }
126
+ if (!deck.isInitialized) {
127
+ return;
128
+ }
129
+ deck._drawLayers('mapbox-repaint', {
130
+ viewports: [currentViewport],
131
+ layerFilter: ({ layer: deckLayer }) => layer.id === deckLayer.id || deckLayer.props.operation.includes('terrain'),
132
+ clearStack,
133
+ clearCanvas: false
134
+ });
135
+ }
136
+ export function getViewState(map) {
137
+ const { lng, lat } = map.getCenter();
138
+ const viewState = {
139
+ // Longitude returned by getCenter can be outside of [-180, 180] when zooming near the anti meridian
140
+ // https://github.com/visgl/deck.gl/issues/6894
141
+ longitude: ((lng + 540) % 360) - 180,
142
+ latitude: lat,
143
+ zoom: map.getZoom(),
144
+ bearing: map.getBearing(),
145
+ pitch: map.getPitch(),
146
+ padding: map.getPadding(),
147
+ repeat: map.getRenderWorldCopies()
148
+ };
149
+ if (map.getTerrain?.()) {
150
+ // When the base map has terrain, we need to target the camera at the terrain surface
151
+ centerCameraOnTerrain(map, viewState);
152
+ }
153
+ return viewState;
154
+ }
155
+ function centerCameraOnTerrain(map, viewState) {
156
+ if (map.getFreeCameraOptions) {
157
+ // mapbox-gl v2
158
+ const { position } = map.getFreeCameraOptions();
159
+ if (!position || position.z === undefined) {
160
+ return;
161
+ }
162
+ // @ts-ignore transform is not typed
163
+ const height = map.transform.height;
164
+ const { longitude, latitude, pitch } = viewState;
165
+ // Convert mapbox mercator coordinate to deck common space
166
+ const cameraX = position.x * TILE_SIZE;
167
+ const cameraY = (1 - position.y) * TILE_SIZE;
168
+ const cameraZ = position.z * TILE_SIZE;
169
+ // Mapbox manipulates zoom in terrain mode, see discussion here: https://github.com/mapbox/mapbox-gl-js/issues/12040
170
+ const center = lngLatToWorld([longitude, latitude]);
171
+ const dx = cameraX - center[0];
172
+ const dy = cameraY - center[1];
173
+ const cameraToCenterDistanceGround = Math.sqrt(dx * dx + dy * dy);
174
+ const pitchRadians = pitch * DEGREES_TO_RADIANS;
175
+ const altitudePixels = 1.5 * height;
176
+ const scale = pitchRadians < 0.001
177
+ ? // Pitch angle too small to deduce the look at point, assume elevation is 0
178
+ (altitudePixels * Math.cos(pitchRadians)) / cameraZ
179
+ : (altitudePixels * Math.sin(pitchRadians)) / cameraToCenterDistanceGround;
180
+ viewState.zoom = Math.log2(scale);
181
+ const cameraZFromSurface = (altitudePixels * Math.cos(pitchRadians)) / scale;
182
+ const surfaceElevation = cameraZ - cameraZFromSurface;
183
+ viewState.position = [0, 0, surfaceElevation / unitsPerMeter(latitude)];
184
+ }
185
+ // @ts-ignore transform is not typed
186
+ else if (typeof map.transform.elevation === 'number') {
187
+ // maplibre-gl
188
+ // @ts-ignore transform is not typed
189
+ viewState.position = [0, 0, map.transform.elevation];
190
+ }
191
+ }
192
+ // function getMapboxVersion(map: Map): {minor: number; major: number} {
193
+ // // parse mapbox version string
194
+ // let major = 0;
195
+ // let minor = 0;
196
+ // // @ts-ignore (2339) undefined property
197
+ // const version: string = map.version;
198
+ // if (version) {
199
+ // [major, minor] = version.split('.').slice(0, 2).map(Number);
200
+ // }
201
+ // return {major, minor};
202
+ // }
203
+ function getViewport(deck, map, useMapboxProjection = true) {
204
+ return new WebMercatorViewport({
205
+ id: 'mapbox',
206
+ x: 0,
207
+ y: 0,
208
+ width: deck.width,
209
+ height: deck.height,
210
+ ...getViewState(map),
211
+ nearZMultiplier: useMapboxProjection
212
+ ? // match mapbox-gl@>=1.3.0's projection matrix
213
+ 0.02
214
+ : // use deck.gl's own default
215
+ 0.1,
216
+ nearZ: map.transform._nearZ / map.transform.height,
217
+ farZ: map.transform._farZ / map.transform.height
218
+ });
219
+ }
220
+ function afterRender(deck, map) {
221
+ const { mapboxLayers, isExternal } = deck.userData;
222
+ if (isExternal) {
223
+ // Draw non-Mapbox layers
224
+ const mapboxLayerIds = Array.from(mapboxLayers, layer => layer.id);
225
+ const deckLayers = flatten(deck.props.layers, Boolean);
226
+ const hasNonMapboxLayers = deckLayers.some(layer => layer && !mapboxLayerIds.includes(layer.id));
227
+ let viewports = deck.getViewports();
228
+ const mapboxViewportIdx = viewports.findIndex(vp => vp.id === 'mapbox');
229
+ const hasNonMapboxViews = viewports.length > 1 || mapboxViewportIdx < 0;
230
+ if (hasNonMapboxLayers || hasNonMapboxViews) {
231
+ if (mapboxViewportIdx >= 0) {
232
+ viewports = viewports.slice();
233
+ viewports[mapboxViewportIdx] = getViewport(deck, map, false);
234
+ }
235
+ deck._drawLayers('mapbox-repaint', {
236
+ viewports,
237
+ layerFilter: params => (!deck.props.layerFilter || deck.props.layerFilter(params)) &&
238
+ (params.viewport.id !== 'mapbox' || !mapboxLayerIds.includes(params.layer.id)),
239
+ clearCanvas: false
240
+ });
241
+ }
242
+ }
243
+ // End of render cycle, clear generated viewport
244
+ deck.userData.currentViewport = null;
245
+ }
246
+ function onMapMove(deck, map) {
247
+ deck.setProps({
248
+ viewState: getViewState(map)
249
+ });
250
+ // Camera changed, will trigger a map repaint right after this
251
+ // Clear any change flag triggered by setting viewState so that deck does not request
252
+ // a second repaint
253
+ deck.needsRedraw({ clearRedrawFlags: true });
254
+ }
255
+ function updateLayers(deck) {
256
+ if (deck.userData.isExternal) {
257
+ return;
258
+ }
259
+ const layers = [];
260
+ deck.userData.mapboxLayers.forEach(deckLayer => {
261
+ const LayerType = deckLayer.props.type;
262
+ const layer = new LayerType(deckLayer.props);
263
+ layers.push(layer);
264
+ });
265
+ deck.setProps({ layers });
266
+ }