gnss-js 2.10.1 → 2.12.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 (55) hide show
  1. package/README.md +16 -1
  2. package/dist/analysis.cjs +24 -25
  3. package/dist/analysis.js +2 -2
  4. package/dist/{clk-DGVBGRzA.d.cts → bias-sinex-OGMw9xEZ.d.cts} +66 -1
  5. package/dist/{clk-DGVBGRzA.d.ts → bias-sinex-OGMw9xEZ.d.ts} +66 -1
  6. package/dist/binex.d.cts +1 -1
  7. package/dist/binex.d.ts +1 -1
  8. package/dist/{chunk-56HM5B6T.js → chunk-2DJ4XENO.js} +177 -9
  9. package/dist/{chunk-GH7MYXON.js → chunk-2KQMCJ5Z.js} +7 -5
  10. package/dist/chunk-E3Y6YKQM.js +65 -0
  11. package/dist/{chunk-3U5AX7PY.js → chunk-FEABDV5P.js} +24 -25
  12. package/dist/{chunk-WQX354KD.js → chunk-H3AKFD25.js} +1 -1
  13. package/dist/{chunk-YUW33VXK.js → chunk-HUXQABJI.js} +2 -0
  14. package/dist/{chunk-74IVYOQV.js → chunk-HWHD5E6V.js} +128 -78
  15. package/dist/{chunk-KUSUN7DP.js → chunk-MFCPYUEI.js} +1 -1
  16. package/dist/{chunk-3KSDL3CO.js → chunk-NIJ6WFQJ.js} +6 -321
  17. package/dist/chunk-NL2ORX75.js +319 -0
  18. package/dist/{chunk-K3GLUWZI.js → chunk-RWFJEVLJ.js} +590 -296
  19. package/dist/{chunk-SEYH4BEN.js → chunk-SZP4TLYR.js} +2 -2
  20. package/dist/chunk-TWGZTRBL.js +323 -0
  21. package/dist/index.cjs +1315 -460
  22. package/dist/index.d.cts +5 -5
  23. package/dist/index.d.ts +5 -5
  24. package/dist/index.js +20 -12
  25. package/dist/{nav-DImXUdbp.d.cts → nav-COp0Vmlw.d.cts} +83 -2
  26. package/dist/{nav-DImXUdbp.d.ts → nav-COp0Vmlw.d.ts} +83 -2
  27. package/dist/{nav-BYmYoh9A.d.cts → nav-CvZXmumD.d.cts} +1 -1
  28. package/dist/{nav-CN8rxL4h.d.ts → nav-D2DFlVpa.d.ts} +1 -1
  29. package/dist/novatel.d.cts +1 -1
  30. package/dist/novatel.d.ts +1 -1
  31. package/dist/novatel.js +3 -3
  32. package/dist/orbit.d.cts +2 -2
  33. package/dist/orbit.d.ts +2 -2
  34. package/dist/osnma.cjs +1336 -0
  35. package/dist/osnma.d.cts +273 -0
  36. package/dist/osnma.d.ts +273 -0
  37. package/dist/osnma.js +1216 -0
  38. package/dist/positioning.cjs +585 -291
  39. package/dist/positioning.d.cts +116 -6
  40. package/dist/positioning.d.ts +116 -6
  41. package/dist/positioning.js +3 -3
  42. package/dist/rinex.cjs +210 -36
  43. package/dist/rinex.d.cts +10 -55
  44. package/dist/rinex.d.ts +10 -55
  45. package/dist/rinex.js +6 -3
  46. package/dist/sbf.cjs +420 -24
  47. package/dist/sbf.d.cts +46 -5
  48. package/dist/sbf.d.ts +46 -5
  49. package/dist/sbf.js +12 -6
  50. package/dist/trimble.d.cts +1 -1
  51. package/dist/trimble.d.ts +1 -1
  52. package/dist/ubx.d.cts +1 -1
  53. package/dist/ubx.d.ts +1 -1
  54. package/dist/ubx.js +5 -4
  55. package/package.json +6 -1
