itowns 2.44.3-next.22 → 2.44.3-next.24

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/debug.js +1 -1
  2. package/dist/debug.js.map +1 -1
  3. package/dist/itowns.js +1 -1
  4. package/dist/itowns.js.map +1 -1
  5. package/examples/layers/JSONLayers/GeoidMNT.json +3 -1
  6. package/examples/source_file_geojson_3d.html +0 -1
  7. package/examples/source_stream_wfs_raster.html +0 -7
  8. package/lib/Converter/Feature2Texture.js +3 -1
  9. package/lib/Converter/convertToTile.js +3 -3
  10. package/lib/Core/Prefab/Globe/Atmosphere.js +4 -2
  11. package/lib/Core/Prefab/Globe/GlobeLayer.js +19 -11
  12. package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +111 -0
  13. package/lib/Core/Prefab/Planar/PlanarLayer.js +15 -8
  14. package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +43 -43
  15. package/lib/Core/Prefab/TileBuilder.js +27 -32
  16. package/lib/Core/Prefab/computeBufferTileGeometry.js +189 -130
  17. package/lib/Core/TileGeometry.js +112 -28
  18. package/lib/Layer/C3DTilesLayer.js +7 -4
  19. package/lib/Layer/ColorLayer.js +35 -9
  20. package/lib/Layer/CopcLayer.js +5 -0
  21. package/lib/Layer/ElevationLayer.js +39 -7
  22. package/lib/Layer/EntwinePointTileLayer.js +12 -5
  23. package/lib/Layer/FeatureGeometryLayer.js +20 -6
  24. package/lib/Layer/GeometryLayer.js +42 -11
  25. package/lib/Layer/LabelLayer.js +11 -5
  26. package/lib/Layer/Layer.js +83 -57
  27. package/lib/Layer/OGC3DTilesLayer.js +3 -2
  28. package/lib/Layer/OrientedImageLayer.js +12 -4
  29. package/lib/Layer/PointCloudLayer.js +69 -23
  30. package/lib/Layer/Potree2Layer.js +7 -2
  31. package/lib/Layer/PotreeLayer.js +8 -3
  32. package/lib/Layer/RasterLayer.js +12 -2
  33. package/lib/Layer/TiledGeometryLayer.js +69 -13
  34. package/lib/Provider/Fetcher.js +5 -1
  35. package/lib/Renderer/OBB.js +9 -11
  36. package/package.json +1 -1
  37. package/lib/Core/Prefab/Globe/BuilderEllipsoidTile.js +0 -110
