itowns 2.44.3-next.4 → 2.44.3-next.40

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 (109) hide show
  1. package/CODING.md +1 -1
  2. package/CONTRIBUTORS.md +1 -0
  3. package/dist/debug.js +1 -1
  4. package/dist/debug.js.map +1 -1
  5. package/dist/itowns.js +1 -1
  6. package/dist/itowns.js.LICENSE.txt +0 -2
  7. package/dist/itowns.js.map +1 -1
  8. package/dist/itowns_widgets.js +1 -1
  9. package/dist/itowns_widgets.js.map +1 -1
  10. package/examples/3dtiles_loader.html +123 -48
  11. package/examples/config.json +3 -10
  12. package/examples/copc_simple_loader.html +15 -5
  13. package/examples/effects_stereo.html +2 -2
  14. package/examples/entwine_3d_loader.html +3 -1
  15. package/examples/entwine_simple_loader.html +1 -1
  16. package/examples/images/itowns_logo.svg +123 -0
  17. package/examples/js/plugins/COGParser.js +1 -1
  18. package/examples/jsm/OGC3DTilesHelper.js +6 -1
  19. package/examples/layers/JSONLayers/GeoidMNT.json +3 -1
  20. package/examples/misc_collada.html +2 -2
  21. package/examples/source_file_geojson_3d.html +0 -1
  22. package/examples/source_file_kml_raster_usgs.html +0 -1
  23. package/examples/source_stream_wfs_raster.html +0 -7
  24. package/examples/vector_tile_mapbox_raster.html +91 -0
  25. package/examples/view_3d_map_webxr.html +3 -1
  26. package/examples/view_multi_25d.html +2 -2
  27. package/lib/Controls/GlobeControls.js +45 -28
  28. package/lib/Controls/StateControl.js +5 -2
  29. package/lib/Converter/Feature2Mesh.js +10 -4
  30. package/lib/Converter/Feature2Texture.js +6 -1
  31. package/lib/Converter/convertToTile.js +3 -8
  32. package/lib/Converter/textureConverter.js +4 -5
  33. package/lib/Core/Deprecated/Undeprecator.js +0 -1
  34. package/lib/Core/Feature.js +3 -4
  35. package/lib/Core/Geographic/Coordinates.js +143 -132
  36. package/lib/Core/Geographic/Crs.js +140 -145
  37. package/lib/Core/Geographic/Extent.js +221 -397
  38. package/lib/Core/Geographic/GeoidGrid.js +1 -1
  39. package/lib/Core/MainLoop.js +1 -3
  40. package/lib/Core/Math/Ellipsoid.js +62 -21
  41. package/lib/Core/Prefab/Globe/Atmosphere.js +4 -8
  42. package/lib/Core/Prefab/Globe/GlobeLayer.js +22 -15
  43. package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +111 -0
  44. package/lib/Core/Prefab/GlobeView.js +2 -7
  45. package/lib/Core/Prefab/Planar/PlanarLayer.js +17 -11
  46. package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +43 -43
  47. package/lib/Core/Prefab/TileBuilder.js +42 -40
  48. package/lib/Core/Prefab/computeBufferTileGeometry.js +195 -130
  49. package/lib/Core/Scheduler/Cache.js +1 -240
  50. package/lib/Core/Style.js +34 -495
  51. package/lib/Core/StyleOptions.js +486 -0
  52. package/lib/Core/Tile/Tile.js +207 -0
  53. package/lib/Core/Tile/TileGrid.js +49 -0
  54. package/lib/Core/TileGeometry.js +112 -28
  55. package/lib/Core/TileMesh.js +3 -3
  56. package/lib/Core/View.js +15 -8
  57. package/lib/Layer/C3DTilesLayer.js +20 -16
  58. package/lib/Layer/ColorLayer.js +35 -9
  59. package/lib/Layer/CopcLayer.js +7 -2
  60. package/lib/Layer/ElevationLayer.js +39 -7
  61. package/lib/Layer/EntwinePointTileLayer.js +14 -7
  62. package/lib/Layer/FeatureGeometryLayer.js +20 -6
  63. package/lib/Layer/GeometryLayer.js +42 -11
  64. package/lib/Layer/LabelLayer.js +45 -27
  65. package/lib/Layer/Layer.js +92 -61
  66. package/lib/Layer/OGC3DTilesLayer.js +212 -56
  67. package/lib/Layer/OrientedImageLayer.js +11 -5
  68. package/lib/Layer/PointCloudLayer.js +76 -30
  69. package/lib/Layer/Potree2Layer.js +9 -2
  70. package/lib/Layer/PotreeLayer.js +10 -3
  71. package/lib/Layer/RasterLayer.js +12 -2
  72. package/lib/Layer/TiledGeometryLayer.js +69 -13
  73. package/lib/Main.js +2 -2
  74. package/lib/Parser/GeoJsonParser.js +1 -1
  75. package/lib/Parser/VectorTileParser.js +42 -29
  76. package/lib/Parser/XbilParser.js +14 -2
  77. package/lib/Provider/Fetcher.js +5 -1
  78. package/lib/Provider/URLBuilder.js +22 -11
  79. package/lib/Renderer/Camera.js +1 -1
  80. package/lib/Renderer/Label2DRenderer.js +9 -7
  81. package/lib/Renderer/OBB.js +11 -13
  82. package/lib/Renderer/PointsMaterial.js +5 -5
  83. package/lib/Renderer/RasterTile.js +1 -2
  84. package/lib/Renderer/SphereHelper.js +0 -6
  85. package/lib/Source/CopcSource.js +13 -2
  86. package/lib/Source/EntwinePointTileSource.js +14 -4
  87. package/lib/Source/FileSource.js +9 -10
  88. package/lib/Source/OrientedImageSource.js +2 -2
  89. package/lib/Source/Source.js +26 -46
  90. package/lib/Source/TMSSource.js +10 -9
  91. package/lib/Source/VectorTilesSource.js +38 -34
  92. package/lib/Source/WFSSource.js +18 -13
  93. package/lib/Source/WMSSource.js +56 -18
  94. package/lib/Source/WMTSSource.js +13 -7
  95. package/lib/ThreeExtended/libs/ktx-parse.module.js +310 -274
  96. package/lib/ThreeExtended/loaders/DRACOLoader.js +3 -2
  97. package/lib/ThreeExtended/loaders/GLTFLoader.js +6 -3
  98. package/lib/ThreeExtended/loaders/KTX2Loader.js +144 -60
  99. package/lib/ThreeExtended/math/ColorSpaces.js +59 -0
  100. package/lib/Utils/CameraUtils.js +1 -1
  101. package/lib/Utils/gui/C3DTilesStyle.js +2 -3
  102. package/lib/Utils/placeObjectOnGround.js +0 -1
  103. package/package.json +10 -8
  104. package/examples/3dtiles_25d.html +0 -120
  105. package/examples/3dtiles_basic.html +0 -94
  106. package/examples/3dtiles_batch_table.html +0 -86
  107. package/examples/3dtiles_ion.html +0 -126
  108. package/examples/3dtiles_pointcloud.html +0 -95
  109. package/lib/Core/Prefab/Globe/BuilderEllipsoidTile.js +0 -110
