@loaders.gl/i3s 3.3.0-alpha.2 → 3.3.0-alpha.4

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 (66) hide show
  1. package/dist/dist.min.js +273 -203
  2. package/dist/es5/arcgis-webscene-loader.js +1 -1
  3. package/dist/es5/i3s-attribute-loader.js +2 -1
  4. package/dist/es5/i3s-attribute-loader.js.map +1 -1
  5. package/dist/es5/i3s-building-scene-layer-loader.js +1 -1
  6. package/dist/es5/i3s-content-loader.js +4 -2
  7. package/dist/es5/i3s-content-loader.js.map +1 -1
  8. package/dist/es5/i3s-loader.js +3 -2
  9. package/dist/es5/i3s-loader.js.map +1 -1
  10. package/dist/es5/i3s-node-page-loader.js +1 -1
  11. package/dist/es5/index.js.map +1 -1
  12. package/dist/es5/lib/parsers/parse-i3s-tile-content.js +18 -12
  13. package/dist/es5/lib/parsers/parse-i3s-tile-content.js.map +1 -1
  14. package/dist/es5/lib/utils/customizeColors.js +213 -0
  15. package/dist/es5/lib/utils/customizeColors.js.map +1 -0
  16. package/dist/es5/types.js.map +1 -1
  17. package/dist/es5/workers/i3s-content-nodejs-worker.js +10 -0
  18. package/dist/es5/workers/i3s-content-nodejs-worker.js.map +1 -0
  19. package/dist/esm/arcgis-webscene-loader.js +1 -1
  20. package/dist/esm/i3s-attribute-loader.js +2 -2
  21. package/dist/esm/i3s-attribute-loader.js.map +1 -1
  22. package/dist/esm/i3s-building-scene-layer-loader.js +1 -1
  23. package/dist/esm/i3s-content-loader.js +3 -2
  24. package/dist/esm/i3s-content-loader.js.map +1 -1
  25. package/dist/esm/i3s-loader.js +3 -2
  26. package/dist/esm/i3s-loader.js.map +1 -1
  27. package/dist/esm/i3s-node-page-loader.js +1 -1
  28. package/dist/esm/index.js.map +1 -1
  29. package/dist/esm/lib/parsers/parse-i3s-tile-content.js +12 -11
  30. package/dist/esm/lib/parsers/parse-i3s-tile-content.js.map +1 -1
  31. package/dist/esm/lib/utils/customizeColors.js +108 -0
  32. package/dist/esm/lib/utils/customizeColors.js.map +1 -0
  33. package/dist/esm/types.js.map +1 -1
  34. package/dist/esm/workers/i3s-content-nodejs-worker.js +5 -0
  35. package/dist/esm/workers/i3s-content-nodejs-worker.js.map +1 -0
  36. package/dist/i3s-attribute-loader.d.ts +6 -0
  37. package/dist/i3s-attribute-loader.d.ts.map +1 -1
  38. package/dist/i3s-attribute-loader.js +2 -1
  39. package/dist/i3s-content-loader.d.ts.map +1 -1
  40. package/dist/i3s-content-loader.js +2 -1
  41. package/dist/i3s-content-nodejs-worker.js +200 -0
  42. package/dist/i3s-content-nodejs-worker.js.map +7 -0
  43. package/dist/i3s-content-worker.js +170 -23
  44. package/dist/i3s-loader.d.ts.map +1 -1
  45. package/dist/i3s-loader.js +2 -1
  46. package/dist/index.d.ts +1 -1
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/lib/parsers/parse-i3s-tile-content.d.ts.map +1 -1
  49. package/dist/lib/parsers/parse-i3s-tile-content.js +12 -11
  50. package/dist/lib/utils/customizeColors.d.ts +14 -0
  51. package/dist/lib/utils/customizeColors.d.ts.map +1 -0
  52. package/dist/lib/utils/customizeColors.js +89 -0
  53. package/dist/types.d.ts +52 -1
  54. package/dist/types.d.ts.map +1 -1
  55. package/dist/workers/i3s-content-nodejs-worker.d.ts +2 -0
  56. package/dist/workers/i3s-content-nodejs-worker.d.ts.map +1 -0
  57. package/dist/workers/i3s-content-nodejs-worker.js +6 -0
  58. package/package.json +11 -10
  59. package/src/i3s-attribute-loader.ts +1 -1
  60. package/src/i3s-content-loader.ts +2 -1
  61. package/src/i3s-loader.ts +2 -1
  62. package/src/index.ts +3 -1
  63. package/src/lib/parsers/parse-i3s-tile-content.ts +21 -13
  64. package/src/lib/utils/customizeColors.ts +129 -0
  65. package/src/types.ts +57 -1
  66. package/src/workers/i3s-content-nodejs-worker.ts +5 -0