@@ -22,14 +22,14 @@ import { RasterElevationTile } from "../Renderer/RasterTile.js";
22
22
  * ```
23
23
  * @property {number} colorTextureElevationMinZ - elevation minimum in `useColorTextureElevation` mode.
24
24
  * @property {number} colorTextureElevationMaxZ - elevation maximum in `useColorTextureElevation` mode.
25
+ *
26
+ * @extends RasterLayer
25
27
  */
26
28
  class ElevationLayer extends RasterLayer {
27
29
  /**
28
30
  * A simple layer, managing an elevation texture to add some reliefs on the
29
31
  * plane or globe view for example.
30
32
  *
31
- * @extends Layer
32
- *
33
33
  * @param {string} id - The id of the layer, that should be unique. It is
34
34
  * not mandatory, but an error will be emitted if this layer is added a
35
35
  * {@link View} that already has a layer going by that id.
@@ -60,14 +60,46 @@ class ElevationLayer extends RasterLayer {
60
60
  */
61
61
  constructor(id) {
62
62
  let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
63
- super(id, config);
63
+ const {
64
+ scale = 1.0,
65
+ noDataValue,
66
+ clampValues,
67
+ useRgbaTextureElevation,
68
+ useColorTextureElevation,
69
+ colorTextureElevationMinZ,
70
+ colorTextureElevationMaxZ,
71
+ bias,
72
+ mode,
73
+ ...rasterConfig
74
+ } = config;
75
+ super(id, rasterConfig);
76
+
77
+ /**
78
+ * @type {boolean}
79
+ * @readonly
80
+ */
81
+ this.isElevationLayer = true;
82
+ this.noDataValue = noDataValue;
64
83
  if (config.zmin || config.zmax) {
65
84
  console.warn('Config using zmin and zmax are deprecated, use {clampValues: {min, max}} structure.');
66
85
  }
67
- this.zmin = config.clampValues?.min ?? config.zmin;
68
- this.zmax = config.clampValues?.max ?? config.zmax;
69
- this.isElevationLayer = true;
70
- this.defineLayerProperty('scale', this.scale || 1.0);
86
+
87
+ /**
88
+ * @type {number | undefined}
89
+ */
90
+ this.zmin = clampValues?.min ?? config.zmin;
91
+
92
+ /**
93
+ * @type {number | undefined}
94
+ */
95
+ this.zmax = clampValues?.max ?? config.zmax;
96
+ this.defineLayerProperty('scale', scale);
97
+ this.useRgbaTextureElevation = useRgbaTextureElevation;
98
+ this.useColorTextureElevation = useColorTextureElevation;
99
+ this.colorTextureElevationMinZ = colorTextureElevationMinZ;
100
+ this.colorTextureElevationMaxZ = colorTextureElevationMaxZ;
101
+ this.bias = bias;
102
+ this.mode = mode;
71
103
  }
72
104
 
73
105
  /**
@@ -10,13 +10,13 @@ bboxMesh.geometry.boundingBox = box3;
10
10
  * @property {boolean} isEntwinePointTileLayer - Used to checkout whether this
11
11
  * layer is a EntwinePointTileLayer. Default is `true`. You should not change
12
12
  * this, as it is used internally for optimisation.
13
+ *
14
+ * @extends PointCloudLayer
13
15
  */
14
16
  class EntwinePointTileLayer extends PointCloudLayer {
15
17
  /**
16
18
  * Constructs a new instance of Entwine Point Tile layer.
17
19
  *
18
- * @extends PointCloudLayer
19
- *
20
20
  * @example
21
21
  * // Create a new point cloud layer
22
22
  * const points = new EntwinePointTileLayer('EPT',
@@ -36,15 +36,22 @@ class EntwinePointTileLayer extends PointCloudLayer {
36
36
  * contains three elements `name, protocol, extent`, these elements will be
37
37
  * available using `layer.name` or something else depending on the property
38
38
  * name. See the list of properties to know which one can be specified.
39
- * @param {string} [config.crs=ESPG:4326] - The CRS of the {@link View} this
39
+ * @param {string} [config.crs='ESPG:4326'] - The CRS of the {@link View} this
40
40
  * layer will be attached to. This is used to determine the extent of this
41
41
  * layer. Default to `EPSG:4326`.
42
- * @param {number} [config.skip=1] - Read one point from every `skip` points
43
- * - see {@link LASParser}.
44
42
  */
45
43
  constructor(id, config) {
46
44
  super(id, config);
45
+
46
+ /**
47
+ * @type {boolean}
48
+ * @readonly
49
+ */
47
50
  this.isEntwinePointTileLayer = true;
51
+
52
+ /**
53
+ * @type {THREE.Vector3}
54
+ */
48
55
  this.scale = new THREE.Vector3(1, 1, 1);
49
56
  const resolve = this.addInitializationStep();
50
57
  this.whenReady = this.source.whenReady.then(() => {
@@ -12,10 +12,11 @@ import Feature2Mesh from "../Converter/Feature2Mesh.js";
12
12
  * @property {boolean} isFeatureGeometryLayer - Used to checkout whether this layer is
13
13
  * a FeatureGeometryLayer. Default is true. You should not change this, as it is used
14
14
  * internally for optimisation.
15
+ *
16
+ * @extends GeometryLayer
15
17
  */
16
18
  class FeatureGeometryLayer extends GeometryLayer {
17
19
  /**
18
- * @extends GeometryLayer
19
20
  *
20
21
  * @param {string} id - The id of the layer, that should be unique. It is
21
22
  * not mandatory, but an error will be emitted if this layer is added a
@@ -28,6 +29,9 @@ class FeatureGeometryLayer extends GeometryLayer {
28
29
  * @param {THREE.Object3D} [options.object3d=new THREE.Group()] root object3d layer.
29
30
  * @param {function} [options.onMeshCreated] this callback is called when the mesh is created. The callback parameters are the
30
31
  * `mesh` and the `context`.
32
+ * @param {function} [options.filter] callback which filters the features of
33
+ * this layer. It takes an object with a `properties` property as argument
34
+ * and shall return a boolean.
31
35
  * @param {boolean} [options.accurate=TRUE] If `accurate` is `true`, data are re-projected with maximum geographical accuracy.
32
36
  * With `true`, `proj4` is used to transform data source.
33
37
  *
@@ -45,14 +49,24 @@ class FeatureGeometryLayer extends GeometryLayer {
45
49
  */
46
50
  constructor(id) {
47
51
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
48
- options.update = FeatureProcessing.update;
49
- options.convert = Feature2Mesh.convert({
50
- batchId: options.batchId
52
+ const {
53
+ object3d,
54
+ batchId,
55
+ onMeshCreated,
56
+ accurate = true,
57
+ filter,
58
+ ...geometryOptions
59
+ } = options;
60
+ super(id, object3d || new Group(), geometryOptions);
61
+ this.update = FeatureProcessing.update;
62
+ this.convert = Feature2Mesh.convert({
63
+ batchId
51
64
  });
52
- super(id, options.object3d || new Group(), options);
65
+ this.onMeshCreated = onMeshCreated;
53
66
  this.isFeatureGeometryLayer = true;
54
- this.accurate = options.accurate ?? true;
67
+ this.accurate = accurate;
55
68
  this.buildExtent = !this.accurate;
69
+ this.filter = filter;
56
70
  }
57
71
  preUpdate(context, sources) {
58
72
  if (sources.has(this.parent)) {
@@ -23,8 +23,6 @@ class GeometryLayer extends Layer {
23
23
  * A layer usually managing a geometry to display on a view. For example, it
24
24
  * can be a layer of buildings extruded from a a WFS stream.
25
25
  *
26
- * @extends Layer
27
- *
28
26
  * @param {string} id - The id of the layer, that should be unique. It is
29
27
  * not mandatory, but an error will be emitted if this layer is added a
30
28
  * {@link View} that already has a layer going by that id.
@@ -36,7 +34,10 @@ class GeometryLayer extends Layer {
36
34
  * contains three elements `name, protocol, extent`, these elements will be
37
35
  * available using `layer.name` or something else depending on the property
38
36
  * name.
39
- * @param {Source} [config.source] - Description and options of the source.
37
+ * @param {Source} config.source - Description and options of the source.
38
+ * @param {number} [config.cacheLifeTime=Infinity] - set life time value in cache.
39
+ * This value is used for [Cache]{@link Cache} expiration mechanism.
40
+ * @param {boolean} [config.visible]
40
41
  *
41
42
  * @throws {Error} `object3d` must be a valid `THREE.Object3d`.
42
43
  *
@@ -55,12 +56,21 @@ class GeometryLayer extends Layer {
55
56
  */
56
57
  constructor(id, object3d) {
57
58
  let config = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
58
- config.cacheLifeTime = config.cacheLifeTime ?? CACHE_POLICIES.GEOMETRY;
59
+ const {
60
+ cacheLifeTime = CACHE_POLICIES.GEOMETRY,
61
+ visible = true,
62
+ opacity = 1.0,
63
+ ...layerConfig
64
+ } = config;
65
+ super(id, {
66
+ ...layerConfig,
67
+ cacheLifeTime
68
+ });
59
69
 
60
- // Remove this part when Object.assign(this, config) will be removed from Layer Constructor
61
- const visible = config.visible;
62
- delete config.visible;
63
- super(id, config);
70
+ /**
71
+ * @type {boolean}
72
+ * @readonly
73
+ */
64
74
  this.isGeometryLayer = true;
65
75
  if (!object3d || !object3d.isObject3D) {
66
76
  throw new Error(`Missing/Invalid object3d parameter (must be a
@@ -69,15 +79,36 @@ class GeometryLayer extends Layer {
69
79
  if (object3d.type === 'Group' && object3d.name === '') {
70
80
  object3d.name = id;
71
81
  }
82
+
83
+ /**
84
+ * @type {THREE.Object3D}
85
+ * @readonly
86
+ */
87
+ this.object3d = object3d;
72
88
  Object.defineProperty(this, 'object3d', {
73
- value: object3d,
74
89
  writable: false,
75
90
  configurable: true
76
91
  });
77
- this.opacity = 1.0;
92
+
93
+ /**
94
+ * @type {number}
95
+ */
96
+ this.opacity = opacity;
97
+
98
+ /**
99
+ * @type {boolean}
100
+ */
78
101
  this.wireframe = false;
102
+
103
+ /**
104
+ * @type {Layer[]}
105
+ */
79
106
  this.attachedLayers = [];
80
- this.visible = visible ?? true;
107
+
108
+ /**
109
+ * @type {boolean}
110
+ */
111
+ this.visible = visible;
81
112
  Object.defineProperty(this.zoom, 'max', {
82
113
  value: Infinity,
83
114
  writable: false
@@ -168,17 +168,23 @@ class LabelLayer extends GeometryLayer {
168
168
  */
169
169
  constructor(id) {
170
170
  let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
171
- const domElement = config.domElement;
172
- delete config.domElement;
173
- super(id, config.object3d || new THREE.Group(), config);
171
+ const {
172
+ domElement,
173
+ performance = true,
174
+ forceClampToTerrain = false,
175
+ margin,
176
+ ...geometryConfig
177
+ } = config;
178
+ super(id, config.object3d || new THREE.Group(), geometryConfig);
174
179
  this.isLabelLayer = true;
175
180
  this.domElement = new DomNode();
176
181
  this.domElement.show();
177
182
  this.domElement.dom.id = `itowns-label-${this.id}`;
178
183
  this.buildExtent = true;
179
184
  this.crs = config.source.crs;
180
- this.performance = config.performance || true;
181
- this.forceClampToTerrain = config.forceClampToTerrain || false;
185
+ this.performance = performance;
186
+ this.forceClampToTerrain = forceClampToTerrain;
187
+ this.margin = margin;
182
188
  this.toHide = new THREE.Group();
183
189
  this.labelDomelement = domElement;
184
190
 
@@ -90,62 +90,96 @@ class Layer extends THREE.EventDispatcher {
90
90
  */
91
91
  constructor(id) {
92
92
  let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
93
- /* istanbul ignore next */
94
- if (config.projection) {
95
- console.warn('Layer projection parameter is deprecated, use crs instead.');
96
- config.crs = config.crs || config.projection;
97
- }
98
- if (config.source === undefined || config.source === true) {
99
- throw new Error(`Layer ${id} needs Source`);
100
- }
93
+ const {
94
+ source,
95
+ name,
96
+ style = {},
97
+ subdivisionThreshold = 256,
98
+ addLabelLayer = false,
99
+ cacheLifeTime,
100
+ options = {},
101
+ updateStrategy,
102
+ zoom,
103
+ mergeFeatures = true,
104
+ crs
105
+ } = config;
101
106
  super();
107
+
108
+ /**
109
+ * @type {boolean}
110
+ * @readonly
111
+ */
102
112
  this.isLayer = true;
103
- if (config.style && !(config.style instanceof Style)) {
104
- if (typeof config.style.fill?.pattern === 'string') {
105
- console.warn('Using style.fill.pattern = { source: Img|url } is adviced');
106
- config.style.fill.pattern = {
107
- source: config.style.fill.pattern
108
- };
109
- }
110
- config.style = new Style(config.style);
111
- }
112
- this.style = config.style || new Style();
113
- this.subdivisionThreshold = config.subdivisionThreshold || 256;
114
- this.sizeDiagonalTexture = (2 * (this.subdivisionThreshold * this.subdivisionThreshold)) ** 0.5;
115
- Object.assign(this, config);
113
+
114
+ /**
115
+ * @type {string}
116
+ * @readonly
117
+ */
118
+ this.id = id;
116
119
  Object.defineProperty(this, 'id', {
117
- value: id,
118
120
  writable: false
119
121
  });
120
- // Default properties
121
- this.options = config.options || {};
122
- if (!this.updateStrategy) {
123
- this.updateStrategy = {
124
- type: STRATEGY_MIN_NETWORK_TRAFFIC,
125
- options: {}
126
- };
122
+
123
+ /**
124
+ * @type {string}
125
+ */
126
+ this.name = name;
127
+ if (source === undefined || source === true) {
128
+ throw new Error(`Layer ${id} needs Source`);
127
129
  }
128
- this.defineLayerProperty('frozen', false);
129
- if (config.zoom) {
130
- this.zoom = {
131
- max: config.zoom.max,
132
- min: config.zoom.min || 0
133
- };
134
- if (this.zoom.max == undefined) {
135
- this.zoom.max = Infinity;
130
+ /**
131
+ * @type {Source}
132
+ */
133
+ this.source = source || new Source({
134
+ url: 'none'
135
+ });
136
+ this.crs = crs;
137
+ if (style && !(style instanceof Style)) {
138
+ if (typeof style.fill?.pattern === 'string') {
139
+ console.warn('Using style.fill.pattern = { source: Img|url } is adviced');
140
+ style.fill.pattern = {
141
+ source: style.fill.pattern
142
+ };
136
143
  }
144
+ this.style = new Style(style);
137
145
  } else {
138
- this.zoom = {
139
- max: Infinity,
140
- min: 0
141
- };
146
+ this.style = style || new Style();
142
147
  }
148
+
149
+ /**
150
+ * @type {number}
151
+ */
152
+ this.subdivisionThreshold = subdivisionThreshold;
153
+ this.sizeDiagonalTexture = (2 * (this.subdivisionThreshold * this.subdivisionThreshold)) ** 0.5;
154
+ this.addLabelLayer = addLabelLayer;
155
+
156
+ // Default properties
157
+ this.options = options;
158
+ this.updateStrategy = updateStrategy ?? {
159
+ type: STRATEGY_MIN_NETWORK_TRAFFIC,
160
+ options: {}
161
+ };
162
+ this.defineLayerProperty('frozen', false);
163
+ this.zoom = {
164
+ min: zoom?.min ?? 0,
165
+ max: zoom?.max ?? Infinity
166
+ };
143
167
  this.info = new InfoLayer(this);
144
- this.source = this.source || new Source({
145
- url: 'none'
146
- });
168
+
169
+ /**
170
+ * @type {boolean}
171
+ */
147
172
  this.ready = false;
173
+
174
+ /**
175
+ * @type {Array<Promise<any>>}
176
+ * @protected
177
+ */
148
178
  this._promises = [];
179
+
180
+ /**
181
+ * @type {Promise<this>}
182
+ */
149
183
  this.whenReady = new Promise((re, rj) => {
150
184
  this._resolve = re;
151
185
  this._reject = rj;
@@ -157,11 +191,12 @@ class Layer extends THREE.EventDispatcher {
157
191
  return this;
158
192
  });
159
193
  this._promises.push(this.source.whenReady);
160
- this.cache = new Cache(config.cacheLifeTime);
161
- this.mergeFeatures = this.mergeFeatures === undefined ? true : config.mergeFeatures;
162
194
 
163
- // TODO: verify but this.source.filter seems be always undefined.
164
- this.filter = this.filter || this.source.filter;
195
+ /**
196
+ * @type {Cache}
197
+ */
198
+ this.cache = new Cache(cacheLifeTime);
199
+ this.mergeFeatures = mergeFeatures;
165
200
  }
166
201
  addInitializationStep() {
167
202
  // Possibility to add rejection handler, if it's necessary.
@@ -243,15 +278,6 @@ class Layer extends THREE.EventDispatcher {
243
278
  return data;
244
279
  }
245
280
 
246
- /**
247
- * Determines whether the specified feature is valid data.
248
- *
249
- * @param {Feature} feature The feature
250
- * @returns {Feature} the feature is returned if it's valided
251
- */
252
- // eslint-disable-next-line
253
- isValidData() {}
254
-
255
281
  /**
256
282
  * Remove and dispose all objects from layer.
257
283
  * @param {boolean} [clearCache=false] Whether to clear the layer cache or not
@@ -335,7 +335,8 @@ class OGC3DTilesLayer extends GeometryLayer {
335
335
  const {
336
336
  face,
337
337
  index,
338
- object
338
+ object,
339
+ instanceId
339
340
  } = intersects[0];
340
341
 
341
342
  /** @type{number|null} */
@@ -343,7 +344,7 @@ class OGC3DTilesLayer extends GeometryLayer {
343
344
  if (object.isPoints && index) {
344
345
  batchId = object.geometry.getAttribute('_BATCHID')?.getX(index) ?? index;
345
346
  } else if (object.isMesh && face) {
346
- batchId = object.geometry.getAttribute('_BATCHID')?.getX(face.a);
347
+ batchId = object.geometry.getAttribute('_BATCHID')?.getX(face.a) ?? instanceId;
347
348
  }
348
349
  if (batchId === undefined) {
349
350
  return null;
@@ -96,14 +96,22 @@ class OrientedImageLayer extends GeometryLayer {
96
96
  */
97
97
  constructor(id) {
98
98
  let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
99
+ const {
100
+ backgroundDistance,
101
+ background = createBackground(backgroundDistance),
102
+ onPanoChanged = () => {},
103
+ getCamerasNameFromFeature = () => {},
104
+ ...geometryOptions
105
+ } = config;
106
+
99
107
  /* istanbul ignore next */
100
108
  if (config.projection) {
101
109
  console.warn('OrientedImageLayer projection parameter is deprecated, use crs instead.');
102
110
  config.crs = config.crs || config.projection;
103
111
  }
104
- super(id, new THREE.Group(), config);
112
+ super(id, new THREE.Group(), geometryOptions);
105
113
  this.isOrientedImageLayer = true;
106
- this.background = config.background || createBackground(config.backgroundDistance);
114
+ this.background = background;
107
115
  if (this.background) {
108
116
  // Add layer id to easily identify the objects later on (e.g. to delete the geometries when deleting the layer)
109
117
  this.background.layer = this.background.layer ?? {};
@@ -115,10 +123,10 @@ class OrientedImageLayer extends GeometryLayer {
115
123
  this.currentPano = undefined;
116
124
 
117
125
  // store a callback to fire event when current panoramic change
118
- this.onPanoChanged = config.onPanoChanged || (() => {});
126
+ this.onPanoChanged = onPanoChanged;
119
127
 
120
128
  // function to get cameras name from panoramic feature
121
- this.getCamerasNameFromFeature = config.getCamerasNameFromFeature || (() => {});
129
+ this.getCamerasNameFromFeature = getCamerasNameFromFeature;
122
130
  const resolve = this.addInitializationStep();
123
131
  this.mergeFeatures = false;
124
132
  this.filteringExtent = false;
@@ -113,6 +113,8 @@ function changeAngleRange(layer) {
113
113
  * @property {number} [maxIntensityRange=1] - The maximal intensity of the
114
114
  * layer. Changing this value will affect the material, if it has the
115
115
  * corresponding uniform. The value is normalized between 0 and 1.
116
+ *
117
+ * @extends GeometryLayer
116
118
  */
117
119
  class PointCloudLayer extends GeometryLayer {
118
120
  /**
@@ -120,8 +122,6 @@ class PointCloudLayer extends GeometryLayer {
120
122
  * Constructs a new instance of a Point Cloud Layer. This should not be used
121
123
  * directly, but rather implemented using `extends`.
122
124
  *
123
- * @extends GeometryLayer
124
- *
125
125
  * @param {string} id - The id of the layer, that should be unique. It is
126
126
  * not mandatory, but an error will be emitted if this layer is added a
127
127
  * {@link View} that already has a layer going by that id.
@@ -130,40 +130,86 @@ class PointCloudLayer extends GeometryLayer {
130
130
  * contains three elements `name, protocol, extent`, these elements will be
131
131
  * available using `layer.name` or something else depending on the property
132
132
  * name. See the list of properties to know which one can be specified.
133
+ * @param {Source} config.source - Description and options of the source.
133
134
  */
134
135
  constructor(id) {
135
136
  let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
136
- super(id, config.object3d || new THREE.Group(), config);
137
+ const {
138
+ object3d = new THREE.Group(),
139
+ group = new THREE.Group(),
140
+ bboxes = new THREE.Group(),
141
+ octreeDepthLimit = -1,
142
+ pointBudget = 2000000,
143
+ pointSize = 2,
144
+ sseThreshold = 2,
145
+ minIntensityRange = 1,
146
+ maxIntensityRange = 65536,
147
+ minElevationRange = 0,
148
+ maxElevationRange = 1000,
149
+ minAngleRange = -90,
150
+ maxAngleRange = 90,
151
+ material = {},
152
+ mode = PNTS_MODE.COLOR,
153
+ ...geometryLayerConfig
154
+ } = config;
155
+ super(id, object3d, geometryLayerConfig);
156
+
157
+ /**
158
+ * @type {boolean}
159
+ * @readonly
160
+ */
137
161
  this.isPointCloudLayer = true;
138
162
  this.protocol = 'pointcloud';
139
- this.group = config.group || new THREE.Group();
163
+ this.group = group;
140
164
  this.object3d.add(this.group);
141
- this.bboxes = config.bboxes || new THREE.Group();
165
+ this.bboxes = bboxes || new THREE.Group();
142
166
  this.bboxes.visible = false;
143
167
  this.object3d.add(this.bboxes);
144
168
  this.group.updateMatrixWorld();
145
169
 
146
170
  // default config
147
- this.octreeDepthLimit = config.octreeDepthLimit || -1;
148
- this.pointBudget = config.pointBudget || 2000000;
149
- this.pointSize = config.pointSize === 0 || !isNaN(config.pointSize) ? config.pointSize : 4;
150
- this.sseThreshold = config.sseThreshold || 2;
151
- this.defineLayerProperty('minIntensityRange', config.minIntensityRange || 1, changeIntensityRange);
152
- this.defineLayerProperty('maxIntensityRange', config.maxIntensityRange || 65536, changeIntensityRange);
153
- this.defineLayerProperty('minElevationRange', config.minElevationRange || 0, changeElevationRange);
154
- this.defineLayerProperty('maxElevationRange', config.maxElevationRange || 1000, changeElevationRange);
155
- this.defineLayerProperty('minAngleRange', config.minAngleRange || -90, changeAngleRange);
156
- this.defineLayerProperty('maxAngleRange', config.maxAngleRange || 90, changeAngleRange);
157
- this.material = config.material || {};
171
+ /**
172
+ * @type {number}
173
+ */
174
+ this.octreeDepthLimit = octreeDepthLimit;
175
+
176
+ /**
177
+ * @type {number}
178
+ */
179
+ this.pointBudget = pointBudget;
180
+
181
+ /**
182
+ * @type {number}
183
+ */
184
+ this.pointSize = pointSize;
185
+
186
+ /**
187
+ * @type {number}
188
+ */
189
+ this.sseThreshold = sseThreshold;
190
+ this.defineLayerProperty('minIntensityRange', minIntensityRange, changeIntensityRange);
191
+ this.defineLayerProperty('maxIntensityRange', maxIntensityRange, changeIntensityRange);
192
+ this.defineLayerProperty('minElevationRange', minElevationRange, changeElevationRange);
193
+ this.defineLayerProperty('maxElevationRange', maxElevationRange, changeElevationRange);
194
+ this.defineLayerProperty('minAngleRange', minAngleRange, changeAngleRange);
195
+ this.defineLayerProperty('maxAngleRange', maxAngleRange, changeAngleRange);
196
+
197
+ /**
198
+ * @type {THREE.Material}
199
+ */
200
+ this.material = material;
158
201
  if (!this.material.isMaterial) {
159
- config.material = config.material || {};
160
- config.material.intensityRange = new THREE.Vector2(this.minIntensityRange, this.maxIntensityRange);
161
- config.material.elevationRange = new THREE.Vector2(this.minElevationRange, this.maxElevationRange);
162
- config.material.angleRange = new THREE.Vector2(this.minAngleRange, this.maxAngleRange);
163
- this.material = new PointsMaterial(config.material);
202
+ this.material.intensityRange = new THREE.Vector2(this.minIntensityRange, this.maxIntensityRange);
203
+ this.material.elevationRange = new THREE.Vector2(this.minElevationRange, this.maxElevationRange);
204
+ this.material.angleRange = new THREE.Vector2(this.minAngleRange, this.maxAngleRange);
205
+ this.material = new PointsMaterial(this.material);
164
206
  }
165
- this.material.defines = this.material.defines || {};
166
- this.mode = config.mode || PNTS_MODE.COLOR;
207
+ this.mode = mode || PNTS_MODE.COLOR;
208
+
209
+ /**
210
+ * @type {PointCloudNode | undefined}
211
+ */
212
+ this.root = undefined;
167
213
  }
168
214
  preUpdate(context, changeSources) {
169
215
  // See https://cesiumjs.org/hosted-apps/massiveworlds/downloads/Ring/WorldScaleTerrainRendering.pptx
@@ -99,13 +99,13 @@ function parseAttributes(jsonAttributes) {
99
99
  * @property {boolean} isPotreeLayer - Used to checkout whether this layer
100
100
  * is a Potree2Layer. Default is `true`. You should not change this, as it is
101
101
  * used internally for optimisation.
102
+ *
103
+ * @extends PointCloudLayer
102
104
  */
103
105
  class Potree2Layer extends PointCloudLayer {
104
106
  /**
105
107
  * Constructs a new instance of Potree2 layer.
106
108
  *
107
- * @extends PointCloudLayer
108
- *
109
109
  * @example
110
110
  * // Create a new point cloud layer
111
111
  * const points = new Potree2Layer('points',
@@ -132,6 +132,11 @@ class Potree2Layer extends PointCloudLayer {
132
132
  */
133
133
  constructor(id, config) {
134
134
  super(id, config);
135
+
136
+ /**
137
+ * @type {boolean}
138
+ * @readonly
139
+ */
135
140
  this.isPotreeLayer = true;
136
141
  const resolve = this.addInitializationStep();
137
142
  this.source.whenReady.then(metadata => {