itowns 2.35.0 → 2.37.0

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 (110) hide show
  1. package/CONTRIBUTING.md +30 -17
  2. package/CONTRIBUTORS.md +1 -0
  3. package/changelog.md +146 -0
  4. package/dist/debug.js +1 -1
  5. package/dist/debug.js.LICENSE.txt +1 -1
  6. package/dist/debug.js.map +1 -1
  7. package/dist/itowns.js +1 -1
  8. package/dist/itowns.js.map +1 -1
  9. package/dist/itowns_widgets.js +2 -0
  10. package/dist/itowns_widgets.js.map +1 -0
  11. package/examples/3dtiles_basic.html +2 -2
  12. package/examples/config.json +25 -6
  13. package/examples/css/widgets.css +248 -0
  14. package/examples/geoid_geoidLayer.html +102 -0
  15. package/examples/images/compass.svg +60 -0
  16. package/examples/images/widget-logo.svg +66 -0
  17. package/examples/itowns-potree.html +252 -0
  18. package/examples/js/GUI/GuiTools.js +17 -0
  19. package/examples/js/Scale.js +1 -0
  20. package/examples/js/plugins/CSVnVRTParser.js +0 -1
  21. package/examples/layers/JSONLayers/Administrative.json +1 -1
  22. package/examples/layers/JSONLayers/Cada.json +1 -1
  23. package/examples/layers/JSONLayers/EtatMajor.json +1 -1
  24. package/examples/layers/JSONLayers/IGN_MNT.json +1 -1
  25. package/examples/layers/JSONLayers/IGN_MNT_HIGHRES.json +1 -1
  26. package/examples/layers/JSONLayers/WORLD_DTM.json +1 -1
  27. package/examples/misc_custom_label.html +0 -2
  28. package/examples/plugins_vrt.html +0 -1
  29. package/examples/source_file_from_fetched_data.html +90 -0
  30. package/examples/source_file_from_format.html +85 -0
  31. package/examples/source_file_from_methods.html +87 -0
  32. package/examples/source_file_from_parsed_data.html +104 -0
  33. package/examples/source_file_geojson_raster.html +21 -48
  34. package/examples/source_file_gpx_raster.html +28 -36
  35. package/examples/source_file_kml_raster.html +1 -4
  36. package/examples/source_file_shapefile.html +39 -35
  37. package/examples/source_stream_wfs_25d.html +29 -29
  38. package/examples/source_stream_wfs_3d.html +21 -12
  39. package/examples/source_stream_wfs_raster.html +20 -20
  40. package/examples/view_25d_map.html +28 -0
  41. package/examples/view_immersive.html +13 -14
  42. package/examples/view_multi_25d.html +1 -1
  43. package/examples/widgets_minimap.html +122 -0
  44. package/examples/widgets_navigation.html +119 -0
  45. package/lib/Controls/FirstPersonControls.js +10 -1
  46. package/lib/Controls/GlobeControls.js +26 -11
  47. package/lib/Controls/PlanarControls.js +1 -1
  48. package/lib/Converter/Feature2Mesh.js +1 -0
  49. package/lib/Converter/Feature2Texture.js +2 -2
  50. package/lib/Converter/convertToTile.js +6 -2
  51. package/lib/Core/3DTiles/C3DTBoundingVolume.js +4 -1
  52. package/lib/Core/Deprecated/Undeprecator.js +1 -1
  53. package/lib/Core/Feature.js +42 -42
  54. package/lib/Core/Geographic/Coordinates.js +56 -0
  55. package/lib/Core/Geographic/Crs.js +15 -0
  56. package/lib/Core/Geographic/Extent.js +100 -12
  57. package/lib/Core/Geographic/GeoidGrid.js +143 -0
  58. package/lib/Core/MainLoop.js +1 -1
  59. package/lib/Core/Math/Ellipsoid.js +27 -9
  60. package/lib/Core/Prefab/Globe/BuilderEllipsoidTile.js +1 -1
  61. package/lib/Core/Prefab/Globe/SkyShader.js +3 -1
  62. package/lib/Core/Prefab/Planar/PlanarLayer.js +3 -1
  63. package/lib/Core/Prefab/PlanarView.js +1 -1
  64. package/lib/Core/Style.js +2 -1
  65. package/lib/Core/TileGeometry.js +3 -1
  66. package/lib/Core/TileMesh.js +11 -16
  67. package/lib/Core/View.js +43 -5
  68. package/lib/Layer/ElevationLayer.js +15 -18
  69. package/lib/Layer/FeatureGeometryLayer.js +3 -1
  70. package/lib/Layer/GeoidLayer.js +131 -0
  71. package/lib/Layer/InfoLayer.js +1 -1
  72. package/lib/Layer/LabelLayer.js +7 -1
  73. package/lib/Layer/Layer.js +1 -1
  74. package/lib/Layer/LayerUpdateStrategy.js +1 -1
  75. package/lib/Layer/PotreeLayer.js +3 -1
  76. package/lib/Layer/TiledGeometryLayer.js +3 -1
  77. package/lib/Main.js +214 -174
  78. package/lib/MainBundle.js +1 -1
  79. package/lib/Parser/B3dmParser.js +2 -1
  80. package/lib/Parser/GDFParser.js +118 -0
  81. package/lib/Parser/GTXParser.js +92 -0
  82. package/lib/Parser/ISGParser.js +121 -0
  83. package/lib/Parser/LASParser.js +3 -1
  84. package/lib/Parser/ShapefileParser.js +0 -1
  85. package/lib/Parser/VectorTileParser.js +1 -1
  86. package/lib/Parser/XbilParser.js +1 -1
  87. package/lib/Process/3dTilesProcessing.js +10 -10
  88. package/lib/Process/FeatureProcessing.js +3 -1
  89. package/lib/Process/LayeredMaterialNodeProcessing.js +7 -4
  90. package/lib/Process/ObjectRemovalHelper.js +5 -2
  91. package/lib/Provider/URLBuilder.js +1 -1
  92. package/lib/Renderer/Label2DRenderer.js +14 -11
  93. package/lib/Renderer/LayeredMaterial.js +4 -3
  94. package/lib/Renderer/OBB.js +20 -27
  95. package/lib/Renderer/PointsMaterial.js +5 -6
  96. package/lib/Renderer/RasterTile.js +23 -5
  97. package/lib/Renderer/Shader/ShaderChunk.js +3 -3
  98. package/lib/Renderer/Shader/ShaderUtils.js +4 -2
  99. package/lib/Source/C3DTilesSource.js +3 -1
  100. package/lib/Source/EntwinePointTileSource.js +3 -1
  101. package/lib/Source/FileSource.js +2 -7
  102. package/lib/Source/PotreeSource.js +3 -1
  103. package/lib/Source/Source.js +15 -10
  104. package/lib/Source/VectorTilesSource.js +19 -0
  105. package/lib/Source/WMTSSource.js +3 -1
  106. package/lib/ThreeExtended/loaders/GLTFLoader.js +239 -98
  107. package/lib/Utils/CameraUtils.js +12 -2
  108. package/lib/Utils/DEMUtils.js +3 -3
  109. package/lib/Utils/FeaturesUtils.js +8 -4
  110. package/package.json +25 -25
