gnss-js 1.30.0 → 1.32.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.
@@ -714,6 +714,172 @@ declare function moonEcef(timeMs: number): [number, number, number];
714
714
  */
715
715
  declare function solidEarthTide(rcv: [number, number, number], sun: [number, number, number], moon: [number, number, number]): [number, number, number];
716
716
 
717
+ /**
718
+ * PPP-AR — integer ambiguity resolution for Precise Point Positioning.
719
+ *
720
+ * Float PPP estimates one *ionosphere-free* ambiguity per satellite arc, a
721
+ * real number in metres. Fixing those to integers is what takes PPP from the
722
+ * decimetre to the centimetre level. The classic two-step decomposition is
723
+ * used here:
724
+ *
725
+ * 1. **Wide-lane** N_WL = N1 − N2 from the Melbourne–Wübbena combination.
726
+ * The WL wavelength is ~86 cm (GPS), so the arc-averaged MW rounds to an
727
+ * integer reliably once the satellite WL fractional-cycle bias is removed.
728
+ * 2. **Narrow-lane** N1, recovered from the float IF ambiguity with N_WL
729
+ * fixed, then resolved with LAMBDA on *between-satellite single
730
+ * differences* (which cancel the receiver phase bias) after removing the
731
+ * satellite NL fractional-cycle bias.
732
+ *
733
+ * The satellite WL/NL fractional-cycle biases come from a phase-bias product
734
+ * (Bias-SINEX OSB from an AR-capable analysis centre such as CNES or CODE).
735
+ * Without them, a single receiver cannot separate the satellite bias from the
736
+ * integer, so those biases are required inputs — pass 0 only for a network
737
+ * datum where they have already been removed.
738
+ *
739
+ * The relation between the IF ambiguity (metres) and the integers is
740
+ * A_IF = λ_NL·N1 + λ_NL·(f2/(f1−f2))·N_WL, λ_NL = c/(f1+f2).
741
+ */
742
+ /** Wide-lane wavelength c/(f1−f2) (m). */
743
+ declare function wlWavelength(f1: number, f2: number): number;
744
+ /** Narrow-lane wavelength c/(f1+f2) (m). */
745
+ declare function nlWavelength(f1: number, f2: number): number;
746
+ /** One satellite's float ambiguity inputs for AR. */
747
+ interface ArSat {
748
+ prn: string;
749
+ /** Float ionosphere-free ambiguity (m) from the PPP EKF. */
750
+ aIF: number;
751
+ /** Arc-averaged Melbourne–Wübbena wide-lane estimate (cycles). */
752
+ mwCyc: number;
753
+ f1: number;
754
+ f2: number;
755
+ /** Satellite wide-lane fractional-cycle bias (cycles). Default 0. */
756
+ wlBiasCyc?: number;
757
+ /** Satellite narrow-lane fractional-cycle bias (cycles). Default 0. */
758
+ nlBiasCyc?: number;
759
+ /** Elevation (deg), used only to pick the reference satellite. */
760
+ elevDeg?: number;
761
+ }
762
+ interface ArOptions {
763
+ /** Max |MW − round| to accept a wide-lane (cycles). Default 0.25. */
764
+ wlThreshold?: number;
765
+ /** Min LAMBDA ratio to accept the narrow-lane fix. Default 3. */
766
+ ratioThreshold?: number;
767
+ }
768
+ interface ArFixedSat {
769
+ prn: string;
770
+ nWl: number;
771
+ n1: number;
772
+ /** Fixed IF ambiguity (m). */
773
+ aIF: number;
774
+ }
775
+ interface ArResult {
776
+ /** Whether the narrow-lane fix passed the ratio test. */
777
+ fixed: boolean;
778
+ /** LAMBDA ratio statistic (second-best / best). */
779
+ ratio: number;
780
+ /** Reference PRN whose absolute N1 stays float (SD datum). */
781
+ refPrn: string | null;
782
+ /** Fixed satellites (includes the reference with its float-rounded N1). */
783
+ sats: ArFixedSat[];
784
+ /** PRNs whose wide-lane did not round confidently (excluded). */
785
+ rejectedWl: string[];
786
+ }
787
+ /**
788
+ * Resolve PPP integer ambiguities from the float IF ambiguities and their
789
+ * covariance. `Qaif` is the n×n float covariance (m²) in the same order as
790
+ * `sats`. Returns the fixed narrow-lane / wide-lane integers and the ratio
791
+ * test result. A `fixed: false` result means the data did not support a
792
+ * confident fix (keep the float solution).
793
+ */
794
+ declare function resolvePppAmbiguities(sats: ArSat[], Qaif: Float64Array, opts?: ArOptions): ArResult;
795
+
796
+ /**
797
+ * Wide-lane fractional-cycle bias (FCB) estimation for PPP-AR — the
798
+ * self-contained route to integer ambiguities that needs no external
799
+ * phase-bias product, only a small network of stations.
800
+ *
801
+ * A single receiver cannot resolve ambiguities because its Melbourne–Wübbena
802
+ * wide-lane float is `Ñ_wl = N (integer) + b_rcv + b_sat`, and the integer
803
+ * and the satellite fractional bias `b_sat` are entangled. Across a *network*
804
+ * they separate: every station sees the same `b_sat` for a given satellite
805
+ * but its own integers and receiver bias, so the fractional part common to
806
+ * all stations *is* the satellite FCB. This is the classic Ge/Gendt method.
807
+ *
808
+ * The estimator alternates:
809
+ * 1. round each arc to its integer N = round(Ñ_wl − b_rcv − b_sat);
810
+ * 2. update each satellite FCB = circular-mean over stations of
811
+ * (Ñ_wl − N − b_rcv);
812
+ * 3. update each receiver bias = circular-mean over satellites of
813
+ * (Ñ_wl − N − b_sat);
814
+ * 4. pin the datum (b_rcv of a reference station ≡ 0) — receiver and
815
+ * satellite biases otherwise trade off by an arbitrary constant.
816
+ *
817
+ * The output `satFcb` feeds `resolvePppAmbiguities`' `wlBiasCyc`.
818
+ */
819
+ /** Minimal per-satellite observation for wide-lane extraction. */
820
+ interface WlObs {
821
+ prn: string;
822
+ f1: number;
823
+ f2: number;
824
+ /** Code on f1/f2 (m) and carrier phase on f1/f2 (cycles). */
825
+ c1: number;
826
+ c2: number;
827
+ l1: number;
828
+ l2: number;
829
+ }
830
+ /**
831
+ * Extract arc-averaged Melbourne–Wübbena wide-lanes for one station from its
832
+ * epoch stream. The MW combination
833
+ * MW = (L1 − L2) − [(f1·C1 + f2·C2)/(f1+f2)] / (c/(f1−f2)) [cycles]
834
+ * is geometry-, clock- and (first-order) ionosphere-free, so it holds the
835
+ * wide-lane ambiguity plus biases and is near-constant within an arc. Arcs
836
+ * are split on a running-mean jump (cycle slip) or a time gap.
837
+ */
838
+ declare function extractWidelaneArcs(station: string, epochs: {
839
+ timeMs: number;
840
+ obs: WlObs[];
841
+ }[], opts?: {
842
+ slipCyc?: number;
843
+ gapMs?: number;
844
+ minObs?: number;
845
+ }): WlArc[];
846
+ /** One continuous wide-lane arc at a station. */
847
+ interface WlArc {
848
+ station: string;
849
+ prn: string;
850
+ /** Arc-averaged Melbourne–Wübbena wide-lane float (cycles). */
851
+ wlFloat: number;
852
+ /** Number of epochs averaged (used as the weight). */
853
+ nObs: number;
854
+ }
855
+ interface WlFcbOptions {
856
+ /** Max iterations. Default 50. */
857
+ maxIter?: number;
858
+ /** Convergence threshold on the largest bias change (cycles). Default 1e-4. */
859
+ tol?: number;
860
+ /** Fix-rate acceptance window |resid| (cycles). Default 0.25. */
861
+ fixWindow?: number;
862
+ }
863
+ interface WlFcbResult {
864
+ /** Per-satellite wide-lane FCB (cycles, wrapped to [−0.5, 0.5)). */
865
+ satFcb: Map<string, number>;
866
+ /** Per-station wide-lane bias (cycles); the reference station is 0. */
867
+ rcvBias: Map<string, number>;
868
+ /** RMS of the post-fit arc residuals Ñ_wl − N − b_rcv − b_sat (cycles). */
869
+ residRms: number;
870
+ /** Fraction of arcs whose residual lies within `fixWindow` of an integer. */
871
+ fixRate: number;
872
+ /** Reference station pinning the datum. */
873
+ refStation: string;
874
+ iterations: number;
875
+ }
876
+ /**
877
+ * Estimate per-satellite wide-lane FCBs from a network of stations' arc
878
+ * wide-lane floats. Needs ≥2 stations sharing satellites to break the
879
+ * integer/bias entanglement.
880
+ */
881
+ declare function estimateWidelaneFcb(arcs: WlArc[], opts?: WlFcbOptions): WlFcbResult;
882
+
717
883
  /**
718
884
  * Single-point positioning (SPP) from pseudoranges and broadcast
719
885
  * ephemerides.
@@ -803,4 +969,4 @@ declare function ionoFree(p1: number, p2: number, f1: number, f2: number): numbe
803
969
  */
