@tangram.gl/tangram-layers 0.0.0-stage → 0.0.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.
Files changed (43) hide show
  1. package/README.md +36 -2
  2. package/dist/experimental/projected-basemaps.js +1310 -0
  3. package/dist/experimental/projected-basemaps.js.map +6 -0
  4. package/dist/experimental/terrain.js +379 -0
  5. package/dist/experimental/terrain.js.map +6 -0
  6. package/dist/experimental/webxr.js +1423 -0
  7. package/dist/experimental/webxr.js.map +6 -0
  8. package/dist/index.js +756 -0
  9. package/dist/index.js.map +6 -0
  10. package/dist/types/experimental/projected-basemaps.d.ts +120 -0
  11. package/dist/types/experimental/projected-detail.d.ts +33 -0
  12. package/dist/types/experimental/projected-navigation.d.ts +117 -0
  13. package/dist/types/experimental/terrain-display.d.ts +124 -0
  14. package/dist/types/experimental/terrain.d.ts +131 -0
  15. package/dist/types/first_person_view_adapter.d.ts +29 -0
  16. package/dist/types/globe_view_adapter.d.ts +33 -0
  17. package/dist/types/index.d.ts +84 -0
  18. package/dist/types/tangram-layer-lifecycle.d.ts +132 -0
  19. package/dist/types/tangram-layer.d.ts +157 -0
  20. package/dist/types/view_adapter_types.d.ts +42 -0
  21. package/dist/types/web_mercator_view_adapter.d.ts +77 -0
  22. package/package.json +80 -3
  23. package/src/experimental/projected-basemaps.ts +301 -0
  24. package/src/experimental/projected-detail.ts +116 -0
  25. package/src/experimental/projected-navigation.ts +323 -0
  26. package/src/experimental/terrain-display.ts +243 -0
  27. package/src/experimental/terrain.ts +240 -0
  28. package/src/experimental/webxr/grabbing.ts +166 -0
  29. package/src/experimental/webxr/index.d.ts +77 -0
  30. package/src/experimental/webxr/index.ts +72 -0
  31. package/src/experimental/webxr/interaction.ts +221 -0
  32. package/src/experimental/webxr/picking.ts +119 -0
  33. package/src/experimental/webxr/presentation.ts +457 -0
  34. package/src/experimental/webxr/projection.ts +371 -0
  35. package/src/experimental/webxr/types.ts +221 -0
  36. package/src/experimental/webxr/views.ts +190 -0
  37. package/src/first_person_view_adapter.ts +107 -0
  38. package/src/globe_view_adapter.ts +103 -0
  39. package/src/index.ts +64 -0
  40. package/src/tangram-layer-lifecycle.ts +130 -0
  41. package/src/tangram-layer.ts +679 -0
  42. package/src/view_adapter_types.ts +40 -0
  43. package/src/web_mercator_view_adapter.ts +185 -0