@@ -7,7 +7,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
7
7
  Object.defineProperty(exports, "__esModule", {
8
8
  value: true
9
9
  });
10
- exports.FeatureCollection = exports["default"] = exports.FeatureGeometry = exports.FeatureBuildingOptions = exports.FEATURE_TYPES = void 0;
10
+ exports["default"] = exports.FeatureGeometry = exports.FeatureCollection = exports.FeatureBuildingOptions = exports.FEATURE_TYPES = void 0;
11
11
 
12
12
  var _get2 = _interopRequireDefault(require("@babel/runtime/helpers/get"));
13
13
 
@@ -57,6 +57,19 @@ function _extendBuffer(feature, size) {
57
57
  }
58
58
  }
59
59
 
60
+ function _setGeometryValues(geom, feature, _long, lat, alt, normal) {
61
+ if (feature.normals) {
62
+ normal.toArray(feature.normals, feature._pos);
63
+ }
64
+
65
+ feature._pushValues(_long, lat, alt);
66
+
67
+ if (geom.size == 3) {
68
+ geom.altitude.min = Math.min(geom.altitude.min, alt);
69
+ geom.altitude.max = Math.max(geom.altitude.max, alt);
70
+ }
71
+ }
72
+
60
73
  var coordOut = new _Coordinates["default"]('EPSG:4326', 0, 0, 0);
61
74
  var defaultNormal = new THREE.Vector3(0, 0, 1);
