gnss-js 1.0.1 → 1.2.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 (42) hide show
  1. package/README.md +54 -0
  2. package/dist/analysis.cjs +3 -3
  3. package/dist/analysis.js +3 -3
  4. package/dist/{chunk-HKN3PUGN.js → chunk-5SPJH4MG.js} +35 -26
  5. package/dist/{chunk-WP2JFDLA.js → chunk-7EEWQ5DU.js} +93 -118
  6. package/dist/{chunk-SO3POWWR.js → chunk-G3N4S3DM.js} +2 -2
  7. package/dist/{chunk-7NOFXKET.js → chunk-HVXYFUCB.js} +72 -257
  8. package/dist/chunk-L5OUUNLT.js +198 -0
  9. package/dist/{chunk-HBLU2EJ4.js → chunk-OZCYOM5D.js} +1 -1
  10. package/dist/{chunk-4YN353Q7.js → chunk-VANVV4F7.js} +21 -7
  11. package/dist/{chunk-LWNTWBHB.js → chunk-W5WKEV7U.js} +3 -2
  12. package/dist/constants.cjs +3 -2
  13. package/dist/constants.js +7 -7
  14. package/dist/{ephemeris-C10stHhM.d.cts → ephemeris-Ohl6NAfw.d.cts} +11 -1
  15. package/dist/{ephemeris-C10stHhM.d.ts → ephemeris-Ohl6NAfw.d.ts} +11 -1
  16. package/dist/frames.cjs +250 -0
  17. package/dist/frames.d.cts +56 -0
  18. package/dist/frames.d.ts +56 -0
  19. package/dist/frames.js +222 -0
  20. package/dist/index.cjs +133 -152
  21. package/dist/index.d.cts +2 -2
  22. package/dist/index.d.ts +2 -2
  23. package/dist/index.js +96 -88
  24. package/dist/orbit.cjs +103 -7
  25. package/dist/orbit.d.cts +1 -1
  26. package/dist/orbit.d.ts +1 -1
  27. package/dist/orbit.js +3 -1
  28. package/dist/positioning.cjs +565 -0
  29. package/dist/positioning.d.cts +68 -0
  30. package/dist/positioning.d.ts +68 -0
  31. package/dist/positioning.js +206 -0
  32. package/dist/rinex.js +2 -2
  33. package/dist/rtcm3.cjs +116 -117
  34. package/dist/rtcm3.d.cts +9 -3
  35. package/dist/rtcm3.d.ts +9 -3
  36. package/dist/rtcm3.js +9 -2
  37. package/dist/signals.cjs +55 -26
  38. package/dist/signals.d.cts +26 -26
  39. package/dist/signals.d.ts +26 -26
  40. package/dist/signals.js +2 -1
  41. package/dist/time.js +20 -18
  42. package/package.json +11 -2
package/dist/constants.js CHANGED
@@ -1,4 +1,10 @@
1
1
  import "./chunk-5S5MONFK.js";
