gnss-js 1.56.0 → 1.58.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.
@@ -43,6 +43,8 @@ __export(positioning_exports, {
43
43
  postProcessRtk: () => postProcessRtk,
44
44
  resolvePppAmbiguities: () => resolvePppAmbiguities,
45
45
  satClockCorrection: () => satClockCorrection,
46
+ sbasIonoDeg: () => sbasIonoDeg,
47
+ sbasLongTermDeg: () => sbasLongTermDeg,
46
48
  sbasProtectionLevels: () => sbasProtectionLevels,
47
49
  solidEarthTide: () => solidEarthTide,
48
50
  solveDgnss: () => solveDgnss,
@@ -1744,6 +1746,17 @@ var DEGF = [
1744
1746
  58e-4
1745
1747
  ];
1746
1748
  var degfcorr = (ai) => ai > 0 && ai <= 15 ? DEGF[ai] : 58e-4;
1749
+ function sbasLongTermDeg(d, vel, ageSec) {
1750
+ if (vel) {
1751
+ if (ageSec > 0 && ageSec < d.iltcV1) return 0;
1752
+ return d.cltcLsb + d.cltcV1 * Math.max(0, -ageSec, ageSec - d.iltcV1);
1753
+ }
1754
+ return d.cltcV0 * Math.floor(Math.abs(ageSec) / d.iltcV0);
1755
+ }
1756
+ function sbasIonoDeg(d, ageSec) {
1757
+ const dt = Math.abs(ageSec);
1758
+ return d.cionoStep * Math.floor(dt / d.iiono) + d.cionoRamp * dt;
1759
+ }
1747
1760
  var x1 = [-75, -65, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 65, 75, 85];
1748
1761
  var x2 = [-55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55];
1749
1762
  var x3 = [-75, -65, -55, -50, -45, -40, -35, -30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 65, 75];
@@ -1797,6 +1810,7 @@ var SbasProcessor = class {
1797
1810
  satIdx = /* @__PURE__ */ new Map();
1798
1811
  iodp = -1;
1799
1812
  tlat = 0;
1813
+ degr = null;
1800
1814
  ion = [];
1801
1815
  /** GEO PRN(s) whose messages have been ingested. */
1802
1816
  geoPrns = /* @__PURE__ */ new Set();
@@ -1823,6 +1837,8 @@ var SbasProcessor = class {
1823
1837
  return this.decodeIntegrity(msg) ? type : -1;
1824
1838
  case 7:
1825
1839
  return this.decodeDegradation(msg) ? type : -1;
1840
+ case 10:
1841
+ return this.decodeMt10(msg) ? type : -1;
1826
1842
  case 18:
1827
1843
  return this.decodeIgpMask(msg) ? type : -1;
1828
1844
  case 24:
@@ -1891,6 +1907,30 @@ var SbasProcessor = class {
1891
1907
  }
1892
1908
  return true;
1893
1909
  }
1910
+ /** MT10 degradation factors (DO-229D Table A-9). Fields follow the 8-bit
1911
+ * preamble + 6-bit type (start bit 14), MSB-first, with the listed LSBs.
1912
+ * Iiono / Iltc_v0 of 0 must be read as 1 (Table A-9, Note 3). */
1913
+ decodeMt10(msg) {
1914
+ const u = (p, n) => getBitU(msg, p, n);
1915
+ this.degr = {
1916
+ brrc: u(14, 10) * 2e-3,
1917
+ cltcLsb: u(24, 10) * 2e-3,
1918
+ cltcV1: u(34, 10) * 5e-5,
1919
+ iltcV1: u(44, 9),
1920
+ cltcV0: u(53, 10) * 2e-3,
1921
+ iltcV0: u(63, 9) || 1,
1922
+ cgeoLsb: u(72, 10) * 5e-4,
1923
+ cgeoV: u(82, 10) * 5e-5,
1924
+ igeo: u(92, 9),
1925
+ cer: u(101, 6) * 0.5,
1926
+ cionoStep: u(107, 10) * 1e-3,
1927
+ iiono: u(117, 9) || 1,
1928
+ cionoRamp: u(126, 10) * 5e-6,
1929
+ rssUdre: u(136, 1) === 1,
1930
+ rssIono: u(137, 1) === 1
1931
+ };
1932
+ return true;
1933
+ }
1894
1934
  decodeMixed(msg, week, tow) {
1895
1935
  if (this.iodp !== getBitU(msg, 110, 2)) return false;
1896
1936
  const blk = getBitU(msg, 112, 2);
@@ -1937,7 +1977,8 @@ var SbasProcessor = class {
1937
1977
  dvel: [0, 0, 0],
1938
1978
  daf0: getBitS(msg, p + 41, 10) * P2_31,
1939
1979
  daf1: 0,
1940
- t0s: gpsSeconds(week, tow)
1980
+ t0s: gpsSeconds(week, tow),
1981
+ vel: false
1941
1982
  };
1942
1983
  return true;
1943
1984
  }
@@ -1961,7 +2002,8 @@ var SbasProcessor = class {
1961
2002
  ],
1962
2003
  daf0: getBitS(msg, p + 47, 11) * P2_31,
1963
2004
  daf1: getBitS(msg, p + 82, 8) * P2_39,
1964
- t0s: gpsSeconds(week, tow + t)
2005
+ t0s: gpsSeconds(week, tow + t),
2006
+ vel: true
1965
2007
  };
1966
2008
  return true;
1967
2009
  }
@@ -2082,9 +2124,16 @@ var SbasProcessor = class {
2082
2124
  const tf = now - s.fcorr.t0s + this.tlat;
2083
2125
  if (Math.abs(tf) > MAXSBSAGEF || s.fcorr.udre >= 15) return null;
2084
2126
  const prc = s.fcorr.prc;
2085
- const varM2 = varfcorr(s.fcorr.udre) + degfcorr(s.fcorr.ai) * tf * tf / 2;
2127
+ const sigUdre = Math.sqrt(varfcorr(s.fcorr.udre));
2128
+ const efc = degfcorr(s.fcorr.ai) * tf * tf / 2;
2129
+ const eltc = this.degr && s.lcorr && s.lcorr.t0s !== 0 ? sbasLongTermDeg(this.degr, s.lcorr.vel, now - s.lcorr.t0s) : 0;
2130
+ const varM2 = this.degr?.rssUdre ? sigUdre * sigUdre + efc * efc + eltc * eltc : (sigUdre + efc + eltc) ** 2;
2086
2131
  return { dPos: drs, dClkS: dclk + prc / C_LIGHT, prcM: prc, varM2, iode };
2087
2132
  }
2133
+ /** The last-decoded MT10 degradation factors, or null if none seen. */
2134
+ get degradation() {
2135
+ return this.degr;
2136
+ }
2088
2137
  /**
2089
2138
  * Slant L1 ionospheric delay (m) at the pierce point for a receiver geodetic
2090
2139
  * position (lat/lon rad, height m) and a satellite az/el (rad), interpolated
@@ -2133,14 +2182,18 @@ var SbasProcessor = class {
2133
2182
  } else return null;
2134
2183
  const now = gpsSeconds(week, tow);
2135
2184
  let delay = 0;
2136
- let varM2 = 0;
2185
+ let varVert = 0;
2137
2186
  for (let i = 0; i < 4; i++) {
2138
2187
  const g = pts[i];
2139
2188
  if (!g) continue;
2140
2189
  delay += w[i] * g.delay;
2141
- varM2 += w[i] * varicorr(g.give) * 9e-8 * Math.abs(now - g.t0s);
2190
+ const sigGive = Math.sqrt(varicorr(g.give));
2191
+ const d = this.degr;
2192
+ const eiono = d ? sbasIonoDeg(d, now - g.t0s) : 0;
2193
+ const sig2 = d?.rssIono ? sigGive * sigGive + eiono * eiono : (sigGive + eiono) ** 2;
2194
+ varVert += w[i] * sig2;
2142
2195
  }
2143
- return { delayM: delay * fp, varM2: varM2 * fp * fp };
2196
+ return { delayM: delay * fp, varM2: varVert * fp * fp };
2144
2197
  }
2145
2198
  /** Find the four IGPs bracketing a pierce point (RTKLIB `searchigp`). */
2146
2199
  searchIgp(latP, lonP) {
@@ -3627,10 +3680,10 @@ function sagnac2(pos, travelTimeS) {
3627
3680
  function sbasAirTropoVar(elRad) {
3628
3681
  const elDeg = elRad * 180 / Math.PI;
3629
3682
  const sigMp = 0.13 + 0.53 * Math.exp(-elDeg / 10);
3630
- const sigNoise = 0.15 + 0.43 * Math.exp(-elDeg / 6.9);
3683
+ const NOISE_DIVG_AADA = 0.36;
3631
3684
  const m = 1.001 / Math.sqrt(2001e-6 + Math.sin(elRad) * Math.sin(elRad));
3632
3685
  const sigTropo = 0.12 * m;
3633
- return sigMp * sigMp + sigNoise * sigNoise + sigTropo * sigTropo;
3686
+ return sigMp * sigMp + NOISE_DIVG_AADA * NOISE_DIVG_AADA + sigTropo * sigTropo;
3634
3687
  }
3635
3688
  function invertMatrix(A) {
3636
3689
  const n = A.length;
@@ -3939,6 +3992,8 @@ function solveSpp(pseudoranges, ephemerides, timeMs, opts = {}) {
3939
3992
  postProcessRtk,
3940
3993
  resolvePppAmbiguities,
3941
3994
  satClockCorrection,
3995
+ sbasIonoDeg,
3996
+ sbasLongTermDeg,
3942
3997
  sbasProtectionLevels,
3943
3998
  solidEarthTide,
3944
3999
  solveDgnss,
@@ -550,6 +550,35 @@ declare function lambdaSearch(a: Float64Array, Q: Float64Array, n: number, m?: n
550
550
  */
551
551
  declare function lambdaReduction(Q: Float64Array, n: number): Float64Array | null;
552
552
 
553
+ /**
554
+ * Long-term correction degradation ε_ltc (m) — DO-229D §A.4.5.1.3, eqs A-54
555
+ * (velocity code 1) and A-55 (velocity code 0). `ageSec` = t − t₀ (s).
556
+ */
557
+ declare function sbasLongTermDeg(d: Degradation, vel: boolean, ageSec: number): number;
558
+ /**
559
+ * Ionospheric-correction degradation ε_iono (m) — DO-229D §A.4.5.2, eq A-59.
560
+ * `ageSec` = t − t_iono (s) of the grid point.
561
+ */
562
+ declare function sbasIonoDeg(d: Degradation, ageSec: number): number;
563
+ /** MT10 degradation parameters (DO-229D Table A-9), needed for the residual
564
+ * variances σ²_flt / σ²_ionogrid (§A.4.5, §J.2.2). */
565
+ interface Degradation {
566
+ brrc: number;
567
+ cltcLsb: number;
568
+ cltcV1: number;
569
+ iltcV1: number;
570
+ cltcV0: number;
571
+ iltcV0: number;
572
+ cgeoLsb: number;
573
+ cgeoV: number;
574
+ igeo: number;
575
+ cer: number;
576
+ cionoStep: number;
577
+ iiono: number;
578
+ cionoRamp: number;
579
+ rssUdre: boolean;
580
+ rssIono: boolean;
581
+ }
553
582
  /** A per-satellite SBAS correction, ready to apply in an SPP solve. */
554
583
  interface SbasSatCorrection {
555
584
  /** Long-term ECEF position correction to add to the satellite position (m). */
@@ -575,6 +604,7 @@ declare class SbasProcessor {
575
604
  private satIdx;
576
605
  private iodp;
577
606
  private tlat;
607
+ private degr;
578
608
  private ion;
579
609
  /** GEO PRN(s) whose messages have been ingested. */
580
610
  readonly geoPrns: Set<string>;
@@ -588,6 +618,10 @@ declare class SbasProcessor {
588
618
  private decodeFast;
589
619
  private decodeIntegrity;
590
620
  private decodeDegradation;
621
+ /** MT10 degradation factors (DO-229D Table A-9). Fields follow the 8-bit
622
+ * preamble + 6-bit type (start bit 14), MSB-first, with the listed LSBs.
623
+ * Iiono / Iltc_v0 of 0 must be read as 1 (Table A-9, Note 3). */
624
+ private decodeMt10;
591
625
  private decodeMixed;
592
626
  private decodeLongCorrHalf;
593
627
  private decodeLong0;
@@ -624,6 +658,8 @@ declare class SbasProcessor {
624
658
  * to the satellite ECEF position and `dClkS` to its clock bias.
625
659
  */
626
660
  satCorrection(prn: string, week: number, tow: number): SbasSatCorrection | null;
661
+ /** The last-decoded MT10 degradation factors, or null if none seen. */
662
+ get degradation(): Readonly<Degradation> | null;
627
663
  /**
628
664
  * Slant L1 ionospheric delay (m) at the pierce point for a receiver geodetic
629
665
  * position (lat/lon rad, height m) and a satellite az/el (rad), interpolated
@@ -1334,4 +1370,4 @@ declare function sbasProtectionLevels(sats: readonly {
1334
1370
  */
1335
1371
  declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
1336
1372
 
1337
- export { type AntennaOffset, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkTrackPoint, type SatGeom, type SbasCorrectionSource, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type 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 };
1373
+ export { type AntennaOffset, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type Degradation, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkTrackPoint, type SatGeom, type SbasCorrectionSource, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, buildPppAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
@@ -550,6 +550,35 @@ declare function lambdaSearch(a: Float64Array, Q: Float64Array, n: number, m?: n
550
550
  */
551
551
  declare function lambdaReduction(Q: Float64Array, n: number): Float64Array | null;
552
552
 
553
+ /**
554
+ * Long-term correction degradation ε_ltc (m) — DO-229D §A.4.5.1.3, eqs A-54
555
+ * (velocity code 1) and A-55 (velocity code 0). `ageSec` = t − t₀ (s).
556
+ */
557
+ declare function sbasLongTermDeg(d: Degradation, vel: boolean, ageSec: number): number;
558
+ /**
559
+ * Ionospheric-correction degradation ε_iono (m) — DO-229D §A.4.5.2, eq A-59.
560
+ * `ageSec` = t − t_iono (s) of the grid point.
561
+ */
562
+ declare function sbasIonoDeg(d: Degradation, ageSec: number): number;
563
+ /** MT10 degradation parameters (DO-229D Table A-9), needed for the residual
564
+ * variances σ²_flt / σ²_ionogrid (§A.4.5, §J.2.2). */
565
+ interface Degradation {
566
+ brrc: number;
567
+ cltcLsb: number;
568
+ cltcV1: number;
569
+ iltcV1: number;
570
+ cltcV0: number;
571
+ iltcV0: number;
572
+ cgeoLsb: number;
573
+ cgeoV: number;
574
+ igeo: number;
575
+ cer: number;
576
+ cionoStep: number;
577
+ iiono: number;
578
+ cionoRamp: number;
579
+ rssUdre: boolean;
580
+ rssIono: boolean;
581
+ }
553
582
  /** A per-satellite SBAS correction, ready to apply in an SPP solve. */
554
583
  interface SbasSatCorrection {
555
584
  /** Long-term ECEF position correction to add to the satellite position (m). */
@@ -575,6 +604,7 @@ declare class SbasProcessor {
575
604
  private satIdx;
576
605
  private iodp;
577
606
  private tlat;
607
+ private degr;
578
608
  private ion;
579
609
  /** GEO PRN(s) whose messages have been ingested. */
580
610
  readonly geoPrns: Set<string>;
@@ -588,6 +618,10 @@ declare class SbasProcessor {
588
618
  private decodeFast;
589
619
  private decodeIntegrity;
590
620
  private decodeDegradation;
621
+ /** MT10 degradation factors (DO-229D Table A-9). Fields follow the 8-bit
622
+ * preamble + 6-bit type (start bit 14), MSB-first, with the listed LSBs.
623
+ * Iiono / Iltc_v0 of 0 must be read as 1 (Table A-9, Note 3). */
624
+ private decodeMt10;
591
625
  private decodeMixed;
592
626
  private decodeLongCorrHalf;
593
627
  private decodeLong0;
@@ -624,6 +658,8 @@ declare class SbasProcessor {
624
658
  * to the satellite ECEF position and `dClkS` to its clock bias.
625
659
  */
626
660
  satCorrection(prn: string, week: number, tow: number): SbasSatCorrection | null;
661
+ /** The last-decoded MT10 degradation factors, or null if none seen. */
662
+ get degradation(): Readonly<Degradation> | null;
627
663
  /**
628
664
  * Slant L1 ionospheric delay (m) at the pierce point for a receiver geodetic
629
665
  * position (lat/lon rad, height m) and a satellite az/el (rad), interpolated
@@ -1334,4 +1370,4 @@ declare function sbasProtectionLevels(sats: readonly {
1334
1370
  */
1335
1371
  declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
1336
1372
 
1337
- export { type AntennaOffset, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkTrackPoint, type SatGeom, type SbasCorrectionSource, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type 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 };
1373
+ export { type AntennaOffset, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type Degradation, type DgnssOptions, type DgnssSolution, type EphemerisSource, type FixedPositionResult, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type NetworkFcbResult, type NetworkFcbSummary, type NlArc, type NlFcbResult, type PppAntennaModel, type PppArc, type PppCorrectionConfig, type PppCorrections, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppFixState, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type RtkObsEpoch, type RtkObsInput, type RtkPostProcessOptions, type RtkPostProcessResult, type RtkTrackPoint, type SatGeom, type SbasCorrectionSource, type SbasIonoDelay, SbasProcessor, type SbasSatCorrection, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, buildPppAntenna, createPppCorrections, estimateNarrowlaneFcb, estimateNetworkFcbs, estimateWidelaneFcb, extractWidelaneArcs, fixPppPosition, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, postProcessRtk, resolvePppAmbiguities, satClockCorrection, sbasIonoDeg, sbasLongTermDeg, sbasProtectionLevels, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
@@ -22,6 +22,8 @@ import {
22
22
  postProcessRtk,
23
23
  resolvePppAmbiguities,
24
24
  satClockCorrection,
25
+ sbasIonoDeg,
26
+ sbasLongTermDeg,
25
27
  sbasProtectionLevels,
26
28
  solidEarthTide,
27
29
  solveDgnss,
@@ -30,7 +32,7 @@ import {
30
32
  sunEcef,
31
33
  toRtkEpoch,
32
34
  wlWavelength
33
- } from "./chunk-BU6YC6VK.js";
35
+ } from "./chunk-SWVIBUHS.js";
34
36
  import "./chunk-WQX354KD.js";
35
37
  import "./chunk-MHGNKSSH.js";
36
38
  import "./chunk-MIIM4LDY.js";
@@ -66,6 +68,8 @@ export {
66
68
  postProcessRtk,
67
69
  resolvePppAmbiguities,
68
70
  satClockCorrection,
71
+ sbasIonoDeg,
72
+ sbasLongTermDeg,
69
73
  sbasProtectionLevels,
70
74
  solidEarthTide,
71
75
  solveDgnss,
package/dist/sbf.cjs CHANGED
@@ -20,12 +20,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/sbf/index.ts
21
21
  var sbf_exports = {};
22
22
  __export(sbf_exports, {
23
+ SBAS_L5_MT_NAMES: () => SBAS_L5_MT_NAMES,
24
+ SBAS_L5_PREAMBLE_UW: () => SBAS_L5_PREAMBLE_UW,
23
25
  decodeSbfNavigation: () => decodeSbfNavigation,
24
26
  feedGeoBlock: () => feedGeoBlock,
27
+ feedGeoL5Block: () => feedGeoL5Block,
28
+ isSbasL1Preamble: () => isSbasL1Preamble,
29
+ isSbasL5Correction: () => isSbasL5Correction,
25
30
  parseSbfAlmanac: () => parseSbfAlmanac,
26
31
  parseSbfBdsNav: () => parseSbfBdsNav,
27
32
  parseSbfCnav: () => parseSbfCnav,
28
33
  parseSbfGalNav: () => parseSbfGalNav,
34
+ parseSbfGeoL5: () => parseSbfGeoL5,
29
35
  parseSbfGeoNav: () => parseSbfGeoNav,
30
36
  parseSbfGloNav: () => parseSbfGloNav,
31
37
  parseSbfGpsNav: () => parseSbfGpsNav,
@@ -35,6 +41,8 @@ __export(sbf_exports, {
35
41
  parseSbfNav: () => parseSbfNav,
36
42
  parseSbfPvt: () => parseSbfPvt,
37
43
  parseSbfReceiverSetup: () => parseSbfReceiverSetup,
44
+ sbasL5MessageName: () => sbasL5MessageName,
45
+ sbasL5MessageType: () => sbasL5MessageType,
38
46
  sbfCrc16: () => crc16,
39
47
  scanSbfFrames: () => scanSbfFrames
40
48
  });
@@ -2033,13 +2041,42 @@ function decodeSbasGeoNav(msg, prn, week, tow) {
2033
2041
  };
2034
2042
  }
2035
2043
 
2044
+ // src/navbits/sbas-l5.ts
2045
+ var SBAS_L5_PREAMBLE_UW = 6056250;
2046
+ function isSbasL1Preamble(msg) {
2047
+ return msg[0] === 83 || msg[0] === 154 || msg[0] === 198;
2048
+ }
2049
+ function sbasL5MessageType(msg) {
2050
+ return getBitU(msg, 4, 6);
2051
+ }
2052
+ var SBAS_L5_MT_NAMES = {
2053
+ 0: "Do Not Use (test)",
2054
+ 31: "SBAS satellite mask",
2055
+ 32: "Satellite clock-ephemeris corrections + covariance",
2056
+ 34: "Integrity (DFREI/DFRECI)",
2057
+ 35: "Integrity (DFREI/DFRECI)",
2058
+ 36: "Integrity (DFREI/DFRECI)",
2059
+ 37: "Degradation parameters + DFREI scale table",
2060
+ 39: "SBAS satellite clock/ephemeris/covariance-1",
2061
+ 40: "SBAS satellite clock/ephemeris/covariance-2",
2062
+ 42: "SNT-to-UTC offset",
2063
+ 47: "SBAS satellite almanacs",
2064
+ 62: "Reserved",
2065
+ 63: "Null message"
2066
+ };
2067
+ function sbasL5MessageName(type) {
2068
+ return SBAS_L5_MT_NAMES[type] ?? (type >= 1 && type <= 61 ? "Spare" : `Type ${type}`);
2069
+ }
2070
+ function isSbasL5Correction(type) {
2071
+ return type === 31 || type === 32 || type >= 34 && type <= 37 || type === 39 || type === 40 || type === 42 || type === 47;
2072
+ }
2073
+
2036
2074
  // src/sbf/rawnav-sbas.ts
2037
- function feedGeoBlock(view, b, onSbasMessage) {
2075
+ function readGeoMessage(view, b) {
2038
2076
  const tow = view.getUint32(b + 8, true);
2039
2077
  const wnc = view.getUint16(b + 12, true);
2040
- const svid = view.getUint8(b + 14);
2041
- const prnStr = svidToPrn(svid);
2042
- if (!prnStr || prnStr[0] !== "S") return {};
2078
+ const prnStr = svidToPrn(view.getUint8(b + 14));
2079
+ if (!prnStr || prnStr[0] !== "S") return null;
2043
2080
  const msg = new Uint8Array(32);
2044
2081
  for (let k = 0; k < 8; k++) {
2045
2082
  const w = view.getUint32(b + 20 + 4 * k, true);
@@ -2048,12 +2085,29 @@ function feedGeoBlock(view, b, onSbasMessage) {
2048
2085
  msg[4 * k + 2] = w >>> 8 & 255;
2049
2086
  msg[4 * k + 3] = w & 255;
2050
2087
  }
2051
- if (!sbasCrcOk(msg)) return { badCrc: true };
2052
- const prn = Number(prnStr.slice(1)) + 100;
2053
- onSbasMessage?.(msg, prn, wnc, tow / 1e3);
2054
- const eph = decodeSbasGeoNav(msg, prn, wnc, tow / 1e3);
2088
+ return { msg, prn: Number(prnStr.slice(1)) + 100, wnc, towSec: tow / 1e3 };
2089
+ }
2090
+ function feedGeoBlock(view, b, onSbasMessage) {
2091
+ const g = readGeoMessage(view, b);
2092
+ if (!g) return {};
2093
+ if (!sbasCrcOk(g.msg)) return { badCrc: true };
2094
+ onSbasMessage?.(g.msg, g.prn, g.wnc, g.towSec);
2095
+ const eph = decodeSbasGeoNav(g.msg, g.prn, g.wnc, g.towSec);
2055
2096
  return eph ? { eph } : {};
2056
2097
  }
2098
+ function feedGeoL5Block(view, b, onSbasMessage, onDfmcMessage) {
2099
+ const g = readGeoMessage(view, b);
2100
+ if (!g) return {};
2101
+ if (!sbasCrcOk(g.msg)) return { badCrc: true };
2102
+ if (isSbasL1Preamble(g.msg)) {
2103
+ onSbasMessage?.(g.msg, g.prn, g.wnc, g.towSec);
2104
+ const eph = decodeSbasGeoNav(g.msg, g.prn, g.wnc, g.towSec);
2105
+ return eph ? { kind: "l1", eph } : { kind: "l1" };
2106
+ }
2107
+ const dfmcType = sbasL5MessageType(g.msg);
2108
+ onDfmcMessage?.(g.msg, g.prn, g.wnc, g.towSec, dfmcType);
2109
+ return { kind: "l5", dfmcType };
2110
+ }
2057
2111
  function parseSbfGeoNav(data, opts = {}) {
2058
2112
  const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
2059
2113
  const ephemerides = [];
@@ -2076,6 +2130,47 @@ function parseSbfGeoNav(data, opts = {}) {
2076
2130
  });
2077
2131
  return { ephemerides, badCrc, messages };
2078
2132
  }
2133
+ function parseSbfGeoL5(data, opts = {}) {
2134
+ const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
2135
+ const ephemerides = [];
2136
+ const seen = /* @__PURE__ */ new Set();
2137
+ const byType = {};
2138
+ const dfmcPrns = /* @__PURE__ */ new Set();
2139
+ let legacyMessages = 0;
2140
+ let dfmcMessages = 0;
2141
+ let badCrc = 0;
2142
+ let messages = 0;
2143
+ scanSbfFrames(data, view, (id, b, len) => {
2144
+ if (id !== 4021 || len < 52) return;
2145
+ messages++;
2146
+ const r = feedGeoL5Block(view, b, opts.onSbasMessage, opts.onDfmcMessage);
2147
+ if (r.badCrc) {
2148
+ badCrc++;
2149
+ } else if (r.kind === "l1") {
2150
+ legacyMessages++;
2151
+ if (r.eph) {
2152
+ const key = `${r.eph.prn}|${r.eph.tocDate.getTime()}`;
2153
+ if (!seen.has(key)) {
2154
+ seen.add(key);
2155
+ ephemerides.push(r.eph);
2156
+ }
2157
+ }
2158
+ } else if (r.kind === "l5" && r.dfmcType !== void 0) {
2159
+ dfmcMessages++;
2160
+ byType[r.dfmcType] = (byType[r.dfmcType] ?? 0) + 1;
2161
+ const prn = view.getUint8(b + 14);
2162
+ const s = svidToPrn(prn);
2163
+ if (s) dfmcPrns.add(s);
2164
+ }
2165
+ });
2166
+ return {
2167
+ ephemerides,
2168
+ legacyMessages,
2169
+ dfmc: { byType, prns: [...dfmcPrns].sort(), messages: dfmcMessages },
2170
+ badCrc,
2171
+ messages
2172
+ };
2173
+ }
2079
2174
 
2080
2175
  // src/sbf/navigation.ts
2081
2176
  var F4_DNU4 = -2e10;
@@ -2098,8 +2193,11 @@ function decodeSbfNavigation(data, opts = {}) {
2098
2193
  gloRaw: 0,
2099
2194
  bdsRaw: 0,
2100
2195
  sbasRaw: 0,
2196
+ sbasL5Raw: 0,
2101
2197
  badFrames: 0
2102
2198
  };
2199
+ const dfmcByType = {};
2200
+ const dfmcPrns = /* @__PURE__ */ new Set();
2103
2201
  const cnavAsm = newCnavAssemblers();
2104
2202
  const galAsm = newGalAssemblers();
2105
2203
  const gloAsm = new GloStringAssembler();
@@ -2209,6 +2307,25 @@ function decodeSbfNavigation(data, opts = {}) {
2209
2307
  else if (r.badCrc) counts.badFrames++;
2210
2308
  return;
2211
2309
  }
2310
+ case 4021: {
2311
+ if (len < 52) return;
2312
+ counts.sbasL5Raw++;
2313
+ const r = feedGeoL5Block(
2314
+ view,
2315
+ b,
2316
+ opts.onSbasMessage,
2317
+ opts.onDfmcMessage
2318
+ );
2319
+ if (r.badCrc) counts.badFrames++;
2320
+ else if (r.kind === "l1") {
2321
+ if (r.eph) addEph(r.eph);
2322
+ } else if (r.kind === "l5" && r.dfmcType !== void 0) {
2323
+ dfmcByType[r.dfmcType] = (dfmcByType[r.dfmcType] ?? 0) + 1;
2324
+ const s = svidToPrn(view.getUint8(b + 14));
2325
+ if (s) dfmcPrns.add(s);
2326
+ }
2327
+ return;
2328
+ }
2212
2329
  /* ---- iono / UTC ---- */
2213
2330
  case 5893:
2214
2331
  // GPSIon
@@ -2233,7 +2350,12 @@ function decodeSbfNavigation(data, opts = {}) {
2233
2350
  return;
2234
2351
  }
2235
2352
  });
2236
- return { ephemerides, cnav, ionoCorrections, leapSeconds, counts };
2353
+ const dfmc = {
2354
+ byType: dfmcByType,
2355
+ prns: [...dfmcPrns].sort(),
2356
+ messages: Object.values(dfmcByType).reduce((a, v) => a + v, 0)
2357
+ };
2358
+ return { ephemerides, cnav, ionoCorrections, leapSeconds, dfmc, counts };
2237
2359
  }
2238
2360
 
2239
2361
  // src/navbits/rs255.ts
@@ -3428,12 +3550,18 @@ function parseSbfMeas(data) {
3428
3550
  }
3429
3551
  // Annotate the CommonJS export names for ESM import in node:
3430
3552
  0 && (module.exports = {
3553
+ SBAS_L5_MT_NAMES,
3554
+ SBAS_L5_PREAMBLE_UW,
3431
3555
  decodeSbfNavigation,
3432
3556
  feedGeoBlock,
3557
+ feedGeoL5Block,
3558
+ isSbasL1Preamble,
3559
+ isSbasL5Correction,
3433
3560
  parseSbfAlmanac,
3434
3561
  parseSbfBdsNav,
3435
3562
  parseSbfCnav,
3436
3563
  parseSbfGalNav,
3564
+ parseSbfGeoL5,
3437
3565
  parseSbfGeoNav,
3438
3566
  parseSbfGloNav,
3439
3567
  parseSbfGpsNav,
@@ -3443,6 +3571,8 @@ function parseSbfMeas(data) {
3443
3571
  parseSbfNav,
3444
3572
  parseSbfPvt,
3445
3573
  parseSbfReceiverSetup,
3574
+ sbasL5MessageName,
3575
+ sbasL5MessageType,
3446
3576
  sbfCrc16,
3447
3577
  scanSbfFrames
3448
3578
  });