@loaders.gl/i3s 4.2.0-alpha.5 → 4.2.0-beta.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 (44) hide show
  1. package/dist/arcgis-webscene-loader.d.ts +19 -2
  2. package/dist/arcgis-webscene-loader.d.ts.map +1 -1
  3. package/dist/arcgis-webscene-loader.js +3 -1
  4. package/dist/dist.dev.js +192 -144
  5. package/dist/dist.min.js +1 -1
  6. package/dist/i3s-attribute-loader.d.ts +14 -3
  7. package/dist/i3s-attribute-loader.d.ts.map +1 -1
  8. package/dist/i3s-attribute-loader.js +3 -1
  9. package/dist/i3s-building-scene-layer-loader.d.ts +15 -3
  10. package/dist/i3s-building-scene-layer-loader.d.ts.map +1 -1
  11. package/dist/i3s-building-scene-layer-loader.js +3 -1
  12. package/dist/i3s-content-loader.d.ts +18 -2
  13. package/dist/i3s-content-loader.d.ts.map +1 -1
  14. package/dist/i3s-content-loader.js +6 -1
  15. package/dist/i3s-content-worker-node.js +51 -51
  16. package/dist/i3s-content-worker-node.js.map +4 -4
  17. package/dist/i3s-content-worker.js +1722 -1702
  18. package/dist/i3s-loader.d.ts +30 -2
  19. package/dist/i3s-loader.d.ts.map +1 -1
  20. package/dist/i3s-loader.js +8 -2
  21. package/dist/i3s-node-page-loader.d.ts +17 -3
  22. package/dist/i3s-node-page-loader.d.ts.map +1 -1
  23. package/dist/i3s-node-page-loader.js +6 -1
  24. package/dist/i3s-slpk-loader.d.ts +13 -2
  25. package/dist/i3s-slpk-loader.d.ts.map +1 -1
  26. package/dist/i3s-slpk-loader.js +6 -1
  27. package/dist/index.cjs +43 -35
  28. package/dist/index.cjs.map +2 -2
  29. package/dist/lib/helpers/i3s-nodepages-tiles.d.ts.map +1 -1
  30. package/dist/lib/helpers/i3s-nodepages-tiles.js +11 -7
  31. package/dist/lib/parsers/parse-arcgis-webscene.js +1 -0
  32. package/dist/lib/parsers/parse-i3s-tile-content.d.ts.map +1 -1
  33. package/dist/lib/parsers/parse-i3s-tile-content.js +3 -25
  34. package/dist/lib/parsers/parse-slpk/slpk-archieve.js +5 -3
  35. package/package.json +12 -10
  36. package/src/arcgis-webscene-loader.ts +4 -6
  37. package/src/i3s-attribute-loader.ts +4 -2
  38. package/src/i3s-building-scene-layer-loader.ts +6 -6
  39. package/src/i3s-content-loader.ts +9 -2
  40. package/src/i3s-loader.ts +11 -3
  41. package/src/i3s-node-page-loader.ts +9 -2
  42. package/src/i3s-slpk-loader.ts +9 -2
  43. package/src/lib/helpers/i3s-nodepages-tiles.ts +1 -3
  44. package/src/lib/parsers/parse-i3s-tile-content.ts +7 -30
@@ -35,9 +35,8 @@ export async function parseI3STileContent(arrayBuffer, tileOptions, tilesetOptio
35
35
  texture: null
36
36
  };
