gnss-js 1.51.0 → 1.53.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.
package/dist/index.cjs CHANGED
@@ -269,6 +269,7 @@ __export(src_exports, {
269
269
  parseSbfIonoUtc: () => parseSbfIonoUtc,
270
270
  parseSbfMeas: () => parseSbfMeas,
271
271
  parseSbfNav: () => parseSbfNav,
272
+ parseSbfPvt: () => parseSbfPvt,
272
273
  parseSbfReceiverSetup: () => parseSbfReceiverSetup,
273
274
  parseSinexBiasDcb: () => parseSinexBiasDcb,
274
275
  parseSourcetable: () => parseSourcetable,
@@ -294,6 +295,7 @@ __export(src_exports, {
294
295
  rhumbLine: () => rhumbLine,
295
296
  rtcm3Constellation: () => rtcm3Constellation,
296
297
  satClockCorrection: () => satClockCorrection,
298
+ sbasProtectionLevels: () => sbasProtectionLevels,
297
299
  sbfCrc16: () => crc16,
298
300
  scanSbfFrames: () => scanSbfFrames,
299
301
  selectEphemeris: () => selectEphemeris,
@@ -7508,6 +7510,58 @@ function parseSbfReceiverSetup(data) {
7508
7510
  return out;
7509
7511
  }
7510
7512
 
7513
+ // src/sbf/pvt.ts
7514
+ var GPS_EPOCH_MS11 = Date.UTC(1980, 0, 6);
7515
+ var RAD2DEG = 180 / Math.PI;
7516
+ var DNU_F8 = -2e10;
7517
+ var MODE_LABELS = {
7518
+ 0: "no-pvt",
7519
+ 1: "standalone",
7520
+ 2: "differential",
7521
+ 3: "fixed-location",
7522
+ 4: "rtk-fixed",
7523
+ 5: "rtk-float",
7524
+ 6: "sbas-aided",
7525
+ 7: "moving-base-rtk-fixed",
7526
+ 8: "moving-base-rtk-float",
7527
+ 10: "ppp"
7528
+ };
7529
+ function parseSbfPvt(data) {
7530
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
7531
+ const records = [];
7532
+ let messages = 0;
7533
+ scanSbfFrames(data, view, (id, b, len) => {
7534
+ if (id !== 4007 || len < 96) return;
7535
+ messages++;
7536
+ const tow = view.getUint32(b + 8, true);
7537
+ const wnc = view.getUint16(b + 12, true);
7538
+ if (tow === 4294967295 || wnc === 65535) return;
7539
+ const modeByte = view.getUint8(b + 14);
7540
+ const modeType = modeByte & 15;
7541
+ const lat = view.getFloat64(b + 16, true);
7542
+ const lon = view.getFloat64(b + 24, true);
7543
+ const hgt = view.getFloat64(b + 32, true);
7544
+ const nrSV = view.getUint8(b + 74);
7545
+ const hAcc = view.getUint16(b + 90, true);
7546
+ const vAcc = view.getUint16(b + 92, true);
7547
+ const hasFix = lat > DNU_F8 && lon > DNU_F8 && hgt > DNU_F8;
7548
+ records.push({
7549
+ timeMs: GPS_EPOCH_MS11 + wnc * 6048e5 + tow,
7550
+ week: wnc,
7551
+ tow: tow / 1e3,
7552
+ modeType,
7553
+ mode: MODE_LABELS[modeType] ?? `mode-${modeType}`,
7554
+ latDeg: hasFix ? lat * RAD2DEG : null,
7555
+ lonDeg: hasFix ? lon * RAD2DEG : null,
7556
+ heightM: hasFix ? hgt : null,
7557
+ nrSV: nrSV === 255 ? null : nrSV,
7558
+ hAccuracyM: hAcc === 65535 ? null : hAcc / 100,
7559
+ vAccuracyM: vAcc === 65535 ? null : vAcc / 100
7560
+ });
7561
+ });
7562
+ return { records, messages };
7563
+ }
7564
+
7511
7565
  // src/sbf/rawnav-gps.ts
7512
7566
  var WNC_DNU = 65535;
7513
7567
  function extractSbfLnavSubframe(view, b) {
@@ -7643,7 +7697,7 @@ function isFnavDummy(page) {
7643
7697
  }
7644
7698
 
7645
7699
  // src/sbf/rawnav-bds.ts
7646
- var GPS_EPOCH_MS11 = Date.UTC(1980, 0, 6);
7700
+ var GPS_EPOCH_MS12 = Date.UTC(1980, 0, 6);
7647
7701
  var MS_PER_WEEK6 = 7 * 86400 * 1e3;
7648
7702
  var TOW_DNU = 4294967295;
7649
7703
  var WNC_DNU2 = 65535;
@@ -7704,7 +7758,7 @@ function feedGloBlock(view, b, assembler) {
7704
7758
  const eph = assembler.push(
7705
7759
  prn,
7706
7760
  str2,
7707
- new Date(GPS_EPOCH_MS11 + wnc * MS_PER_WEEK6 + towMs),
7761
+ new Date(GPS_EPOCH_MS12 + wnc * MS_PER_WEEK6 + towMs),
7708
7762
  view.getUint8(b + 18) - 8
7709
7763
  // FreqNr, offset by 8
7710
7764
  );
@@ -8454,7 +8508,7 @@ function parseSbfHas(data) {
8454
8508
 
8455
8509
  // src/sbf/index.ts
8456
8510
  var CLIGHT = 299792458;
8457
- var GPS_EPOCH_MS12 = Date.UTC(1980, 0, 6);
8511
+ var GPS_EPOCH_MS13 = Date.UTC(1980, 0, 6);
8458
8512
  var MS_PER_WEEK7 = 7 * 864e5;
8459
8513
  var M3_SYS = ["G", "R", "E", "C", "S", "J", "I"];
8460
8514
  var M3_PR_BASE = [19e6, 19e6, 22e6, 2e7, 34e6, 34e6, 34e6];
@@ -9108,7 +9162,7 @@ function parseSbfMeas(data) {
9108
9162
  const tow = view.getUint32(i + 8, true);
9109
9163
  const wnc = view.getUint16(i + 12, true);
9110
9164
  if (tow !== 4294967295 && wnc !== 65535) {
9111
- ensureEpoch(GPS_EPOCH_MS12 + wnc * MS_PER_WEEK7 + tow);
9165
+ ensureEpoch(GPS_EPOCH_MS13 + wnc * MS_PER_WEEK7 + tow);
9112
9166
  if (id === 4109) decodeMeas3Ranges(i, tow);
9113
9167
  else if (id === 4110) decodeMeas3CN0(i, len);
9114
9168
  else if (id === 4111) decodeMeas3Doppler(i, len);
@@ -9175,15 +9229,15 @@ var ID_GPSEPHEM = 7;
9175
9229
  var ID_BDSEPHEMERIS = 1696;
9176
9230
  var ID_RAWWAASFRAME = 287;
9177
9231
  var ID_RAWSBASFRAME = 973;
9178
- var GPS_EPOCH_MS13 = Date.UTC(1980, 0, 6);
9232
+ var GPS_EPOCH_MS14 = Date.UTC(1980, 0, 6);
9179
9233
  var BDT_EPOCH_MS3 = Date.UTC(2006, 0, 1);
9180
9234
  var SEC_PER_WEEK9 = 7 * 86400;
9181
9235
  var SEC_PER_DAY2 = 86400;
9182
9236
  var MS_PER_WEEK8 = SEC_PER_WEEK9 * 1e3;
9183
- var gpsMs2 = (week, sec) => GPS_EPOCH_MS13 + week * MS_PER_WEEK8 + sec * 1e3;
9237
+ var gpsMs2 = (week, sec) => GPS_EPOCH_MS14 + week * MS_PER_WEEK8 + sec * 1e3;
9184
9238
  var sowOf3 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK9;
9185
9239
  function nearWeekMs(refMs, sow) {
9186
- const refWeek = Math.floor((refMs - GPS_EPOCH_MS13) / MS_PER_WEEK8);
9240
+ const refWeek = Math.floor((refMs - GPS_EPOCH_MS14) / MS_PER_WEEK8);
9187
9241
  let ms = gpsMs2(refWeek, sow);
9188
9242
  if (ms < refMs - MS_PER_WEEK8 / 2) ms += MS_PER_WEEK8;
9189
9243
  else if (ms > refMs + MS_PER_WEEK8 / 2) ms -= MS_PER_WEEK8;
@@ -9210,9 +9264,9 @@ function decodeGloEphemeris(view, p) {
9210
9264
  tof += Math.floor(tow / SEC_PER_DAY2) * SEC_PER_DAY2;
9211
9265
  if (tof < tow - 43200) tof += SEC_PER_DAY2;
9212
9266
  else if (tof > tow + 43200) tof -= SEC_PER_DAY2;
9213
- const toeGpsMs = GPS_EPOCH_MS13 + (week * SEC_PER_WEEK9 + tow) * 1e3;
9214
- const tofGpsMs = GPS_EPOCH_MS13 + (week * SEC_PER_WEEK9 + tof) * 1e3;
9215
- const tofUtcSec = (getUtcDate(new Date(tofGpsMs)).getTime() - GPS_EPOCH_MS13) / 1e3;
9267
+ const toeGpsMs = GPS_EPOCH_MS14 + (week * SEC_PER_WEEK9 + tow) * 1e3;
9268
+ const tofGpsMs = GPS_EPOCH_MS14 + (week * SEC_PER_WEEK9 + tof) * 1e3;
9269
+ const tofUtcSec = (getUtcDate(new Date(tofGpsMs)).getTime() - GPS_EPOCH_MS14) / 1e3;
9216
9270
  return {
9217
9271
  system: "R",
9218
9272
  prn: `R${String(slot).padStart(2, "0")}`,
@@ -9277,7 +9331,7 @@ function decodeGalEphemeris(view, p, headerMs) {
9277
9331
  omega: view.getFloat64(p + 60, true),
9278
9332
  omegaDot: view.getFloat64(p + 140, true),
9279
9333
  idot: view.getFloat64(p + 124, true),
9280
- week: Math.floor((toeMs - GPS_EPOCH_MS13) / MS_PER_WEEK8),
9334
+ week: Math.floor((toeMs - GPS_EPOCH_MS14) / MS_PER_WEEK8),
9281
9335
  // RINEX Galileo SVH bit layout (E1B DVS/HS in bits 0-2, E5a in
9282
9336
  // 3-5, E5b in 6-8) — same packing as RTKLIB.
9283
9337
  svHealth: svhE5b << 7 | dvsE5b << 6 | svhE5a << 4 | dvsE5a << 3 | svhE1b << 1 | dvsE1b,
@@ -9464,7 +9518,7 @@ function parseNovatelNav(data, opts = {}) {
9464
9518
  }
9465
9519
 
9466
9520
  // src/novatel/index.ts
9467
- var GPS_EPOCH_MS14 = Date.UTC(1980, 0, 6);
9521
+ var GPS_EPOCH_MS15 = Date.UTC(1980, 0, 6);
9468
9522
  var MS_PER_WEEK9 = 7 * 864e5;
9469
9523
  var HDR = 28;
9470
9524
  var ID_RANGE = 43;
@@ -9634,7 +9688,7 @@ function parseNovatelRange(data) {
9634
9688
  if (!codes.includes(code)) codes.push(code);
9635
9689
  }
9636
9690
  epochs.push({
9637
- timeMs: GPS_EPOCH_MS14 + week * MS_PER_WEEK9 + towMs,
9691
+ timeMs: GPS_EPOCH_MS15 + week * MS_PER_WEEK9 + towMs,
9638
9692
  meas
9639
9693
  });
9640
9694
  }
@@ -9686,7 +9740,7 @@ function parseNovatelRange(data) {
9686
9740
  if (!codes.includes(code)) codes.push(code);
9687
9741
  }
9688
9742
  epochs.push({
9689
- timeMs: GPS_EPOCH_MS14 + week * MS_PER_WEEK9 + towMs,
9743
+ timeMs: GPS_EPOCH_MS15 + week * MS_PER_WEEK9 + towMs,
9690
9744
  meas
9691
9745
  });
9692
9746
  }
@@ -9737,14 +9791,14 @@ function* trimbleFrames(data, stats) {
9737
9791
  }
9738
9792
 
9739
9793
  // src/trimble/nav.ts
9740
- var GPS_EPOCH_MS15 = Date.UTC(1980, 0, 6);
9794
+ var GPS_EPOCH_MS16 = Date.UTC(1980, 0, 6);
9741
9795
  var BDT_EPOCH_MS4 = Date.UTC(2006, 0, 1);
9742
9796
  var SEC_PER_WEEK10 = 7 * 86400;
9743
9797
  var MS_PER_WEEK10 = SEC_PER_WEEK10 * 1e3;
9744
9798
  var GPS_PI2 = 3.1415926535898;
9745
9799
  var BDS_WEEK_OFFSET = 1356;
9746
9800
  var BDS_LEAP_SEC = 14;
9747
- var gpsMs3 = (week, sec) => GPS_EPOCH_MS15 + week * MS_PER_WEEK10 + sec * 1e3;
9801
+ var gpsMs3 = (week, sec) => GPS_EPOCH_MS16 + week * MS_PER_WEEK10 + sec * 1e3;
9748
9802
  var sowOf4 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK10;
9749
9803
  var SUB_GPS_EPHEMERIS = 1;
9750
9804
  var SUB_ION_UTC = 3;
@@ -9897,7 +9951,7 @@ function decodeGloEphemeris2(view, base) {
9897
9951
  // RINEX stores −τn as the clock bias; the record carries τn (ICD sign).
9898
9952
  tauN: -view.getFloat64(base + 113, false),
9899
9953
  gammaN: view.getFloat64(base + 121, false),
9900
- messageFrameTime: (tocMs - GPS_EPOCH_MS15) / 1e3 % SEC_PER_WEEK10,
9954
+ messageFrameTime: (tocMs - GPS_EPOCH_MS16) / 1e3 % SEC_PER_WEEK10,
9901
9955
  // State vector: metres / m·s⁻¹ / m·s⁻² → km / km·s⁻¹ / km·s⁻².
9902
9956
  x: view.getFloat64(base + 33, false) / 1e3,
9903
9957
  xDot: view.getFloat64(base + 41, false) / 1e3,
@@ -9968,7 +10022,7 @@ function parseTrimbleNav(data) {
9968
10022
  }
9969
10023
 
9970
10024
  // src/trimble/index.ts
9971
- var GPS_EPOCH_MS16 = Date.UTC(1980, 0, 6);
10025
+ var GPS_EPOCH_MS17 = Date.UTC(1980, 0, 6);
9972
10026
  var MS_PER_WEEK11 = 7 * 864e5;
9973
10027
  var REC_TYPE_27 = 6;
9974
10028
  var SYS = {
@@ -10166,7 +10220,7 @@ function decodeEpoch(epoch, epochs, obsCodes) {
10166
10220
  o += c.length;
10167
10221
  }
10168
10222
  const dv = new DataView(M.buffer, M.byteOffset, M.byteLength);
10169
- const timeMs = GPS_EPOCH_MS16 + epoch.week * MS_PER_WEEK11 + epoch.towMs;
10223
+ const timeMs = GPS_EPOCH_MS17 + epoch.week * MS_PER_WEEK11 + epoch.towMs;
10170
10224
  const meas = [];
10171
10225
  let q = 0;
10172
10226
  for (let sv = 0; sv < epoch.nsv && q + 8 <= M.length; sv++) {
@@ -10347,13 +10401,13 @@ function* binexRecords(data, view, stats) {
10347
10401
  }
10348
10402
 
10349
10403
  // src/binex/nav.ts
10350
- var GPS_EPOCH_MS17 = Date.UTC(1980, 0, 6);
10404
+ var GPS_EPOCH_MS18 = Date.UTC(1980, 0, 6);
10351
10405
  var GLO_DAY0_MS = Date.UTC(1980, 0, 1);
10352
10406
  var BDT_EPOCH_MS5 = Date.UTC(2006, 0, 1);
10353
10407
  var SEC_PER_WEEK11 = 7 * 86400;
10354
10408
  var MS_PER_WEEK12 = SEC_PER_WEEK11 * 1e3;
10355
10409
  var SC2RAD = GPS_PI;
10356
- var gpsMs4 = (week, sec) => GPS_EPOCH_MS17 + week * MS_PER_WEEK12 + sec * 1e3;
10410
+ var gpsMs4 = (week, sec) => GPS_EPOCH_MS18 + week * MS_PER_WEEK12 + sec * 1e3;
10357
10411
  var sowOf5 = (dateMs) => (dateMs / 1e3 % SEC_PER_WEEK11 + SEC_PER_WEEK11) % SEC_PER_WEEK11;
10358
10412
  var two6 = (n) => String(n).padStart(2, "0");
10359
10413
  var Reader = class {
@@ -10641,7 +10695,7 @@ function decodeBinexEph(view, body, len, le) {
10641
10695
  }
10642
10696
 
10643
10697
  // src/binex/index.ts
10644
- var GPS_EPOCH_MS18 = Date.UTC(1980, 0, 6);
10698
+ var GPS_EPOCH_MS19 = Date.UTC(1980, 0, 6);
10645
10699
  var CLIGHT2 = 299792458;
10646
10700
  var OBS_CODES = {
10647
10701
  0: [
@@ -10899,7 +10953,7 @@ function decodeObsRecord(data, view, body, len, obsCodes) {
10899
10953
  p += 4;
10900
10954
  const msec = view.getUint16(p);
10901
10955
  p += 2;
10902
- const timeMs = GPS_EPOCH_MS18 + min * 6e4 + msec;
10956
+ const timeMs = GPS_EPOCH_MS19 + min * 6e4 + msec;
10903
10957
  const flag = data[p++];
10904
10958
  const nsat = (flag & 63) + 1;
10905
10959
  if (flag & 128) p += 3;
@@ -10985,7 +11039,7 @@ function parseBinex(data) {
10985
11039
  var GM_GPS = 3986005e8;
10986
11040
  var GM_GAL = 3986004418e5;
10987
11041
  var GM_BDS = 3986004418e5;
10988
- var GPS_EPOCH_MS19 = Date.UTC(1980, 0, 6);
11042
+ var GPS_EPOCH_MS20 = Date.UTC(1980, 0, 6);
10989
11043
  var BDT_EPOCH_MS6 = Date.UTC(2006, 0, 1);
10990
11044
  var WEEK_MS = 6048e5;
10991
11045
  var BDT_MINUS_GPST_MS = 14e3;
@@ -10994,7 +11048,7 @@ function almanacEpochMs(alm) {
10994
11048
  if (alm.system === "C") {
10995
11049
  return BDT_EPOCH_MS6 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3 + BDT_MINUS_GPST_MS;
10996
11050
  }
10997
- return GPS_EPOCH_MS19 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3;
11051
+ return GPS_EPOCH_MS20 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3;
10998
11052
  }
10999
11053
  function almanacSatPosition(alm, timeMs) {
11000
11054
  const GM = alm.system === "E" ? GM_GAL : alm.system === "C" ? GM_BDS : GM_GPS;
@@ -11503,10 +11557,10 @@ function selectBest(ephs, timeMs) {
11503
11557
  }
11504
11558
  return best;
11505
11559
  }
11506
- var GPS_EPOCH_MS20 = START_GPS_TIME.getTime();
11560
+ var GPS_EPOCH_MS21 = START_GPS_TIME.getTime();
11507
11561
  var MS_PER_WEEK13 = 7 * 864e5;
11508
11562
  var BDS_EPOCH_MS = START_BDS_TIME.getTime();
11509
- var GAL_EPOCH_MS = GPS_EPOCH_MS20 + 1024 * MS_PER_WEEK13;
11563
+ var GAL_EPOCH_MS = GPS_EPOCH_MS21 + 1024 * MS_PER_WEEK13;
11510
11564
  function ephInfoToEphemeris(info) {
11511
11565
  const sys = info.prn.charAt(0);
11512
11566
  if (sys === "R") {
@@ -11557,8 +11611,8 @@ function ephInfoToEphemeris(info) {
11557
11611
  } else if (sys === "E") {
11558
11612
  epochMs = GAL_EPOCH_MS;
11559
11613
  } else {
11560
- epochMs = GPS_EPOCH_MS20;
11561
- const weeksNow = (info.lastReceived - GPS_EPOCH_MS20) / MS_PER_WEEK13;
11614
+ epochMs = GPS_EPOCH_MS21;
11615
+ const weeksNow = (info.lastReceived - GPS_EPOCH_MS21) / MS_PER_WEEK13;
11562
11616
  week += 1024 * Math.round((weeksNow - week) / 1024);
11563
11617
  }
11564
11618
  const tocDate = new Date(epochMs + week * MS_PER_WEEK13 + tocSec * 1e3);
@@ -14978,6 +15032,65 @@ function sagnac2(pos, travelTimeS) {
14978
15032
  const s = Math.sin(theta);
14979
15033
  return [pos.x * c + pos.y * s, -pos.x * s + pos.y * c, pos.z];
14980
15034
  }
15035
+ function sbasAirTropoVar(elRad) {
15036
+ const elDeg = elRad * 180 / Math.PI;
15037
+ const sigMp = 0.13 + 0.53 * Math.exp(-elDeg / 10);
15038
+ const sigNoise = 0.15 + 0.43 * Math.exp(-elDeg / 6.9);
15039
+ const m = 1.001 / Math.sqrt(2001e-6 + Math.sin(elRad) * Math.sin(elRad));
15040
+ const sigTropo = 0.12 * m;
15041
+ return sigMp * sigMp + sigNoise * sigNoise + sigTropo * sigTropo;
15042
+ }
15043
+ function invertMatrix(A) {
15044
+ const n = A.length;
15045
+ const M = A.map((row, i) => [
15046
+ ...row,
15047
+ ...Array.from({ length: n }, (_, j) => i === j ? 1 : 0)
15048
+ ]);
15049
+ for (let col = 0; col < n; col++) {
15050
+ let piv = col;
15051
+ for (let r = col + 1; r < n; r++)
15052
+ if (Math.abs(M[r][col]) > Math.abs(M[piv][col])) piv = r;
15053
+ if (Math.abs(M[piv][col]) < 1e-12) return null;
15054
+ [M[col], M[piv]] = [M[piv], M[col]];
15055
+ const d = M[col][col];
15056
+ for (let j = 0; j < 2 * n; j++) M[col][j] /= d;
15057
+ for (let r = 0; r < n; r++) {
15058
+ if (r === col) continue;
15059
+ const f = M[r][col];
15060
+ for (let j = 0; j < 2 * n; j++) M[r][j] -= f * M[col][j];
15061
+ }
15062
+ }
15063
+ return M.map((row) => row.slice(n));
15064
+ }
15065
+ function sbasProtectionLevels(sats, opts = {}) {
15066
+ const kH = opts.kH ?? 6;
15067
+ const kV = opts.kV ?? 5.33;
15068
+ if (sats.length < 4) return null;
15069
+ const N = [0, 1, 2, 3].map(() => [0, 0, 0, 0]);
15070
+ for (const s of sats) {
15071
+ if (!(s.variance > 0)) continue;
15072
+ const ce = Math.cos(s.elRad);
15073
+ const g = [
15074
+ ce * Math.sin(s.azRad),
15075
+ ce * Math.cos(s.azRad),
15076
+ Math.sin(s.elRad),
15077
+ 1
15078
+ ];
15079
+ const w = 1 / s.variance;
15080
+ for (let i = 0; i < 4; i++)
15081
+ for (let j = 0; j < 4; j++) N[i][j] += w * g[i] * g[j];
15082
+ }
15083
+ const cov = invertMatrix(N);
15084
+ if (!cov) return null;
15085
+ const dE2 = cov[0][0];
15086
+ const dN2 = cov[1][1];
15087
+ const dEN = cov[0][1];
15088
+ const dU = Math.sqrt(Math.max(cov[2][2], 0));
15089
+ const dMajor = Math.sqrt(
15090
+ (dE2 + dN2) / 2 + Math.sqrt(((dE2 - dN2) / 2) ** 2 + dEN * dEN)
15091
+ );
15092
+ return { hpl: kH * dMajor, vpl: kV * dU, dMajor, dU };
15093
+ }
14981
15094
  function solveLinear(A, b) {
14982
15095
  const n = b.length;
14983
15096
  const M = A.map((row, i) => [...row, b[i]]);
@@ -15034,7 +15147,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
15034
15147
  const sysRows = new Map(systems.map((s) => [s, 0]));
15035
15148
  for (const k of Object.keys(residuals2)) delete residuals2[k];
15036
15149
  const positionSaneIter = x9 * x9 + y2 * y2 + z2 * z2 > 1e12;
15037
- const [rxLat, rxLon, rxHgt] = positionSaneIter ? ecefToGeodetic(x9, y2, z2) : [0, 0, 0];
15150
+ const [rxLat2, rxLon2, rxHgt2] = positionSaneIter ? ecefToGeodetic(x9, y2, z2) : [0, 0, 0];
15038
15151
  for (const prn of prns) {
15039
15152
  const psr = pseudoranges.get(prn);
15040
15153
  const eph = ephemerides.get(prn);
@@ -15073,7 +15186,7 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
15073
15186
  const sinEl = Math.max(Math.sin(elev), 0.1);
15074
15187
  weight = sinEl * sinEl;
15075
15188
  }
15076
- const tropo = troposphere && positionSane ? tropoDelay2(elev, rxLat, rxHgt) : 0;
15189
+ const tropo = troposphere && positionSane ? tropoDelay2(elev, rxLat2, rxHgt2) : 0;
15077
15190
  let ionoM = 0;
15078
15191
  if ((sbas || gim || iono) && positionSane) {
15079
15192
  let l1M = null;
@@ -15081,18 +15194,18 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
15081
15194
  const si = sbas.ionoDelay(
15082
15195
  gpsWeek,
15083
15196
  gpsTow,
15084
- rxLat,
15085
- rxLon,
15086
- rxHgt,
15197
+ rxLat2,
15198
+ rxLon2,
15199
+ rxHgt2,
15087
15200
  azim,
15088
15201
  elev
15089
15202
  );
15090
15203
  if (si) l1M = si.delayM;
15091
15204
  }
15092
15205
  if (l1M === null && gim)
15093
- l1M = gimSlantIonoDelayL1(gim, rxLat, rxLon, azim, elev, timeMs);
15206
+ l1M = gimSlantIonoDelayL1(gim, rxLat2, rxLon2, azim, elev, timeMs);
15094
15207
  if (l1M === null && iono) {
15095
- l1M = C_LIGHT * klobucharDelay(iono, rxLat, rxLon, azim, elev, gpsTow);
15208
+ l1M = C_LIGHT * klobucharDelay(iono, rxLat2, rxLon2, azim, elev, gpsTow);
15096
15209
  }
15097
15210
  if (l1M !== null) {
15098
15211
  const f = PRIMARY_FREQ_HZ[sys] ?? F_L12;
@@ -15165,6 +15278,8 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
15165
15278
  const { x, y, z, clock, residuals, iterations, converged } = inner;
15166
15279
  const used = [];
15167
15280
  const azels = [];
15281
+ const [rxLat, rxLon, rxHgt] = ecefToGeodetic(x, y, z);
15282
+ const sbasRows = [];
15168
15283
  for (const prn of candidates) {
15169
15284
  if (!(prn in residuals)) continue;
15170
15285
  const eph = ephemerides.get(prn);
@@ -15174,8 +15289,27 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
15174
15289
  if (azel.el >= elevationMaskDeg * Math.PI / 180) {
15175
15290
  used.push(prn);
15176
15291
  azels.push(azel);
15292
+ if (sbas) {
15293
+ const sc = sbas.satCorrection(prn, gpsWeek, gpsTow);
15294
+ const si = sbas.ionoDelay(
15295
+ gpsWeek,
15296
+ gpsTow,
15297
+ rxLat,
15298
+ rxLon,
15299
+ rxHgt,
15300
+ azel.az,
15301
+ azel.el
15302
+ );
15303
+ if (sc && si)
15304
+ sbasRows.push({
15305
+ azRad: azel.az,
15306
+ elRad: azel.el,
15307
+ variance: sc.varM2 + si.varM2 + sbasAirTropoVar(azel.el)
15308
+ });
15309
+ }
15177
15310
  }
15178
15311
  }
15312
+ const pl = sbas ? sbasProtectionLevels(sbasRows) : null;
15179
15313
  return {
15180
15314
  position: [x, y, z],
15181
15315
  clockBias: Object.fromEntries(clock),
@@ -15184,7 +15318,8 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
15184
15318
  residuals,
15185
15319
  dop: computeDop(azels),
15186
15320
  iterations,
15187
- converged
15321
+ converged,
15322
+ ...pl ? { hpl: pl.hpl, vpl: pl.vpl, sbasSats: sbasRows.length } : sbas ? { sbasSats: sbasRows.length } : {}
15188
15323
  };
15189
15324
  }
15190
15325
 
@@ -17697,6 +17832,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
17697
17832
  parseSbfIonoUtc,
17698
17833
  parseSbfMeas,
17699
17834
  parseSbfNav,
17835
+ parseSbfPvt,
17700
17836
  parseSbfReceiverSetup,
17701
17837
  parseSinexBiasDcb,
17702
17838
  parseSourcetable,
@@ -17722,6 +17858,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
17722
17858
  rhumbLine,
17723
17859
  rtcm3Constellation,
17724
17860
  satClockCorrection,
17861
+ sbasProtectionLevels,
17725
17862
  sbfCrc16,
17726
17863
  scanSbfFrames,
17727
17864
  selectEphemeris,
package/dist/index.d.cts CHANGED
@@ -11,13 +11,13 @@ export { C as ClkFile, I as IonexGrid, S as Sp3File, a as Sp3Sample, c as clkBia
11
11
  export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.cjs';
12
12
  export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.cjs';
13
13
  export { UbxCnavResult, UbxFrame, UbxIonoUtcResult, UbxMeasurement, UbxNavOptions, UbxNavResult, UbxParseResult, UbxRawNavOptions, UbxRawNavResult, UbxRawxEpoch, parseUbxCnav, parseUbxIonoUtc, parseUbxNav, parseUbxRawNav, parseUbxRawx, ubxFrames } from './ubx.cjs';
14
- export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGeoNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfReceiverSetup, sbfCrc16, scanSbfFrames } from './sbf.cjs';
14
+ export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGeoNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, SbfPvt, SbfPvtResult, SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfPvt, parseSbfReceiverSetup, sbfCrc16, scanSbfFrames } from './sbf.cjs';
15
15
  export { NovatelEpoch, NovatelMeasurement, NovatelNavResult, NovatelParseResult, OEM4_HLEN, Oem4Frame, crc32, oem4Frames, parseNovatelNav, parseNovatelRange } from './novatel.cjs';
16
16
  export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, TrimbleParseResult, parseTrimble, parseTrimbleNav, trimbleFrames } from './trimble.cjs';
17
17
  export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.cjs';
18
18
  export { AllPositionsData, AlmanacPosition, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, almanacEpochMs, almanacSatPosition, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, computeVisibilityFromPositions, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassAlmanacEpochMs, glonassAlmanacPosition, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.cjs';
19
19
  export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.cjs';
20
- export { AntennaOffset, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, DgnssOptions, DgnssSolution, EphemerisSource, FixedPositionResult, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, NetworkFcbResult, NetworkFcbSummary, NlArc, NlFcbResult, PppAntennaModel, PppArc, PppCorrectionConfig, PppCorrections, PppEpoch, PppEpochContext, PppEpochResult, PppFixState, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, RtkObsEpoch, RtkObsInput, RtkPostProcessOptions, RtkPostProcessResult, RtkTrackPoint, SatGeom, SbasCorrectionSource, SbasIonoDelay, SbasProcessor, SbasSatCorrection, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, buildPppAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.cjs';
20
+ export { AntennaOffset, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, DgnssOptions, DgnssSolution, EphemerisSource, FixedPositionResult, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, NetworkFcbResult, NetworkFcbSummary, NlArc, NlFcbResult, PppAntennaModel, PppArc, PppCorrectionConfig, PppCorrections, PppEpoch, PppEpochContext, PppEpochResult, PppFixState, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, RtkObsEpoch, RtkObsInput, RtkPostProcessOptions, RtkPostProcessResult, RtkTrackPoint, SatGeom, SbasCorrectionSource, SbasIonoDelay, SbasProcessor, SbasSatCorrection, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, buildPppAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, resolvePppAmbiguities, satClockCorrection, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.cjs';
21
21
  export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.cjs';
22
22
  export { CompleteSatSignal, CompleteSignalStats, CompletenessAccumulator, CompletenessResult, CycleSlipAccumulator, CycleSlipEvent, CycleSlipResult, CycleSlipSignalStats, IonoAccumulator, IonoDcbResult, IonoPoint, IonoRatePoint, IonoRateSeries, IonoResult, IonoSeries, MultipathAccumulator, MultipathPoint, MultipathResult, MultipathSeries, MultipathSignalStat, QualityResult, SatDcbMap, analyzeQuality, applyIonoDcb, computeIonoRate, detrendIonoArcs, parseSinexBiasDcb } from './analysis.cjs';
23
23
  export { AntennaEntry, AntexFile, FrequencyData, frequencyLabel, parseAntex } from './antex.cjs';
package/dist/index.d.ts CHANGED
@@ -11,13 +11,13 @@ export { C as ClkFile, I as IonexGrid, S as Sp3File, a as Sp3Sample, c as clkBia
11
11
  export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.js';
12
12
  export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.js';
13
13
  export { UbxCnavResult, UbxFrame, UbxIonoUtcResult, UbxMeasurement, UbxNavOptions, UbxNavResult, UbxParseResult, UbxRawNavOptions, UbxRawNavResult, UbxRawxEpoch, parseUbxCnav, parseUbxIonoUtc, parseUbxNav, parseUbxRawNav, parseUbxRawx, ubxFrames } from './ubx.js';
14
- export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGeoNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfReceiverSetup, sbfCrc16, scanSbfFrames } from './sbf.js';
14
+ export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGeoNavResult, SbfGloNavResult, SbfGpsNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfNavCounts, SbfNavigation, SbfParseResult, SbfPvt, SbfPvtResult, SbfReceiverSetup, decodeSbfNavigation, feedGeoBlock, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGeoNav, parseSbfGloNav, parseSbfGpsNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, parseSbfPvt, parseSbfReceiverSetup, sbfCrc16, scanSbfFrames } from './sbf.js';
15
15
  export { NovatelEpoch, NovatelMeasurement, NovatelNavResult, NovatelParseResult, OEM4_HLEN, Oem4Frame, crc32, oem4Frames, parseNovatelNav, parseNovatelRange } from './novatel.js';
16
16
  export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, TrimbleParseResult, parseTrimble, parseTrimbleNav, trimbleFrames } from './trimble.js';
17
17
  export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.js';
18
18
  export { AllPositionsData, AlmanacPosition, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, almanacEpochMs, almanacSatPosition, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, computeVisibilityFromPositions, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassAlmanacEpochMs, glonassAlmanacPosition, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.js';
19
19
  export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.js';
20
- export { AntennaOffset, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, DgnssOptions, DgnssSolution, EphemerisSource, FixedPositionResult, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, NetworkFcbResult, NetworkFcbSummary, NlArc, NlFcbResult, PppAntennaModel, PppArc, PppCorrectionConfig, PppCorrections, PppEpoch, PppEpochContext, PppEpochResult, PppFixState, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, RtkObsEpoch, RtkObsInput, RtkPostProcessOptions, RtkPostProcessResult, RtkTrackPoint, SatGeom, SbasCorrectionSource, SbasIonoDelay, SbasProcessor, SbasSatCorrection, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, buildPppAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.js';
20
+ export { AntennaOffset, ArFixedSat, ArOptions, ArResult, ArSat, CorrectionResult, DgnssOptions, DgnssSolution, EphemerisSource, FixedPositionResult, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, NetworkFcbResult, NetworkFcbSummary, NlArc, NlFcbResult, PppAntennaModel, PppArc, PppCorrectionConfig, PppCorrections, PppEpoch, PppEpochContext, PppEpochResult, PppFixState, PppOptions, PppSatObs, PppSolution, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, RtkObsEpoch, RtkObsInput, RtkPostProcessOptions, RtkPostProcessResult, RtkTrackPoint, SatGeom, SbasCorrectionSource, SbasIonoDelay, SbasProcessor, SbasSatCorrection, SppOptions, SppSolution, TropoMapping, WlArc, WlFcbOptions, WlFcbResult, WlObs, buildPppAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, resolvePppAmbiguities, satClockCorrection, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength } from './positioning.js';
21
21
  export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.js';
22
22
  export { CompleteSatSignal, CompleteSignalStats, CompletenessAccumulator, CompletenessResult, CycleSlipAccumulator, CycleSlipEvent, CycleSlipResult, CycleSlipSignalStats, IonoAccumulator, IonoDcbResult, IonoPoint, IonoRatePoint, IonoRateSeries, IonoResult, IonoSeries, MultipathAccumulator, MultipathPoint, MultipathResult, MultipathSeries, MultipathSignalStat, QualityResult, SatDcbMap, analyzeQuality, applyIonoDcb, computeIonoRate, detrendIonoArcs, parseSinexBiasDcb } from './analysis.js';
23
23
  export { AntennaEntry, AntexFile, FrequencyData, frequencyLabel, parseAntex } from './antex.js';
package/dist/index.js CHANGED
@@ -66,9 +66,10 @@ import {
66
66
  parseSbfIonoUtc,
67
67
  parseSbfMeas,
68
68
  parseSbfNav,
69
+ parseSbfPvt,
69
70
  parseSbfReceiverSetup,
70
71
  scanSbfFrames
71
- } from "./chunk-DE5IUULR.js";
72
+ } from "./chunk-ZPNMIUNZ.js";
72
73
  import "./chunk-FA2UTLEQ.js";
73
74
  import {
74
75
  OEM4_HLEN,
@@ -157,6 +158,7 @@ import {
157
158
  postProcessRtk,
158
159
  resolvePppAmbiguities,
159
160
  satClockCorrection,
161
+ sbasProtectionLevels,
160
162
  solidEarthTide,
161
163
  solveDgnss,
162
164
  solvePpp,
@@ -164,7 +166,7 @@ import {
164
166
  sunEcef,
165
167
  toRtkEpoch,
166
168
  wlWavelength
167
- } from "./chunk-E3QCNJL4.js";
169
+ } from "./chunk-U32IU7RO.js";
168
170
  import "./chunk-WQX354KD.js";
169
171
  import {
170
172
  almanacEpochMs,
@@ -605,6 +607,7 @@ export {
605
607
  parseSbfIonoUtc,
606
608
  parseSbfMeas,
607
609
  parseSbfNav,
610
+ parseSbfPvt,
608
611
  parseSbfReceiverSetup,
609
612
  parseSinexBiasDcb,
610
613
  parseSourcetable,
@@ -630,6 +633,7 @@ export {
630
633
  rhumbLine,
631
634
  rtcm3Constellation,
632
635
  satClockCorrection,
636
+ sbasProtectionLevels,
633
637
  crc16 as sbfCrc16,
634
638
  scanSbfFrames,
635
639
  selectEphemeris,