@loaders.gl/potree 4.3.0-alpha.4 → 4.3.0-alpha.6

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 (37) hide show
  1. package/dist/dist.dev.js +19541 -21
  2. package/dist/dist.min.js +21 -1
  3. package/dist/index.cjs +181 -20
  4. package/dist/index.cjs.map +4 -4
  5. package/dist/index.d.ts +1 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +1 -0
  8. package/dist/lib/potree-node-source.d.ts +66 -0
  9. package/dist/lib/potree-node-source.d.ts.map +1 -0
  10. package/dist/lib/potree-node-source.js +141 -0
  11. package/dist/parsers/parse-potree-hierarchy-chunk.d.ts +21 -2
  12. package/dist/parsers/parse-potree-hierarchy-chunk.d.ts.map +1 -1
  13. package/dist/parsers/parse-potree-hierarchy-chunk.js +32 -18
  14. package/dist/potree-hierarchy-chunk-loader.d.ts +6 -1
  15. package/dist/potree-hierarchy-chunk-loader.d.ts.map +1 -1
  16. package/dist/potree-hierarchy-chunk-loader.js +9 -3
  17. package/dist/potree-loader.d.ts +3 -2
  18. package/dist/potree-loader.d.ts.map +1 -1
  19. package/dist/potree-loader.js +4 -5
  20. package/dist/potree-source.d.ts +22 -0
  21. package/dist/potree-source.d.ts.map +1 -0
  22. package/dist/potree-source.js +22 -0
  23. package/dist/types/potree-metadata.d.ts +88 -0
  24. package/dist/types/potree-metadata.d.ts.map +1 -0
  25. package/dist/types/potree-metadata.js +4 -0
  26. package/dist/utils/parse-version.d.ts +5 -0
  27. package/dist/utils/parse-version.d.ts.map +1 -0
  28. package/dist/utils/parse-version.js +7 -0
  29. package/package.json +5 -3
  30. package/src/index.ts +1 -0
  31. package/src/lib/potree-node-source.ts +174 -0
  32. package/src/parsers/parse-potree-hierarchy-chunk.ts +52 -26
  33. package/src/potree-hierarchy-chunk-loader.ts +10 -3
  34. package/src/potree-loader.ts +3 -4
  35. package/src/potree-source.ts +28 -0
  36. package/src/types/potree-metadata.ts +94 -0
  37. package/src/utils/parse-version.ts +8 -0
@@ -54,32 +54,53 @@ Would have an index looking like this:
54
54
  | r36 | `0b00000000` (=0) | `1` |
55
55
  */
56
56
 
57
- /** @todo these types are an incorrect mess */
57
+ /** Node metadata from index file */
58
58
  export type POTreeTileHeader = {
59
+ /** Number of child nodes */
59
60
  childCount: number;
61
+ /** Human readable name */
60
62
  name: string;
63
+ /** Child availability mask */
61
64
  childMask: number;
62
65
  };
63
66
 
64
- /** @todo these types are an incorrect mess */
67
+ /** Hierarchical potree node structure */
65
68
  export type POTreeNode = {
69
+ /** Index data */
66
70
  header: POTreeTileHeader;
71
+ /** Human readable name */
67
72
  name: string;
73
+ /** Number of points */
68
74
  pointCount: number;
75
+ /** Node's level in the tree */
76
+ level: number;
77
+ /** Has children */
78
+ hasChildren: boolean;
79
+ /** Space between points */
80
+ spacing: number;
81
+ /** Available children */
69
82
  children: POTreeNode[];
83
+ /** All children including unavailable */
70
84
  childrenByIndex: POTreeNode[];
71
85
  };
72
86
 