804
970
  declare function solveSpp(pseudoranges: Map<string, number>, ephemerides: Map<string, Ephemeris>, timeMs: number, opts?: SppOptions): SppSolution | null;
805
971
 
806
- export { type AntennaOffset, type CorrectionResult, type DgnssOptions, type DgnssSolution, type EphemerisSource, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type PppAntennaModel, type PppCorrectionConfig, type PppCorrections, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type SatGeom, type SppOptions, type SppSolution, type TropoMapping, buildPppAntenna, createPppCorrections, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch };
972
+ export { type AntennaOffset, type ArFixedSat, type ArOptions, type ArResult, type ArSat, type CorrectionResult, type DgnssOptions, type DgnssSolution, type EphemerisSource, IONO_L1_M_PER_TECU, type KlobucharCoeffs, type LambdaResult, type PppAntennaModel, type PppCorrectionConfig, type PppCorrections, type PppEpoch, type PppEpochContext, type PppEpochResult, type PppOptions, type PppSatObs, type PppSolution, type RawObservation, type RtkEpochMeasurements, RtkFloatEngine, type RtkFloatOptions, type RtkFloatSolution, type RtkMeasurement, type SatGeom, type SppOptions, type SppSolution, type TropoMapping, type WlArc, type WlFcbOptions, type WlFcbResult, type WlObs, buildPppAntenna, createPppCorrections, estimateWidelaneFcb, extractWidelaneArcs, gimSlantIonoDelayL1, gimVerticalTec, gmst, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, moonEcef, niellMapping, nlWavelength, resolvePppAmbiguities, satClockCorrection, solidEarthTide, solveDgnss, solvePpp, solveSpp, sunEcef, toRtkEpoch, wlWavelength };
@@ -3,6 +3,8 @@ import {
3
3
  RtkFloatEngine,
4
4
  buildPppAntenna,
5
5
  createPppCorrections,
6
+ estimateWidelaneFcb,
7
+ extractWidelaneArcs,
6
8
  gimSlantIonoDelayL1,
7
9
  gimVerticalTec,
8
10
  gmst,
@@ -12,14 +14,17 @@ import {
12
14
  lambdaSearch,
13
15
  moonEcef,
14
16
  niellMapping,
17
+ nlWavelength,
18
+ resolvePppAmbiguities,
15
19
  satClockCorrection,
16
20
  solidEarthTide,
17
21
  solveDgnss,
18
22
  solvePpp,
19
23
  solveSpp,
20
24
  sunEcef,
21
- toRtkEpoch
22
- } from "./chunk-CRFFUU5Y.js";
25
+ toRtkEpoch,
26
+ wlWavelength
27
+ } from "./chunk-HOH27N42.js";
23
28
  import "./chunk-MHGNKSSH.js";