package/dist/rinex.cjs CHANGED
@@ -22,6 +22,7 @@ var rinex_exports = {};
22
22
  __export(rinex_exports, {
23
23
  EMPTY_WARNINGS: () => EMPTY_WARNINGS,
24
24
  SYSTEM_ORDER: () => SYSTEM_ORDER,
25
+ SatOsbTable: () => SatOsbTable,
25
26
  WarningAccumulator: () => WarningAccumulator,
26
27
  biasMetres: () => biasMetres,
27
28
  clkBias: () => clkBias,
@@ -59,20 +60,14 @@ module.exports = __toCommonJS(rinex_exports);
59
60
  // src/rinex/crx.ts
60
61
  function crxRepair(old, diff) {
61
62
  const chars = old.split("");
62
- for (let i = 0; i < diff.length; i++) {
63
+ const n = Math.min(old.length, diff.length);
64
+ for (let i = 0; i < n; i++) {
63
65
  const dc = diff[i];
64
- if (dc === " ") {
65
- } else if (dc === "&") {
66
- chars[i] = " ";
67
- } else {
68
- chars[i] = dc;
69
- }
70
- }
71
- if (diff.length > chars.length) {
72
- for (let i = chars.length; i < diff.length; i++) {
73
- chars[i] = diff[i] === "&" ? " " : diff[i];
74
- }
66
+ if (dc === " ") continue;
67
+ chars[i] = dc === "&" ? " " : dc;
75
68
  }
69
+ for (let i = old.length; i < diff.length; i++)
70
+ chars[i] = diff[i] === "&" ? " " : diff[i];
76
71
  return chars.join("");
77
72
  }
78
73
  function parseCrxDataLine(line, ntype) {
@@ -782,6 +777,15 @@ function readObsValue(line, index) {
782
777
  const v = parseFloat(raw);
783
778
  return isNaN(v) ? null : v;
784
779
  }
780
+ function normalizePrn(id) {
781
+ let sys = id[0];
782
+ let num = id.substring(1);
783
+ if (sys === " " || /\d/.test(sys)) {
784
+ num = id;
785
+ sys = "G";
786
+ }
787
+ return sys + num.replace(/\s/g, "").padStart(2, "0");
788
+ }
785
789
  function parseEpochLine3(line) {
786
790
  if (line[0] !== ">") return null;
787
791
  const yr = parseInt(line.substring(2, 6));
@@ -931,7 +935,7 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
931
935
  function processSatLineV3(line) {
932
936
  if (!header || line.length < 3) return;
933
937
  const sys = line[0];
934
- const prn = line.substring(0, 3);
938
+ const prn = normalizePrn(line.substring(0, 3));
935
939
  trackSat(sys, prn);
936
940
  const obsLine = line.substring(3);
937
941
  const codes = header.obsTypes[sys] ?? [];
@@ -956,10 +960,8 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
956
960
  let v2ObsAccum = [];
957
961
  function processSatLineV2(line) {
958
962
  if (!header || v2SatIndex >= v2SatIds.length) return;
959
- const satId = v2SatIds[v2SatIndex];
960
- let sys = satId[0];
961
- if (sys === " " || /\d/.test(sys)) sys = "G";
962
- const prn = sys + satId.substring(1).padStart(2, "0");
963
+ const prn = normalizePrn(v2SatIds[v2SatIndex]);
964
+ const sys = prn[0];
963
965
  if (v2CurrentSatLine === 0) {
964
966
  trackSat(sys, prn);
965
967
  if (onSatObs) v2ObsAccum = [];
@@ -1050,6 +1052,7 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1050
1052
  } else {
1051
1053
  epochLine = crxRepair(crxPrevEpochLine, line);
1052
1054
  }
1055
+ epochLine = epochLine.replace(/ +$/, "");
1053
1056
  if (isV3) {
1054
1057
  if (epochLine[0] !== ">") return;
1055
1058
  const info = parseEpochLine3(epochLine);
@@ -1067,10 +1070,11 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1067
1070
  return;
1068
1071
  }
1069
1072
  resetEpochAccum(info);
1070
- const satPart = epochLine.substring(41).replace(/\s+$/, "");
1071
1073
  crxSatList = [];
1072
- for (let i = 0; i + 3 <= satPart.length; i += 3) {
1073
- crxSatList.push(satPart.substring(i, i + 3));
1074
+ for (let k = 0; k < info.numSats; k++) {
1075
+ crxSatList.push(
1076
+ normalizePrn(epochLine.substring(41 + 3 * k, 44 + 3 * k))
1077
+ );
1074
1078
  }
1075
1079
  crxSatIndex = 0;
1076
1080
  crxPrevEpochLine = epochLine;
@@ -1091,11 +1095,7 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
1091
1095
  return;
1092
1096
  }
1093
1097
  resetEpochAccum(info);
1094
- crxSatList = (info.satIds ?? []).map((id) => {
1095
- let sys = id[0];
1096
- if (sys === " " || /\d/.test(sys)) sys = "G";
1097
- return sys + id.substring(1).padStart(2, "0");
1098
- });
1098
+ crxSatList = (info.satIds ?? []).slice(0, info.numSats).map(normalizePrn);
1099
1099
  crxSatIndex = 0;
1100
1100
  crxPrevEpochLine = epochLine;
1101
1101
  crxPhase = "clock";
@@ -1495,6 +1495,15 @@ var SEC_PER_WEEK2 = 7 * 86400;
1495
1495
  var CNAV_A_REF = 26559710;
1496
1496
  var CNAV_OMEGA_DOT_REF = -26e-10;
1497
1497
 
1498
+ // src/navbits/bds-cnav.ts
1499
+ var BDT_EPOCH_MS = Date.UTC(2006, 0, 1);
1500
+ var SEC_PER_WEEK3 = 7 * 86400;
1501
+ var BDS_CNAV_A_REF_MEO = 27906100;
1502
+ var BDS_CNAV_A_REF_IGSO_GEO = 42162200;
1503
+ function bdsCnavAref(satType) {
1504
+ return satType === 3 ? BDS_CNAV_A_REF_MEO : BDS_CNAV_A_REF_IGSO_GEO;
1505
+ }
1506
+
1498
1507
  // src/rinex/nav.ts
1499
1508
  var DATA_LINES = {
1500
1509
  G: 7,
@@ -1520,16 +1529,17 @@ var R4_MSG_LINES = {
1520
1529
  // RINEX 4 adds orbit-4 (status flags) vs 3 in RINEX 3
1521
1530
  // EPH type parsed into RinexCnavEphemeris for G/J (skipped otherwise)
1522
1531
  CNAV: 9,
1523
- // EPH types we skip (different field layout)
1532
+ // BeiDou-3 B-CNAV, parsed into BdsCnavEphemeris
1524
1533
  CNV1: 10,
1525
1534
  CNV2: 10,
1526
1535
  CNV3: 9,
1536
+ // EPH types we skip (different field layout)
1527
1537
  L1NV: 8,
1528
1538
  L1OC: 9,
1529
1539
  L3OC: 9
1530
1540
  };
1531
1541
  var GPS_EPOCH_MS3 = Date.UTC(1980, 0, 6);
1532
- var SEC_PER_WEEK3 = 7 * 86400;
1542
+ var SEC_PER_WEEK4 = 7 * 86400;
1533
1543
  var QZSS_CNAV_A_REF = 42164200;
1534
1544
  var SUPPORTED_EPH_MSGS = /* @__PURE__ */ new Set([
1535
1545
  "LNAV",
@@ -1674,8 +1684,8 @@ function buildCnavEphemeris(sys, prn, date, epochVals, d) {
1674
1684
  const num = (r, c) => d[r]?.[c] ?? 0;
1675
1685
  const opt = (r, c) => d[r]?.[c] ?? null;
1676
1686
  const t = (date.getTime() - GPS_EPOCH_MS3) / 1e3;
1677
- const week = Math.floor(t / SEC_PER_WEEK3);
1678
- const toc = t - week * SEC_PER_WEEK3;
1687
+ const week = Math.floor(t / SEC_PER_WEEK4);
1688
+ const toc = t - week * SEC_PER_WEEK4;
1679
1689
  const sqrtA = num(1, 3);
1680
1690
  const a = sqrtA * sqrtA;
1681
1691
  const aRef = sys === "J" ? QZSS_CNAV_A_REF : CNAV_A_REF;
@@ -1732,6 +1742,68 @@ function buildCnavEphemeris(sys, prn, date, epochVals, d) {
1732
1742
  tow: num(7, 0)
1733
1743
  };
1734
1744
  }
1745
+ var BDT_EPOCH_MS2 = Date.UTC(2006, 0, 1);
1746
+ function buildBdsCnavEphemeris(message, prn, date, epochVals, d) {
1747
+ const num = (r, c) => d[r]?.[c] ?? 0;
1748
+ const opt = (r, c) => d[r]?.[c] ?? null;
1749
+ const cnv3 = message === "CNV3";
1750
+ const t = (date.getTime() - BDT_EPOCH_MS2) / 1e3;
1751
+ const weekToc = Math.floor(t / SEC_PER_WEEK4);
1752
+ const toc = t - weekToc * SEC_PER_WEEK4;
1753
+ const toe = num(2, 0);
1754
+ const week = toe - toc > SEC_PER_WEEK4 / 2 ? weekToc - 1 : toc - toe > SEC_PER_WEEK4 / 2 ? weekToc + 1 : weekToc;
1755
+ const sqrtA = num(1, 3);
1756
+ const a = sqrtA * sqrtA;
1757
+ const satType = num(4, 2);
1758
+ return {
1759
+ system: "C",
1760
+ prn,
1761
+ message,
1762
+ week,
1763
+ toe,
1764
+ toeDate: new Date(BDT_EPOCH_MS2 + (week * SEC_PER_WEEK4 + toe) * 1e3),
1765
+ toc,
1766
+ tocDate: date,
1767
+ satType,
1768
+ a,
1769
+ deltaA: a - bdsCnavAref(satType),
1770
+ aDot: num(0, 0),
1771
+ deltaN0: num(0, 2),
1772
+ deltaN0Dot: num(4, 1),
1773
+ m0: num(0, 3),
1774
+ e: num(1, 1),
1775
+ omega: num(3, 2),
1776
+ omega0: num(2, 2),
1777
+ i0: num(3, 0),
1778
+ omegaDot: num(3, 3),
1779
+ i0Dot: num(4, 0),
1780
+ cis: num(2, 3),
1781
+ cic: num(2, 1),
1782
+ crs: num(0, 1),
1783
+ crc: num(3, 1),
1784
+ cus: num(1, 2),
1785
+ cuc: num(1, 0),
1786
+ af0: epochVals[0] ?? 0,
1787
+ af1: epochVals[1] ?? 0,
1788
+ af2: epochVals[2] ?? 0,
1789
+ iode: cnv3 ? null : opt(8, 3),
1790
+ iodc: cnv3 ? null : opt(7, 3),
1791
+ tgdB1Cp: cnv3 ? null : opt(6, 2),
1792
+ tgdB2ap: cnv3 ? null : opt(6, 3),
1793
+ iscB1Cd: cnv3 ? null : opt(6, 0),
1794
+ iscB2ad: cnv3 ? null : opt(6, 1),
1795
+ tgdB2bI: cnv3 ? opt(6, 3) : null,
1796
+ top: opt(4, 3),
1797
+ sisaiOe: opt(5, 0),
1798
+ sisaiOcb: opt(5, 1),
1799
+ sisaiOc1: opt(5, 2),
1800
+ sisaiOc2: opt(5, 3),
1801
+ sismai: cnv3 ? opt(6, 0) : opt(7, 0),
1802
+ health: cnv3 ? opt(6, 1) : opt(7, 1),
1803
+ integrityFlags: cnv3 ? opt(6, 2) : opt(7, 2),
1804
+ tow: cnv3 ? num(7, 0) : num(8, 0)
1805
+ };
1806
+ }
1735
1807
  function parseNavFile(text) {
1736
1808
  const lines = text.split("\n");
1737
1809
  const header = {
@@ -1742,6 +1814,7 @@ function parseNavFile(text) {
1742
1814
  };
1743
1815
  const ephemerides = [];
1744
1816
  const cnav = [];
1817
+ const bdsCnav = [];
1745
1818
  let inHeader = true;
1746
1819
  let i = 0;
1747
1820
  while (i < lines.length) {
@@ -1810,7 +1883,8 @@ function parseNavFile(text) {
1810
1883
  continue;
1811
1884
  }
1812
1885
  const isCnav = msgType === "CNAV" && (svSys === "G" || svSys === "J");
1813
- if (!SUPPORTED_EPH_MSGS.has(msgType) && !isCnav) {
1886
+ const isBdsCnav = svSys === "C" && (msgType === "CNV1" || msgType === "CNV2" || msgType === "CNV3");
1887
+ if (!SUPPORTED_EPH_MSGS.has(msgType) && !isCnav && !isBdsCnav) {
1814
1888
  const totalLines = R4_MSG_LINES[msgType] ?? 2;
1815
1889
  i += totalLines + 1;
1816
1890
  continue;
@@ -1822,17 +1896,34 @@ function parseNavFile(text) {
1822
1896
  const sys2 = epochLine.charAt(0);
1823
1897
  const parsed = parseNavEpochV3(epochLine);
1824
1898
  const prn2 = `${sys2}${parsed.prn.substring(1)}`;
1825
- if (isCnav) {
1899
+ if (isCnav || isBdsCnav) {
1826
1900
  const slotLines = [];
1827
1901
  for (let j = 0; j < numDataLines2; j++) {
1828
1902
  i++;
1829
1903
  if (i >= lines.length) break;
1830
1904
  slotLines.push(parseDataLineSlots(lines[i]));
1831
1905
  }
1832
- if (slotLines.length === numDataLines2 && (sys2 === "G" || sys2 === "J")) {
1833
- cnav.push(
1834
- buildCnavEphemeris(sys2, prn2, parsed.date, parsed.values, slotLines)
1835
- );
1906
+ if (slotLines.length === numDataLines2) {
1907
+ if (isBdsCnav && sys2 === "C")
1908
+ bdsCnav.push(
1909
+ buildBdsCnavEphemeris(
1910
+ msgType,
1911
+ prn2,
1912
+ parsed.date,
1913
+ parsed.values,
1914
+ slotLines
1915
+ )
1916
+ );
1917
+ else if (sys2 === "G" || sys2 === "J")
1918
+ cnav.push(
1919
+ buildCnavEphemeris(
1920
+ sys2,
1921
+ prn2,
1922
+ parsed.date,
1923
+ parsed.values,
1924
+ slotLines
1925
+ )
1926
+ );
1836
1927
  }
1837
1928
  i++;
1838
1929
  continue;
@@ -1910,7 +2001,12 @@ function parseNavFile(text) {
1910
2001
  }
1911
2002
  i++;
1912
2003
  }
1913
- return cnav.length > 0 ? { header, ephemerides, cnav } : { header, ephemerides };
2004
+ return {
2005
+ header,
2006
+ ephemerides,
2007
+ ...cnav.length > 0 && { cnav },
2008
+ ...bdsCnav.length > 0 && { bdsCnav }
2009
+ };
1914
2010
  }
1915
2011
 
1916
2012
  // src/rinex/nav-writer.ts
@@ -2106,6 +2202,30 @@ function cnavRecord(eph) {
2106
2202
  orbitLine4([eph.tow, resolveWnOp(eph.week, eph.wnOp)])
2107
2203
  ].join("\n");
2108
2204
  }
2205
+ function bdsCnavRecord(eph) {
2206
+ const lines = [
2207
+ epochLine4(eph.prn, eph.tocDate, [eph.af0, eph.af1, eph.af2]),
2208
+ orbitLine4([eph.aDot, eph.crs, eph.deltaN0, eph.m0]),
2209
+ orbitLine4([eph.cuc, eph.e, eph.cus, Math.sqrt(eph.a)]),
2210
+ orbitLine4([eph.toe, eph.cic, eph.omega0, eph.cis]),
2211
+ orbitLine4([eph.i0, eph.crc, eph.omega, eph.omegaDot]),
2212
+ orbitLine4([eph.i0Dot, eph.deltaN0Dot, eph.satType, eph.top]),
2213
+ orbitLine4([eph.sisaiOe, eph.sisaiOcb, eph.sisaiOc1, eph.sisaiOc2])
2214
+ ];
2215
+ if (eph.message === "CNV3") {
2216
+ lines.push(
2217
+ orbitLine4([eph.sismai, eph.health, eph.integrityFlags, eph.tgdB2bI]),
2218
+ orbitLine4([eph.tow])
2219
+ );
2220
+ } else {
2221
+ lines.push(
2222
+ orbitLine4([eph.iscB1Cd, eph.iscB2ad, eph.tgdB1Cp, eph.tgdB2ap]),
2223
+ orbitLine4([eph.sismai, eph.health, eph.integrityFlags, eph.iodc]),
2224
+ orbitLine4([eph.tow, null, null, eph.iode])
2225
+ );
2226
+ }
2227
+ return lines.join("\n");
2228
+ }
2109
2229
  var KLOBUCHAR_SOURCES = [
2110
2230
  ["GPSA", "GPSB", "G", "LNAV"],
2111
2231
  ["QZSA", "QZSB", "J", "LNAV"],
@@ -2183,6 +2303,15 @@ function writeRinexNav4(nav) {
2183
2303
  ` + cnavRecord(eph)
2184
2304
  });
2185
2305
  }
2306
+ for (const eph of nav.bdsCnav ?? []) {
2307
+ records.push({
2308
+ prn: eph.prn,
2309
+ time: eph.tocDate.getTime(),
2310
+ label: eph.message,
2311
+ body: `> EPH ${padL(eph.prn, 3)} ${eph.message}
2312
+ ` + bdsCnavRecord(eph)
2313
+ });
2314
+ }
2186
2315
  records.sort(
2187
2316
  (a, b) => a.prn.localeCompare(b.prn) || a.time - b.time || a.label.localeCompare(b.label)
2188
2317
  );
@@ -2529,6 +2658,50 @@ function findSatBias(bias, prn, obs1, obs2, tMs) {
2529
2658
  }
2530
2659
  return null;
2531
2660
  }
2661
+ var SatOsbTable = class {
2662
+ byKey = /* @__PURE__ */ new Map();
2663
+ constructor(bias) {
2664
+ const recs = Array.isArray(bias) ? bias : bias.records;
2665
+ const groups = /* @__PURE__ */ new Map();
2666
+ for (const r of recs) {
2667
+ if (r.type !== "OSB" || !r.prn || r.station) continue;
2668
+ if (r.unit !== "ns") continue;
2669
+ const k = `${r.prn} ${r.obs1}`;
2670
+ let g = groups.get(k);
2671
+ if (!g) groups.set(k, g = []);
2672
+ g.push(r);
2673
+ }
2674
+ for (const [k, g] of groups) {
2675
+ g.sort((a, b) => a.startMs - b.startMs);
2676
+ this.byKey.set(k, {
2677
+ start: Float64Array.from(g, (r) => r.startMs),
2678
+ end: Float64Array.from(g, (r) => r.endMs),
2679
+ m: Float64Array.from(g, biasMetres)
2680
+ });
2681
+ }
2682
+ }
2683
+ /** Whether any phase (L…) OSB is present — i.e. the product supports AR. */
2684
+ get hasPhase() {
2685
+ for (const k of this.byKey.keys())
2686
+ if (k.split(" ")[1][0] === "L") return true;
2687
+ return false;
2688
+ }
2689
+ /** OSB (m) of `prn`'s observable `obs` (e.g. 'C1W', 'L2W') at `tMs`;
2690
+ * null when the product has none valid then. */
2691
+ get(prn, obs, tMs) {
2692
+ const e = this.byKey.get(`${prn} ${obs}`) ?? this.byKey.get(`${prn} ${obs.slice(0, 2)}X`);
2693
+ if (!e) return null;
2694
+ let lo = 0;
2695
+ let hi = e.start.length - 1;
2696
+ if (tMs < e.start[0]) return null;
2697
+ while (lo < hi) {
2698
+ const mid = lo + hi + 1 >> 1;
2699
+ if (e.start[mid] <= tMs) lo = mid;
2700
+ else hi = mid - 1;
2701
+ }
2702
+ return tMs <= e.end[lo] ? e.m[lo] : null;
2703
+ }
2704
+ };
2532
2705
 
2533
2706
  // src/rinex/obs-writer-common.ts
2534
2707
  function createGzipLineSink() {
@@ -2920,6 +3093,7 @@ function writeRinex4ObsBlob(header, epochs, obsTypes) {
2920
3093
  0 && (module.exports = {
2921
3094
  EMPTY_WARNINGS,
2922
3095
  SYSTEM_ORDER,
3096
+ SatOsbTable,
2923
3097
  WarningAccumulator,
2924
3098
  biasMetres,
2925
3099
  clkBias,
package/dist/rinex.d.cts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { R as RinexHeader } from './parser-JPjjFgeP.cjs';
2
2
  export { E as EpochSummary, P as ParseOptions, a as RinexResult, b as RinexStats, S as SYSTEM_ORDER, c as SatObsCallback, p as parseRinexStream, s as systemCmp, d as systemName } from './parser-JPjjFgeP.cjs';
3
- import { a as NavResult, N as NavHeader, E as Ephemeris, R as RinexCnavEphemeris } from './nav-DImXUdbp.cjs';
4
- export { G as GlonassEphemeris, K as KeplerEphemeris, p as parseNavFile } from './nav-DImXUdbp.cjs';
5
- export { C as ClkFile, I as IonexGrid, S as Sp3File, a as Sp3Sample, c as clkBias, p as parseClk, b as parseIonex, d as parseSp3, s as sp3Position } from './clk-DGVBGRzA.cjs';
3
+ import { b as NavResult, N as NavHeader, E as Ephemeris, R as RinexCnavEphemeris, B as BdsCnavEphemeris } from './nav-COp0Vmlw.cjs';
4
+ export { a as BdsCnavMessage, G as GlonassEphemeris, K as KeplerEphemeris, p as parseNavFile } from './nav-COp0Vmlw.cjs';
5
+ export { B as BiasRecord, a as BiasSinex, C as ClkFile, I as IonexGrid, S as SatOsbTable, b as Sp3File, c as Sp3Sample, d as biasMetres, e as clkBias, f as findSatBias, p as parseBiasSinex, g as parseClk, h as parseIonex, i as parseSp3, s as sp3Position } from './bias-sinex-OGMw9xEZ.cjs';
6
6
 
7
7
  /**
8
8
  * Compact RINEX (Hatanaka / CRX) decompression utilities.
@@ -155,7 +155,8 @@ declare function writeRinexNav(nav: NavResult): string;
155
155
  *
156
156
  * Produces `> EPH` data records for the classic ephemeris types
157
157
  * (GPS/QZSS/NavIC LNAV, Galileo INAV, BeiDou D1/D2, GLONASS FDMA,
158
- * SBAS), `> EPH ... CNAV` records for GPS/QZSS CNAV ephemerides, and
158
+ * SBAS), `> EPH ... CNAV` records for GPS/QZSS CNAV ephemerides, BeiDou-3
159
+ * `CNV1`/`CNV2`/`CNV3` records for B-CNAV ephemerides, and
159
160
  * `> ION` records for the header's Klobuchar/NeQuick-G coefficients,
160
161
  * per the RINEX 4.01 record tables (A9-A18, A21, A26, A32, A33).
161
162
  */
@@ -165,13 +166,15 @@ interface Nav4Input {
165
166
  header: NavHeader;
166
167
  ephemerides: Ephemeris[];
167
168
  cnav?: RinexCnavEphemeris[];
169
+ bdsCnav?: BdsCnavEphemeris[];
168
170
  }
169
171
  /**
170
172
  * Write a RINEX 4.01 mixed navigation file.
171
173
  *
172
174
  * Emits `> EPH` records for every classic ephemeris (message labels
173
- * per constellation: LNAV, INAV, D1/D2, FDMA, SBAS) and every CNAV
174
- * ephemeris (`CNAV`), sorted by PRN, epoch, then label; followed by
175
+ * per constellation: LNAV, INAV, D1/D2, FDMA, SBAS), every GPS/QZSS
176
+ * CNAV ephemeris (`CNAV`) and every BeiDou-3 B-CNAV ephemeris (`CNV1`/
177
+ * `CNV2`/`CNV3`), sorted by PRN, epoch, then label; followed by
175
178
  * `> ION` records when the header carries Klobuchar (GPSA/GPSB,
176
179
  * QZSA/QZSB, BDSA/BDSB, IRNA/IRNB) or NeQuick-G (GAL) coefficients.
177
180
  * ION records need a transmit-time epoch, which RINEX 3-style headers
@@ -182,54 +185,6 @@ interface Nav4Input {
182
185
  */
183
186
  declare function writeRinexNav4(nav: Nav4Input): string;
184
187
 
185
- /**
186
- * Bias-SINEX (`.BIA`) parser — GNSS code/phase biases published by the IGS
187
- * analysis centres. Two record kinds matter here:
188
- *
189
- * - **DSB** differential signal bias (OBS1−OBS2), the classic inter-code
190
- * bias used for ionosphere/DCB corrections in SPP.
191
- * - **OSB** observable-specific (absolute) bias for a single OBS, the
192
- * ingredient PPP-AR needs: the *phase* OSBs are the satellite
193
- * fractional-cycle biases that make the ambiguities integer-recoverable.
194
- *
195
- * Values keep their file unit (`ns` for code/most phase biases, `cyc` for
196
- * cycle-based phase biases); `biasMetres` converts ns → m via c.
197
- */
198
- interface BiasRecord {
199
- /** 'DSB' | 'OSB' | 'ISB' | … */
200
- type: string;
201
- /** Satellite PRN (e.g. 'G01', 'E11'); '' for a pure station bias. */
202
- prn: string;
203
- /** Station (9-char), '' for satellite biases. */
204
- station: string;
205
- /** First observable code (e.g. 'C1W', 'L1C'). */
206
- obs1: string;
207
- /** Second observable (DSB only; '' for OSB). */
208
- obs2: string;
209
- /** Validity start / end (GPS-scale ms); ±Infinity when open. */
210
- startMs: number;
211
- endMs: number;
212
- /** Estimated value in the file unit. */
213
- value: number;
214
- /** File unit ('ns' | 'cyc' | …). */
215
- unit: string;
216
- }
217
- interface BiasSinex {
218
- records: BiasRecord[];
219
- /** All satellite records grouped by PRN (station === ''). */
220
- bySat: Map<string, BiasRecord[]>;
221
- }
222
- /** Parse a Bias-SINEX file. */
223
- declare function parseBiasSinex(text: string): BiasSinex;
224
- /** A satellite bias record's value in metres (ns → m via c; cyc left as-is). */
225
- declare function biasMetres(r: BiasRecord): number;
226
- /**
227
- * Look up a satellite bias: a DSB by its (obs1,obs2) pair, or an OSB by obs1
228
- * alone (pass obs2 = undefined), valid at `tMs` (default: any). Returns the
229
- * record or null.
230
- */
231
- declare function findSatBias(bias: BiasSinex, prn: string, obs1: string, obs2?: string, tMs?: number): BiasRecord | null;
232
-
233
188
  /**
234
189
  * RINEX 3.04 / 4.01 observation file writer.
235
190
  *
@@ -320,4 +275,4 @@ declare function createGzipLineSink(): {
320
275
  */
321
276
  declare function stationHeaderLines(header: RinexHeader): string[];
322
277
 
323
- export { type BiasRecord, type BiasSinex, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, biasMetres, createGzipLineSink, crxDecompress, crxRepair, findSatBias, fmtD, fmtF, hdrLine, modalIntervalS, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
278
+ export { BdsCnavEphemeris, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, createGzipLineSink, crxDecompress, crxRepair, fmtD, fmtF, hdrLine, modalIntervalS, padL, padR, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
package/dist/rinex.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import { R as RinexHeader } from './parser-JPjjFgeP.js';
2
2
  export { E as EpochSummary, P as ParseOptions, a as RinexResult, b as RinexStats, S as SYSTEM_ORDER, c as SatObsCallback, p as parseRinexStream, s as systemCmp, d as systemName } from './parser-JPjjFgeP.js';
3
- import { a as NavResult, N as NavHeader, E as Ephemeris, R as RinexCnavEphemeris } from './nav-DImXUdbp.js';
4
- export { G as GlonassEphemeris, K as KeplerEphemeris, p as parseNavFile } from './nav-DImXUdbp.js';
5
- export { C as ClkFile, I as IonexGrid, S as Sp3File, a as Sp3Sample, c as clkBias, p as parseClk, b as parseIonex, d as parseSp3, s as sp3Position } from './clk-DGVBGRzA.js';
3
+ import { b as NavResult, N as NavHeader, E as Ephemeris, R as RinexCnavEphemeris, B as BdsCnavEphemeris } from './nav-COp0Vmlw.js';
4
+ export { a as BdsCnavMessage, G as GlonassEphemeris, K as KeplerEphemeris, p as parseNavFile } from './nav-COp0Vmlw.js';
5
+ export { B as BiasRecord, a as BiasSinex, C as ClkFile, I as IonexGrid, S as SatOsbTable, b as Sp3File, c as Sp3Sample, d as biasMetres, e as clkBias, f as findSatBias, p as parseBiasSinex, g as parseClk, h as parseIonex, i as parseSp3, s as sp3Position } from './bias-sinex-OGMw9xEZ.js';
6
6
 
7
7
  /**
8
8
  * Compact RINEX (Hatanaka / CRX) decompression utilities.
@@ -155,7 +155,8 @@ declare function writeRinexNav(nav: NavResult): string;
155
155
  *
156
156
  * Produces `> EPH` data records for the classic ephemeris types
157
157
  * (GPS/QZSS/NavIC LNAV, Galileo INAV, BeiDou D1/D2, GLONASS FDMA,
158
- * SBAS), `> EPH ... CNAV` records for GPS/QZSS CNAV ephemerides, and
158
+ * SBAS), `> EPH ... CNAV` records for GPS/QZSS CNAV ephemerides, BeiDou-3
159
+ * `CNV1`/`CNV2`/`CNV3` records for B-CNAV ephemerides, and
159
160
  * `> ION` records for the header's Klobuchar/NeQuick-G coefficients,
160
161
  * per the RINEX 4.01 record tables (A9-A18, A21, A26, A32, A33).
161
162
  */
@@ -165,13 +166,15 @@ interface Nav4Input {
165
166
  header: NavHeader;
166
167
  ephemerides: Ephemeris[];
167
168
  cnav?: RinexCnavEphemeris[];
169
+ bdsCnav?: BdsCnavEphemeris[];
168
170
  }
169
171
  /**
170
172
  * Write a RINEX 4.01 mixed navigation file.
171
173
  *
172
174
  * Emits `> EPH` records for every classic ephemeris (message labels
173
- * per constellation: LNAV, INAV, D1/D2, FDMA, SBAS) and every CNAV
174
- * ephemeris (`CNAV`), sorted by PRN, epoch, then label; followed by
175
+ * per constellation: LNAV, INAV, D1/D2, FDMA, SBAS), every GPS/QZSS
176
+ * CNAV ephemeris (`CNAV`) and every BeiDou-3 B-CNAV ephemeris (`CNV1`/
177
+ * `CNV2`/`CNV3`), sorted by PRN, epoch, then label; followed by
175
178
  * `> ION` records when the header carries Klobuchar (GPSA/GPSB,
176
179
  * QZSA/QZSB, BDSA/BDSB, IRNA/IRNB) or NeQuick-G (GAL) coefficients.
177
180
  * ION records need a transmit-time epoch, which RINEX 3-style headers
@@ -182,54 +185,6 @@ interface Nav4Input {
182
185
  */
183
186
  declare function writeRinexNav4(nav: Nav4Input): string;
184
187
 
185
- /**
186
- * Bias-SINEX (`.BIA`) parser — GNSS code/phase biases published by the IGS
187
- * analysis centres. Two record kinds matter here:
188
- *
189
- * - **DSB** differential signal bias (OBS1−OBS2), the classic inter-code
190
- * bias used for ionosphere/DCB corrections in SPP.
191
- * - **OSB** observable-specific (absolute) bias for a single OBS, the
192
- * ingredient PPP-AR needs: the *phase* OSBs are the satellite
193
- * fractional-cycle biases that make the ambiguities integer-recoverable.
194
- *
195
- * Values keep their file unit (`ns` for code/most phase biases, `cyc` for
196
- * cycle-based phase biases); `biasMetres` converts ns → m via c.
197
- */
198
- interface BiasRecord {
199
- /** 'DSB' | 'OSB' | 'ISB' | … */
200
- type: string;
201
- /** Satellite PRN (e.g. 'G01', 'E11'); '' for a pure station bias. */
202
- prn: string;
203
- /** Station (9-char), '' for satellite biases. */
204
- station: string;
205
- /** First observable code (e.g. 'C1W', 'L1C'). */
206
- obs1: string;
207
- /** Second observable (DSB only; '' for OSB). */
208
- obs2: string;
209
- /** Validity start / end (GPS-scale ms); ±Infinity when open. */
210
- startMs: number;
211
- endMs: number;
212
- /** Estimated value in the file unit. */
213
- value: number;
214
- /** File unit ('ns' | 'cyc' | …). */
215
- unit: string;
216
- }
217
- interface BiasSinex {
218
- records: BiasRecord[];
219
- /** All satellite records grouped by PRN (station === ''). */
220
- bySat: Map<string, BiasRecord[]>;
221
- }
222
- /** Parse a Bias-SINEX file. */
223
- declare function parseBiasSinex(text: string): BiasSinex;
224
- /** A satellite bias record's value in metres (ns → m via c; cyc left as-is). */
225
- declare function biasMetres(r: BiasRecord): number;
226
- /**
227
- * Look up a satellite bias: a DSB by its (obs1,obs2) pair, or an OSB by obs1
228
- * alone (pass obs2 = undefined), valid at `tMs` (default: any). Returns the
229
- * record or null.
230
- */
231
- declare function findSatBias(bias: BiasSinex, prn: string, obs1: string, obs2?: string, tMs?: number): BiasRecord | null;
232
-
233
188
  /**
234
189
  * RINEX 3.04 / 4.01 observation file writer.
235
190
  *
@@ -320,4 +275,4 @@ declare function createGzipLineSink(): {
320
275
  */
321
276
  declare function stationHeaderLines(header: RinexHeader): string[];
322
277
 
323
- export { type BiasRecord, type BiasSinex, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, biasMetres, createGzipLineSink, crxDecompress, crxRepair, findSatBias, fmtD, fmtF, hdrLine, modalIntervalS, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
278
+ export { BdsCnavEphemeris, type CompactEpoch, type CrxField, type DiffState, EMPTY_WARNINGS, Ephemeris, type Nav4Input, NavHeader, NavResult, RinexCnavEphemeris, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, type WriteCrxOptions, createGzipLineSink, crxDecompress, crxRepair, fmtD, fmtF, hdrLine, modalIntervalS, padL, padR, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
package/dist/rinex.js CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  EMPTY_WARNINGS,
3
+ SatOsbTable,
3
4
  WarningAccumulator,
4
5
  biasMetres,
5
6
  createGzipLineSink,
@@ -21,7 +22,7 @@ import {
21
22
  writeRinexNav,
22
23
  writeRinexNav4,
23
24
  writeRinexObsBlob
24
- } from "./chunk-56HM5B6T.js";
25
+ } from "./chunk-2DJ4XENO.js";
25
26
  import {
26
27
  SYSTEM_ORDER,
27
28
  crxDecompress,
@@ -30,19 +31,21 @@ import {
30
31
  parseRinexStream,
31
32
  systemCmp,
32
33
  systemName
33
- } from "./chunk-3U5AX7PY.js";
34
+ } from "./chunk-FEABDV5P.js";
35
+ import "./chunk-NL2ORX75.js";
34
36
  import {
35
37
  clkBias,
36
38
  parseClk,
37
39
  parseSp3,
38
40
  sp3Position
39
41
  } from "./chunk-GPEP67TG.js";
40
- import "./chunk-YUW33VXK.js";
42
+ import "./chunk-HUXQABJI.js";
41
43
  import "./chunk-V2D5KUKH.js";
42
44
  import "./chunk-FIEWO4J4.js";
43
45
  export {
44
46
  EMPTY_WARNINGS,
45
47
  SYSTEM_ORDER,
48
+ SatOsbTable,
46
49
  WarningAccumulator,
47
50
  biasMetres,
48
51
  clkBias,