2
+ import {
3
+ WGS84_ECCENTRICITY_SQUARED,
4
+ WGS84_FLATTENING,
5
+ WGS84_SEMI_MAJOR_AXIS,
6
+ WGS84_SEMI_MINOR_AXIS
7
+ } from "./chunk-6FAL6P4G.js";
2
8
  import {
3
9
  DAYS_MJD2000_MJD,
4
10
  DAYS_MJD_JULIAN,
@@ -45,13 +51,7 @@ import {
45
51
  formatUTCTime,
46
52
  getFreq,
47
53
  gloFreq
48
- } from "./chunk-LWNTWBHB.js";
49
- import {
50
- WGS84_ECCENTRICITY_SQUARED,
51
- WGS84_FLATTENING,
52
- WGS84_SEMI_MAJOR_AXIS,
53
- WGS84_SEMI_MINOR_AXIS
54
- } from "./chunk-6FAL6P4G.js";
54
+ } from "./chunk-W5WKEV7U.js";
55
55
  export {
56
56
  ARC_GAP_FACTOR,
57
57
  BAND_LABELS,
@@ -7,6 +7,16 @@ interface Rtcm3Frame {
7
7
  length: number;
8
8
  payload: Uint8Array;
9
9
  }
10
+ /** Called when a message decoder swallows an exception. */
11
+ type Rtcm3DebugHandler = (context: string, error: unknown) => void;
12
+ /**
13
+ * Install a handler to observe decode errors that are otherwise
14
+ * silently mapped to null results (corrupt frames, truncated payloads).
15
+ * Pass null to remove.
16
+ */
17
+ declare function setRtcm3DebugHandler(fn: Rtcm3DebugHandler | null): void;
18
+ /** @internal Report a swallowed decode error to the debug handler. */
19
+ declare function reportDecodeError(context: string, error: unknown): void;
10
20
  /** Simple bit reader for parsing RTCM3 payloads at bit level. */
11
21
  declare class BitReader {
12
22
  private data;
@@ -111,4 +121,4 @@ declare function readString(r: BitReader, nChars: number): string;
111
121
  /** Decode any supported ephemeris message. Returns null for non-ephemeris or decode errors. */
112
122
  declare function decodeEphemeris(frame: Rtcm3Frame): EphemerisInfo | null;
113
123
 
114
- export { BitReader as B, type EphemerisInfo as E, Rtcm3Decoder as R, type Rtcm3Frame as a, decodeEphemeris as d, readString as r };
124
+ export { BitReader as B, type EphemerisInfo as E, type Rtcm3DebugHandler as R, Rtcm3Decoder as a, type Rtcm3Frame as b, reportDecodeError as c, decodeEphemeris as d, readString as r, setRtcm3DebugHandler as s };
@@ -7,6 +7,16 @@ interface Rtcm3Frame {
7
7
  length: number;
8
8
  payload: Uint8Array;
9
9
  }
10
+ /** Called when a message decoder swallows an exception. */
11
+ type Rtcm3DebugHandler = (context: string, error: unknown) => void;
12
+ /**
13
+ * Install a handler to observe decode errors that are otherwise
14
+ * silently mapped to null results (corrupt frames, truncated payloads).
15
+ * Pass null to remove.
16
+ */
17
+ declare function setRtcm3DebugHandler(fn: Rtcm3DebugHandler | null): void;
18
+ /** @internal Report a swallowed decode error to the debug handler. */
19
+ declare function reportDecodeError(context: string, error: unknown): void;
10
20
  /** Simple bit reader for parsing RTCM3 payloads at bit level. */
11
21
  declare class BitReader {
12
22
  private data;
@@ -111,4 +121,4 @@ declare function readString(r: BitReader, nChars: number): string;
111
121
  /** Decode any supported ephemeris message. Returns null for non-ephemeris or decode errors. */
112
122
  declare function decodeEphemeris(frame: Rtcm3Frame): EphemerisInfo | null;
113
123
 
114
- export { BitReader as B, type EphemerisInfo as E, Rtcm3Decoder as R, type Rtcm3Frame as a, decodeEphemeris as d, readString as r };
124
+ export { BitReader as B, type EphemerisInfo as E, type Rtcm3DebugHandler as R, Rtcm3Decoder as a, type Rtcm3Frame as b, reportDecodeError as c, decodeEphemeris as d, readString as r, setRtcm3DebugHandler as s };
@@ -0,0 +1,250 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/frames/index.ts
21
+ var frames_exports = {};
22
+ __export(frames_exports, {
23
+ REFERENCE_FRAMES: () => REFERENCE_FRAMES,
24
+ applyHelmert: () => applyHelmert,
25
+ dateToEpoch: () => dateToEpoch,
26
+ transformFrame: () => transformFrame
27
+ });
28
+ module.exports = __toCommonJS(frames_exports);
29
+ var H = (t, d, r, tDot, dDot, rDot, epoch) => ({ t, d, r, tDot, dDot, rDot, epoch });
30
+ var Z = [0, 0, 0];
31
+ var FROM_ITRF2020 = {
32
+ ITRF2014: H([-1.4, -0.9, 1.4], -0.42, Z, [0, -0.1, 0.2], 0, Z, 2015),
33
+ ITRF2008: H([0.2, 1, 3.3], -0.29, Z, [0, -0.1, 0.1], 0.03, Z, 2015),
34
+ ITRF2005: H([2.7, 0.1, -1.4], 0.65, Z, [0.3, -0.1, 0.1], 0.03, Z, 2015),
35
+ ITRF2000: H([-0.2, 0.8, -34.2], 2.25, Z, [0.1, 0, -1.7], 0.11, Z, 2015),
36
+ ITRF97: H(
37
+ [6.5, -3.9, -77.9],
38
+ 3.98,
39
+ [0, 0, 0.36],
40
+ [0.1, -0.6, -3.1],
41
+ 0.12,
42
+ [0, 0, 0.02],
43
+ 2015
44
+ ),
45
+ ITRF96: H(
46
+ [6.5, -3.9, -77.9],
47
+ 3.98,
48
+ [0, 0, 0.36],
49
+ [0.1, -0.6, -3.1],
50
+ 0.12,
51
+ [0, 0, 0.02],
52
+ 2015
53
+ ),
54
+ ITRF94: H(
55
+ [6.5, -3.9, -77.9],
56
+ 3.98,
57
+ [0, 0, 0.36],
58
+ [0.1, -0.6, -3.1],
59
+ 0.12,
60
+ [0, 0, 0.02],
61
+ 2015
62
+ ),
63
+ ITRF93: H(
64
+ [-65.8, 1.9, -71.3],
65
+ 4.47,
66
+ [-3.36, -4.33, 0.75],
67
+ [-2.8, -0.2, -2.3],
68
+ 0.12,
69
+ [-0.11, -0.19, 0.07],
70
+ 2015
71
+ ),
72
+ ITRF92: H(
73
+ [14.5, -1.9, -85.9],
74
+ 3.27,
75
+ [0, 0, 0.36],
76
+ [0.1, -0.6, -3.1],
77
+ 0.12,
78
+ [0, 0, 0.02],
79
+ 2015
80
+ ),
81
+ ITRF91: H(
82
+ [26.5, 12.1, -91.9],
83
+ 4.67,
84
+ [0, 0, 0.36],
85
+ [0.1, -0.6, -3.1],
86
+ 0.12,
87
+ [0, 0, 0.02],
88
+ 2015
89
+ ),
90
+ ITRF90: H(
91
+ [24.5, 8.1, -107.9],
92
+ 4.97,
93
+ [0, 0, 0.36],
94
+ [0.1, -0.6, -3.1],
95
+ 0.12,
96
+ [0, 0, 0.02],
97
+ 2015
98
+ ),
99
+ ITRF89: H(
100
+ [29.5, 32.1, -145.9],
101
+ 8.37,
102
+ [0, 0, 0.36],
103
+ [0.1, -0.6, -3.1],
104
+ 0.12,
105
+ [0, 0, 0.02],
106
+ 2015
107
+ ),
108
+ ITRF88: H(
109
+ [24.5, -3.9, -169.9],
110
+ 11.47,
111
+ [0.1, 0, 0.36],
112
+ [0.1, -0.6, -3.1],
113
+ 0.12,
114
+ [0, 0, 0.02],
115
+ 2015
116
+ ),
117
+ /** ITRF2020 → ETRF2020, EPSG:10572 (epoch-1989 variant) */
118
+ ETRF2020: H(Z, 0, Z, Z, 0, [0.086, 0.519, -0.753], 1989)
119
+ };
120
+ var ITRF2014_TO_ETRF2014 = H(Z, 0, Z, Z, 0, [0.085, 0.531, -0.77], 1989);
121
+ var ITRF2014_TO_ETRF2000 = H(
122
+ [54.7, 52.2, -74.1],
123
+ 2.12,
124
+ [1.701, 10.29, -16.632],
125
+ [0.1, 0.1, -1.9],
126
+ 0.11,
127
+ [0.081, 0.49, -0.792],
128
+ 2010
129
+ );
130
+ var ITRF2014_TO_NAD83_2011 = H(
131
+ [1005.3, -1909.21, -541.57],
132
+ 0.36891,
133
+ [-26.78138, 0.42027, -10.93206],
134
+ [0.79, -0.6, -1.44],
135
+ -0.07201,
136
+ [-0.06667, 0.75744, 0.05133],
137
+ 2010
138
+ );
139
+ var MAS_TO_RAD = Math.PI / (180 * 3600 * 1e3);
140
+ function applyHelmert(xyz, p, epoch, inverse = false) {
141
+ const dt = epoch - p.epoch;
142
+ const sign = inverse ? -1 : 1;
143
+ const tx = sign * (p.t[0] + p.tDot[0] * dt) / 1e3;
144
+ const ty = sign * (p.t[1] + p.tDot[1] * dt) / 1e3;
145
+ const tz = sign * (p.t[2] + p.tDot[2] * dt) / 1e3;
146
+ const d = sign * (p.d + p.dDot * dt) * 1e-9;
147
+ const rx = sign * (p.r[0] + p.rDot[0] * dt) * MAS_TO_RAD;
148
+ const ry = sign * (p.r[1] + p.rDot[1] * dt) * MAS_TO_RAD;
149
+ const rz = sign * (p.r[2] + p.rDot[2] * dt) * MAS_TO_RAD;
150
+ const [x, y, z] = xyz;
151
+ return [
152
+ x + tx + d * x - rz * y + ry * z,
153
+ y + ty + rz * x + d * y - rx * z,
154
+ z + tz - ry * x + rx * y + d * z
155
+ ];
156
+ }
157
+ var EDGES = [
158
+ ...Object.entries(FROM_ITRF2020).map(([to, p]) => ({
159
+ from: "ITRF2020",
160
+ to,
161
+ p
162
+ })),
163
+ { from: "ITRF2014", to: "ETRF2014", p: ITRF2014_TO_ETRF2014 },
164
+ { from: "ITRF2014", to: "ETRF2000", p: ITRF2014_TO_ETRF2000 },
165
+ { from: "ITRF2014", to: "NAD83(2011)", p: ITRF2014_TO_NAD83_2011 }
166
+ ];
167
+ var REFERENCE_FRAMES = [
168
+ "WGS84",
169
+ "ITRF2020",
170
+ "ITRF2014",
171
+ "ITRF2008",
172
+ "ITRF2005",
173
+ "ITRF2000",
174
+ "ITRF97",
175
+ "ITRF96",
176
+ "ITRF94",
177
+ "ITRF93",
178
+ "ITRF92",
179
+ "ITRF91",
180
+ "ITRF90",
181
+ "ITRF89",
182
+ "ITRF88",
183
+ "ETRF2020",
184
+ "ETRF2014",
185
+ "ETRF2000",
186
+ "NAD83(2011)"
187
+ ];
188
+ function resolveAlias(f) {
189
+ return f === "WGS84" ? "ITRF2020" : f;
190
+ }
191
+ function findPath(from, to) {
192
+ if (from === to) return [];
193
+ const queue = [from];
194
+ const cameFrom = /* @__PURE__ */ new Map();
195
+ const seen = /* @__PURE__ */ new Set([from]);
196
+ while (queue.length > 0) {
197
+ const cur = queue.shift();
198
+ for (const edge of EDGES) {
199
+ let next = null;
200
+ let inverse = false;
201
+ if (edge.from === cur) {
202
+ next = edge.to;
203
+ } else if (edge.to === cur) {
204
+ next = edge.from;
205
+ inverse = true;
206
+ }
207
+ if (next === null || seen.has(next)) continue;
208
+ seen.add(next);
209
+ cameFrom.set(next, { prev: cur, edge, inverse });
210
+ if (next === to) {
211
+ const path = [];
212
+ let node = to;
213
+ while (node !== from) {
214
+ const step = cameFrom.get(node);
215
+ path.unshift({ edge: step.edge, inverse: step.inverse });
216
+ node = step.prev;
217
+ }
218
+ return path;
219
+ }
220
+ queue.push(next);
221
+ }
222
+ }
223
+ return null;
224
+ }
225
+ function transformFrame(xyz, from, to, epoch) {
226
+ const src = resolveAlias(from);
227
+ const dst = resolveAlias(to);
228
+ const path = findPath(src, dst);
229
+ if (!path) {
230
+ throw new Error(`No transformation path from ${from} to ${to}`);
231
+ }
232
+ let out = [xyz[0], xyz[1], xyz[2]];
233
+ for (const { edge, inverse } of path) {
234
+ out = applyHelmert(out, edge.p, epoch, inverse);
235
+ }
236
+ return out;
237
+ }
238
+ function dateToEpoch(date) {
239
+ const year = date.getUTCFullYear();
240
+ const start = Date.UTC(year, 0, 1);
241
+ const end = Date.UTC(year + 1, 0, 1);
242
+ return year + (date.getTime() - start) / (end - start);
243
+ }
244
+ // Annotate the CommonJS export names for ESM import in node:
245
+ 0 && (module.exports = {
246
+ REFERENCE_FRAMES,
247
+ applyHelmert,
248
+ dateToEpoch,
249
+ transformFrame
250
+ });
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Terrestrial reference frame transformations.
3
+ *
4
+ * Time-dependent 14-parameter Helmert transformations between ITRF
5
+ * realizations, the ETRS89 realizations (ETRF2000/2014/2020), and
6
+ * NAD83(2011). All parameters are taken verbatim from authoritative
7
+ * sources — IERS/IGN for ITRF↔ITRF, EPSG registry entries for the
8
+ * rest — never re-derived. Each parameter set cites its source.
9
+ *
10
+ * Conventions: parameters are stored in the IERS "Position Vector"
11
+ * convention (rotations describe the rotation of the position vector,
12
+ * CRS source→target: Xs = X + T + D·X + R·X with
13
+ * R·X = (−R3·y + R2·z, R3·x − R1·z, −R2·x + R1·y) ).
14
+ * EPSG entries published in the opposite "Coordinate Frame rotation"
15
+ * convention (NAD83) have their rotations negated at definition time.
16
+ *
17
+ * WGS84 note: the current WGS84 realization (G2296) is aligned to
18
+ * ITRF2020 at the few-cm level; this module treats 'WGS84' as an alias
19
+ * of ITRF2020, which is the standard GNSS practice.
20
+ */
21
+ type ReferenceFrame = 'ITRF2020' | 'ITRF2014' | 'ITRF2008' | 'ITRF2005' | 'ITRF2000' | 'ITRF97' | 'ITRF96' | 'ITRF94' | 'ITRF93' | 'ITRF92' | 'ITRF91' | 'ITRF90' | 'ITRF89' | 'ITRF88' | 'ETRF2020' | 'ETRF2014' | 'ETRF2000' | 'NAD83(2011)' | 'WGS84';
22
+ /**
23
+ * 14-parameter Helmert set (Position Vector convention).
24
+ * Units: translations mm (rates mm/yr), scale ppb (ppb/yr),
25
+ * rotations mas (mas/yr); epoch in decimal years.
26
+ */
27
+ interface Helmert14 {
28
+ t: [number, number, number];
29
+ d: number;
30
+ r: [number, number, number];
31
+ tDot: [number, number, number];
32
+ dDot: number;
33
+ rDot: [number, number, number];
34
+ epoch: number;
35
+ }
36
+ /**
37
+ * Apply a time-dependent Helmert transformation (Position Vector
38
+ * convention) to geocentric coordinates, evaluated at `epoch`
39
+ * (decimal years). Pass `inverse` to go target → source.
40
+ */
41
+ declare function applyHelmert(xyz: readonly [number, number, number], p: Helmert14, epoch: number, inverse?: boolean): [number, number, number];
42
+ /** Frames supported by transformFrame (WGS84 is an ITRF2020 alias). */
43
+ declare const REFERENCE_FRAMES: ReferenceFrame[];
44
+ /**
45
+ * Transform geocentric coordinates between reference frames at a given
46
+ * coordinate epoch (decimal years, e.g. 2010.5).
47
+ *
48
+ * The epoch is the epoch of the coordinates themselves — the same
49
+ * physical location is expressed in both frames at that instant; no
50
+ * intra-plate velocity propagation is applied.
51
+ */
52
+ declare function transformFrame(xyz: readonly [number, number, number], from: ReferenceFrame, to: ReferenceFrame, epoch: number): [number, number, number];
53
+ /** Convert a Date to the decimal-year epoch used by transformFrame. */
54
+ declare function dateToEpoch(date: Date): number;
55
+
56
+ export { type Helmert14, REFERENCE_FRAMES, type ReferenceFrame, applyHelmert, dateToEpoch, transformFrame };
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Terrestrial reference frame transformations.
3
+ *
4
+ * Time-dependent 14-parameter Helmert transformations between ITRF
5
+ * realizations, the ETRS89 realizations (ETRF2000/2014/2020), and
6
+ * NAD83(2011). All parameters are taken verbatim from authoritative
7
+ * sources — IERS/IGN for ITRF↔ITRF, EPSG registry entries for the
8
+ * rest — never re-derived. Each parameter set cites its source.
9
+ *
10
+ * Conventions: parameters are stored in the IERS "Position Vector"
11
+ * convention (rotations describe the rotation of the position vector,
12
+ * CRS source→target: Xs = X + T + D·X + R·X with
13
+ * R·X = (−R3·y + R2·z, R3·x − R1·z, −R2·x + R1·y) ).
14
+ * EPSG entries published in the opposite "Coordinate Frame rotation"
15
+ * convention (NAD83) have their rotations negated at definition time.
16
+ *
17
+ * WGS84 note: the current WGS84 realization (G2296) is aligned to
18
+ * ITRF2020 at the few-cm level; this module treats 'WGS84' as an alias
19
+ * of ITRF2020, which is the standard GNSS practice.
20
+ */
21
+ type ReferenceFrame = 'ITRF2020' | 'ITRF2014' | 'ITRF2008' | 'ITRF2005' | 'ITRF2000' | 'ITRF97' | 'ITRF96' | 'ITRF94' | 'ITRF93' | 'ITRF92' | 'ITRF91' | 'ITRF90' | 'ITRF89' | 'ITRF88' | 'ETRF2020' | 'ETRF2014' | 'ETRF2000' | 'NAD83(2011)' | 'WGS84';
22
+ /**
23
+ * 14-parameter Helmert set (Position Vector convention).
24
+ * Units: translations mm (rates mm/yr), scale ppb (ppb/yr),
25
+ * rotations mas (mas/yr); epoch in decimal years.
26
+ */
27
+ interface Helmert14 {
28
+ t: [number, number, number];
29
+ d: number;
30
+ r: [number, number, number];
31
+ tDot: [number, number, number];
32
+ dDot: number;
33
+ rDot: [number, number, number];
34
+ epoch: number;
35
+ }
36
+ /**
37
+ * Apply a time-dependent Helmert transformation (Position Vector
38
+ * convention) to geocentric coordinates, evaluated at `epoch`
39
+ * (decimal years). Pass `inverse` to go target → source.
40
+ */
41
+ declare function applyHelmert(xyz: readonly [number, number, number], p: Helmert14, epoch: number, inverse?: boolean): [number, number, number];
42
+ /** Frames supported by transformFrame (WGS84 is an ITRF2020 alias). */
43
+ declare const REFERENCE_FRAMES: ReferenceFrame[];
44
+ /**
45
+ * Transform geocentric coordinates between reference frames at a given
46
+ * coordinate epoch (decimal years, e.g. 2010.5).
47
+ *
48
+ * The epoch is the epoch of the coordinates themselves — the same
49
+ * physical location is expressed in both frames at that instant; no
50
+ * intra-plate velocity propagation is applied.
51
+ */
52
+ declare function transformFrame(xyz: readonly [number, number, number], from: ReferenceFrame, to: ReferenceFrame, epoch: number): [number, number, number];
53
+ /** Convert a Date to the decimal-year epoch used by transformFrame. */
54
+ declare function dateToEpoch(date: Date): number;
55
+
56
+ export { type Helmert14, REFERENCE_FRAMES, type ReferenceFrame, applyHelmert, dateToEpoch, transformFrame };
package/dist/frames.js ADDED
@@ -0,0 +1,222 @@
1
+ // src/frames/index.ts
2
+ var H = (t, d, r, tDot, dDot, rDot, epoch) => ({ t, d, r, tDot, dDot, rDot, epoch });
3
+ var Z = [0, 0, 0];
4
+ var FROM_ITRF2020 = {
5
+ ITRF2014: H([-1.4, -0.9, 1.4], -0.42, Z, [0, -0.1, 0.2], 0, Z, 2015),
6
+ ITRF2008: H([0.2, 1, 3.3], -0.29, Z, [0, -0.1, 0.1], 0.03, Z, 2015),
7
+ ITRF2005: H([2.7, 0.1, -1.4], 0.65, Z, [0.3, -0.1, 0.1], 0.03, Z, 2015),
8
+ ITRF2000: H([-0.2, 0.8, -34.2], 2.25, Z, [0.1, 0, -1.7], 0.11, Z, 2015),
9
+ ITRF97: H(
10
+ [6.5, -3.9, -77.9],
11
+ 3.98,
12
+ [0, 0, 0.36],
13
+ [0.1, -0.6, -3.1],
14
+ 0.12,
15
+ [0, 0, 0.02],
16
+ 2015
17
+ ),
18
+ ITRF96: H(
19
+ [6.5, -3.9, -77.9],
20
+ 3.98,
21
+ [0, 0, 0.36],
22
+ [0.1, -0.6, -3.1],
23
+ 0.12,
24
+ [0, 0, 0.02],
25
+ 2015
26
+ ),
27
+ ITRF94: H(
28
+ [6.5, -3.9, -77.9],
29
+ 3.98,
30
+ [0, 0, 0.36],
31
+ [0.1, -0.6, -3.1],
32
+ 0.12,
33
+ [0, 0, 0.02],
34
+ 2015
35
+ ),
36
+ ITRF93: H(
37
+ [-65.8, 1.9, -71.3],
38
+ 4.47,
39
+ [-3.36, -4.33, 0.75],
40
+ [-2.8, -0.2, -2.3],
41
+ 0.12,
42
+ [-0.11, -0.19, 0.07],
43
+ 2015
44
+ ),
45
+ ITRF92: H(
46
+ [14.5, -1.9, -85.9],
47
+ 3.27,
48
+ [0, 0, 0.36],
49
+ [0.1, -0.6, -3.1],
50
+ 0.12,
51
+ [0, 0, 0.02],
52
+ 2015
53
+ ),
54
+ ITRF91: H(
55
+ [26.5, 12.1, -91.9],
56
+ 4.67,
57
+ [0, 0, 0.36],
58
+ [0.1, -0.6, -3.1],
59
+ 0.12,
60
+ [0, 0, 0.02],
61
+ 2015
62
+ ),
63
+ ITRF90: H(
64
+ [24.5, 8.1, -107.9],
65
+ 4.97,
66
+ [0, 0, 0.36],
67
+ [0.1, -0.6, -3.1],
68
+ 0.12,
69
+ [0, 0, 0.02],
70
+ 2015
71
+ ),
72
+ ITRF89: H(
73
+ [29.5, 32.1, -145.9],
74
+ 8.37,
75
+ [0, 0, 0.36],
76
+ [0.1, -0.6, -3.1],
77
+ 0.12,
78
+ [0, 0, 0.02],
79
+ 2015
80
+ ),
81
+ ITRF88: H(
82
+ [24.5, -3.9, -169.9],
83
+ 11.47,
84
+ [0.1, 0, 0.36],
85
+ [0.1, -0.6, -3.1],
86
+ 0.12,
87
+ [0, 0, 0.02],
88
+ 2015
89
+ ),
90
+ /** ITRF2020 → ETRF2020, EPSG:10572 (epoch-1989 variant) */
91
+ ETRF2020: H(Z, 0, Z, Z, 0, [0.086, 0.519, -0.753], 1989)
92
+ };
93
+ var ITRF2014_TO_ETRF2014 = H(Z, 0, Z, Z, 0, [0.085, 0.531, -0.77], 1989);
94
+ var ITRF2014_TO_ETRF2000 = H(
95
+ [54.7, 52.2, -74.1],
96
+ 2.12,
97
+ [1.701, 10.29, -16.632],
98
+ [0.1, 0.1, -1.9],
99
+ 0.11,
100
+ [0.081, 0.49, -0.792],
101
+ 2010
102
+ );
103
+ var ITRF2014_TO_NAD83_2011 = H(
104
+ [1005.3, -1909.21, -541.57],
105
+ 0.36891,
106
+ [-26.78138, 0.42027, -10.93206],
107
+ [0.79, -0.6, -1.44],
108
+ -0.07201,
109
+ [-0.06667, 0.75744, 0.05133],
110
+ 2010
111
+ );
112
+ var MAS_TO_RAD = Math.PI / (180 * 3600 * 1e3);
113
+ function applyHelmert(xyz, p, epoch, inverse = false) {
114
+ const dt = epoch - p.epoch;
115
+ const sign = inverse ? -1 : 1;
116
+ const tx = sign * (p.t[0] + p.tDot[0] * dt) / 1e3;
117
+ const ty = sign * (p.t[1] + p.tDot[1] * dt) / 1e3;
118
+ const tz = sign * (p.t[2] + p.tDot[2] * dt) / 1e3;
119
+ const d = sign * (p.d + p.dDot * dt) * 1e-9;
120
+ const rx = sign * (p.r[0] + p.rDot[0] * dt) * MAS_TO_RAD;
121
+ const ry = sign * (p.r[1] + p.rDot[1] * dt) * MAS_TO_RAD;
122
+ const rz = sign * (p.r[2] + p.rDot[2] * dt) * MAS_TO_RAD;
123
+ const [x, y, z] = xyz;
124
+ return [
125
+ x + tx + d * x - rz * y + ry * z,
126
+ y + ty + rz * x + d * y - rx * z,
127
+ z + tz - ry * x + rx * y + d * z
128
+ ];
129
+ }
130
+ var EDGES = [
131
+ ...Object.entries(FROM_ITRF2020).map(([to, p]) => ({
132
+ from: "ITRF2020",
133
+ to,
134
+ p
135
+ })),
136
+ { from: "ITRF2014", to: "ETRF2014", p: ITRF2014_TO_ETRF2014 },
137
+ { from: "ITRF2014", to: "ETRF2000", p: ITRF2014_TO_ETRF2000 },
138
+ { from: "ITRF2014", to: "NAD83(2011)", p: ITRF2014_TO_NAD83_2011 }
139
+ ];
140
+ var REFERENCE_FRAMES = [
141
+ "WGS84",
142
+ "ITRF2020",
143
+ "ITRF2014",
144
+ "ITRF2008",
145
+ "ITRF2005",
146
+ "ITRF2000",
147
+ "ITRF97",
148
+ "ITRF96",
149
+ "ITRF94",
150
+ "ITRF93",
151
+ "ITRF92",
152
+ "ITRF91",
153
+ "ITRF90",
154
+ "ITRF89",
155
+ "ITRF88",
156
+ "ETRF2020",
157
+ "ETRF2014",
158
+ "ETRF2000",
159
+ "NAD83(2011)"
160
+ ];
161
+ function resolveAlias(f) {
162
+ return f === "WGS84" ? "ITRF2020" : f;
163
+ }
164
+ function findPath(from, to) {
165
+ if (from === to) return [];
166
+ const queue = [from];
167
+ const cameFrom = /* @__PURE__ */ new Map();
168
+ const seen = /* @__PURE__ */ new Set([from]);
169
+ while (queue.length > 0) {
170
+ const cur = queue.shift();
171
+ for (const edge of EDGES) {
172
+ let next = null;
173
+ let inverse = false;
174
+ if (edge.from === cur) {
175
+ next = edge.to;
176
+ } else if (edge.to === cur) {
177
+ next = edge.from;
178
+ inverse = true;
179
+ }
180
+ if (next === null || seen.has(next)) continue;
181
+ seen.add(next);
182
+ cameFrom.set(next, { prev: cur, edge, inverse });
183
+ if (next === to) {
184
+ const path = [];
185
+ let node = to;
186
+ while (node !== from) {
187
+ const step = cameFrom.get(node);
188
+ path.unshift({ edge: step.edge, inverse: step.inverse });
189
+ node = step.prev;
190
+ }
191
+ return path;
192
+ }
193
+ queue.push(next);
194
+ }
195
+ }
196
+ return null;
197
+ }
198
+ function transformFrame(xyz, from, to, epoch) {
199
+ const src = resolveAlias(from);
200
+ const dst = resolveAlias(to);
201
+ const path = findPath(src, dst);
202
+ if (!path) {
203
+ throw new Error(`No transformation path from ${from} to ${to}`);
204
+ }
205
+ let out = [xyz[0], xyz[1], xyz[2]];
206
+ for (const { edge, inverse } of path) {
207
+ out = applyHelmert(out, edge.p, epoch, inverse);
208
+ }
209
+ return out;
210
+ }
211
+ function dateToEpoch(date) {
212
+ const year = date.getUTCFullYear();
213
+ const start = Date.UTC(year, 0, 1);
214
+ const end = Date.UTC(year + 1, 0, 1);
215
+ return year + (date.getTime() - start) / (end - start);
216
+ }
217
+ export {
218
+ REFERENCE_FRAMES,
219
+ applyHelmert,
220
+ dateToEpoch,
221
+ transformFrame
222
+ };