73
- // type POTreeTileNode = POTreeNode;
74
-
75
- // load hierarchy
76
- export function parsePotreeHierarchyChunk(arrayBuffer: ArrayBuffer) {
87
+ /**
88
+ * load hierarchy
89
+ * @param arrayBuffer - binary index data
90
+ * @returns root node
91
+ **/
92
+ export function parsePotreeHierarchyChunk(arrayBuffer: ArrayBuffer): POTreeNode {
77
93
  const tileHeaders = parseBinaryChunk(arrayBuffer);
78
94
  return buildHierarchy(tileHeaders);
79
95
  }
80
96
 
81
- // Parses the binary rows
82
- function parseBinaryChunk(arrayBuffer: ArrayBuffer, byteOffset = 0) {
97
+ /**
98
+ * Parses the binary rows
99
+ * @param arrayBuffer - binary index data to parse
100
+ * @param byteOffset - byte offset to start from
101
+ * @returns flat nodes array
102
+ * */
103
+ function parseBinaryChunk(arrayBuffer: ArrayBuffer, byteOffset = 0): POTreeNode[] {
83
104
  const dataView = new DataView(arrayBuffer);
84
105
 
85
106
  const stack: POTreeNode[] = [];
@@ -90,8 +111,7 @@ function parseBinaryChunk(arrayBuffer: ArrayBuffer, byteOffset = 0) {
90
111
  byteOffset = decodeRow(dataView, byteOffset, topTileHeader);
91
112
 
92
113
  stack.push(topTileHeader);
93
-
94
- const tileHeaders: POTreeTileHeader[] = [];
114
+ const tileHeaders: POTreeNode[] = [topTileHeader];
95
115
 
96
116
  while (stack.length > 0) {
97
117
  const snode = stack.shift();
@@ -100,11 +120,10 @@ function parseBinaryChunk(arrayBuffer: ArrayBuffer, byteOffset = 0) {
100
120
  for (let i = 0; i < 8; i++) {
101
121
  if (snode && (snode.header.childMask & mask) !== 0) {
102
122
  // @ts-expect-error
103
- const tileHeader: POTreeTileHeader = {};
123
+ const tileHeader: POTreeNode = {};
104
124
  byteOffset = decodeRow(dataView, byteOffset, tileHeader);
105
125
  tileHeader.name = snode.name + i;
106
126
 
107
- // @ts-expect-error
108
127
  stack.push(tileHeader);
109
128
  tileHeaders.push(tileHeader);
110
129
  snode.header.childCount++;
@@ -120,7 +139,14 @@ function parseBinaryChunk(arrayBuffer: ArrayBuffer, byteOffset = 0) {
120
139
  return tileHeaders;
121
140
  }
122
141
 
123
- function decodeRow(dataView, byteOffset, tileHeader) {
142
+ /**
143
+ * Reads next row from binary index file
144
+ * @param dataView - index data
145
+ * @param byteOffset - current offset in the index data
146
+ * @param tileHeader - container to read to
147
+ * @returns new offset
148
+ */
149
+ function decodeRow(dataView: DataView, byteOffset: number, tileHeader: POTreeNode): number {
124
150
  tileHeader.header = tileHeader.header || {};
125
151
  tileHeader.header.childMask = dataView.getUint8(byteOffset);
126
152
  tileHeader.header.childCount = 0;
@@ -130,16 +156,16 @@ function decodeRow(dataView, byteOffset, tileHeader) {
130
156
  return byteOffset;
131
157
  }
132
158
 
133
- // Resolves the binary rows into a hierarchy (tree structure)
134
- function buildHierarchy(tileHeaders, options: {spacing?: number} = {}): POTreeNode {
159
+ /** Resolves the binary rows into a hierarchy (tree structure) */
160
+ function buildHierarchy(flatNodes: POTreeNode[], options: {spacing?: number} = {}): POTreeNode {
135
161
  const DEFAULT_OPTIONS = {spacing: 100}; // TODO assert instead of default?
136
162
  options = {...DEFAULT_OPTIONS, ...options};
137
163
 
138
- const topNode = tileHeaders[0];
164
+ const topNode: POTreeNode = flatNodes[0];
139
165
  const nodes = {};
140
166
 
141
- for (const tileHeader of tileHeaders) {
142
- const {name} = tileHeader;
167
+ for (const node of flatNodes) {
168
+ const {name} = node;
143
169
 
144
170
  const index = parseInt(name.charAt(name.length - 1), 10);
145
171
  const parentName = name.substring(0, name.length - 1);
@@ -147,20 +173,20 @@ function buildHierarchy(tileHeaders, options: {spacing?: number} = {}): POTreeNo
147
173
  const level = name.length - 1;
148
174
  // assert(parentNode && level >= 0);
149
175
 
150
- tileHeader.level = level;
151
- tileHeader.hasChildren = tileHeader.header.childCount;
152
- tileHeader.children = [];
153
- tileHeader.childrenByIndex = new Array(8).fill(null);
154
- tileHeader.spacing = (options?.spacing || 0) / Math.pow(2, level);
176
+ node.level = level;
177
+ node.hasChildren = Boolean(node.header.childCount);
178
+ node.children = [];
179
+ node.childrenByIndex = new Array(8).fill(null);
180
+ node.spacing = (options?.spacing || 0) / Math.pow(2, level);
155
181
  // tileHeader.boundingVolume = Utils.createChildAABB(parentNode.boundingBox, index);
156
182
 
157
183
  if (parentNode) {
158
- parentNode.children.push(tileHeader);
159
- parentNode.childrenByIndex[index] = tileHeader;
184
+ parentNode.children.push(node);
185
+ parentNode.childrenByIndex[index] = node;
160
186
  }
161
187
 
162
188
  // Add the node to the map
163
- nodes[name] = tileHeader;
189
+ nodes[name] = node;
164
190
  }
165
191
 
166
192
  // First node is the root
@@ -7,20 +7,27 @@ import type {POTreeLoaderOptions} from './potree-loader';
7
7
  import type {POTreeNode} from './parsers/parse-potree-hierarchy-chunk';
8
8
  import {parsePotreeHierarchyChunk} from './parsers/parse-potree-hierarchy-chunk';
9
9
 
10
+ // __VERSION__ is injected by babel-plugin-version-inline
11
+ // @ts-ignore TS2304: Cannot find name '__VERSION__'.
12
+ const VERSION = typeof __VERSION__ !== 'undefined' ? __VERSION__ : 'latest';
13
+
10
14
  /** Potree hierarchy chunk loader */
11
- // @ts-ignore not a valid loader
12
15
  export const PotreeHierarchyChunkLoader = {
13
16
  dataType: null as unknown as POTreeNode,
14
17
  batchType: null as never,
15
18
 
16
- id: 'potree',
17
19
  name: 'potree Hierarchy Chunk',
20
+ id: 'potree-hrc',
21
+ module: 'potree',
22
+ version: VERSION,
18
23
  extensions: ['hrc'],
19
24
  mimeTypes: ['application/octet-stream'],
20
25
  // binary potree files have no header bytes, no content test function possible
21
26
  // test: ['...'],
22
27
  parse: async (arrayBuffer, options) => parsePotreeHierarchyChunk(arrayBuffer),
23
28
  parseSync: (arrayBuffer, options) => parsePotreeHierarchyChunk(arrayBuffer),
29
+ options: {
30
+ potree: {}
31
+ },
24
32
  binary: true
25
- // @ts-ignore
26
33
  } as const satisfies LoaderWithParser<POTreeNode, never, POTreeLoaderOptions>;
@@ -13,21 +13,20 @@ export type POTreeLoaderOptions = LoaderOptions & {
13
13
  };
14
14
 
15
15
  /** Potree loader */
16
- // @ts-ignore
17
16
  export const PotreeLoader = {
18
17
  dataType: null as unknown as any,
19
18
  batchType: null as never,
20
19
 
21
- name: 'potree',
20
+ name: 'potree metadata',
22
21
  id: 'potree',
23
22
  module: 'potree',
24
23
  version: VERSION,
25
- extensions: ['json'],
24
+ extensions: ['js'],
26
25
  mimeTypes: ['application/json'],
27
26
  testText: (text) => text.indexOf('octreeDir') >= 0,
27
+ parse: (data: ArrayBuffer) => JSON.parse(new TextDecoder().decode(data)),
28
28
  parseTextSync: (text) => JSON.parse(text),
29
29
  options: {
30
30
  potree: {}
31
31
  }
32
- // @ts-ignore
33
32
  } as const satisfies LoaderWithParser<any, never, POTreeLoaderOptions>;
@@ -0,0 +1,28 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ import {Source} from '@loaders.gl/loader-utils';
6
+ import {PotreeNodesSource, PotreeNodesSourceProps} from './lib/potree-node-source';
7
+
8
+ const VERSION = '1.7';
9
+
10
+ /**
11
+ * Creates point cloud data sources for Potree urls
12
+ */
13
+ export const PotreeSource = {
14
+ name: 'Potree',
15
+ id: 'potree',
16
+ module: 'potree',
17
+ version: VERSION,
18
+ extensions: ['bin', 'las', 'laz'],
19
+ mimeTypes: ['application/octet-stream'],
20
+ options: {url: undefined!, potree: {}},
21
+ type: 'potree',
22
+ fromUrl: true,
23
+ fromBlob: true,
24
+
25
+ testURL: (url: string) => url.endsWith('.js'),
26
+ createDataSource: (url: string | Blob, props: PotreeNodesSourceProps) =>
27
+ new PotreeNodesSource(url, props)
28
+ } as const satisfies Source<PotreeNodesSource, PotreeNodesSourceProps>;
@@ -0,0 +1,94 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ /** Bounding box */
6
+ export interface PotreeBoundingBox {
7
+ /** Min X */
8
+ lx: number;
9
+ /** Min Y */
10
+ ly: number;
11
+ /** Min Z */
12
+ lz: number;
13
+ /** Max X */
14
+ ux: number;
15
+ /** Max Y */
16
+ uy: number;
17
+ /** Max Z */
18
+ uz: number;
19
+ }
20
+
21
+ /** Attribute types for *.bin content */
22
+ export type PotreeAttribute =
23
+ /** 3 (uint32) numbers: x, y, z */
24
+ | 'POSITION_CARTESIAN'
25
+ /** 4 x (uint8) numbers for the color: r, g, b, a */
26
+ | 'RGBA_PACKED'
27
+ /** 4 x (uint8) numbers for the color: r, g, b, a */
28
+ | 'COLOR_PACKED'
29
+ /** 3 x (uint8) numbers for the color: r, g, b */
30
+ | 'RGB_PACKED'
31
+ /** 3 x (float) numbers: x', y', z' */
32
+ | 'NORMAL_FLOATS'
33
+ /** (uint8) number */
34
+ | 'FILLER_1B'
35
+ /** (uint16) number specifying the point's intensity */
36
+ | 'INTENSITY'
37
+ /** (uint8) id for the class used */
38
+ | 'CLASSIFICATION'
39
+ /** Note: might need to be revisited, best don't use */
40
+ | 'NORMAL_SPHEREMAPPED'
41
+ /** Note: might need to be revisited, best don't use */
42
+ | 'NORMAL_OCT16'
43
+ /** 3 x (float) numbers: x', y', z' */
44
+ | 'NORMAL';
45
+
46
+ /** Hierarchy item: [node name leading with 'r', points count
47
+ * @example [r043, 145]
48
+ ] */
49
+ export type HierarchyItem = [string, number];
50
+
51
+ /**
52
+ * Potree data set format metadata (cloud.js)
53
+ * @version 1.7
54
+ * @link https://github.com/potree/potree/blob/1.7/docs/potree-file-format.md
55
+ * */
56
+ export interface PotreeMetadata {
57
+ /** Version number in which this file is written */
58
+ version: string;
59
+ /** Folder that is used to load additional data */
60
+ octreeDir: string;
61
+ /** Amount of points contained in the whole pointcloud data */
62
+ points: number;
63
+ /**
64
+ * This parameter is used to transform the point data
65
+ * to the projection system used while visualizing the points. It has to be
66
+ * in a format that is parsable by [proj.4][proj4].
67
+ * */
68
+ projection: string;
69
+ /** Bounding box of the world used to limit the initial POV. */
70
+ boundingBox: PotreeBoundingBox;
71
+ /** Bounding box of the actual points in the data */
72
+ tightBoundingBox: PotreeBoundingBox;
73
+ /** Description of point attributes in data files */
74
+ pointAttributes: 'LAS' | 'LAZ' | PotreeAttribute[];
75
+ /**
76
+ * Space between points at the root node.
77
+ * This value is halved at each octree level.
78
+ * */
79
+ spacing: number;
80
+ /**
81
+ * Scale applied to convert POSITION_CARTESIAN components
82
+ * from uint32 values to floating point values. The full transformation
83
+ * to world coordinates is
84
+ * position = (POSITION_CARTESIAN * scale) + boundingBox.min
85
+ * */
86
+ scale: number;
87
+ /** Amount of Octree levels before a new folder hierarchy is expected. */
88
+ hierarchyStepSize: number;
89
+ /**
90
+ * The hierarchy of files, now loaded through index files.
91
+ * @deprecated
92
+ * */
93
+ hierarchy: HierarchyItem[];
94
+ }
@@ -0,0 +1,8 @@
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
3
+ // Copyright (c) vis.gl contributors
4
+
5
+ export function parseVersion(version: string): {major: number; minor: number} {
6
+ const parts = version.split('.').map(Number);
7
+ return {major: parts[0], minor: parts[1]};
8
+ }