@@ -0,0 +1,49 @@
1
+ import * as THREE from 'three';
2
+ import Extent from "../Geographic/Extent.js";
3
+ const _countTiles = new THREE.Vector2();
4
+ const _dim = new THREE.Vector2();
5
+ export const globalExtentTMS = new Map();
6
+ export const schemeTiles = new Map();
7
+ const extent4326 = new Extent('EPSG:4326', -180, 180, -90, 90);
8
+ globalExtentTMS.set('EPSG:4326', extent4326);
9
+
10
+ // Compute global extent of TMS in EPSG:3857
11
+ // It's square whose a side is between -180° to 180°.
12
+ // So, west extent, it's 180 convert in EPSG:3857
13
+ const extent3857 = extent4326.as('EPSG:3857');
14
+ extent3857.clampSouthNorth(extent3857.west, extent3857.east);
15
+ globalExtentTMS.set('EPSG:3857', extent3857);
16
+ const defaultScheme = new THREE.Vector2(1, 1);
17
+ schemeTiles.set('EPSG:3857', defaultScheme);
18
+ schemeTiles.set('EPSG:4326', new THREE.Vector2(2, 1));
19
+
20
+ // TODO: For now we can only have a single TMS grid per proj4 identifier.
21
+ // This causes TMS identifier to be proj4 identifier.
22
+ export function getInfoTms(crs) {
23
+ const globalExtent = globalExtentTMS.get(crs);
24
+ if (!globalExtent) {
25
+ throw new Error(`The tile matrix set ${crs} is not defined.`);
26
+ }
27
+ const globalDimension = globalExtent.planarDimensions(_dim);
28
+ const sTs = schemeTiles.get(crs) ?? defaultScheme;
29
+ // The isInverted parameter is to be set to the correct value, true or false
30
+ // (default being false) if the computation of the coordinates needs to be
31
+ // inverted to match the same scheme as OSM, Google Maps or other system.
32
+ // See link below for more information
33
+ // https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/
34
+ // in crs includes ':NI' => tms isn't inverted (NOT INVERTED)
35
+ const isInverted = !crs.includes(':NI');
36
+ return {
37
+ epsg: crs,
38
+ globalExtent,
39
+ globalDimension,
40
+ sTs,
41
+ isInverted
42
+ };
43
+ }
44
+ export function getCountTiles(crs, zoom) {
45
+ const sTs = schemeTiles.get(crs) || defaultScheme;
46
+ const count = 2 ** zoom;
47
+ _countTiles.set(count, count).multiply(sTs);
48
+ return _countTiles;
49
+ }
@@ -1,40 +1,124 @@
1
1
  import * as THREE from 'three';
