itowns 2.45.1-next.0 → 2.45.1-next.1

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 (185) hide show
  1. package/dist/455.js +2 -0
  2. package/dist/455.js.map +1 -0
  3. package/dist/debug.js +3 -0
  4. package/dist/debug.js.LICENSE.txt +13 -0
  5. package/dist/debug.js.map +1 -0
  6. package/dist/itowns.js +3 -0
  7. package/dist/itowns.js.LICENSE.txt +5 -0
  8. package/dist/itowns.js.map +1 -0
  9. package/dist/itowns_lasparser.js +2 -0
  10. package/dist/itowns_lasparser.js.map +1 -0
  11. package/dist/itowns_lasworker.js +2 -0
  12. package/dist/itowns_lasworker.js.map +1 -0
  13. package/dist/itowns_potree2worker.js +2 -0
  14. package/dist/itowns_potree2worker.js.map +1 -0
  15. package/dist/itowns_widgets.js +2 -0
  16. package/dist/itowns_widgets.js.map +1 -0
  17. package/lib/Controls/FirstPersonControls.js +308 -0
  18. package/lib/Controls/FlyControls.js +175 -0
  19. package/lib/Controls/GlobeControls.js +1178 -0
  20. package/lib/Controls/PlanarControls.js +1025 -0
  21. package/lib/Controls/StateControl.js +432 -0
  22. package/lib/Controls/StreetControls.js +392 -0
  23. package/lib/Converter/Feature2Mesh.js +612 -0
  24. package/lib/Converter/Feature2Texture.js +174 -0
  25. package/lib/Converter/convertToTile.js +70 -0
  26. package/lib/Converter/textureConverter.js +43 -0
  27. package/lib/Core/3DTiles/C3DTBatchTable.js +131 -0
  28. package/lib/Core/3DTiles/C3DTBatchTableHierarchyExtension.js +96 -0
  29. package/lib/Core/3DTiles/C3DTBoundingVolume.js +156 -0
  30. package/lib/Core/3DTiles/C3DTExtensions.js +97 -0
  31. package/lib/Core/3DTiles/C3DTFeature.js +110 -0
  32. package/lib/Core/3DTiles/C3DTilesEnums.js +20 -0
  33. package/lib/Core/3DTiles/C3DTileset.js +99 -0
  34. package/lib/Core/3DTiles/utils/BinaryPropertyAccessor.js +100 -0
  35. package/lib/Core/AnimationPlayer.js +142 -0
  36. package/lib/Core/CopcNode.js +174 -0
  37. package/lib/Core/Deprecated/Undeprecator.js +74 -0
  38. package/lib/Core/EntwinePointTileNode.js +126 -0
  39. package/lib/Core/Feature.js +488 -0
  40. package/lib/Core/Geographic/GeoidGrid.js +108 -0
  41. package/lib/Core/Label.js +222 -0
  42. package/lib/Core/MainLoop.js +209 -0
  43. package/lib/Core/Picking.js +255 -0
  44. package/lib/Core/PointCloudNode.js +42 -0
  45. package/lib/Core/Potree2Node.js +206 -0
  46. package/lib/Core/Potree2PointAttributes.js +139 -0
  47. package/lib/Core/PotreeNode.js +101 -0
  48. package/lib/Core/Prefab/Globe/Atmosphere.js +293 -0
  49. package/lib/Core/Prefab/Globe/GlobeLayer.js +152 -0
  50. package/lib/Core/Prefab/Globe/GlobeTileBuilder.js +110 -0
  51. package/lib/Core/Prefab/Globe/SkyShader.js +78 -0
  52. package/lib/Core/Prefab/GlobeView.js +155 -0
  53. package/lib/Core/Prefab/Planar/PlanarLayer.js +59 -0
  54. package/lib/Core/Prefab/Planar/PlanarTileBuilder.js +71 -0
  55. package/lib/Core/Prefab/PlanarView.js +62 -0
  56. package/lib/Core/Prefab/TileBuilder.js +82 -0
  57. package/lib/Core/Prefab/computeBufferTileGeometry.js +248 -0
  58. package/lib/Core/Scheduler/Cache.js +17 -0
  59. package/lib/Core/Scheduler/CancelledCommandException.js +15 -0
  60. package/lib/Core/Scheduler/Scheduler.js +294 -0
  61. package/lib/Core/Style.js +660 -0
  62. package/lib/Core/StyleOptions.js +486 -0
  63. package/lib/Core/System/Capabilities.js +63 -0
  64. package/lib/Core/Tile/Tile.js +205 -0
  65. package/lib/Core/Tile/TileGrid.js +49 -0
  66. package/lib/Core/TileGeometry.js +124 -0
  67. package/lib/Core/TileMesh.js +108 -0
  68. package/lib/Core/View.js +1115 -0
  69. package/lib/Layer/C3DTilesLayer.js +459 -0
  70. package/lib/Layer/ColorLayer.js +154 -0
  71. package/lib/Layer/CopcLayer.js +63 -0
  72. package/lib/Layer/ElevationLayer.js +139 -0
  73. package/lib/Layer/EntwinePointTileLayer.js +71 -0
  74. package/lib/Layer/FeatureGeometryLayer.js +77 -0
  75. package/lib/Layer/GeoidLayer.js +80 -0
  76. package/lib/Layer/GeometryLayer.js +233 -0
  77. package/lib/Layer/InfoLayer.js +64 -0
  78. package/lib/Layer/LabelLayer.js +469 -0
  79. package/lib/Layer/Layer.js +335 -0
  80. package/lib/Layer/LayerUpdateState.js +89 -0
  81. package/lib/Layer/LayerUpdateStrategy.js +80 -0
  82. package/lib/Layer/OGC3DTilesLayer.js +543 -0
  83. package/lib/Layer/OrientedImageLayer.js +227 -0
  84. package/lib/Layer/PointCloudLayer.js +405 -0
  85. package/lib/Layer/Potree2Layer.js +171 -0
  86. package/lib/Layer/PotreeLayer.js +72 -0
  87. package/lib/Layer/RasterLayer.js +37 -0
  88. package/lib/Layer/ReferencingLayerProperties.js +62 -0
  89. package/lib/Layer/TiledGeometryLayer.js +459 -0
  90. package/lib/Loader/LASLoader.js +193 -0
  91. package/lib/Loader/Potree2BrotliLoader.js +261 -0
  92. package/lib/Loader/Potree2Loader.js +207 -0
  93. package/lib/Main.js +113 -0
  94. package/lib/MainBundle.js +4 -0
  95. package/lib/Parser/B3dmParser.js +174 -0
  96. package/lib/Parser/CameraCalibrationParser.js +94 -0
  97. package/lib/Parser/GDFParser.js +72 -0
  98. package/lib/Parser/GTXParser.js +75 -0
  99. package/lib/Parser/GeoJsonParser.js +212 -0
  100. package/lib/Parser/GpxParser.js +25 -0
  101. package/lib/Parser/ISGParser.js +71 -0
  102. package/lib/Parser/KMLParser.js +25 -0
  103. package/lib/Parser/LASParser.js +137 -0
  104. package/lib/Parser/MapBoxUrlParser.js +83 -0
  105. package/lib/Parser/PntsParser.js +131 -0
  106. package/lib/Parser/Potree2BinParser.js +92 -0
  107. package/lib/Parser/PotreeBinParser.js +106 -0
  108. package/lib/Parser/PotreeCinParser.js +29 -0
  109. package/lib/Parser/ShapefileParser.js +78 -0
  110. package/lib/Parser/VectorTileParser.js +215 -0
  111. package/lib/Parser/XbilParser.js +120 -0
  112. package/lib/Parser/deprecated/LegacyGLTFLoader.js +1386 -0
  113. package/lib/Parser/iGLTFLoader.js +168 -0
  114. package/lib/Process/3dTilesProcessing.js +304 -0
  115. package/lib/Process/FeatureProcessing.js +76 -0
  116. package/lib/Process/LayeredMaterialNodeProcessing.js +229 -0
  117. package/lib/Process/ObjectRemovalHelper.js +97 -0
  118. package/lib/Process/handlerNodeError.js +23 -0
  119. package/lib/Provider/3dTilesProvider.js +149 -0
  120. package/lib/Provider/DataSourceProvider.js +24 -0
  121. package/lib/Provider/Fetcher.js +233 -0
  122. package/lib/Provider/PointCloudProvider.js +45 -0
  123. package/lib/Provider/TileProvider.js +16 -0
  124. package/lib/Provider/URLBuilder.js +116 -0
  125. package/lib/Renderer/Camera.js +281 -0
  126. package/lib/Renderer/Color.js +56 -0
  127. package/lib/Renderer/ColorLayersOrdering.js +115 -0
  128. package/lib/Renderer/CommonMaterial.js +31 -0
  129. package/lib/Renderer/Label2DRenderer.js +192 -0
  130. package/lib/Renderer/LayeredMaterial.js +243 -0
  131. package/lib/Renderer/OBB.js +150 -0
  132. package/lib/Renderer/OrientedImageCamera.js +118 -0
  133. package/lib/Renderer/OrientedImageMaterial.js +167 -0
  134. package/lib/Renderer/PointsMaterial.js +485 -0
  135. package/lib/Renderer/RasterTile.js +243 -0
  136. package/lib/Renderer/RenderMode.js +31 -0
  137. package/lib/Renderer/Shader/ShaderChunk.js +160 -0
  138. package/lib/Renderer/Shader/ShaderUtils.js +47 -0
  139. package/lib/Renderer/SphereHelper.js +17 -0
  140. package/lib/Renderer/WebXR.js +51 -0
  141. package/lib/Renderer/c3DEngine.js +214 -0
  142. package/lib/Source/C3DTilesGoogleSource.js +74 -0
  143. package/lib/Source/C3DTilesIonSource.js +54 -0
  144. package/lib/Source/C3DTilesSource.js +30 -0
  145. package/lib/Source/CopcSource.js +126 -0
  146. package/lib/Source/EntwinePointTileSource.js +72 -0
  147. package/lib/Source/FileSource.js +188 -0
  148. package/lib/Source/OGC3DTilesGoogleSource.js +29 -0
  149. package/lib/Source/OGC3DTilesIonSource.js +34 -0
  150. package/lib/Source/OGC3DTilesSource.js +21 -0
  151. package/lib/Source/OrientedImageSource.js +59 -0
  152. package/lib/Source/Potree2Source.js +167 -0
  153. package/lib/Source/PotreeSource.js +82 -0
  154. package/lib/Source/Source.js +202 -0
  155. package/lib/Source/TMSSource.js +144 -0
  156. package/lib/Source/VectorTilesSource.js +182 -0
  157. package/lib/Source/WFSSource.js +170 -0
  158. package/lib/Source/WMSSource.js +167 -0
  159. package/lib/Source/WMTSSource.js +92 -0
  160. package/lib/ThreeExtended/capabilities/WebGL.js +69 -0
  161. package/lib/ThreeExtended/libs/ktx-parse.module.js +506 -0
  162. package/lib/ThreeExtended/libs/zstddec.module.js +29 -0
  163. package/lib/ThreeExtended/loaders/DDSLoader.js +200 -0
  164. package/lib/ThreeExtended/loaders/DRACOLoader.js +400 -0
  165. package/lib/ThreeExtended/loaders/GLTFLoader.js +2879 -0
  166. package/lib/ThreeExtended/loaders/KTX2Loader.js +709 -0
  167. package/lib/ThreeExtended/math/ColorSpaces.js +59 -0
  168. package/lib/ThreeExtended/utils/BufferGeometryUtils.js +846 -0
  169. package/lib/ThreeExtended/utils/WorkerPool.js +70 -0
  170. package/lib/Utils/CameraUtils.js +554 -0
  171. package/lib/Utils/DEMUtils.js +350 -0
  172. package/lib/Utils/FeaturesUtils.js +156 -0
  173. package/lib/Utils/Gradients.js +16 -0
  174. package/lib/Utils/ThreeUtils.js +115 -0
  175. package/lib/Utils/gui/C3DTilesStyle.js +218 -0
  176. package/lib/Utils/gui/Main.js +7 -0
  177. package/lib/Utils/gui/Minimap.js +152 -0
  178. package/lib/Utils/gui/Navigation.js +245 -0
  179. package/lib/Utils/gui/Scale.js +104 -0
  180. package/lib/Utils/gui/Searchbar.js +234 -0
  181. package/lib/Utils/gui/Widget.js +80 -0
  182. package/lib/Utils/placeObjectOnGround.js +136 -0
  183. package/lib/Worker/LASLoaderWorker.js +19 -0
  184. package/lib/Worker/Potree2Worker.js +21 -0
  185. package/package.json +2 -2
