itowns 2.43.2-next.1 → 2.43.2-next.11

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 (60) hide show
  1. package/README.md +2 -0
  2. package/dist/debug.js +1 -1
  3. package/dist/debug.js.map +1 -1
  4. package/dist/itowns.js +1 -1
  5. package/dist/itowns.js.map +1 -1
  6. package/dist/itowns_widgets.js +1 -1
  7. package/dist/itowns_widgets.js.map +1 -1
  8. package/examples/3dtiles_25d.html +1 -1
  9. package/examples/3dtiles_basic.html +2 -2
  10. package/examples/3dtiles_batch_table.html +1 -3
  11. package/examples/3dtiles_pointcloud.html +9 -15
  12. package/examples/copc_simple_loader.html +1 -1
  13. package/examples/entwine_3d_loader.html +1 -1
  14. package/examples/entwine_simple_loader.html +1 -1
  15. package/examples/js/plugins/COGParser.js +84 -50
  16. package/examples/js/plugins/COGSource.js +7 -4
  17. package/examples/layers/JSONLayers/OPENSM.json +1 -1
  18. package/examples/potree_25d_map.html +1 -1
  19. package/examples/potree_3d_map.html +1 -1
  20. package/examples/source_file_cog.html +22 -5
  21. package/lib/Controls/FirstPersonControls.js +0 -1
  22. package/lib/Controls/FlyControls.js +0 -1
  23. package/lib/Converter/Feature2Mesh.js +2 -4
  24. package/lib/Converter/textureConverter.js +1 -1
  25. package/lib/Core/3DTiles/C3DTBatchTable.js +1 -1
  26. package/lib/Core/3DTiles/C3DTFeature.js +0 -1
  27. package/lib/Core/Feature.js +1 -2
  28. package/lib/Core/Geographic/CoordStars.js +0 -1
  29. package/lib/Core/Label.js +0 -1
  30. package/lib/Core/MainLoop.js +0 -1
  31. package/lib/Core/Prefab/Globe/Atmosphere.js +0 -4
  32. package/lib/Core/Prefab/Globe/GlobeLayer.js +3 -3
  33. package/lib/Core/Style.js +2 -4
  34. package/lib/Core/View.js +2 -4
  35. package/lib/Layer/C3DTilesLayer.js +3 -1
  36. package/lib/Layer/ElevationLayer.js +2 -3
  37. package/lib/Layer/GeoidLayer.js +1 -2
  38. package/lib/Layer/LabelLayer.js +8 -17
  39. package/lib/Layer/Layer.js +4 -2
  40. package/lib/Layer/PointCloudLayer.js +4 -7
  41. package/lib/Layer/ReferencingLayerProperties.js +3 -3
  42. package/lib/Layer/TiledGeometryLayer.js +2 -3
  43. package/lib/Parser/GeoJsonParser.js +2 -3
  44. package/lib/Parser/LASParser.js +2 -3
  45. package/lib/Parser/deprecated/LegacyGLTFLoader.js +1 -2
  46. package/lib/Process/FeatureProcessing.js +1 -2
  47. package/lib/Process/LayeredMaterialNodeProcessing.js +3 -9
  48. package/lib/Process/ObjectRemovalHelper.js +1 -2
  49. package/lib/Provider/3dTilesProvider.js +1 -0
  50. package/lib/Renderer/ColorLayersOrdering.js +1 -2
  51. package/lib/Renderer/Label2DRenderer.js +1 -4
  52. package/lib/Renderer/PointsMaterial.js +14 -9
  53. package/lib/Renderer/RenderMode.js +0 -1
  54. package/lib/ThreeExtended/loaders/DDSLoader.js +11 -1
  55. package/lib/ThreeExtended/loaders/DRACOLoader.js +0 -1
  56. package/lib/ThreeExtended/loaders/GLTFLoader.js +1 -0
  57. package/lib/Utils/DEMUtils.js +2 -2
  58. package/lib/Utils/OrientationUtils.js +0 -1
  59. package/lib/Utils/gui/Searchbar.js +1 -2
  60. package/package.json +8 -7
@@ -22,10 +22,8 @@
22
22
  * @returns {GeoTIFFLevel} The selected zoom level.
23
23
  */
