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/{chunk-6GTS5MVI.js → chunk-5RNDQQ6J.js} +81 -0
- package/dist/{chunk-5WHKMKIB.js → chunk-EVFD4UNZ.js} +98 -4
- package/dist/{chunk-4KMWWCUR.js → chunk-GPEP67TG.js} +63 -1
- package/dist/{sp3-BAq8l39b.d.ts → clk-DGVBGRzA.d.cts} +27 -1
- package/dist/{sp3-BAq8l39b.d.cts → clk-DGVBGRzA.d.ts} +27 -1
- package/dist/index.cjs +284 -43
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +20 -4
- package/dist/positioning.cjs +123 -5
- package/dist/positioning.d.cts +86 -2
- package/dist/positioning.d.ts +86 -2
- package/dist/positioning.js +10 -4
- package/dist/rinex.cjs +146 -0
- package/dist/rinex.d.cts +50 -2
- package/dist/rinex.d.ts +50 -2
- package/dist/rinex.js +12 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -111,6 +111,7 @@ __export(src_exports, {
|
|
|
111
111
|
analyzeQuality: () => analyzeQuality,
|
|
112
112
|
applyHelmert: () => applyHelmert,
|
|
113
113
|
applyIonoDcb: () => applyIonoDcb,
|
|
114
|
+
biasMetres: () => biasMetres,
|
|
114
115
|
binexCrc16: () => binexCrc16,
|
|
115
116
|
binexCrc32: () => binexCrc32,
|
|
116
117
|
binexCsum8: () => binexCsum8,
|
|
@@ -119,6 +120,7 @@ __export(src_exports, {
|
|
|
119
120
|
buildObsIndices: () => buildObsIndices,
|
|
120
121
|
buildPppAntenna: () => buildPppAntenna,
|
|
121
122
|
clampUnit: () => clampUnit,
|
|
123
|
+
clkBias: () => clkBias,
|
|
122
124
|
computeAllPositions: () => computeAllPositions,
|
|
123
125
|
computeDop: () => computeDop,
|
|
124
126
|
computeIonoRate: () => computeIonoRate,
|
|
@@ -149,6 +151,7 @@ __export(src_exports, {
|
|
|
149
151
|
ephInfoToEphemeris: () => ephInfoToEphemeris,
|
|
150
152
|
euclidean3D: () => euclidean3D,
|
|
151
153
|
fetchSourcetable: () => fetchSourcetable,
|
|
154
|
+
findSatBias: () => findSatBias,
|
|
152
155
|
fmtD: () => fmtD,
|
|
153
156
|
fmtF: () => fmtF,
|
|
154
157
|
formatUTCTime: () => formatUTCTime,
|
|
@@ -231,12 +234,15 @@ __export(src_exports, {
|
|
|
231
234
|
msmEpochToDate: () => msmEpochToDate,
|
|
232
235
|
navTimesFromEph: () => navTimesFromEph,
|
|
233
236
|
niellMapping: () => niellMapping,
|
|
237
|
+
nlWavelength: () => nlWavelength,
|
|
234
238
|
nmeaCoordToDecimal: () => nmeaCoordToDecimal,
|
|
235
239
|
oem4Frames: () => oem4Frames,
|
|
236
240
|
padL: () => padL,
|
|
237
241
|
padR: () => padR,
|
|
238
242
|
parseAntex: () => parseAntex,
|
|
243
|
+
parseBiasSinex: () => parseBiasSinex,
|
|
239
244
|
parseBinex: () => parseBinex,
|
|
245
|
+
parseClk: () => parseClk,
|
|
240
246
|
parseCrxDataLine: () => parseCrxDataLine,
|
|
241
247
|
parseIonex: () => parseIonex,
|
|
242
248
|
parseNavFile: () => parseNavFile,
|
|
@@ -272,6 +278,7 @@ __export(src_exports, {
|
|
|
272
278
|
readString: () => readString,
|
|
273
279
|
reportDecodeError: () => reportDecodeError,
|
|
274
280
|
resetGloFreqCache: () => resetGloFreqCache,
|
|
281
|
+
resolvePppAmbiguities: () => resolvePppAmbiguities,
|
|
275
282
|
rhumbLine: () => rhumbLine,
|
|
276
283
|
rtcm3Constellation: () => rtcm3Constellation,
|
|
277
284
|
satClockCorrection: () => satClockCorrection,
|
|
@@ -297,6 +304,7 @@ __export(src_exports, {
|
|
|
297
304
|
updateStreamStats: () => updateStreamStats,
|
|
298
305
|
verifyChecksum: () => verifyChecksum,
|
|
299
306
|
vincenty: () => vincenty,
|
|
307
|
+
wlWavelength: () => wlWavelength,
|
|
300
308
|
writeCrx: () => writeCrx,
|
|
301
309
|
writeModernObsBlob: () => writeModernObsBlob,
|
|
302
310
|
writeRinex2ObsBlob: () => writeRinex2ObsBlob,
|
|
@@ -3896,6 +3904,141 @@ function sp3Position(sp3, prn, tMs, order = 9) {
|
|
|
3896
3904
|
return { x, y, z, clk };
|
|
3897
3905
|
}
|
|
3898
3906
|
|
|
3907
|
+
// src/rinex/clk.ts
|
|
3908
|
+
var GPS_EPOCH_MS4 = Date.UTC(1980, 0, 6);
|
|
3909
|
+
function parseClk(text) {
|
|
3910
|
+
const sats = {};
|
|
3911
|
+
let inData = false;
|
|
3912
|
+
for (const line of text.split("\n")) {
|
|
3913
|
+
if (!inData) {
|
|
3914
|
+
if (line.includes("END OF HEADER")) inData = true;
|
|
3915
|
+
continue;
|
|
3916
|
+
}
|
|
3917
|
+
if (line.length < 3 || line[0] !== "A" || line[1] !== "S") continue;
|
|
3918
|
+
const p = line.slice(2).trim().split(/\s+/);
|
|
3919
|
+
if (p.length < 9) continue;
|
|
3920
|
+
const prn = p[0];
|
|
3921
|
+
const y = +p[1];
|
|
3922
|
+
const mo = +p[2];
|
|
3923
|
+
const d = +p[3];
|
|
3924
|
+
const h = +p[4];
|
|
3925
|
+
const mi = +p[5];
|
|
3926
|
+
const s = +p[6];
|
|
3927
|
+
const bias = +p[8];
|
|
3928
|
+
if (!Number.isFinite(bias)) continue;
|
|
3929
|
+
const t = Date.UTC(y, mo - 1, d, h, mi, Math.floor(s)) + s % 1 * 1e3;
|
|
3930
|
+
let e = sats[prn];
|
|
3931
|
+
if (!e) {
|
|
3932
|
+
e = { t: [], c: [] };
|
|
3933
|
+
sats[prn] = e;
|
|
3934
|
+
}
|
|
3935
|
+
e.t.push(t);
|
|
3936
|
+
e.c.push(bias);
|
|
3937
|
+
}
|
|
3938
|
+
let intervalSec = 30;
|
|
3939
|
+
for (const e of Object.values(sats)) {
|
|
3940
|
+
if (e.t.length >= 2) {
|
|
3941
|
+
intervalSec = Math.round((e.t[1] - e.t[0]) / 1e3);
|
|
3942
|
+
break;
|
|
3943
|
+
}
|
|
3944
|
+
}
|
|
3945
|
+
return { sats, intervalSec };
|
|
3946
|
+
}
|
|
3947
|
+
function clkBias(clk, prn, tMs) {
|
|
3948
|
+
const e = clk.sats[prn];
|
|
3949
|
+
if (!e || e.t.length === 0) return null;
|
|
3950
|
+
const { t, c } = e;
|
|
3951
|
+
let lo = 0;
|
|
3952
|
+
let hi = t.length - 1;
|
|
3953
|
+
if (tMs < t[0] || tMs > t[hi]) return null;
|
|
3954
|
+
while (lo < hi) {
|
|
3955
|
+
const mid = lo + hi + 1 >> 1;
|
|
3956
|
+
if (t[mid] <= tMs) lo = mid;
|
|
3957
|
+
else hi = mid - 1;
|
|
3958
|
+
}
|
|
3959
|
+
if (t[lo] === tMs || lo === t.length - 1) return c[lo];
|
|
3960
|
+
const t0 = t[lo];
|
|
3961
|
+
const t1 = t[lo + 1];
|
|
3962
|
+
if (t1 - t0 > clk.intervalSec * 1e3 * 4) return null;
|
|
3963
|
+
const f = (tMs - t0) / (t1 - t0);
|
|
3964
|
+
return c[lo] + f * (c[lo + 1] - c[lo]);
|
|
3965
|
+
}
|
|
3966
|
+
|
|
3967
|
+
// src/rinex/bias-sinex.ts
|
|
3968
|
+
function parseEpoch(s, openTo) {
|
|
3969
|
+
const m = /^(\d{4}):(\d{3}):(\d{5})$/.exec(s.trim());
|
|
3970
|
+
if (!m) return openTo;
|
|
3971
|
+
const y = +m[1];
|
|
3972
|
+
if (y === 0) return openTo;
|
|
3973
|
+
const doy = +m[2];
|
|
3974
|
+
const sod = +m[3];
|
|
3975
|
+
return Date.UTC(y, 0, 1) + (doy - 1) * 864e5 + sod * 1e3;
|
|
3976
|
+
}
|
|
3977
|
+
function parseBiasSinex(text) {
|
|
3978
|
+
const records = [];
|
|
3979
|
+
let inBlock = false;
|
|
3980
|
+
for (const line of text.split("\n")) {
|
|
3981
|
+
if (line.startsWith("+BIAS/SOLUTION")) {
|
|
3982
|
+
inBlock = true;
|
|
3983
|
+
continue;
|
|
3984
|
+
}
|
|
3985
|
+
if (line.startsWith("-BIAS/SOLUTION")) {
|
|
3986
|
+
inBlock = false;
|
|
3987
|
+
continue;
|
|
3988
|
+
}
|
|
3989
|
+
if (!inBlock || line.length < 65 || line.startsWith("*")) continue;
|
|
3990
|
+
const type = line.slice(1, 4).trim();
|
|
3991
|
+
if (type !== "DSB" && type !== "OSB" && type !== "ISB") continue;
|
|
3992
|
+
const prn = line.slice(11, 14).trim();
|
|
3993
|
+
const station = line.slice(15, 24).trim();
|
|
3994
|
+
const obs1 = line.slice(25, 29).trim();
|
|
3995
|
+
const obs2 = line.slice(30, 34).trim();
|
|
3996
|
+
const startMs = parseEpoch(line.slice(35, 49), -Infinity);
|
|
3997
|
+
const endMs = parseEpoch(line.slice(50, 64), Infinity);
|
|
3998
|
+
const tail = line.slice(65).trim().split(/\s+/);
|
|
3999
|
+
if (tail.length < 2) continue;
|
|
4000
|
+
const unit = tail[0];
|
|
4001
|
+
const value = Number(tail[1]);
|
|
4002
|
+
if (!Number.isFinite(value)) continue;
|
|
4003
|
+
records.push({
|
|
4004
|
+
type,
|
|
4005
|
+
prn,
|
|
4006
|
+
station,
|
|
4007
|
+
obs1,
|
|
4008
|
+
obs2,
|
|
4009
|
+
startMs,
|
|
4010
|
+
endMs,
|
|
4011
|
+
value,
|
|
4012
|
+
unit
|
|
4013
|
+
});
|
|
4014
|
+
}
|
|
4015
|
+
const bySat = /* @__PURE__ */ new Map();
|
|
4016
|
+
for (const r of records) {
|
|
4017
|
+
if (!r.prn || r.station) continue;
|
|
4018
|
+
let a = bySat.get(r.prn);
|
|
4019
|
+
if (!a) {
|
|
4020
|
+
a = [];
|
|
4021
|
+
bySat.set(r.prn, a);
|
|
4022
|
+
}
|
|
4023
|
+
a.push(r);
|
|
4024
|
+
}
|
|
4025
|
+
return { records, bySat };
|
|
4026
|
+
}
|
|
4027
|
+
function biasMetres(r) {
|
|
4028
|
+
return r.unit === "ns" ? r.value * 1e-9 * C_LIGHT : r.value;
|
|
4029
|
+
}
|
|
4030
|
+
function findSatBias(bias, prn, obs1, obs2, tMs) {
|
|
4031
|
+
const recs = bias.bySat.get(prn);
|
|
4032
|
+
if (!recs) return null;
|
|
4033
|
+
for (const r of recs) {
|
|
4034
|
+
if (r.obs1 !== obs1) continue;
|
|
4035
|
+
if (obs2 === void 0 ? r.obs2 !== "" : r.obs2 !== obs2) continue;
|
|
4036
|
+
if (tMs != null && (tMs < r.startMs || tMs > r.endMs)) continue;
|
|
4037
|
+
return r;
|
|
4038
|
+
}
|
|
4039
|
+
return null;
|
|
4040
|
+
}
|
|
4041
|
+
|
|
3899
4042
|
// src/rinex/obs-writer-common.ts
|
|
3900
4043
|
function createGzipLineSink() {
|
|
3901
4044
|
const encoder = new TextEncoder();
|
|
@@ -6147,7 +6290,7 @@ var BdsAssembler = class {
|
|
|
6147
6290
|
};
|
|
6148
6291
|
|
|
6149
6292
|
// src/navbits/gal.ts
|
|
6150
|
-
var
|
|
6293
|
+
var GPS_EPOCH_MS5 = Date.UTC(1980, 0, 6);
|
|
6151
6294
|
var SEC_PER_WEEK5 = 7 * 86400;
|
|
6152
6295
|
var HALF_WEEK3 = 302400;
|
|
6153
6296
|
var GST_GPS_WEEK_OFFSET = 1024;
|
|
@@ -6160,7 +6303,7 @@ function galFnavPageCrcOk(page) {
|
|
|
6160
6303
|
return crc24q(page, 214) === getBitU(page, 214, 24);
|
|
6161
6304
|
}
|
|
6162
6305
|
function gpsDate2(week, sec) {
|
|
6163
|
-
return new Date(
|
|
6306
|
+
return new Date(GPS_EPOCH_MS5 + (week * SEC_PER_WEEK5 + sec) * 1e3);
|
|
6164
6307
|
}
|
|
6165
6308
|
function weekOfToe(week, tow, toe) {
|
|
6166
6309
|
if (toe - tow > HALF_WEEK3) return week - 1;
|
|
@@ -6455,7 +6598,7 @@ var GalFnavAssembler = class {
|
|
|
6455
6598
|
};
|
|
6456
6599
|
|
|
6457
6600
|
// src/navbits/glo.ts
|
|
6458
|
-
var
|
|
6601
|
+
var GPS_EPOCH_MS6 = Date.UTC(1980, 0, 6);
|
|
6459
6602
|
var SEC_PER_WEEK6 = 7 * 86400;
|
|
6460
6603
|
var SEC_PER_DAY = 86400;
|
|
6461
6604
|
var GLO_STRING_BYTES = 10;
|
|
@@ -6549,7 +6692,7 @@ function decodeGloStrings(strings, refDate, opts = {}) {
|
|
|
6549
6692
|
const slot = getBitU(b, i, 5);
|
|
6550
6693
|
if (frn1 !== 1 || frn2 !== 2 || frn3 !== 3 || frn4 !== 4) return null;
|
|
6551
6694
|
if (slot < 1 || slot > 27) return null;
|
|
6552
|
-
const utcSec = (getUtcDate(refDate).getTime() -
|
|
6695
|
+
const utcSec = (getUtcDate(refDate).getTime() - GPS_EPOCH_MS6) / 1e3;
|
|
6553
6696
|
const week = Math.floor(utcSec / SEC_PER_WEEK6);
|
|
6554
6697
|
let tow = utcSec - week * SEC_PER_WEEK6;
|
|
6555
6698
|
const tod = tow % SEC_PER_DAY;
|
|
@@ -6564,7 +6707,7 @@ function decodeGloStrings(strings, refDate, opts = {}) {
|
|
|
6564
6707
|
system: "R",
|
|
6565
6708
|
prn: `R${String(slot).padStart(2, "0")}`,
|
|
6566
6709
|
// RINEX GLONASS epochs are UTC: build the UTC toe Date directly.
|
|
6567
|
-
tocDate: new Date(
|
|
6710
|
+
tocDate: new Date(GPS_EPOCH_MS6 + (week * SEC_PER_WEEK6 + tow + toe) * 1e3),
|
|
6568
6711
|
tauN: -tauN,
|
|
6569
6712
|
// RINEX stores −τn; the SIS carries τn (ICD sign)
|
|
6570
6713
|
gammaN,
|
|
@@ -6618,7 +6761,7 @@ var GloStringAssembler = class {
|
|
|
6618
6761
|
};
|
|
6619
6762
|
|
|
6620
6763
|
// src/ubx/rawnav.ts
|
|
6621
|
-
var
|
|
6764
|
+
var GPS_EPOCH_MS7 = Date.UTC(1980, 0, 6);
|
|
6622
6765
|
var SEC_PER_WEEK7 = 7 * 86400;
|
|
6623
6766
|
var two2 = (n) => String(n).padStart(2, "0");
|
|
6624
6767
|
function parseUbxRawNav(data, opts = {}) {
|
|
@@ -6638,7 +6781,7 @@ function parseUbxRawNav(data, opts = {}) {
|
|
|
6638
6781
|
if (week === 0 && opts.refWeek !== void 0) week = opts.refWeek;
|
|
6639
6782
|
if (week > 0) {
|
|
6640
6783
|
refDate = new Date(
|
|
6641
|
-
|
|
6784
|
+
GPS_EPOCH_MS7 + (week * SEC_PER_WEEK7 + rcvTow) * 1e3
|
|
6642
6785
|
);
|
|
6643
6786
|
}
|
|
6644
6787
|
continue;
|
|
@@ -6718,7 +6861,7 @@ function parseUbxRawNav(data, opts = {}) {
|
|
|
6718
6861
|
}
|
|
6719
6862
|
|
|
6720
6863
|
// src/ubx/index.ts
|
|
6721
|
-
var
|
|
6864
|
+
var GPS_EPOCH_MS8 = Date.UTC(1980, 0, 6);
|
|
6722
6865
|
var MS_PER_WEEK3 = 7 * 864e5;
|
|
6723
6866
|
var SIGNALS = {
|
|
6724
6867
|
0: { 0: ["G", "1C"], 3: ["G", "2X"], 4: ["G", "2X"] },
|
|
@@ -6801,7 +6944,7 @@ function parseUbxRawx(data) {
|
|
|
6801
6944
|
if (!codes.includes(sig[1])) codes.push(sig[1]);
|
|
6802
6945
|
}
|
|
6803
6946
|
epochs.push({
|
|
6804
|
-
timeMs:
|
|
6947
|
+
timeMs: GPS_EPOCH_MS8 + week * MS_PER_WEEK3 + Math.round(rcvTow * 1e3),
|
|
6805
6948
|
leapS: leapValid ? leapS : null,
|
|
6806
6949
|
meas
|
|
6807
6950
|
});
|
|
@@ -6872,7 +7015,7 @@ function svidToPrn(svid) {
|
|
|
6872
7015
|
|
|
6873
7016
|
// src/sbf/nav.ts
|
|
6874
7017
|
var PI2 = Math.PI;
|
|
6875
|
-
var
|
|
7018
|
+
var GPS_EPOCH_MS9 = Date.UTC(1980, 0, 6);
|
|
6876
7019
|
var BDT_EPOCH_MS2 = Date.UTC(2006, 0, 1);
|
|
6877
7020
|
var SEC_PER_WEEK8 = 7 * 86400;
|
|
6878
7021
|
var MS_PER_WEEK4 = SEC_PER_WEEK8 * 1e3;
|
|
@@ -6884,7 +7027,7 @@ function adjustWeek(refWeek, wn, mod) {
|
|
|
6884
7027
|
if (offset < -(mod / 2 - 1)) offset += mod;
|
|
6885
7028
|
return refWeek - offset;
|
|
6886
7029
|
}
|
|
6887
|
-
var gpsMs = (week, sec) =>
|
|
7030
|
+
var gpsMs = (week, sec) => GPS_EPOCH_MS9 + week * MS_PER_WEEK4 + sec * 1e3;
|
|
6888
7031
|
var sowOf2 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK8;
|
|
6889
7032
|
function decodeGpsQzsNav(view, b, sys) {
|
|
6890
7033
|
const svid = view.getUint8(b + 14);
|
|
@@ -7034,7 +7177,7 @@ function decodeGloNav(view, b) {
|
|
|
7034
7177
|
const tocDate = new Date(toeGpsMs - leapMs);
|
|
7035
7178
|
const tofGpsMs = gpsMs(wnc, 0) + view.getUint32(b + 8, true);
|
|
7036
7179
|
const tofLeapMs = getGpsLeap(new Date(tofGpsMs)) * 1e3;
|
|
7037
|
-
const messageFrameTime = (tofGpsMs - tofLeapMs -
|
|
7180
|
+
const messageFrameTime = (tofGpsMs - tofLeapMs - GPS_EPOCH_MS9) / 1e3 % SEC_PER_WEEK8;
|
|
7038
7181
|
return {
|
|
7039
7182
|
system: "R",
|
|
7040
7183
|
prn,
|
|
@@ -7306,7 +7449,7 @@ function isFnavDummy(page) {
|
|
|
7306
7449
|
}
|
|
7307
7450
|
|
|
7308
7451
|
// src/sbf/rawnav-bds.ts
|
|
7309
|
-
var
|
|
7452
|
+
var GPS_EPOCH_MS10 = Date.UTC(1980, 0, 6);
|
|
7310
7453
|
var MS_PER_WEEK5 = 7 * 86400 * 1e3;
|
|
7311
7454
|
var TOW_DNU = 4294967295;
|
|
7312
7455
|
var WNC_DNU = 65535;
|
|
@@ -7376,7 +7519,7 @@ function parseSbfGloNav(data) {
|
|
|
7376
7519
|
const eph = assembler.push(
|
|
7377
7520
|
prn,
|
|
7378
7521
|
str,
|
|
7379
|
-
new Date(
|
|
7522
|
+
new Date(GPS_EPOCH_MS10 + wnc * MS_PER_WEEK5 + towMs),
|
|
7380
7523
|
view.getUint8(b + 18) - 8
|
|
7381
7524
|
// FreqNr, offset by 8
|
|
7382
7525
|
);
|
|
@@ -7910,7 +8053,7 @@ function parseSbfHas(data) {
|
|
|
7910
8053
|
|
|
7911
8054
|
// src/sbf/index.ts
|
|
7912
8055
|
var CLIGHT = 299792458;
|
|
7913
|
-
var
|
|
8056
|
+
var GPS_EPOCH_MS11 = Date.UTC(1980, 0, 6);
|
|
7914
8057
|
var MS_PER_WEEK6 = 7 * 864e5;
|
|
7915
8058
|
var M3_SYS = ["G", "R", "E", "C", "S", "J", "I"];
|
|
7916
8059
|
var M3_PR_BASE = [19e6, 19e6, 22e6, 2e7, 34e6, 34e6, 34e6];
|
|
@@ -8564,7 +8707,7 @@ function parseSbfMeas(data) {
|
|
|
8564
8707
|
const tow = view.getUint32(i + 8, true);
|
|
8565
8708
|
const wnc = view.getUint16(i + 12, true);
|
|
8566
8709
|
if (tow !== 4294967295 && wnc !== 65535) {
|
|
8567
|
-
ensureEpoch(
|
|
8710
|
+
ensureEpoch(GPS_EPOCH_MS11 + wnc * MS_PER_WEEK6 + tow);
|
|
8568
8711
|
if (id === 4109) decodeMeas3Ranges(i, tow);
|
|
8569
8712
|
else if (id === 4110) decodeMeas3CN0(i, len);
|
|
8570
8713
|
else if (id === 4111) decodeMeas3Doppler(i, len);
|
|
@@ -8629,15 +8772,15 @@ var ID_GALEPHEMERIS = 1122;
|
|
|
8629
8772
|
var ID_QZSSEPHEMERIS = 1336;
|
|
8630
8773
|
var ID_GPSEPHEM = 7;
|
|
8631
8774
|
var ID_BDSEPHEMERIS = 1696;
|
|
8632
|
-
var
|
|
8775
|
+
var GPS_EPOCH_MS12 = Date.UTC(1980, 0, 6);
|
|
8633
8776
|
var BDT_EPOCH_MS3 = Date.UTC(2006, 0, 1);
|
|
8634
8777
|
var SEC_PER_WEEK9 = 7 * 86400;
|
|
8635
8778
|
var SEC_PER_DAY2 = 86400;
|
|
8636
8779
|
var MS_PER_WEEK7 = SEC_PER_WEEK9 * 1e3;
|
|
8637
|
-
var gpsMs2 = (week, sec) =>
|
|
8780
|
+
var gpsMs2 = (week, sec) => GPS_EPOCH_MS12 + week * MS_PER_WEEK7 + sec * 1e3;
|
|
8638
8781
|
var sowOf3 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK9;
|
|
8639
8782
|
function nearWeekMs(refMs, sow) {
|
|
8640
|
-
const refWeek = Math.floor((refMs -
|
|
8783
|
+
const refWeek = Math.floor((refMs - GPS_EPOCH_MS12) / MS_PER_WEEK7);
|
|
8641
8784
|
let ms = gpsMs2(refWeek, sow);
|
|
8642
8785
|
if (ms < refMs - MS_PER_WEEK7 / 2) ms += MS_PER_WEEK7;
|
|
8643
8786
|
else if (ms > refMs + MS_PER_WEEK7 / 2) ms -= MS_PER_WEEK7;
|
|
@@ -8664,9 +8807,9 @@ function decodeGloEphemeris(view, p) {
|
|
|
8664
8807
|
tof += Math.floor(tow / SEC_PER_DAY2) * SEC_PER_DAY2;
|
|
8665
8808
|
if (tof < tow - 43200) tof += SEC_PER_DAY2;
|
|
8666
8809
|
else if (tof > tow + 43200) tof -= SEC_PER_DAY2;
|
|
8667
|
-
const toeGpsMs =
|
|
8668
|
-
const tofGpsMs =
|
|
8669
|
-
const tofUtcSec = (getUtcDate(new Date(tofGpsMs)).getTime() -
|
|
8810
|
+
const toeGpsMs = GPS_EPOCH_MS12 + (week * SEC_PER_WEEK9 + tow) * 1e3;
|
|
8811
|
+
const tofGpsMs = GPS_EPOCH_MS12 + (week * SEC_PER_WEEK9 + tof) * 1e3;
|
|
8812
|
+
const tofUtcSec = (getUtcDate(new Date(tofGpsMs)).getTime() - GPS_EPOCH_MS12) / 1e3;
|
|
8670
8813
|
return {
|
|
8671
8814
|
system: "R",
|
|
8672
8815
|
prn: `R${String(slot).padStart(2, "0")}`,
|
|
@@ -8731,7 +8874,7 @@ function decodeGalEphemeris(view, p, headerMs) {
|
|
|
8731
8874
|
omega: view.getFloat64(p + 60, true),
|
|
8732
8875
|
omegaDot: view.getFloat64(p + 140, true),
|
|
8733
8876
|
idot: view.getFloat64(p + 124, true),
|
|
8734
|
-
week: Math.floor((toeMs -
|
|
8877
|
+
week: Math.floor((toeMs - GPS_EPOCH_MS12) / MS_PER_WEEK7),
|
|
8735
8878
|
// RINEX Galileo SVH bit layout (E1B DVS/HS in bits 0-2, E5a in
|
|
8736
8879
|
// 3-5, E5b in 6-8) — same packing as RTKLIB.
|
|
8737
8880
|
svHealth: svhE5b << 7 | dvsE5b << 6 | svhE5a << 4 | dvsE5a << 3 | svhE1b << 1 | dvsE1b,
|
|
@@ -8903,7 +9046,7 @@ function parseNovatelNav(data) {
|
|
|
8903
9046
|
}
|
|
8904
9047
|
|
|
8905
9048
|
// src/novatel/index.ts
|
|
8906
|
-
var
|
|
9049
|
+
var GPS_EPOCH_MS13 = Date.UTC(1980, 0, 6);
|
|
8907
9050
|
var MS_PER_WEEK8 = 7 * 864e5;
|
|
8908
9051
|
var HDR = 28;
|
|
8909
9052
|
var ID_RANGE = 43;
|
|
@@ -9073,7 +9216,7 @@ function parseNovatelRange(data) {
|
|
|
9073
9216
|
if (!codes.includes(code)) codes.push(code);
|
|
9074
9217
|
}
|
|
9075
9218
|
epochs.push({
|
|
9076
|
-
timeMs:
|
|
9219
|
+
timeMs: GPS_EPOCH_MS13 + week * MS_PER_WEEK8 + towMs,
|
|
9077
9220
|
meas
|
|
9078
9221
|
});
|
|
9079
9222
|
}
|
|
@@ -9125,7 +9268,7 @@ function parseNovatelRange(data) {
|
|
|
9125
9268
|
if (!codes.includes(code)) codes.push(code);
|
|
9126
9269
|
}
|
|
9127
9270
|
epochs.push({
|
|
9128
|
-
timeMs:
|
|
9271
|
+
timeMs: GPS_EPOCH_MS13 + week * MS_PER_WEEK8 + towMs,
|
|
9129
9272
|
meas
|
|
9130
9273
|
});
|
|
9131
9274
|
}
|
|
@@ -9176,11 +9319,11 @@ function* trimbleFrames(data, stats) {
|
|
|
9176
9319
|
}
|
|
9177
9320
|
|
|
9178
9321
|
// src/trimble/nav.ts
|
|
9179
|
-
var
|
|
9322
|
+
var GPS_EPOCH_MS14 = Date.UTC(1980, 0, 6);
|
|
9180
9323
|
var SEC_PER_WEEK10 = 7 * 86400;
|
|
9181
9324
|
var MS_PER_WEEK9 = SEC_PER_WEEK10 * 1e3;
|
|
9182
9325
|
var GPS_PI2 = 3.1415926535898;
|
|
9183
|
-
var gpsMs3 = (week, sec) =>
|
|
9326
|
+
var gpsMs3 = (week, sec) => GPS_EPOCH_MS14 + week * MS_PER_WEEK9 + sec * 1e3;
|
|
9184
9327
|
var sowOf4 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK10;
|
|
9185
9328
|
var SUB_GPS_EPHEMERIS = 1;
|
|
9186
9329
|
var SUB_ION_UTC = 3;
|
|
@@ -9282,7 +9425,7 @@ function parseTrimbleNav(data) {
|
|
|
9282
9425
|
}
|
|
9283
9426
|
|
|
9284
9427
|
// src/trimble/index.ts
|
|
9285
|
-
var
|
|
9428
|
+
var GPS_EPOCH_MS15 = Date.UTC(1980, 0, 6);
|
|
9286
9429
|
var MS_PER_WEEK10 = 7 * 864e5;
|
|
9287
9430
|
var REC_TYPE_27 = 6;
|
|
9288
9431
|
var SYS = {
|
|
@@ -9480,7 +9623,7 @@ function decodeEpoch(epoch, epochs, obsCodes) {
|
|
|
9480
9623
|
o += c.length;
|
|
9481
9624
|
}
|
|
9482
9625
|
const dv = new DataView(M.buffer, M.byteOffset, M.byteLength);
|
|
9483
|
-
const timeMs =
|
|
9626
|
+
const timeMs = GPS_EPOCH_MS15 + epoch.week * MS_PER_WEEK10 + epoch.towMs;
|
|
9484
9627
|
const meas = [];
|
|
9485
9628
|
let q = 0;
|
|
9486
9629
|
for (let sv = 0; sv < epoch.nsv && q + 8 <= M.length; sv++) {
|
|
@@ -9661,13 +9804,13 @@ function* binexRecords(data, view, stats) {
|
|
|
9661
9804
|
}
|
|
9662
9805
|
|
|
9663
9806
|
// src/binex/nav.ts
|
|
9664
|
-
var
|
|
9807
|
+
var GPS_EPOCH_MS16 = Date.UTC(1980, 0, 6);
|
|
9665
9808
|
var GLO_DAY0_MS = Date.UTC(1980, 0, 1);
|
|
9666
9809
|
var BDT_EPOCH_MS4 = Date.UTC(2006, 0, 1);
|
|
9667
9810
|
var SEC_PER_WEEK11 = 7 * 86400;
|
|
9668
9811
|
var MS_PER_WEEK11 = SEC_PER_WEEK11 * 1e3;
|
|
9669
9812
|
var SC2RAD = GPS_PI;
|
|
9670
|
-
var gpsMs4 = (week, sec) =>
|
|
9813
|
+
var gpsMs4 = (week, sec) => GPS_EPOCH_MS16 + week * MS_PER_WEEK11 + sec * 1e3;
|
|
9671
9814
|
var sowOf5 = (dateMs) => (dateMs / 1e3 % SEC_PER_WEEK11 + SEC_PER_WEEK11) % SEC_PER_WEEK11;
|
|
9672
9815
|
var two5 = (n) => String(n).padStart(2, "0");
|
|
9673
9816
|
var Reader = class {
|
|
@@ -9955,7 +10098,7 @@ function decodeBinexEph(view, body, len, le) {
|
|
|
9955
10098
|
}
|
|
9956
10099
|
|
|
9957
10100
|
// src/binex/index.ts
|
|
9958
|
-
var
|
|
10101
|
+
var GPS_EPOCH_MS17 = Date.UTC(1980, 0, 6);
|
|
9959
10102
|
var CLIGHT2 = 299792458;
|
|
9960
10103
|
var OBS_CODES = {
|
|
9961
10104
|
0: [
|
|
@@ -10213,7 +10356,7 @@ function decodeObsRecord(data, view, body, len, obsCodes) {
|
|
|
10213
10356
|
p += 4;
|
|
10214
10357
|
const msec = view.getUint16(p);
|
|
10215
10358
|
p += 2;
|
|
10216
|
-
const timeMs =
|
|
10359
|
+
const timeMs = GPS_EPOCH_MS17 + min * 6e4 + msec;
|
|
10217
10360
|
const flag = data[p++];
|
|
10218
10361
|
const nsat = (flag & 63) + 1;
|
|
10219
10362
|
if (flag & 128) p += 3;
|
|
@@ -10299,7 +10442,7 @@ function parseBinex(data) {
|
|
|
10299
10442
|
var GM_GPS = 3986005e8;
|
|
10300
10443
|
var GM_GAL = 3986004418e5;
|
|
10301
10444
|
var GM_BDS = 3986004418e5;
|
|
10302
|
-
var
|
|
10445
|
+
var GPS_EPOCH_MS18 = Date.UTC(1980, 0, 6);
|
|
10303
10446
|
var BDT_EPOCH_MS5 = Date.UTC(2006, 0, 1);
|
|
10304
10447
|
var WEEK_MS = 6048e5;
|
|
10305
10448
|
var BDT_MINUS_GPST_MS = 14e3;
|
|
@@ -10308,7 +10451,7 @@ function almanacEpochMs(alm) {
|
|
|
10308
10451
|
if (alm.system === "C") {
|
|
10309
10452
|
return BDT_EPOCH_MS5 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3 + BDT_MINUS_GPST_MS;
|
|
10310
10453
|
}
|
|
10311
|
-
return
|
|
10454
|
+
return GPS_EPOCH_MS18 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3;
|
|
10312
10455
|
}
|
|
10313
10456
|
function almanacSatPosition(alm, timeMs) {
|
|
10314
10457
|
const GM = alm.system === "E" ? GM_GAL : alm.system === "C" ? GM_BDS : GM_GPS;
|
|
@@ -10817,10 +10960,10 @@ function selectBest(ephs, timeMs) {
|
|
|
10817
10960
|
}
|
|
10818
10961
|
return best;
|
|
10819
10962
|
}
|
|
10820
|
-
var
|
|
10963
|
+
var GPS_EPOCH_MS19 = START_GPS_TIME.getTime();
|
|
10821
10964
|
var MS_PER_WEEK12 = 7 * 864e5;
|
|
10822
10965
|
var BDS_EPOCH_MS = START_BDS_TIME.getTime();
|
|
10823
|
-
var GAL_EPOCH_MS =
|
|
10966
|
+
var GAL_EPOCH_MS = GPS_EPOCH_MS19 + 1024 * MS_PER_WEEK12;
|
|
10824
10967
|
function ephInfoToEphemeris(info) {
|
|
10825
10968
|
const sys = info.prn.charAt(0);
|
|
10826
10969
|
if (sys === "R") {
|
|
@@ -10871,8 +11014,8 @@ function ephInfoToEphemeris(info) {
|
|
|
10871
11014
|
} else if (sys === "E") {
|
|
10872
11015
|
epochMs = GAL_EPOCH_MS;
|
|
10873
11016
|
} else {
|
|
10874
|
-
epochMs =
|
|
10875
|
-
const weeksNow = (info.lastReceived -
|
|
11017
|
+
epochMs = GPS_EPOCH_MS19;
|
|
11018
|
+
const weeksNow = (info.lastReceived - GPS_EPOCH_MS19) / MS_PER_WEEK12;
|
|
10876
11019
|
week += 1024 * Math.round((weeksNow - week) / 1024);
|
|
10877
11020
|
}
|
|
10878
11021
|
const tocDate = new Date(epochMs + week * MS_PER_WEEK12 + tocSec * 1e3);
|
|
@@ -12834,7 +12977,7 @@ function sagnacRotate(x, y, z, travelS) {
|
|
|
12834
12977
|
const s = Math.sin(theta);
|
|
12835
12978
|
return [x * c + y * s, -x * s + y * c, z];
|
|
12836
12979
|
}
|
|
12837
|
-
function satStateAtEmission(sp3, prn, recvTimeMs, rcv) {
|
|
12980
|
+
function satStateAtEmission(sp3, prn, recvTimeMs, rcv, clk) {
|
|
12838
12981
|
let travelS = 0.075;
|
|
12839
12982
|
let sx = 0;
|
|
12840
12983
|
let sy = 0;
|
|
@@ -12853,7 +12996,7 @@ function satStateAtEmission(sp3, prn, recvTimeMs, rcv) {
|
|
|
12853
12996
|
const vz = (pPlus.z - pMinus.z) / 1;
|
|
12854
12997
|
velDotPos = p.x * vx + p.y * vy + p.z * vz;
|
|
12855
12998
|
}
|
|
12856
|
-
clkS = p.clk;
|
|
12999
|
+
clkS = (clk && clkBias(clk, prn, tEmit)) ?? p.clk;
|
|
12857
13000
|
const [rx, ry, rz] = sagnacRotate(p.x, p.y, p.z, travelS);
|
|
12858
13001
|
sx = rx;
|
|
12859
13002
|
sy = ry;
|
|
@@ -12967,7 +13110,7 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
12967
13110
|
for (const o of epoch.obs) {
|
|
12968
13111
|
if (o.c1 === 0 || o.c2 === 0 || o.l1 === 0 || o.l2 === 0) continue;
|
|
12969
13112
|
const slip = detectSlip(o, ei);
|
|
12970
|
-
const sat = satStateAtEmission(sp3, o.prn, epoch.timeMs, rcv);
|
|
13113
|
+
const sat = satStateAtEmission(sp3, o.prn, epoch.timeMs, rcv, opts.clk);
|
|
12971
13114
|
if (!sat) continue;
|
|
12972
13115
|
const [elRad, azRad] = getAer(
|
|
12973
13116
|
sat.state.x,
|
|
@@ -13162,6 +13305,96 @@ function solvePpp(epochs, sp3, opts) {
|
|
|
13162
13305
|
};
|
|
13163
13306
|
}
|
|
13164
13307
|
|
|
13308
|
+
// src/positioning/ppp-ar.ts
|
|
13309
|
+
function wlWavelength(f1, f2) {
|
|
13310
|
+
return C_LIGHT / (f1 - f2);
|
|
13311
|
+
}
|
|
13312
|
+
function nlWavelength(f1, f2) {
|
|
13313
|
+
return C_LIGHT / (f1 + f2);
|
|
13314
|
+
}
|
|
13315
|
+
function resolvePppAmbiguities(sats, Qaif, opts = {}) {
|
|
13316
|
+
const wlThreshold = opts.wlThreshold ?? 0.25;
|
|
13317
|
+
const ratioThreshold = opts.ratioThreshold ?? 3;
|
|
13318
|
+
const kept = [];
|
|
13319
|
+
const nWl = [];
|
|
13320
|
+
const rejectedWl = [];
|
|
13321
|
+
for (let i = 0; i < sats.length; i++) {
|
|
13322
|
+
const s = sats[i];
|
|
13323
|
+
const wlFloat = s.mwCyc - (s.wlBiasCyc ?? 0);
|
|
13324
|
+
const r = Math.round(wlFloat);
|
|
13325
|
+
if (Math.abs(wlFloat - r) <= wlThreshold) {
|
|
13326
|
+
kept.push(i);
|
|
13327
|
+
nWl.push(r);
|
|
13328
|
+
} else {
|
|
13329
|
+
rejectedWl.push(s.prn);
|
|
13330
|
+
}
|
|
13331
|
+
}
|
|
13332
|
+
if (kept.length < 2) {
|
|
13333
|
+
return {
|
|
13334
|
+
fixed: false,
|
|
13335
|
+
ratio: 0,
|
|
13336
|
+
refPrn: null,
|
|
13337
|
+
sats: [],
|
|
13338
|
+
rejectedWl
|
|
13339
|
+
};
|
|
13340
|
+
}
|
|
13341
|
+
const n1Float = [];
|
|
13342
|
+
const lamNl = [];
|
|
13343
|
+
for (let k = 0; k < kept.length; k++) {
|
|
13344
|
+
const s = sats[kept[k]];
|
|
13345
|
+
const lNl = nlWavelength(s.f1, s.f2);
|
|
13346
|
+
lamNl.push(lNl);
|
|
13347
|
+
const n1 = s.aIF / lNl - s.f2 / (s.f1 - s.f2) * nWl[k] - (s.nlBiasCyc ?? 0);
|
|
13348
|
+
n1Float.push(n1);
|
|
13349
|
+
}
|
|
13350
|
+
let ref = 0;
|
|
13351
|
+
for (let k = 1; k < kept.length; k++) {
|
|
13352
|
+
const e = sats[kept[k]].elevDeg ?? -1;
|
|
13353
|
+
if (e > (sats[kept[ref]].elevDeg ?? -1)) ref = k;
|
|
13354
|
+
}
|
|
13355
|
+
const m = kept.length - 1;
|
|
13356
|
+
const sd2 = new Float64Array(m);
|
|
13357
|
+
const Qsd = new Float64Array(m * m);
|
|
13358
|
+
const others = [];
|
|
13359
|
+
for (let k = 0; k < kept.length; k++) if (k !== ref) others.push(k);
|
|
13360
|
+
const n = sats.length;
|
|
13361
|
+
const qN1 = (ka, kb) => Qaif[kept[ka] * n + kept[kb]] / (lamNl[ka] * lamNl[kb]);
|
|
13362
|
+
for (let a = 0; a < m; a++) {
|
|
13363
|
+
const ka = others[a];
|
|
13364
|
+
sd2[a] = n1Float[ka] - n1Float[ref];
|
|
13365
|
+
for (let b = 0; b < m; b++) {
|
|
13366
|
+
const kb = others[b];
|
|
13367
|
+
Qsd[a * m + b] = qN1(ka, kb) - qN1(ka, ref) - qN1(ref, kb) + qN1(ref, ref);
|
|
13368
|
+
}
|
|
13369
|
+
}
|
|
13370
|
+
const res = lambdaSearch(sd2, Qsd, m, 2);
|
|
13371
|
+
const ratio = res ? Math.min(res.ratio, 999.9) : 0;
|
|
13372
|
+
const fixed = !!res && ratio >= ratioThreshold;
|
|
13373
|
+
const refN1 = Math.round(n1Float[ref]);
|
|
13374
|
+
const sdFix = res?.candidates[0];
|
|
13375
|
+
const outSats = [];
|
|
13376
|
+
for (let k = 0; k < kept.length; k++) {
|
|
13377
|
+
const s = sats[kept[k]];
|
|
13378
|
+
let n1;
|
|
13379
|
+
if (k === ref) {
|
|
13380
|
+
n1 = refN1;
|
|
13381
|
+
} else {
|
|
13382
|
+
const a = others.indexOf(k);
|
|
13383
|
+
n1 = fixed && sdFix ? refN1 + Math.round(sdFix[a]) : Math.round(n1Float[k]);
|
|
13384
|
+
}
|
|
13385
|
+
const lNl = lamNl[k];
|
|
13386
|
+
const aIF = lNl * n1 + lNl * (s.f2 / (s.f1 - s.f2)) * nWl[k];
|
|
13387
|
+
outSats.push({ prn: s.prn, nWl: nWl[k], n1, aIF });
|
|
13388
|
+
}
|
|
13389
|
+
return {
|
|
13390
|
+
fixed,
|
|
13391
|
+
ratio,
|
|
13392
|
+
refPrn: sats[kept[ref]].prn,
|
|
13393
|
+
sats: outSats,
|
|
13394
|
+
rejectedWl
|
|
13395
|
+
};
|
|
13396
|
+
}
|
|
13397
|
+
|
|
13165
13398
|
// src/positioning/index.ts
|
|
13166
13399
|
var GM_GPS3 = 3986005e8;
|
|
13167
13400
|
var F_REL = -4442807633e-19;
|
|
@@ -15741,6 +15974,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
15741
15974
|
analyzeQuality,
|
|
15742
15975
|
applyHelmert,
|
|
15743
15976
|
applyIonoDcb,
|
|
15977
|
+
biasMetres,
|
|
15744
15978
|
binexCrc16,
|
|
15745
15979
|
binexCrc32,
|
|
15746
15980
|
binexCsum8,
|
|
@@ -15749,6 +15983,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
15749
15983
|
buildObsIndices,
|
|
15750
15984
|
buildPppAntenna,
|
|
15751
15985
|
clampUnit,
|
|
15986
|
+
clkBias,
|
|
15752
15987
|
computeAllPositions,
|
|
15753
15988
|
computeDop,
|
|
15754
15989
|
computeIonoRate,
|
|
@@ -15779,6 +16014,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
15779
16014
|
ephInfoToEphemeris,
|
|
15780
16015
|
euclidean3D,
|
|
15781
16016
|
fetchSourcetable,
|
|
16017
|
+
findSatBias,
|
|
15782
16018
|
fmtD,
|
|
15783
16019
|
fmtF,
|
|
15784
16020
|
formatUTCTime,
|
|
@@ -15861,12 +16097,15 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
15861
16097
|
msmEpochToDate,
|
|
15862
16098
|
navTimesFromEph,
|
|
15863
16099
|
niellMapping,
|
|
16100
|
+
nlWavelength,
|
|
15864
16101
|
nmeaCoordToDecimal,
|
|
15865
16102
|
oem4Frames,
|
|
15866
16103
|
padL,
|
|
15867
16104
|
padR,
|
|
15868
16105
|
parseAntex,
|
|
16106
|
+
parseBiasSinex,
|
|
15869
16107
|
parseBinex,
|
|
16108
|
+
parseClk,
|
|
15870
16109
|
parseCrxDataLine,
|
|
15871
16110
|
parseIonex,
|
|
15872
16111
|
parseNavFile,
|
|
@@ -15902,6 +16141,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
15902
16141
|
readString,
|
|
15903
16142
|
reportDecodeError,
|
|
15904
16143
|
resetGloFreqCache,
|
|
16144
|
+
resolvePppAmbiguities,
|
|
15905
16145
|
rhumbLine,
|
|
15906
16146
|
rtcm3Constellation,
|
|
15907
16147
|
satClockCorrection,
|
|
@@ -15927,6 +16167,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
15927
16167
|
updateStreamStats,
|
|
15928
16168
|
verifyChecksum,
|
|
15929
16169
|
vincenty,
|
|
16170
|
+
wlWavelength,
|
|
15930
16171
|
writeCrx,
|
|
15931
16172
|
writeModernObsBlob,
|
|
15932
16173
|
writeRinex2ObsBlob,
|