@@ -0,0 +1,2 @@
1
+ import '@loaders.gl/polyfills';
2
+ //# sourceMappingURL=i3s-content-nodejs-worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i3s-content-nodejs-worker.d.ts","sourceRoot":"","sources":["../../src/workers/i3s-content-nodejs-worker.ts"],"names":[],"mappings":"AACA,OAAO,uBAAuB,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const loader_utils_1 = require("@loaders.gl/loader-utils");
4
+ require("@loaders.gl/polyfills");
5
+ const i3s_content_loader_1 = require("../i3s-content-loader");
6
+ (0, loader_utils_1.createLoaderWorker)(i3s_content_loader_1.I3SContentLoader);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loaders.gl/i3s",
3
- "version": "3.3.0-alpha.2",
3
+ "version": "3.3.0-alpha.4",
4
4
  "description": "i3s .",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -27,17 +27,18 @@
27
27
  "README.md"
28
28
  ],
29
29
  "scripts": {
30
- "pre-build": "npm run build-bundle && npm run build-worker",
30
+ "pre-build": "npm run build-bundle && npm run build-worker && npm run build-loader-worker-nodejs",
31
31
  "build-bundle": "esbuild src/bundle.ts --bundle --outfile=dist/dist.min.js",
32
- "build-worker": "esbuild src/workers/i3s-content-worker.ts --bundle --outfile=dist/i3s-content-worker.js --define:__VERSION__=\\\"$npm_package_version\\\""
32
+ "build-worker": "esbuild src/workers/i3s-content-worker.ts --bundle --outfile=dist/i3s-content-worker.js --define:__VERSION__=\\\"$npm_package_version\\\"",
33
+ "build-loader-worker-nodejs": "esbuild src/workers/i3s-content-nodejs-worker.ts --outfile=dist/i3s-content-nodejs-worker.js --platform=node --target=esnext,node12 --minify --bundle --sourcemap --define:__VERSION__=\\\"$npm_package_version\\\""
33
34
  },
34
35
  "dependencies": {
35
- "@loaders.gl/draco": "3.3.0-alpha.2",
36
- "@loaders.gl/images": "3.3.0-alpha.2",
37
- "@loaders.gl/loader-utils": "3.3.0-alpha.2",
38
- "@loaders.gl/schema": "3.3.0-alpha.2",
39
- "@loaders.gl/textures": "3.3.0-alpha.2",
40
- "@loaders.gl/tiles": "3.3.0-alpha.2",
36
+ "@loaders.gl/draco": "3.3.0-alpha.4",
37
+ "@loaders.gl/images": "3.3.0-alpha.4",
38
+ "@loaders.gl/loader-utils": "3.3.0-alpha.4",
39
+ "@loaders.gl/schema": "3.3.0-alpha.4",
40
+ "@loaders.gl/textures": "3.3.0-alpha.4",
41
+ "@loaders.gl/tiles": "3.3.0-alpha.4",
41
42
  "@luma.gl/constants": "^8.5.4",
42
43
  "@math.gl/core": "^3.5.1",
43
44
  "@math.gl/culling": "^3.5.1",
@@ -47,5 +48,5 @@
47
48
  "peerDependencies": {
48
49
  "@loaders.gl/core": "^3.2.0"
49
50
  },
50
- "gitHead": "628f1f0eed0f14b50ccff4c561023acf6e0657e6"
51
+ "gitHead": "d1c524fd3cb9296ecd1bf7d185765c4f6aaef6a1"
51
52
  }
