@itowns/geographic 2.46.1-next.52 → 2.46.1-next.54

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.
@@ -65,6 +65,7 @@ declare class Coordinates {
65
65
  /**
66
66
  * Sets the Coordinate Reference System.
67
67
  * @param crs - Coordinate Reference System (e.g. 'EPSG:4978')
68
+ * @returns
68
69
  */
69
70
  setCrs(crs: ProjectionLike): this;
70
71
  /**
@@ -73,6 +74,7 @@ declare class Coordinates {
73
74
  * @param x - x or longitude value.
74
75
  * @param y - y or latitude value.
75
76
  * @param z - z or altitude value.
77
+ * @returns
76
78
  */
77
79
  setFromValues(x?: number, y?: number, z?: number): this;
78
80
  /**
@@ -83,6 +85,7 @@ declare class Coordinates {
83
85
  *
84
86
  * @param array - The source array.
85
87
  * @param offset - Optional offset into the array. Default is 0.
88
+ * @returns
86
89
  */
87
90
  setFromArray(array: number[], offset?: number): this;
88
91
  /**
@@ -91,11 +94,13 @@ declare class Coordinates {
91
94
  * properties.
92
95
  *
93
96
  * @param v - The source object.
97
+ * @returns
94
98
  */
95
99
  setFromVector3(v: Vector3Like): this;
96
100
  /**
97
101
  * Returns a new coordinate with the same `(x, y, z)` vector and crs as this
98
102
  * one.
103
+ * @returns
99
104
  */
100
105
  clone(): Coordinates;
101
106
  /**
@@ -103,6 +108,7 @@ declare class Coordinates {
103
108
  * to this coordinate.
104
109
  *
105
110
  * @param src - The source coordinate to copy from.
111
+ * @returns
106
112
  */
107
113
  copy(src: CoordinatesLike): this;
108
114
  get longitude(): number;
@@ -111,6 +117,7 @@ declare class Coordinates {
111
117
  set altitude(value: number);
112
118
  /**
113
119
  * The geodesic normal of the coordinate.
120
+ * @returns
114
121
  */
115
122
  get geodesicNormal(): Vector3;
116
123
  /**
@@ -138,12 +145,16 @@ declare class Coordinates {
138
145
  * Computes the planar distance from this coordinates to `coord`.
139
146
  * **Planar distance** is the straight-line euclidean distance calculated in
140
147
  * a 2D cartesian coordinate system.
148
+ * @param coord
149
+ * @returns
141
150
  */
142
151
  planarDistanceTo(coord: Coordinates): number;
143
152
  /**
144
153
  * Computes the geodetic distance from this coordinates to `coord`.
145
154
  * **Geodetic distance** is calculated in an ellipsoid space as the shortest
146
155
  * distance across the curved surface of the ellipsoid.
156
+ * @param coord
157
+ * @returns
147
158
  */
148
159
  geodeticDistanceTo(coord: Coordinates): number;
149
160
  /**
@@ -159,6 +170,7 @@ declare class Coordinates {
159
170
  * by `mat`, and divides by perspective.
160
171
  *
161
172
  * @param mat - The matrix.
173
+ * @returns
162
174
  */
163
175
  applyMatrix4(mat: Matrix4): this;
164
176
  /**
@@ -93,6 +93,7 @@ class Coordinates {
93
93
  /**
94
94
  * Sets the Coordinate Reference System.
95
95
  * @param crs - Coordinate Reference System (e.g. 'EPSG:4978')
96
+ * @returns
96
97
  */
97
98
  setCrs(crs) {
98
99
  CRS.isValid(crs);
@@ -106,6 +107,7 @@ class Coordinates {
106
107
  * @param x - x or longitude value.
107
108
  * @param y - y or latitude value.
108
109
  * @param z - z or altitude value.
110
+ * @returns
109
111
  */
110
112
  setFromValues(x = 0, y = 0, z = 0) {
111
113
  this.x = x;
@@ -123,6 +125,7 @@ class Coordinates {
123
125
  *
124
126
  * @param array - The source array.
125
127
  * @param offset - Optional offset into the array. Default is 0.
128
+ * @returns
126
129
  */
127
130
  setFromArray(array, offset = 0) {
128
131
  return this.setFromValues(array[offset], array[offset + 1], array[offset + 2]);
@@ -134,6 +137,7 @@ class Coordinates {
134
137
  * properties.
135
138
  *
136
139
  * @param v - The source object.
140
+ * @returns
137
141
  */
138
142
  setFromVector3(v) {
139
143
  return this.setFromValues(v.x, v.y, v.z);
@@ -142,6 +146,7 @@ class Coordinates {
142
146
  /**
143
147
  * Returns a new coordinate with the same `(x, y, z)` vector and crs as this
144
148
  * one.
149
+ * @returns
145
150
  */
146
151
  clone() {
147
152
  return new Coordinates(this.crs, this.x, this.y, this.z);
@@ -152,6 +157,7 @@ class Coordinates {
152
157
  * to this coordinate.
153
158
  *
154
159
  * @param src - The source coordinate to copy from.
160
+ * @returns
155
161
  */
156
162
  copy(src) {
157
163
  this.crs = src.crs;
@@ -172,6 +178,7 @@ class Coordinates {
172
178
 
173
179
  /**
174
180
  * The geodesic normal of the coordinate.
181
+ * @returns
175
182
  */
176
183
  get geodesicNormal() {
177
184
  if (this._normalNeedsUpdate) {
@@ -218,6 +225,8 @@ class Coordinates {
218
225
  * Computes the planar distance from this coordinates to `coord`.
219
226
  * **Planar distance** is the straight-line euclidean distance calculated in
220
227
  * a 2D cartesian coordinate system.
228
+ * @param coord
229
+ * @returns
221
230
  */
222
231
  planarDistanceTo(coord) {
223
232
  this.toVector3(v0).setZ(0);
@@ -229,6 +238,8 @@ class Coordinates {
229
238
  * Computes the geodetic distance from this coordinates to `coord`.
230
239
  * **Geodetic distance** is calculated in an ellipsoid space as the shortest
231
240
  * distance across the curved surface of the ellipsoid.
241
+ * @param coord
242
+ * @returns
232
243
  */
233
244
  geodeticDistanceTo(coord) {
234
245
  this.as('EPSG:4326', coord0);
@@ -254,6 +265,7 @@ class Coordinates {
254
265
  * by `mat`, and divides by perspective.
255
266
  *
256
267
  * @param mat - The matrix.
268
+ * @returns
257
269
  */
258
270
  applyMatrix4(mat) {
259
271
  Vector3.prototype.applyMatrix4.call(this, mat);
package/lib/Crs.d.ts CHANGED
@@ -31,6 +31,7 @@ export declare const UNIT: {
31
31
  * @internal
32
32
  *
33
33
  * @param crs - The CRS to test.
34
+ * @returns
34
35
  */
35
36
  export declare function is4326(crs: ProjectionLike): crs is "EPSG:4326";
36
37
  /**
@@ -44,14 +45,16 @@ export declare function getUnit(crs: ProjectionLike): 1 | 2 | 3 | undefined;
44
45
  * Asserts that the CRS is using metric units.
45
46
  *
46
47
  * @param crs - The CRS to check.
47
- * @throws {@link Error} if the CRS is not valid.
48
+ * @returns
49
+ * @throws {Error} if the CRS is not valid.
48
50
  */
49
51
  export declare function isMetricUnit(crs: ProjectionLike): boolean;
50
52
  /**
51
53
  * Asserts that the CRS is geographic.
52
54
  *
53
55
  * @param crs - The CRS to check.
54
- * @throws {@link Error} if the CRS is not valid.
56
+ * @returns
57
+ * @throws {Error} if the CRS is not valid.
55
58
  */
56
59
  export declare function isGeographic(crs: ProjectionLike): boolean;
57
60
  /**
@@ -66,7 +69,7 @@ export declare function isGeocentric(crs: ProjectionLike): boolean;
66
69
  * includes an unit.
67
70
  *
68
71
  * @param crs - The CRS to test.
69
- * @throws {@link Error} if the crs is not valid.
72
+ * @throws {Error} if the crs is not valid.
70
73
  */
71
74
  export declare function isValid(crs: ProjectionLike): void;
72
75
  /**
package/lib/Crs.js CHANGED
@@ -58,6 +58,7 @@ export const UNIT = {
58
58
  * @internal
59
59
  *
60
60
  * @param crs - The CRS to test.
61
+ * @returns
61
62
  */
62
63
  export function is4326(crs) {
63
64
  return crs === 'EPSG:4326';
@@ -97,7 +98,8 @@ export function getUnit(crs) {
97
98
  * Asserts that the CRS is using metric units.
98
99
  *
99
100
  * @param crs - The CRS to check.
100
- * @throws {@link Error} if the CRS is not valid.
101
+ * @returns
102
+ * @throws {Error} if the CRS is not valid.
101
103
  */
102
104
  export function isMetricUnit(crs) {
103
105
  return getUnit(crs) === UNIT.METER;
@@ -107,7 +109,8 @@ export function isMetricUnit(crs) {
107
109
  * Asserts that the CRS is geographic.
108
110
  *
109
111
  * @param crs - The CRS to check.
110
- * @throws {@link Error} if the CRS is not valid.
112
+ * @returns
113
+ * @throws {Error} if the CRS is not valid.
111
114
  */
112
115
  export function isGeographic(crs) {
113
116
  return getUnit(crs) === UNIT.DEGREE;
@@ -130,7 +133,7 @@ export function isGeocentric(crs) {
130
133
  * includes an unit.
131
134
  *
132
135
  * @param crs - The CRS to test.
133
- * @throws {@link Error} if the crs is not valid.
136
+ * @throws {Error} if the crs is not valid.
134
137
  */
135
138
  export function isValid(crs) {
136
139
  const proj = proj4.defs(crs);
@@ -28,6 +28,7 @@ declare class Ellipsoid {
28
28
  * @param cartesian - The given cartesian coordinate.
29
29
  * @param target - An object to store this vector to. If this is not
30
30
  * specified, a new vector will be created.
31
+ * @returns
31
32
  */
32
33
  geodeticSurfaceNormal(cartesian: Coordinates, target?: Vector3): Vector3;
33
34
  /**
@@ -37,6 +38,7 @@ declare class Ellipsoid {
37
38
  * @param coordCarto - The given geographic coordinate.
38
39
  * @param target - An object to store this vector to. If this is not
39
40
  * specified, a new vector will be created.
41
+ * @returns
40
42
  */
41
43
  geodeticSurfaceNormalCartographic(coordCarto: Coordinates, target?: Vector3): Vector3;
42
44
  /**
@@ -45,6 +47,7 @@ declare class Ellipsoid {
45
47
  * properties.
46
48
  *
47
49
  * @param size - The source vector.
50
+ * @returns
48
51
  */
49
52
  setSize(size: Vector3Like): this;
50
53
  cartographicToCartesian(coordCarto: Coordinates, target?: Vector3): Vector3;
package/lib/Ellipsoid.js CHANGED
@@ -36,6 +36,7 @@ class Ellipsoid {
36
36
  * @param cartesian - The given cartesian coordinate.
37
37
  * @param target - An object to store this vector to. If this is not
38
38
  * specified, a new vector will be created.
39
+ * @returns
39
40
  */
40
41
  geodeticSurfaceNormal(cartesian, target = new Vector3()) {
41
42
  return cartesian.toVector3(target).multiply(this._invRadiiSquared).normalize();
@@ -48,6 +49,7 @@ class Ellipsoid {
48
49
  * @param coordCarto - The given geographic coordinate.
49
50
  * @param target - An object to store this vector to. If this is not
50
51
  * specified, a new vector will be created.
52
+ * @returns
51
53
  */
52
54
  geodeticSurfaceNormalCartographic(coordCarto, target = new Vector3()) {
53
55
  const longitude = MathUtils.degToRad(coordCarto.longitude);
@@ -62,6 +64,7 @@ class Ellipsoid {
62
64
  * properties.
63
65
  *
64
66
  * @param size - The source vector.
67
+ * @returns
65
68
  */
66
69
  setSize(size) {
67
70
  this.size.set(size.x, size.y, size.z);
@@ -134,7 +137,7 @@ class Ellipsoid {
134
137
  // both intersections are behind the ray origin
135
138
  return false;
136
139
  }
137
- let t = 0;
140
+ let t;
138
141
  if (t1 <= EPSILON) {
139
142
  t = t2;
140
143
  } else if (t2 <= EPSILON) {
package/lib/Extent.d.ts CHANGED
@@ -51,6 +51,7 @@ declare class Extent {
51
51
  constructor(crs: ProjectionLike, west?: number, east?: number, south?: number, north?: number);
52
52
  /**
53
53
  * Returns a new extent with the same bounds and crs as this one.
54
+ * @returns
54
55
  */
55
56
  clone(): Extent;
56
57
  /**
@@ -59,6 +60,7 @@ declare class Extent {
59
60
  * @param crs - target's projection.
60
61
  * @param target - The target to store the projected extent. If this not
61
62
  * provided a new extent will be created.
63
+ * @returns
62
64
  */
63
65
  as(crs: string, target?: Extent): Extent;
64
66
  /**
@@ -66,6 +68,7 @@ declare class Extent {
66
68
  *
67
69
  * @param target - The target to store the center coordinate. If this not
68
70
  * provided a new coordinate will be created.
71
+ * @returns
69
72
  */
70
73
  center(target?: Coordinates): Coordinates;
71
74
  /**
@@ -75,6 +78,7 @@ declare class Extent {
75
78
  * 2D Cartesian coordinate system.
76
79
  *
77
80
  * @param target - optional target
81
+ * @returns
78
82
  */
79
83
  planarDimensions(target?: Vector2): Vector2;
80
84
  /**
@@ -84,6 +88,7 @@ declare class Extent {
84
88
  * across the curved surface of the ellipsoid.
85
89
  *
86
90
  * @param target - optional target
91
+ * @returns
87
92
  */
88
93
  geodeticDimensions(target?: Vector2): Vector2;
89
94
  /**
@@ -92,6 +97,7 @@ declare class Extent {
92
97
  * Spatial euclidean distance chord is calculated in an ellispoid space.
93
98
  *
94
99
  * @param target - optional target
100
+ * @returns
95
101
  */
96
102
  spatialEuclideanDimensions(target?: Vector2): Vector2;
97
103
  /**
@@ -100,6 +106,7 @@ declare class Extent {
100
106
  * @param coord - the given coordinates.
101
107
  * @param epsilon - error margin when comparing to the coordinates.
102
108
  * Default is 0.
109
+ * @returns
103
110
  */
104
111
  isPointInside(coord: Coordinates, epsilon?: number): boolean;
105
112
  /**
@@ -107,6 +114,7 @@ declare class Extent {
107
114
  *
108
115
  * @param extent - the extent to check
109
116
  * @param epsilon - error margin when comparing the extent bounds.
117
+ * @returns
110
118
  */
111
119
  isInside(extent: Extent, epsilon?: number): boolean;
112
120
  /**
@@ -125,14 +133,41 @@ declare class Extent {
125
133
  * Checks wheter this bounding box intersects with the given extent
126
134
  * parameter.
127
135
  * @param extent - the provided extent
136
+ * @returns
128
137
  */
129
138
  intersectsExtent(extent: Extent): boolean;
139
+ /**
140
+ * Tests whether two extents intersect.
141
+ *
142
+ * This method checks if the geographic extents `extentA` and `extentB`
143
+ * overlap. If their coordinate reference systems (CRS) differ, `extentB`
144
+ * is reprojected into the CRS of `extentA` before performing the test.
145
+ *
146
+ * Extents that touch at an edge or a corner aren't treated as intersecting.
147
+ *
148
+ * @param extentA - The reference extent.
149
+ * @param extentB - The extent to test against.
150
+ *
151
+ * @returns `true` if the extents intersect, `false` otherwise.
152
+ */
130
153
  static intersectsExtent(extentA: Extent, extentB: Extent): boolean;
131
154
  /**
132
155
  * Returns the intersection of this extent with another one.
133
- * @param extent - extent to intersect
156
+ *
157
+ * This method computes the overlapping region between this extent and
158
+ * another extent. If their coordinate reference systems (CRS) differ,
159
+ * the other extent is reprojected into the CRS of this extent before
160
+ * performing the intersection.
161
+ *
162
+ *
163
+ * @param extent - The extent to intersect with this one.
164
+ * @param target - The target extent to store the result. If not provided,
165
+ * a new extent will be created.
166
+ *
167
+ * @returns The intersection extent
168
+ * (may be empty if extents do not intersect).
134
169
  */
135
- intersect(extent: Extent): Extent;
170
+ intersect(extent: Extent, target?: Extent): Extent;
136
171
  /**
137
172
  * Set west, east, south and north values.
138
173
  *
@@ -140,6 +175,7 @@ declare class Extent {
140
175
  * @param v1 - the `east` value of this extent. Default is 0.
141
176
  * @param v2 - the `south` value of this extent. Default is 0.
142
177
  * @param v3 - the `north` value of this extent. Default is 0.
178
+ * @returns
143
179
  */
144
180
  set(v0: number, v1: number, v2: number, v3: number): this;
145
181
  /**
@@ -148,24 +184,28 @@ declare class Extent {
148
184
  * `north` property to `array[offset + 3]`.
149
185
  * @param array - the source array
150
186
  * @param offset - offset into the array. Default is 0.
187
+ * @returns
151
188
  */
152
189
  setFromArray(array: ArrayLike<number>, offset?: number): this;
153
190
  /**
154
191
  * Sets this extent `west`, `east`, `south` and `north` properties from an
155
192
  * `extent` bounds.
156
193
  * @param extent - the source extent
194
+ * @returns
157
195
  */
158
196
  setFromExtent(extent: ExtentLike): this;
159
197
  /**
160
198
  * Copies the passed extent to this extent.
161
199
  * @param extent - extent to copy.
200
+ * @returns
162
201
  */
163
202
  copy(extent: Extent): this;
164
203
  /**
165
204
  * Union this extent with the input extent.
166
205
  * @param extent - the extent to union.
206
+ * @returns
167
207
  */
168
- union(extent: Extent): void;
208
+ union(extent: Extent): this;
169
209
  /**
170
210
  * expandByCoordinates perfoms the minimal extension
171
211
  * for the coordinates to belong to this Extent object
@@ -173,12 +213,11 @@ declare class Extent {
173
213
  */
174
214
  expandByCoordinates(coordinates: Coordinates): void;
175
215
  /**
176
- * expandByValuesCoordinates perfoms the minimal extension
177
- * for the coordinates values to belong to this Extent object
178
- * @param we - The coordinate on west-east
179
- * @param sn - The coordinate on south-north
180
- *
181
- */
216
+ * expandByValuesCoordinates perfoms the minimal extension
217
+ * for the coordinates values to belong to this Extent object
218
+ * @param we - The coordinate on west-east
219
+ * @param sn - The coordinate on south-north
220
+ */
182
221
  expandByValuesCoordinates(we: number, sn: number): void;
183
222
  /**
184
223
  * Instance Extent with THREE.Box3.
@@ -189,11 +228,13 @@ declare class Extent {
189
228
  *
190
229
  * @param crs - Projection of extent to instancied.
191
230
  * @param box - Bounding-box
231
+ * @returns
192
232
  */
193
233
  static fromBox3(crs: ProjectionLike, box: Box3): Extent;
194
234
  /**
195
235
  * Return values of extent in string, separated by the separator input.
196
236
  * @param sep - string separator
237
+ * @returns
197
238
  */
198
239
  toString(sep?: string): string;
199
240
  /**
package/lib/Extent.js CHANGED
@@ -69,6 +69,7 @@ class Extent {
69
69
 
70
70
  /**
71
71
  * Returns a new extent with the same bounds and crs as this one.
72
+ * @returns
72
73
  */
73
74
  clone() {
74
75
  return new Extent(this.crs, this.west, this.east, this.south, this.north);
@@ -80,6 +81,7 @@ class Extent {
80
81
  * @param crs - target's projection.
81
82
  * @param target - The target to store the projected extent. If this not
82
83
  * provided a new extent will be created.
84
+ * @returns
83
85
  */
84
86
  as(crs, target = new Extent('EPSG:4326')) {
85
87
  CRS.isValid(crs);
@@ -120,6 +122,7 @@ class Extent {
120
122
  *
121
123
  * @param target - The target to store the center coordinate. If this not
122
124
  * provided a new coordinate will be created.
125
+ * @returns
123
126
  */
124
127
  center(target = new Coordinates(this.crs)) {
125
128
  this.planarDimensions(_dim);
@@ -135,6 +138,7 @@ class Extent {
135
138
  * 2D Cartesian coordinate system.
136
139
  *
137
140
  * @param target - optional target
141
+ * @returns
138
142
  */
139
143
  planarDimensions(target = new Vector2()) {
140
144
  // Calculte the dimensions for x and y
@@ -148,6 +152,7 @@ class Extent {
148
152
  * across the curved surface of the ellipsoid.
149
153
  *
150
154
  * @param target - optional target
155
+ * @returns
151
156
  */
152
157
  geodeticDimensions(target = new Vector2()) {
153
158
  // set 3 corners extent
@@ -168,6 +173,7 @@ class Extent {
168
173
  * Spatial euclidean distance chord is calculated in an ellispoid space.
169
174
  *
170
175
  * @param target - optional target
176
+ * @returns
171
177
  */
172
178
  spatialEuclideanDimensions(target = new Vector2()) {
173
179
  // set 3 corners extent
@@ -188,6 +194,7 @@ class Extent {
188
194
  * @param coord - the given coordinates.
189
195
  * @param epsilon - error margin when comparing to the coordinates.
190
196
  * Default is 0.
197
+ * @returns
191
198
  */
192
199
  isPointInside(coord, epsilon = 0) {
193
200
  if (this.crs == coord.crs) {
@@ -205,6 +212,7 @@ class Extent {
205
212
  *
206
213
  * @param extent - the extent to check
207
214
  * @param epsilon - error margin when comparing the extent bounds.
215
+ * @returns
208
216
  */
209
217
  isInside(extent, epsilon = CRS.reasonableEpsilon(this.crs)) {
210
218
  extent.as(this.crs, _extent);
@@ -239,28 +247,55 @@ class Extent {
239
247
  * Checks wheter this bounding box intersects with the given extent
240
248
  * parameter.
241
249
  * @param extent - the provided extent
250
+ * @returns
242
251
  */
243
252
  intersectsExtent(extent) {
244
253
  return Extent.intersectsExtent(this, extent);
245
254
  }
255
+
256
+ /**
257
+ * Tests whether two extents intersect.
258
+ *
259
+ * This method checks if the geographic extents `extentA` and `extentB`
260
+ * overlap. If their coordinate reference systems (CRS) differ, `extentB`
261
+ * is reprojected into the CRS of `extentA` before performing the test.
262
+ *
263
+ * Extents that touch at an edge or a corner aren't treated as intersecting.
264
+ *
265
+ * @param extentA - The reference extent.
266
+ * @param extentB - The extent to test against.
267
+ *
268
+ * @returns `true` if the extents intersect, `false` otherwise.
269
+ */
246
270
  static intersectsExtent(extentA, extentB) {
247
- // TODO don't work when is on limit
248
271
  const other = extentB.crs == extentA.crs ? extentB : extentB.as(extentA.crs, _extent);
249
272
  return !(extentA.west >= other.east || extentA.east <= other.west || extentA.south >= other.north || extentA.north <= other.south);
250
273
  }
251
274
 
252
275
  /**
253
276
  * Returns the intersection of this extent with another one.
254
- * @param extent - extent to intersect
277
+ *
278
+ * This method computes the overlapping region between this extent and
279
+ * another extent. If their coordinate reference systems (CRS) differ,
280
+ * the other extent is reprojected into the CRS of this extent before
281
+ * performing the intersection.
282
+ *
283
+ *
284
+ * @param extent - The extent to intersect with this one.
285
+ * @param target - The target extent to store the result. If not provided,
286
+ * a new extent will be created.
287
+ *
288
+ * @returns The intersection extent
289
+ * (may be empty if extents do not intersect).
255
290
  */
256
- intersect(extent) {
291
+ intersect(extent, target = new Extent(this.crs)) {
257
292
  if (!this.intersectsExtent(extent)) {
258
- return new Extent(this.crs);
293
+ return target;
259
294
  }
260
295
  if (extent.crs != this.crs) {
261
296
  extent = extent.as(this.crs, _extent);
262
297
  }
263
- return new Extent(this.crs, Math.max(this.west, extent.west), Math.min(this.east, extent.east), Math.max(this.south, extent.south), Math.min(this.north, extent.north));
298
+ return target.set(Math.max(this.west, extent.west), Math.min(this.east, extent.east), Math.max(this.south, extent.south), Math.min(this.north, extent.north));
264
299
  }
265
300
 
266
301
  /**
@@ -270,6 +305,7 @@ class Extent {
270
305
  * @param v1 - the `east` value of this extent. Default is 0.
271
306
  * @param v2 - the `south` value of this extent. Default is 0.
272
307
  * @param v3 - the `north` value of this extent. Default is 0.
308
+ * @returns
273
309
  */
274
310
  set(v0, v1, v2, v3) {
275
311
  if (v0 == undefined) {
@@ -301,6 +337,7 @@ class Extent {
301
337
  * `north` property to `array[offset + 3]`.
302
338
  * @param array - the source array
303
339
  * @param offset - offset into the array. Default is 0.
340
+ * @returns
304
341
  */
305
342
  setFromArray(array, offset = 0) {
306
343
  this.west = array[offset];
@@ -314,6 +351,7 @@ class Extent {
314
351
  * Sets this extent `west`, `east`, `south` and `north` properties from an
315
352
  * `extent` bounds.
316
353
  * @param extent - the source extent
354
+ * @returns
317
355
  */
318
356
  setFromExtent(extent) {
319
357
  this.west = extent.west;
@@ -326,6 +364,7 @@ class Extent {
326
364
  /**
327
365
  * Copies the passed extent to this extent.
328
366
  * @param extent - extent to copy.
367
+ * @returns
329
368
  */
330
369
  copy(extent) {
331
370
  this.crs = extent.crs;
@@ -335,6 +374,7 @@ class Extent {
335
374
  /**
336
375
  * Union this extent with the input extent.
337
376
  * @param extent - the extent to union.
377
+ * @returns
338
378
  */
339
379
  union(extent) {
340
380
  if (extent.crs != this.crs) {
@@ -360,6 +400,7 @@ class Extent {
360
400
  this.north = north;
361
401
  }
362
402
  }
403
+ return this;
363
404
  }
364
405
 
365
406
  /**
@@ -373,12 +414,11 @@ class Extent {
373
414
  }
374
415
 
375
416
  /**
376
- * expandByValuesCoordinates perfoms the minimal extension
377
- * for the coordinates values to belong to this Extent object
378
- * @param we - The coordinate on west-east
379
- * @param sn - The coordinate on south-north
380
- *
381
- */
417
+ * expandByValuesCoordinates perfoms the minimal extension
418
+ * for the coordinates values to belong to this Extent object
419
+ * @param we - The coordinate on west-east
420
+ * @param sn - The coordinate on south-north
421
+ */
382
422
  expandByValuesCoordinates(we, sn) {
383
423
  if (we < this.west) {
384
424
  this.west = we;
@@ -403,6 +443,7 @@ class Extent {
403
443
  *
404
444
  * @param crs - Projection of extent to instancied.
405
445
  * @param box - Bounding-box
446
+ * @returns
406
447
  */
407
448
  static fromBox3(crs, box) {
408
449
  if (CRS.isGeocentric(crs)) {
@@ -425,6 +466,7 @@ class Extent {
425
466
  /**
426
467
  * Return values of extent in string, separated by the separator input.
427
468
  * @param sep - string separator
469
+ * @returns
428
470
  */
429
471
  toString(sep = '') {
430
472
  return `${this.east}${sep}${this.north}${sep}${this.west}${sep}${this.south}`;
@@ -20,16 +20,16 @@ interface PhotogrammetryAngles {
20
20
  type Attitude = Partial<EulerAngles> | Partial<PhotogrammetryAngles>;
21
21
  type QuaternionFunction = (coords: Coordinates, target?: Quaternion) => Quaternion;
22
22
  type ProjectionLike = ProjectionDefinition | string;
23
- type LCCProjection = {
23
+ interface LCCProjection {
24
24
  long0: number;
25
25
  lat0: number;
26
- };
27
- type TMercProjection = {
26
+ }
27
+ interface TMercProjection {
28
28
  a: number;
29
29
  b: number;
30
30
  e?: number;
31
31
  long0: number;
32
- };
32
+ }
33
33
  /**
34
34
  * The transform from the platform frame to the local East, North, Up (ENU)
35
35
  * frame is `RotationZ(heading).RotationX(pitch).RotationY(roll)`.
@@ -263,6 +263,7 @@ export function quaternionFromEnuToLongLat(coordinates, target = new Quaternion(
263
263
  * identity (0,0,0,1).
264
264
  *
265
265
  * @param proj - the unimplemented projection (may be parsed using proj4)
266
+ * @param proj.projName - the name of the projection
266
267
  * @param coordinates - the origin of the local East North Up (ENU) frame
267
268
  * @param target - output Quaternion
268
269
  * @returns The target quaternion if coordinates is defined, otherwise, a
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@itowns/geographic",
3
- "version": "2.46.1-next.52",
3
+ "version": "2.46.1-next.54",
4
4
  "description": "Proj4-based three.js geodesy toolkit",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -77,7 +77,7 @@ class Coordinates {
77
77
  * @param y - y or latitude value.
78
78
  * @param z - z or altitude value.
79
79
  */
80
- constructor(crs: ProjectionLike, x: number = 0, y: number = 0, z: number = 0) {
80
+ constructor(crs: ProjectionLike, x = 0, y = 0, z = 0) {
81
81
  this.isCoordinates = true;
82
82
 
83
83
  CRS.isValid(crs);
@@ -118,6 +118,7 @@ class Coordinates {
118
118
  /**
119
119
  * Sets the Coordinate Reference System.
120
120
  * @param crs - Coordinate Reference System (e.g. 'EPSG:4978')
121
+ * @returns
121
122
  */
122
123
  setCrs(crs: ProjectionLike): this {
123
124
  CRS.isValid(crs);
@@ -131,8 +132,9 @@ class Coordinates {
131
132
  * @param x - x or longitude value.
132
133
  * @param y - y or latitude value.
133
134
  * @param z - z or altitude value.
135
+ * @returns
134
136
  */
135
- setFromValues(x: number = 0, y: number = 0, z: number = 0): this {
137
+ setFromValues(x = 0, y = 0, z = 0): this {
136
138
  this.x = x;
137
139
  this.y = y;
138
140
  this.z = z;
@@ -149,8 +151,9 @@ class Coordinates {
149
151
  *
150
152
  * @param array - The source array.
151
153
  * @param offset - Optional offset into the array. Default is 0.
154
+ * @returns
152
155
  */
153
- setFromArray(array: number[], offset: number = 0): this {
156
+ setFromArray(array: number[], offset = 0): this {
154
157
  return this.setFromValues(
155
158
  array[offset],
156
159
  array[offset + 1],
@@ -164,6 +167,7 @@ class Coordinates {
164
167
  * properties.
165
168
  *
166
169
  * @param v - The source object.
170
+ * @returns
167
171
  */
168
172
  setFromVector3(v: Vector3Like): this {
169
173
  return this.setFromValues(v.x, v.y, v.z);
@@ -172,6 +176,7 @@ class Coordinates {
172
176
  /**
173
177
  * Returns a new coordinate with the same `(x, y, z)` vector and crs as this
174
178
  * one.
179
+ * @returns
175
180
  */
176
181
  clone(): Coordinates {
177
182
  return new Coordinates(this.crs, this.x, this.y, this.z);
@@ -182,6 +187,7 @@ class Coordinates {
182
187
  * to this coordinate.
183
188
  *
184
189
  * @param src - The source coordinate to copy from.
190
+ * @returns
185
191
  */
186
192
  copy(src: CoordinatesLike): this {
187
193
  this.crs = src.crs;
@@ -206,6 +212,7 @@ class Coordinates {
206
212
 
207
213
  /**
208
214
  * The geodesic normal of the coordinate.
215
+ * @returns
209
216
  */
210
217
  get geodesicNormal() {
211
218
  if (this._normalNeedsUpdate) {
@@ -246,7 +253,7 @@ class Coordinates {
246
253
  * @returns An array [x, y, z], or copies x, y and z into the provided
247
254
  * array.
248
255
  */
249
- toArray(array: number[] = [], offset: number = 0): ArrayLike<number> {
256
+ toArray(array: number[] = [], offset = 0): ArrayLike<number> {
250
257
  return Vector3.prototype.toArray.call(this, array, offset);
251
258
  }
252
259
 
@@ -254,6 +261,8 @@ class Coordinates {
254
261
  * Computes the planar distance from this coordinates to `coord`.
255
262
  * **Planar distance** is the straight-line euclidean distance calculated in
256
263
  * a 2D cartesian coordinate system.
264
+ * @param coord
265
+ * @returns
257
266
  */
258
267
  planarDistanceTo(coord: Coordinates): number {
259
268
  this.toVector3(v0).setZ(0);
@@ -265,6 +274,8 @@ class Coordinates {
265
274
  * Computes the geodetic distance from this coordinates to `coord`.
266
275
  * **Geodetic distance** is calculated in an ellipsoid space as the shortest
267
276
  * distance across the curved surface of the ellipsoid.
277
+ * @param coord
278
+ * @returns
268
279
  */
269
280
  geodeticDistanceTo(coord: Coordinates): number {
270
281
  this.as('EPSG:4326', coord0);
@@ -290,6 +301,7 @@ class Coordinates {
290
301
  * by `mat`, and divides by perspective.
291
302
  *
292
303
  * @param mat - The matrix.
304
+ * @returns
293
305
  */
294
306
  applyMatrix4(mat: Matrix4): this {
295
307
  Vector3.prototype.applyMatrix4.call(this, mat);
package/src/Crs.ts CHANGED
@@ -2,12 +2,12 @@ import proj4 from 'proj4';
2
2
  import type { Converter } from 'proj4';
3
3
  import type { ProjectionDefinition } from 'proj4/dist/lib/defs';
4
4
 
5
- type proj4Def = {
6
- type: string,
7
- PROJCS: proj4Def,
8
- unknown?: string,
9
- (alias: string): proj4Def & { name: string },
10
- title: string,
5
+ interface proj4Def {
6
+ type: string;
7
+ PROJCS: proj4Def;
8
+ unknown?: string;
9
+ (alias: string): proj4Def & { name: string };
10
+ title: string;
11
11
  }
12
12
 
13
13
  proj4.defs('EPSG:4978', '+proj=geocent +datum=WGS84 +units=m +no_defs');
@@ -74,6 +74,7 @@ export const UNIT = {
74
74
  * @internal
75
75
  *
76
76
  * @param crs - The CRS to test.
77
+ * @returns
77
78
  */
78
79
  export function is4326(crs: ProjectionLike) {
79
80
  return crs === 'EPSG:4326';
@@ -114,7 +115,8 @@ export function getUnit(crs: ProjectionLike) {
114
115
  * Asserts that the CRS is using metric units.
115
116
  *
116
117
  * @param crs - The CRS to check.
117
- * @throws {@link Error} if the CRS is not valid.
118
+ * @returns
119
+ * @throws {Error} if the CRS is not valid.
118
120
  */
119
121
  export function isMetricUnit(crs: ProjectionLike) {
120
122
  return getUnit(crs) === UNIT.METER;
@@ -124,7 +126,8 @@ export function isMetricUnit(crs: ProjectionLike) {
124
126
  * Asserts that the CRS is geographic.
125
127
  *
126
128
  * @param crs - The CRS to check.
127
- * @throws {@link Error} if the CRS is not valid.
129
+ * @returns
130
+ * @throws {Error} if the CRS is not valid.
128
131
  */
129
132
  export function isGeographic(crs: ProjectionLike) {
130
133
  return getUnit(crs) === UNIT.DEGREE;
@@ -147,7 +150,7 @@ export function isGeocentric(crs: ProjectionLike) {
147
150
  * includes an unit.
148
151
  *
149
152
  * @param crs - The CRS to test.
150
- * @throws {@link Error} if the crs is not valid.
153
+ * @throws {Error} if the crs is not valid.
151
154
  */
152
155
  export function isValid(crs: ProjectionLike) {
153
156
  const proj = proj4.defs(crs);
package/src/Ellipsoid.ts CHANGED
@@ -47,6 +47,7 @@ class Ellipsoid {
47
47
  * @param cartesian - The given cartesian coordinate.
48
48
  * @param target - An object to store this vector to. If this is not
49
49
  * specified, a new vector will be created.
50
+ * @returns
50
51
  */
51
52
  geodeticSurfaceNormal(
52
53
  cartesian: Coordinates,
@@ -62,6 +63,7 @@ class Ellipsoid {
62
63
  * @param coordCarto - The given geographic coordinate.
63
64
  * @param target - An object to store this vector to. If this is not
64
65
  * specified, a new vector will be created.
66
+ * @returns
65
67
  */
66
68
  geodeticSurfaceNormalCartographic(
67
69
  coordCarto: Coordinates,
@@ -82,6 +84,7 @@ class Ellipsoid {
82
84
  * properties.
83
85
  *
84
86
  * @param size - The source vector.
87
+ * @returns
85
88
  */
86
89
  setSize(size: Vector3Like): this {
87
90
  this.size.set(size.x, size.y, size.z);
@@ -146,7 +149,7 @@ class Ellipsoid {
146
149
 
147
150
  const phi = Math.atan(
148
151
  (position.z * (1 - f) + e * a * sinu * sinu * sinu) /
149
- ((1 - f) * (rsqXY - e * a * cosu * cosu * cosu)));
152
+ ((1 - f) * (rsqXY - e * a * cosu * cosu * cosu)));
150
153
 
151
154
  const h = (rsqXY * Math.cos(phi)) +
152
155
  position.z * Math.sin(phi) -
@@ -202,7 +205,7 @@ class Ellipsoid {
202
205
  return false;
203
206
  }
204
207
 
205
- let t = 0;
208
+ let t;
206
209
  if (t1 <= EPSILON) { t = t2; } else
207
210
  if (t2 <= EPSILON) { t = t1; } else { t = (t1 < t2) ? t1 : t2; }
208
211
 
@@ -236,7 +239,7 @@ class Ellipsoid {
236
239
 
237
240
  const distRad = Math.acos(
238
241
  Math.sin(latitude1) * Math.sin(latitude2) +
239
- Math.cos(latitude1) * Math.cos(latitude2) * Math.cos(longitude2 - longitude1));
242
+ Math.cos(latitude1) * Math.cos(latitude2) * Math.cos(longitude2 - longitude1));
240
243
 
241
244
  const e = this.eccentricity;
242
245
  const latMoy = (latitude1 + latitude2) * 0.5;
package/src/Extent.ts CHANGED
@@ -100,6 +100,7 @@ class Extent {
100
100
 
101
101
  /**
102
102
  * Returns a new extent with the same bounds and crs as this one.
103
+ * @returns
103
104
  */
104
105
  clone() {
105
106
  return new Extent(this.crs, this.west, this.east, this.south, this.north);
@@ -111,6 +112,7 @@ class Extent {
111
112
  * @param crs - target's projection.
112
113
  * @param target - The target to store the projected extent. If this not
113
114
  * provided a new extent will be created.
115
+ * @returns
114
116
  */
115
117
  as(crs: string, target: Extent = new Extent('EPSG:4326')) {
116
118
  CRS.isValid(crs);
@@ -155,6 +157,7 @@ class Extent {
155
157
  *
156
158
  * @param target - The target to store the center coordinate. If this not
157
159
  * provided a new coordinate will be created.
160
+ * @returns
158
161
  */
159
162
  center(target = new Coordinates(this.crs)) {
160
163
  this.planarDimensions(_dim);
@@ -172,6 +175,7 @@ class Extent {
172
175
  * 2D Cartesian coordinate system.
173
176
  *
174
177
  * @param target - optional target
178
+ * @returns
175
179
  */
176
180
  planarDimensions(target = new Vector2()) {
177
181
  // Calculte the dimensions for x and y
@@ -185,6 +189,7 @@ class Extent {
185
189
  * across the curved surface of the ellipsoid.
186
190
  *
187
191
  * @param target - optional target
192
+ * @returns
188
193
  */
189
194
  geodeticDimensions(target = new Vector2()) {
190
195
  // set 3 corners extent
@@ -209,6 +214,7 @@ class Extent {
209
214
  * Spatial euclidean distance chord is calculated in an ellispoid space.
210
215
  *
211
216
  * @param target - optional target
217
+ * @returns
212
218
  */
213
219
  spatialEuclideanDimensions(target = new Vector2()) {
214
220
  // set 3 corners extent
@@ -233,6 +239,7 @@ class Extent {
233
239
  * @param coord - the given coordinates.
234
240
  * @param epsilon - error margin when comparing to the coordinates.
235
241
  * Default is 0.
242
+ * @returns
236
243
  */
237
244
  isPointInside(coord: Coordinates, epsilon = 0) {
238
245
  if (this.crs == coord.crs) {
@@ -243,9 +250,9 @@ class Extent {
243
250
 
244
251
  // TODO this ignores altitude
245
252
  return _c.x <= this.east + epsilon &&
246
- _c.x >= this.west - epsilon &&
247
- _c.y <= this.north + epsilon &&
248
- _c.y >= this.south - epsilon;
253
+ _c.x >= this.west - epsilon &&
254
+ _c.y <= this.north + epsilon &&
255
+ _c.y >= this.south - epsilon;
249
256
  }
250
257
 
251
258
  /**
@@ -253,13 +260,14 @@ class Extent {
253
260
  *
254
261
  * @param extent - the extent to check
255
262
  * @param epsilon - error margin when comparing the extent bounds.
263
+ * @returns
256
264
  */
257
265
  isInside(extent: Extent, epsilon = CRS.reasonableEpsilon(this.crs)) {
258
266
  extent.as(this.crs, _extent);
259
267
  return this.east - _extent.east <= epsilon &&
260
- _extent.west - this.west <= epsilon &&
261
- this.north - _extent.north <= epsilon &&
262
- _extent.south - this.south <= epsilon;
268
+ _extent.west - this.west <= epsilon &&
269
+ this.north - _extent.north <= epsilon &&
270
+ _extent.south - this.south <= epsilon;
263
271
  }
264
272
 
265
273
  /**
@@ -294,13 +302,27 @@ class Extent {
294
302
  * Checks wheter this bounding box intersects with the given extent
295
303
  * parameter.
296
304
  * @param extent - the provided extent
305
+ * @returns
297
306
  */
298
307
  intersectsExtent(extent: Extent) {
299
308
  return Extent.intersectsExtent(this, extent);
300
309
  }
301
310
 
311
+ /**
312
+ * Tests whether two extents intersect.
313
+ *
314
+ * This method checks if the geographic extents `extentA` and `extentB`
315
+ * overlap. If their coordinate reference systems (CRS) differ, `extentB`
316
+ * is reprojected into the CRS of `extentA` before performing the test.
317
+ *
318
+ * Extents that touch at an edge or a corner aren't treated as intersecting.
319
+ *
320
+ * @param extentA - The reference extent.
321
+ * @param extentB - The extent to test against.
322
+ *
323
+ * @returns `true` if the extents intersect, `false` otherwise.
324
+ */
302
325
  static intersectsExtent(extentA: Extent, extentB: Extent) {
303
- // TODO don't work when is on limit
304
326
  const other = extentB.crs == extentA.crs ? extentB : extentB.as(extentA.crs, _extent);
305
327
  return !(extentA.west >= other.east ||
306
328
  extentA.east <= other.west ||
@@ -310,16 +332,29 @@ class Extent {
310
332
 
311
333
  /**
312
334
  * Returns the intersection of this extent with another one.
313
- * @param extent - extent to intersect
335
+ *
336
+ * This method computes the overlapping region between this extent and
337
+ * another extent. If their coordinate reference systems (CRS) differ,
338
+ * the other extent is reprojected into the CRS of this extent before
339
+ * performing the intersection.
340
+ *
341
+ *
342
+ * @param extent - The extent to intersect with this one.
343
+ * @param target - The target extent to store the result. If not provided,
344
+ * a new extent will be created.
345
+ *
346
+ * @returns The intersection extent
347
+ * (may be empty if extents do not intersect).
314
348
  */
315
- intersect(extent: Extent) {
349
+ intersect(extent: Extent, target = new Extent(this.crs)) {
316
350
  if (!this.intersectsExtent(extent)) {
317
- return new Extent(this.crs);
351
+ return target;
318
352
  }
319
353
  if (extent.crs != this.crs) {
320
354
  extent = extent.as(this.crs, _extent);
321
355
  }
322
- return new Extent(this.crs,
356
+
357
+ return target.set(
323
358
  Math.max(this.west, extent.west),
324
359
  Math.min(this.east, extent.east),
325
360
  Math.max(this.south, extent.south),
@@ -333,6 +368,7 @@ class Extent {
333
368
  * @param v1 - the `east` value of this extent. Default is 0.
334
369
  * @param v2 - the `south` value of this extent. Default is 0.
335
370
  * @param v3 - the `north` value of this extent. Default is 0.
371
+ * @returns
336
372
  */
337
373
  set(v0: number, v1: number, v2: number, v3: number): this {
338
374
  if (v0 == undefined) {
@@ -370,8 +406,9 @@ class Extent {
370
406
  * `north` property to `array[offset + 3]`.
371
407
  * @param array - the source array
372
408
  * @param offset - offset into the array. Default is 0.
409
+ * @returns
373
410
  */
374
- setFromArray(array: ArrayLike<number>, offset: number = 0): this {
411
+ setFromArray(array: ArrayLike<number>, offset = 0): this {
375
412
  this.west = array[offset];
376
413
  this.east = array[offset + 1];
377
414
  this.south = array[offset + 2];
@@ -383,6 +420,7 @@ class Extent {
383
420
  * Sets this extent `west`, `east`, `south` and `north` properties from an
384
421
  * `extent` bounds.
385
422
  * @param extent - the source extent
423
+ * @returns
386
424
  */
387
425
  setFromExtent(extent: ExtentLike): this {
388
426
  this.west = extent.west;
@@ -395,6 +433,7 @@ class Extent {
395
433
  /**
396
434
  * Copies the passed extent to this extent.
397
435
  * @param extent - extent to copy.
436
+ * @returns
398
437
  */
399
438
  copy(extent: Extent): this {
400
439
  this.crs = extent.crs;
@@ -404,6 +443,7 @@ class Extent {
404
443
  /**
405
444
  * Union this extent with the input extent.
406
445
  * @param extent - the extent to union.
446
+ * @returns
407
447
  */
408
448
  union(extent: Extent) {
409
449
  if (extent.crs != this.crs) {
@@ -432,6 +472,8 @@ class Extent {
432
472
  this.north = north;
433
473
  }
434
474
  }
475
+
476
+ return this;
435
477
  }
436
478
 
437
479
  /**
@@ -445,12 +487,11 @@ class Extent {
445
487
  }
446
488
 
447
489
  /**
448
- * expandByValuesCoordinates perfoms the minimal extension
449
- * for the coordinates values to belong to this Extent object
450
- * @param we - The coordinate on west-east
451
- * @param sn - The coordinate on south-north
452
- *
453
- */
490
+ * expandByValuesCoordinates perfoms the minimal extension
491
+ * for the coordinates values to belong to this Extent object
492
+ * @param we - The coordinate on west-east
493
+ * @param sn - The coordinate on south-north
494
+ */
454
495
  expandByValuesCoordinates(we: number, sn: number) {
455
496
  if (we < this.west) {
456
497
  this.west = we;
@@ -475,6 +516,7 @@ class Extent {
475
516
  *
476
517
  * @param crs - Projection of extent to instancied.
477
518
  * @param box - Bounding-box
519
+ * @returns
478
520
  */
479
521
  static fromBox3(crs: ProjectionLike, box: Box3) {
480
522
  if (CRS.isGeocentric(crs)) {
@@ -499,6 +541,7 @@ class Extent {
499
541
  /**
500
542
  * Return values of extent in string, separated by the separator input.
501
543
  * @param sep - string separator
544
+ * @returns
502
545
  */
503
546
  toString(sep = '') {
504
547
  return `${this.east}${sep}${this.north}${sep}${this.west}${sep}${this.south}`;
@@ -34,8 +34,8 @@ type QuaternionFunction = (coords: Coordinates, target?: Quaternion) => Quaterni
34
34
 
35
35
  // To unify with Crs.js ProjectionLike type ?
36
36
  type ProjectionLike = ProjectionDefinition | string;
37
- type LCCProjection = { long0: number, lat0: number };
38
- type TMercProjection = { a: number, b: number, e?: number, long0: number };
37
+ interface LCCProjection { long0: number; lat0: number }
38
+ interface TMercProjection { a: number; b: number; e?: number; long0: number }
39
39
 
40
40
  /**
41
41
  * The transform from the platform frame to the local East, North, Up (ENU)
@@ -367,6 +367,7 @@ export function quaternionUnimplemented(
367
367
  * identity (0,0,0,1).
368
368
  *
369
369
  * @param proj - the unimplemented projection (may be parsed using proj4)
370
+ * @param proj.projName - the name of the projection
370
371
  * @param coordinates - the origin of the local East North Up (ENU) frame
371
372
  * @param target - output Quaternion
372
373
  * @returns The target quaternion if coordinates is defined, otherwise, a