2
- import computeBuffers, { getBufferIndexSize } from "./Prefab/computeBufferTileGeometry.js";
3
- function defaultBuffers(params) {
4
- params.buildIndexAndUv_0 = true;
5
- params.center = params.builder.center(params.extent).clone();
6
- const buffers = computeBuffers(params);
7
- buffers.index = new THREE.BufferAttribute(buffers.index, 1);
8
- buffers.uvs[0] = new THREE.BufferAttribute(buffers.uvs[0], 2);
9
- buffers.position = new THREE.BufferAttribute(buffers.position, 3);
10
- buffers.normal = new THREE.BufferAttribute(buffers.normal, 3);
11
- for (let i = 1; i < params.builder.uvCount; i++) {
12
- buffers.uvs[1] = new THREE.BufferAttribute(buffers.uvs[1], 1);
13
- }
14
- return buffers;
2
+ import { computeBuffers, getBufferIndexSize } from "./Prefab/computeBufferTileGeometry.js";
3
+ import Coordinates from "./Geographic/Coordinates.js";
4
+ function defaultBuffers(builder, params) {
5
+ const fullParams = {
6
+ disableSkirt: false,
7
+ hideSkirt: false,
8
+ buildIndexAndUv_0: true,
9
+ segments: 16,
10
+ coordinates: new Coordinates(builder.crs),
11
+ center: builder.center(params.extent).clone(),
12
+ ...params
13
+ };
14
+ const buffers = computeBuffers(builder, fullParams);
15
+ const bufferAttributes = {
16
+ index: buffers.index ? new THREE.BufferAttribute(buffers.index, 1) : null,
17
+ uvs: [...(buffers.uvs[0] ? [new THREE.BufferAttribute(buffers.uvs[0], 2)] : []), ...(buffers.uvs[1] ? [new THREE.BufferAttribute(buffers.uvs[1], 1)] : [])],
18
+ position: new THREE.BufferAttribute(buffers.position, 3),
19
+ normal: new THREE.BufferAttribute(buffers.normal, 3)
20
+ };
21
+ return bufferAttributes;
15
22
  }
16
- class TileGeometry extends THREE.BufferGeometry {
17
- constructor(params) {
18
- let buffers = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultBuffers(params);
23
+ export class TileGeometry extends THREE.BufferGeometry {
24
+ /** Oriented Bounding Box of the tile geometry. */
25
+
26
+ /** Ground area covered by this tile geometry. */
27
+
28
+ /** Resolution of the tile geometry in segments per side. */
29
+
30
+ /**
31
+ * [TileGeometry] instances are shared between tiles. Since a geometry
32
+ * handles its own GPU resource, it needs a reference counter to dispose of
33
+ * that resource only when it is discarded by every single owner of a
34
+ * reference to the geometry.
35
+ */
36
+ // https://github.com/iTowns/itowns/pull/2440#discussion_r1860743294
37
+ // TODO: Remove nullability by reworking OBB:setFromExtent
38
+
39
+ constructor(builder, params) {
40
+ let bufferAttributes = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : defaultBuffers(builder, params);
19
41
  super();
20
- this.center = params.center;
21
42
  this.extent = params.extent;
22
43
  this.segments = params.segments;
23
- this.setIndex(buffers.index);
24
- this.setAttribute('position', buffers.position);
25
- this.setAttribute('normal', buffers.normal);
26
- this.setAttribute('uv', buffers.uvs[0]);
27
- for (let i = 1; i < buffers.uvs.length; i++) {
28
- this.setAttribute(`uv_${i}`, buffers.uvs[i]);
44
+ this.setIndex(bufferAttributes.index);
45
+ this.setAttribute('position', bufferAttributes.position);
46
+ this.setAttribute('normal', bufferAttributes.normal);
47
+ this.setAttribute('uv', bufferAttributes.uvs[0]);
48
+ for (let i = 1; i < bufferAttributes.uvs.length; i++) {
49
+ this.setAttribute(`uv_${i}`, bufferAttributes.uvs[i]);
29
50
  }
30
51
  this.computeBoundingBox();
31
- this.OBB = {};
52
+ this.OBB = null;
32
53
  if (params.hideSkirt) {
33
54
  this.hideSkirt = params.hideSkirt;
34
55
  }
56
+ this._refCount = null;
35
57
  }
36
- set hideSkirt(value) {
37
- this.setDrawRange(0, getBufferIndexSize(this.segments, value));
58
+
59
+ /**
60
+ * Enables or disables skirt rendering.
61
+ *
62
+ * @param toggle - Whether to hide the skirt; true hides, false shows.
63
+ */
64
+ set hideSkirt(toggle) {
65
+ this.setDrawRange(0, getBufferIndexSize(this.segments, toggle));
38
66
  }
39
- }
40
- export default TileGeometry;
67
+
68
+ /**
69
+ * Initialize reference count for this geometry if it is currently null.
70
+ *
71
+ * @param cacheTile - The [Cache] used to store this geometry.
72
+ * @param keys - The [south, level, epsg] key of this geometry.
73
+ */
74
+ initRefCount(cacheTile, key) {
75
+ if (this._refCount !== null) {
76
+ return;
77
+ }
78
+ this._refCount = {
79
+ count: 0,
80
+ fn: () => {
81
+ this._refCount.count--;
82
+ if (this._refCount.count <= 0) {
83
+ // To avoid remove index buffer and attribute buffer uv
84
+ // error un-bound buffer in webgl with VAO rendering.
85
+ // Could be removed if the attribute buffer deleting is
86
+ // taken into account in the buffer binding state
87
+ // (in THREE.WebGLBindingStates code).
88
+ this.index = null;
89
+ delete this.attributes.uv;
90
+ cacheTile.delete(key);
91
+ super.dispose();
92
+ // THREE.BufferGeometry.prototype.dispose.call(this);
93
+ }
94
+ }
95
+ };
96
+ }
97
+
98
+ /**
99
+ * Increase reference count.
100
+ *
101
+ * @throws If reference count has not been initialized.
102
+ */
103
+ increaseRefCount() {
104
+ if (this._refCount === null) {
105
+ throw new Error('[TileGeometry::increaseRefCount] ' + 'Tried to increment an unitialized reference count.');
106
+ }
107
+ this._refCount.count++;
108
+ }
109
+
110
+ /**
111
+ * The current reference count of this [TileGeometry] if it has been
112
+ * initialized.
113
+ */
114
+ get refCount() {
115
+ return this._refCount?.count;
116
+ }
117
+ dispose() {
118
+ if (this._refCount == null) {
119
+ super.dispose();
120
+ } else {
121
+ this._refCount.fn();
122
+ }
123
+ }
124
+ }
@@ -1,6 +1,6 @@
1
1
  import * as THREE from 'three';
2
- import CRS from "./Geographic/Crs.js";
3
2
  import { geoidLayerIsVisible } from "../Layer/GeoidLayer.js";
3
+ import { tiledCovering } from "./Tile/Tile.js";
4
4
 
5
5
  /**
6
6
  * A TileMesh is a THREE.Mesh with a geometricError and an OBB
@@ -29,7 +29,7 @@ class TileMesh extends THREE.Mesh {
29
29
  this.boundingSphere = new THREE.Sphere();
30
30
  this.obb.box3D.getBoundingSphere(this.boundingSphere);
31
31
  for (const tms of layer.tileMatrixSets) {
32
- this.#_tms.set(tms, this.extent.tiledCovering(tms));
32
+ this.#_tms.set(tms, tiledCovering(this.extent, tms));
33
33
  }
34
34
  this.frustumCulled = false;
35
35
  this.matrixAutoUpdate = false;
@@ -70,7 +70,7 @@ class TileMesh extends THREE.Mesh {
70
70
  this.obb.box3D.getBoundingSphere(this.boundingSphere);
71
71
  }
72
72
  getExtentsByProjection(crs) {
73
- return this.#_tms.get(CRS.formatToTms(crs));
73
+ return this.#_tms.get(crs);
74
74
  }
75
75
 
76
76
  /**
package/lib/Core/View.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as THREE from 'three';
2
+ import * as CRS from "./Geographic/Crs.js";
2
3
  import Camera from "../Renderer/Camera.js";
3
4
  import initializeWebXR from "../Renderer/WebXR.js";
4
5
  import MainLoop, { MAIN_LOOP_EVENTS, RENDERING_PAUSED } from "./MainLoop.js";
@@ -6,7 +7,6 @@ import Capabilities from "./System/Capabilities.js";
6
7
  import { COLOR_LAYERS_ORDER_CHANGED } from "../Renderer/ColorLayersOrdering.js";
7
8
  import c3DEngine from "../Renderer/c3DEngine.js";
8
9
  import RenderMode from "../Renderer/RenderMode.js";
9
- import CRS from "./Geographic/Crs.js";
10
10
  import Coordinates from "./Geographic/Coordinates.js";
11
11
  import FeaturesUtils from "../Utils/FeaturesUtils.js";
12
12
  import { getMaxColorSamplerUnitsCount } from "../Renderer/LayeredMaterial.js";
@@ -30,7 +30,8 @@ export const VIEW_EVENTS = {
30
30
  LAYER_ADDED: 'layer-added',
31
31
  INITIALIZED: 'initialized',
32
32
  COLOR_LAYERS_ORDER_CHANGED,
33
- CAMERA_MOVED: 'camera-moved'
33
+ CAMERA_MOVED: 'camera-moved',
34
+ DISPOSED: 'disposed'
34
35
  };
35
36
 
36
37
  /**
@@ -52,7 +53,7 @@ function _preprocessLayer(view, layer, parentLayer) {
52
53
  // Find crs projection layer, this is projection destination
53
54
  layer.crs = view.referenceCrs;
54
55
  } else if (!layer.crs) {
55
- if (parentLayer && parentLayer.tileMatrixSets && parentLayer.tileMatrixSets.includes(CRS.formatToTms(source.crs))) {
56
+ if (parentLayer && parentLayer.tileMatrixSets && parentLayer.tileMatrixSets.includes(source.crs)) {
56
57
  layer.crs = source.crs;
57
58
  } else {
58
59
  layer.crs = parentLayer && parentLayer.extent.crs;
@@ -109,9 +110,11 @@ const coordinates = new Coordinates('EPSG:4326');
109
110
  const viewers = [];
110
111
  // Size of the camera frustrum, in meters
111
112
  let screenMeters;
113
+ let id = 0;
112
114
 
113
115
  /**
114
- * @property {HTMLElement} domElement - Thhe domElement holding the canvas where the view is displayed
116
+ * @property {number} id - The id of the view. It's incremented at each new view instance, starting at 0.
117
+ * @property {HTMLElement} domElement - The domElement holding the canvas where the view is displayed
115
118
  * @property {String} referenceCrs - The coordinate reference system of the view
116
119
  * @property {MainLoop} mainLoop - itowns mainloop scheduling the operations
117
120
  * @property {THREE.Scene} scene - threejs scene of the view
@@ -136,10 +139,10 @@ class View extends THREE.EventDispatcher {
136
139
  * var view = itowns.View('EPSG:4326', viewerDiv, { camera: { type: itowns.CAMERA_TYPE.ORTHOGRAPHIC } });
137
140
  * var customControls = itowns.THREE.OrbitControls(view.camera3D, viewerDiv);
138
141
  *
139
- * @param {string} crs - The default CRS of Three.js coordinates. Should be a cartesian CRS.
142
+ * @param {String} crs - The default CRS of Three.js coordinates. Should be a cartesian CRS.
140
143
  * @param {HTMLElement} viewerDiv - Where to instanciate the Three.js scene in the DOM
141
144
  * @param {Object} [options] - Optional properties.
142
- * @param {object} [options.camera] - Options for the camera associated to the view. See {@link Camera} options.
145
+ * @param {Object} [options.camera] - Options for the camera associated to the view. See {@link Camera} options.
143
146
  * @param {MainLoop} [options.mainLoop] - {@link MainLoop} instance to use, otherwise a default one will be constructed
144
147
  * @param {WebGLRenderer|Object} [options.renderer] - {@link WebGLRenderer} instance to use, otherwise
145
148
  * a default one will be constructed. In this case, if options.renderer is an object, it will be used to
@@ -159,6 +162,7 @@ class View extends THREE.EventDispatcher {
159
162
  }
160
163
  super();
161
164
  this.domElement = viewerDiv;
165
+ this.id = id++;
162
166
  this.referenceCrs = crs;
163
167
  let engine;
164
168
  // options.renderer can be 2 separate things:
@@ -272,8 +276,6 @@ class View extends THREE.EventDispatcher {
272
276
  }
273
277
  // remove alls frameRequester
274
278
  this.removeAllFrameRequesters();
275
- // remove alls events
276
- this.removeAllEvents();
277
279
  // remove all layers
278
280
  const layers = this.getLayers(l => !l.isTiledGeometryLayer && !l.isAtmosphere);
279
281
  for (const layer of layers) {
@@ -290,6 +292,11 @@ class View extends THREE.EventDispatcher {
290
292
  viewers.splice(id, 1);
291
293
  // Remove remaining objects in the scene (e.g. helpers, debug, etc.)
292
294
  this.scene.traverse(ObjectRemovalHelper.cleanup);
295
+ this.dispatchEvent({
296
+ type: VIEW_EVENTS.DISPOSED
297
+ });
298
+ // remove alls events
299
+ this.removeAllEvents();
293
300
  }
294
301
 
295
302
  /**
@@ -51,11 +51,14 @@ function findTileID(object) {
51
51
  function object3DHasFeature(object3d) {
52
52
  return object3d.geometry && object3d.geometry.attributes._BATCHID;
53
53
  }
54
+
55
+ /**
56
+ * @extends GeometryLayer
57
+ */
54
58
  class C3DTilesLayer extends GeometryLayer {
55
59
  #fillColorMaterialsBuffer;
56
60
  /**
57
61
  * @deprecated Deprecated 3D Tiles layer. Use {@link OGC3DTilesLayer} instead.
58
- * @extends GeometryLayer
59
62
  *
60
63
  * @example
61
64
  * // Create a new 3d-tiles layer from a web server
@@ -83,7 +86,7 @@ class C3DTilesLayer extends GeometryLayer {
83
86
  * {@link View} that already has a layer going by that id.
84
87
  * @param {object} config configuration, all elements in it
85
88
  * will be merged as is in the layer.
86
- * @param {C3TilesSource} config.source The source of 3d Tiles.
89
+ * @param {C3DTilesSource} config.source The source of 3d Tiles.
87
90
  *
88
91
  * name.
89
92
  * @param {Number} [config.sseThreshold=16] The [Screen Space Error](https://github.com/CesiumGS/3d-tiles/blob/main/specification/README.md#geometric-error)
@@ -102,6 +105,7 @@ class C3DTilesLayer extends GeometryLayer {
102
105
  * @param {View} view The view
103
106
  */
104
107
  constructor(id, config, view) {
108
+ console.warn('C3DTilesLayer is deprecated and will be removed in iTowns 3.0 version. Use OGC3DTilesLayer instead.');
105
109
  super(id, new THREE.Group(), {
106
110
  source: config.source
107
111
  });
@@ -142,7 +146,7 @@ class C3DTilesLayer extends GeometryLayer {
142
146
  }
143
147
  }
144
148
 
145
- /** @type {Style} */
149
+ /** @type {Style | null} */
146
150
  this._style = config.style || null;
147
151
 
148
152
  /** @type {Map<string, THREE.MeshStandardMaterial>} */
@@ -368,21 +372,15 @@ class C3DTilesLayer extends GeometryLayer {
368
372
  if (c3DTileFeature.object3d != object3d) {
369
373
  continue; // this feature do not belong to object3d
370
374
  }
375
+ this._style.context.setGeometry({
376
+ properties: c3DTileFeature
377
+ });
378
+
371
379
  /** @type {THREE.Color} */
372
- let color = null;
373
- if (typeof this._style.fill.color === 'function') {
374
- color = new THREE.Color(this._style.fill.color(c3DTileFeature));
375
- } else {
376
- color = new THREE.Color(this._style.fill.color);
377
- }
380
+ const color = new THREE.Color(this._style.fill.color);
378
381
 
379
382
  /** @type {number} */
380
- let opacity = null;
381
- if (typeof this._style.fill.opacity === 'function') {
382
- opacity = this._style.fill.opacity(c3DTileFeature);
383
- } else {
384
- opacity = this._style.fill.opacity;
385
- }
383
+ const opacity = this._style.fill.opacity;
386
384
  const materialId = color.getHexString() + opacity;
387
385
  let material = null;
388
386
  if (this.#fillColorMaterialsBuffer.has(materialId)) {
@@ -445,7 +443,13 @@ class C3DTilesLayer extends GeometryLayer {
445
443
  return this.#fillColorMaterialsBuffer.size;
446
444
  }
447
445
  set style(value) {
448
- this._style = value;
446
+ if (value instanceof Style) {
447
+ this._style = value;
448
+ } else if (!value) {
449
+ this._style = null;
450
+ } else {
451
+ this._style = new Style(value);
452
+ }
449
453
  this.updateStyle();
450
454
  }
451
455
  get style() {
@@ -44,6 +44,8 @@ import { deprecatedColorLayerOptions } from "../Core/Deprecated/Undeprecator.js"
44
44
  * * `1`: used to amplify the transparency effect.
45
45
  * * `2`: unused.
46
46
  * * `3`: could be used by your own glsl code.
47
+ *
48
+ * @extends RasterLayer
47
49
  */
48
50
  class ColorLayer extends RasterLayer {
49
51
  /**
@@ -51,8 +53,6 @@ class ColorLayer extends RasterLayer {
51
53
  * it can be an aerial view of the ground or a simple transparent layer with the
52
54
  * roads displayed.
53
55
  *
54
- * @extends Layer
55
- *
56
56
  * @param {string} id - The id of the layer, that should be unique. It is
57
57
  * not mandatory, but an error will be emitted if this layer is added a
58
58
  * {@link View} that already has a layer going by that id.
@@ -92,15 +92,41 @@ class ColorLayer extends RasterLayer {
92
92
  constructor(id) {
93
93
  let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
94
94
  deprecatedColorLayerOptions(config);
95
- super(id, config);
95
+ const {
96
+ effect_type = 0,
97
+ effect_parameter = 1.0,
98
+ transparent,
99
+ ...rasterConfig
100
+ } = config;
101
+ super(id, rasterConfig);
102
+
103
+ /**
104
+ * @type {boolean}
105
+ * @readonly
106
+ */
96
107
  this.isColorLayer = true;
97
- this.defineLayerProperty('visible', true);
98
- this.defineLayerProperty('opacity', 1.0);
99
- this.defineLayerProperty('sequence', 0);
100
- this.transparent = config.transparent || this.opacity < 1.0;
108
+
109
+ /**
110
+ * @type {boolean}
111
+ */
112
+ this.visible = true;
113
+ this.defineLayerProperty('visible', this.visible);
114
+
115
+ /**
116
+ * @type {number}
117
+ */
118
+ this.opacity = 1.0;
119
+ this.defineLayerProperty('opacity', this.opacity);
120
+
121
+ /**
122
+ * @type {number}
123
+ */
124
+ this.sequence = 0;
125
+ this.defineLayerProperty('sequence', this.sequence);
126
+ this.transparent = transparent || this.opacity < 1.0;
101
127
  this.noTextureParentOutsideLimit = config.source ? config.source.isFileSource : false;
102
- this.effect_type = config.effect_type ?? 0;
103
- this.effect_parameter = config.effect_parameter ?? 1.0;
128
+ this.effect_type = effect_type;
129
+ this.effect_parameter = effect_parameter;
104
130
 
105
131
  // Feature options
106
132
  this.buildExtent = true;
@@ -30,6 +30,11 @@ class CopcLayer extends PointCloudLayer {
30
30
  */
31
31
  constructor(id, config) {
32
32
  super(id, config);
33
+
34
+ /**
35
+ * @type {boolean}
36
+ * @readonly
37
+ */
33
38
  this.isCopcLayer = true;
34
39
  const resolve = () => this;
35
40
  this.whenReady = this.source.whenReady.then((/** @type {CopcSource} */source) => {
@@ -44,8 +49,8 @@ class CopcLayer extends PointCloudLayer {
44
49
  this.root = new CopcNode(0, 0, 0, 0, pageOffset, pageLength, this, -1);
45
50
  this.root.bbox.min.fromArray(cube, 0);
46
51
  this.root.bbox.max.fromArray(cube, 3);
47
- this.minElevationRange = source.header.min[2];
48
- this.maxElevationRange = source.header.max[2];
52
+ this.minElevationRange = this.minElevationRange ?? source.header.min[2];
53
+ this.maxElevationRange = this.maxElevationRange ?? source.header.max[2];
49
54
  this.scale = new THREE.Vector3(1.0, 1.0, 1.0);
50
55
  this.offset = new THREE.Vector3(0.0, 0.0, 0.0);
51
56
  return this.root.loadOctree().then(resolve);
@@ -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,23 +36,30 @@ 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(() => {
51
58
  this.root = new EntwinePointTileNode(0, 0, 0, 0, this, -1);
52
59
  this.root.bbox.min.fromArray(this.source.boundsConforming, 0);
53
60
  this.root.bbox.max.fromArray(this.source.boundsConforming, 3);
54
- this.minElevationRange = this.source.boundsConforming[2];
55
- this.maxElevationRange = this.source.boundsConforming[5];
61
+ this.minElevationRange = this.minElevationRange ?? this.source.boundsConforming[2];
62
+ this.maxElevationRange = this.maxElevationRange ?? this.source.boundsConforming[5];
56
63
  this.extent = Extent.fromBox3(config.crs || 'EPSG:4326', this.root.bbox);
57
64
  return this.root.loadOctree().then(resolve);
58
65
  });
@@ -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)) {