gnss-js 1.29.0 → 1.31.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/rinex.cjs CHANGED
@@ -23,14 +23,19 @@ __export(rinex_exports, {
23
23
  EMPTY_WARNINGS: () => EMPTY_WARNINGS,
24
24
  SYSTEM_ORDER: () => SYSTEM_ORDER,
25
25
  WarningAccumulator: () => WarningAccumulator,
26
+ biasMetres: () => biasMetres,
27
+ clkBias: () => clkBias,
26
28
  createGzipLineSink: () => createGzipLineSink,
27
29
  crxDecompress: () => crxDecompress,
28
30
  crxRepair: () => crxRepair,
31
+ findSatBias: () => findSatBias,
29
32
  fmtD: () => fmtD,
30
33
  fmtF: () => fmtF,
31
34
  hdrLine: () => hdrLine,
32
35
  padL: () => padL,
33
36
  padR: () => padR,
37
+ parseBiasSinex: () => parseBiasSinex,
38
+ parseClk: () => parseClk,
34
39
  parseCrxDataLine: () => parseCrxDataLine,
35
40
  parseIonex: () => parseIonex,
36
41
  parseNavFile: () => parseNavFile,
@@ -595,6 +600,7 @@ var SYSTEM_NAMES = {
595
600
  I: "NavIC",
596
601
  S: "SBAS"
597
602
  };
603
+ var C_LIGHT = 299792458;
598
604
 
599
605
  // src/rinex/parser.ts
600
606
  var CHUNK_SIZE = 2 * 1024 * 1024;
@@ -2388,6 +2394,141 @@ function sp3Position(sp3, prn, tMs, order = 9) {
2388
2394
  return { x, y, z, clk };
2389
2395
  }
2390
2396
 
2397
+ // src/rinex/clk.ts
2398
+ var GPS_EPOCH_MS4 = Date.UTC(1980, 0, 6);
2399
+ function parseClk(text) {
2400
+ const sats = {};
2401
+ let inData = false;
2402
+ for (const line of text.split("\n")) {
2403
+ if (!inData) {
2404
+ if (line.includes("END OF HEADER")) inData = true;
2405
+ continue;
2406
+ }
2407
+ if (line.length < 3 || line[0] !== "A" || line[1] !== "S") continue;
2408
+ const p = line.slice(2).trim().split(/\s+/);
2409
+ if (p.length < 9) continue;
2410
+ const prn = p[0];
2411
+ const y = +p[1];
2412
+ const mo = +p[2];
2413
+ const d = +p[3];
2414
+ const h = +p[4];
2415
+ const mi = +p[5];
2416
+ const s = +p[6];
2417
+ const bias = +p[8];
2418
+ if (!Number.isFinite(bias)) continue;
2419
+ const t = Date.UTC(y, mo - 1, d, h, mi, Math.floor(s)) + s % 1 * 1e3;
2420
+ let e = sats[prn];
2421
+ if (!e) {
2422
+ e = { t: [], c: [] };
2423
+ sats[prn] = e;
2424
+ }
2425
+ e.t.push(t);
2426
+ e.c.push(bias);
2427
+ }
2428
+ let intervalSec = 30;
2429
+ for (const e of Object.values(sats)) {
2430
+ if (e.t.length >= 2) {
2431
+ intervalSec = Math.round((e.t[1] - e.t[0]) / 1e3);
2432
+ break;
2433
+ }
2434
+ }
2435
+ return { sats, intervalSec };
2436
+ }
2437
+ function clkBias(clk, prn, tMs) {
2438
+ const e = clk.sats[prn];
2439
+ if (!e || e.t.length === 0) return null;
2440
+ const { t, c } = e;
2441
+ let lo = 0;
2442
+ let hi = t.length - 1;
2443
+ if (tMs < t[0] || tMs > t[hi]) return null;
2444
+ while (lo < hi) {
2445
+ const mid = lo + hi + 1 >> 1;
2446
+ if (t[mid] <= tMs) lo = mid;
2447
+ else hi = mid - 1;
2448
+ }
2449
+ if (t[lo] === tMs || lo === t.length - 1) return c[lo];
2450
+ const t0 = t[lo];
2451
+ const t1 = t[lo + 1];
2452
+ if (t1 - t0 > clk.intervalSec * 1e3 * 4) return null;
2453
+ const f = (tMs - t0) / (t1 - t0);
2454
+ return c[lo] + f * (c[lo + 1] - c[lo]);
2455
+ }
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
+
2391
2532
  // src/rinex/obs-writer-common.ts
2392
2533
  function createGzipLineSink() {
2393
2534
  const encoder = new TextEncoder();
@@ -2766,14 +2907,19 @@ function writeRinex4ObsBlob(header, epochs, obsTypes) {
2766
2907
  EMPTY_WARNINGS,
2767
2908
  SYSTEM_ORDER,
2768
2909
  WarningAccumulator,
2910
+ biasMetres,
2911
+ clkBias,
2769
2912
  createGzipLineSink,
2770
2913
  crxDecompress,
2771
2914
  crxRepair,
2915
+ findSatBias,
2772
2916
  fmtD,
2773
2917
  fmtF,
2774
2918
  hdrLine,
2775
2919
  padL,
2776
2920
  padR,
2921
+ parseBiasSinex,
2922
+ parseClk,
2777
2923
  parseCrxDataLine,
2778
2924
  parseIonex,
2779
2925
  parseNavFile,
package/dist/rinex.d.cts CHANGED
@@ -2,7 +2,7 @@ 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
3
  import { a as NavResult, N as NavHeader, E as Ephemeris, R as RinexCnavEphemeris } from './nav-DImXUdbp.cjs';
4
4
  export { G as GlonassEphemeris, K as KeplerEphemeris, p as parseNavFile } from './nav-DImXUdbp.cjs';
5
- export { I as IonexGrid, S as Sp3File, a as Sp3Sample, p as parseIonex, b as parseSp3, s as sp3Position } from './sp3-BAq8l39b.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';
6
6
 
7
7
  /**
8
8
  * Compact RINEX (Hatanaka / CRX) decompression utilities.
@@ -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
@@ -2,7 +2,7 @@ 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
3
  import { a as NavResult, N as NavHeader, E as Ephemeris, R as RinexCnavEphemeris } from './nav-DImXUdbp.js';
4
4
  export { G as GlonassEphemeris, K as KeplerEphemeris, p as parseNavFile } from './nav-DImXUdbp.js';
5
- export { I as IonexGrid, S as Sp3File, a as Sp3Sample, p as parseIonex, b as parseSp3, s as sp3Position } from './sp3-BAq8l39b.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';
6
6
 
7
7
  /**
8
8
  * Compact RINEX (Hatanaka / CRX) decompression utilities.
@@ -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-6GTS5MVI.js";
23
+ } from "./chunk-5RNDQQ6J.js";
21
24
  import "./chunk-726LQBGM.js";
22
25
  import "./chunk-IQ5OIMQD.js";
23
26
  import {
@@ -30,22 +33,29 @@ import {
30
33
  systemName
31
34
  } from "./chunk-3U5AX7PY.js";
32
35
  import {
36
+ clkBias,
37
+ parseClk,
33
38
  parseSp3,
34
39
  sp3Position
35
- } from "./chunk-4KMWWCUR.js";
40
+ } from "./chunk-GPEP67TG.js";
36
41
  import "./chunk-FIEWO4J4.js";
37
42
  export {
38
43
  EMPTY_WARNINGS,
39
44
  SYSTEM_ORDER,
40
45
  WarningAccumulator,
46
+ biasMetres,
47
+ clkBias,
41
48
  createGzipLineSink,
42
49
  crxDecompress,
43
50
  crxRepair,
51
+ findSatBias,
44
52
  fmtD,
45
53
  fmtF,
46
54
  hdrLine,
47
55
  padL,
48
56
  padR,
57
+ parseBiasSinex,
58
+ parseClk,
49
59
  parseCrxDataLine,
50
60
  parseIonex,
51
61
  parseNavFile,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gnss-js",
3
- "version": "1.29.0",
3
+ "version": "1.31.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,