24
24
  function selectLevel(source, requestExtent, requestWidth, requestHeight) {
25
- // Number of images = original + overviews if any
26
- const cropped = requestExtent.clone().intersect(source.extent);
27
25
  // Dimensions of the requested extent
28
- const extentDimension = cropped.planarDimensions();
26
+ const extentDimension = requestExtent.clone().planarDimensions();
29
27
 
30
28
  const targetResolution = Math.min(
31
29
  extentDimension.x / requestWidth,
@@ -87,70 +85,112 @@ function makeWindowFromExtent(source, extent, resolution) {
87
85
  }
88
86
 
89
87
  /**
90
- * Creates a texture from the pixel buffer(s).
88
+ * Reads raster data from the image as RGB.
89
+ * The result is always an interleaved typed array.
90
+ * Colorspaces other than RGB will be transformed to RGB, color maps expanded.
91
+ *
92
+ * @param {Source} source The COGSource.
93
+ * @param {GeoTIFFLevel} level The GeoTIFF level to read
94
+ * @param {number[]} viewport The image region to read.
95
+ * @returns {Promise<TypedArray[]>} The raster data
96
+ */
97
+ async function readRGB(source, level, viewport) {
98
+ try {
99
+ // TODO possible optimization: instead of letting geotiff.js crop and resample
100
+ // the tiles into the desired region, we could use image.getTileOrStrip() to
101
+ // read individual tiles (aka blocks) and make a texture per block. This way,
102
+ // there would not be multiple concurrent reads for the same block, and we would not
103
+ // waste time resampling the blocks since resampling is already done in the composer.
104
+ // We would create more textures, but it could be worth it.
105
+ return await level.image.readRGB({
106
+ window: viewport,
107
+ pool: source.pool,
108
+ width: source.tileWidth,
109
+ height: source.tileHeight,
110
+ resampleMethod: source.resampleMethod,
111
+ enableAlpha: true,
112
+ interleave: true,
113
+ });
114
+ } catch (error) {
115
+ if (error.toString() === 'AggregateError: Request failed') {
116
+ // Problem with the source that is blocked by another fetch
117
+ // (request failed in readRasters). See the conversations in
118
+ // https://github.com/geotiffjs/geotiff.js/issues/218
119
+ // https://github.com/geotiffjs/geotiff.js/issues/221
120
+ // https://github.com/geotiffjs/geotiff.js/pull/224
121
+ // Retry until it is not blocked.
122
+ // TODO retry counter
123
+ await new Promise((resolve) => {
124
+ setTimeout(resolve, 100);
125
+ });
126
+ return readRGB(level, viewport, source);
127
+ }
128
+ throw error;
129
+ }
130
+ }
131
+
132
+ /**
133
+ * Creates a texture from the pixel buffer
91
134
  *
92
135
  * @param {Object} source The COGSource
93
- * @param {THREE.TypedArray | THREE.TypedArray[]} buffers The buffers (one buffer per band)
94
- * @param {number} buffers.width
95
- * @param {number} buffers.height
96
- * @param {number} buffers.byteLength
136
+ * @param {THREE.TypedArray[]} buffer The pixel buffer
137
+ * @param {number} buffer.width
138
+ * @param {number} buffer.height
139
+ * @param {number} buffer.byteLength
97
140
  * @returns {THREE.DataTexture} The generated texture.
98
141
  */
99
- function createTexture(source, buffers) {
100
- const { width, height, byteLength } = buffers;
142
+ function createTexture(source, buffer) {
143
+ const { byteLength } = buffer;
144
+ const width = source.tileWidth;
145
+ const height = source.tileHeight;
101
146
  const pixelCount = width * height;
102
147
  const targetDataType = source.dataType;
103
148
  const format = THREE.RGBAFormat;
104
149
  const channelCount = 4;
105
- let texture;
106
- let data;
107
-
108
- // Check if it's a RGBA buffer
109
- if (pixelCount * channelCount === byteLength) {
110
- data = buffers;
111
- }
150
+ const isRGBA = pixelCount * channelCount === byteLength;
151
+ let tmpBuffer = buffer;
112
152
 
113
153
  switch (targetDataType) {
114
154
  case THREE.UnsignedByteType: {
115
- if (!data) {
116
- // We convert RGB buffer to RGBA
117
- const newBuffers = new Uint8ClampedArray(pixelCount * channelCount);
118
- data = convertToRGBA(buffers, newBuffers, source.defaultAlpha);
155
+ if (!isRGBA) {
156
+ tmpBuffer = convertToRGBA(tmpBuffer, new Uint8ClampedArray(pixelCount * channelCount), source.defaultAlpha);
119
157
  }
120
- texture = new THREE.DataTexture(data, width, height, format, THREE.UnsignedByteType);
121
- break;
158
+ return new THREE.DataTexture(tmpBuffer, width, height, format, THREE.UnsignedByteType);
122
159
  }
123
160
  case THREE.FloatType: {
124
- if (!data) {
125
- // We convert RGB buffer to RGBA
126
- const newBuffers = new Float32Array(pixelCount * channelCount);
127
- data = convertToRGBA(buffers, newBuffers, source.defaultAlpha / 255);
161
+ if (!isRGBA) {
162
+ tmpBuffer = convertToRGBA(tmpBuffer, new Float32Array(pixelCount * channelCount), source.defaultAlpha / 255);
128
163
  }
129
- texture = new THREE.DataTexture(data, width, height, format, THREE.FloatType);
130
- break;
164
+ return new THREE.DataTexture(tmpBuffer, width, height, format, THREE.FloatType);
131
165
  }
132
166
  default:
133
167
  throw new Error('unsupported data type');
134
168
  }
135
-
136
- return texture;
137
169
  }
138
170
 
139
- function convertToRGBA(buffers, newBuffers, defaultAlpha) {
140
- const { width, height } = buffers;
171
+ /**
172
+ * Convert RGB pixel buffer to RGBA pixel buffer
173
+ *
174
+ * @param {THREE.TypedArray[]} buffer The RGB pixel buffer
175
+ * @param {THREE.TypedArray[]} newBuffer The empty RGBA pixel buffer
176
+ * @param {number} defaultAlpha Default alpha value
177
+ * @returns {THREE.DataTexture} The generated texture.
178
+ */
179
+ function convertToRGBA(buffer, newBuffer, defaultAlpha) {
180
+ const { width, height } = buffer;
141
181
 
142
182
  for (let i = 0; i < width * height; i++) {
143
183
  const oldIndex = i * 3;
144
184
  const index = i * 4;
145
185
  // Copy RGB from original buffer
146
- newBuffers[index + 0] = buffers[oldIndex + 0]; // R
147
- newBuffers[index + 1] = buffers[oldIndex + 1]; // G
148
- newBuffers[index + 2] = buffers[oldIndex + 2]; // B
186
+ newBuffer[index + 0] = buffer[oldIndex + 0]; // R
187
+ newBuffer[index + 1] = buffer[oldIndex + 1]; // G
188
+ newBuffer[index + 2] = buffer[oldIndex + 2]; // B
149
189
  // Add alpha to new buffer
150
- newBuffers[index + 3] = defaultAlpha; // A
190
+ newBuffer[index + 3] = defaultAlpha; // A
151
191
  }
152
192
 
153
- return newBuffers;
193
+ return newBuffer;
154
194
  }
155
195
 
156
196
  /**
@@ -195,20 +235,14 @@ const COGParser = (function _() {
195
235
  */
196
236
  parse: async function _(data, options) {
197
237
  const source = options.in;
198
- const nodeExtent = data.extent.as(source.crs);
199
- const level = selectLevel(source, nodeExtent, source.tileWidth, source.tileHeight);
200
- const viewport = makeWindowFromExtent(source, nodeExtent, level.resolution);
201
-
202
- const buffers = await level.image.readRGB({
203
- window: viewport,
204
- pool: source.pool,
205
- enableAlpha: true,
206
- interleave: true,
207
- });
238
+ const tileExtent = options.extent.as(source.crs);
208
239
 
209
- const texture = createTexture(source, buffers);
240
+ const level = selectLevel(source, tileExtent, source.tileWidth, source.tileHeight);
241
+ const viewport = makeWindowFromExtent(source, tileExtent, level.resolution);
242
+ const rgbBuffer = await readRGB(source, level, viewport);
243
+ const texture = createTexture(source, rgbBuffer);
210
244
  texture.flipY = true;
211
- texture.extent = data.extent;
245
+ texture.extent = options.extent;
212
246
  texture.needsUpdate = true;
213
247
  texture.magFilter = THREE.LinearFilter;
214
248
  texture.minFilter = THREE.LinearFilter;
@@ -15,6 +15,9 @@
15
15
  * @property {string} url - The URL of the COG.
16
16
  * @property {GeoTIFF.Pool} pool - Pool use to decode GeoTiff.
17
17
  * @property {number} defaultAlpha - Alpha byte value used if no alpha is present in COG. Default value is 255.
18
+ * @property {number} tileWidth - Tile width in pixels. Default value use 'geotiff.getTileWidth()'.
19
+ * @property {number} tileHeight - Tile height in pixels. Default value use 'geotiff.getTileHeight()'.
20
+ * @property {number} resampleMethod - The desired resampling method. Default is 'nearest'.
18
21
  *
19
22
  * @example
20
23
  * // Create the source
@@ -59,9 +62,9 @@ class COGSource extends itowns.Source {
59
62
  this.firstImage = await geotiff.getImage();
60
63
  this.origin = this.firstImage.getOrigin();
61
64
  this.dataType = this.selectDataType(this.firstImage.getSampleFormat(), this.firstImage.getBitsPerSample());
62
-
63
- this.tileWidth = this.firstImage.getTileWidth();
64
- this.tileHeight = this.firstImage.getTileHeight();
65
+ this.tileWidth = source.tileWidth || this.firstImage.getTileWidth();
66
+ this.tileHeight = source.tileHeight || this.firstImage.getTileHeight();
67
+ this.resampleMethod = source.resampleMethod || 'nearest';
65
68
 
66
69
  // Compute extent
67
70
  const [minX, minY, maxX, maxY] = this.firstImage.getBoundingBox();
@@ -80,7 +83,7 @@ class COGSource extends itowns.Source {
80
83
  .then(image => this.makeLevel(image, image.getResolution(this.firstImage)));
81
84
  promises.push(promise);
82
85
  }
83
- this.levels.push(await Promise.all(promises));
86
+ this.levels = this.levels.concat(await Promise.all(promises));
84
87
  });
85
88
  }
86
89
 
@@ -4,7 +4,7 @@
4
4
  "crs": "EPSG:3857",
5
5
  "isInverted": true,
6
6
  "format": "image/png",
7
- "url": "http://osm.oslandia.io/styles/klokantech-basic/${z}/${x}/${y}.png",
7
+ "url": "https://maps.pole-emploi.fr/styles/klokantech-basic/${z}/${x}/${y}.png",
8
8
  "attribution": {
9
9
  "name":"OpenStreetMap",
10
10
  "url": "http://www.openstreetmap.org/"
@@ -102,7 +102,7 @@
102
102
  potreeLayer.root.bbox.getSize(size);
103
103
  potreeLayer.root.bbox.getCenter(lookAt);
104
104
 
105
- debug.PotreeDebug.initTools(view, potreeLayer, debugGui);
105
+ debug.PointCloudDebug.initTools(view, potreeLayer, debugGui);
106
106
 
107
107
  view.camera3D.far = 2.0 * size.length();
108
108
 
@@ -71,7 +71,7 @@
71
71
 
72
72
  // add potreeLayer to scene
73
73
  function onLayerReady() {
74
- debug.PotreeDebug.initTools(view, potreeLayer, debugGui);
74
+ debug.PointCloudDebug.initTools(view, potreeLayer, debugGui);
75
75
 
76
76
  // update stats window
77
77
  var info = document.getElementById('info');
@@ -36,6 +36,7 @@
36
36
  itowns.proj4.defs('EPSG:2154', '+proj=lcc +lat_1=49 +lat_2=44 +lat_0=46.5 +lon_0=3 +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs');
37
37
 
38
38
  var viewerDiv = document.getElementById('viewerDiv');
39
+ var view;
39
40
 
40
41
  function readCOGURL() {
41
42
  var url = document.getElementById('cog_url').value || new URLSearchParams(window.location.search).get('geotiff');
@@ -47,7 +48,7 @@
47
48
  }
48
49
 
49
50
  function loadRGBSample() {
50
- document.getElementById('cog_url').value = 'https://cdn.jsdelivr.net/gh/bloc-in-bloc/iTowns2-sample-data@add-cog-sample/cog/orvault.tif';
51
+ document.getElementById('cog_url').value = 'https://cdn.jsdelivr.net/gh/iTowns/iTowns2-sample-data/cog/nantes/nantes.tif';
51
52
  readCOGURL();
52
53
  }
53
54
 
@@ -56,17 +57,33 @@
56
57
  readCOGURL();
57
58
  }
58
59
 
59
- function loadCOG(url, crs) {
60
+ function removeAllChildNodes(parent) {
61
+ while (parent.firstChild) {
62
+ parent.removeChild(parent.firstChild);
63
+ }
64
+ }
65
+
66
+ function loadCOG(url) {
60
67
  // create a source from a Cloud Optimized GeoTiff
61
68
  var cogSource = new COGSource({
62
69
  url: url,
63
- crs: "EPSG:2154"
70
+ crs: "EPSG:2154",
71
+ // Default resample method is 'nearest', 'bilinear' looks better when zoomed
72
+ resampleMethod: 'bilinear'
64
73
  });
65
74
 
66
75
  cogSource.whenReady.then(() => {
67
- var view = new itowns.PlanarView(viewerDiv, cogSource.extent, { disableSkirt: true, placement: { tilt: 90 } });
76
+ if (view !== undefined) {
77
+ view.dispose(true);
78
+ removeAllChildNodes(viewerDiv);
79
+ }
80
+ view = new itowns.PlanarView(viewerDiv, cogSource.extent, {
81
+ // Default maxSubdivisionLevel is 5, so with huge geotiff it's not enough to see details when zoomed
82
+ maxSubdivisionLevel: 10,
83
+ disableSkirt: true,
84
+ placement: { tilt: 90 }
85
+ });
68
86
  setupLoadingScreen(viewerDiv, view);
69
- new itowns.PlanarControls(view, {});
70
87
  var cogLayer = new itowns.ColorLayer('cog', {
71
88
  source: cogSource,
72
89
  });
@@ -49,7 +49,6 @@ const MOVEMENTS = {
49
49
  sign: -1
50
50
  } // DOWN: PageDown key
51
51
  };
52
-
53
52
  function moveCameraVerticalPlanar(value) {
54
53
  this.camera.position.z += value;
55
54
  }
@@ -45,7 +45,6 @@ const MOVEMENTS = {
45
45
  oneshot: true
46
46
  } // WHEEL down
47
47
  };
48
-
49
48
  function onDocumentMouseDown(event) {
50
49
  event.preventDefault();
51
50
  this._isMouseDown = true;
@@ -416,7 +416,6 @@ function featureToExtrudedPolygon(feature, options) {
416
416
  meshColor.toArray(colors, t); // top
417
417
  meshColor.multiplyScalar(0.5).toArray(colors, i); // base is half dark
418
418
  }
419
-
420
419
  featureId++;
421
420
  const geomVertices = vertices.slice(startTop * 3, (end + totalVertices) * 3);
422
421
  const holesOffsets = geometry.indices.map(i => i.offset - start).slice(1);
@@ -496,14 +495,13 @@ function pointsToInstancedMeshes(feature) {
496
495
  * @return {THREE.Mesh} mesh or GROUP of THREE.InstancedMesh
497
496
  */
498
497
  function featureToMesh(feature, options) {
499
- var _style$point, _style$point$model;
500
498
  if (!feature.vertices) {
501
499
  return;
502
500
  }
503
501
  let mesh;
504
502
  switch (feature.type) {
505
503
  case FEATURE_TYPES.POINT:
506
- if ((_style$point = style.point) !== null && _style$point !== void 0 && (_style$point$model = _style$point.model) !== null && _style$point$model !== void 0 && _style$point$model.object) {
504
+ if (style.point?.model?.object) {
507
505
  try {
508
506
  mesh = pointsToInstancedMeshes(feature);
509
507
  mesh.isInstancedMesh = true;
@@ -592,7 +590,7 @@ export default {
592
590
  // style properties (@link StyleOptions) using options.style.
593
591
  // This is usually done in some tests and if you want to use Feature2Mesh.convert()
594
592
  // as in examples/source_file_gpx_3d.html.
595
- style = (this === null || this === void 0 ? void 0 : this.style) || (options.style ? new Style(options.style) : defaultStyle);
593
+ style = this?.style || (options.style ? new Style(options.style) : defaultStyle);
596
594
  context.setCollection(collection);
597
595
  const features = collection.features;
598
596
  if (!features || features.length == 0) {
@@ -21,7 +21,7 @@ export default {
21
21
  const backgroundLayer = layer.source.backgroundLayer;
22
22
  const backgroundColor = backgroundLayer && backgroundLayer.paint ? new THREE.Color(backgroundLayer.paint['background-color']) : undefined;
23
23
  extentDestination.as(CRS.formatToEPSG(layer.crs), extentTexture);
24
- texture = Feature2Texture.createTextureFromFeature(data, extentTexture, 256, layer.style, backgroundColor);
24
+ texture = Feature2Texture.createTextureFromFeature(data, extentTexture, layer.subdivisionThreshold, layer.style, backgroundColor);
25
25
  texture.features = data;
26
26
  texture.extent = extentDestination;
27
27
  } else if (data.isTexture) {
@@ -52,7 +52,7 @@ class C3DTBatchTable {
52
52
  if (Array.isArray(propVal)) {
53
53
  continue;
54
54
  }
55
- if (typeof (propVal === null || propVal === void 0 ? void 0 : propVal.byteOffset) !== 'undefined' && typeof (propVal === null || propVal === void 0 ? void 0 : propVal.componentType) !== 'undefined' && typeof (propVal === null || propVal === void 0 ? void 0 : propVal.type) !== 'undefined') {
55
+ if (typeof propVal?.byteOffset !== 'undefined' && typeof propVal?.componentType !== 'undefined' && typeof propVal?.type !== 'undefined') {
56
56
  jsonContent[propKey] = binaryPropertyAccessor(binaryBuffer, this.batchLength, propVal.byteOffset, propVal.componentType, propVal.type);
57
57
  } else {
58
58
  console.error('Invalid 3D Tiles batch table property that is neither a JSON array nor a valid ' + 'accessor to a binary body');
@@ -103,7 +103,6 @@ class C3DTFeature {
103
103
  console.warn(`[C3DTFeature]: No batch table found for tile ${this.tileId}.`);
104
104
  return null; // or return undefined;
105
105
  }
106
-
107
106
  this.#info = batchTable.getInfoById(this.batchId);
108
107
  return this.#info;
109
108
  }
@@ -338,10 +338,9 @@ export class FeatureCollection extends THREE.Object3D {
338
338
  * @param {FeatureBuildingOptions|Layer} options The building options .
339
339
  */
340
340
  constructor(options) {
341
- var _options$source;
342
341
  super();
343
342
  this.isFeatureCollection = true;
344
- this.crs = CRS.formatToEPSG(options.accurate || !((_options$source = options.source) !== null && _options$source !== void 0 && _options$source.crs) ? options.crs : options.source.crs);
343
+ this.crs = CRS.formatToEPSG(options.accurate || !options.source?.crs ? options.crs : options.source.crs);
345
344
  this.features = [];
346
345
  this.mergeFeatures = options.mergeFeatures === undefined ? true : options.mergeFeatures;
347
346
  this.size = options.structure == '3d' ? 3 : 2;
@@ -68,7 +68,6 @@ const CoordStars = {
68
68
  };
69
69
  };
70
70
  },
71
-
72
71
  // Return scene coordinate ({x,y,z}) of sun
73
72
  getSunPositionInScene(date, lat, lon) {
74
73
  const sun = CoordStars.getSunPosition()(date, lat, lon);
package/lib/Core/Label.js CHANGED
@@ -71,7 +71,6 @@ class Label extends THREE.Object3D {
71
71
  // TODO: add smooth transition for fade in/out
72
72
  }
73
73
  },
74
-
75
74
  get() {
76
75
  return _visible;
77
76
  }
@@ -88,7 +88,6 @@ class MainLoop extends EventDispatcher {
88
88
  this.scheduler = scheduler;
89
89
  this.gfxEngine = engine; // TODO: remove me
90
90
  }
91
-
92
91
  scheduleViewUpdate(view, forceRedraw) {
93
92
  this.#needsRedraw |= forceRedraw;
94
93
  if (this.renderingState !== RENDERING_SCHEDULED) {
@@ -72,7 +72,6 @@ class Atmosphere extends GeometryLayer {
72
72
  value: new THREE.Vector2(window.innerWidth, window.innerHeight)
73
73
  } // Should be updated on screen resize...
74
74
  },
75
-
76
75
  vertexShader: GlowVS,
77
76
  fragmentShader: GlowFS,
78
77
  side: THREE.BackSide,
@@ -100,7 +99,6 @@ class Atmosphere extends GeometryLayer {
100
99
  value: new THREE.Vector2(window.innerWidth, window.innerHeight)
101
100
  } // Should be updated on screen resize...
102
101
  },
103
-
104
102
  vertexShader: GlowVS,
105
103
  fragmentShader: GlowFS,
106
104
  side: THREE.FrontSide,
@@ -135,7 +133,6 @@ class Atmosphere extends GeometryLayer {
135
133
  scaleDepth: 0.25
136
134
  // mieScaleDepth: 0.1,
137
135
  };
138
-
139
136
  this.object3d.updateMatrixWorld();
140
137
  }
141
138
  update(context, layer, node) {
@@ -288,7 +285,6 @@ class Atmosphere extends GeometryLayer {
288
285
  skyDome.material.uniforms.mieDirectionalG.value = effectController.mieDirectionalG;
289
286
  skyDome.material.uniforms.up.value = new THREE.Vector3(); // no more necessary, estimate normal from cam..
290
287
  }
291
-
292
288
  setRealisticOn(bool) {
293
289
  if (bool) {
294
290
  if (!this.realisticAtmosphere.children.length) {
@@ -3,7 +3,6 @@ import TiledGeometryLayer from "../../../Layer/TiledGeometryLayer.js";
3
3
  import { ellipsoidSizes } from "../../Math/Ellipsoid.js";
4
4
  import { globalExtentTMS, schemeTiles } from "../../Geographic/Extent.js";
5
5
  import BuilderEllipsoidTile from "./BuilderEllipsoidTile.js";
6
- import { SIZE_DIAGONAL_TEXTURE } from "../../../Process/LayeredMaterialNodeProcessing.js";
7
6
  import CRS from "../../Geographic/Crs.js";
8
7
 
9
8
  // matrix to convert sphere to ellipsoid
@@ -129,7 +128,7 @@ class GlobeLayer extends TiledGeometryLayer {
129
128
  return isOccluded;
130
129
  }
131
130
  computeTileZoomFromDistanceCamera(distance, camera) {
132
- const preSinus = SIZE_DIAGONAL_TEXTURE * (this.sseSubdivisionThreshold * 0.5) / camera._preSSE / ellipsoidSizes.x;
131
+ const preSinus = this.sizeDiagonalTexture * (this.sseSubdivisionThreshold * 0.5) / camera._preSSE / ellipsoidSizes.x;
133
132
  let sinus = distance * preSinus;
134
133
  let zoom = Math.log(Math.PI / (2.0 * Math.asin(sinus))) / Math.log(2);
135
134
  const delta = Math.PI / 2 ** zoom;
@@ -143,7 +142,8 @@ class GlobeLayer extends TiledGeometryLayer {
143
142
  const delta = Math.PI / 2 ** zoom;
144
143
  const circleChord = 2.0 * ellipsoidSizes.x * Math.sin(delta * 0.5);
145
144
  const radius = circleChord * 0.5;
146
- return camera._preSSE * (radius / SIZE_DIAGONAL_TEXTURE) / (this.sseSubdivisionThreshold * 0.5) + radius;
145
+ const error = radius / this.sizeDiagonalTexture;
146
+ return camera._preSSE * error / (this.sseSubdivisionThreshold * 0.5) + radius;
147
147
  }
148
148
  }
149
149
  export default GlobeLayer;
package/lib/Core/Style.js CHANGED
@@ -12,8 +12,7 @@ const matrix = document.createElementNS('http://www.w3.org/2000/svg', 'svg').cre
12
12
  const canvas = document.createElement('canvas');
13
13
  const inv255 = 1 / 255;
14
14
  function baseAltitudeDefault(properties, ctx) {
15
- var _ctx$coordinates;
16
- return (ctx === null || ctx === void 0 ? void 0 : (_ctx$coordinates = ctx.coordinates) === null || _ctx$coordinates === void 0 ? void 0 : _ctx$coordinates.z) || 0;
15
+ return ctx?.coordinates?.z || 0;
17
16
  }
18
17
  export function readExpression(property, ctx) {
19
18
  if (property != undefined) {
@@ -154,7 +153,6 @@ function defineStyleProperty(style, category, parameter, userValue, defaultValue
154
153
  Object.defineProperty(style[category], parameter, {
155
154
  enumerable: true,
156
155
  get: () => {
157
- var _style$context$featur, _style$context$featur2;
158
156
  // != to check for 'undefined' and 'null' value)
159
157
  if (property != undefined) {
160
158
  return property;
@@ -162,7 +160,7 @@ function defineStyleProperty(style, category, parameter, userValue, defaultValue
162
160
  if (userValue != undefined) {
163
161
  return readExpression(userValue, style.context);
164
162
  }
165
- const dataValue = (_style$context$featur = style.context.featureStyle) === null || _style$context$featur === void 0 ? void 0 : (_style$context$featur2 = _style$context$featur[category]) === null || _style$context$featur2 === void 0 ? void 0 : _style$context$featur2[parameter];
163
+ const dataValue = style.context.featureStyle?.[category]?.[parameter];
166
164
  if (dataValue != undefined) {
167
165
  return readExpression(dataValue, style.context);
168
166
  }
package/lib/Core/View.js CHANGED
@@ -232,8 +232,7 @@ class View extends THREE.EventDispatcher {
232
232
  * @returns {THREE.WebGLRenderer} the WebGLRenderer used to render this view.
233
233
  */
234
234
  get renderer() {
235
- var _this$mainLoop, _this$mainLoop$gfxEng;
236
- return (_this$mainLoop = this.mainLoop) === null || _this$mainLoop === void 0 ? void 0 : (_this$mainLoop$gfxEng = _this$mainLoop.gfxEngine) === null || _this$mainLoop$gfxEng === void 0 ? void 0 : _this$mainLoop$gfxEng.getRenderer();
235
+ return this.mainLoop?.gfxEngine?.getRenderer();
237
236
  }
238
237
 
239
238
  /**
@@ -241,8 +240,7 @@ class View extends THREE.EventDispatcher {
241
240
  * @returns {THREE.Camera} the threejs camera of this view
242
241
  */
243
242
  get camera3D() {
244
- var _this$camera;
245
- return (_this$camera = this.camera) === null || _this$camera === void 0 ? void 0 : _this$camera.camera3D;
243
+ return this.camera?.camera3D;
246
244
  }
247
245
 
248
246
  /**
@@ -92,7 +92,9 @@ class C3DTilesLayer extends GeometryLayer {
92
92
  * @param {Number} [config.cleanupDelay=1000] The time (in ms) after which a tile content (and its children) are
93
93
  * removed from the scene.
94
94
  * @param {C3DTExtensions} [config.registeredExtensions] 3D Tiles extensions managers registered for this tileset.
95
- * @param {String} [config.pntsMode= PNTS_MODE.COLOR] {@link PointsMaterials} Point cloud coloring mode. Only 'COLOR' or 'CLASSIFICATION' are possible. COLOR uses RGB colors of the points, CLASSIFICATION uses a classification property of the batch table to color points.
95
+ * @param {String} [config.pntsMode= PNTS_MODE.COLOR] {@link PointsMaterials} Point cloud coloring mode.
96
+ * Only 'COLOR' or 'CLASSIFICATION' are possible. COLOR uses RGB colors of the points,
97
+ * CLASSIFICATION uses a classification property of the batch table to color points.
96
98
  * @param {String} [config.pntsShape= PNTS_SHAPE.CIRCLE] Point cloud point shape. Only 'CIRCLE' or 'SQUARE' are possible.
97
99
  * @param {String} [config.pntsSizeMode= PNTS_SIZE_MODE.VALUE] {@link PointsMaterials} Point cloud size mode. Only 'VALUE' or 'ATTENUATED' are possible. VALUE use constant size, ATTENUATED compute size depending on distance from point to camera.
98
100
  * @param {Number} [config.pntsMinAttenuatedSize=3] Minimum scale used by 'ATTENUATED' size mode
@@ -60,14 +60,13 @@ class ElevationLayer extends RasterLayer {
60
60
  * view.addLayer(elevation);
61
61
  */
62
62
  constructor(id) {
63
- var _config$clampValues, _config$clampValues2;
64
63
  let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
65
64
  super(id, config);
66
65
  if (config.zmin || config.zmax) {
67
66
  console.warn('Config using zmin and zmax are deprecated, use {clampValues: {min, max}} structure.');
68
67
  }
69
- this.zmin = ((_config$clampValues = config.clampValues) === null || _config$clampValues === void 0 ? void 0 : _config$clampValues.min) ?? config.zmin;
70
- this.zmax = ((_config$clampValues2 = config.clampValues) === null || _config$clampValues2 === void 0 ? void 0 : _config$clampValues2.max) ?? config.zmax;
68
+ this.zmin = config.clampValues?.min ?? config.zmin;
69
+ this.zmax = config.clampValues?.max ?? config.zmax;
71
70
  this.isElevationLayer = true;
72
71
  this.defineLayerProperty('scale', this.scale || 1.0);
73
72
  }
@@ -1,8 +1,7 @@
1
1
  import Layer from "./Layer.js";
2
2
  import LayerUpdateState from "./LayerUpdateState.js";
3
3
  export function geoidLayerIsVisible(tilelayer) {
4
- var _tilelayer$attachedLa;
5
- return tilelayer === null || tilelayer === void 0 ? void 0 : (_tilelayer$attachedLa = tilelayer.attachedLayers.filter(l => l.isGeoidLayer)[0]) === null || _tilelayer$attachedLa === void 0 ? void 0 : _tilelayer$attachedLa.visible;
4
+ return tilelayer?.attachedLayers.filter(l => l.isGeoidLayer)[0]?.visible;
6
5
  }
7
6
 
8
7
  /**
@@ -195,11 +195,9 @@ class LabelLayer extends GeometryLayer {
195
195
  set visible(value) {
196
196
  super.visible = value;
197
197
  if (value) {
198
- var _this$domElement;
199
- (_this$domElement = this.domElement) === null || _this$domElement === void 0 ? void 0 : _this$domElement.show();
198
+ this.domElement?.show();
200
199
  } else {
201
- var _this$domElement2;
202
- (_this$domElement2 = this.domElement) === null || _this$domElement2 === void 0 ? void 0 : _this$domElement2.hide();
200
+ this.domElement?.hide();
203
201
  }
204
202
  }
205
203
  get submittedLabelNodes() {
@@ -231,16 +229,15 @@ class LabelLayer extends GeometryLayer {
231
229
  coord.crs = data.crs;
232
230
  context.setZoom(extent.zoom);
233
231
  data.features.forEach(f => {
234
- var _f$style, _f$style$text, _f$style2, _f$style2$point;
235
232
  // TODO: add support for LINE and POLYGON
236
233
  if (f.type !== FEATURE_TYPES.POINT) {
237
234
  return;
238
235
  }
239
236
  context.setFeature(f);
240
- const featureField = (_f$style = f.style) === null || _f$style === void 0 ? void 0 : (_f$style$text = _f$style.text) === null || _f$style$text === void 0 ? void 0 : _f$style$text.field;
237
+ const featureField = f.style?.text?.field;
241
238
 
242
239
  // determine if altitude style is specified by the user
243
- const altitudeStyle = (_f$style2 = f.style) === null || _f$style2 === void 0 ? void 0 : (_f$style2$point = _f$style2.point) === null || _f$style2$point === void 0 ? void 0 : _f$style2$point.base_altitude;
240
+ const altitudeStyle = f.style?.point?.base_altitude;
244
241
  const isDefaultElevationStyle = altitudeStyle instanceof Function && altitudeStyle.name == 'baseAltitudeDefault';
245
242
 
246
243
  // determine if the altitude needs update with ElevationLayer
@@ -292,19 +289,14 @@ class LabelLayer extends GeometryLayer {
292
289
  this.toHide.add(labelsNode);
293
290
  }
294
291
  #findClosestDomElement(node) {
295
- var _node$parent;
296
- if ((_node$parent = node.parent) !== null && _node$parent !== void 0 && _node$parent.isTileMesh) {
297
- var _node$parent$link$thi;
298
- return ((_node$parent$link$thi = node.parent.link[this.id]) === null || _node$parent$link$thi === void 0 ? void 0 : _node$parent$link$thi.domElements) || this.#findClosestDomElement(node.parent);
292
+ if (node.parent?.isTileMesh) {
293
+ return node.parent.link[this.id]?.domElements || this.#findClosestDomElement(node.parent);
299
294
  } else {
300
295
  return this.domElement;
301
296
  }
302
297
  }
303
298
  #hasLabelChildren(object) {
304
- return object.children.every(c => {
305
- var _c$layerUpdateState$t;
306
- return c.layerUpdateState && ((_c$layerUpdateState$t = c.layerUpdateState[this.id]) === null || _c$layerUpdateState$t === void 0 ? void 0 : _c$layerUpdateState$t.hasFinished());
307
- });
299
+ return object.children.every(c => c.layerUpdateState && c.layerUpdateState[this.id]?.hasFinished());
308
300
  }
309
301
 
310
302
  // Remove all labels invisible with pre-culling with screen grid
@@ -439,8 +431,7 @@ class LabelLayer extends GeometryLayer {
439
431
  this.removeNodeDomElement(node);
440
432
  }
441
433
  removeNodeDomElement(node) {
442
- var _node$link$this$id;
443
- if ((_node$link$this$id = node.link[this.id]) !== null && _node$link$this$id !== void 0 && _node$link$this$id.domElements) {
434
+ if (node.link[this.id]?.domElements) {
444
435
  const child = node.link[this.id].domElements.dom;
445
436
  child.parentElement.removeChild(child);
446
437
  delete node.link[this.id].domElements;