@itowns/geographic 2.46.1-next.5 → 2.46.1-next.51
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.
- package/lib/CoordStars.d.ts +13 -0
- package/lib/Coordinates.d.ts +196 -0
- package/lib/Coordinates.js +7 -30
- package/lib/Crs.d.ts +108 -0
- package/lib/Crs.js +61 -8
- package/lib/Ellipsoid.d.ts +74 -0
- package/lib/Ellipsoid.js +5 -10
- package/lib/Extent.d.ts +246 -0
- package/lib/Extent.js +14 -33
- package/lib/OrientationUtils.d.ts +105 -0
- package/lib/OrientationUtils.js +41 -74
- package/lib/index.d.ts +7 -0
- package/package.json +7 -7
- package/src/Coordinates.ts +1 -15
- package/src/Crs.ts +76 -9
- package/src/OrientationUtils.ts +26 -8
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
declare const CoordStars: {
|
|
2
|
+
getSunPosition(): (date: Date | number, lat: number, lon: number) => {
|
|
3
|
+
EclipticLongitude: number;
|
|
4
|
+
declinaison: number;
|
|
5
|
+
ascension: number;
|
|
6
|
+
H: number;
|
|
7
|
+
SiderealTime: number;
|
|
8
|
+
altitude: number;
|
|
9
|
+
azimuth: number;
|
|
10
|
+
};
|
|
11
|
+
getSunPositionInScene(date: Date | number, lat: number, lon: number): import("three").Vector3;
|
|
12
|
+
};
|
|
13
|
+
export default CoordStars;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { Vector3, type Vector3Like, type Matrix4 } from 'three';
|
|
2
|
+
import type { ProjectionLike } from './Crs';
|
|
3
|
+
export interface CoordinatesLike {
|
|
4
|
+
readonly crs: string;
|
|
5
|
+
readonly x: number;
|
|
6
|
+
readonly y: number;
|
|
7
|
+
readonly z: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* A class representing a geographic or geocentric coordinate.
|
|
11
|
+
*
|
|
12
|
+
* A coordinate is defined by a [CRS](http://inspire.ec.europa.eu/theme/rs)
|
|
13
|
+
* (Coordinate Reference System) and a 3-dimensional vector `(x, y, z)`.
|
|
14
|
+
* For geocentric projections, it is recommended to use the `latitude`,
|
|
15
|
+
* `longitude` and `altitude` aliases to refer to vector components.
|
|
16
|
+
*
|
|
17
|
+
* To change a value, prefer the use of the `set*` methods.
|
|
18
|
+
*
|
|
19
|
+
* By default, the `EPSG:4978` and `EPSG:4326` projections are supported. To use
|
|
20
|
+
* a different projection, it must have been declared previously with `proj4`.
|
|
21
|
+
* A comprehensive list of projections and their corresponding proj4 string can
|
|
22
|
+
* be found at [epsg.io](https://epsg.io/).
|
|
23
|
+
*
|
|
24
|
+
* @example Geocentric coordinates
|
|
25
|
+
* ```js
|
|
26
|
+
* new Coordinates('EPSG:4978', 20885167, 849862, 23385912);
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @example Geographic coordinates
|
|
30
|
+
* ```js
|
|
31
|
+
* new Coordinates('EPSG:4326', 2.33, 48.24, 24999549);
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @example Defining the EPSG:2154 projection with proj4
|
|
35
|
+
* ```js
|
|
36
|
+
* proj4.defs('EPSG:2154', `+proj=lcc +lat_0=46.5 +lon_0=3 +lat_1=49 +lat_2=44
|
|
37
|
+
* +x_0=700000 +y_0=6600000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m
|
|
38
|
+
* +no_defs +type=crs`);
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
declare class Coordinates {
|
|
42
|
+
/**
|
|
43
|
+
* Read-only flag to check if a given object is of type `Coordinates`.
|
|
44
|
+
*/
|
|
45
|
+
readonly isCoordinates: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* A default or user-defined CRS (see {@link ProjectionLike}).
|
|
48
|
+
*/
|
|
49
|
+
crs: ProjectionLike;
|
|
50
|
+
/** The x value (or longitude) of this coordinate. */
|
|
51
|
+
x: number;
|
|
52
|
+
/** The y value (or latitude) of this coordinate. */
|
|
53
|
+
y: number;
|
|
54
|
+
/** The z value (or altitude) of this coordinate. */
|
|
55
|
+
z: number;
|
|
56
|
+
private _normal;
|
|
57
|
+
private _normalNeedsUpdate;
|
|
58
|
+
/**
|
|
59
|
+
* @param crs - A default or user-defined CRS (see {@link ProjectionLike}).
|
|
60
|
+
* @param x - x or longitude value.
|
|
61
|
+
* @param y - y or latitude value.
|
|
62
|
+
* @param z - z or altitude value.
|
|
63
|
+
*/
|
|
64
|
+
constructor(crs: ProjectionLike, x?: number, y?: number, z?: number);
|
|
65
|
+
/**
|
|
66
|
+
* Sets the Coordinate Reference System.
|
|
67
|
+
* @param crs - Coordinate Reference System (e.g. 'EPSG:4978')
|
|
68
|
+
*/
|
|
69
|
+
setCrs(crs: ProjectionLike): this;
|
|
70
|
+
/**
|
|
71
|
+
* Sets the x, y and z components of this coordinate.
|
|
72
|
+
*
|
|
73
|
+
* @param x - x or longitude value.
|
|
74
|
+
* @param y - y or latitude value.
|
|
75
|
+
* @param z - z or altitude value.
|
|
76
|
+
*/
|
|
77
|
+
setFromValues(x?: number, y?: number, z?: number): this;
|
|
78
|
+
/**
|
|
79
|
+
* Sets the coordinates's {@link Coordinates#x | x} component to
|
|
80
|
+
* `array[offset + 0]`, {@link Coordinates#y | y} component to
|
|
81
|
+
* `array[offset + 1]` and {@link Coordinates#z | z} component to
|
|
82
|
+
* `array[offset + 2]`.
|
|
83
|
+
*
|
|
84
|
+
* @param array - The source array.
|
|
85
|
+
* @param offset - Optional offset into the array. Default is 0.
|
|
86
|
+
*/
|
|
87
|
+
setFromArray(array: number[], offset?: number): this;
|
|
88
|
+
/**
|
|
89
|
+
* Sets the `(x, y, z)` vector of this coordinate from a 3-dimensional
|
|
90
|
+
* vector-like object. This object shall have both `x`, `y` and `z`
|
|
91
|
+
* properties.
|
|
92
|
+
*
|
|
93
|
+
* @param v - The source object.
|
|
94
|
+
*/
|
|
95
|
+
setFromVector3(v: Vector3Like): this;
|
|
96
|
+
/**
|
|
97
|
+
* Returns a new coordinate with the same `(x, y, z)` vector and crs as this
|
|
98
|
+
* one.
|
|
99
|
+
*/
|
|
100
|
+
clone(): Coordinates;
|
|
101
|
+
/**
|
|
102
|
+
* Copies the `(x, y, z)` vector components and crs of the passed coordinate
|
|
103
|
+
* to this coordinate.
|
|
104
|
+
*
|
|
105
|
+
* @param src - The source coordinate to copy from.
|
|
106
|
+
*/
|
|
107
|
+
copy(src: CoordinatesLike): this;
|
|
108
|
+
get longitude(): number;
|
|
109
|
+
get latitude(): number;
|
|
110
|
+
get altitude(): number;
|
|
111
|
+
set altitude(value: number);
|
|
112
|
+
/**
|
|
113
|
+
* The geodesic normal of the coordinate.
|
|
114
|
+
*/
|
|
115
|
+
get geodesicNormal(): Vector3;
|
|
116
|
+
/**
|
|
117
|
+
* Copies the `x`, `y` and `z` components into the provided `THREE.Vector3`.
|
|
118
|
+
*
|
|
119
|
+
* @param target - An object to store this vector to. If this is not
|
|
120
|
+
* specified, a new vector will be created.
|
|
121
|
+
*
|
|
122
|
+
* @returns A vector `(x, y, z)`, or copies x, y and z into the provided
|
|
123
|
+
* vector.
|
|
124
|
+
*/
|
|
125
|
+
toVector3(target?: Vector3): Vector3;
|
|
126
|
+
/**
|
|
127
|
+
* Copies the `x`, `y` and `z` components into the provided array.
|
|
128
|
+
*
|
|
129
|
+
* @param array - An array to store this vector to. If this is not
|
|
130
|
+
* provided a new array will be created.
|
|
131
|
+
* @param offset - An optional offset into the array.
|
|
132
|
+
*
|
|
133
|
+
* @returns An array [x, y, z], or copies x, y and z into the provided
|
|
134
|
+
* array.
|
|
135
|
+
*/
|
|
136
|
+
toArray(array?: number[], offset?: number): ArrayLike<number>;
|
|
137
|
+
/**
|
|
138
|
+
* Computes the planar distance from this coordinates to `coord`.
|
|
139
|
+
* **Planar distance** is the straight-line euclidean distance calculated in
|
|
140
|
+
* a 2D cartesian coordinate system.
|
|
141
|
+
*/
|
|
142
|
+
planarDistanceTo(coord: Coordinates): number;
|
|
143
|
+
/**
|
|
144
|
+
* Computes the geodetic distance from this coordinates to `coord`.
|
|
145
|
+
* **Geodetic distance** is calculated in an ellipsoid space as the shortest
|
|
146
|
+
* distance across the curved surface of the ellipsoid.
|
|
147
|
+
*/
|
|
148
|
+
geodeticDistanceTo(coord: Coordinates): number;
|
|
149
|
+
/**
|
|
150
|
+
* Computes the euclidean distance from this coordinates to `coord` in a
|
|
151
|
+
* WGS84 projection.
|
|
152
|
+
*
|
|
153
|
+
* @param coord - The coordinate
|
|
154
|
+
* @returns earth euclidean distance
|
|
155
|
+
*/
|
|
156
|
+
spatialEuclideanDistanceTo(coord: Coordinates): number;
|
|
157
|
+
/**
|
|
158
|
+
* Multiplies this coordinate (with an implicit 1 in the 4th dimension)
|
|
159
|
+
* by `mat`, and divides by perspective.
|
|
160
|
+
*
|
|
161
|
+
* @param mat - The matrix.
|
|
162
|
+
*/
|
|
163
|
+
applyMatrix4(mat: Matrix4): this;
|
|
164
|
+
/**
|
|
165
|
+
* Projects this coordinate to the specified
|
|
166
|
+
* [CRS](http://inspire.ec.europa.eu/theme/rs).
|
|
167
|
+
*
|
|
168
|
+
* @param crs - The target CRS to which the coordinate will be converted.
|
|
169
|
+
* @param target - The target to store the projected coordinate. If this not
|
|
170
|
+
* provided a new coordinate will be created.
|
|
171
|
+
*
|
|
172
|
+
* @returns The coordinate projected into the specified CRS.
|
|
173
|
+
*
|
|
174
|
+
* @example Conversion from a geographic to a geocentric reference system
|
|
175
|
+
* ```js
|
|
176
|
+
* const geographicCoords = new Coordinates('EPSG:4326',
|
|
177
|
+
* 2.33, // longitude
|
|
178
|
+
* 48.24, // latitude
|
|
179
|
+
* 24999549, // altitude
|
|
180
|
+
* );
|
|
181
|
+
* const geocentricCoords = geographicCoords.as('EPSG:4978');
|
|
182
|
+
* ```
|
|
183
|
+
*
|
|
184
|
+
* @example Conversion from a geocentric to a geographic reference system
|
|
185
|
+
* ```js
|
|
186
|
+
* const geocentricCoords = new Coordinates('EPSG:4978',
|
|
187
|
+
* 20885167, // x
|
|
188
|
+
* 849862, // y
|
|
189
|
+
* 23385912, // z
|
|
190
|
+
* );
|
|
191
|
+
* const geographicCoords = geocentricCoords.as('EPSG:4326');
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
as(crs: ProjectionLike, target?: Coordinates): Coordinates;
|
|
195
|
+
}
|
|
196
|
+
export default Coordinates;
|
package/lib/Coordinates.js
CHANGED
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
import { Vector3, MathUtils } from 'three';
|
|
2
|
-
import proj4 from 'proj4';
|
|
3
2
|
import Ellipsoid from "./Ellipsoid.js";
|
|
4
3
|
import * as CRS from "./Crs.js";
|
|
5
4
|
const ellipsoid = /* @__PURE__ */new Ellipsoid();
|
|
6
|
-
const projectionCache = {};
|
|
7
5
|
const v0 = /* @__PURE__ */new Vector3();
|
|
8
6
|
const v1 = /* @__PURE__ */new Vector3();
|
|
9
7
|
let coord0;
|
|
10
8
|
let coord1;
|
|
11
|
-
function proj4cache(crsIn, crsOut) {
|
|
12
|
-
if (!projectionCache[crsIn]) {
|
|
13
|
-
projectionCache[crsIn] = {};
|
|
14
|
-
}
|
|
15
|
-
if (!projectionCache[crsIn][crsOut]) {
|
|
16
|
-
projectionCache[crsIn][crsOut] = proj4(crsIn, crsOut);
|
|
17
|
-
}
|
|
18
|
-
return projectionCache[crsIn][crsOut];
|
|
19
|
-
}
|
|
20
|
-
|
|
21
9
|
/**
|
|
22
10
|
* A class representing a geographic or geocentric coordinate.
|
|
23
11
|
*
|
|
@@ -71,10 +59,7 @@ class Coordinates {
|
|
|
71
59
|
* @param y - y or latitude value.
|
|
72
60
|
* @param z - z or altitude value.
|
|
73
61
|
*/
|
|
74
|
-
constructor(crs) {
|
|
75
|
-
let x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
76
|
-
let y = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
77
|
-
let z = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 0;
|
|
62
|
+
constructor(crs, x = 0, y = 0, z = 0) {
|
|
78
63
|
this.isCoordinates = true;
|
|
79
64
|
CRS.isValid(crs);
|
|
80
65
|
this.crs = crs;
|
|
@@ -122,10 +107,7 @@ class Coordinates {
|
|
|
122
107
|
* @param y - y or latitude value.
|
|
123
108
|
* @param z - z or altitude value.
|
|
124
109
|
*/
|
|
125
|
-
setFromValues() {
|
|
126
|
-
let x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
|
|
127
|
-
let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
128
|
-
let z = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
|
|
110
|
+
setFromValues(x = 0, y = 0, z = 0) {
|
|
129
111
|
this.x = x;
|
|
130
112
|
this.y = y;
|
|
131
113
|
this.z = z;
|
|
@@ -142,8 +124,7 @@ class Coordinates {
|
|
|
142
124
|
* @param array - The source array.
|
|
143
125
|
* @param offset - Optional offset into the array. Default is 0.
|
|
144
126
|
*/
|
|
145
|
-
setFromArray(array) {
|
|
146
|
-
let offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
127
|
+
setFromArray(array, offset = 0) {
|
|
147
128
|
return this.setFromValues(array[offset], array[offset + 1], array[offset + 2]);
|
|
148
129
|
}
|
|
149
130
|
|
|
@@ -215,8 +196,7 @@ class Coordinates {
|
|
|
215
196
|
* @returns A vector `(x, y, z)`, or copies x, y and z into the provided
|
|
216
197
|
* vector.
|
|
217
198
|
*/
|
|
218
|
-
toVector3() {
|
|
219
|
-
let target = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : new Vector3();
|
|
199
|
+
toVector3(target = new Vector3()) {
|
|
220
200
|
return target.copy(this);
|
|
221
201
|
}
|
|
222
202
|
|
|
@@ -230,9 +210,7 @@ class Coordinates {
|
|
|
230
210
|
* @returns An array [x, y, z], or copies x, y and z into the provided
|
|
231
211
|
* array.
|
|
232
212
|
*/
|
|
233
|
-
toArray() {
|
|
234
|
-
let array = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
|
|
235
|
-
let offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
213
|
+
toArray(array = [], offset = 0) {
|
|
236
214
|
return Vector3.prototype.toArray.call(this, array, offset);
|
|
237
215
|
}
|
|
238
216
|
|
|
@@ -312,15 +290,14 @@ class Coordinates {
|
|
|
312
290
|
* const geographicCoords = geocentricCoords.as('EPSG:4326');
|
|
313
291
|
* ```
|
|
314
292
|
*/
|
|
315
|
-
as(crs) {
|
|
316
|
-
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Coordinates(crs);
|
|
293
|
+
as(crs, target = new Coordinates(crs)) {
|
|
317
294
|
if (this.crs == crs) {
|
|
318
295
|
target.copy(this);
|
|
319
296
|
} else {
|
|
320
297
|
if (CRS.is4326(this.crs) && crs == 'EPSG:3857') {
|
|
321
298
|
this.y = MathUtils.clamp(this.y, -89.999999, 89.999999);
|
|
322
299
|
}
|
|
323
|
-
target.setFromArray(
|
|
300
|
+
target.setFromArray(CRS.transform(this.crs, crs).forward([this.x, this.y, this.z]));
|
|
324
301
|
}
|
|
325
302
|
target.crs = crs;
|
|
326
303
|
return target;
|
package/lib/Crs.d.ts
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { Converter } from 'proj4';
|
|
2
|
+
import type { ProjectionDefinition } from 'proj4/dist/lib/defs';
|
|
3
|
+
/**
|
|
4
|
+
* A projection as a CRS identifier string. This identifier references a
|
|
5
|
+
* projection definition previously defined with
|
|
6
|
+
* [`proj4.defs`](https://github.com/proj4js/proj4js#named-projections).
|
|
7
|
+
*/
|
|
8
|
+
export type ProjectionLike = string;
|
|
9
|
+
export declare function transform(crsIn: ProjectionLike, crsOut: ProjectionLike): Converter;
|
|
10
|
+
/**
|
|
11
|
+
* System units supported for a coordinate system. See
|
|
12
|
+
* [proj](https://proj4.org/en/9.5/operations/conversions/unitconvert.html#angular-units).
|
|
13
|
+
* Note that only degree and meters units are supported for now.
|
|
14
|
+
*/
|
|
15
|
+
export declare const UNIT: {
|
|
16
|
+
/**
|
|
17
|
+
* Angular unit in degree.
|
|
18
|
+
*/
|
|
19
|
+
readonly DEGREE: 1;
|
|
20
|
+
/**
|
|
21
|
+
* Distance unit in meter.
|
|
22
|
+
*/
|
|
23
|
+
readonly METER: 2;
|
|
24
|
+
/**
|
|
25
|
+
* Distance unit in foot.
|
|
26
|
+
*/
|
|
27
|
+
readonly FOOT: 3;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Checks that the CRS is EPSG:4326.
|
|
31
|
+
* @internal
|
|
32
|
+
*
|
|
33
|
+
* @param crs - The CRS to test.
|
|
34
|
+
*/
|
|
35
|
+
export declare function is4326(crs: ProjectionLike): crs is "EPSG:4326";
|
|
36
|
+
/**
|
|
37
|
+
* Returns the horizontal coordinates system units associated with this CRS.
|
|
38
|
+
*
|
|
39
|
+
* @param crs - The CRS to extract the unit from.
|
|
40
|
+
* @returns Either `UNIT.METER`, `UNIT.DEGREE`, `UNIT.FOOT` or `undefined`.
|
|
41
|
+
*/
|
|
42
|
+
export declare function getUnit(crs: ProjectionLike): 1 | 2 | 3 | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* Asserts that the CRS is using metric units.
|
|
45
|
+
*
|
|
46
|
+
* @param crs - The CRS to check.
|
|
47
|
+
* @throws {@link Error} if the CRS is not valid.
|
|
48
|
+
*/
|
|
49
|
+
export declare function isMetricUnit(crs: ProjectionLike): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Asserts that the CRS is geographic.
|
|
52
|
+
*
|
|
53
|
+
* @param crs - The CRS to check.
|
|
54
|
+
* @throws {@link Error} if the CRS is not valid.
|
|
55
|
+
*/
|
|
56
|
+
export declare function isGeographic(crs: ProjectionLike): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Asserts that the CRS is geocentric.
|
|
59
|
+
*
|
|
60
|
+
* @param crs - The CRS to test.
|
|
61
|
+
* @returns false if the crs isn't defined.
|
|
62
|
+
*/
|
|
63
|
+
export declare function isGeocentric(crs: ProjectionLike): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Asserts that the CRS is valid, meaning it has been previously defined and
|
|
66
|
+
* includes an unit.
|
|
67
|
+
*
|
|
68
|
+
* @param crs - The CRS to test.
|
|
69
|
+
* @throws {@link Error} if the crs is not valid.
|
|
70
|
+
*/
|
|
71
|
+
export declare function isValid(crs: ProjectionLike): void;
|
|
72
|
+
/**
|
|
73
|
+
* Gives a reasonable epsilon for this CRS.
|
|
74
|
+
*
|
|
75
|
+
* @param crs - The CRS to use.
|
|
76
|
+
* @returns 0.01 if the CRS is EPSG:4326, 0.001 otherwise.
|
|
77
|
+
*/
|
|
78
|
+
export declare function reasonableEpsilon(crs: ProjectionLike): 0.01 | 0.001;
|
|
79
|
+
/**
|
|
80
|
+
* Returns the axis parameter defined in proj4 for the provided crs.
|
|
81
|
+
* Might be undefined depending on crs definition.
|
|
82
|
+
*
|
|
83
|
+
* @param crs - The CRS to get axis from.
|
|
84
|
+
* @returns the matching proj4 axis string, 'enu' for instance (east, north, up)
|
|
85
|
+
*/
|
|
86
|
+
export declare function axisOrder(crs: ProjectionLike): string | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Defines a proj4 projection as a named alias.
|
|
89
|
+
* This function is an alias for the
|
|
90
|
+
* [`proj4.defs`](https://github.com/proj4js/proj4js#named-projections) function.
|
|
91
|
+
*/
|
|
92
|
+
export declare const defs: typeof import("proj4/dist/lib/defs").default;
|
|
93
|
+
/**
|
|
94
|
+
* Fetches a CRS definition from epsg.io and registers it with proj4.
|
|
95
|
+
* If the CRS is already defined, returns the existing definition.
|
|
96
|
+
*
|
|
97
|
+
* @param crs - The EPSG code string (e.g. "EPSG:2154").
|
|
98
|
+
* @returns The proj4 projection definition.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* // Register EPSG:2154 (RGF93 / Lambert-93)
|
|
102
|
+
* await CRS.fromEPSG('EPSG:2154');
|
|
103
|
+
*
|
|
104
|
+
* // Register EPSG:4269 (NAD83)
|
|
105
|
+
* await CRS.fromEPSG('EPSG:4269');
|
|
106
|
+
*/
|
|
107
|
+
export declare function fromEPSG(crs: string): Promise<ProjectionDefinition>;
|
|
108
|
+
export declare function defsFromWkt(wkt: string): string;
|
package/lib/Crs.js
CHANGED
|
@@ -12,7 +12,18 @@ proj4.defs('WGS84').axis = 'neu';
|
|
|
12
12
|
* projection definition previously defined with
|
|
13
13
|
* [`proj4.defs`](https://github.com/proj4js/proj4js#named-projections).
|
|
14
14
|
*/
|
|
15
|
+
// TODO Unify with OrientationUtils.js
|
|
15
16
|
|
|
17
|
+
const proj4Cache = {};
|
|
18
|
+
export function transform(crsIn, crsOut) {
|
|
19
|
+
if (!proj4Cache[crsIn]) {
|
|
20
|
+
proj4Cache[crsIn] = {};
|
|
21
|
+
}
|
|
22
|
+
if (!proj4Cache[crsIn][crsOut]) {
|
|
23
|
+
proj4Cache[crsIn][crsOut] = proj4(crsIn, crsOut);
|
|
24
|
+
}
|
|
25
|
+
return proj4Cache[crsIn][crsOut];
|
|
26
|
+
}
|
|
16
27
|
function isString(s) {
|
|
17
28
|
return typeof s === 'string' || s instanceof String;
|
|
18
29
|
}
|
|
@@ -56,7 +67,7 @@ function unitFromProj4Unit(proj) {
|
|
|
56
67
|
return UNIT.DEGREE;
|
|
57
68
|
} else if (proj.units === 'm' || proj.units === 'meter') {
|
|
58
69
|
return UNIT.METER;
|
|
59
|
-
} else if (proj.units === 'foot') {
|
|
70
|
+
} else if (proj.units === 'foot' || proj.units === 'ft') {
|
|
60
71
|
return UNIT.FOOT;
|
|
61
72
|
} else if (proj.units === undefined && proj.to_meter === undefined) {
|
|
62
73
|
// See https://proj.org/en/9.4/usage/projections.html [17/10/2024]
|
|
@@ -124,7 +135,7 @@ export function isGeocentric(crs) {
|
|
|
124
135
|
export function isValid(crs) {
|
|
125
136
|
const proj = proj4.defs(crs);
|
|
126
137
|
if (!proj) {
|
|
127
|
-
throw new Error(`Undefined crs '${crs}'. Add it with
|
|
138
|
+
throw new Error(`Undefined crs '${crs}'. Add it with itowns.CRS.defs('${crs}', wktString)`);
|
|
128
139
|
}
|
|
129
140
|
if (!unitFromProj4Unit(proj)) {
|
|
130
141
|
throw new Error(`No valid unit found for crs '${crs}', found ${proj.units}`);
|
|
@@ -160,11 +171,53 @@ export function axisOrder(crs) {
|
|
|
160
171
|
|
|
161
172
|
/**
|
|
162
173
|
* Defines a proj4 projection as a named alias.
|
|
163
|
-
* This function is
|
|
164
|
-
* [`proj4.defs`](https://github.com/proj4js/proj4js#named-projections)
|
|
165
|
-
|
|
174
|
+
* This function is an alias for the
|
|
175
|
+
* [`proj4.defs`](https://github.com/proj4js/proj4js#named-projections) function.
|
|
176
|
+
*/
|
|
177
|
+
export const defs = proj4.defs;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Fetches a CRS definition from epsg.io and registers it with proj4.
|
|
181
|
+
* If the CRS is already defined, returns the existing definition.
|
|
182
|
+
*
|
|
183
|
+
* @param crs - The EPSG code string (e.g. "EPSG:2154").
|
|
184
|
+
* @returns The proj4 projection definition.
|
|
166
185
|
*
|
|
167
|
-
* @
|
|
168
|
-
*
|
|
186
|
+
* @example
|
|
187
|
+
* // Register EPSG:2154 (RGF93 / Lambert-93)
|
|
188
|
+
* await CRS.fromEPSG('EPSG:2154');
|
|
189
|
+
*
|
|
190
|
+
* // Register EPSG:4269 (NAD83)
|
|
191
|
+
* await CRS.fromEPSG('EPSG:4269');
|
|
169
192
|
*/
|
|
170
|
-
export
|
|
193
|
+
export async function fromEPSG(crs) {
|
|
194
|
+
const def = proj4.defs(crs);
|
|
195
|
+
if (def) {
|
|
196
|
+
return def;
|
|
197
|
+
}
|
|
198
|
+
const code = crs.replace(/^EPSG:/i, '');
|
|
199
|
+
const response = await fetch(`https://epsg.io/${code}.proj4`);
|
|
200
|
+
if (!response.ok) {
|
|
201
|
+
throw new Error(`Failed to fetch EPSG:${code} from epsg.io: ${response.status}`);
|
|
202
|
+
}
|
|
203
|
+
const proj4def = await response.text();
|
|
204
|
+
proj4.defs(crs, proj4def);
|
|
205
|
+
return proj4.defs(crs);
|
|
206
|
+
}
|
|
207
|
+
export function defsFromWkt(wkt) {
|
|
208
|
+
proj4.defs('unknown', wkt);
|
|
209
|
+
const proj4Defs = proj4.defs;
|
|
210
|
+
let projCS;
|
|
211
|
+
if (proj4Defs('unknown').type === 'COMPD_CS') {
|
|
212
|
+
console.warn('Compound coordinate system is not yet supported.');
|
|
213
|
+
projCS = proj4Defs('unknown').PROJCS;
|
|
214
|
+
} else {
|
|
215
|
+
projCS = proj4Defs('unknown');
|
|
216
|
+
}
|
|
217
|
+
const crsAlias = projCS.title || projCS.name || 'EPSG:XXXX';
|
|
218
|
+
if (!(crsAlias in proj4.defs)) {
|
|
219
|
+
proj4.defs(crsAlias, projCS);
|
|
220
|
+
}
|
|
221
|
+
delete proj4Defs.unknown;
|
|
222
|
+
return crsAlias;
|
|
223
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { Vector3, type Vector3Like, type Ray } from 'three';
|
|
2
|
+
import Coordinates from './Coordinates';
|
|
3
|
+
/**
|
|
4
|
+
* Length of the semi-axes of the WGS84 ellipsoid.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
export declare const ellipsoidSizes: Vector3;
|
|
8
|
+
declare class Ellipsoid {
|
|
9
|
+
/**
|
|
10
|
+
* Length of the semi-axes of the ellipsoid.
|
|
11
|
+
*/
|
|
12
|
+
size: Vector3;
|
|
13
|
+
/**
|
|
14
|
+
* Eccentricity of the ellipsoid.
|
|
15
|
+
*/
|
|
16
|
+
eccentricity: number;
|
|
17
|
+
private _radiiSquared;
|
|
18
|
+
private _invRadiiSquared;
|
|
19
|
+
/**
|
|
20
|
+
* @param size - Length of the semi-axes of the ellipsoid. Defaults to those
|
|
21
|
+
* defined by the WGS84 ellipsoid.
|
|
22
|
+
*/
|
|
23
|
+
constructor(size?: Vector3);
|
|
24
|
+
/**
|
|
25
|
+
* Computes the normal vector to an ellipsoid at the given cartesian
|
|
26
|
+
* coordinate `(x, y, z)`.
|
|
27
|
+
*
|
|
28
|
+
* @param cartesian - The given cartesian coordinate.
|
|
29
|
+
* @param target - An object to store this vector to. If this is not
|
|
30
|
+
* specified, a new vector will be created.
|
|
31
|
+
*/
|
|
32
|
+
geodeticSurfaceNormal(cartesian: Coordinates, target?: Vector3): Vector3;
|
|
33
|
+
/**
|
|
34
|
+
* Computes the normal vector to an ellipsoid at the given geographic
|
|
35
|
+
* coordinate `(longitude, latitude, altitude)`.
|
|
36
|
+
*
|
|
37
|
+
* @param coordCarto - The given geographic coordinate.
|
|
38
|
+
* @param target - An object to store this vector to. If this is not
|
|
39
|
+
* specified, a new vector will be created.
|
|
40
|
+
*/
|
|
41
|
+
geodeticSurfaceNormalCartographic(coordCarto: Coordinates, target?: Vector3): Vector3;
|
|
42
|
+
/**
|
|
43
|
+
* Sets the length of the semi-axes of this ellipsoid from a 3-dimensional
|
|
44
|
+
* vector-like object. The object shall have both `x`, `y` and `z`
|
|
45
|
+
* properties.
|
|
46
|
+
*
|
|
47
|
+
* @param size - The source vector.
|
|
48
|
+
*/
|
|
49
|
+
setSize(size: Vector3Like): this;
|
|
50
|
+
cartographicToCartesian(coordCarto: Coordinates, target?: Vector3): Vector3;
|
|
51
|
+
/**
|
|
52
|
+
* Convert cartesian coordinates to geographic according to the current
|
|
53
|
+
* ellipsoid of revolution.
|
|
54
|
+
* @param position - The coordinate to convert
|
|
55
|
+
* @param target - coordinate to copy result
|
|
56
|
+
* @returns an object describing the coordinates on the reference ellipsoid,
|
|
57
|
+
* angles are in degree
|
|
58
|
+
*/
|
|
59
|
+
cartesianToCartographic(position: Vector3Like, target?: Coordinates): Coordinates;
|
|
60
|
+
cartographicToCartesianArray(coordCartoArray: Coordinates[]): Vector3[];
|
|
61
|
+
intersection(ray: Ray): Vector3 | false;
|
|
62
|
+
/**
|
|
63
|
+
* Calculate the geodesic distance, between coordCarto1 and coordCarto2.
|
|
64
|
+
* It's most short distance on ellipsoid surface between coordCarto1 and
|
|
65
|
+
* coordCarto2.
|
|
66
|
+
* It's called orthodromy.
|
|
67
|
+
*
|
|
68
|
+
* @param coordCarto1 - The coordinate carto 1
|
|
69
|
+
* @param coordCarto2 - The coordinate carto 2
|
|
70
|
+
* @returns The orthodromic distance between the two given coordinates.
|
|
71
|
+
*/
|
|
72
|
+
geodesicDistance(coordCarto1: Coordinates, coordCarto2: Coordinates): number;
|
|
73
|
+
}
|
|
74
|
+
export default Ellipsoid;
|
package/lib/Ellipsoid.js
CHANGED
|
@@ -21,8 +21,7 @@ class Ellipsoid {
|
|
|
21
21
|
* @param size - Length of the semi-axes of the ellipsoid. Defaults to those
|
|
22
22
|
* defined by the WGS84 ellipsoid.
|
|
23
23
|
*/
|
|
24
|
-
constructor() {
|
|
25
|
-
let size = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ellipsoidSizes;
|
|
24
|
+
constructor(size = ellipsoidSizes) {
|
|
26
25
|
this.size = new Vector3();
|
|
27
26
|
this._radiiSquared = new Vector3();
|
|
28
27
|
this._invRadiiSquared = new Vector3();
|
|
@@ -38,8 +37,7 @@ class Ellipsoid {
|
|
|
38
37
|
* @param target - An object to store this vector to. If this is not
|
|
39
38
|
* specified, a new vector will be created.
|
|
40
39
|
*/
|
|
41
|
-
geodeticSurfaceNormal(cartesian) {
|
|
42
|
-
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Vector3();
|
|
40
|
+
geodeticSurfaceNormal(cartesian, target = new Vector3()) {
|
|
43
41
|
return cartesian.toVector3(target).multiply(this._invRadiiSquared).normalize();
|
|
44
42
|
}
|
|
45
43
|
|
|
@@ -51,8 +49,7 @@ class Ellipsoid {
|
|
|
51
49
|
* @param target - An object to store this vector to. If this is not
|
|
52
50
|
* specified, a new vector will be created.
|
|
53
51
|
*/
|
|
54
|
-
geodeticSurfaceNormalCartographic(coordCarto) {
|
|
55
|
-
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Vector3();
|
|
52
|
+
geodeticSurfaceNormalCartographic(coordCarto, target = new Vector3()) {
|
|
56
53
|
const longitude = MathUtils.degToRad(coordCarto.longitude);
|
|
57
54
|
const latitude = MathUtils.degToRad(coordCarto.latitude);
|
|
58
55
|
const cosLatitude = Math.cos(latitude);
|
|
@@ -75,8 +72,7 @@ class Ellipsoid {
|
|
|
75
72
|
this.eccentricity = Math.sqrt(this._radiiSquared.x - this._radiiSquared.z) / this.size.x;
|
|
76
73
|
return this;
|
|
77
74
|
}
|
|
78
|
-
cartographicToCartesian(coordCarto) {
|
|
79
|
-
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Vector3();
|
|
75
|
+
cartographicToCartesian(coordCarto, target = new Vector3()) {
|
|
80
76
|
normal.copy(coordCarto.geodesicNormal);
|
|
81
77
|
target.multiplyVectors(this._radiiSquared, normal);
|
|
82
78
|
const gamma = Math.sqrt(normal.dot(target));
|
|
@@ -93,8 +89,7 @@ class Ellipsoid {
|
|
|
93
89
|
* @returns an object describing the coordinates on the reference ellipsoid,
|
|
94
90
|
* angles are in degree
|
|
95
91
|
*/
|
|
96
|
-
cartesianToCartographic(position) {
|
|
97
|
-
let target = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : new Coordinates('EPSG:4326', 0, 0, 0);
|
|
92
|
+
cartesianToCartographic(position, target = new Coordinates('EPSG:4326', 0, 0, 0)) {
|
|
98
93
|
// for details, see for example http://www.linz.govt.nz/data/geodetic-system/coordinate-conversion/geodetic-datum-conversions/equations-used-datum
|
|
99
94
|
// TODO the following is only valable for oblate ellipsoid of
|
|
100
95
|
// revolution. do we want to support triaxial ellipsoid?
|