@@ -0,0 +1,335 @@
1
+ import * as THREE from 'three';
2
+ import { STRATEGY_MIN_NETWORK_TRAFFIC } from "./LayerUpdateStrategy.js";
3
+ import InfoLayer from "./InfoLayer.js";
4
+ import Source from "../Source/Source.js";
5
+ import { LRUCache } from 'lru-cache';
6
+ import Style from "../Core/Style.js";
7
+
8
+ /**
9
+ * @property {boolean} isLayer - Used to checkout whether this layer is a Layer.
10
+ * Default is true. You should not change this, as it is used internally for
11
+ * optimisation.
12
+ * @property {boolean} ready - This property is false when the layer isn't added.
13
+ * It's true when the layer is added and all initializations are done.
14
+ * @property {Source} source - This source determines the datas to be displayed with the layer.
15
+ * The layer determines how this data are displayed.
16
+ * By example:
17
+ * * For ColorLayer/ElevationLayer, the source datas are rasterised (if it's necessary).
18
+ * * For GeometryLayer, the source datas are converted to meshes (not possible for the raster data sources).
19
+ * @property {Promise} whenReady - this promise is resolved when the layer is added and all initializations are done.
20
+ * This promise is resolved with this layer.
21
+ * This promise is returned by [View#addLayer]{@link View}.
22
+ * @property {object} [zoom] - This property is used only the layer is attached
23
+ * to {@link TiledGeometryLayer}.
24
+ * By example,
25
+ * The layer checks the tile zoom level to determine if the layer is visible in this tile.
26
+ *
27
+ * ![tiled geometry](/docs/static/images/wfszoommaxmin.jpeg)
28
+ * _In `GlobeView`, **red lines** represents the **WGS84 grid** and **orange lines** the Pseudo-mercator grid_
29
+ * _In this example [WFS to 3D objects](http://www.itowns-project.org/itowns/examples/index.html#source_stream_wfs_3d), the building layer zoom min is 14._
30
+ * _In the lower part of the picture, the zoom tiles 14 have buildings, while in the upper part of the picture, the level 13 tiles have no buildings._
31
+ *
32
+ * @property {number} [zoom.max=Infinity] - this is the maximum zoom beyond which it'll be hidden.
33
+ * @property {number} [zoom.min=0] - this is the minimum zoom from which it'll be visible.
34
+ *
35
+ */
36
+ class Layer extends THREE.EventDispatcher {
37
+ /**
38
+ * Don't use directly constructor to instance a new Layer. Instead, use
39
+ * another available type of Layer, implement a new one inheriting from this
40
+ * one or use [View#addLayer]{@link View}.
41
+ *
42
+ * @protected
43
+ *
44
+ * @param {string} id - The id of the layer, that should be unique. It is
45
+ * not mandatory, but an error will be emitted if this layer is added a
46
+ * {@link View} that already has a layer going by that id.
47
+ * @param {Object} config - configuration, all elements in it
48
+ * will be merged as is in the layer. For example, if the configuration
49
+ * contains three elements `name, extent`, these elements will be
50
+ * available using `layer.name` or something else depending on the property
51
+ * name.
52
+ * @param {Source|boolean} config.source - instantiated Source specifies data source to display.
53
+ * if config.source is a boolean, it can only be false. if config.source is false,
54
+ * the layer doesn't need Source (like debug Layer or procedural layer).
55
+ * @param {StyleOptions} [config.style] - an object that contain any properties
56
+ * (order, zoom, fill, stroke, point, text or/and icon)
57
+ * and sub properties of a Style (@see {@link StyleOptions}). Or directly a {@link Style} .<br/>
58
+ * When entering a StyleOptions the missing style properties will be look for in the data (if any)
59
+ * what won't be done when you use a Style.
60
+ * @param {number} [config.cacheLifeTime=Infinity] - set life time value in cache.
61
+ * This value is used for cache expiration mechanism.
62
+ * @param {(boolean|Object)} [config.addLabelLayer] - Used to tell if this layer has
63
+ * labels to display from its data. For example, it needs to be set to `true`
64
+ * for a layer with vector tiles. If it's `true` a new `LabelLayer` is added and attached to this `Layer`.
65
+ * You can also configure it with {@link LabelLayer} options described below such as: `addLabelLayer: { performance: true }`.
66
+ * @param {boolean} [config.addLabelLayer.performance=false] - In case label layer adding, so remove labels that have no chance of being visible.
67
+ * Indeed, even in the best case, labels will never be displayed. By example, if there's many labels.
68
+ * @param {boolean} [config.addLabelLayer.forceClampToTerrain=false] - use elevation layer to clamp label on terrain.
69
+ * @param {number} [config.subdivisionThreshold=256] - set the texture size and, if applied to the globe, affects the tile subdivision.
70
+ *
71
+ * @example
72
+ * // Add and create a new Layer
73
+ * const newLayer = new Layer('id', options);
74
+ * view.addLayer(newLayer);
75
+ *
76
+ * // Change layer's visibility
77
+ * const layerToChange = view.getLayerById('idLayerToChange');
78
+ * layerToChange.visible = false;
79
+ * view.notifyChange(); // update viewer
80
+ *
81
+ * // Change layer's opacity
82
+ * const layerToChange = view.getLayerById('idLayerToChange');
83
+ * layerToChange.opacity = 0.5;
84
+ * view.notifyChange(); // update viewer
85
+ *
86
+ * // Listen properties
87
+ * const layerToListen = view.getLayerById('idLayerToListen');
88
+ * layerToListen.addEventListener('visible-property-changed', (event) => console.log(event));
89
+ * layerToListen.addEventListener('opacity-property-changed', (event) => console.log(event));
90
+ */
91
+ constructor(id) {
92
+ let config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
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;
106
+ super();
107
+
108
+ /**
109
+ * @type {boolean}
110
+ * @readonly
111
+ */
112
+ this.isLayer = true;
113
+
114
+ /**
115
+ * @type {string}
116
+ * @readonly
117
+ */
118
+ this.id = id;
119
+ Object.defineProperty(this, 'id', {
120
+ writable: false
121
+ });
122
+
123
+ /**
124
+ * @type {string}
125
+ */
126
+ this.name = name;
127
+ if (source === undefined || source === true) {
128
+ throw new Error(`Layer ${id} needs Source`);
129
+ }
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
+ };
143
+ }
144
+ this.style = new Style(style);
145
+ } else {
146
+ this.style = style || new Style();
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
+ };
167
+ this.info = new InfoLayer(this);
168
+
169
+ /**
170
+ * @type {boolean}
171
+ */
172
+ this.ready = false;
173
+
174
+ /**
175
+ * @type {Array<Promise<any>>}
176
+ * @protected
177
+ */
178
+ this._promises = [];
179
+
180
+ /**
181
+ * @type {Promise<this>}
182
+ */
183
+ this.whenReady = new Promise((re, rj) => {
184
+ this._resolve = re;
185
+ this._reject = rj;
186
+ }).then(() => {
187
+ this.ready = true;
188
+ this.source.onLayerAdded({
189
+ out: this
190
+ });
191
+ return this;
192
+ });
193
+ this._promises.push(this.source.whenReady);
194
+
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;
205
+ }
206
+ addInitializationStep() {
207
+ // Possibility to add rejection handler, if it's necessary.
208
+ let resolve;
209
+ this._promises.push(new Promise(re => {
210
+ resolve = re;
211
+ }));
212
+ return resolve;
213
+ }
214
+
215
+ /**
216
+ * Defines a property for this layer, with a default value and a callback
217
+ * executed when the property changes.
218
+ * <br><br>
219
+ * When changing the property, it also emits an event, named following this
220
+ * convention: `${propertyName}-property-changed`, with `${propertyName}`
221
+ * being replaced by the name of the property. For example, if the added
222
+ * property name is `frozen`, it will emit a `frozen-property-changed`.
223
+ * <br><br>
224
+ * @example <caption>The emitted event has some properties assigned to it</caption>
225
+ * event = {
226
+ * new: {
227
+ * ${propertyName}: * // the new value of the property
228
+ * },
229
+ * previous: {
230
+ * ${propertyName}: * // the previous value of the property
231
+ * },
232
+ * target: Layer // the layer it has been dispatched from
233
+ * type: string // the name of the emitted event
234
+ * }
235
+ *
236
+ * @param {string} propertyName - The name of the property, also used in
237
+ * the emitted event name.
238
+ * @param {*} defaultValue - The default set value.
239
+ * @param {function} [onChange] - The function executed when the property is
240
+ * changed. Parameters are the layer the property is defined on, and the
241
+ * name of the property.
242
+ */
243
+ defineLayerProperty(propertyName, defaultValue, onChange) {
244
+ const existing = Object.getOwnPropertyDescriptor(this, propertyName);
245
+ if (!existing || !existing.set) {
246
+ let property = this[propertyName] == undefined ? defaultValue : this[propertyName];
247
+ Object.defineProperty(this, propertyName, {
248
+ get: () => property,
249
+ set: newValue => {
250
+ if (property !== newValue) {
251
+ const event = {
252
+ type: `${propertyName}-property-changed`,
253
+ previous: {},
254
+ new: {}
255
+ };
256
+ event.previous[propertyName] = property;
257
+ event.new[propertyName] = newValue;
258
+ property = newValue;
259
+ if (onChange) {
260
+ onChange(this, propertyName);
261
+ }
262
+ this.dispatchEvent(event);
263
+ }
264
+ }
265
+ });
266
+ }
267
+ }
268
+
269
+ // Placeholder
270
+ // eslint-disable-next-line
271
+ convert(data) {
272
+ return data;
273
+ }
274
+ getData(from, to) {
275
+ const key = this.source.getDataKey(this.source.isVectorSource ? to : from);
276
+ let data = this.cache.get(key);
277
+ if (!data) {
278
+ data = this.source.loadData(from, this).then(feat => this.convert(feat, to), err => {
279
+ throw err;
280
+ });
281
+ this.cache.set(key, data);
282
+ }
283
+ return data;
284
+ }
285
+
286
+ /**
287
+ * Remove and dispose all objects from layer.
288
+ * @param {boolean} [clearCache=false] Whether to clear the layer cache or not
289
+ */
290
+ // eslint-disable-next-line
291
+ delete() {
292
+ console.warn('Function delete doesn\'t exist for this layer');
293
+ }
294
+ }
295
+ export default Layer;
296
+ export const ImageryLayers = {
297
+ // move this to new index
298
+ // After the modification :
299
+ // * the minimum sequence will always be 0
300
+ // * the maximum sequence will always be layers.lenght - 1
301
+ // the ordering of all layers (Except that specified) doesn't change
302
+ moveLayerToIndex: function (layer, newIndex, imageryLayers) {
303
+ newIndex = Math.min(newIndex, imageryLayers.length - 1);
304
+ newIndex = Math.max(newIndex, 0);
305
+ const oldIndex = layer.sequence;
306
+ for (const imagery of imageryLayers) {
307
+ if (imagery.id === layer.id) {
308
+ // change index of specified layer
309
+ imagery.sequence = newIndex;
310
+ } else if (imagery.sequence > oldIndex && imagery.sequence <= newIndex) {
311
+ // down all layers between the old index and new index (to compensate the deletion of the old index)
312
+ imagery.sequence--;
313
+ } else if (imagery.sequence >= newIndex && imagery.sequence < oldIndex) {
314
+ // up all layers between the new index and old index (to compensate the insertion of the new index)
315
+ imagery.sequence++;
316
+ }
317
+ }
318
+ },
319
+ moveLayerDown: function (layer, imageryLayers) {
320
+ if (layer.sequence > 0) {
321
+ this.moveLayerToIndex(layer, layer.sequence - 1, imageryLayers);
322
+ }
323
+ },
324
+ moveLayerUp: function (layer, imageryLayers) {
325
+ const m = imageryLayers.length - 1;
326
+ if (layer.sequence < m) {
327
+ this.moveLayerToIndex(layer, layer.sequence + 1, imageryLayers);
328
+ }
329
+ },
330
+ getColorLayersIdOrderedBySequence: function (imageryLayers) {
331
+ const copy = Array.from(imageryLayers);
332
+ copy.sort((a, b) => a.sequence - b.sequence);
333
+ return copy.map(l => l.id);
334
+ }
335
+ };
@@ -0,0 +1,89 @@
1
+ const UPDATE_STATE = {
2
+ IDLE: 0,
3
+ PENDING: 1,
4
+ ERROR: 2,
5
+ DEFINITIVE_ERROR: 3,
6
+ FINISHED: 4
7
+ };
8
+ const PAUSE_BETWEEN_ERRORS = [1.0, 3.0, 7.0, 60.0];
9
+
10
+ /**
11
+ * LayerUpdateState is the update state of a layer, for a given object (e.g tile).
12
+ * It stores information to allow smart update decisions, and especially network
13
+ * error handling.
14
+ * @constructor
15
+ */
16
+ class LayerUpdateState {
17
+ constructor() {
18
+ this.state = UPDATE_STATE.IDLE;
19
+ this.lastErrorTimestamp = 0;
20
+ this.errorCount = 0;
21
+ // lowestLevelError is lowest level with error.
22
+ //
23
+ // if lowestLevelError is Infinity, so there has been no error.
24
+ //
25
+ // if lowestLevelError isn't Infinity, so the strategy is to find the
26
+ // highest level between the current level and lowestLevelError.
27
+ // the dichotomy method is used to find it.
28
+ this.failureParams = {
29
+ lowestLevelError: Infinity
30
+ };
31
+ }
32
+ hasFinished() {
33
+ return UPDATE_STATE.FINISHED == this.state;
34
+ }
35
+ canTryUpdate() {
36
+ let timestamp = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Date.now();
37
+ switch (this.state) {
38
+ case UPDATE_STATE.IDLE:
39
+ {
40
+ return true;
41
+ }
42
+ case UPDATE_STATE.DEFINITIVE_ERROR:
43
+ case UPDATE_STATE.PENDING:
44
+ case UPDATE_STATE.FINISHED:
45
+ {
46
+ return false;
47
+ }
48
+ case UPDATE_STATE.ERROR:
49
+ default:
50
+ {
51
+ const errorDuration = this.secondsUntilNextTry() * 1000;
52
+ return errorDuration <= timestamp - this.lastErrorTimestamp;
53
+ }
54
+ }
55
+ }
56
+ secondsUntilNextTry() {
57
+ if (this.state !== UPDATE_STATE.ERROR) {
58
+ return 0;
59
+ }
60
+ const idx = Math.max(0, Math.min(this.errorCount, PAUSE_BETWEEN_ERRORS.length) - 1);
61
+ return PAUSE_BETWEEN_ERRORS[idx];
62
+ }
63
+ newTry() {
64
+ this.state = UPDATE_STATE.PENDING;
65
+ }
66
+ success() {
67
+ this.lastErrorTimestamp = 0;
68
+ this.state = UPDATE_STATE.IDLE;
69
+ }
70
+ noMoreUpdatePossible() {
71
+ this.state = UPDATE_STATE.FINISHED;
72
+ }
73
+ noData(failureParams) {
74
+ this.state = UPDATE_STATE.IDLE;
75
+ this.failureParams.lowestLevelError = Math.min(failureParams.targetLevel, this.failureParams.lowestLevelError);
76
+ }
77
+ failure(timestamp, definitive, failureParams) {
78
+ if (failureParams && failureParams.targetLevel != undefined) {
79
+ this.failureParams.lowestLevelError = Math.min(failureParams.targetLevel, this.failureParams.lowestLevelError);
80
+ }
81
+ this.lastErrorTimestamp = timestamp;
82
+ this.state = definitive ? UPDATE_STATE.DEFINITIVE_ERROR : UPDATE_STATE.ERROR;
83
+ this.errorCount++;
84
+ }
85
+ inError() {
86
+ return this.state == UPDATE_STATE.DEFINITIVE_ERROR || this.state == UPDATE_STATE.ERROR;
87
+ }
88
+ }
89
+ export default LayerUpdateState;
@@ -0,0 +1,80 @@
1
+ import { EMPTY_TEXTURE_ZOOM } from "../Renderer/RasterTile.js";
2
+ /**
3
+ * This modules implements various layer update strategies.
4
+ *
5
+ * Default strategy is STRATEGY_MIN_NETWORK_TRAFFIC which aims
6
+ * to reduce the amount of network traffic.
7
+ */
8
+
9
+ export const STRATEGY_MIN_NETWORK_TRAFFIC = 0;
10
+ export const STRATEGY_GROUP = 1;
11
+ export const STRATEGY_PROGRESSIVE = 2;
12
+ export const STRATEGY_DICHOTOMY = 3;
13
+ function _minimizeNetworkTraffic(node, nodeLevel, currentLevel, source) {
14
+ // TO DO source.isVectorTileSource is a temp fix for pendingSubdivision.
15
+ // see issue https://github.com/iTowns/itowns/issues/2214
16
+ if (node.pendingSubdivision && !source.isVectorTileSource) {
17
+ return currentLevel;
18
+ }
19
+ return nodeLevel;
20
+ }
21
+
22
+ // Maps nodeLevel to groups defined in layer's options
23
+ // eg with groups = [3, 7, 12]:
24
+ // * nodeLevel = 2 -> 3
25
+ // * nodeLevel = 4 -> 3
26
+ // * nodeLevel = 7 -> 7
27
+ // * nodeLevel = 15 -> 12
28
+ function _group(nodeLevel, options) {
29
+ const f = options.groups.filter(val => val <= nodeLevel);
30
+ return f.length ? f[f.length - 1] : options.groups[0];
31
+ }
32
+ function _progressive(nodeLevel, currentLevel, options) {
33
+ return Math.min(nodeLevel, currentLevel + (options.increment || 1));
34
+ }
35
+
36
+ // Load textures at mid-point between current level and node's level.
37
+ // This produces smoother transitions and a single fetch updates multiple
38
+ // tiles thanks to caching.
39
+ function _dichotomy(nodeLevel, currentLevel) {
40
+ let options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
41
+ if (currentLevel == EMPTY_TEXTURE_ZOOM) {
42
+ return options.zoom ? options.zoom.min : 0;
43
+ }
44
+ return Math.min(nodeLevel, Math.ceil((currentLevel + nodeLevel) / 2));
45
+ }
46
+ export function chooseNextLevelToFetch(strategy, node) {
47
+ let nodeLevel = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : node.level;
48
+ let currentLevel = arguments.length > 3 ? arguments[3] : undefined;
49
+ let layer = arguments.length > 4 ? arguments[4] : undefined;
50
+ let failureParams = arguments.length > 5 ? arguments[5] : undefined;
51
+ let nextLevelToFetch;
52
+ const maxZoom = layer.source.zoom ? layer.source.zoom.max : Infinity;
53
+ if (failureParams.lowestLevelError != Infinity) {
54
+ nextLevelToFetch = _dichotomy(failureParams.lowestLevelError, currentLevel, layer.source);
55
+ nextLevelToFetch = failureParams.lowestLevelError == nextLevelToFetch ? nextLevelToFetch - 1 : nextLevelToFetch;
56
+ if (strategy == STRATEGY_GROUP) {
57
+ nextLevelToFetch = _group(nextLevelToFetch, layer.updateStrategy.options);
58
+ }
59
+ } else {
60
+ switch (strategy) {
61
+ case STRATEGY_GROUP:
62
+ nextLevelToFetch = _group(nodeLevel, layer.updateStrategy.options);
63
+ break;
64
+ case STRATEGY_PROGRESSIVE:
65
+ {
66
+ nextLevelToFetch = _progressive(nodeLevel, currentLevel, layer.updateStrategy.options);
67
+ break;
68
+ }
69
+ case STRATEGY_DICHOTOMY:
70
+ nextLevelToFetch = _dichotomy(nodeLevel, currentLevel, layer.source);
71
+ break;
72
+ // default strategy
73
+ case STRATEGY_MIN_NETWORK_TRAFFIC:
74
+ default:
75
+ nextLevelToFetch = _minimizeNetworkTraffic(node, nodeLevel, currentLevel, layer.source);
76
+ }
77
+ nextLevelToFetch = Math.min(nextLevelToFetch, maxZoom);
78
+ }
79
+ return nextLevelToFetch;
80
+ }