@deck.gl-community/layers 0.0.0 → 9.0.2

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 (39) hide show
  1. package/dist/index.cjs +493 -403
  2. package/dist/index.cjs.map +7 -0
  3. package/dist/index.d.ts +6 -0
  4. package/dist/index.js +6 -5
  5. package/dist/path-marker-layer/arrow-2d-geometry.d.ts +4 -0
  6. package/dist/path-marker-layer/arrow-2d-geometry.js +58 -0
  7. package/dist/path-marker-layer/create-path-markers.d.ts +18 -0
  8. package/dist/path-marker-layer/create-path-markers.js +78 -0
  9. package/dist/path-marker-layer/path-marker-layer.d.ts +40 -0
  10. package/dist/path-marker-layer/path-marker-layer.js +124 -0
  11. package/dist/path-marker-layer/polyline.d.ts +18 -0
  12. package/dist/path-marker-layer/polyline.js +40 -0
  13. package/dist/path-outline-layer/outline.d.ts +8 -0
  14. package/dist/path-outline-layer/outline.js +100 -0
  15. package/dist/path-outline-layer/path-outline-layer.d.ts +34 -0
  16. package/dist/path-outline-layer/path-outline-layer.js +116 -0
  17. package/dist/tile-source-layer/tile-source-layer.d.ts +43 -0
  18. package/dist/tile-source-layer/tile-source-layer.js +109 -0
  19. package/package.json +33 -20
  20. package/src/index.ts +8 -5
  21. package/src/path-marker-layer/arrow-2d-geometry.ts +65 -0
  22. package/src/path-marker-layer/create-path-markers.ts +122 -0
  23. package/src/path-marker-layer/path-marker-layer.ts +183 -0
  24. package/src/path-marker-layer/polyline.ts +44 -0
  25. package/src/path-outline-layer/outline.ts +107 -0
  26. package/src/path-outline-layer/path-outline-layer.ts +159 -0
  27. package/src/{tile-source-layer.ts → tile-source-layer/tile-source-layer.ts} +34 -26
  28. package/dist/data-driven-tile-3d-layer/data-driven-tile-3d-layer.js +0 -193
  29. package/dist/data-driven-tile-3d-layer/data-driven-tile-3d-layer.js.map +0 -1
  30. package/dist/data-driven-tile-3d-layer/utils/colorize-tile.js +0 -31
  31. package/dist/data-driven-tile-3d-layer/utils/colorize-tile.js.map +0 -1
  32. package/dist/data-driven-tile-3d-layer/utils/filter-tile.js +0 -146
  33. package/dist/data-driven-tile-3d-layer/utils/filter-tile.js.map +0 -1
  34. package/dist/index.js.map +0 -1
  35. package/dist/tile-source-layer.js +0 -112
  36. package/dist/tile-source-layer.js.map +0 -1
  37. package/src/data-driven-tile-3d-layer/data-driven-tile-3d-layer.ts +0 -257
  38. package/src/data-driven-tile-3d-layer/utils/colorize-tile.ts +0 -49
  39. package/src/data-driven-tile-3d-layer/utils/filter-tile.ts +0 -175
