@deck.gl/arcgis 9.0.0-beta.8 → 9.0.0

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.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Use deck.gl as a custom ArcGIS API for JavaScript layer",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
- "version": "9.0.0-beta.8",
6
+ "version": "9.0.0",
7
7
  "publishConfig": {
8
8
  "access": "public"
9
9
  },
@@ -36,14 +36,18 @@
36
36
  "prepublishOnly": "npm run build-bundle && npm run build-bundle -- --env=dev"
37
37
  },
38
38
  "dependencies": {
39
- "@luma.gl/constants": "9.0.0-beta.10",
39
+ "@luma.gl/constants": "^9.0.6",
40
+ "@luma.gl/webgl": "^9.0.6",
40
41
  "esri-loader": "^3.3.0"
41
42
  },
42
43
  "peerDependencies": {
43
44
  "@arcgis/core": "^4.0.0",
44
- "@deck.gl/core": "^9.0.0-beta",
45
- "@luma.gl/core": "9.0.0-beta.10",
46
- "@luma.gl/engine": "9.0.0-beta.10"
45
+ "@deck.gl/core": "^9.0.0",
46
+ "@luma.gl/core": "^9.0.0",
47
+ "@luma.gl/engine": "^9.0.0"
47
48
  },
48
- "gitHead": "8867a1047c2693d44e4af9507c296cf7ab61f9e8"
49
+ "devDependencies": {
50
+ "@arcgis/core": "^4.21.0"
51
+ },
52
+ "gitHead": "fcb5ccf0a899e651949b24986488211e278e9321"
49
53
  }
package/src/commons.ts CHANGED
@@ -1,15 +1,24 @@
1
1
  /* eslint-disable no-invalid-this */
2
2
 
3
- import type {Device} from '@luma.gl/core';
4
- import {Model} from '@luma.gl/engine';
3
+ import {GL} from '@luma.gl/constants';
4
+ import {Model, Geometry} from '@luma.gl/engine';
5
5
  import {Deck} from '@deck.gl/core';
6
- import {WebGLDevice} from '@luma.gl/webgl';
6
+ import type {Device, Texture, Framebuffer} from '@luma.gl/core';
7
+ import type {WebGLDevice} from '@luma.gl/webgl';
7
8
 
