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
@@ -16,6 +16,8 @@ const boundingSphereCenter = new THREE.Vector3();
16
16
  * as it is used internally for optimisation.
17
17
  * @property {boolean} hideSkirt (default false) - Used to hide the skirt (tile borders).
18
18
  * Useful when the layer opacity < 1
19
+ *
20
+ * @extends GeometryLayer
19
21
  */
20
22
  class TiledGeometryLayer extends GeometryLayer {
21
23
  /**
@@ -38,12 +40,10 @@ class TiledGeometryLayer extends GeometryLayer {
38
40
  * It corresponds at meters by pixel. If the projection tile exceeds a certain pixel size (on screen)
39
41
  * then it is subdivided into 4 tiles with a zoom greater than 1.
40
42
  *
41
- * @extends GeometryLayer
42
- *
43
43
  * @param {string} id - The id of the layer, that should be unique. It is
44
44
  * not mandatory, but an error will be emitted if this layer is added a
45
45
  * {@link View} that already has a layer going by that id.
46
- * @param {THREE.Object3d} object3d - The object3d used to contain the
46
+ * @param {THREE.Object3D} object3d - The object3d used to contain the
47
47
  * geometry of the TiledGeometryLayer. It is usually a `THREE.Group`, but it
48
48
  * can be anything inheriting from a `THREE.Object3d`.
49
49
  * @param {Array} schemeTile - extents Array of root tiles
@@ -58,16 +58,63 @@ class TiledGeometryLayer extends GeometryLayer {
58
58
  * @throws {Error} `object3d` must be a valid `THREE.Object3d`.
59
59
  */
60
60
  constructor(id, object3d, schemeTile, builder, config) {
61
- // cacheLifeTime = CACHE_POLICIES.INFINITE because the cache is handled by the builder
62
- config.cacheLifeTime = CACHE_POLICIES.INFINITE;
63
- config.source = false;
64
- super(id, object3d, config);
61
+ const {
62
+ sseSubdivisionThreshold = 1.0,
63
+ minSubdivisionLevel,
64
+ maxSubdivisionLevel,
65
+ maxDeltaElevationLevel,
66
+ tileMatrixSets,
67
+ diffuse,
68
+ showOutline = false,
69
+ segments,
70
+ disableSkirt = false,
71
+ materialOptions,
72
+ ...configGeometryLayer
73
+ } = config;
74
+ super(id, object3d, {
75
+ ...configGeometryLayer,
76
+ // cacheLifeTime = CACHE_POLICIES.INFINITE because the cache is handled by the builder
77
+ cacheLifeTime: CACHE_POLICIES.INFINITE,
78
+ source: false
79
+ });
80
+
81
+ /**
82
+ * @type {boolean}
83
+ * @readonly
84
+ */
65
85
  this.isTiledGeometryLayer = true;
86
+ this.protocol = 'tile';
87
+
66
88
  // TODO : this should be add in a preprocess method specific to GeoidLayer.
67
89
  this.object3d.geoidHeight = 0;
68
- this.protocol = 'tile';
90
+
91
+ /**
92
+ * @type {boolean}
93
+ */
94
+ this.disableSkirt = disableSkirt;
69
95
  this._hideSkirt = !!config.hideSkirt;
70
- this.sseSubdivisionThreshold = this.sseSubdivisionThreshold || 1.0;
96
+
97
+ /**
98
+ * @type {number}
99
+ */
100
+ this.sseSubdivisionThreshold = sseSubdivisionThreshold;
101
+
102
+ /**
103
+ * @type {number}
104
+ */
105
+ this.minSubdivisionLevel = minSubdivisionLevel;
106
+
107
+ /**
108
+ * @type {number}
109
+ */
110
+ this.maxSubdivisionLevel = maxSubdivisionLevel;
111
+
112
+ /**
113
+ * @type {number}
114
+ * @deprecated
115
+ */
116
+ this.maxDeltaElevationLevel = maxDeltaElevationLevel;
117
+ this.segments = segments;
71
118
  this.schemeTile = schemeTile;
72
119
  this.builder = builder;
73
120
  this.info = new InfoTiledGeometryLayer(this);
@@ -77,9 +124,19 @@ class TiledGeometryLayer extends GeometryLayer {
77
124
  if (!this.builder) {
78
125
  throw new Error(`Cannot init tiled layer without builder for layer ${this.id}`);
79
126
  }
80
- if (config.maxDeltaElevationLevel) {
81
- console.warn('Config using maxDeltaElevationLevel is deprecated. The parameter maxDeltaElevationLevel is not longer used');
82
- }
127
+ this.maxScreenSizeNode = this.sseSubdivisionThreshold * (this.sizeDiagonalTexture * 2);
128
+ this.tileMatrixSets = tileMatrixSets;
129
+ this.materialOptions = materialOptions;
130
+
131
+ /*
132
+ * @type {boolean}
133
+ */
134
+ this.showOutline = showOutline;
135
+
136
+ /**
137
+ * @type {THREE.Vector3 | undefined}
138
+ */
139
+ this.diffuse = diffuse;
83
140
  this.level0Nodes = [];
84
141
  const promises = [];
85
142
  for (const root of this.schemeTile) {
@@ -90,7 +147,6 @@ class TiledGeometryLayer extends GeometryLayer {
90
147
  this.object3d.add(...level0s);
91
148
  this.object3d.updateMatrixWorld();
92
149
  }));
93
- this.maxScreenSizeNode = this.sseSubdivisionThreshold * (this.sizeDiagonalTexture * 2);
94
150
  }
95
151
  get hideSkirt() {
96
152
  return this._hideSkirt;
package/lib/Main.js CHANGED
@@ -7,7 +7,7 @@ export const REVISION = conf.version;
7
7
  export { default as Extent } from "./Core/Geographic/Extent.js";
8
8
  export { default as Coordinates } from "./Core/Geographic/Coordinates.js";
9
9
  export { default as GeoidGrid } from "./Core/Geographic/GeoidGrid.js";
10
- export { default as CRS } from "./Core/Geographic/Crs.js";
10
+ export * as CRS from "./Core/Geographic/Crs.js";
11
11
  export { default as Ellipsoid, ellipsoidSizes } from "./Core/Math/Ellipsoid.js";
12
12
  export { default as GlobeView, GLOBE_VIEW_EVENTS } from "./Core/Prefab/GlobeView.js";
13
13
  export { default as PlanarView } from "./Core/Prefab/PlanarView.js";
@@ -53,7 +53,7 @@ export { default as PointCloudLayer } from "./Layer/PointCloudLayer.js";
53
53
  export { default as PotreeLayer } from "./Layer/PotreeLayer.js";
54
54
  export { default as Potree2Layer } from "./Layer/Potree2Layer.js";
55
55
  export { default as C3DTilesLayer, C3DTILES_LAYER_EVENTS } from "./Layer/C3DTilesLayer.js";
56
- export { default as OGC3DTilesLayer, OGC3DTILES_LAYER_EVENTS, enableDracoLoader, enableKtx2Loader } from "./Layer/OGC3DTilesLayer.js";
56
+ export { default as OGC3DTilesLayer, OGC3DTILES_LAYER_EVENTS, enableDracoLoader, enableKtx2Loader, enableMeshoptDecoder } from "./Layer/OGC3DTilesLayer.js";
57
57
  export { default as TiledGeometryLayer } from "./Layer/TiledGeometryLayer.js";
58
58
  export { default as OrientedImageLayer } from "./Layer/OrientedImageLayer.js";
59
59
  export { STRATEGY_MIN_NETWORK_TRAFFIC, STRATEGY_GROUP, STRATEGY_PROGRESSIVE, STRATEGY_DICHOTOMY } from "./Layer/LayerUpdateStrategy.js";
@@ -195,7 +195,7 @@ export default {
195
195
  _in.crs = _in.crs || readCRS(json);
196
196
  if (out.filteringExtent) {
197
197
  if (typeof out.filteringExtent == 'boolean') {
198
- out.filterExtent = options.extent.as(_in.crs);
198
+ out.filterExtent = options.extent.isExtent ? options.extent.as(_in.crs) : options.extent.toExtent(_in.crs);
199
199
  } else if (out.filteringExtent.isExtent) {
200
200
  out.filterExtent = out.filteringExtent;
201
201
  }
@@ -1,7 +1,7 @@
1
1
  import { Vector2, Vector3 } from 'three';
2
2
  import Protobuf from 'pbf';
3
3
  import { VectorTile } from '@mapbox/vector-tile';
4
- import { globalExtentTMS } from "../Core/Geographic/Extent.js";
4
+ import { globalExtentTMS } from "../Core/Tile/TileGrid.js";
5
5
  import { FeatureCollection, FEATURE_TYPES } from "../Core/Feature.js";
6
6
  import { deprecatedParsingOptionsToNewOne } from "../Core/Deprecated/Undeprecator.js";
7
7
  import Coordinates from "../Core/Geographic/Coordinates.js";
@@ -105,9 +105,10 @@ function vtFeatureToFeatureGeometry(vtFeature, feature) {
105
105
  function readPBF(file, options) {
106
106
  options.out = options.out || {};
107
107
  const vectorTile = new VectorTile(new Protobuf(file));
108
- const sourceLayers = Object.keys(vectorTile.layers);
109
- if (sourceLayers.length < 1) {
110
- return;
108
+ const vtLayerNames = Object.keys(vectorTile.layers);
109
+ const collection = new FeatureCollection(options.out);
110
+ if (vtLayerNames.length < 1) {
111
+ return Promise.resolve(collection);
111
112
  }
112
113
 
113
114
  // x,y,z tile coordinates
@@ -117,44 +118,56 @@ function readPBF(file, options) {
117
118
  // https://alastaira.wordpress.com/2011/07/06/converting-tms-tile-coordinates-to-googlebingosm-tile-coordinates/
118
119
  // Only if the layer.origin is top
119
120
  const y = options.in.isInverted ? options.extent.row : (1 << z) - options.extent.row - 1;
120
- const collection = new FeatureCollection(options.out);
121
- const vFeature = vectorTile.layers[sourceLayers[0]];
122
- // TODO: verify if size is correct because is computed with only one feature (vFeature).
123
- const size = vFeature.extent * 2 ** z;
121
+ const vFeature0 = vectorTile.layers[vtLayerNames[0]];
122
+ // TODO: verify if size is correct because is computed with only one feature (vFeature0).
123
+ const size = vFeature0.extent * 2 ** z;
124
124
  const center = -0.5 * size;
125
125
  collection.scale.set(globalExtent.x / size, -globalExtent.y / size, 1);
126
- collection.position.set(vFeature.extent * x + center, vFeature.extent * y + center, 0).multiply(collection.scale);
126
+ collection.position.set(vFeature0.extent * x + center, vFeature0.extent * y + center, 0).multiply(collection.scale);
127
127
  collection.updateMatrixWorld();
128
- sourceLayers.forEach(layer_id => {
129
- if (!options.in.layers[layer_id]) {
130
- return;
128
+ vtLayerNames.forEach(vtLayerName => {
129
+ if (!options.in.layers[vtLayerName]) {
130
+ return Promise.resolve(collection);
131
131
  }
132
- const sourceLayer = vectorTile.layers[layer_id];
133
- for (let i = sourceLayer.length - 1; i >= 0; i--) {
134
- const vtFeature = sourceLayer.feature(i);
132
+ const vectorTileLayer = vectorTile.layers[vtLayerName];
133
+ for (let i = vectorTileLayer.length - 1; i >= 0; i--) {
134
+ const vtFeature = vectorTileLayer.feature(i);
135
135
  vtFeature.tileNumbers = {
136
136
  x,
137
137
  y: options.extent.row,
138
138
  z
139
139
  };
140
- const layers = options.in.layers[layer_id].filter(l => l.filterExpression.filter({
140
+ // Find layers where this vtFeature is used
141
+ const layers = options.in.layers[vtLayerName].filter(l => l.filterExpression.filter({
141
142
  zoom: z
142
- }, vtFeature) && z >= l.zoom.min && z < l.zoom.max);
143
+ }, vtFeature));
144
+ for (const layer of layers) {
145
+ const feature = collection.requestFeatureById(layer.id, vtFeature.type - 1);
146
+ feature.id = layer.id;
147
+ feature.order = layer.order;
148
+ feature.style = options.in.styles[feature.id];
149
+ vtFeatureToFeatureGeometry(vtFeature, feature);
150
+ }
151
+
152
+ /*
153
+ // This optimization is not fully working and need to be reassessed
154
+ // (see https://github.com/iTowns/itowns/pull/2469/files#r1861802136)
143
155
  let feature;
144
156
  for (const layer of layers) {
145
- if (!feature) {
146
- feature = collection.requestFeatureById(layer.id, vtFeature.type - 1);
147
- feature.id = layer.id;
148
- feature.order = layer.order;
149
- feature.style = options.in.styles[feature.id];
150
- vtFeatureToFeatureGeometry(vtFeature, feature);
151
- } else if (!collection.features.find(f => f.id === layer.id)) {
152
- feature = collection.newFeatureByReference(feature);
153
- feature.id = layer.id;
154
- feature.order = layer.order;
155
- feature.style = options.in.styles[feature.id];
156
- }
157
+ if (!feature) {
158
+ feature = collection.requestFeatureById(layer.id, vtFeature.type - 1);
159
+ feature.id = layer.id;
160
+ feature.order = layer.order;
161
+ feature.style = options.in.styles[feature.id];
162
+ vtFeatureToFeatureGeometry(vtFeature, feature);
163
+ } else if (!collection.features.find(f => f.id === layer.id)) {
164
+ feature = collection.newFeatureByReference(feature);
165
+ feature.id = layer.id;
166
+ feature.order = layer.order;
167
+ feature.style = options.in.styles[feature.id];
168
+ }
157
169
  }
170
+ */
158
171
  }
159
172
  });
160
173
  collection.removeEmptyFeature();
@@ -67,10 +67,22 @@ export function computeMinMaxElevation(texture, pitch, options) {
67
67
  }
68
68
  }
69
69
  }
70
- if (options.zmin > min) {
70
+ }
71
+
72
+ // Clamp values to zmin and zmax values configured in ElevationLayer
73
+ if (options.zmin != null) {
74
+ if (min < options.zmin) {
71
75
  min = options.zmin;
72
76
  }
73
- if (options.zmax < max) {
77
+ if (max < options.zmin) {
78
+ max = options.zmin;
79
+ }
80
+ }
81
+ if (options.zmax != null) {
82
+ if (min > options.zmax) {
83
+ min = options.zmax;
84
+ }
85
+ if (max > options.zmax) {
74
86
  max = options.zmax;
75
87
  }
76
88
  }
@@ -102,7 +102,11 @@ export default {
102
102
  res = resolve;
103
103
  rej = reject;
104
104
  });
105
- textureLoader.load(url, res, () => {}, rej);
105
+ textureLoader.load(url, res, () => {}, event => {
106
+ const error = new Error(`Failed to load texture from URL: \`${url}\``);
107
+ error.originalEvent = event;
108
+ rej(error);
109
+ });
106
110
  return promise;
107
111
  },
108
112
  /**
@@ -1,6 +1,9 @@
1
- import Extent from "../Core/Geographic/Extent.js";
2
- const extent = new Extent('EPSG:4326', [0, 0, 0, 0]);
3
1
  let subDomainsCount = 0;
2
+
3
+ /**
4
+ * @param {string} url
5
+ * @returns {string}
6
+ */
4
7
  function subDomains(url) {
5
8
  const subDomainsPtrn = /\$\{u:([\w-_.|]+)\}/.exec(url);
6
9
  if (!subDomainsPtrn) {
@@ -51,8 +54,13 @@ export default {
51
54
  * // The resulting url is:
52
55
  * // http://server.geo/tms/15/2142/3412.jpg;
53
56
  *
54
- * @param {Extent} coords - the coordinates
55
- * @param {Source} source
57
+ * @param {Object} coords - tile coordinates
58
+ * @param {number} coords.row - tile row
59
+ * @param {number} coords.col - tile column
60
+ * @param {number} coords.zoom - tile zoom
61
+ * @param {Object} source
62
+ * @param {string} source.url
63
+ * @param {Function} source.tileMatrixCallback
56
64
  *
57
65
  * @return {string} the formed url
58
66
  */
@@ -79,8 +87,12 @@ export default {
79
87
  * // The resulting url is:
80
88
  * // http://server.geo/wms/BBOX=12,35,14,46&FORMAT=jpg&SERVICE=WMS
81
89
  *
82
- * @param {Extent} bbox - the bounding box
83
- * @param {Object} source
90
+ * @param {Object} bbox - the bounding box
91
+ * @param {number} bbox.west
92
+ * @param {number} bbox.south
93
+ * @param {number} bbox.east
94
+ * @param {number} bbox.north
95
+ * @param {Object} source - the source of data
84
96
  * @param {string} source.crs
85
97
  * @param {number} source.bboxDigits
86
98
  * @param {string} source.url
@@ -93,11 +105,10 @@ export default {
93
105
  if (source.bboxDigits !== undefined) {
94
106
  precision = source.bboxDigits;
95
107
  }
96
- bbox.as(source.crs, extent);
97
- const w = extent.west.toFixed(precision);
98
- const s = extent.south.toFixed(precision);
99
- const e = extent.east.toFixed(precision);
100
- const n = extent.north.toFixed(precision);
108
+ const w = bbox.west.toFixed(precision);
109
+ const s = bbox.south.toFixed(precision);
110
+ const e = bbox.east.toFixed(precision);
111
+ const n = bbox.north.toFixed(precision);
101
112
  let bboxInUnit = source.axisOrder || 'wsen';
102
113
  bboxInUnit = bboxInUnit.replace('w', `${w},`).replace('s', `${s},`).replace('e', `${e},`).replace('n', `${n},`).slice(0, -1);
103
114
  return subDomains(source.url.replace('%bbox', bboxInUnit));
@@ -173,7 +173,7 @@ class Camera {
173
173
  * @return {Coordinates} Coordinates object holding camera's position.
174
174
  */
175
175
  position(crs) {
176
- return new Coordinates(this.crs, this.camera3D.position).as(crs || this.crs);
176
+ return new Coordinates(this.crs).setFromVector3(this.camera3D.position).as(crs || this.crs);
177
177
  }
178
178
 
179
179
  /**
@@ -167,13 +167,15 @@ class Label2DRenderer {
167
167
  if (!frustum.containsPoint(worldPosition.applyMatrix4(camera.matrixWorldInverse)) ||
168
168
  // Check if globe horizon culls the label
169
169
  // Do some horizon culling (if possible) if the tiles level is small enough.
170
- label.horizonCullingPoint && GlobeLayer.horizonCulling(label.horizonCullingPoint) ||
171
- // Check if content isn't present in visible labels
172
- this.grid.visible.some(l => {
173
- // TODO for icon without text filter by position
174
- const textContent = label.content.textContent;
175
- return textContent !== '' && l.content.textContent.toLowerCase() == textContent.toLowerCase();
176
- })) {
170
+ label.horizonCullingPoint && GlobeLayer.horizonCulling(label.horizonCullingPoint)
171
+ // Why do we might need this part ?
172
+ // || // Check if content isn't present in visible labels
173
+ // this.grid.visible.some((l) => {
174
+ // // TODO for icon without text filter by position
175
+ // const textContent = label.content.textContent;
176
+ // return textContent !== '' && l.content.textContent.toLowerCase() == textContent.toLowerCase();
177
+ // })
178
+ ) {
177
179
  label.visible = false;
178
180
  } else {
179
181
  // projecting world position label
@@ -1,12 +1,11 @@
1
1
  import * as THREE from 'three';
2
- import TileGeometry from "../Core/TileGeometry.js";
3
- import BuilderEllipsoidTile from "../Core/Prefab/Globe/BuilderEllipsoidTile.js";
2
+ import * as CRS from "../Core/Geographic/Crs.js";
3
+ import { TileGeometry } from "../Core/TileGeometry.js";
4
+ import { GlobeTileBuilder } from "../Core/Prefab/Globe/GlobeTileBuilder.js";
4
5
  import Coordinates from "../Core/Geographic/Coordinates.js";
5
- import CRS from "../Core/Geographic/Crs.js";
6
6
 
7
7
  // get oriented bounding box of tile
8
- const builder = new BuilderEllipsoidTile({
9
- crs: 'EPSG:4978',
8
+ const builder = new GlobeTileBuilder({
10
9
  uvCount: 1
11
10
  });
12
11
  const size = new THREE.Vector3();
@@ -114,18 +113,17 @@ class OBB extends THREE.Object3D {
114
113
  let maxHeight = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : extent.max || 0;
115
114
  if (extent.crs == 'EPSG:4326') {
116
115
  const {
117
- sharableExtent,
116
+ shareableExtent,
118
117
  quaternion,
119
118
  position
120
- } = builder.computeSharableExtent(extent);
119
+ } = builder.computeShareableExtent(extent);
121
120
  // Compute the minimum count of segment to build tile
122
- const segments = Math.max(Math.floor(sharableExtent.planarDimensions(dimension).x / 90 + 1), 2);
123
- const geometry = new TileGeometry({
124
- extent: sharableExtent,
121
+ const segments = Math.max(Math.floor(shareableExtent.planarDimensions(dimension).x / 90 + 1), 2);
122
+ const geometry = new TileGeometry(builder, {
123
+ extent: shareableExtent,
125
124
  level: 0,
126
125
  segments,
127
- disableSkirt: true,
128
- builder
126
+ disableSkirt: true
129
127
  });
130
128
  obb.box3D.copy(geometry.boundingBox);
131
129
  obb.natBox.copy(geometry.boundingBox);
@@ -137,7 +135,7 @@ class OBB extends THREE.Object3D {
137
135
  this.position.copy(position);
138
136
  this.quaternion.copy(quaternion);
139
137
  this.updateMatrixWorld(true);
140
- } else if (!CRS.isTms(extent.crs) && CRS.isMetricUnit(extent.crs)) {
138
+ } else if (CRS.isMetricUnit(extent.crs)) {
141
139
  extent.center(coord).toVector3(this.position);
142
140
  extent.planarDimensions(dimension);
143
141
  size.set(dimension.x, dimension.y, Math.abs(maxHeight - minHeight));
@@ -258,14 +258,11 @@ class PointsMaterial extends THREE.ShaderMaterial {
258
258
  /**
259
259
  * @class PointsMaterial
260
260
  * @param {object} [options={}] The options
261
- * @param {number} [options.size=0] size point
261
+ * @param {number} [options.size=1] point size
262
262
  * @param {number} [options.mode=PNTS_MODE.COLOR] display mode.
263
263
  * @param {number} [options.shape=PNTS_SHAPE.CIRCLE] rendered points shape.
264
264
  * @param {THREE.Vector4} [options.overlayColor=new THREE.Vector4(0, 0, 0, 0)] overlay color.
265
- * @param {THREE.Vector2} [options.intensityRange=new THREE.Vector2(1, 65536)] intensity range.
266
- * @param {THREE.Vector2} [options.elevationRange=new THREE.Vector2(0, 1000)] elevation range.
267
- * @param {THREE.Vector2} [options.angleRange=new THREE.Vector2(-90, 90)] scan angle range.
268
- * @param {Scheme} [options.classificationScheme] LUT for point classification colorization.
265
+ * @param {Scheme} [options.classificationScheme] LUT for point classification colorization.
269
266
  * @param {Scheme} [options.discreteScheme] LUT for other discret point values colorization.
270
267
  * @param {string} [options.gradient] Descrition of the gradient to use for continuous point values.
271
268
  * (Default value will be the 'SPECTRAL' gradient from Utils/Gradients)
@@ -273,6 +270,9 @@ class PointsMaterial extends THREE.ShaderMaterial {
273
270
  * @param {number} [options.minAttenuatedSize=3] minimum scale used by 'ATTENUATED' size mode
274
271
  * @param {number} [options.maxAttenuatedSize=10] maximum scale used by 'ATTENUATED' size mode
275
272
  *
273
+ * @property {THREE.Vector2} [options.intensityRange=new THREE.Vector2(1, 65536)] intensity range (default value will be [1, 65536] if not defined at Layer level).
274
+ * @property {THREE.Vector2} [options.elevationRange=new THREE.Vector2(0, 1000)] elevation range (default value will be [0, 1000] if not defined at Layer level).
275
+ * @property {THREE.Vector2} [options.angleRange=new THREE.Vector2(-90, 90)] scan angle range (default value will be [-90, 90] if not defined at Layer level).
276
276
  * @property {Scheme} classificationScheme - Color scheme for point classification values.
277
277
  * @property {Scheme} discreteScheme - Color scheme for all other discrete values.
278
278
  * @property {object} gradients - Descriptions of all available gradients.
@@ -1,7 +1,6 @@
1
1
  import * as THREE from 'three';
2
2
  import { ELEVATION_MODES } from "./LayeredMaterial.js";
3
3
  import { checkNodeElevationTextureValidity, insertSignificantValuesFromParent, computeMinMaxElevation } from "../Parser/XbilParser.js";
4
- import CRS from "../Core/Geographic/Crs.js";
5
4
  export const EMPTY_TEXTURE_ZOOM = -1;
6
5
  const pitch = new THREE.Vector4();
7
6
  function getIndiceWithPitch(i, pitch, w) {
@@ -29,7 +28,7 @@ class RasterTile extends THREE.EventDispatcher {
29
28
  constructor(material, layer) {
30
29
  super();
31
30
  this.layer = layer;
32
- this.crs = layer.parent.tileMatrixSets.indexOf(CRS.formatToTms(layer.crs));
31
+ this.crs = layer.parent.tileMatrixSets.indexOf(layer.crs);
33
32
  if (this.crs == -1) {
34
33
  console.error('Unknown crs:', layer.crs);
35
34
  }
@@ -1,9 +1,3 @@
1
- /*
2
- * To change this license header, choose License Headers in Project Properties.
3
- * To change this template file, choose Tools | Templates
4
- * and open the template in the editor.
5
- */
6
-
7
1
  import * as THREE from 'three';
8
2
  function SphereHelper(radius) {
9
3
  THREE.Mesh.call(this);
@@ -1,3 +1,4 @@
1
+ import proj4 from 'proj4';
1
2
  import { Binary, Info, Las } from 'copc';
2
3
  import Extent from "../Core/Geographic/Extent.js";
3
4
  import Fetcher from "../Provider/Fetcher.js";
@@ -102,8 +103,18 @@ class CopcSource extends Source {
102
103
  this.header = metadata.header;
103
104
  this.info = metadata.info;
104
105
  this.eb = metadata.eb;
105
- // TODO: use wkt definition in `metadata.wkt` to infer/define crs
106
- this.crs = config.crs || 'EPSG:4326';
106
+ proj4.defs('unknown', metadata.wkt);
107
+ let projCS;
108
+ if (proj4.defs('unknown').type === 'COMPD_CS') {
109
+ console.warn('CopcSource: compound coordinate system is not yet supported.');
110
+ projCS = proj4.defs('unknown').PROJCS;
111
+ } else {
112
+ projCS = proj4.defs('unknown');
113
+ }
114
+ this.crs = projCS.title || projCS.name || 'EPSG:4326';
115
+ if (!(this.crs in proj4.defs)) {
116
+ proj4.defs(this.crs, projCS);
117
+ }
107
118
  const bbox = new THREE.Box3();
108
119
  bbox.min.fromArray(this.info.cube, 0);
109
120
  bbox.max.fromArray(this.info.cube, 3);
@@ -38,10 +38,19 @@ class EntwinePointTileSource extends Source {
38
38
  // Set parser and its configuration from schema
39
39
  this.parse = metadata.dataType === 'laszip' ? LASParser.parse : PotreeBinParser.parse;
40
40
  this.extension = metadata.dataType === 'laszip' ? 'laz' : 'bin';
41
- if (metadata.srs && metadata.srs.authority && metadata.srs.horizontal) {
42
- this.crs = `${metadata.srs.authority}:${metadata.srs.horizontal}`;
43
- if (!proj4.defs(this.crs)) {
44
- proj4.defs(this.crs, metadata.srs.wkt);
41
+ if (metadata.srs) {
42
+ if (metadata.srs.authority && metadata.srs.horizontal) {
43
+ this.crs = `${metadata.srs.authority}:${metadata.srs.horizontal}`;
44
+ if (!proj4.defs(this.crs)) {
45
+ proj4.defs(this.crs, metadata.srs.wkt);
46
+ }
47
+ } else if (metadata.srs.wkt) {
48
+ proj4.defs('unknown', metadata.srs.wkt);
49
+ const projCS = proj4.defs('unknown');
50
+ this.crs = projCS.title || projCS.name;
51
+ if (!(this.crs in proj4.defs)) {
52
+ proj4.defs(this.crs, projCS);
53
+ }
45
54
  }
46
55
  if (metadata.srs.vertical && metadata.srs.vertical !== metadata.srs.horizontal) {
47
56
  console.warn('EntwinePointTileSource: Vertical coordinates system code is not yet supported.');
@@ -53,6 +62,7 @@ class EntwinePointTileSource extends Source {
53
62
  // span in ept.json. This needs improvements.
54
63
  this.spacing = (Math.abs(metadata.boundsConforming[3] - metadata.boundsConforming[0]) + Math.abs(metadata.boundsConforming[4] - metadata.boundsConforming[1])) / (2 * metadata.span);
55
64
  this.boundsConforming = metadata.boundsConforming;
65
+ this.bounds = metadata.bounds;
56
66
  this.span = metadata.span;
57
67
  return this;
58
68
  });
@@ -1,6 +1,5 @@
1
1
  import Source from "./Source.js";
2
- import Cache from "../Core/Scheduler/Cache.js";
3
- import CRS from "../Core/Geographic/Crs.js";
2
+ import { LRUCache } from 'lru-cache';
4
3
 
5
4
  /**
6
5
  * An object defining the source of a single resource to get from a direct
@@ -104,12 +103,10 @@ class FileSource extends Source {
104
103
  * presents in `features` under the property `crs`, it is fine.
105
104
  */
106
105
  constructor(source) {
107
- /* istanbul ignore next */
108
106
  if (source.parsedData) {
109
107
  console.warn('FileSource parsedData parameter is deprecated, use features instead of.');
110
108
  source.features = source.features || source.parsedData;
111
109
  }
112
- /* istanbul ignore next */
113
110
  if (source.projection) {
114
111
  console.warn('FileSource projection parameter is deprecated, use crs instead.');
115
112
  source.crs = source.crs || source.projection;
@@ -136,8 +133,10 @@ class FileSource extends Source {
136
133
  this.fetchedData = f;
137
134
  });
138
135
  } else if (source.features) {
139
- this._featuresCaches[source.features.crs] = new Cache();
140
- this._featuresCaches[source.features.crs].setByArray(Promise.resolve(source.features), [0]);
136
+ this._featuresCaches[source.features.crs] = new LRUCache({
137
+ max: 500
138
+ });
139
+ this._featuresCaches[source.features.crs].set(0, Promise.resolve(source.features));
141
140
  }
142
141
  this.whenReady.then(() => this.fetchedData);
143
142
  this.zoom = {
@@ -151,14 +150,14 @@ class FileSource extends Source {
151
150
  onLayerAdded(options) {
152
151
  options.in = this;
153
152
  super.onLayerAdded(options);
154
- let features = this._featuresCaches[options.out.crs].getByArray([0]);
153
+ let features = this._featuresCaches[options.out.crs].get(0);
155
154
  if (!features) {
156
155
  options.out.buildExtent = this.crs != 'EPSG:4978';
157
156
  if (options.out.buildExtent) {
158
- options.out.forcedExtentCrs = options.out.crs != 'EPSG:4978' ? options.out.crs : CRS.formatToEPSG(this.crs);
157
+ options.out.forcedExtentCrs = options.out.crs != 'EPSG:4978' ? options.out.crs : this.crs;
159
158
  }
160
159
  features = this.parser(this.fetchedData, options);
161
- this._featuresCaches[options.out.crs].setByArray(features, [0]);
160
+ this._featuresCaches[options.out.crs].set(0, features);
162
161
  }
163
162
  features.then(data => {
164
163
  if (data.extent) {
@@ -180,7 +179,7 @@ class FileSource extends Source {
180
179
  * @return {FeatureCollection|Texture} The parsed data.
181
180
  */
182
181
  loadData(extent, out) {
183
- return this._featuresCaches[out.crs].getByArray([0]);
182
+ return this._featuresCaches[out.crs].get(0);
184
183
  }
185
184
  extentInsideLimit(extent) {
186
185
  return this.extent.intersectsExtent(extent);
@@ -41,8 +41,8 @@ class OrientedImageSource extends Source {
41
41
  urlFromExtent(imageInfo) {
42
42
  return this.imageUrl(imageInfo.cameraId, imageInfo.panoId);
43
43
  }
44
- requestToKey(image) {
45
- return [image.cameraId, image.panoId];
44
+ getDataKey(image) {
45
+ return `c${image.cameraId}p${image.panoId}`;
46
46
  }
47
47
 
48
48
  /**