gnss-js 1.41.0 → 1.42.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.
@@ -55,6 +55,7 @@ var sowOf = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK;
55
55
  var SUB_GPS_EPHEMERIS = 1;
56
56
  var SUB_ION_UTC = 3;
57
57
  var SUB_GLO_EPHEMERIS = 9;
58
+ var SUB_GAL_EPHEMERIS = 11;
58
59
  var SUB_BDS_EPHEMERIS = 21;
59
60
  function readKepler(view, base) {
60
61
  return {
@@ -147,6 +148,46 @@ function decodeBdsEphemeris(view, base) {
147
148
  ...keplerCommon(r)
148
149
  };
149
150
  }
151
+ function decodeGalEphemeris(view, base) {
152
+ const svid = view.getUint8(base + 5);
153
+ if (svid < 1 || svid > 36) return null;
154
+ const g = (o) => view.getFloat64(base + o, false);
155
+ const week = view.getUint16(base + 7, false);
156
+ const toe = view.getUint32(base + 9, false);
157
+ const tocMs = gpsMs(week, toe);
158
+ return {
159
+ system: "E",
160
+ prn: `E${String(svid).padStart(2, "0")}`,
161
+ toc: sowOf(tocMs),
162
+ tocDate: new Date(tocMs),
163
+ toe,
164
+ week,
165
+ iode: view.getUint16(base + 13, false),
166
+ // IODnav
167
+ af0: g(146),
168
+ af1: g(154),
169
+ af2: g(162),
170
+ crs: g(19),
171
+ deltaN: g(27) * GPS_PI,
172
+ m0: g(35) * GPS_PI,
173
+ cuc: g(43) * GPS_PI,
174
+ e: g(51),
175
+ cus: g(59) * GPS_PI,
176
+ sqrtA: g(67),
177
+ cic: g(75) * GPS_PI,
178
+ omega0: g(83) * GPS_PI,
179
+ cis: g(91) * GPS_PI,
180
+ i0: g(99) * GPS_PI,
181
+ crc: g(107),
182
+ omega: g(115) * GPS_PI,
183
+ omegaDot: g(123) * GPS_PI,
184
+ idot: g(131) * GPS_PI,
185
+ svHealth: 0,
186
+ // Galileo SISA/health word not located; observed sats healthy
187
+ tgd: g(179)
188
+ // BGD E5a/E1 (the RINEX Galileo tgd slot)
189
+ };
190
+ }
150
191
  function decodeGloEphemeris(view, base) {
151
192
  const slot = view.getUint8(base + 5);
152
193
  if (slot < 1 || slot > 24) return null;
@@ -197,6 +238,12 @@ function parseTrimbleNav(data) {
197
238
  if (lastIode.get(eph.prn) === eph.iode) continue;
198
239
  lastIode.set(eph.prn, eph.iode);
199
240
  ephemerides.push(eph);
241
+ } else if (sub === SUB_GAL_EPHEMERIS && f.len >= 183) {
242
+ const eph = decodeGalEphemeris(view, f.start);
243
+ if (!eph) continue;
244
+ if (lastIode.get(eph.prn) === eph.iode) continue;
245
+ lastIode.set(eph.prn, eph.iode);
246
+ ephemerides.push(eph);
200
247
  } else if (sub === SUB_ION_UTC && f.len >= 102) {
201
248
  const p = f.start;
202
249
  const alpha = [];
package/dist/index.cjs CHANGED
@@ -9601,6 +9601,7 @@ var sowOf4 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK10;
9601
9601
  var SUB_GPS_EPHEMERIS = 1;
9602
9602
  var SUB_ION_UTC = 3;
9603
9603
  var SUB_GLO_EPHEMERIS = 9;
9604
+ var SUB_GAL_EPHEMERIS = 11;
9604
9605
  var SUB_BDS_EPHEMERIS = 21;
9605
9606
  function readKepler(view, base) {
9606
9607
  return {
@@ -9693,6 +9694,46 @@ function decodeBdsEphemeris3(view, base) {
9693
9694
  ...keplerCommon(r)
9694
9695
  };
9695
9696
  }
9697
+ function decodeGalEphemeris2(view, base) {
9698
+ const svid = view.getUint8(base + 5);
9699
+ if (svid < 1 || svid > 36) return null;
9700
+ const g = (o) => view.getFloat64(base + o, false);
9701
+ const week = view.getUint16(base + 7, false);
9702
+ const toe = view.getUint32(base + 9, false);
9703
+ const tocMs = gpsMs3(week, toe);
9704
+ return {
9705
+ system: "E",
9706
+ prn: `E${String(svid).padStart(2, "0")}`,
9707
+ toc: sowOf4(tocMs),
9708
+ tocDate: new Date(tocMs),
9709
+ toe,
9710
+ week,
9711
+ iode: view.getUint16(base + 13, false),
9712
+ // IODnav
9713
+ af0: g(146),
9714
+ af1: g(154),
9715
+ af2: g(162),
9716
+ crs: g(19),
9717
+ deltaN: g(27) * GPS_PI2,
9718
+ m0: g(35) * GPS_PI2,
9719
+ cuc: g(43) * GPS_PI2,
9720
+ e: g(51),
9721
+ cus: g(59) * GPS_PI2,
9722
+ sqrtA: g(67),
9723
+ cic: g(75) * GPS_PI2,
9724
+ omega0: g(83) * GPS_PI2,
9725
+ cis: g(91) * GPS_PI2,
9726
+ i0: g(99) * GPS_PI2,
9727
+ crc: g(107),
9728
+ omega: g(115) * GPS_PI2,
9729
+ omegaDot: g(123) * GPS_PI2,
9730
+ idot: g(131) * GPS_PI2,
9731
+ svHealth: 0,
9732
+ // Galileo SISA/health word not located; observed sats healthy
9733
+ tgd: g(179)
9734
+ // BGD E5a/E1 (the RINEX Galileo tgd slot)
9735
+ };
9736
+ }
9696
9737
  function decodeGloEphemeris2(view, base) {
9697
9738
  const slot = view.getUint8(base + 5);
9698
9739
  if (slot < 1 || slot > 24) return null;
@@ -9743,6 +9784,12 @@ function parseTrimbleNav(data) {
9743
9784
  if (lastIode.get(eph.prn) === eph.iode) continue;
9744
9785
  lastIode.set(eph.prn, eph.iode);
9745
9786
  ephemerides.push(eph);
9787
+ } else if (sub === SUB_GAL_EPHEMERIS && f.len >= 183) {
9788
+ const eph = decodeGalEphemeris2(view, f.start);
9789
+ if (!eph) continue;
9790
+ if (lastIode.get(eph.prn) === eph.iode) continue;
9791
+ lastIode.set(eph.prn, eph.iode);
9792
+ ephemerides.push(eph);
9746
9793
  } else if (sub === SUB_ION_UTC && f.len >= 102) {
9747
9794
  const p = f.start;
9748
9795
  const alpha = [];
package/dist/index.js CHANGED
@@ -79,7 +79,7 @@ import {
79
79
  parseTrimble,
80
80
  parseTrimbleNav,
81
81
  trimbleFrames
82
- } from "./chunk-EPATQ3LT.js";
82
+ } from "./chunk-4ER3NBP3.js";
83
83
  import {
84
84
  binexCrc16,
85
85
  binexCrc32,
package/dist/trimble.cjs CHANGED
@@ -166,6 +166,7 @@ var sowOf = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK;
166
166
  var SUB_GPS_EPHEMERIS = 1;
167
167
  var SUB_ION_UTC = 3;
168
168
  var SUB_GLO_EPHEMERIS = 9;
169
+ var SUB_GAL_EPHEMERIS = 11;
169
170
  var SUB_BDS_EPHEMERIS = 21;
170
171
  function readKepler(view, base) {
171
172
  return {
@@ -258,6 +259,46 @@ function decodeBdsEphemeris(view, base) {
258
259
  ...keplerCommon(r)
259
260
  };
260
261
  }
262
+ function decodeGalEphemeris(view, base) {
263
+ const svid = view.getUint8(base + 5);
264
+ if (svid < 1 || svid > 36) return null;
265
+ const g = (o) => view.getFloat64(base + o, false);
266
+ const week = view.getUint16(base + 7, false);
267
+ const toe = view.getUint32(base + 9, false);
268
+ const tocMs = gpsMs(week, toe);
269
+ return {
270
+ system: "E",
271
+ prn: `E${String(svid).padStart(2, "0")}`,
272
+ toc: sowOf(tocMs),
273
+ tocDate: new Date(tocMs),
274
+ toe,
275
+ week,
276
+ iode: view.getUint16(base + 13, false),
277
+ // IODnav
278
+ af0: g(146),
279
+ af1: g(154),
280
+ af2: g(162),
281
+ crs: g(19),
282
+ deltaN: g(27) * GPS_PI,
283
+ m0: g(35) * GPS_PI,
284
+ cuc: g(43) * GPS_PI,
285
+ e: g(51),
286
+ cus: g(59) * GPS_PI,
287
+ sqrtA: g(67),
288
+ cic: g(75) * GPS_PI,
289
+ omega0: g(83) * GPS_PI,
290
+ cis: g(91) * GPS_PI,
291
+ i0: g(99) * GPS_PI,
292
+ crc: g(107),
293
+ omega: g(115) * GPS_PI,
294
+ omegaDot: g(123) * GPS_PI,
295
+ idot: g(131) * GPS_PI,
296
+ svHealth: 0,
297
+ // Galileo SISA/health word not located; observed sats healthy
298
+ tgd: g(179)
299
+ // BGD E5a/E1 (the RINEX Galileo tgd slot)
300
+ };
301
+ }
261
302
  function decodeGloEphemeris(view, base) {
262
303
  const slot = view.getUint8(base + 5);
263
304
  if (slot < 1 || slot > 24) return null;
@@ -308,6 +349,12 @@ function parseTrimbleNav(data) {
308
349
  if (lastIode.get(eph.prn) === eph.iode) continue;
309
350
  lastIode.set(eph.prn, eph.iode);
310
351
  ephemerides.push(eph);
352
+ } else if (sub === SUB_GAL_EPHEMERIS && f.len >= 183) {
353
+ const eph = decodeGalEphemeris(view, f.start);
354
+ if (!eph) continue;
355
+ if (lastIode.get(eph.prn) === eph.iode) continue;
356
+ lastIode.set(eph.prn, eph.iode);
357
+ ephemerides.push(eph);
311
358
  } else if (sub === SUB_ION_UTC && f.len >= 102) {
312
359
  const p = f.start;
313
360
  const alpha = [];
@@ -25,8 +25,9 @@ declare function trimbleFrames(data: Uint8Array, stats: {
25
25
 
26
26
  /**
27
27
  * Trimble RT17/RT27 navigation-message decoding: RETSVDATA (0x55)
28
- * GPS ephemeris (subtype 1), GLONASS ephemeris (subtype 9), BeiDou
29
- * ephemeris (subtype 21) and ION / UTC data (subtype 3).
28
+ * GPS ephemeris (subtype 1), GLONASS ephemeris (subtype 9), Galileo
29
+ * ephemeris (subtype 11), BeiDou ephemeris (subtype 21) and ION / UTC
30
+ * data (subtype 3).
30
31
  *
31
32
  * The GPS path is ported field-for-field from RTKLIB's `src/rcv/rt17.c`
32
33
  * (`decode_gps_ephemeris` / `decode_ion_utc_data`, tomojitakasu/RTKLIB,
@@ -46,8 +47,8 @@ declare function trimbleFrames(data: Uint8Array, stats: {
46
47
  * RETSVDATA table (st[]: 1 = GPS Eph, 9 = GLONASS Eph, 11 = Galileo Eph,
47
48
  * 21 = BeiDou Eph) — but RTKLIB only *decodes* subtypes 1 and 3, so the
48
49
  * GLONASS/BeiDou field layouts here were reverse-engineered and validated
49
- * against physics + the 2026-07-27 BRDC. Still not decoded: Galileo
50
- * (subtype 11) and the QZSS/almanac subtypes (13/23/27 on this stream).
50
+ * against physics + the 2026-07-27 BRDC. Still not decoded: the
51
+ * QZSS / almanac subtypes (13/23/27 on this stream).
51
52
  */
52
53
 
53
54
  interface TrimbleNavResult {
package/dist/trimble.d.ts CHANGED
@@ -25,8 +25,9 @@ declare function trimbleFrames(data: Uint8Array, stats: {
25
25
 
26
26
  /**
27
27
  * Trimble RT17/RT27 navigation-message decoding: RETSVDATA (0x55)
28
- * GPS ephemeris (subtype 1), GLONASS ephemeris (subtype 9), BeiDou
29
- * ephemeris (subtype 21) and ION / UTC data (subtype 3).
28
+ * GPS ephemeris (subtype 1), GLONASS ephemeris (subtype 9), Galileo
29
+ * ephemeris (subtype 11), BeiDou ephemeris (subtype 21) and ION / UTC
30
+ * data (subtype 3).
30
31
  *
31
32
  * The GPS path is ported field-for-field from RTKLIB's `src/rcv/rt17.c`
32
33
  * (`decode_gps_ephemeris` / `decode_ion_utc_data`, tomojitakasu/RTKLIB,
@@ -46,8 +47,8 @@ declare function trimbleFrames(data: Uint8Array, stats: {
46
47
  * RETSVDATA table (st[]: 1 = GPS Eph, 9 = GLONASS Eph, 11 = Galileo Eph,
47
48
  * 21 = BeiDou Eph) — but RTKLIB only *decodes* subtypes 1 and 3, so the
48
49
  * GLONASS/BeiDou field layouts here were reverse-engineered and validated
49
- * against physics + the 2026-07-27 BRDC. Still not decoded: Galileo
50
- * (subtype 11) and the QZSS/almanac subtypes (13/23/27 on this stream).
50
+ * against physics + the 2026-07-27 BRDC. Still not decoded: the
51
+ * QZSS / almanac subtypes (13/23/27 on this stream).
51
52
  */
52
53
 
53
54
  interface TrimbleNavResult {
package/dist/trimble.js CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  parseTrimble,
3
3
  parseTrimbleNav,
4
4
  trimbleFrames
5
- } from "./chunk-EPATQ3LT.js";
5
+ } from "./chunk-4ER3NBP3.js";
6
6
  import "./chunk-HVXYFUCB.js";
7
7
  import "./chunk-LEEU5OIO.js";
8
8
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gnss-js",
3
- "version": "1.41.0",
3
+ "version": "1.42.0",
4
4
  "description": "Comprehensive GNSS library for JavaScript — time scales, coordinates, RINEX parsing, RTCM3 decoding, orbit computation, and signal analysis",
5
5
  "type": "module",
6
6
  "sideEffects": false,