@@ -87,7 +87,7 @@ function getAttributesData(tile) {
87
87
  * @param {Object} attribute
88
88
  * @returns {String}
89
89
  */
90
- function getAttributeValueType(attribute) {
90
+ export function getAttributeValueType(attribute) {
91
91
  if (attribute.hasOwnProperty('objectIds')) {
92
92
  return 'Oid32';
93
93
  } else if (attribute.hasOwnProperty('attributeValues')) {
@@ -1,3 +1,4 @@
1
+ import {isBrowser} from '@loaders.gl/worker-utils';
1
2
  import type {LoaderWithParser, LoaderContext} from '@loaders.gl/loader-utils';
2
3
  import type {I3SLoaderOptions} from './i3s-loader';
3
4
  import {parseI3STileContent} from './lib/parsers/parse-i3s-tile-content';
@@ -12,7 +13,7 @@ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'beta';
12
13
  */
13
14
  export const I3SContentLoader: LoaderWithParser = {
14
15
  name: 'I3S Content (Indexed Scene Layers)',
15
- id: 'i3s-content',
16
+ id: isBrowser ? 'i3s-content' : 'i3s-content-nodejs',
16
17
  module: 'i3s',
17
18
  worker: true,
18
19
  version: VERSION,
package/src/i3s-loader.ts CHANGED
@@ -41,7 +41,8 @@ export const I3SLoader: LoaderWithParser = {
41
41
  useDracoGeometry: true,
42
42
  useCompressedTextures: true,
43
43
  decodeTextures: true,
44
- coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS
44
+ coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS,
45
+ colorsByAttribute: null
45
46
  }
46
47
  }
47
48
  };
package/src/index.ts CHANGED
@@ -26,6 +26,8 @@ export type {
26
26
  I3SMaterialDefinition,
27
27
  TextureDefinitionInfo,
28
28
  MaterialDefinitionInfo,
29
- FullExtent
29
+ FullExtent,
30
+ StatisticsInfo,
31
+ StatsInfo
30
32
  } from './types';
31
33
  export {COORDINATE_SYSTEM} from './lib/parsers/constants';
@@ -22,6 +22,8 @@ import {
22
22
  import {getUrlWithToken} from '../utils/url-utils';
23
23
 
24
24
  import {GL_TYPE_MAP, getConstructorForDataFormat, sizeOf, COORDINATE_SYSTEM} from './constants';
25
+ import {I3SLoaderOptions} from '../../i3s-loader';
26
+ import {customizeColors} from '../utils/customizeColors';
25
27
 
26
28
  const scratchVector = new Vector3([0, 0, 0]);
27
29
 
@@ -41,17 +43,6 @@ function getLoaderForTextureFormat(textureFormat?: 'jpg' | 'png' | 'ktx-etc2' |
41
43
 
42
44
  const I3S_ATTRIBUTE_TYPE = 'i3s-attribute-type';
43
45
 
44
- const defaultContent: I3STileContent = {
45
- attributes: {},
46
- indices: null,
47
- featureIds: [],
48
- vertexCount: 0,
49
- modelMatrix: new Matrix4(),
50
- coordinateSystem: 0,
51
- byteLength: 0,
52
- texture: null
53
- };
54
-
55
46
  export async function parseI3STileContent(
56
47
  arrayBuffer: ArrayBuffer,
57
48
  tileOptions: I3STileOptions,
@@ -59,7 +50,16 @@ export async function parseI3STileContent(
59
50
  options?: LoaderOptions,
60
51
  context?: LoaderContext
61
52
  ): Promise<I3STileContent> {
62
- const content: I3STileContent = defaultContent;
53
+ const content: I3STileContent = {
54
+ attributes: {},
55
+ indices: null,
56
+ featureIds: [],
57
+ vertexCount: 0,
58
+ modelMatrix: new Matrix4(),
59
+ coordinateSystem: 0,
60
+ byteLength: 0,
61
+ texture: null
62
+ };
63
63
 
64
64
  if (tileOptions.textureUrl) {
65
65
  const url = getUrlWithToken(tileOptions.textureUrl, options?.i3s?.token);
@@ -112,7 +112,7 @@ async function parseI3SNodeGeometry(
112
112
  content: I3STileContent,
113
113
  tileOptions: I3STileOptions,
114
114
  tilesetOptions: I3STilesetOptions,
115
- options?: LoaderOptions
115
+ options?: I3SLoaderOptions
116
116
  ): Promise<I3STileContent> {
117
117
  const contentByteLength = arrayBuffer.byteLength;
118
118
  let attributes: I3SMeshAttributes;
@@ -201,6 +201,14 @@ async function parseI3SNodeGeometry(
201
201
  content.coordinateSystem = COORDINATE_SYSTEM.LNGLAT_OFFSETS;
202
202
  }
203
203
 
204
+ attributes.color = await customizeColors(
205
+ attributes.color,
206
+ attributes.id,
207
+ tileOptions,
208
+ tilesetOptions,
209
+ options
210
+ );
211
+
204
212
  content.attributes = {
205
213
  positions: attributes.position,
206
214
  normals: attributes.normal,
@@ -0,0 +1,129 @@
1
+ import type {MeshAttribute} from '@loaders.gl/schema';
2
+ import type {COLOR, I3STileOptions, I3STilesetOptions} from '../../types';
3
+
4
+ import {load} from '@loaders.gl/core';
5
+ import {getAttributeValueType, I3SAttributeLoader} from '../../i3s-attribute-loader';
6
+ import {I3SLoaderOptions} from '../../i3s-loader';
7
+ import {getUrlWithToken} from '../utils/url-utils';
8
+
9
+ /**
10
+ * Modify vertex colors array to visualize 3D objects in a attribute driven way
11
+ * @param colors - vertex colors attribute
12
+ * @param featureIds - feature Ids attribute
13
+ * @param tileOptions - tile - related options
14
+ * @param tilesetOptions - tileset-related options
15
+ * @param options - loader options
16
+ * @returns midified colors attribute
17
+ */
18
+ export async function customizeColors(
19
+ colors: MeshAttribute,
20
+ featureIds: MeshAttribute,
21
+ tileOptions: I3STileOptions,
22
+ tilesetOptions: I3STilesetOptions,
23
+ options?: I3SLoaderOptions
24
+ ): Promise<MeshAttribute> {
25
+ if (!options?.i3s?.colorsByAttribute) {
26
+ return colors;
27
+ }
28
+
29
+ const colorizeAttributeField = tilesetOptions.fields.find(
30
+ ({name}) => name === options?.i3s?.colorsByAttribute?.attributeName
31
+ );
32
+ if (
33
+ !colorizeAttributeField ||
34
+ !['esriFieldTypeDouble', 'esriFieldTypeInteger', 'esriFieldTypeSmallInteger'].includes(
35
+ colorizeAttributeField.type
36
+ )
37
+ ) {
38
+ return colors;
39
+ }
40
+
41
+ const colorizeAttributeData = await loadFeatureAttributeData(
42
+ colorizeAttributeField.name,
43
+ tileOptions,
44
+ tilesetOptions,
45
+ options
46
+ );
47
+ if (!colorizeAttributeData) {
48
+ return colors;
49
+ }
50
+
51
+ const objectIdField = tilesetOptions.fields.find(({type}) => type === 'esriFieldTypeOID');
52
+ if (!objectIdField) {
53
+ return colors;
54
+ }
55
+
56
+ const objectIdAttributeData = await loadFeatureAttributeData(
57
+ objectIdField.name,
58
+ tileOptions,
59
+ tilesetOptions,
60
+ options
61
+ );
62
+ if (!objectIdAttributeData) {
63
+ return colors;
64
+ }
65
+
66
+ const attributeValuesMap: {[key: number]: COLOR} = {};
67
+ for (let i = 0; i < objectIdAttributeData[objectIdField.name].length; i++) {
68
+ attributeValuesMap[objectIdAttributeData[objectIdField.name][i]] = calculateColorForAttribute(
69
+ colorizeAttributeData[colorizeAttributeField.name][i] as number,
70
+ options
71
+ );
72
+ }
73
+
74
+ for (let i = 0; i < featureIds.value.length; i++) {
75
+ const color = attributeValuesMap[featureIds.value[i]];
76
+ if (!color) {
77
+ continue; // eslint-disable-line no-continue
78
+ }
79
+ colors.value.set(color, i * 4);
80
+ }
81
+
82
+ return colors;
83
+ }
84
+
85
+ /**
86
+ * Calculate rgba color from the attribute value
87
+ * @param attributeValue - value of the attribute
88
+ * @param options - loader options
89
+ * @returns - color array for a specific attribute value
90
+ */
91
+ function calculateColorForAttribute(attributeValue: number, options?: I3SLoaderOptions): COLOR {
92
+ if (!options?.i3s?.colorsByAttribute) {
93
+ return [255, 255, 255, 255];
94
+ }
95
+ const {minValue, maxValue, minColor, maxColor} = options.i3s.colorsByAttribute;
96
+ const rate = (attributeValue - minValue) / (maxValue - minValue);
97
+ const color: COLOR = [255, 255, 255, 255];
98
+ for (let i = 0; i < minColor.length; i++) {
99
+ color[i] = Math.round((maxColor[i] - minColor[i]) * rate + minColor[i]);
100
+ }
101
+ return color;
102
+ }
103
+
104
+ /**
105
+ * Load feature attribute data from the ArcGIS rest service
106
+ * @param attributeName - attribute name
107
+ * @param tileOptions - tile-related options
108
+ * @param tilesetOptions - tileset-related options
109
+ * @param options - loader options
110
+ * @returns - Array-like list of the attribute values
111
+ */
112
+ async function loadFeatureAttributeData(
113
+ attributeName: string,
114
+ {attributeUrls}: I3STileOptions,
115
+ {attributeStorageInfo}: I3STilesetOptions,
116
+ options?: I3SLoaderOptions
117
+ ): Promise<{[key: string]: string[] | Uint32Array | Uint16Array | Float64Array} | null> {
118
+ const attributeIndex = attributeStorageInfo.findIndex(({name}) => attributeName === name);
119
+ if (attributeIndex === -1) {
120
+ return null;
121
+ }
122
+ const objectIdAttributeUrl = getUrlWithToken(attributeUrls[attributeIndex], options?.i3s?.token);
123
+ const attributeType = getAttributeValueType(attributeStorageInfo[attributeIndex]);
124
+ const objectIdAttributeData = await load(objectIdAttributeUrl, I3SAttributeLoader, {
125
+ attributeName,
126
+ attributeType
127
+ });
128
+ return objectIdAttributeData;
129
+ }
package/src/types.ts CHANGED
@@ -13,6 +13,9 @@ export enum DATA_TYPE {
13
13
  Float32 = 'Float32',
14
14
  Float64 = 'Float64'
15
15
  }
16
+
17
+ export type COLOR = [number, number, number, number];
18
+
16
19
  /**
17
20
  * spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.8/3DSceneLayer.cmn.md
18
21
  */
@@ -110,6 +113,13 @@ export type I3SParseOptions = {
110
113
  * Supported coordinate systems: METER_OFFSETS, LNGLAT_OFFSETS
111
114
  */
112
115
  coordinateSystem?: number;
116
+ colorsByAttribute?: {
117
+ attributeName: string;
118
+ minValue: number;
119
+ maxValue: number;
120
+ minColor: COLOR;
121
+ maxColor: COLOR;
122
+ };
113
123
  };
114
124
 
115
125
  export type I3STileOptions = {
@@ -118,11 +128,14 @@ export type I3STileOptions = {
118
128
  textureFormat?: I3STextureFormat;
119
129
  textureLoaderOptions?: any;
120
130
  materialDefinition?: I3SMaterialDefinition;
131
+ attributeUrls: string[];
121
132
  mbs: Mbs;
122
133
  };
123
134
 
124
135
  export type I3STilesetOptions = {
125
136
  store: Store;
137
+ attributeStorageInfo: AttributeStorageInfo[];
138
+ fields: Field[];
126
139
  };
127
140
 
128
141
  // TODO Replace "[key: string]: any" with actual defenition
@@ -157,7 +170,7 @@ export type BoundingVolumes = {
157
170
  export type Obb = {
158
171
  center: number[] | Vector3;
159
172
  halfSize: number[] | Vector3;
160
- quaternion: Quaternion;
173
+ quaternion: number[] | Quaternion;
161
174
  };
162
175
 
163
176
  export type Mbs = [number, number, number, number];
@@ -1005,3 +1018,46 @@ type CameraPosition = {
1005
1018
  y: number;
1006
1019
  z: number;
1007
1020
  };
1021
+
1022
+ /**
1023
+ * Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.8/statsInfo.cmn.md
1024
+ */
1025
+ export type StatsInfo = {
1026
+ /** Represents the count of the value. */
1027
+ totalValuesCount?: number;
1028
+ /** Minimum attribute value for the entire layer. */
1029
+ min?: number;
1030
+ /** Maximum attribute value for the entire layer. */
1031
+ max?: number;
1032
+ /** Count for the entire layer. */
1033
+ count?: number;
1034
+ /** Sum of the attribute values over the entire layer. */
1035
+ sum?: number;
1036
+ /** Representing average or mean value. For example, sum/count. */
1037
+ avg?: number;
1038
+ /** Representing the standard deviation. */
1039
+ stddev?: number;
1040
+ /** Representing variance. For example, stats.stddev *stats.stddev. */
1041
+ variance?: number;
1042
+ /** Represents the histogram. */
1043
+ histogram?: Histogram;
1044
+ /** An array of most frequently used values within the point cloud scene layer. */
1045
+ mostFrequentValues?: ValueCount[];
1046
+ };
1047
+
1048
+ /** Spec - https://github.com/Esri/i3s-spec/blob/master/docs/1.8/histogram.cmn.md */
1049
+ export type Histogram = {
1050
+ /** Minimum attribute value for the entire layer. */
1051
+ minimum: number;
1052
+ /** Maximum attribute value for the entire layer. Maximum array size for stats.histo.counts is 256. */
1053
+ maximum: number;
1054
+ /** Count for the entire layer. */
1055
+ counts: number;
1056
+ };
1057
+
1058
+ export type ValueCount = {
1059
+ /** Type of the attribute values after decompression, if applicable. Please note that string is not supported for point cloud scene layer attributes. */
1060
+ value: number | string;
1061
+ /** Count of the number of values. May exceed 32 bits. */
1062
+ count: number;
1063
+ };
@@ -0,0 +1,5 @@
1
+ import {createLoaderWorker} from '@loaders.gl/loader-utils';
2
+ import '@loaders.gl/polyfills';
3
+ import {I3SContentLoader} from '../i3s-content-loader';
4
+
5
+ createLoaderWorker(I3SContentLoader);