62
75
  var FEATURE_TYPES = {
@@ -68,25 +81,26 @@ exports.FEATURE_TYPES = FEATURE_TYPES;
68
81
  var typeToStyleProperty = ['point', 'stroke', 'fill'];
69
82
  /**
70
83
  * @property {string} crs - The CRS to convert the input coordinates to.
84
+ * @property {string} [structure='2d'] - data structure type : 2d or 3d.
85
+ * If the structure is 3d, the feature have 3 dimensions by vertices positions and
86
+ * a normal for each vertices.
71
87
  * @property {Extent|boolean} [filteringExtent=undefined] - Optional filter to reject
72
- * features outside of extent. Extent filetring is file extent if filteringExtent is true.
73
- * @property {boolean} [buildExtent=false] - If true the geometry will
88
+ * features outside of extent. Extent filtering is file extent if filteringExtent is true.
89
+ * @property {boolean} [buildExtent] - If true the geometry will
74
90
  * have an extent property containing the area covered by the geometry.
91
+ * Default value is false if `structure` parameter is set to '3d', and true otherwise.
75
92
  * True if the layer does not inherit from {@link GeometryLayer}.
76
93
  * @property {string} forcedExtentCrs - force feature extent crs if buildExtent is true.
77
94
  * @property {function} [filter] - Filter function to remove features
78
- * @property {boolean} [mergeFeatures=true] - If true all geometries are merged by type and multi-type
79
- * @property {string} [structure='2d'] - data structure type : 2d or 3d.
80
- * If the structure is 3d, the feature have 3 dimensions by vertices positions and
81
- * a normal for each vertices.
95
+ * @property {boolean} [mergeFeatures=true] - If true all geometries are merged by type and multi-type.
82
96
  * @property {Style} style - The style to inherit when creating
83
97
  * style for all new features.
84
98
  *
85
99
  */
86
100
 
87
- var FeatureBuildingOptions = function FeatureBuildingOptions() {
101
+ var FeatureBuildingOptions = /*#__PURE__*/(0, _createClass2["default"])(function FeatureBuildingOptions() {
88
102
  (0, _classCallCheck2["default"])(this, FeatureBuildingOptions);
89
- };
103
+ });
90
104
  /**
91
105
  * @property {Extent} extent - The 2D extent containing all the points
92
106
  * composing the geometry.
@@ -98,7 +112,6 @@ var FeatureBuildingOptions = function FeatureBuildingOptions() {
98
112
  * anything specified in the GeoJSON under the `properties` property.
99
113
  */
100
114
 
101
-
102
115
  exports.FeatureBuildingOptions = FeatureBuildingOptions;
103
116
 
104
117
  var FeatureGeometry = /*#__PURE__*/function () {
@@ -175,6 +188,12 @@ var FeatureGeometry = /*#__PURE__*/function () {
175
188
  var last = this.indices.length - 1;
176
189
  return this.indices[last];
177
190
  }
191
+ }, {
192
+ key: "baseAltitude",
193
+ value: function baseAltitude(feature, coordinates) {
194
+ var base_altitude = feature.style[typeToStyleProperty[feature.type]].base_altitude || 0;
195
+ return isNaN(base_altitude) ? base_altitude(this.properties, coordinates) : base_altitude;
196
+ }
178
197
  /**
179
198
  * Push new coordinates in vertices buffer.
180
199
  * @param {Coordinates} coordIn The coordinates to push.
@@ -184,30 +203,16 @@ var FeatureGeometry = /*#__PURE__*/function () {
184
203
  }, {
185
204
  key: "pushCoordinates",
186
205
  value: function pushCoordinates(coordIn, feature) {
187
- if (this.size == 3) {
188
- // set altitude from context
189
- var base_altitude = feature.style[typeToStyleProperty[feature.type]].base_altitude;
190
- coordIn.z = isNaN(base_altitude) ? base_altitude(this.properties, coordIn) : base_altitude;
191
- }
192
-
206
+ coordIn.z = this.baseAltitude(feature, coordIn);
193
207
  coordIn.as(feature.crs, coordOut);
194
208
  feature.transformToLocalSystem(coordOut);
195
209
 
196
- if (feature.normals) {
197
- coordOut.geodesicNormal.toArray(feature.normals, feature._pos);
198
- }
199
-
200
- feature._pushValues(coordOut.x, coordOut.y, coordOut.z); // expand extent if present
210
+ _setGeometryValues(this, feature, coordOut.x, coordOut.y, coordOut.z, coordOut.geodesicNormal); // expand extent if present
201
211
 
202
212
 
203
213
  if (this._currentExtent) {
204
214
  this._currentExtent.expandByCoordinates(feature.useCrsOut ? coordOut : coordIn);
205
215
  }
206
-
207
- if (this.size == 3) {
208
- this.altitude.min = Math.min(this.altitude.min, coordIn.z);
209
- this.altitude.max = Math.max(this.altitude.max, coordIn.z);
210
- }
211
216
  }
212
217
  /**
213
218
  * Push new values coordinates in vertices buffer.
@@ -217,30 +222,20 @@ var FeatureGeometry = /*#__PURE__*/function () {
217
222
  * @param {Feature} feature - the feature containing the geometry
218
223
  * @param {number} long The longitude coordinate.
219
224
  * @param {number} lat The latitude coordinate.
220
- * @param {number} [alt=0] The altitude coordinate.
221
225
  * @param {THREE.Vector3} [normal=THREE.Vector3(0,0,1)] the normal on coordinates.
222
226
  */
223
227
 
224
228
  }, {
225
229
  key: "pushCoordinatesValues",
226
- value: function pushCoordinatesValues(feature, _long, lat) {
227
- var alt = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
228
- var normal = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : defaultNormal;
229
-
230
- if (feature.normals) {
231
- normal.toArray(feature.normals, feature._pos);
232
- }
230
+ value: function pushCoordinatesValues(feature, _long2, lat) {
231
+ var normal = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : defaultNormal;
232
+ var altitude = this.baseAltitude(feature);
233
233
 
234
- feature._pushValues(_long, lat, alt); // expand extent if present
234
+ _setGeometryValues(this, feature, _long2, lat, altitude, normal); // expand extent if present
235
235
 
236
236
 
237
237
  if (this._currentExtent) {
238
- this._currentExtent.expandByValuesCoordinates(_long, lat);
239
- }
240
-
241
- if (this.size == 3) {
242
- this.altitude.min = Math.min(this.altitude.min, alt);
243
- this.altitude.max = Math.max(this.altitude.max, alt);
238
+ this._currentExtent.expandByValuesCoordinates(_long2, lat);
244
239
  }
245
240
  }
246
241
  /**
@@ -469,7 +464,6 @@ var FeatureCollection = /*#__PURE__*/function (_THREE$Object3D) {
469
464
  _this.crs = _Crs["default"].formatToEPSG(options.crs);
470
465
  _this.features = [];
471
466
  _this.mergeFeatures = options.mergeFeatures === undefined ? true : options.mergeFeatures;
472
- _this.extent = options.buildExtent ? defaultExtent(options.forcedExtentCrs || _this.crs) : undefined;
473
467
  _this.size = options.structure == '3d' ? 3 : 2;
474
468
  _this.filterExtent = options.filterExtent;
475
469
  _this.style = options.style;
@@ -478,6 +472,8 @@ var FeatureCollection = /*#__PURE__*/function (_THREE$Object3D) {
478
472
  _this.center = new _Coordinates["default"]('EPSG:4326', 0, 0);
479
473
 
480
474
  if (_this.size == 2) {
475
+ _this.extent = options.buildExtent === false ? undefined : defaultExtent(options.forcedExtentCrs || _this.crs);
476
+
481
477
  _this._setLocalSystem = function (center) {
482
478
  // set local system center
483
479
  center.as('EPSG:4326', _this.center); // set position to local system center
@@ -491,6 +487,8 @@ var FeatureCollection = /*#__PURE__*/function (_THREE$Object3D) {
491
487
 
492
488
  _this._transformToLocalSystem = transformToLocalSystem2D;
493
489
  } else {
490
+ _this.extent = options.buildExtent ? defaultExtent(options.forcedExtentCrs || _this.crs) : undefined;
491
+
494
492
  _this._setLocalSystem = function (center) {
495
493
  // set local system center
496
494
  center.as('EPSG:4326', _this.center);
@@ -686,6 +684,8 @@ var FeatureCollection = /*#__PURE__*/function (_THREE$Object3D) {
686
684
  ref.normals = feature.normals;
687
685
  ref.size = feature.size;
688
686
  ref.vertices = feature.vertices;
687
+ ref.altitude.min = feature.altitude.min;
688
+ ref.altitude.max = feature.altitude.max;
689
689
  ref._pos = feature._pos;
690
690
  this.features.push(ref);
691
691
  return ref;
@@ -29,6 +29,10 @@ _proj["default"].defs('EPSG:4978', '+proj=geocent +datum=WGS84 +units=m +no_defs
29
29
 
30
30
  var ellipsoid = new _Ellipsoid["default"]();
31
31
  var projectionCache = {};
32
+ var v0 = new THREE.Vector3();
33
+ var v1 = new THREE.Vector3();
34
+ var coord0;
35
+ var coord1;
32
36
 
33
37
  function proj4cache(crsIn, crsOut) {
34
38
  if (!projectionCache[crsIn]) {
@@ -242,6 +246,56 @@ var Coordinates = /*#__PURE__*/function () {
242
246
  var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new THREE.Vector3();
243
247
  return target.copy(this);
244
248
  }
249
+ /**
250
+ * Calculate planar distance between this coordinates and `coord`.
251
+ * Planar distance is the straight-line euclidean distance calculated in a 2D cartesian coordinate system.
252
+ *
253
+ * @param {Coordinates} coord The coordinate
254
+ * @return {number} planar distance
255
+ *
256
+ */
257
+
258
+ }, {
259
+ key: "planarDistanceTo",
260
+ value: function planarDistanceTo(coord) {
261
+ this.toVector3(v0).setZ(0);
262
+ coord.toVector3(v1).setZ(0);
263
+ return v0.distanceTo(v1);
264
+ }
265
+ /**
266
+ * Calculate geodetic distance between this coordinates and `coord`.
267
+ * **Geodetic distance** is calculated in an ellispoid space as the shortest distance
268
+ * across the curved surface of the world.
269
+ *
270
+ * => As the crow flies/ Orthodromy
271
+ *
272
+ * @param {Coordinates} coord The coordinate
273
+ * @return {number} geodetic distance
274
+ *
275
+ */
276
+
277
+ }, {
278
+ key: "geodeticDistanceTo",
279
+ value: function geodeticDistanceTo(coord) {
280
+ this.as('EPSG:4326', coord0);
281
+ coord.as('EPSG:4326', coord1);
282
+ return ellipsoid.geodesicDistance(coord0, coord1);
283
+ }
284
+ /**
285
+ * Calculate earth euclidean distance between this coordinates and `coord`.
286
+ *
287
+ * @param {Coordinates} coord The coordinate
288
+ * @return {number} earth euclidean distance
289
+ *
290
+ */
291
+
292
+ }, {
293
+ key: "spatialEuclideanDistanceTo",
294
+ value: function spatialEuclideanDistanceTo(coord) {
295
+ this.as('EPSG:4978', coord0).toVector3(v0);
296
+ coord.as('EPSG:4978', coord1).toVector3(v1);
297
+ return v0.distanceTo(v1);
298
+ }
245
299
  /**
246
300
  * Multiplies this `coordinates` (with an implicit 1 in the 4th dimension) and `mat`.
247
301
  *
@@ -302,5 +356,7 @@ var Coordinates = /*#__PURE__*/function () {
302
356
  return Coordinates;
303
357
  }();
304
358
 
359
+ coord0 = new Coordinates('EPSG:4326', 0, 0, 0);
360
+ coord1 = new Coordinates('EPSG:4326', 0, 0, 0);
305
361
  var _default = Coordinates;
306
362
  exports["default"] = _default;
@@ -36,6 +36,12 @@ function is4326(crs) {
36
36
  return crs === 'EPSG:4326';
37
37
  }
38
38
 
39
+ function isGeocentric(crs) {
40
+ var projection = _proj["default"].defs(crs);
41
+
42
+ return !projection ? false : projection.projName == 'geocent';
43
+ }
44
+
39
45
  function _unitFromProj4Unit(projunit) {
40
46
  if (projunit === 'degrees') {
41
47
  return UNIT.DEGREE;
@@ -140,6 +146,15 @@ var _default = {
140
146
  */
141
147
  is4326: is4326,
142
148
 
149
+ /**
150
+ * Is the CRS geocentric ?
151
+ * if crs isn't defined the method returns false.
152
+ *
153
+ * @param {string} crs - The CRS to test.
154
+ * @return {boolean}
155
+ */
156
+ isGeocentric: isGeocentric,
157
+
143
158
  /**
144
159
  * Give a reasonnable epsilon to use with this CRS.
145
160
  *
@@ -7,7 +7,7 @@ var _typeof = require("@babel/runtime/helpers/typeof");
7
7
  Object.defineProperty(exports, "__esModule", {
8
8
  value: true
9
9
  });
10
- exports["default"] = exports.schemeTiles = exports.globalExtentTMS = void 0;
10
+ exports.schemeTiles = exports.globalExtentTMS = exports["default"] = void 0;
11
11
 
12
12
  var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
13
13
 
@@ -33,6 +33,8 @@ var _dim2 = new THREE.Vector2();
33
33
 
34
34
  var _countTiles = new THREE.Vector2();
35
35
 
36
+ var _box = new THREE.Box3();
37
+
36
38
  var tmsCoord = new THREE.Vector2();
37
39
  var dimensionTile = new THREE.Vector2();
38
40
  var defaultScheme = new THREE.Vector2(2, 2);
@@ -41,6 +43,9 @@ var r = {
41
43
  col: 0,
42
44
  invDiff: 0
43
45
  };
46
+ var cNorthWest = new _Coordinates["default"]('EPSG:4326', 0, 0, 0);
47
+ var cSouthWest = new _Coordinates["default"]('EPSG:4326', 0, 0, 0);
48
+ var cNorthEast = new _Coordinates["default"]('EPSG:4326', 0, 0, 0);
44
49
  var southWest = new THREE.Vector3();
45
50
  var northEast = new THREE.Vector3();
46
51
 
@@ -74,7 +79,7 @@ function getInfoTms(crs) {
74
79
  var epsg = _Crs["default"].formatToEPSG(crs);
75
80
 
76
81
  var globalExtent = globalExtentTMS.get(epsg);
77
- var globalDimension = globalExtent.dimensions(_dim2);
82
+ var globalDimension = globalExtent.planarDimensions(_dim2);
78
83
 
79
84
  var tms = _Crs["default"].formatToTms(crs);
80
85
 
@@ -109,6 +114,8 @@ var Extent = /*#__PURE__*/function () {
109
114
  * Extent is geographical bounding rectangle defined by 4 limits: west, east, south and north.
110
115
  * If crs is tiled projection (WMTS or TMS), the extent is defined by zoom, row and column.
111
116
  *
117
+ * Warning, using geocentric projection isn't consistent with geographical extent.
118
+ *
112
119
  * @param {String} crs projection of limit values.
113
120
  * @param {number|Array.<number>|Coordinates|Object} v0 west value, zoom
114
121
  * value, Array of values [west, east, south and north], Coordinates of
@@ -120,6 +127,11 @@ var Extent = /*#__PURE__*/function () {
120
127
  */
121
128
  function Extent(crs, v0, v1, v2, v3) {
122
129
  (0, _classCallCheck2["default"])(this, Extent);
130
+
131
+ if (_Crs["default"].isGeocentric(crs)) {
132
+ throw new Error("".concat(crs, " is a geocentric projection, it doesn't make sense with a geographical extent"));
133
+ }
134
+
123
135
  this.isExtent = true;
124
136
  this.crs = crs; // Scale/zoom
125
137
 
@@ -173,7 +185,7 @@ var Extent = /*#__PURE__*/function () {
173
185
  sTs = _getInfoTms.sTs;
174
186
 
175
187
  extent.clampByExtent(globalExtent);
176
- extent.dimensions(dimensionTile);
188
+ extent.planarDimensions(dimensionTile);
177
189
  var zoom = this.zoom + 1 || Math.floor(Math.log2(Math.round(globalDimension.x / (dimensionTile.x * sTs.x))));
178
190
  var countTiles = getCountTiles(crs, zoom);
179
191
  var center = extent.center(_c);
@@ -199,7 +211,7 @@ var Extent = /*#__PURE__*/function () {
199
211
 
200
212
  var _center = this.center(_c);
201
213
 
202
- this.dimensions(dimensionTile); // Each level has 2^n * 2^n tiles...
214
+ this.planarDimensions(dimensionTile); // Each level has 2^n * 2^n tiles...
203
215
  // ... so we count how many tiles of the same width as tile we can fit in the layer
204
216
  // ... 2^zoom = tilecount => zoom = log2(tilecount)
205
217
 
@@ -297,7 +309,7 @@ var Extent = /*#__PURE__*/function () {
297
309
  throw new Error('Invalid operation for WMTS bbox');
298
310
  }
299
311
 
300
- this.dimensions(_dim);
312
+ this.planarDimensions(_dim);
301
313
  target.crs = this.crs;
302
314
  target.setFromValues(this.west + _dim.x * 0.5, this.south + _dim.y * 0.5);
303
315
  return target;
@@ -314,10 +326,71 @@ var Extent = /*#__PURE__*/function () {
314
326
  key: "dimensions",
315
327
  value: function dimensions() {
316
328
  var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new THREE.Vector2();
329
+ console.warn('Extent.dimensions is deprecated, use planarDimensions, geodeticDimensions or spatialEuclideanDimensions');
317
330
  target.x = Math.abs(this.east - this.west);
318
331
  target.y = Math.abs(this.north - this.south);
319
332
  return target;
320
333
  }
334
+ /**
335
+ * Planar dimensions are two planar distances west/east and south/north.
336
+ * Planar distance straight-line Euclidean distance calculated in a 2D Cartesian coordinate system.
337
+ *
338
+ * @param {THREE.Vector2} [target=new THREE.Vector2()] The target
339
+ * @return {THREE.Vector2} Planar dimensions
340
+ */
341
+
342
+ }, {
343
+ key: "planarDimensions",
344
+ value: function planarDimensions() {
345
+ var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new THREE.Vector2();
346
+ // Calculte the dimensions for x and y
347
+ return target.set(Math.abs(this.east - this.west), Math.abs(this.north - this.south));
348
+ }
349
+ /**
350
+ * Geodetic dimensions are two planar distances west/east and south/north.
351
+ * Geodetic distance is calculated in an ellispoid space as the distance
352
+ * across the curved surface of the world.
353
+ *
354
+ * @param {THREE.Vector2} [target=new THREE.Vector2()] The target
355
+ * @return {THREE.Vector2} geodetic dimensions
356
+ */
357
+
358
+ }, {
359
+ key: "geodeticDimensions",
360
+ value: function geodeticDimensions() {
361
+ var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new THREE.Vector2();
362
+ // set 3 corners extent
363
+ cNorthWest.crs = this.crs;
364
+ cSouthWest.crs = this.crs;
365
+ cNorthEast.crs = this.crs;
366
+ cNorthWest.setFromValues(this.west, this.north, 0);
367
+ cSouthWest.setFromValues(this.west, this.south, 0);
368
+ cNorthEast.setFromValues(this.east, this.north, 0); // calcul geodetic distance northWest/northEast and northWest/southWest
369
+
370
+ return target.set(cNorthWest.geodeticDistanceTo(cNorthEast), cNorthWest.geodeticDistanceTo(cSouthWest));
371
+ }
372
+ /**
373
+ * Spatial euclidean dimensions are two spatial euclidean distances between west/east corner and south/north corner.
374
+ * Spatial euclidean distance chord is calculated in a ellispoid space.
375
+ *
376
+ * @param {THREE.Vector2} [target=new THREE.Vector2()] The target
377
+ * @return {THREE.Vector2} spatial euclidean dimensions
378
+ */
379
+
380
+ }, {
381
+ key: "spatialEuclideanDimensions",
382
+ value: function spatialEuclideanDimensions() {
383
+ var target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new THREE.Vector2();
384
+ // set 3 corners extent
385
+ cNorthWest.crs = this.crs;
386
+ cSouthWest.crs = this.crs;
387
+ cNorthEast.crs = this.crs;
388
+ cNorthWest.setFromValues(this.west, this.north, 0);
389
+ cSouthWest.setFromValues(this.west, this.south, 0);
390
+ cNorthEast.setFromValues(this.east, this.north, 0); // calcul chord distance northWest/northEast and northWest/southWest
391
+
392
+ return target.set(cNorthWest.spatialEuclideanDistanceTo(cNorthEast), cNorthWest.spatialEuclideanDistanceTo(cSouthWest));
393
+ }
321
394
  /**
322
395
  * Return true if `coord` is inside the bounding box.
323
396
  *
@@ -394,8 +467,8 @@ var Extent = /*#__PURE__*/function () {
394
467
  return target.set(this.col * r.invDiff - r.col, this.row * r.invDiff - r.row, r.invDiff, r.invDiff);
395
468
  }
396
469
 
397
- extent.dimensions(_dim);
398
- this.dimensions(_dim2);
470
+ extent.planarDimensions(_dim);
471
+ this.planarDimensions(_dim2);
399
472
  var originX = (this.west - extent.west) / _dim.x;
400
473
  var originY = (extent.north - this.north) / _dim.y;
401
474
  var scaleX = _dim2.x / _dim.x;
@@ -609,9 +682,14 @@ var Extent = /*#__PURE__*/function () {
609
682
  }
610
683
  }
611
684
  /**
612
- * Instance Extent with THREE.Box2
685
+ * Instance Extent with THREE.Box3.
686
+ *
687
+ * If crs is a geocentric projection, the `box3.min` and `box3.max`
688
+ * should be the geocentric coordinates of `min` and `max` of a `box3`
689
+ * in local tangent plane.
690
+ *
613
691
  * @param {string} crs Projection of extent to instancied.
614
- * @param {THREE.Box2} box
692
+ * @param {THREE.Box3} box
615
693
  * @return {Extent}
616
694
  */
617
695
 
@@ -657,7 +735,7 @@ var Extent = /*#__PURE__*/function () {
657
735
  value: function subdivisionByScheme() {
658
736
  var scheme = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultScheme;
659
737
  var subdivisedExtents = [];
660
- var dimSub = this.dimensions(_dim).divide(scheme);
738
+ var dimSub = this.planarDimensions(_dim).divide(scheme);
661
739
 
662
740
  for (var x = scheme.x - 1; x >= 0; x--) {
663
741
  for (var y = scheme.y - 1; y >= 0; y--) {
@@ -680,8 +758,8 @@ var Extent = /*#__PURE__*/function () {
680
758
  key: "applyMatrix4",
681
759
  value: function applyMatrix4(matrix) {
682
760
  if (!_Crs["default"].isTms(this.crs)) {
683
- southWest.set(this.west, this.south).applyMatrix4(matrix);
684
- northEast.set(this.east, this.north).applyMatrix4(matrix);
761
+ southWest.set(this.west, this.south, 0).applyMatrix4(matrix);
762
+ northEast.set(this.east, this.north, 0).applyMatrix4(matrix);
685
763
  this.west = southWest.x;
686
764
  this.east = northEast.x;
687
765
  this.south = southWest.y;
@@ -752,6 +830,16 @@ var Extent = /*#__PURE__*/function () {
752
830
  }], [{
753
831
  key: "fromBox3",
754
832
  value: function fromBox3(crs, box) {
833
+ if (_Crs["default"].isGeocentric(crs)) {
834
+ // if geocentric reproject box on 'EPSG:4326'
835
+ crs = 'EPSG:4326';
836
+ box = _box.copy(box);
837
+ cSouthWest.crs = crs;
838
+ cSouthWest.setFromVector3(box.min).as(crs, cSouthWest).toVector3(box.min);
839
+ cNorthEast.crs = crs;
840
+ cNorthEast.setFromVector3(box.max).as(crs, cNorthEast).toVector3(box.max);
841
+ }
842
+
755
843
  return new Extent(crs, {
756
844
  west: box.min.x,
757
845
  east: box.max.x,
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+
5
+ var _typeof = require("@babel/runtime/helpers/typeof");
6
+
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ exports["default"] = void 0;
11
+
12
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
13
+
14
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
15
+
16
+ var THREE = _interopRequireWildcard(require("three"));
17
+
18
+ var _Coordinates = _interopRequireDefault(require("./Coordinates"));
19
+
20
+ var _Crs = _interopRequireDefault(require("./Crs"));
21
+
22
+ function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
23
+
24
+ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
25
+
26
+ var coord = new _Coordinates["default"]('EPSG:4326');
27
+ var indexes = new THREE.Vector2();
28
+
29
+ function biLinearInterpolation(indexes, getData) {
30
+ var j = Math.floor(indexes.x);
31
+ var i = Math.floor(indexes.y);
32
+ var u = indexes.x - j;
33
+ var v = indexes.y - i;
34
+ return (1 - u) * ((1 - v) * getData(i, j) + v * getData(i + 1, j)) + u * ((1 - v) * getData(i, j + 1) + v * getData(i + 1, j + 1));
35
+ }
36
+ /**
37
+ * An instance of `GeoidGrid` allows accessing some geoid height grid data from geographic instances (like some
38
+ * `{@link Coordinates}`). The geoid height grid data must contain geoid height values for a set of geographic points
39
+ * regularly dispatched on a planar surface.
40
+ *
41
+ * @property {Extent} extent The geographic extent of the geoid height grid data.
42
+ * @property {THREE.Vector2} step The distance between two consecutive points of the geoid height grid. The
43
+ * `x` value stands for the distance along the West-East direction, and the
44
+ * `y` value stands for the distance along the South-North direction.
45
+ * @property {THREE.Vector2} dimensions The planar dimensions of the geoid height grid data extent.
46
+ * @property {THREE.Vector2} dataSize The number of values in the gridded data along the West-East direction (`x`
47
+ * axis) and the South-North direction (`y` axis).
48
+ *
49
+ * @example
50
+ * // Create a set of gridded data.
51
+ * const data = [
52
+ * [1, 2, 3],
53
+ * [2, 3, 4],
54
+ * [3, 4, 5],
55
+ * ];
56
+ * // This set of data presents the following spatial distribution of geoid heights values :
57
+ * //
58
+ * // Latitudes ^
59
+ * // |
60
+ * // 41.0 | 3 4 5
61
+ * // 40.5 | 2 3 4
62
+ * // 40.0 | 1 2 3
63
+ * // |------------->
64
+ * // 1 2 3 Longitudes
65
+ *
66
+ * // Create a GeoidGrid allowing to access the gridded data.
67
+ * const geoidGrid = new GeoidGrid(
68
+ * new Extent('EPSG:4326', 1, 3, 40, 41),
69
+ * new THREE.Vector2(1, 0.5),
70
+ * (verticalIndex, horizontalIndex) => data[verticalIndex][horizontalIndex],
71
+ * );
72
+ *
73
+ * // Access a value of geoid height at some geographic coordinates.
74
+ * // The value is interpolated from the gridded data.
75
+ * const value = geoidGrid.getHeightAtCoordinates(
76
+ * new Coordinates('EPSG:4326', 1.5, 40.25)
77
+ * );
78
+ * // This should return 2.0, which is the result from the bi-linear
79
+ * // interpolation at the center of the `[[1, 2], [2, 3]]` subsection
80
+ * // of the grid data.
81
+ */
82
+
83
+
84
+ var GeoidGrid = /*#__PURE__*/function () {
85
+ /**
86
+ * @param {Extent} extent The geographic extent of the geoid height grid data.
87
+ * @param {THREE.Vector2} step The distance between two consecutive points of the geoid height grid. The
88
+ * `x` value stands for the distance along the West-East direction, and the
89
+ * `y` value stands for the distance along the South-North direction.
90
+ * @param {function} getData A method that allows reading a value in the geoid height grid from its
91
+ * vertical and horizontal indexes. The lower an index, the lower the
92
+ * coordinate on the corresponding axis - 0 being the index of the minimal
93
+ * coordinate of the gridded data on a given axis. In other words :
94
+ * - `getData(0, 0)` must return the geoid height value at the SOUTH-WEST
95
+ * corner of your data extent.
96
+ * - `getData(0, j)` must return a geoid height on the southern limit of your
97
+ * data extent.
98
+ * - `getData(i, 0)` must return a geoid height on the western limit of your
99
+ * data extent.
100
+ * - if your gridded data has dimensions (rowNumber, colNumber),
101
+ * `getData(rowNumber - 1, colNumber - 1)` must return the geoid height at
102
+ * the NORTH-EAST corner of your data extent.
103
+ */
104
+ function GeoidGrid(extent, step, getData) {
105
+ (0, _classCallCheck2["default"])(this, GeoidGrid);
106
+
107
+ _Crs["default"].isGeographic(extent.crs);
108
+
109
+ this.extent = extent;
110
+ this.step = new THREE.Vector2(step.x, step.y || step.x);
111
+ this.dimensions = this.extent.planarDimensions();
112
+ this.dataSize = new THREE.Vector2().addVectors(this.step, this.dimensions).divide(this.step).round();
113
+ this.getData = getData;
114
+ }
115
+ /**
116
+ * Get the value of the geoid height at given geographic `{@link Coordinates}`. The geoid height value is
117
+ * bi-linearly interpolated from the gridded data accessed by the `GeoidGrid` instance.
118
+ *
119
+ * @param {Coordinates} coordinates Geographic coordinates to get the geoid height value at.
120
+ *
121
+ * @returns {number} The geoid height value at the given `{@link Coordinates}`, bi-interpolated from the gridded
122
+ * data accessed by the `GeoidGrid` instance.
123
+ */
124
+
125
+
126
+ (0, _createClass2["default"])(GeoidGrid, [{
127
+ key: "getHeightAtCoordinates",
128
+ value: function getHeightAtCoordinates(coordinates) {
129
+ coordinates.as(this.extent.crs, coord);
130
+ indexes.set((this.dataSize.x - 1) * (coord.x - this.extent.west) / this.dimensions.x, (this.dataSize.y - 1) * (coord.y - this.extent.south) / this.dimensions.y); // TODO : add management for global GeoidGrid.
131
+
132
+ if (indexes.x < 0 || indexes.x >= this.dataSize.x - 1 || indexes.y < 0 || indexes.y >= this.dataSize.y - 1) {
133
+ return 0;
134
+ }
135
+
136
+ return biLinearInterpolation(indexes, this.getData);
137
+ }
138
+ }]);
139
+ return GeoidGrid;
140
+ }();
141
+
142
+ var _default = GeoidGrid;
143
+ exports["default"] = _default;
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports["default"] = exports.MAIN_LOOP_EVENTS = exports.RENDERING_SCHEDULED = exports.RENDERING_PAUSED = void 0;
6
+ exports["default"] = exports.RENDERING_SCHEDULED = exports.RENDERING_PAUSED = exports.MAIN_LOOP_EVENTS = void 0;
7
7
 
8
8
  var _three = require("three");
9
9