24
29
  import "./chunk-37QNKGTC.js";
25
30
  import "./chunk-6FAL6P4G.js";
@@ -32,6 +37,8 @@ export {
32
37
  RtkFloatEngine,
33
38
  buildPppAntenna,
34
39
  createPppCorrections,
40
+ estimateWidelaneFcb,
41
+ extractWidelaneArcs,
35
42
  gimSlantIonoDelayL1,
36
43
  gimVerticalTec,
37
44
  gmst,
@@ -41,11 +48,14 @@ export {
41
48
  lambdaSearch,
42
49
  moonEcef,
43
50
  niellMapping,
51
+ nlWavelength,
52
+ resolvePppAmbiguities,
44
53
  satClockCorrection,
45
54
  solidEarthTide,
46
55
  solveDgnss,
47
56
  solvePpp,
48
57
  solveSpp,
49
58
  sunEcef,
50
- toRtkEpoch
59
+ toRtkEpoch,
60
+ wlWavelength
51
61
  };
package/dist/rinex.cjs CHANGED
@@ -23,15 +23,18 @@ __export(rinex_exports, {
23
23
  EMPTY_WARNINGS: () => EMPTY_WARNINGS,
24
24
  SYSTEM_ORDER: () => SYSTEM_ORDER,
25
25
  WarningAccumulator: () => WarningAccumulator,
26
+ biasMetres: () => biasMetres,
26
27
  clkBias: () => clkBias,
27
28
  createGzipLineSink: () => createGzipLineSink,
28
29
  crxDecompress: () => crxDecompress,
29
30
  crxRepair: () => crxRepair,
31
+ findSatBias: () => findSatBias,
30
32
  fmtD: () => fmtD,
31
33
  fmtF: () => fmtF,
32
34
  hdrLine: () => hdrLine,
33
35
  padL: () => padL,
34
36
  padR: () => padR,
37
+ parseBiasSinex: () => parseBiasSinex,
35
38
  parseClk: () => parseClk,
36
39
  parseCrxDataLine: () => parseCrxDataLine,
37
40
  parseIonex: () => parseIonex,
@@ -597,6 +600,7 @@ var SYSTEM_NAMES = {
597
600
  I: "NavIC",
598
601
  S: "SBAS"
599
602
  };
603
+ var C_LIGHT = 299792458;
600
604
 
601
605
  // src/rinex/parser.ts
602
606
  var CHUNK_SIZE = 2 * 1024 * 1024;
@@ -2450,6 +2454,81 @@ function clkBias(clk, prn, tMs) {
2450
2454
  return c[lo] + f * (c[lo + 1] - c[lo]);
2451
2455
  }
2452
2456
 
2457
+ // src/rinex/bias-sinex.ts
2458
+ function parseEpoch(s, openTo) {
2459
+ const m = /^(\d{4}):(\d{3}):(\d{5})$/.exec(s.trim());
2460
+ if (!m) return openTo;
2461
+ const y = +m[1];
2462
+ if (y === 0) return openTo;
2463
+ const doy = +m[2];
2464
+ const sod = +m[3];
2465
+ return Date.UTC(y, 0, 1) + (doy - 1) * 864e5 + sod * 1e3;
2466
+ }
2467
+ function parseBiasSinex(text) {
2468
+ const records = [];
2469
+ let inBlock = false;
2470
+ for (const line of text.split("\n")) {
2471
+ if (line.startsWith("+BIAS/SOLUTION")) {
2472
+ inBlock = true;
2473
+ continue;
2474
+ }
2475
+ if (line.startsWith("-BIAS/SOLUTION")) {
2476
+ inBlock = false;
2477
+ continue;
2478
+ }
2479
+ if (!inBlock || line.length < 65 || line.startsWith("*")) continue;
2480
+ const type = line.slice(1, 4).trim();
2481
+ if (type !== "DSB" && type !== "OSB" && type !== "ISB") continue;
2482
+ const prn = line.slice(11, 14).trim();
2483
+ const station = line.slice(15, 24).trim();
2484
+ const obs1 = line.slice(25, 29).trim();
2485
+ const obs2 = line.slice(30, 34).trim();
2486
+ const startMs = parseEpoch(line.slice(35, 49), -Infinity);
2487
+ const endMs = parseEpoch(line.slice(50, 64), Infinity);
2488
+ const tail = line.slice(65).trim().split(/\s+/);
2489
+ if (tail.length < 2) continue;
2490
+ const unit = tail[0];
2491
+ const value = Number(tail[1]);
2492
+ if (!Number.isFinite(value)) continue;
2493
+ records.push({
2494
+ type,
2495
+ prn,
2496
+ station,
2497
+ obs1,
2498
+ obs2,
2499
+ startMs,
2500
+ endMs,
2501
+ value,
2502
+ unit
2503
+ });
2504
+ }
2505
+ const bySat = /* @__PURE__ */ new Map();
2506
+ for (const r of records) {
2507
+ if (!r.prn || r.station) continue;
2508
+ let a = bySat.get(r.prn);
2509
+ if (!a) {
2510
+ a = [];
2511
+ bySat.set(r.prn, a);
2512
+ }
2513
+ a.push(r);
2514
+ }
2515
+ return { records, bySat };
2516
+ }
2517
+ function biasMetres(r) {
2518
+ return r.unit === "ns" ? r.value * 1e-9 * C_LIGHT : r.value;
2519
+ }
2520
+ function findSatBias(bias, prn, obs1, obs2, tMs) {
2521
+ const recs = bias.bySat.get(prn);
2522
+ if (!recs) return null;
2523
+ for (const r of recs) {
2524
+ if (r.obs1 !== obs1) continue;
2525
+ if (obs2 === void 0 ? r.obs2 !== "" : r.obs2 !== obs2) continue;
2526
+ if (tMs != null && (tMs < r.startMs || tMs > r.endMs)) continue;
2527
+ return r;
2528
+ }
2529
+ return null;
2530
+ }
2531
+
2453
2532
  // src/rinex/obs-writer-common.ts
2454
2533
  function createGzipLineSink() {
2455
2534
  const encoder = new TextEncoder();
@@ -2828,15 +2907,18 @@ function writeRinex4ObsBlob(header, epochs, obsTypes) {
2828
2907
  EMPTY_WARNINGS,
2829
2908
  SYSTEM_ORDER,
2830
2909
  WarningAccumulator,
2910
+ biasMetres,
2831
2911
  clkBias,
2832
2912
  createGzipLineSink,
2833
2913
  crxDecompress,
2834
2914
  crxRepair,
2915
+ findSatBias,
2835
2916
  fmtD,
2836
2917
  fmtF,
2837
2918
  hdrLine,
2838
2919
  padL,
2839
2920
  padR,
2921
+ parseBiasSinex,
2840
2922
  parseClk,
2841
2923
  parseCrxDataLine,
2842
2924
  parseIonex,
package/dist/rinex.d.cts CHANGED
@@ -182,6 +182,54 @@ interface Nav4Input {
182
182
  */
183
183
  declare function writeRinexNav4(nav: Nav4Input): string;
184
184
 
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
+
185
233
  /**
186
234
  * RINEX 3.04 / 4.01 observation file writer.
187
235
  *
@@ -263,4 +311,4 @@ declare function createGzipLineSink(): {
263
311
  */
264
312
  declare function stationHeaderLines(header: RinexHeader): string[];
265
313
 
266
- export { 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, padL, padR, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
314
+ 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, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
package/dist/rinex.d.ts CHANGED
@@ -182,6 +182,54 @@ interface Nav4Input {
182
182
  */
183
183
  declare function writeRinexNav4(nav: Nav4Input): string;
184
184
 
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
+
185
233
  /**
186
234
  * RINEX 3.04 / 4.01 observation file writer.
187
235
  *
@@ -263,4 +311,4 @@ declare function createGzipLineSink(): {
263
311
  */
264
312
  declare function stationHeaderLines(header: RinexHeader): string[];
265
313
 
266
- export { 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, padL, padR, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
314
+ 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, padL, padR, parseBiasSinex, parseCrxDataLine, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob };
package/dist/rinex.js CHANGED
@@ -1,12 +1,15 @@
1
1
  import {
2
2
  EMPTY_WARNINGS,
3
3
  WarningAccumulator,
4
+ biasMetres,
4
5
  createGzipLineSink,
6
+ findSatBias,
5
7
  fmtD,
6
8
  fmtF,
7
9
  hdrLine,
8
10
  padL,
9
11
  padR,
12
+ parseBiasSinex,
10
13
  parseIonex,
11
14
  parseNavFile,
12
15
  stationHeaderLines,
@@ -17,7 +20,7 @@ import {
17
20
  writeRinexNav,
18
21
  writeRinexNav4,
19
22
  writeRinexObsBlob
20
- } from "./chunk-KDM2NVBO.js";
23
+ } from "./chunk-5RNDQQ6J.js";
21
24
  import "./chunk-726LQBGM.js";
22
25
  import "./chunk-IQ5OIMQD.js";
23
26
  import {
@@ -40,15 +43,18 @@ export {
40
43
  EMPTY_WARNINGS,
41
44
  SYSTEM_ORDER,
42
45
  WarningAccumulator,
46
+ biasMetres,
43
47
  clkBias,
44
48
  createGzipLineSink,
45
49
  crxDecompress,
46
50
  crxRepair,
51
+ findSatBias,
47
52
  fmtD,
48
53
  fmtF,
49
54
  hdrLine,
50
55
  padL,
51
56
  padR,
57
+ parseBiasSinex,
52
58
  parseClk,
53
59
  parseCrxDataLine,
54
60
  parseIonex,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gnss-js",
3
- "version": "1.30.0",
3
+ "version": "1.32.0",
4
4
  "description": "Comprehensive GNSS library for JavaScript — time scales, coordinates, RINEX parsing, RTCM3 decoding, orbit computation, and signal analysis",
5
5
  "type": "module",
6
6
  "sideEffects": false,