@@ -1,257 +0,0 @@
1
- import {Tile3DLayer, Tile3DLayerProps} from '@deck.gl/geo-layers/typed';
2
- import {UpdateParameters, Viewport, DefaultProps} from '@deck.gl/core/typed';
3
- import {TILE_TYPE, Tile3D, Tileset3D} from '@loaders.gl/tiles';
4
- import {load} from '@loaders.gl/core';
5
-
6
- const defaultProps: DefaultProps<DataDrivenTile3DLayerProps> = {
7
- colorsByAttribute: null,
8
- filtersByAttribute: null
9
- };
10
-
11
- type DataDrivenTile3DLayerProps<DataT = any> = _DataDrivenTile3DLayerProps &
12
- Tile3DLayerProps<DataT>;
13
-
14
- type _DataDrivenTile3DLayerProps = {
15
- onTraversalComplete?: (selectedTiles: Tile3D[]) => Tile3D[];
16
- colorsByAttribute?: ColorsByAttribute | null;
17
- customizeColors?: (
18
- tile: Tile3D,
19
- colorsByAttribute: ColorsByAttribute | null
20
- ) => Promise<{isColored: boolean; id: string}>;
21
- filtersByAttribute?: FiltersByAttribute | null;
22
- filterTile?: (
23
- tile: Tile3D,
24
- filtersByAttribute: FiltersByAttribute | null
25
- ) => Promise<{isFiltered: boolean; id: string}>;
26
- };
27
-
28
- export type ColorsByAttribute = {
29
- /** Feature attribute name */
30
- attributeName: string;
31
- /** Minimum attribute value */
32
- minValue: number;
33
- /** Maximum attribute value */
34
- maxValue: number;
35
- /** Minimum color. 3DObject will be colorized with gradient from `minColor to `maxColor` */
36
- minColor: [number, number, number, number];
37
- /** Maximum color. 3DObject will be colorized with gradient from `minColor to `maxColor` */
38
- maxColor: [number, number, number, number];
39
- /** Colorization mode. `replace` - replace vertex colors with a new colors, `multiply` - multiply vertex colors with new colors */
40
- mode: string;
41
- };
42
-
43
- export type FiltersByAttribute = {
44
- /** Feature attribute name */
45
- attributeName: string;
46
- /** Filter value */
47
- value: number;
48
- };
49
-
50
- //@ts-expect-error call of private method of the base class
51
- export class DataDrivenTile3DLayer<DataT = any, ExtraProps extends {} = {}> extends Tile3DLayer<
52
- DataT,
53
- Required<_DataDrivenTile3DLayerProps> & ExtraProps
54
- > {
55
- static layerName = 'DataDrivenTile3DLayer';
56
- static defaultProps = defaultProps as any;
57
-
58
- state!: {
59
- activeViewports: any;
60
- frameNumber?: number;
61
- lastUpdatedViewports: {[viewportId: string]: Viewport} | null;
62
- layerMap: {[layerId: string]: any};
63
- tileset3d: Tileset3D | null;
64
-
65
- colorsByAttribute: ColorsByAttribute | null;
66
- filtersByAttribute: FiltersByAttribute | null;
67
- loadingCounter: number;
68
- };
69
-
70
- initializeState() {
71
- super.initializeState();
72
-
73
- this.setState({
74
- colorsByAttribute: this.props.colorsByAttribute,
75
- filtersByAttribute: this.props.filtersByAttribute,
76
- loadingCounter: 0
77
- });
78
- }
79
-
80
- updateState(params: UpdateParameters<this>): void {
81
- const {props, oldProps, changeFlags} = params;
82
-
83
- if (props.data && props.data !== oldProps.data) {
84
- this._loadTileset(props.data);
85
- } else if (props.colorsByAttribute !== oldProps.colorsByAttribute) {
86
- this.setState({
87
- colorsByAttribute: props.colorsByAttribute
88
- });
89
- this._colorizeTileset();
90
- } else if (props.filtersByAttribute !== oldProps.filtersByAttribute) {
91
- this.setState({
92
- filtersByAttribute: props.filtersByAttribute
93
- });
94
- this._filterTileset();
95
- } else if (changeFlags.viewportChanged) {
96
- const {activeViewports} = this.state;
97
- const viewportsNumber = Object.keys(activeViewports).length;
98
- if (viewportsNumber) {
99
- if (!this.state.loadingCounter) {
100
- //@ts-expect-error call of private method of the base class
101
- super._updateTileset(activeViewports);
102
- }
103
- this.state.lastUpdatedViewports = activeViewports;
104
- this.state.activeViewports = {};
105
- }
106
- } else {
107
- super.updateState(params);
108
- }
109
- }
110
-
111
- private override async _loadTileset(tilesetUrl) {
112
- const {loadOptions = {}} = this.props;
113
-
114
- // TODO: deprecate `loader` in v9.0
115
- let loader = this.props.loader || this.props.loaders;
116
- if (Array.isArray(loader)) {
117
- loader = loader[0];
118
- }
119
-
120
- const options = {loadOptions: {...loadOptions}};
121
- if (loader.preload) {
122
- const preloadOptions = await loader.preload(tilesetUrl, loadOptions);
123
-
124
- if (preloadOptions.headers) {
125
- options.loadOptions.fetch = {
126
- ...options.loadOptions.fetch,
127
- headers: preloadOptions.headers
128
- };
129
- }
130
- Object.assign(options, preloadOptions);
131
- }
132
- //@ts-expect-error loader
133
- const tilesetJson = await load(tilesetUrl, loader, options.loadOptions);
134
-
135
- const tileset3d = new Tileset3D(tilesetJson, {
136
- onTileLoad: this._onTileLoad.bind(this),
137
- //@ts-expect-error call of private method of the base class
138
- onTileUnload: super._onTileUnload.bind(this),
139
- onTileError: this.props.onTileError,
140
- // New code ------------------
141
- onTraversalComplete: this._onTraversalComplete.bind(this),
142
- // ---------------------------
143
- ...options
144
- });
145
-
146
- this.setState({
147
- tileset3d,
148
- layerMap: {}
149
- });
150
-
151
- //@ts-expect-error call of private method of the base class
152
- super._updateTileset(this.state.activeViewports);
153
- this.props.onTilesetLoad(tileset3d);
154
- }
155
-
156
- private override _onTileLoad(tileHeader: Tile3D): void {
157
- const {lastUpdatedViewports} = this.state;
158
- // New code ------------------
159
- this._colorizeTiles([tileHeader]);
160
- this._filterTiles([tileHeader]);
161
- // ---------------------------
162
- this.props.onTileLoad(tileHeader);
163
- // New code ------------------ condition is added
164
- if (!this.state.colorsByAttribute && !this.state.filtersByAttribute) {
165
- // ---------------------------
166
- //@ts-expect-error call of private method of the base class
167
- super._updateTileset(lastUpdatedViewports);
168
- this.setNeedsUpdate();
169
- // New code ------------------
170
- }
171
- // ------------------
172
- }
173
-
174
- private _onTraversalComplete(selectedTiles: Tile3D[]): Tile3D[] {
175
- this._colorizeTiles(selectedTiles);
176
- this._filterTiles(selectedTiles);
177
- return this.props.onTraversalComplete
178
- ? this.props.onTraversalComplete(selectedTiles)
179
- : selectedTiles;
180
- }
181
-
182
- private _colorizeTiles(tiles: Tile3D[]): void {
183
- if (this.props.customizeColors && tiles[0]?.type === TILE_TYPE.MESH) {
184
- const {layerMap, colorsByAttribute} = this.state;
185
- const promises: Promise<{isColored: boolean; id: string}>[] = [];
186
- for (const tile of tiles) {
187
- promises.push(this.props.customizeColors(tile, colorsByAttribute));
188
- }
189
- this.setState({
190
- loadingCounter: this.state.loadingCounter + 1
191
- });
192
- Promise.allSettled(promises).then((result) => {
193
- this.setState({
194
- loadingCounter: this.state.loadingCounter - 1
195
- });
196
- let isTileChanged = false;
197
- for (const item of result) {
198
- if (item.status === 'fulfilled' && item.value.isColored) {
199
- isTileChanged = true;
200
- delete layerMap[item.value.id];
201
- }
202
- }
203
- if (isTileChanged && !this.state.loadingCounter) {
204
- //@ts-expect-error call of private method of the base class
205
- super._updateTileset(this.state.activeViewports);
206
- this.setNeedsUpdate();
207
- }
208
- });
209
- }
210
- }
211
-
212
- private _colorizeTileset(): void {
213
- const {tileset3d} = this.state;
214
-
215
- if (tileset3d) {
216
- this._colorizeTiles(tileset3d.selectedTiles);
217
- }
218
- }
219
-
220
- private _filterTiles(tiles: Tile3D[]): void {
221
- if (this.props.filterTile && tiles[0]?.type === TILE_TYPE.MESH) {
222
- const {layerMap, filtersByAttribute} = this.state;
223
- const promises: Promise<{isFiltered: boolean; id: string}>[] = [];
224
- for (const tile of tiles) {
225
- promises.push(this.props.filterTile(tile, filtersByAttribute));
226
- }
227
- this.setState({
228
- loadingCounter: this.state.loadingCounter + 1
229
- });
230
- Promise.allSettled(promises).then((result) => {
231
- this.setState({
232
- loadingCounter: this.state.loadingCounter - 1
233
- });
234
- let isTileChanged = false;
235
- for (const item of result) {
236
- if (item.status === 'fulfilled' && item.value.isFiltered) {
237
- isTileChanged = true;
238
- delete layerMap[item.value.id];
239
- }
240
- }
241
- if (isTileChanged && !this.state.loadingCounter) {
242
- //@ts-expect-error call of private method of the base class
243
- super._updateTileset(this.state.activeViewports);
244
- this.setNeedsUpdate();
245
- }
246
- });
247
- }
248
- }
249
-
250
- private _filterTileset(): void {
251
- const {tileset3d} = this.state;
252
-
253
- if (tileset3d) {
254
- this._filterTiles(tileset3d.selectedTiles);
255
- }
256
- }
257
- }
@@ -1,49 +0,0 @@
1
- import {customizeColors} from '@loaders.gl/i3s';
2
- import {Tile3D} from '@loaders.gl/tiles';
3
- import {ColorsByAttribute} from '../data-driven-tile-3d-layer';
4
-
5
- /**
6
- * Update tile colors with the custom colors assigned to the I3S Loader
7
- * @returns {Promise<{isColored: boolean; id: string}>} Result of the tile colorization - isColored: true/false and tile id
8
- */
9
- export const colorizeTile = async (
10
- tile: Tile3D,
11
- colorsByAttribute: ColorsByAttribute | null
12
- ): Promise<{isColored: boolean; id: string}> => {
13
- const result = {isColored: false, id: tile.id};
14
-
15
- if (tile.content.customColors !== colorsByAttribute) {
16
- if (tile.content && colorsByAttribute) {
17
- if (!tile.content.originalColorsAttributes) {
18
- tile.content.originalColorsAttributes = {
19
- ...tile.content.attributes.colors,
20
- value: new Uint8Array(tile.content.attributes.colors.value)
21
- };
22
- } else if (colorsByAttribute.mode === 'multiply') {
23
- tile.content.attributes.colors.value.set(tile.content.originalColorsAttributes.value);
24
- }
25
-
26
- tile.content.customColors = colorsByAttribute;
27
-
28
- const newColors = await customizeColors(
29
- tile.content.attributes.colors,
30
- tile.content.featureIds,
31
- tile.header.attributeUrls,
32
- tile.tileset.tileset.fields,
33
- tile.tileset.tileset.attributeStorageInfo,
34
- colorsByAttribute,
35
- (tile.tileset.loadOptions as any).i3s.token
36
- );
37
- // Make sure custom colors is not changed during async customizeColors execution
38
- if (tile.content.customColors === colorsByAttribute) {
39
- tile.content.attributes.colors = newColors;
40
- result.isColored = true;
41
- }
42
- } else if (tile.content && tile.content.originalColorsAttributes) {
43
- tile.content.attributes.colors.value = tile.content.originalColorsAttributes.value;
44
- tile.content.customColors = null;
45
- result.isColored = true;
46
- }
47
- }
48
- return result;
49
- };
@@ -1,175 +0,0 @@
1
- import {Tile3D} from '@loaders.gl/tiles';
2
- import {FiltersByAttribute} from '../data-driven-tile-3d-layer';
3
- import {AttributeStorageInfo, I3SAttributeLoader} from '@loaders.gl/i3s';
4
- import {load} from '@loaders.gl/core';
5
- import {TypedArray} from '@loaders.gl/schema';
6
-
7
- type I3STileAttributes = Record<string, string[] | TypedArray | null>;
8
-
9
- /**
10
- * Filter tile indices by attribute value
11
- * @param tile - tile to be filtered
12
- * @param filtersByAttribute - custom filters patameters
13
- * @returns {Promise<{isFiltered: boolean; id: string}>} Result of the tile filtering - isFiltered: true/false and tile id
14
- */
15
- export const filterTile = async (
16
- tile: Tile3D,
17
- filtersByAttribute: FiltersByAttribute | null
18
- ): Promise<{isFiltered: boolean; id: string}> => {
19
- const result = {isFiltered: false, id: tile.id};
20
-
21
- if (tile.content.userData?.customFilters !== filtersByAttribute) {
22
- if (tile.content && filtersByAttribute) {
23
- if (tile.content.userData?.originalIndices === undefined) {
24
- tile.content.userData = {};
25
- //save original indices for filtring cancellation
26
- tile.content.userData.originalIndices = tile.content.indices;
27
- }
28
- tile.content.indices = tile.content.userData?.originalIndices;
29
- tile.content.userData.customFilters = filtersByAttribute;
30
-
31
- const {indices} = await filterTileIndices(
32
- tile,
33
- filtersByAttribute,
34
- (tile.tileset.loadOptions as any).i3s.token
35
- );
36
- // Make sure custom filters is not changed during async filtring execution
37
- if (indices && tile.content.userData.customFilters === filtersByAttribute) {
38
- tile.content.indices = indices;
39
- result.isFiltered = true;
40
- }
41
- } else if (tile.content && tile.content.userData?.originalIndices !== undefined) {
42
- tile.content.indices = tile.content.userData.originalIndices;
43
- tile.content.userData.customFilters = null;
44
- result.isFiltered = true;
45
- }
46
- }
47
- return result;
48
- };
49
-
50
- async function filterTileIndices(
51
- tile: Tile3D,
52
- filtersByAttribute: FiltersByAttribute,
53
- token: string
54
- ): Promise<{success: boolean; indices?: Uint32Array}> {
55
- if (!filtersByAttribute.attributeName.length) {
56
- return {success: false};
57
- }
58
-
59
- const filterAttributeField = tile.tileset.tileset.fields.find(
60
- ({name}) => name === filtersByAttribute?.attributeName
61
- );
62
-
63
- if (
64
- !filterAttributeField ||
65
- !['esriFieldTypeDouble', 'esriFieldTypeInteger', 'esriFieldTypeSmallInteger'].includes(
66
- filterAttributeField.type
67
- )
68
- ) {
69
- return {success: false};
70
- }
71
-
72
- const tileFilterAttributeData = await loadFeatureAttributeData(
73
- filterAttributeField.name,
74
- tile.header.attributeUrls,
75
- tile.tileset.tileset.attributeStorageInfo,
76
- token
77
- );
78
- if (!tileFilterAttributeData) {
79
- return {success: false};
80
- }
81
-
82
- const objectIdField = tile.tileset.tileset.fields.find(({type}) => type === 'esriFieldTypeOID');
83
- if (!objectIdField) {
84
- return {success: false};
85
- }
86
-
87
- const objectIdAttributeData = await loadFeatureAttributeData(
88
- objectIdField.name,
89
- tile.header.attributeUrls,
90
- tile.tileset.tileset.attributeStorageInfo,
91
- token
92
- );
93
- if (!objectIdAttributeData) {
94
- return {success: false};
95
- }
96
-
97
- const attributeValuesMap = {};
98
- objectIdAttributeData[objectIdField.name]?.forEach((elem, index) => {
99
- attributeValuesMap[elem] =
100
- //@ts-expect-error possible null
101
- tileFilterAttributeData[filterAttributeField.name][index];
102
- });
103
-
104
- if (!tile.content.indices) {
105
- const triangles: number[] = [];
106
- for (let i = 0; i < tile.content.featureIds.length; i += 3) {
107
- if (attributeValuesMap[tile.content.featureIds[i]] === filtersByAttribute.value) {
108
- triangles.push(i);
109
- }
110
- }
111
-
112
- const indices = new Uint32Array(3 * triangles.length);
113
-
114
- triangles.forEach((vertex, index) => {
115
- indices[index * 3] = vertex;
116
- indices[index * 3 + 1] = vertex + 1;
117
- indices[index * 3 + 2] = vertex + 2;
118
- });
119
- return {success: true, indices};
120
- } else {
121
- const triangles: number[] = [];
122
- for (let i = 0; i < tile.content.indices.length; i += 3) {
123
- if (
124
- attributeValuesMap[tile.content.featureIds[tile.content.indices[i]]] ===
125
- filtersByAttribute.value
126
- ) {
127
- triangles.push(i);
128
- }
129
- }
130
-
131
- const indices = new Uint32Array(3 * triangles.length);
132
-
133
- triangles.forEach((vertex, index) => {
134
- indices[index * 3] = tile.content.indices[vertex];
135
- indices[index * 3 + 1] = tile.content.indices[vertex + 1];
136
- indices[index * 3 + 2] = tile.content.indices[vertex + 2];
137
- });
138
- return {success: true, indices};
139
- }
140
- }
141
-
142
- async function loadFeatureAttributeData(
143
- attributeName: string,
144
- attributeUrls: string[],
145
- attributesStorageInfo: AttributeStorageInfo[],
146
- token?: string
147
- ): Promise<I3STileAttributes | null> {
148
- const attributeIndex = attributesStorageInfo.findIndex(({name}) => attributeName === name);
149
- if (attributeIndex === -1) {
150
- return null;
151
- }
152
- const objectIdAttributeUrl = getUrlWithToken(attributeUrls[attributeIndex], token);
153
- const attributeType = getAttributeValueType(attributesStorageInfo[attributeIndex]);
154
- const objectIdAttributeData = await load(objectIdAttributeUrl, I3SAttributeLoader, {
155
- attributeName,
156
- attributeType
157
- });
158
-
159
- return objectIdAttributeData;
160
- }
161
-
162
- function getUrlWithToken(url: string, token: string | null = null): string {
163
- return token ? `${url}?token=${token}` : url;
164
- }
165
-
166
- function getAttributeValueType(attribute: AttributeStorageInfo) {
167
- // eslint-disable-next-line no-prototype-builtins
168
- if (attribute.hasOwnProperty('objectIds')) {
169
- return 'Oid32';
170
- // eslint-disable-next-line no-prototype-builtins
171
- } else if (attribute.hasOwnProperty('attributeValues')) {
172
- return attribute.attributeValues?.valueType;
173
- }
174
- return '';
175
- }