gnss-js 1.65.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -81,7 +81,9 @@ __export(src_exports, {
81
81
  OMEGA_E: () => OMEGA_E,
82
82
  REFERENCE_FRAMES: () => REFERENCE_FRAMES,
83
83
  RINEX_CODES: () => RINEX_CODES,
84
+ RTCM2_MESSAGE_NAMES: () => RTCM2_MESSAGE_NAMES,
84
85
  RTCM3_MESSAGE_NAMES: () => RTCM3_MESSAGE_NAMES,
86
+ Rtcm2Decoder: () => Rtcm2Decoder,
85
87
  Rtcm3Decoder: () => Rtcm3Decoder,
86
88
  RtkFloatEngine: () => RtkFloatEngine,
87
89
  SBAS_L5_MT_NAMES: () => SBAS_L5_MT_NAMES,
@@ -147,6 +149,7 @@ __export(src_exports, {
147
149
  decodeIgsSsr: () => decodeIgsSsr,
148
150
  decodeLegacyObs: () => decodeLegacyObs,
149
151
  decodeMsmFull: () => decodeMsmFull,
152
+ decodeObs: () => decodeObs,
150
153
  decodeSbfNavigation: () => decodeSbfNavigation,
151
154
  decodeSsr: () => decodeSsr,
152
155
  decodeSystemParams: () => decodeSystemParams,
@@ -247,13 +250,14 @@ __export(src_exports, {
247
250
  klobucharDelay: () => klobucharDelay,
248
251
  lambdaReduction: () => lambdaReduction,
249
252
  lambdaSearch: () => lambdaSearch,
253
+ looksLikeRtcm2: () => looksLikeRtcm2,
250
254
  maskRadForAzimuth: () => maskRadForAzimuth,
251
255
  moonEcef: () => moonEcef,
252
- msmEpochToDate: () => msmEpochToDate,
253
256
  navTimesFromEph: () => navTimesFromEph,
254
257
  niellMapping: () => niellMapping,
255
258
  nlWavelength: () => nlWavelength,
256
259
  nmeaCoordToDecimal: () => nmeaCoordToDecimal,
260
+ obsEpochToDate: () => obsEpochToDate,
257
261
  oem4Frames: () => oem4Frames,
258
262
  padL: () => padL,
259
263
  padR: () => padR,
@@ -306,6 +310,11 @@ __export(src_exports, {
306
310
  resetGloFreqCache: () => resetGloFreqCache,
307
311
  resolvePppAmbiguities: () => resolvePppAmbiguities,
308
312
  rhumbLine: () => rhumbLine,
313
+ rtcm2Dgps: () => rtcm2Dgps,
314
+ rtcm2Observation: () => rtcm2Observation,
315
+ rtcm2Station: () => rtcm2Station,
316
+ rtcm2Text: () => rtcm2Text,
317
+ rtcm2Time: () => rtcm2Time,
309
318
  rtcm3Constellation: () => rtcm3Constellation,
310
319
  satClockCorrection: () => satClockCorrection,
311
320
  sbasIonoDeg: () => sbasIonoDeg,
@@ -4476,6 +4485,265 @@ function writeRinex4ObsBlob(header, epochs, obsTypes) {
4476
4485
  });
4477
4486
  }
4478
4487
 
4488
+ // src/rtcm2/index.ts
4489
+ var RTCM2_PREAMBLE = 102;
4490
+ var HAMMING = [
4491
+ 3139384448,
4492
+ 1569692224,
4493
+ 2932329728,
4494
+ 1466164864,
4495
+ 1806824256,
4496
+ 2340063680
4497
+ ];
4498
+ function getbitu(buff, pos, len) {
4499
+ let v = 0;
4500
+ for (let i = pos; i < pos + len; i++)
4501
+ v = v * 2 + (buff[i >> 3] >> 7 - (i & 7) & 1);
4502
+ return v >>> 0;
4503
+ }
4504
+ function getbits(buff, pos, len) {
4505
+ const v = getbitu(buff, pos, len);
4506
+ return v & 1 << len - 1 ? v - 2 ** len : v;
4507
+ }
4508
+ function decodeWord(w) {
4509
+ let word = w >>> 0;
4510
+ if (word & 1073741824) word = (word ^ 1073741760) >>> 0;
4511
+ let parity = 0;
4512
+ for (let i = 0; i < 6; i++) {
4513
+ parity <<= 1;
4514
+ let x = (word & HAMMING[i]) >>> 6;
4515
+ while (x) {
4516
+ parity ^= x & 1;
4517
+ x >>>= 1;
4518
+ }
4519
+ }
4520
+ if (parity >>> 0 !== (word & 63)) return null;
4521
+ return [word >>> 22 & 255, word >>> 14 & 255, word >>> 6 & 255];
4522
+ }
4523
+ var Rtcm2Decoder = class {
4524
+ word = 0;
4525
+ nbyte = 0;
4526
+ nbit = 0;
4527
+ len = 0;
4528
+ buff = new Uint8Array(256);
4529
+ /** Reset the framer (e.g. after a stream reconnect). */
4530
+ reset() {
4531
+ this.word = 0;
4532
+ this.nbyte = 0;
4533
+ this.nbit = 0;
4534
+ this.len = 0;
4535
+ }
4536
+ decode(bytes) {
4537
+ const frames = [];
4538
+ for (const raw of bytes) {
4539
+ if ((raw & 192) !== 64) continue;
4540
+ let data = raw;
4541
+ for (let i = 0; i < 6; i++, data >>= 1) {
4542
+ this.word = (this.word << 1 | data & 1) >>> 0;
4543
+ if (this.nbyte === 0) {
4544
+ let preamb = this.word >>> 22 & 255;
4545
+ if (this.word & 1073741824) preamb ^= 255;
4546
+ if (preamb !== RTCM2_PREAMBLE) continue;
4547
+ const d2 = decodeWord(this.word);
4548
+ if (!d2) continue;
4549
+ this.buff[0] = d2[0];
4550
+ this.buff[1] = d2[1];
4551
+ this.buff[2] = d2[2];
4552
+ this.nbyte = 3;
4553
+ this.nbit = 0;
4554
+ continue;
4555
+ }
4556
+ if (++this.nbit < 30) continue;
4557
+ this.nbit = 0;
4558
+ const d = decodeWord(this.word);
4559
+ if (!d) {
4560
+ this.nbyte = 0;
4561
+ this.word &= 3;
4562
+ continue;
4563
+ }
4564
+ this.buff[this.nbyte] = d[0];
4565
+ this.buff[this.nbyte + 1] = d[1];
4566
+ this.buff[this.nbyte + 2] = d[2];
4567
+ this.nbyte += 3;
4568
+ if (this.nbyte === 6) this.len = (this.buff[5] >> 3) * 3 + 6;
4569
+ if (this.nbyte < this.len) continue;
4570
+ frames.push(this.readHeader(this.buff.slice(0, this.len)));
4571
+ this.nbyte = 0;
4572
+ this.word &= 3;
4573
+ }
4574
+ }
4575
+ return frames;
4576
+ }
4577
+ readHeader(payload) {
4578
+ return {
4579
+ messageType: getbitu(payload, 8, 6),
4580
+ stationId: getbitu(payload, 14, 10),
4581
+ zcountSec: getbitu(payload, 24, 13) * 0.6,
4582
+ sequenceNo: getbitu(payload, 37, 3),
4583
+ lengthWords: payload[5] >> 3,
4584
+ health: getbitu(payload, 45, 3),
4585
+ payload
4586
+ };
4587
+ }
4588
+ };
4589
+ function rtcm2Station(frame) {
4590
+ const p = frame.payload;
4591
+ const nbit = frame.lengthWords * 24;
4592
+ if (frame.messageType === 3) {
4593
+ if (nbit < 96) return null;
4594
+ return {
4595
+ position: [
4596
+ getbits(p, 48, 32) * 0.01,
4597
+ getbits(p, 80, 32) * 0.01,
4598
+ getbits(p, 112, 32) * 0.01
4599
+ ]
4600
+ };
4601
+ }
4602
+ if (frame.messageType === 22) {
4603
+ if (nbit < 24) return null;
4604
+ const l1 = [
4605
+ getbits(p, 48, 8) / 25600,
4606
+ getbits(p, 56, 8) / 25600,
4607
+ getbits(p, 64, 8) / 25600
4608
+ ];
4609
+ let height;
4610
+ if (nbit >= 48) {
4611
+ const noh = getbits(p, 48 + 24 + 5, 1);
4612
+ height = noh ? 0 : getbitu(p, 48 + 24 + 6, 18) / 25600;
4613
+ }
4614
+ return { l1Offset: l1, height };
4615
+ }
4616
+ return null;
4617
+ }
4618
+ function rtcm2Observation(frame) {
4619
+ const t = frame.messageType;
4620
+ if (t !== 18 && t !== 19) return null;
4621
+ const p = frame.payload;
4622
+ const nbit = frame.lengthWords * 24 + 48;
4623
+ let i = 48;
4624
+ if (i + 24 > nbit) return null;
4625
+ const fRaw = getbitu(p, i, 2);
4626
+ i += 4;
4627
+ const microSec = getbitu(p, i, 20);
4628
+ i += 20;
4629
+ if (fRaw & 1) return null;
4630
+ const freq = fRaw >> 1;
4631
+ let sync = false;
4632
+ const records = [];
4633
+ while (i + 48 <= nbit) {
4634
+ sync = getbitu(p, i, 1) === 1;
4635
+ i += 1;
4636
+ const code = getbitu(p, i, 1);
4637
+ i += 1;
4638
+ const sys = getbitu(p, i, 1);
4639
+ i += 1;
4640
+ let prn = getbitu(p, i, 5);
4641
+ i += 5;
4642
+ let loss;
4643
+ if (t === 18) {
4644
+ i += 3;
4645
+ loss = getbitu(p, i, 5);
4646
+ i += 5;
4647
+ } else {
4648
+ i += 8;
4649
+ }
4650
+ const val = t === 18 ? getbits(p, i, 32) : getbitu(p, i, 32);
4651
+ i += 32;
4652
+ if (prn === 0) prn = 32;
4653
+ const system = sys ? "R" : "G";
4654
+ const rec = {
4655
+ prn: `${system}${String(prn).padStart(2, "0")}`,
4656
+ system,
4657
+ freq,
4658
+ code: code ? "P" : "C/A",
4659
+ lossOfLock: loss
4660
+ };
4661
+ if (t === 18)
4662
+ rec.phaseCycles = -val / 256;
4663
+ else rec.pseudorangeM = val * 0.02;
4664
+ records.push(rec);
4665
+ }
4666
+ return { freq, sync, microSec, records };
4667
+ }
4668
+ function rtcm2Dgps(frame) {
4669
+ const t = frame.messageType;
4670
+ if (t !== 1 && t !== 9 && t !== 31) return null;
4671
+ const system = t === 31 ? "R" : "G";
4672
+ const p = frame.payload;
4673
+ const nbit = frame.lengthWords * 24 + 48;
4674
+ let i = 48;
4675
+ const corrections = [];
4676
+ while (i + 40 <= nbit) {
4677
+ const fact = getbitu(p, i, 1);
4678
+ i += 1;
4679
+ const udre = getbitu(p, i, 2);
4680
+ i += 2;
4681
+ let prn = getbitu(p, i, 5);
4682
+ i += 5;
4683
+ const prc = getbits(p, i, 16);
4684
+ i += 16;
4685
+ const rrc = getbits(p, i, 8);
4686
+ i += 8;
4687
+ const iod = getbits(p, i, 8);
4688
+ i += 8;
4689
+ if (prn === 0) prn = 32;
4690
+ corrections.push({
4691
+ prn: `${system}${String(prn).padStart(2, "0")}`,
4692
+ prc: prc * (fact ? 0.32 : 0.02),
4693
+ rrc: rrc * (fact ? 0.032 : 2e-3),
4694
+ iod,
4695
+ udre
4696
+ });
4697
+ }
4698
+ return { system, corrections };
4699
+ }
4700
+ function rtcm2Time(frame) {
4701
+ if (frame.messageType !== 14) return null;
4702
+ const p = frame.payload;
4703
+ if (frame.lengthWords * 24 < 24) return null;
4704
+ return {
4705
+ zcountSec: getbitu(p, 24, 13) * 0.6,
4706
+ week: getbitu(p, 48, 10),
4707
+ hour: getbitu(p, 58, 8),
4708
+ leapSeconds: getbitu(p, 66, 6)
4709
+ };
4710
+ }
4711
+ function rtcm2Text(frame) {
4712
+ if (frame.messageType !== 16) return null;
4713
+ const p = frame.payload;
4714
+ const nbit = frame.lengthWords * 24 + 48;
4715
+ let s = "";
4716
+ for (let i = 48; i + 8 <= nbit; i += 8) {
4717
+ const c = getbitu(p, i, 8);
4718
+ if (c === 0) break;
4719
+ s += String.fromCharCode(c);
4720
+ }
4721
+ return s;
4722
+ }
4723
+ var RTCM2_MESSAGE_NAMES = {
4724
+ 1: "GPS differential corrections",
4725
+ 3: "Reference station parameters (ARP)",
4726
+ 9: "GPS partial correction set",
4727
+ 14: "GPS time of week",
4728
+ 16: "GPS special message (text)",
4729
+ 17: "GPS ephemerides",
4730
+ 18: "RTK uncorrected carrier phase",
4731
+ 19: "RTK uncorrected pseudorange",
4732
+ 22: "Extended reference station parameters",
4733
+ 23: "Antenna type definition",
4734
+ 24: "Antenna reference point (ARP)",
4735
+ 31: "GLONASS differential corrections",
4736
+ 32: "GLONASS reference station parameters",
4737
+ 34: "GLONASS partial correction set",
4738
+ 36: "GLONASS special message"
4739
+ };
4740
+ function looksLikeRtcm2(bytes) {
4741
+ const n = Math.min(bytes.length, 4096);
4742
+ if (n < 12) return false;
4743
+ for (let i = 0; i < n; i++) if ((bytes[i] & 192) !== 64) return false;
4744
+ return new Rtcm2Decoder().decode(bytes.subarray(0, n)).length >= 2;
4745
+ }
4746
+
4479
4747
  // src/rtcm3/decoder.ts
4480
4748
  var debugHandler = null;
4481
4749
  function setRtcm3DebugHandler(fn) {
@@ -4520,9 +4788,6 @@ var BitReader = class {
4520
4788
  skip(n) {
4521
4789
  this.bitPos += n;
4522
4790
  }
4523
- get bitsLeft() {
4524
- return this.data.length * 8 - this.bitPos;
4525
- }
4526
4791
  };
4527
4792
  function crc24q2(data, length) {
4528
4793
  let crc = 0;
@@ -5024,7 +5289,7 @@ function decodeEphemeris(frame) {
5024
5289
  }
5025
5290
  }
5026
5291
 
5027
- // src/rtcm3/igs-ssr.ts
5292
+ // src/rtcm3/ssr-common.ts
5028
5293
  var UPDATE_INTERVAL_S = [
5029
5294
  1,
5030
5295
  2,
@@ -5043,6 +5308,28 @@ var UPDATE_INTERVAL_S = [
5043
5308
  7200,
5044
5309
  10800
5045
5310
  ];
5311
+ function ssrUraMm(v) {
5312
+ if (v === 0) return null;
5313
+ const cls = v >> 3 & 7;
5314
+ const val = v & 7;
5315
+ return 3 ** cls * (1 + val / 4) - 1;
5316
+ }
5317
+ function readSsrOrbit(r, sat) {
5318
+ sat.iode = r.readU(8);
5319
+ sat.deltaRadial = r.readS(22) * 1e-4;
5320
+ sat.deltaAlongTrack = r.readS(20) * 4e-4;
5321
+ sat.deltaCrossTrack = r.readS(20) * 4e-4;
5322
+ sat.dotRadial = r.readS(21) * 1e-6;
5323
+ sat.dotAlongTrack = r.readS(19) * 4e-6;
5324
+ sat.dotCrossTrack = r.readS(19) * 4e-6;
5325
+ }
5326
+ function readSsrClock(r, sat) {
5327
+ sat.c0 = r.readS(22) * 1e-4;
5328
+ sat.c1 = r.readS(21) * 1e-6;
5329
+ sat.c2 = r.readS(27) * 2e-8;
5330
+ }
5331
+
5332
+ // src/rtcm3/igs-ssr.ts
5046
5333
  var SYSTEM_BY_BASE = {
5047
5334
  20: "G",
5048
5335
  40: "R",
@@ -5066,12 +5353,6 @@ function prnFor(system, id) {
5066
5353
  if (system === "S") return `S${two(19 + id)}`;
5067
5354
  return `${system}${two(id)}`;
5068
5355
  }
5069
- function ssrUraMm(v) {
5070
- if (v === 0) return null;
5071
- const cls = v >> 3 & 7;
5072
- const val = v & 7;
5073
- return 3 ** cls * (1 + val / 4) - 1;
5074
- }
5075
5356
  function decodeIgsSsr(frame) {
5076
5357
  if (frame.messageType !== 4076) return null;
5077
5358
  const r = new BitReader(frame.payload);
@@ -5098,26 +5379,12 @@ function decodeIgsSsr(frame) {
5098
5379
  mwConsistency = r.readU(1) === 1;
5099
5380
  }
5100
5381
  const nsat = r.readU(6);
5101
- const readOrbit = (s) => {
5102
- s.iode = r.readU(8);
5103
- s.deltaRadial = r.readS(22) * 1e-4;
5104
- s.deltaAlongTrack = r.readS(20) * 4e-4;
5105
- s.deltaCrossTrack = r.readS(20) * 4e-4;
5106
- s.dotRadial = r.readS(21) * 1e-6;
5107
- s.dotAlongTrack = r.readS(19) * 4e-6;
5108
- s.dotCrossTrack = r.readS(19) * 4e-6;
5109
- };
5110
- const readClock2 = (s) => {
5111
- s.c0 = r.readS(22) * 1e-4;
5112
- s.c1 = r.readS(21) * 1e-6;
5113
- s.c2 = r.readS(27) * 2e-8;
5114
- };
5115
5382
  const satellites = [];
5116
5383
  for (let i = 0; i < nsat; i++) {
5117
5384
  const id = r.readU(6);
5118
5385
  const sat = { prn: prnFor(system, id) };
5119
- if (kind === "orbit" || kind === "combined") readOrbit(sat);
5120
- if (kind === "clock" || kind === "combined") readClock2(sat);
5386
+ if (kind === "orbit" || kind === "combined") readSsrOrbit(r, sat);
5387
+ if (kind === "clock" || kind === "combined") readSsrClock(r, sat);
5121
5388
  else if (kind === "ura")
5122
5389
  sat.uraMm = ssrUraMm(r.readU(6));
5123
5390
  else if (kind === "highRateClock")
@@ -5210,116 +5477,6 @@ function decodeIono(r, version, im) {
5210
5477
  };
5211
5478
  }
5212
5479
 
5213
- // src/rtcm3/legacy-obs.ts
5214
- var PRUNIT_GPS = 299792.458;
5215
- var PRUNIT_GLO = 599584.916;
5216
- var LAM_GPS_L1 = C_LIGHT / 157542e4;
5217
- var LAM_GPS_L2 = C_LIGHT / 12276e5;
5218
- var PPR_INVALID = -(2 ** 19);
5219
- var PR21_INVALID = -(2 ** 13);
5220
- function legacyLockSec(i) {
5221
- if (i < 24) return i;
5222
- if (i < 48) return 2 * i - 24;
5223
- if (i < 72) return 4 * i - 120;
5224
- if (i < 96) return 8 * i - 408;
5225
- if (i < 120) return 16 * i - 1176;
5226
- if (i < 127) return 32 * i - 3096;
5227
- return 937;
5228
- }
5229
- var two2 = (n) => n.toString().padStart(2, "0");
5230
- function decodeLegacyObs(frame) {
5231
- const type = frame.messageType;
5232
- const gps = type >= 1001 && type <= 1004;
5233
- const glo = type >= 1009 && type <= 1012;
5234
- if (!gps && !glo) return null;
5235
- const ext = type === 1002 || type === 1004 || type === 1010 || type === 1012;
5236
- const dual = type === 1003 || type === 1004 || type === 1011 || type === 1012;
5237
- const system = gps ? "G" : "R";
5238
- const r = new BitReader(frame.payload);
5239
- r.readU(12);
5240
- r.readU(12);
5241
- let epochMs;
5242
- let nsat;
5243
- if (gps) {
5244
- epochMs = r.readU(30);
5245
- r.readU(1);
5246
- nsat = r.readU(5);
5247
- r.readU(1);
5248
- r.readU(3);
5249
- } else {
5250
- const tk = r.readU(27);
5251
- r.readU(1);
5252
- nsat = r.readU(5);
5253
- r.readU(1);
5254
- r.readU(3);
5255
- const gloDow = new Date(Date.now() + 3 * 36e5).getUTCDay();
5256
- epochMs = (gloDow << 27 | tk) >>> 0;
5257
- }
5258
- const observations = [];
5259
- for (let s = 0; s < nsat; s++) {
5260
- const satId = r.readU(6);
5261
- const code1 = r.readU(1);
5262
- const freqCh = glo ? r.readU(5) : 0;
5263
- const pr1raw = r.readU(gps ? 24 : 25);
5264
- const ppr1 = r.readS(20);
5265
- const lock1 = r.readU(7);
5266
- let amb = 0;
5267
- let cnr1 = 0;
5268
- if (ext) {
5269
- amb = r.readU(gps ? 8 : 7);
5270
- cnr1 = r.readU(8);
5271
- }
5272
- let code2 = 0;
5273
- let pr21 = 0;
5274
- let ppr2 = 0;
5275
- let lock2 = 0;
5276
- let cnr2 = 0;
5277
- if (dual) {
5278
- code2 = r.readU(2);
5279
- pr21 = r.readS(14);
5280
- ppr2 = r.readS(20);
5281
- lock2 = r.readU(7);
5282
- if (ext) cnr2 = r.readU(8);
5283
- }
5284
- if (gps && (satId < 1 || satId > 32)) continue;
5285
- if (glo && (satId < 1 || satId > 24)) continue;
5286
- const prunit = gps ? PRUNIT_GPS : PRUNIT_GLO;
5287
- const pr1 = pr1raw * 0.02 + amb * prunit;
5288
- const k = freqCh - 7;
5289
- const lamL1 = gps ? LAM_GPS_L1 : C_LIGHT / (GLO_F1_BASE + k * GLO_F1_STEP);
5290
- const lamL2 = gps ? LAM_GPS_L2 : C_LIGHT / (GLO_F2_BASE + k * GLO_F2_STEP);
5291
- const signals = [];
5292
- {
5293
- const sig = {
5294
- rinexCode: gps ? code1 ? "1W" : "1C" : code1 ? "1P" : "1C",
5295
- pseudorange: pr1,
5296
- wavelength: lamL1,
5297
- lockTime: legacyLockSec(lock1)
5298
- };
5299
- if (ppr1 !== PPR_INVALID) sig.phase = (pr1 + ppr1 * 5e-4) / lamL1;
5300
- if (ext && cnr1 > 0) sig.cn0 = cnr1 * 0.25;
5301
- signals.push(sig);
5302
- }
5303
- if (dual) {
5304
- const sig = {
5305
- rinexCode: gps ? code2 === 0 ? "2X" : "2W" : code2 === 0 ? "2C" : "2P",
5306
- wavelength: lamL2,
5307
- lockTime: legacyLockSec(lock2)
5308
- };
5309
- if (pr21 !== PR21_INVALID) sig.pseudorange = pr1 + pr21 * 0.02;
5310
- if (ppr2 !== PPR_INVALID) sig.phase = (pr1 + ppr2 * 5e-4) / lamL2;
5311
- if (ext && cnr2 > 0) sig.cn0 = cnr2 * 0.25;
5312
- signals.push(sig);
5313
- }
5314
- observations.push({
5315
- prn: `${system}${two2(satId)}`,
5316
- system,
5317
- signals
5318
- });
5319
- }
5320
- return { messageType: type, epochMs, system, observations };
5321
- }
5322
-
5323
5480
  // src/rtcm3/msm.ts
5324
5481
  var GPS_L1 = FREQ.G["1"];
5325
5482
  var GPS_L2 = FREQ.G["2"];
@@ -5818,7 +5975,7 @@ function decodeMsmFull(frame) {
5818
5975
  }
5819
5976
  var GPS_EPOCH = START_GPS_TIME.getTime();
5820
5977
  var MS_PER_WEEK = MILLISECONDS_IN_WEEK;
5821
- function msmEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
5978
+ function obsEpochToDate(sys, epochMs, refTime = /* @__PURE__ */ new Date()) {
5822
5979
  const refMs = refTime.getTime();
5823
5980
  if (sys === "R") {
5824
5981
  const dayOfWeek = epochMs >>> 27 & 7;
@@ -5854,25 +6011,120 @@ function resetGloFreqCache() {
5854
6011
  gloFreqNum.fill(-128);
5855
6012
  }
5856
6013
 
6014
+ // src/rtcm3/legacy-obs.ts
6015
+ var PRUNIT_GPS = 299792.458;
6016
+ var PRUNIT_GLO = 599584.916;
6017
+ var LAM_GPS_L1 = C_LIGHT / 157542e4;
6018
+ var LAM_GPS_L2 = C_LIGHT / 12276e5;
6019
+ var PPR_INVALID = -(2 ** 19);
6020
+ var PR21_INVALID = -(2 ** 13);
6021
+ function legacyLockSec(i) {
6022
+ if (i < 24) return i;
6023
+ if (i < 48) return 2 * i - 24;
6024
+ if (i < 72) return 4 * i - 120;
6025
+ if (i < 96) return 8 * i - 408;
6026
+ if (i < 120) return 16 * i - 1176;
6027
+ if (i < 127) return 32 * i - 3096;
6028
+ return 937;
6029
+ }
6030
+ var two2 = (n) => n.toString().padStart(2, "0");
6031
+ function decodeLegacyObs(frame) {
6032
+ const type = frame.messageType;
6033
+ const gps = type >= 1001 && type <= 1004;
6034
+ const glo = type >= 1009 && type <= 1012;
6035
+ if (!gps && !glo) return null;
6036
+ const ext = type === 1002 || type === 1004 || type === 1010 || type === 1012;
6037
+ const dual = type === 1003 || type === 1004 || type === 1011 || type === 1012;
6038
+ const system = gps ? "G" : "R";
6039
+ const r = new BitReader(frame.payload);
6040
+ r.readU(12);
6041
+ r.readU(12);
6042
+ let epochMs;
6043
+ let nsat;
6044
+ if (gps) {
6045
+ epochMs = r.readU(30);
6046
+ r.readU(1);
6047
+ nsat = r.readU(5);
6048
+ r.readU(1);
6049
+ r.readU(3);
6050
+ } else {
6051
+ const tk = r.readU(27);
6052
+ r.readU(1);
6053
+ nsat = r.readU(5);
6054
+ r.readU(1);
6055
+ r.readU(3);
6056
+ const gloDow = new Date(Date.now() + 3 * 36e5).getUTCDay();
6057
+ epochMs = (gloDow << 27 | tk) >>> 0;
6058
+ }
6059
+ const observations = [];
6060
+ for (let s = 0; s < nsat; s++) {
6061
+ const satId = r.readU(6);
6062
+ const code1 = r.readU(1);
6063
+ const freqCh = glo ? r.readU(5) : 0;
6064
+ const pr1raw = r.readU(gps ? 24 : 25);
6065
+ const ppr1 = r.readS(20);
6066
+ const lock1 = r.readU(7);
6067
+ let amb = 0;
6068
+ let cnr1 = 0;
6069
+ if (ext) {
6070
+ amb = r.readU(gps ? 8 : 7);
6071
+ cnr1 = r.readU(8);
6072
+ }
6073
+ let code2 = 0;
6074
+ let pr21 = 0;
6075
+ let ppr2 = 0;
6076
+ let lock2 = 0;
6077
+ let cnr2 = 0;
6078
+ if (dual) {
6079
+ code2 = r.readU(2);
6080
+ pr21 = r.readS(14);
6081
+ ppr2 = r.readS(20);
6082
+ lock2 = r.readU(7);
6083
+ if (ext) cnr2 = r.readU(8);
6084
+ }
6085
+ if (gps && (satId < 1 || satId > 32)) continue;
6086
+ if (glo && (satId < 1 || satId > 24)) continue;
6087
+ const prunit = gps ? PRUNIT_GPS : PRUNIT_GLO;
6088
+ const pr1 = pr1raw * 0.02 + amb * prunit;
6089
+ const k = freqCh - 7;
6090
+ const lamL1 = gps ? LAM_GPS_L1 : C_LIGHT / (GLO_F1_BASE + k * GLO_F1_STEP);
6091
+ const lamL2 = gps ? LAM_GPS_L2 : C_LIGHT / (GLO_F2_BASE + k * GLO_F2_STEP);
6092
+ const signals = [];
6093
+ {
6094
+ const sig = {
6095
+ rinexCode: gps ? code1 ? "1W" : "1C" : code1 ? "1P" : "1C",
6096
+ pseudorange: pr1,
6097
+ wavelength: lamL1,
6098
+ lockTime: legacyLockSec(lock1)
6099
+ };
6100
+ if (ppr1 !== PPR_INVALID) sig.phase = (pr1 + ppr1 * 5e-4) / lamL1;
6101
+ if (ext && cnr1 > 0) sig.cn0 = cnr1 * 0.25;
6102
+ signals.push(sig);
6103
+ }
6104
+ if (dual) {
6105
+ const sig = {
6106
+ rinexCode: gps ? code2 === 0 ? "2X" : "2W" : code2 === 0 ? "2C" : "2P",
6107
+ wavelength: lamL2,
6108
+ lockTime: legacyLockSec(lock2)
6109
+ };
6110
+ if (pr21 !== PR21_INVALID) sig.pseudorange = pr1 + pr21 * 0.02;
6111
+ if (ppr2 !== PPR_INVALID) sig.phase = (pr1 + ppr2 * 5e-4) / lamL2;
6112
+ if (ext && cnr2 > 0) sig.cn0 = cnr2 * 0.25;
6113
+ signals.push(sig);
6114
+ }
6115
+ observations.push({
6116
+ prn: `${system}${two2(satId)}`,
6117
+ system,
6118
+ signals
6119
+ });
6120
+ }
6121
+ return { messageType: type, epochMs, system, observations };
6122
+ }
6123
+ function decodeObs(frame) {
6124
+ return decodeMsmFull(frame) ?? decodeLegacyObs(frame);
6125
+ }
6126
+
5857
6127
  // src/rtcm3/ssr.ts
5858
- var UPDATE_INTERVAL_S2 = [
5859
- 1,
5860
- 2,
5861
- 5,
5862
- 10,
5863
- 15,
5864
- 30,
5865
- 60,
5866
- 120,
5867
- 240,
5868
- 300,
5869
- 600,
5870
- 900,
5871
- 1800,
5872
- 3600,
5873
- 7200,
5874
- 10800
5875
- ];
5876
6128
  var GPS_SIGNAL = {
5877
6129
  0: "L1 C/A",
5878
6130
  1: "L1 P",
@@ -5907,12 +6159,6 @@ var SSR_KIND = {
5907
6159
  1067: { system: "R", kind: "ura" },
5908
6160
  1068: { system: "R", kind: "highRateClock" }
5909
6161
  };
5910
- function ssrUraMm2(v) {
5911
- if (v === 0) return null;
5912
- const cls = v >> 3 & 7;
5913
- const val = v & 7;
5914
- return 3 ** cls * (1 + val / 4) - 1;
5915
- }
5916
6162
  var two3 = (n) => n.toString().padStart(2, "0");
5917
6163
  function decodeSsr(frame) {
5918
6164
  const spec = SSR_KIND[frame.messageType];
@@ -5922,7 +6168,7 @@ function decodeSsr(frame) {
5922
6168
  const r = new BitReader(frame.payload);
5923
6169
  r.readU(12);
5924
6170
  const epochS = r.readU(gps ? 20 : 17);
5925
- const updateIntervalS = UPDATE_INTERVAL_S2[r.readU(4)];
6171
+ const updateIntervalS = UPDATE_INTERVAL_S[r.readU(4)];
5926
6172
  const multipleMessage = r.readU(1) === 1;
5927
6173
  const hasDatum = kind === "orbit" || kind === "combined";
5928
6174
  const referenceDatum = hasDatum ? r.readU(1) : void 0;
@@ -5932,30 +6178,14 @@ function decodeSsr(frame) {
5932
6178
  const nsat = r.readU(6);
5933
6179
  const sigName = gps ? GPS_SIGNAL : GLO_SIGNAL;
5934
6180
  const satellites = [];
5935
- const readOrbit = (sat) => {
5936
- sat.deltaRadial = r.readS(22) * 1e-4;
5937
- sat.deltaAlongTrack = r.readS(20) * 4e-4;
5938
- sat.deltaCrossTrack = r.readS(20) * 4e-4;
5939
- sat.dotRadial = r.readS(21) * 1e-6;
5940
- sat.dotAlongTrack = r.readS(19) * 4e-6;
5941
- sat.dotCrossTrack = r.readS(19) * 4e-6;
5942
- };
5943
- const readClock2 = (sat) => {
5944
- sat.c0 = r.readS(22) * 1e-4;
5945
- sat.c1 = r.readS(21) * 1e-6;
5946
- sat.c2 = r.readS(27) * 2e-8;
5947
- };
5948
6181
  for (let i = 0; i < nsat; i++) {
5949
6182
  const satId = gps ? r.readU(6) : r.readU(5);
5950
6183
  const sat = { prn: `${system}${two3(satId)}` };
5951
- if (kind === "orbit" || kind === "combined") {
5952
- sat.iode = r.readU(8);
5953
- readOrbit(sat);
5954
- }
5955
- if (kind === "combined") readClock2(sat);
5956
- else if (kind === "clock") readClock2(sat);
6184
+ if (kind === "orbit" || kind === "combined") readSsrOrbit(r, sat);
6185
+ if (kind === "combined") readSsrClock(r, sat);
6186
+ else if (kind === "clock") readSsrClock(r, sat);
5957
6187
  else if (kind === "ura")
5958
- sat.uraMm = ssrUraMm2(r.readU(6));
6188
+ sat.uraMm = ssrUraMm(r.readU(6));
5959
6189
  else if (kind === "highRateClock")
5960
6190
  sat.highRateClock = r.readS(22) * 1e-4;
5961
6191
  else if (kind === "codeBias") {
@@ -6323,9 +6553,9 @@ function updateStreamStats(stats, frames, rawBytes) {
6323
6553
  entry.count++;
6324
6554
  entry.lastSeen = now;
6325
6555
  entry.totalBytes += frame.length + 6;
6326
- const msmEpoch = decodeMsmFull(frame);
6327
- if (msmEpoch) {
6328
- for (const obs of msmEpoch.observations) {
6556
+ const obsEpoch = decodeObs(frame);
6557
+ if (obsEpoch) {
6558
+ for (const obs of obsEpoch.observations) {
6329
6559
  const signals = [];
6330
6560
  let bestCn0 = 0;
6331
6561
  for (const sig of obs.signals) {
@@ -6334,7 +6564,7 @@ function updateStreamStats(stats, frames, rawBytes) {
6334
6564
  if (sig.cn0 > bestCn0) bestCn0 = sig.cn0;
6335
6565
  }
6336
6566
  }
6337
- if (signals.length > 0) {
6567
+ if (obs.signals.length > 0) {
6338
6568
  stats.satellites.set(obs.prn, {
6339
6569
  prn: obs.prn,
6340
6570
  system: obs.system,
@@ -18578,7 +18808,9 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
18578
18808
  OMEGA_E,
18579
18809
  REFERENCE_FRAMES,
18580
18810
  RINEX_CODES,
18811
+ RTCM2_MESSAGE_NAMES,
18581
18812
  RTCM3_MESSAGE_NAMES,
18813
+ Rtcm2Decoder,
18582
18814
  Rtcm3Decoder,
18583
18815
  RtkFloatEngine,
18584
18816
  SBAS_L5_MT_NAMES,
@@ -18644,6 +18876,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
18644
18876
  decodeIgsSsr,
18645
18877
  decodeLegacyObs,
18646
18878
  decodeMsmFull,
18879
+ decodeObs,
18647
18880
  decodeSbfNavigation,
18648
18881
  decodeSsr,
18649
18882
  decodeSystemParams,
@@ -18744,13 +18977,14 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
18744
18977
  klobucharDelay,
18745
18978
  lambdaReduction,
18746
18979
  lambdaSearch,
18980
+ looksLikeRtcm2,
18747
18981
  maskRadForAzimuth,
18748
18982
  moonEcef,
18749
- msmEpochToDate,
18750
18983
  navTimesFromEph,
18751
18984
  niellMapping,
18752
18985
  nlWavelength,
18753
18986
  nmeaCoordToDecimal,
18987
+ obsEpochToDate,
18754
18988
  oem4Frames,
18755
18989
  padL,
18756
18990
  padR,
@@ -18803,6 +19037,11 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
18803
19037
  resetGloFreqCache,
18804
19038
  resolvePppAmbiguities,
18805
19039
  rhumbLine,
19040
+ rtcm2Dgps,
19041
+ rtcm2Observation,
19042
+ rtcm2Station,
19043
+ rtcm2Text,
19044
+ rtcm2Time,
18806
19045
  rtcm3Constellation,
18807
19046
  satClockCorrection,
18808
19047
  sbasIonoDeg,