8
- export function initializeResources(device: Device) {
9
- // 'this' refers to the BaseLayerViewGL2D class from
10
- // import BaseLayerViewGL2D from "@arcgis/core/views/2d/layers/BaseLayerViewGL2D.js";
9
+ interface Renderer {
10
+ redraw: () => void;
11
+ }
12
+
13
+ export type RenderResources = {
14
+ deck: Deck;
15
+ texture: Texture;
16
+ model: Model;
17
+ fbo: Framebuffer;
18
+ };
11
19
 
12
- const deckglTexture = device.createTexture({
20
+ export function initializeResources(this: Renderer, device: Device): RenderResources {
21
+ const texture = device.createTexture({
13
22
  format: 'rgba8unorm',
14
23
  width: 1,
15
24
  height: 1,
@@ -21,18 +30,14 @@ export function initializeResources(device: Device) {
21
30
  }
22
31
  });
23
32
 
24
- this.deckglTexture = deckglTexture;
25
-
26
- this.buffer = device.createBuffer(new Int8Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1]));
27
-
28
- this.model = new Model(device, {
33
+ const model = new Model(device, {
29
34
  vs: `\
30
35
  #version 300 es
31
- in vec2 a_pos;
36
+ in vec2 pos;
32
37
  out vec2 v_texcoord;
33
38
  void main(void) {
34
- gl_Position = vec4(a_pos, 0.0, 1.0);
35
- v_texcoord = (a_pos + 1.0) / 2.0;
39
+ gl_Position = vec4(pos, 0.0, 1.0);
40
+ v_texcoord = (pos + 1.0) / 2.0;
36
41
  }
37
42
  `,
38
43
  fs: `\
@@ -48,30 +53,30 @@ void main(void) {
48
53
  fragColor = imageColor;
49
54
  }
50
55
  `,
51
- bufferLayout: [{name: 'a_pos', format: 'sint8x2'}],
52
56
  bindings: {
53
- deckglTexture
57
+ deckglTexture: texture
54
58
  },
55
59
  parameters: {
56
60
  depthWriteEnabled: true,
57
61
  depthCompare: 'less-equal'
58
62
  },
59
- attributes: {
60
- // eslint-disable-next-line camelcase
61
- a_pos: this.buffer
62
- },
63
- vertexCount: 6,
64
- topology: 'triangle-strip'
63
+ geometry: new Geometry({
64
+ topology: 'triangle-strip',
65
+ attributes: {
66
+ pos: {size: 2, value: new Int8Array([-1, -1, 1, -1, -1, 1, -1, 1, 1, 1, 1, -1])}
67
+ }
68
+ }),
69
+ vertexCount: 6
65
70
  });
66
71
 
67
- this.deckFbo = device.createFramebuffer({
72
+ const fbo = device.createFramebuffer({
68
73
  id: 'deckfbo',
69
74
  width: 1,
70
75
  height: 1,
71
- colorAttachments: [deckglTexture]
76
+ colorAttachments: [texture]
72
77
  });
73
78
 
74
- this.deckInstance = new Deck({
79
+ const deckInstance = new Deck({
75
80
  // The view state will be set dynamically to track the MapView current extent.
76
81
  viewState: {},
77
82
 
@@ -79,7 +84,7 @@ void main(void) {
79
84
  controller: false,
80
85
 
81
86
  // We use the same WebGL context as the ArcGIS API for JavaScript.
82
- gl: (device as WebGLDevice).gl,
87
+ device,
83
88
 
84
89
  // We need depth testing in general; we don't know what layers might be added to the deck.
85
90
  parameters: {
@@ -87,7 +92,7 @@ void main(void) {
87
92
  },
88
93
 
89
94
  // This deck renders into an auxiliary framebuffer.
90
- _framebuffer: this.deckFbo,
95
+ _framebuffer: fbo,
91
96
 
92
97
  // To disable canvas resizing, since the FBO is owned by the ArcGIS API for JavaScript.
93
98
  width: null,
@@ -95,34 +100,50 @@ void main(void) {
95
100
 
96
101
  _customRender: redrawReason => {
97
102
  if (redrawReason === 'arcgis') {
98
- this.deckInstance._drawLayers(redrawReason);
103
+ deckInstance._drawLayers(redrawReason);
99
104
  } else {
100
105
  this.redraw();
101
106
  }
102
107
  }
103
108
  });
109
+
110
+ return {deck: deckInstance, texture, fbo, model};
104
111
  }
105
112
 
106
- export function render({gl, width, height, viewState}) {
107
- const screenFbo = gl.getParameter(gl.FRAMEBUFFER_BINDING);
113
+ export function render(
114
+ resources: RenderResources,
115
+ viewport: {
116
+ width: number;
117
+ height: number;
118
+ longitude: number;
119
+ latitude: number;
120
+ zoom: number;
121
+ altitude?: number;
122
+ pitch: number;
123
+ bearing: number;
124
+ }
125
+ ) {
126
+ const {model, deck, fbo} = resources;
127
+ const device = model.device;
128
+ const screenFbo = (device as WebGLDevice).getParametersWebGL(GL.FRAMEBUFFER_BINDING);
129
+ const {width, height, ...viewState} = viewport;
108
130
 
109
131
  /* global window */
110
132
  const dpr = window.devicePixelRatio;
111
- width = Math.round(width * dpr);
112
- height = Math.round(height * dpr);
133
+ const pixelWidth = Math.round(width * dpr);
134
+ const pixelHeight = Math.round(height * dpr);
113
135
 
114
- this.deckFbo.resize({width, height});
136
+ fbo.resize({width: pixelWidth, height: pixelHeight});
115
137
 
116
- this.deckInstance.setProps({viewState});
138
+ deck.setProps({viewState});
117
139
  // redraw deck immediately into deckFbo
118
- this.deckInstance.redraw('arcgis');
140
+ deck.redraw('arcgis');
119
141
 
120
142
  // We overlay the texture on top of the map using the full-screen quad.
121
- const device: WebGLDevice = this.deckInstance.device;
122
143
 
123
144
  const textureToScreenPass = device.beginRenderPass({
124
145
  framebuffer: screenFbo,
125
- parameters: {viewport: [0, 0, width, height]},
146
+ parameters: {viewport: [0, 0, pixelWidth, pixelHeight]},
126
147
  clearColor: [0, 0, 0, 0],
127
148
  clearDepth: 1
128
149
  });
@@ -130,23 +151,17 @@ export function render({gl, width, height, viewState}) {
130
151
  device.withParametersWebGL(
131
152
  {
132
153
  blend: true,
133
- blendFunc: [gl.ONE, gl.ONE_MINUS_SRC_ALPHA]
154
+ blendFunc: [GL.ONE, GL.ONE_MINUS_SRC_ALPHA]
134
155
  },
135
156
  () => {
136
- this.model.setBindings({
137
- deckglTexture: this.deckFbo.colorAttachments[0]
138
- });
139
- this.model.draw(textureToScreenPass);
157
+ model.draw(textureToScreenPass);
140
158
  }
141
159
  );
142
160
  }
143
161
 
144
- export function finalizeResources() {
145
- this.deckInstance?.finalize();
146
- this.deckInstance = null;
147
-
148
- this.model?.delete();
149
- this.buffer?.delete();
150
- this.deckFbo?.delete();
151
- this.deckglTexture?.delete();
162
+ export function finalizeResources(resources: RenderResources) {
163
+ resources.deck.finalize();
164
+ resources.model.destroy();
165
+ resources.fbo.destroy();
166
+ resources.texture.destroy();
152
167
  }
@@ -4,10 +4,7 @@ import {initializeResources, render, finalizeResources} from './commons';
4
4
  export default function createDeckLayerView2D(BaseLayerViewGL2D) {
5
5
  return BaseLayerViewGL2D.createSubclass({
6
6
  properties: {
7
- deckgl: {},
8
- deckFbo: {},
9
- model: {},
10
- buffer: {}
7
+ resources: null
11
8
  },
12
9
 
13
10
  // Attach is called as soon as the layer view is ready to start rendering.
@@ -17,13 +14,13 @@ export default function createDeckLayerView2D(BaseLayerViewGL2D) {
17
14
  const gl = this.context;
18
15
  const device = WebGLDevice.attach(gl);
19
16
 
20
- initializeResources.call(this, device);
17
+ this.resources = initializeResources.call(this, device);
21
18
 
22
19
  // Update deck props
23
- this.layer.deck.on('change', props => this.deckInstance.setProps(props));
20
+ this.layer.deck.on('change', props => this.resources.deck.setProps(props));
24
21
 
25
22
  // We need to start drawing the deck.gl layer immediately.
26
- this.deckInstance.setProps(this.layer.deck.toJSON());
23
+ this.resources.deck.setProps(this.layer.deck.toJSON());
27
24
  },
28
25
 
29
26
  redraw() {
@@ -32,7 +29,8 @@ export default function createDeckLayerView2D(BaseLayerViewGL2D) {
32
29
 
33
30
  // Called when the layer must be destroyed.
34
31
  detach() {
35
- finalizeResources.call(this);
32
+ finalizeResources(this.resources);
33
+ this.resources = null;
36
34
  },
37
35
 
38
36
  // Called every time that the layer view must be rendered.
@@ -41,17 +39,14 @@ export default function createDeckLayerView2D(BaseLayerViewGL2D) {
41
39
  // The view state must be kept in-sync with the MapView of the ArcGIS API.
42
40
  const state = renderParameters.state;
43
41
 
44
- render.call(this, {
45
- gl: renderParameters.context,
42
+ render(this.resources, {
46
43
  width,
47
44
  height,
48
- viewState: {
49
- latitude: this.view.center.latitude,
50
- longitude: this.view.center.longitude,
51
- zoom: this.view.featuresTilingScheme.scaleToLevel(state.scale),
52
- bearing: -state.rotation,
53
- pitch: 0
54
- }
45
+ latitude: this.view.center.latitude,
46
+ longitude: this.view.center.longitude,
47
+ zoom: this.view.featuresTilingScheme.scaleToLevel(state.scale),
48
+ bearing: -state.rotation,
49
+ pitch: 0
55
50
  });
56
51
  }
57
52
  });
@@ -0,0 +1,65 @@
1
+ /* eslint-disable no-invalid-this */
2
+ import {WebGLDevice} from '@luma.gl/webgl';
3
+ import {initializeResources, render, finalizeResources, RenderResources} from './commons';
4
+
5
+ import SceneView from '@arcgis/core/views/SceneView';
6
+ import type {DeckProps} from '@deck.gl/core';
7
+
8
+ /** Convert ArcGIS FOV to WebMercatorViewport altitude */
9
+ function arcgisFOVToDeckAltitude(fov: number, aspectRatio: number): number {
10
+ // ArcGIS fov is corner-to-corner
11
+ const D = Math.sqrt(1 + aspectRatio ** 2);
12
+ const halfFOV = (fov / 2 / 180) * Math.PI;
13
+ return D / 2 / Math.tan(halfFOV);
14
+ }
15
+
16
+ export default function createDeckRenderer(DeckProps, externalRenderers) {
17
+ class DeckRenderer {
18
+ view: SceneView;
19
+ deck: any;
20
+ resources: RenderResources | null = null;
21
+
22
+ constructor(view: SceneView, props: DeckProps) {
23
+ this.view = view;
24
+ this.deck = new DeckProps(props);
25
+ }
26
+
27
+ setup(context) {
28
+ const gl = context.gl;
29
+ const device = WebGLDevice.attach(gl);
30
+ const resources = initializeResources.call(this, device);
31
+
32
+ this.deck.on('change', props => resources.deck.setProps(props));
33
+
34
+ resources.deck.setProps(this.deck.toJSON());
35
+ this.resources = resources;
36
+ }
37
+
38
+ dispose() {
39
+ if (this.resources) {
40
+ finalizeResources(this.resources);
41
+ }
42
+ }
43
+
44
+ redraw() {
45
+ externalRenderers.requestRender(this.view);
46
+ }
47
+
48
+ render() {
49
+ const [width, height] = this.view.size;
50
+
51
+ render(this.resources!, {
52
+ width,
53
+ height,
54
+ latitude: this.view.center.latitude,
55
+ longitude: this.view.center.longitude,
56
+ altitude: arcgisFOVToDeckAltitude(this.view.camera.fov, width / height),
57
+ zoom: this.view.zoom,
58
+ bearing: this.view.camera.heading,
59
+ pitch: this.view.camera.tilt
60
+ });
61
+ }
62
+ }
63
+
64
+ return DeckRenderer;
65
+ }
@@ -2,11 +2,20 @@ import createDeckProps from './deck-props';
2
2
  import createDeckLayer from './deck-layer';
3
3
  import createDeckLayerView2D from './deck-layer-view-2d';
4
4
  import createDeckRenderer from './deck-renderer';
5
- import {loadModules as esriLoaderLoadModules} from 'esri-loader';
5
+ import {loadModules as esriLoaderLoadModules, ILoadScriptOptions} from 'esri-loader';
6
6
 
7
- let arcGIS = null;
7
+ type LoadedModules = {
8
+ DeckLayer: any;
9
+ DeckRenderer: any;
10
+ modules?: unknown[];
11
+ };
8
12
 
9
- export async function loadArcGISModules(modules, loadScriptOptions) {
13
+ let arcGIS: LoadedModules;
14
+
15
+ export async function loadArcGISModules(
16
+ modules: string[],
17
+ loadScriptOptions: ILoadScriptOptions
18
+ ): Promise<LoadedModules> {
10
19
  const namespace = Array.isArray(modules) ? null : modules;
11
20
  await loadArcGISModule(namespace, loadScriptOptions);
12
21
 
@@ -18,7 +27,10 @@ export async function loadArcGISModules(modules, loadScriptOptions) {
18
27
  return arcGIS;
19
28
  }
20
29
 
21
- function loadArcGISModule(esri, loadScriptOptions) {
30
+ async function loadArcGISModule(
31
+ esri,
32
+ loadScriptOptions: ILoadScriptOptions
33
+ ): Promise<LoadedModules> {
22
34
  if (arcGIS) {
23
35
  // Already loaded
24
36
  return arcGIS;
@@ -34,7 +46,7 @@ function loadArcGISModule(esri, loadScriptOptions) {
34
46
  return initialize(Layer, Accessor, BaseLayerViewGL2D, externalRenderers);
35
47
  }
36
48
 
37
- return esriLoaderLoadModules(
49
+ const [Layer, Accessor, BaseLayerViewGL2D, externalRenderers] = await esriLoaderLoadModules(
38
50
  [
39
51
  'esri/layers/Layer',
40
52
  'esri/core/Accessor',
@@ -42,12 +54,11 @@ function loadArcGISModule(esri, loadScriptOptions) {
42
54
  'esri/views/3d/externalRenderers'
43
55
  ],
44
56
  loadScriptOptions
45
- ).then(([Layer, Accessor, BaseLayerViewGL2D, externalRenderers]) => {
46
- return initialize(Layer, Accessor, BaseLayerViewGL2D, externalRenderers);
47
- });
57
+ );
58
+ return initialize(Layer, Accessor, BaseLayerViewGL2D, externalRenderers);
48
59
  }
49
60
 
50
- function initialize(Layer, Accessor, BaseLayerViewGL2D, externalRenderers) {
61
+ function initialize(Layer, Accessor, BaseLayerViewGL2D, externalRenderers): LoadedModules {
51
62
  const DeckProps = createDeckProps(Accessor);
52
63
  const DeckLayerView2D = createDeckLayerView2D(BaseLayerViewGL2D);
53
64
  const DeckLayer = createDeckLayer(DeckProps, Layer, DeckLayerView2D);
@@ -1,56 +0,0 @@
1
- /* eslint-disable no-invalid-this */
2
-
3
- import {initializeResources, render, finalizeResources} from './commons';
4
-
5
- // ArcGIS fov is corner-to-corner
6
- function arcgisFOVToDeckAltitude(fov, aspectRatio) {
7
- const D = Math.sqrt(1 + aspectRatio ** 2);
8
- const halfFOV = (fov / 2 / 180) * Math.PI;
9
- return D / 2 / Math.tan(halfFOV);
10
- }
11
-
12
- export default function createDeckRenderer(DeckProps, externalRenderers) {
13
- class DeckRenderer {
14
- constructor(view, props) {
15
- this.view = view;
16
- this.deck = new DeckProps(props);
17
- }
18
-
19
- setup(context) {
20
- const gl = context.gl;
21
- initializeResources.call(this, gl);
22
-
23
- this.deck.on('change', props => this.deckInstance.setProps(props));
24
-
25
- this.deckInstance.setProps(this.deck.toJSON());
26
- }
27
-
28
- dispose() {
29
- finalizeResources.call(this);
30
- }
31
-
32
- redraw() {
33
- externalRenderers.requestRender(this.view);
34
- }
35
-
36
- render(context) {
37
- const [width, height] = this.view.size;
38
-
39
- render.call(this, {
40
- gl: context.gl,
41
- width,
42
- height,
43
- viewState: {
44
- latitude: this.view.center.latitude,
45
- longitude: this.view.center.longitude,
46
- altitude: arcgisFOVToDeckAltitude(this.view.camera.fov, width / height),
47
- zoom: this.view.zoom,
48
- bearing: this.view.camera.heading,
49
- pitch: this.view.camera.tilt
50
- }
51
- });
52
- }
53
- }
54
-
55
- return DeckRenderer;
56
- }
File without changes
File without changes
File without changes