@@ -0,0 +1,40 @@
1
+ // tangram-layers
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ /** deck.gl's planar camera surface, independent of concrete viewport subclasses. */
6
+ export interface PlanarCameraViewport {
7
+ longitude?: number;
8
+ latitude?: number;
9
+ zoom?: number;
10
+ pitch?: number;
11
+ height?: number;
12
+ isGeospatial?: boolean;
13
+ viewMatrix?: ArrayLike<number> | null;
14
+ projectionMatrix?: ArrayLike<number> | null;
15
+ distanceScales?: {unitsPerMeter?: ArrayLike<number>};
16
+ getDistanceScales?: () => {unitsPerMeter?: ArrayLike<number>};
17
+ }
18
+
19
+ /** Public methods required to derive a FirstPersonView ground footprint. */
20
+ export interface FirstPersonViewport extends PlanarCameraViewport {
21
+ width: number;
22
+ height: number;
23
+ position?: ArrayLike<number>;
24
+ unproject?: (pixel: number[], options?: {targetZ: number}) => number[];
25
+ projectFlat?: (coordinate: number[]) => number[];
26
+ unprojectFlat?: (coordinate: number[]) => number[];
27
+ }
28
+
29
+ /** Public GlobeView matrix and geographic-bounds contract. */
30
+ export interface GlobeViewport {
31
+ width: number;
32
+ height: number;
33
+ longitude: number;
34
+ latitude: number;
35
+ zoom: number;
36
+ viewMatrix?: ArrayLike<number>;
37
+ projectionMatrix?: ArrayLike<number>;
38
+ cameraPosition?: ArrayLike<number>;
39
+ getBounds?: (options: {z: number}) => unknown;
40
+ }
@@ -0,0 +1,185 @@
1
+ // tangram-layers
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {PROJECTION_CONSTANTS} from '@tangram.gl/tangram-renderer/core';
6
+
7
+ const DECK_TO_TANGRAM_ZOOM_OFFSET = 1;
8
+ const DECK_WORLD_SIZE = 512;
9
+ const TANGRAM_HALF_WORLD_METERS = Math.PI * PROJECTION_CONSTANTS.mercatorRadius;
10
+
11
+ type Matrix = ArrayLike<number>;
12
+
13
+ interface DistanceScales {
14
+ unitsPerMeter?: ArrayLike<number>;
15
+ }
16
+
17
+ interface WebMercatorViewport {
18
+ longitude?: number;
19
+ latitude?: number;
20
+ zoom?: number;
21
+ pitch?: number;
22
+ height?: number;
23
+ isGeospatial?: boolean;
24
+ viewMatrix?: Matrix | null;
25
+ projectionMatrix?: Matrix | null;
26
+ distanceScales?: DistanceScales;
27
+ getDistanceScales?: () => DistanceScales;
28
+ }
29
+
30
+ interface RenderDimensions {
31
+ width: number;
32
+ height: number;
33
+ }
34
+
35
+ interface TangramCameraFrame {
36
+ view: Float64Array;
37
+ projection: Float32Array;
38
+ position: [number, number, number];
39
+ }
40
+
41
+ /**
42
+ * Adapts deck.gl Web Mercator viewports to Tangram's host-frame contract.
43
+ *
44
+ * The adapter keeps deck-specific viewport validation and matrix conversion
45
+ * out of the layer lifecycle while preserving Tangram's EPSG:3857 meter frame.
46
+ */
47
+ export default class WebMercatorViewAdapter {
48
+ /**
49
+ * Checks that a deck viewport provides the public Web Mercator contract used
50
+ * by TangramLayer.
51
+ * @param viewport deck.gl viewport.
52
+ * @returns Validation error, or null when supported.
53
+ */
54
+ static validateViewport(viewport: WebMercatorViewport): Error | null {
55
+ if (viewport?.isGeospatial === false) {
56
+ return new Error('a Web Mercator viewport is required');
57
+ }
58
+ if (WebMercatorViewAdapter.validateGeographicAnchor(viewport, 'Web Mercator viewport')) {
59
+ return new Error('a Web Mercator viewport is required');
60
+ }
61
+ return null;
62
+ }
63
+
64
+ /**
65
+ * Validates the geographic anchor shared by all deck.gl view adapters.
66
+ * @param viewport deck.gl viewport.
67
+ * @param viewportName View name used in the error message.
68
+ * @returns Validation error, or null when the anchor is finite.
69
+ */
70
+ static validateGeographicAnchor(
71
+ viewport: WebMercatorViewport,
72
+ viewportName = 'viewport'
73
+ ): Error | null {
74
+ if (
75
+ !Number.isFinite(viewport?.longitude) ||
76
+ !Number.isFinite(viewport?.latitude) ||
77
+ !Number.isFinite(viewport?.zoom)
78
+ ) {
79
+ return new Error(`${viewportName} requires finite longitude, latitude, and zoom`);
80
+ }
81
+ return null;
82
+ }
83
+
84
+ /**
85
+ * Converts deck.gl camera matrices to Tangram camera matrices.
86
+ *
87
+ * Tangram tile models use absolute EPSG:3857 meters while deck matrices
88
+ * consume zoom-zero common coordinates. Altitude uses deck's
89
+ * latitude-dependent distance scale.
90
+ * @param viewport deck.gl WebMercatorViewport.
91
+ * @returns Tangram camera matrices and eye position.
92
+ */
93
+ static getCameraFrame(viewport: WebMercatorViewport): TangramCameraFrame {
94
+ const distanceScales =
95
+ typeof viewport.getDistanceScales === 'function'
96
+ ? viewport.getDistanceScales()
97
+ : viewport.distanceScales;
98
+ const unitsPerMeter = distanceScales && distanceScales.unitsPerMeter;
99
+ const viewMatrix = viewport.viewMatrix;
100
+ const projectionMatrix = viewport.projectionMatrix;
101
+ if (
102
+ !viewMatrix ||
103
+ viewMatrix.length !== 16 ||
104
+ !projectionMatrix ||
105
+ projectionMatrix.length !== 16 ||
106
+ !unitsPerMeter ||
107
+ !Number.isFinite(unitsPerMeter[2])
108
+ ) {
109
+ throw new Error('deck viewport camera matrices and distance scales are required');
110
+ }
111
+
112
+ const xyScale = DECK_WORLD_SIZE / (TANGRAM_HALF_WORLD_METERS * 2);
113
+ const metersToCommon = new Float64Array(16);
114
+ metersToCommon[0] = xyScale;
115
+ metersToCommon[5] = xyScale;
116
+ metersToCommon[10] = unitsPerMeter[2];
117
+ metersToCommon[12] = DECK_WORLD_SIZE / 2;
118
+ metersToCommon[13] = DECK_WORLD_SIZE / 2;
119
+ metersToCommon[15] = 1;
120
+
121
+ return {
122
+ view: multiplyMatrices(viewMatrix, metersToCommon),
123
+ projection: new Float32Array(projectionMatrix),
124
+ // The view matrix places the camera at the origin in eye coordinates.
125
+ position: [0, 0, 0]
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Builds Tangram's external-camera frame for a deck.gl MapView.
131
+ * @param viewport deck.gl WebMercatorViewport.
132
+ * @param dimensions Render-target size.
133
+ * @returns Tangram HostFrame legacy shape.
134
+ */
135
+ static getFrame(
136
+ viewport: WebMercatorViewport,
137
+ {width, height}: RenderDimensions
138
+ ): {
139
+ viewport: RenderDimensions;
140
+ view: {longitude: number; latitude: number; zoom: number};
141
+ projection: {type: 'web-mercator'};
142
+ camera: TangramCameraFrame;
143
+ tileBuffer: number;
144
+ } {
145
+ const longitude = viewport.longitude;
146
+ const latitude = viewport.latitude;
147
+ const zoom = viewport.zoom;
148
+ if (
149
+ typeof longitude !== 'number' ||
150
+ !Number.isFinite(longitude) ||
151
+ typeof latitude !== 'number' ||
152
+ !Number.isFinite(latitude) ||
153
+ typeof zoom !== 'number' ||
154
+ !Number.isFinite(zoom)
155
+ ) {
156
+ throw new Error('a Web Mercator viewport is required');
157
+ }
158
+ const pitch = (Math.abs(viewport.pitch || 0) * Math.PI) / 180;
159
+ return {
160
+ viewport: {width, height},
161
+ view: {
162
+ longitude,
163
+ latitude,
164
+ zoom: zoom + DECK_TO_TANGRAM_ZOOM_OFFSET
165
+ },
166
+ projection: {type: 'web-mercator'},
167
+ camera: WebMercatorViewAdapter.getCameraFrame(viewport),
168
+ tileBuffer: Math.min(4, Math.ceil((Math.tan(pitch) * (viewport.height || height)) / 256))
169
+ };
170
+ }
171
+ }
172
+
173
+ function multiplyMatrices(left: Matrix, right: Matrix): Float64Array {
174
+ const result = new Float64Array(16);
175
+ for (let column = 0; column < 4; column++) {
176
+ for (let row = 0; row < 4; row++) {
177
+ let value = 0;
178
+ for (let index = 0; index < 4; index++) {
179
+ value += left[index * 4 + row] * right[column * 4 + index];
180
+ }
181
+ result[column * 4 + row] = value;
182
+ }
183
+ }
184
+ return result;
185
+ }