37
37
  if (tileOptions.textureUrl) {
38
- const url = getUrlWithToken(getInternalPathFromUrl(tileOptions.textureUrl),
39
38
  // @ts-expect-error options is not properly typed
40
- options?.i3s?.token);
39
+ const url = getUrlWithToken(tileOptions.textureUrl, options?.i3s?.token);
41
40
  const loader = getLoaderForTextureFormat(tileOptions.textureFormat);
42
41
  const fetchFunc = context?.fetch || fetch;
43
42
  const response = await fetchFunc(url); // options?.fetch
@@ -51,7 +50,6 @@ export async function parseI3STileContent(arrayBuffer, tileOptions, tilesetOptio
51
50
  // Image constructor is not supported in worker thread.
52
51
  // Do parsing image data on the main thread by using context to avoid worker issues.
53
52
  const texture = await parseFromContext(arrayBuffer, [], options, context);
54
- // @ts-expect-error
55
53
  content.texture = texture;
56
54
  }
57
55
  catch (e) {
@@ -85,26 +83,6 @@ export async function parseI3STileContent(arrayBuffer, tileOptions, tilesetOptio
85
83
  }
86
84
  return await parseI3SNodeGeometry(arrayBuffer, content, tileOptions, tilesetOptions, options);
87
85
  }
88
- /**
89
- * Get the URL inside SLPK archive
90
- * @param url - full url with *.slpk prefix
91
- * @returns URL inside SLPK archive
92
- */
93
- function getInternalPathFromUrl(url) {
94
- const slpkUrlParts = url.split('.slpk');
95
- let filename;
96
- // Not '.slpk'. The file will be loaded with global fetch function
97
- if (slpkUrlParts.length === 1) {
98
- filename = url;
99
- }
100
- else if (slpkUrlParts.length === 2) {
101
- filename = slpkUrlParts[1].slice(1);
102
- }
103
- else {
104
- filename = url;
105
- }
106
- return filename;
107
- }
108
86
  /* eslint-disable max-statements */
109
87
  async function parseI3SNodeGeometry(arrayBuffer, content, tileOptions, tilesetOptions, options) {
110
88
  const contentByteLength = arrayBuffer.byteLength;
@@ -233,11 +211,11 @@ function parseHeaders(arrayBuffer, options) {
233
211
  for (const { property, type } of options.store.defaultGeometrySchema.header) {
234
212
  const TypedArrayTypeHeader = getConstructorForDataFormat(type);
235
213
  switch (property) {
236
- case HeaderAttributeProperty.vertexCount:
214
+ case HeaderAttributeProperty.vertexCount.toString():
237
215
  vertexCount = new TypedArrayTypeHeader(arrayBuffer, 0, 4)[0];
238
216
  byteOffset += sizeOf(type);
239
217
  break;
240
- case HeaderAttributeProperty.featureCount:
218
+ case HeaderAttributeProperty.featureCount.toString():
241
219
  featureCount = new TypedArrayTypeHeader(arrayBuffer, 4, 4)[0];
242
220
  byteOffset += sizeOf(type);
243
221
  break;
@@ -40,6 +40,11 @@ const PATH_DESCRIPTIONS = [
40
40
  * Class for handling information about slpk file
41
41
  */
42
42
  export class SLPKArchive extends IndexedArchive {
43
+ // Maps hex-encoded md5 filename hashes to bigint offsets into the archive
44
+ hashTable;
45
+ _textEncoder = new TextEncoder();
46
+ _textDecoder = new TextDecoder();
47
+ _md5Hash = new MD5Hash();
43
48
  /**
44
49
  * Constructor
45
50
  * @param fileProvider - instance of a binary data reader
@@ -48,9 +53,6 @@ export class SLPKArchive extends IndexedArchive {
48
53
  */
49
54
  constructor(fileProvider, hashTable, fileName) {
50
55
  super(fileProvider, hashTable, fileName);
51
- this._textEncoder = new TextEncoder();
52
- this._textDecoder = new TextDecoder();
53
- this._md5Hash = new MD5Hash();
54
56
  this.hashTable = hashTable;
55
57
  }
56
58
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loaders.gl/i3s",
3
- "version": "4.2.0-alpha.5",
3
+ "version": "4.2.0-beta.1",
4
4
  "description": "i3s .",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -42,14 +42,16 @@
42
42
  "build-worker-node": "esbuild src/workers/i3s-content-worker-node.ts --outfile=dist/i3s-content-worker-node.js --platform=node --target=node16 --minify --bundle --sourcemap --define:__VERSION__=\\\"$npm_package_version\\\""
43
43
  },
44
44
  "dependencies": {
45
- "@loaders.gl/compression": "4.2.0-alpha.5",
46
- "@loaders.gl/crypto": "4.2.0-alpha.5",
47
- "@loaders.gl/draco": "4.2.0-alpha.5",
48
- "@loaders.gl/images": "4.2.0-alpha.5",
49
- "@loaders.gl/loader-utils": "4.2.0-alpha.5",
50
- "@loaders.gl/schema": "4.2.0-alpha.5",
51
- "@loaders.gl/textures": "4.2.0-alpha.5",
52
- "@loaders.gl/tiles": "4.2.0-alpha.5",
45
+ "@loaders.gl/compression": "4.2.0-beta.1",
46
+ "@loaders.gl/crypto": "4.2.0-beta.1",
47
+ "@loaders.gl/draco": "4.2.0-beta.1",
48
+ "@loaders.gl/images": "4.2.0-beta.1",
49
+ "@loaders.gl/loader-utils": "4.2.0-beta.1",
50
+ "@loaders.gl/math": "4.2.0-beta.1",
51
+ "@loaders.gl/schema": "4.2.0-beta.1",
52
+ "@loaders.gl/textures": "4.2.0-beta.1",
53
+ "@loaders.gl/tiles": "4.2.0-beta.1",
54
+ "@loaders.gl/zip": "4.2.0-beta.1",
53
55
  "@math.gl/core": "^4.0.0",
54
56
  "@math.gl/culling": "^4.0.0",
55
57
  "@math.gl/geospatial": "^4.0.0"
@@ -57,5 +59,5 @@
57
59
  "peerDependencies": {
58
60
  "@loaders.gl/core": "^4.0.0"
59
61
  },
60
- "gitHead": "32d95a81971f104e4dfeb88ab57065f05321a76a"
62
+ "gitHead": "c386a9196516fe3ff24847b40e6c77be039cf905"
61
63
  }
@@ -13,11 +13,9 @@ export type ArcGISWebSceneLoaderOptions = LoaderOptions & {};
13
13
  * Loader for ArcGIS WebScene
14
14
  * Spec - https://developers.arcgis.com/web-scene-specification/objects/webscene/
15
15
  */
16
- export const ArcGISWebSceneLoader: LoaderWithParser<
17
- ArcGISWebSceneData,
18
- never,
19
- ArcGISWebSceneLoaderOptions
20
- > = {
16
+ export const ArcGISWebSceneLoader = {
17
+ dataType: null as unknown as ArcGISWebSceneData,
18
+ batchType: null as never,
21
19
  name: 'ArcGIS Web Scene Loader',
22
20
  id: 'arcgis-web-scene',
23
21
  module: 'i3s',
@@ -26,7 +24,7 @@ export const ArcGISWebSceneLoader: LoaderWithParser<
26
24
  parse,
27
25
  extensions: ['json'],
28
26
  options: {}
29
- };
27
+ } as const satisfies LoaderWithParser<ArcGISWebSceneData, never, ArcGISWebSceneLoaderOptions>;
30
28
 
31
29
  /**
32
30
  * Parse ArcGIS webscene
@@ -14,7 +14,9 @@ const REJECTED_STATUS = 'rejected';
14
14
  /**
15
15
  * Loader for I3S attributes
16
16
  */
17
- export const I3SAttributeLoader: LoaderWithParser<I3STileAttributes, never, I3SLoaderOptions> = {
17
+ export const I3SAttributeLoader = {
18
+ dataType: null as unknown as I3STileAttributes,
19
+ batchType: null as never,
18
20
  name: 'I3S Attribute',
19
21
  id: 'i3s-attribute',
20
22
  module: 'i3s',
@@ -24,7 +26,7 @@ export const I3SAttributeLoader: LoaderWithParser<I3STileAttributes, never, I3SL
24
26
  extensions: ['bin'],
25
27
  options: {},
26
28
  binary: true
27
- };
29
+ } as const satisfies LoaderWithParser<I3STileAttributes, never, I3SLoaderOptions>;
28
30
 
29
31
 
30
32
  // TODO - these seem to use the loader rather than being part of the loader. Move to different file...
@@ -8,14 +8,14 @@ import {parseBuildingSceneLayer} from './lib/parsers/parse-i3s-building-scene-la
8
8
  // @ts-ignore TS2304: Cannot find name '__VERSION__'.
9
9
 
10
10
  const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
11
+
11
12
  /**
12
13
  * Loader for I3S - Building Scene Layer
13
14
  */
14
- export const I3SBuildingSceneLayerLoader: LoaderWithParser<
15
- BuildingSceneLayerTileset,
16
- never,
17
- I3SLoaderOptions
18
- > = {
15
+ export const I3SBuildingSceneLayerLoader = {
16
+ dataType: null as unknown as BuildingSceneLayerTileset,
17
+ batchType: null as never,
18
+
19
19
  name: 'I3S Building Scene Layer',
20
20
  id: 'i3s-building-scene-layer',
21
21
  module: 'i3s',
@@ -24,7 +24,7 @@ export const I3SBuildingSceneLayerLoader: LoaderWithParser<
24
24
  parse,
25
25
  extensions: ['json'],
26
26
  options: {}
27
- };
27
+ } as const satisfies LoaderWithParser<BuildingSceneLayerTileset, never, I3SLoaderOptions>;
28
28
 
29
29
  async function parse(
30
30
  data: ArrayBuffer,
@@ -1,3 +1,7 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright vis.gl contributors
4
+
1
5
  import type {LoaderWithParser, LoaderContext} from '@loaders.gl/loader-utils';
2
6
  import type {I3SLoaderOptions} from './i3s-loader';
3
7
  import {parseI3STileContent} from './lib/parsers/parse-i3s-tile-content';
@@ -11,7 +15,10 @@ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
11
15
  /**
12
16
  * Loader for I3S - Indexed 3D Scene Layer
13
17
  */
14
- export const I3SContentLoader: LoaderWithParser<I3STileContent | null, never, I3SLoaderOptions> = {
18
+ export const I3SContentLoader = {
19
+ dataType: null as unknown as I3STileContent | null,
20
+ batchType: null as never,
21
+
15
22
  name: 'I3S Content (Indexed Scene Layers)',
16
23
  id: 'i3s-content',
17
24
  module: 'i3s',
@@ -23,7 +30,7 @@ export const I3SContentLoader: LoaderWithParser<I3STileContent | null, never, I3
23
30
  options: {
24
31
  'i3s-content': {}
25
32
  }
26
- };
33
+ } as const satisfies LoaderWithParser<I3STileContent | null, never, I3SLoaderOptions>;
27
34
 
28
35
  async function parse(data, options?: I3SLoaderOptions, context?: LoaderContext) {
29
36
  const {tile, _tileOptions, tileset, _tilesetOptions} = options?.i3s || {};
package/src/i3s-loader.ts CHANGED
@@ -1,3 +1,7 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright vis.gl contributors
4
+
1
5
  import type {LoaderWithParser, LoaderOptions} from '@loaders.gl/loader-utils';
2
6
  import {parse} from '@loaders.gl/core';
3
7
  import type {I3STilesetHeader} from './types';
@@ -12,6 +16,7 @@ import {getUrlWithoutParams} from './lib/utils/url-utils';
12
16
  const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
13
17
 
14
18
  const TILESET_REGEX = /layers\/[0-9]+$/;
19
+ const LOCAL_SLPK_REGEX = /\.slpk$/;
15
20
  const TILE_HEADER_REGEX = /nodes\/([0-9-]+|root)$/;
16
21
  const SLPK_HEX = '504b0304';
17
22
  const POINT_CLOUD = 'PointCloud';
@@ -23,7 +28,10 @@ export type I3SLoaderOptions = LoaderOptions & {
23
28
  /**
24
29
  * Loader for I3S - Indexed 3D Scene Layer
25
30
  */
26
- export const I3SLoader: LoaderWithParser<I3STilesetHeader, never, LoaderOptions> = {
31
+ export const I3SLoader = {
32
+ dataType: null as unknown as I3STilesetHeader,
33
+ batchType: null as never,
34
+
27
35
  name: 'I3S (Indexed Scene Layers)',
28
36
  id: 'i3s',
29
37
  module: 'i3s',
@@ -46,7 +54,7 @@ export const I3SLoader: LoaderWithParser<I3STilesetHeader, never, LoaderOptions>
46
54
  coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS
47
55
  }
48
56
  }
49
- };
57
+ } as const satisfies LoaderWithParser<I3STilesetHeader, never, LoaderOptions>;
50
58
 
51
59
  async function parseI3S(data, options: I3SLoaderOptions = {}, context): Promise<I3STilesetHeader> {
52
60
  const url = context.url;
@@ -63,7 +71,7 @@ async function parseI3S(data, options: I3SLoaderOptions = {}, context): Promise<
63
71
  // auto detect file type based on url
64
72
  let isTileset;
65
73
  if (options.i3s.isTileset === 'auto') {
66
- isTileset = TILESET_REGEX.test(urlWithoutParams);
74
+ isTileset = TILESET_REGEX.test(urlWithoutParams) || LOCAL_SLPK_REGEX.test(urlWithoutParams);
67
75
  } else {
68
76
  isTileset = options.i3s.isTileset;
69
77
  }
@@ -1,3 +1,7 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright vis.gl contributors
4
+
1
5
  import type {LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
2
6
  import type {I3SLoaderOptions} from './i3s-loader';
3
7
  import type {NodePage} from './types';
@@ -9,7 +13,10 @@ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
9
13
  /**
10
14
  * Loader for I3S node pages
11
15
  */
12
- export const I3SNodePageLoader: LoaderWithParser<NodePage, never, I3SLoaderOptions> = {
16
+ export const I3SNodePageLoader = {
17
+ dataType: null as unknown as NodePage,
18
+ batchType: null as never,
19
+
13
20
  name: 'I3S Node Page',
14
21
  id: 'i3s-node-page',
15
22
  module: 'i3s',
@@ -20,7 +27,7 @@ export const I3SNodePageLoader: LoaderWithParser<NodePage, never, I3SLoaderOptio
20
27
  options: {
21
28
  i3s: {}
22
29
  }
23
- };
30
+ } as const satisfies LoaderWithParser<NodePage, never, I3SLoaderOptions>;
24
31
 
25
32
  async function parseNodePage(data: ArrayBuffer, options?: LoaderOptions): Promise<NodePage> {
26
33
  return JSON.parse(new TextDecoder().decode(data)) as NodePage;
@@ -1,3 +1,7 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright vis.gl contributors
4
+
1
5
  import type {LoaderOptions, LoaderWithParser} from '@loaders.gl/loader-utils';
2
6
  import {DataViewFile} from '@loaders.gl/loader-utils';
3
7
  import {parseSLPKArchive} from './lib/parsers/parse-slpk/parse-slpk';
@@ -21,7 +25,10 @@ export type SLPKLoaderOptions = LoaderOptions & {
21
25
  * @todo - this reloads the entire archive for every tile, should be optimized
22
26
  * @todo - this should be updated to use `parseFile` and ReadableFile
23
27
  */
24
- export const SLPKLoader: LoaderWithParser<ArrayBuffer, never, SLPKLoaderOptions> = {
28
+ export const SLPKLoader = {
29
+ dataType: null as unknown as ArrayBuffer,
30
+ batchType: null as never,
31
+
25
32
  name: 'I3S SLPK (Scene Layer Package)',
26
33
  id: 'slpk',
27
34
  module: 'i3s',
@@ -33,4 +40,4 @@ export const SLPKLoader: LoaderWithParser<ArrayBuffer, never, SLPKLoaderOptions>
33
40
  const archive = await parseSLPKArchive(new DataViewFile(new DataView(data)));
34
41
  return archive.getFile(options.slpk?.path ?? '', options.slpk?.pathMode);
35
42
  }
36
- };
43
+ } as const satisfies LoaderWithParser<ArrayBuffer, never, SLPKLoaderOptions>;
@@ -58,9 +58,7 @@ export default class I3SNodePagesTiles {
58
58
  const pageIndex = Math.floor(id / this.nodesPerPage);
59
59
  if (!this.nodePages[pageIndex] && !this.pendingNodePages[pageIndex]) {
60
60
  const nodePageUrl = getUrlWithToken(
61
- this.url.indexOf('.slpk') !== -1
62
- ? `nodepages/${pageIndex}`
63
- : `${this.url}/nodepages/${pageIndex}`,
61
+ `${this.url}/nodepages/${pageIndex}`,
64
62
  // @ts-expect-error this.options is not properly typed
65
63
  this.options.i3s?.token
66
64
  );
@@ -61,11 +61,8 @@ export async function parseI3STileContent(
61
61
  };
62
62
 
63
63
  if (tileOptions.textureUrl) {
64
- const url = getUrlWithToken(
65
- getInternalPathFromUrl(tileOptions.textureUrl),
66
- // @ts-expect-error options is not properly typed
67
- options?.i3s?.token
68
- );
64
+ // @ts-expect-error options is not properly typed
65
+ const url = getUrlWithToken(tileOptions.textureUrl, options?.i3s?.token);
69
66
  const loader = getLoaderForTextureFormat(tileOptions.textureFormat);
70
67
  const fetchFunc = context?.fetch || fetch;
71
68
  const response = await fetchFunc(url); // options?.fetch
@@ -79,17 +76,16 @@ export async function parseI3STileContent(
79
76
  try {
80
77
  // Image constructor is not supported in worker thread.
81
78
  // Do parsing image data on the main thread by using context to avoid worker issues.
82
- const texture = await parseFromContext(arrayBuffer, [], options, context!);
83
- // @ts-expect-error
79
+ const texture: any = await parseFromContext(arrayBuffer, [], options, context!);
84
80
  content.texture = texture;
85
81
  } catch (e) {
86
82
  // context object is different between worker and node.js conversion script.
87
83
  // To prevent error we parse data in ordinary way if it is not parsed by using context.
88
- const texture = await parse(arrayBuffer, loader, options, context);
84
+ const texture: any = await parse(arrayBuffer, loader, options, context);
89
85
  content.texture = texture;
90
86
  }
91
87
  } else if (loader === CompressedTextureLoader || loader === BasisLoader) {
92
- let texture = await load(arrayBuffer, loader, tileOptions.textureLoaderOptions);
88
+ let texture: any = await load(arrayBuffer, loader, tileOptions.textureLoaderOptions);
93
89
  if (loader === BasisLoader) {
94
90
  texture = texture[0];
95
91
  }
@@ -114,25 +110,6 @@ export async function parseI3STileContent(
114
110
  return await parseI3SNodeGeometry(arrayBuffer, content, tileOptions, tilesetOptions, options);
115
111
  }
116
112
 
117
- /**
118
- * Get the URL inside SLPK archive
119
- * @param url - full url with *.slpk prefix
120
- * @returns URL inside SLPK archive
121
- */
122
- function getInternalPathFromUrl(url: string): string {
123
- const slpkUrlParts = url.split('.slpk');
124
- let filename: string | null;
125
- // Not '.slpk'. The file will be loaded with global fetch function
126
- if (slpkUrlParts.length === 1) {
127
- filename = url;
128
- } else if (slpkUrlParts.length === 2) {
129
- filename = slpkUrlParts[1].slice(1);
130
- } else {
131
- filename = url;
132
- }
133
- return filename;
134
- }
135
-
136
113
  /* eslint-disable max-statements */
137
114
  async function parseI3SNodeGeometry(
138
115
  arrayBuffer: ArrayBuffer,
@@ -315,11 +292,11 @@ function parseHeaders(arrayBuffer: ArrayBuffer, options: I3STilesetOptions) {
315
292
  for (const {property, type} of options.store.defaultGeometrySchema.header) {
316
293
  const TypedArrayTypeHeader = getConstructorForDataFormat(type);
317
294
  switch (property) {
318
- case HeaderAttributeProperty.vertexCount:
295
+ case HeaderAttributeProperty.vertexCount.toString():
319
296
  vertexCount = new TypedArrayTypeHeader(arrayBuffer, 0, 4)[0];
320
297
  byteOffset += sizeOf(type);
321
298
  break;
322
- case HeaderAttributeProperty.featureCount:
299
+ case HeaderAttributeProperty.featureCount.toString():
323
300
  featureCount = new TypedArrayTypeHeader(arrayBuffer, 4, 4)[0];
324
301
  byteOffset += sizeOf(type);
325
302
  break;