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
@@ -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
@@ -5,7 +5,6 @@ import GeometryLayer from "./GeometryLayer.js";
5
5
  import Coordinates from "../Core/Geographic/Coordinates.js";
6
6
  import Extent from "../Core/Geographic/Extent.js";
7
7
  import Label from "../Core/Label.js";
8
- import { FEATURE_TYPES } from "../Core/Feature.js";
9
8
  import { readExpression, StyleContext } from "../Core/Style.js";
10
9
  import { ScreenGrid } from "../Renderer/Label2DRenderer.js";
11
10
  const context = new StyleContext();
@@ -168,17 +167,23 @@ class LabelLayer extends GeometryLayer {
168
167
  */
169
168
  constructor(id) {
170
169
  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);
170
+ const {
171
+ domElement,
172
+ performance = true,
173
+ forceClampToTerrain = false,
174
+ margin,
175
+ ...geometryConfig
176
+ } = config;
177
+ super(id, config.object3d || new THREE.Group(), geometryConfig);
174
178
  this.isLabelLayer = true;
175
179
  this.domElement = new DomNode();
176
180
  this.domElement.show();
177
181
  this.domElement.dom.id = `itowns-label-${this.id}`;
178
182
  this.buildExtent = true;
179
183
  this.crs = config.source.crs;
180
- this.performance = config.performance || true;
181
- this.forceClampToTerrain = config.forceClampToTerrain || false;
184
+ this.performance = performance;
185
+ this.forceClampToTerrain = forceClampToTerrain;
186
+ this.margin = margin;
182
187
  this.toHide = new THREE.Group();
183
188
  this.labelDomelement = domElement;
184
189
 
@@ -216,21 +221,26 @@ class LabelLayer extends GeometryLayer {
216
221
  *
217
222
  * @param {FeatureCollection} data - The FeatureCollection to read the
218
223
  * labels from.
219
- * @param {Extent} extent
224
+ * @param {Extent|Tile} extentOrTile
220
225
  *
221
226
  * @return {Label[]} An array containing all the created labels.
222
227
  */
223
- convert(data, extent) {
228
+ convert(data, extentOrTile) {
224
229
  const labels = [];
225
230
 
226
231
  // Converting the extent now is faster for further operation
227
- extent.as(data.crs, _extent);
232
+ if (extentOrTile.isExtent) {
233
+ extentOrTile.as(data.crs, _extent);
234
+ } else {
235
+ extentOrTile.toExtent(data.crs, _extent);
236
+ }
228
237
  coord.crs = data.crs;
229
- context.setZoom(extent.zoom);
238
+ context.setZoom(extentOrTile.zoom);
230
239
  data.features.forEach(f => {
231
- // TODO: add support for LINE and POLYGON
232
- if (f.type !== FEATURE_TYPES.POINT) {
233
- return;
240
+ if (f.style.text) {
241
+ if (Object.keys(f.style.text).length === 0) {
242
+ return;
243
+ }
234
244
  }
235
245
  context.setFeature(f);
236
246
  const featureField = f.style?.text?.field;
@@ -242,19 +252,11 @@ class LabelLayer extends GeometryLayer {
242
252
  // determine if the altitude needs update with ElevationLayer
243
253
  labels.needsAltitude = labels.needsAltitude || this.forceClampToTerrain === true || isDefaultElevationStyle && !f.hasRawElevationData;
244
254
  f.geometries.forEach(g => {
245
- // NOTE: this only works because only POINT is supported, it
246
- // needs more work for LINE and POLYGON
247
- coord.setFromArray(f.vertices, g.size * g.indices[0].offset);
248
- // Transform coordinate to data.crs projection
249
- coord.applyMatrix4(data.matrixWorld);
250
- if (!_extent.isPointInside(coord)) {
251
- return;
252
- }
253
- const geometryField = g.properties.style && g.properties.style.text && g.properties.style.text.field;
254
255
  context.setGeometry(g);
255
- let content;
256
256
  this.style.setContext(context);
257
257
  const layerField = this.style.text && this.style.text.field;
258
+ const geometryField = g.properties.style && g.properties.style.text && g.properties.style.text.field;
259
+ let content;
258
260
  if (this.labelDomelement) {
259
261
  content = readExpression(this.labelDomelement, context);
260
262
  } else if (!geometryField && !featureField && !layerField) {
@@ -263,10 +265,26 @@ class LabelLayer extends GeometryLayer {
263
265
  return;
264
266
  }
265
267
  }
266
- const label = new Label(content, coord.clone(), this.style);
267
- label.layerId = this.id;
268
- label.padding = this.margin || label.padding;
269
- labels.push(label);
268
+ if (this.style.zoom.min > this.style.context.zoom || this.style.zoom.max <= this.style.context.zoom) {
269
+ return;
270
+ }
271
+
272
+ // NOTE: this only works fine for POINT.
273
+ // It needs more work for LINE and POLYGON as we currently only use the first point of the entity
274
+
275
+ g.indices.forEach(i => {
276
+ coord.setFromArray(f.vertices, g.size * i.offset);
277
+ // Transform coordinate to data.crs projection
278
+ coord.applyMatrix4(data.matrixWorld);
279
+ if (!_extent.isPointInside(coord)) {
280
+ return;
281
+ }
282
+ const label = new Label(content, coord.clone(), this.style);
283
+ label.layerId = this.id;
284
+ label.order = f.order;
285
+ label.padding = this.margin || label.padding;
286
+ labels.push(label);
287
+ });
270
288
  });
271
289
  });
272
290
  return labels;
@@ -2,7 +2,7 @@ import * as THREE from 'three';
2
2
  import { STRATEGY_MIN_NETWORK_TRAFFIC } from "./LayerUpdateStrategy.js";
3
3
  import InfoLayer from "./InfoLayer.js";
4
4
  import Source from "../Source/Source.js";
5
- import Cache from "../Core/Scheduler/Cache.js";
5
+ import { LRUCache } from 'lru-cache';
6
6
  import Style from "../Core/Style.js";
7
7
 
8
8
  /**
@@ -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,17 @@ 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 LRUCache({
199
+ max: 500,
200
+ ...(cacheLifeTime !== Infinity && {
201
+ ttl: cacheLifeTime
202
+ })
203
+ });
204
+ this.mergeFeatures = mergeFeatures;
165
205
  }
166
206
  addInitializationStep() {
167
207
  // Possibility to add rejection handler, if it's necessary.
@@ -232,26 +272,17 @@ class Layer extends THREE.EventDispatcher {
232
272
  return data;
233
273
  }
234
274
  getData(from, to) {
235
- const key = this.source.requestToKey(this.source.isVectorSource ? to : from);
236
- let data = this.cache.getByArray(key);
275
+ const key = this.source.getDataKey(this.source.isVectorSource ? to : from);
276
+ let data = this.cache.get(key);
237
277
  if (!data) {
238
278
  data = this.source.loadData(from, this).then(feat => this.convert(feat, to), err => {
239
279
  throw err;
240
280
  });
241
- this.cache.setByArray(data, key);
281
+ this.cache.set(key, data);
242
282
  }
243
283
  return data;
244
284
  }
245
285
 
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
286
  /**
256
287
  * Remove and dispose all objects from layer.
257
288
  * @param {boolean} [clearCache=false] Whether to clear the layer cache or not