gnss-js 1.25.0 → 1.27.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/binex.cjs +799 -0
- package/dist/binex.d.cts +189 -0
- package/dist/binex.d.ts +189 -0
- package/dist/binex.js +19 -0
- package/dist/{chunk-VTX3VCL4.js → chunk-5AUK42AL.js} +4 -2
- package/dist/{chunk-WZDFZ76K.js → chunk-726LQBGM.js} +8 -148
- package/dist/{chunk-PZNVFCKJ.js → chunk-AFEDNWXI.js} +5 -3
- package/dist/chunk-CKRNXZHT.js +424 -0
- package/dist/{chunk-7RKLWE6R.js → chunk-F4CM6Q4F.js} +4 -2
- package/dist/{chunk-MCAVU3XL.js → chunk-FEOMYZEU.js} +5 -3
- package/dist/chunk-IQ5OIMQD.js +148 -0
- package/dist/chunk-OK4GGNOO.js +756 -0
- package/dist/{chunk-NOQAAUGY.js → chunk-QVNNHACQ.js} +441 -2
- package/dist/index.cjs +1635 -17
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +43 -16
- package/dist/novatel.js +3 -2
- package/dist/rinex.cjs +438 -0
- package/dist/rinex.d.cts +27 -1
- package/dist/rinex.d.ts +27 -1
- package/dist/rinex.js +5 -2
- package/dist/sbf.js +4 -3
- package/dist/trimble.cjs +452 -0
- package/dist/trimble.d.cts +147 -0
- package/dist/trimble.d.ts +147 -0
- package/dist/trimble.js +10 -0
- package/dist/ubx.js +4 -3
- package/package.json +11 -1
package/dist/index.cjs
CHANGED
|
@@ -111,6 +111,10 @@ __export(src_exports, {
|
|
|
111
111
|
analyzeQuality: () => analyzeQuality,
|
|
112
112
|
applyHelmert: () => applyHelmert,
|
|
113
113
|
applyIonoDcb: () => applyIonoDcb,
|
|
114
|
+
binexCrc16: () => binexCrc16,
|
|
115
|
+
binexCrc32: () => binexCrc32,
|
|
116
|
+
binexCsum8: () => binexCsum8,
|
|
117
|
+
binexRecords: () => binexRecords,
|
|
114
118
|
buildGloChannelMap: () => buildGloChannelMap,
|
|
115
119
|
buildObsIndices: () => buildObsIndices,
|
|
116
120
|
clampUnit: () => clampUnit,
|
|
@@ -131,6 +135,7 @@ __export(src_exports, {
|
|
|
131
135
|
crxDecompress: () => crxDecompress,
|
|
132
136
|
crxRepair: () => crxRepair,
|
|
133
137
|
dateToEpoch: () => dateToEpoch,
|
|
138
|
+
decodeBinexEph: () => decodeBinexEph,
|
|
134
139
|
decodeEphemeris: () => decodeEphemeris,
|
|
135
140
|
decodeMsmFull: () => decodeMsmFull,
|
|
136
141
|
deg2dms: () => deg2dms,
|
|
@@ -152,6 +157,7 @@ __export(src_exports, {
|
|
|
152
157
|
geodeticToUtm: () => geodeticToUtm,
|
|
153
158
|
getAer: () => getAer,
|
|
154
159
|
getBdsTime: () => getBdsTime,
|
|
160
|
+
getBnxi: () => getBnxi,
|
|
155
161
|
getDateFromBdsTime: () => getDateFromBdsTime,
|
|
156
162
|
getDateFromDayOfWeek: () => getDateFromDayOfWeek,
|
|
157
163
|
getDateFromDayOfYear: () => getDateFromDayOfYear,
|
|
@@ -225,6 +231,7 @@ __export(src_exports, {
|
|
|
225
231
|
padL: () => padL,
|
|
226
232
|
padR: () => padR,
|
|
227
233
|
parseAntex: () => parseAntex,
|
|
234
|
+
parseBinex: () => parseBinex,
|
|
228
235
|
parseCrxDataLine: () => parseCrxDataLine,
|
|
229
236
|
parseIonex: () => parseIonex,
|
|
230
237
|
parseNavFile: () => parseNavFile,
|
|
@@ -244,6 +251,8 @@ __export(src_exports, {
|
|
|
244
251
|
parseSinexBiasDcb: () => parseSinexBiasDcb,
|
|
245
252
|
parseSourcetable: () => parseSourcetable,
|
|
246
253
|
parseSp3: () => parseSp3,
|
|
254
|
+
parseTrimble: () => parseTrimble,
|
|
255
|
+
parseTrimbleNav: () => parseTrimbleNav,
|
|
247
256
|
parseUbxCnav: () => parseUbxCnav,
|
|
248
257
|
parseUbxIonoUtc: () => parseUbxIonoUtc,
|
|
249
258
|
parseUbxNav: () => parseUbxNav,
|
|
@@ -274,11 +283,13 @@ __export(src_exports, {
|
|
|
274
283
|
systemName: () => systemName,
|
|
275
284
|
toRtkEpoch: () => toRtkEpoch,
|
|
276
285
|
transformFrame: () => transformFrame,
|
|
286
|
+
trimbleFrames: () => trimbleFrames,
|
|
277
287
|
ubxFrames: () => ubxFrames,
|
|
278
288
|
updateStationMeta: () => updateStationMeta,
|
|
279
289
|
updateStreamStats: () => updateStreamStats,
|
|
280
290
|
verifyChecksum: () => verifyChecksum,
|
|
281
291
|
vincenty: () => vincenty,
|
|
292
|
+
writeCrx: () => writeCrx,
|
|
282
293
|
writeModernObsBlob: () => writeModernObsBlob,
|
|
283
294
|
writeRinex2ObsBlob: () => writeRinex2ObsBlob,
|
|
284
295
|
writeRinex4ObsBlob: () => writeRinex4ObsBlob,
|
|
@@ -1309,6 +1320,442 @@ function crxDecompress(prev, field) {
|
|
|
1309
1320
|
};
|
|
1310
1321
|
}
|
|
1311
1322
|
|
|
1323
|
+
// src/rinex/crx-writer.ts
|
|
1324
|
+
var ARC_ORDER = 3;
|
|
1325
|
+
function emptyData() {
|
|
1326
|
+
return { u: [0, 0, 0, 0], l: [0, 0, 0, 0], order: -1 };
|
|
1327
|
+
}
|
|
1328
|
+
function cAtol(s) {
|
|
1329
|
+
let i = 0;
|
|
1330
|
+
while (i < s.length && (s[i] === " " || s[i] === " ")) i++;
|
|
1331
|
+
let sign = 1;
|
|
1332
|
+
if (s[i] === "+" || s[i] === "-") {
|
|
1333
|
+
if (s[i] === "-") sign = -1;
|
|
1334
|
+
i++;
|
|
1335
|
+
}
|
|
1336
|
+
let n = 0;
|
|
1337
|
+
let any = false;
|
|
1338
|
+
while (i < s.length && s[i] >= "0" && s[i] <= "9") {
|
|
1339
|
+
n = n * 10 + (s.charCodeAt(i) - 48);
|
|
1340
|
+
i++;
|
|
1341
|
+
any = true;
|
|
1342
|
+
}
|
|
1343
|
+
return any ? sign * n : 0;
|
|
1344
|
+
}
|
|
1345
|
+
function strdiff(s1, s2) {
|
|
1346
|
+
let ds = "";
|
|
1347
|
+
const n = Math.min(s1.length, s2.length);
|
|
1348
|
+
let i = 0;
|
|
1349
|
+
for (; i < n; i++) {
|
|
1350
|
+
if (s2[i] === s1[i]) ds += " ";
|
|
1351
|
+
else if (s2[i] === " ") ds += "&";
|
|
1352
|
+
else ds += s2[i];
|
|
1353
|
+
}
|
|
1354
|
+
if (s1.length > s2.length) {
|
|
1355
|
+
for (let k = i; k < s1.length; k++) ds += s1[k] === " " ? " " : "&";
|
|
1356
|
+
} else if (s2.length > s1.length) {
|
|
1357
|
+
ds += s2.slice(i);
|
|
1358
|
+
}
|
|
1359
|
+
let end = ds.length;
|
|
1360
|
+
while (end > 0 && ds[end - 1] === " ") end--;
|
|
1361
|
+
return ds.slice(0, end);
|
|
1362
|
+
}
|
|
1363
|
+
function readValue(field14) {
|
|
1364
|
+
const c = field14.padEnd(14, " ").split("");
|
|
1365
|
+
const p7 = c[7];
|
|
1366
|
+
c[10] = c[9];
|
|
1367
|
+
c[9] = c[8];
|
|
1368
|
+
let l = cAtol(c.slice(9, 14).join(""));
|
|
1369
|
+
let u;
|
|
1370
|
+
if (p7 === " ") {
|
|
1371
|
+
u = 0;
|
|
1372
|
+
} else if (p7 === "-") {
|
|
1373
|
+
u = 0;
|
|
1374
|
+
l = -l;
|
|
1375
|
+
} else {
|
|
1376
|
+
c[8] = ".";
|
|
1377
|
+
u = cAtol(c.slice(0, 14).join(""));
|
|
1378
|
+
if (u < 0) l = -l;
|
|
1379
|
+
}
|
|
1380
|
+
return { u, l };
|
|
1381
|
+
}
|
|
1382
|
+
function putdiff(dddu, dddl) {
|
|
1383
|
+
dddu += Math.trunc(dddl / 1e5);
|
|
1384
|
+
dddl %= 1e5;
|
|
1385
|
+
if (dddu < 0 && dddl > 0) {
|
|
1386
|
+
dddu++;
|
|
1387
|
+
dddl -= 1e5;
|
|
1388
|
+
} else if (dddu > 0 && dddl < 0) {
|
|
1389
|
+
dddu--;
|
|
1390
|
+
dddl += 1e5;
|
|
1391
|
+
}
|
|
1392
|
+
if (dddu === 0) return String(dddl);
|
|
1393
|
+
return `${dddu}${String(Math.abs(dddl)).padStart(5, "0")}`;
|
|
1394
|
+
}
|
|
1395
|
+
function putClock(du, dl, cOrder) {
|
|
1396
|
+
du += Math.trunc(dl / 1e8);
|
|
1397
|
+
dl %= 1e8;
|
|
1398
|
+
if (du < 0 && dl > 0) {
|
|
1399
|
+
du++;
|
|
1400
|
+
dl -= 1e8;
|
|
1401
|
+
} else if (du > 0 && dl < 0) {
|
|
1402
|
+
du--;
|
|
1403
|
+
dl += 1e8;
|
|
1404
|
+
}
|
|
1405
|
+
let out = "";
|
|
1406
|
+
if (cOrder === 0) out += `${ARC_ORDER}&`;
|
|
1407
|
+
if (du === 0) out += String(dl);
|
|
1408
|
+
else out += `${du}${String(Math.abs(dl)).padStart(8, "0")}`;
|
|
1409
|
+
return out;
|
|
1410
|
+
}
|
|
1411
|
+
function chop(line) {
|
|
1412
|
+
let end = line.length;
|
|
1413
|
+
if (end > 0 && line[end - 1] === "\r") end--;
|
|
1414
|
+
while (end > 0 && line[end - 1] === " ") end--;
|
|
1415
|
+
return line.slice(0, end);
|
|
1416
|
+
}
|
|
1417
|
+
function readSat(lines, cursor, rinexVersion, ntype, ntypeGnss) {
|
|
1418
|
+
let line = chop(lines[cursor.li++] ?? "");
|
|
1419
|
+
let maxField;
|
|
1420
|
+
let ntypeRec;
|
|
1421
|
+
let firstRec;
|
|
1422
|
+
let satId = "";
|
|
1423
|
+
if (rinexVersion === 2) {
|
|
1424
|
+
maxField = 5;
|
|
1425
|
+
ntypeRec = ntype;
|
|
1426
|
+
firstRec = 0;
|
|
1427
|
+
} else {
|
|
1428
|
+
satId = line.slice(0, 3);
|
|
1429
|
+
const sys = line[0];
|
|
1430
|
+
maxField = ntypeRec = ntypeGnss[sys] ?? -1;
|
|
1431
|
+
if (maxField < 0) return null;
|
|
1432
|
+
firstRec = 3;
|
|
1433
|
+
}
|
|
1434
|
+
const data = [];
|
|
1435
|
+
let flag = "";
|
|
1436
|
+
for (let i = 0; i < ntypeRec; i += maxField) {
|
|
1437
|
+
const nfield = Math.min(ntypeRec - i, maxField);
|
|
1438
|
+
const need = firstRec + 16 * nfield;
|
|
1439
|
+
let body = line;
|
|
1440
|
+
if (body.length < need) body = body.padEnd(need, " ");
|
|
1441
|
+
for (let j = 0; j < nfield; j++) {
|
|
1442
|
+
const p = firstRec + j * 16;
|
|
1443
|
+
const rec = body.slice(p, p + 16);
|
|
1444
|
+
const d = emptyData();
|
|
1445
|
+
if (rec[10] === ".") {
|
|
1446
|
+
flag += rec[14] ?? " ";
|
|
1447
|
+
flag += rec[15] ?? " ";
|
|
1448
|
+
const v = readValue(rec.slice(0, 14));
|
|
1449
|
+
d.u[0] = v.u;
|
|
1450
|
+
d.l[0] = v.l;
|
|
1451
|
+
d.order = 0;
|
|
1452
|
+
} else if (rec.slice(0, 14).trim() === "") {
|
|
1453
|
+
flag += rec[14] ?? " ";
|
|
1454
|
+
flag += rec[15] ?? " ";
|
|
1455
|
+
d.order = -1;
|
|
1456
|
+
} else {
|
|
1457
|
+
return null;
|
|
1458
|
+
}
|
|
1459
|
+
data.push(d);
|
|
1460
|
+
}
|
|
1461
|
+
if (i + maxField < ntypeRec) {
|
|
1462
|
+
line = chop(lines[cursor.li++] ?? "");
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
1465
|
+
return { sat: { data, flag, ntypeRec }, satId };
|
|
1466
|
+
}
|
|
1467
|
+
var MONTHS = [
|
|
1468
|
+
"Jan",
|
|
1469
|
+
"Feb",
|
|
1470
|
+
"Mar",
|
|
1471
|
+
"Apr",
|
|
1472
|
+
"May",
|
|
1473
|
+
"Jun",
|
|
1474
|
+
"Jul",
|
|
1475
|
+
"Aug",
|
|
1476
|
+
"Sep",
|
|
1477
|
+
"Oct",
|
|
1478
|
+
"Nov",
|
|
1479
|
+
"Dec"
|
|
1480
|
+
];
|
|
1481
|
+
function crinexDate() {
|
|
1482
|
+
const d = /* @__PURE__ */ new Date();
|
|
1483
|
+
const dd = String(d.getUTCDate()).padStart(2, "0");
|
|
1484
|
+
const mon = MONTHS[d.getUTCMonth()];
|
|
1485
|
+
const yy = String(d.getUTCFullYear() % 100).padStart(2, "0");
|
|
1486
|
+
const hh = String(d.getUTCHours()).padStart(2, "0");
|
|
1487
|
+
const mm = String(d.getUTCMinutes()).padStart(2, "0");
|
|
1488
|
+
return `${dd}-${mon}-${yy} ${hh}:${mm}`;
|
|
1489
|
+
}
|
|
1490
|
+
function writeCrx(rinexText, opts = {}) {
|
|
1491
|
+
const rawLines = rinexText.split("\n");
|
|
1492
|
+
const cursor = { li: 0 };
|
|
1493
|
+
const out = [];
|
|
1494
|
+
const firstLine = chop(rawLines[cursor.li++] ?? "");
|
|
1495
|
+
if (firstLine.slice(60, 80) !== "RINEX VERSION / TYPE" || firstLine[20] !== "O") {
|
|
1496
|
+
throw new Error("writeCrx: not a RINEX observation file");
|
|
1497
|
+
}
|
|
1498
|
+
const rinexVersion = parseInt(firstLine, 10);
|
|
1499
|
+
const rinexVersionFull = readVersionFull(firstLine);
|
|
1500
|
+
if (rinexVersionFull < 0) throw new Error("writeCrx: invalid RINEX version");
|
|
1501
|
+
const crxVersion = rinexVersionFull >= 402 ? "3.1" : rinexVersion === 2 ? "1.0" : "3.0";
|
|
1502
|
+
out.push(
|
|
1503
|
+
`${crxVersion.padEnd(20)}${"COMPACT RINEX FORMAT".padEnd(40)}${"CRINEX VERS / TYPE".padEnd(20)}`
|
|
1504
|
+
);
|
|
1505
|
+
const prog = (opts.prog ?? "gnss-js writeCrx").slice(0, 40);
|
|
1506
|
+
const date = opts.date ?? crinexDate();
|
|
1507
|
+
out.push(`${prog.padEnd(40)}${date.padEnd(20)}CRINEX PROG / DATE`);
|
|
1508
|
+
out.push(firstLine);
|
|
1509
|
+
let ntype = 0;
|
|
1510
|
+
const ntypeGnss = {};
|
|
1511
|
+
let line;
|
|
1512
|
+
do {
|
|
1513
|
+
line = chop(rawLines[cursor.li++] ?? "");
|
|
1514
|
+
out.push(line);
|
|
1515
|
+
const label2 = line.slice(60).trimStart();
|
|
1516
|
+
if (label2.startsWith("# / TYPES OF OBSERV") && line[5] !== " ") {
|
|
1517
|
+
ntype = parseInt(line, 10);
|
|
1518
|
+
} else if (label2.startsWith("SYS / # / OBS TYPES") && line[0] !== " ") {
|
|
1519
|
+
ntypeGnss[line[0]] = parseInt(line.slice(3), 10);
|
|
1520
|
+
}
|
|
1521
|
+
if (cursor.li >= rawLines.length) break;
|
|
1522
|
+
} while (!line.slice(60).trimStart().startsWith("END OF HEADER"));
|
|
1523
|
+
const v2 = rinexVersion === 2;
|
|
1524
|
+
const off = v2 ? { event: 28, nsat: 29, satlst: 32, clock: 68, satOld: 32, shiftClk: 1 } : {
|
|
1525
|
+
event: 31,
|
|
1526
|
+
nsat: 32,
|
|
1527
|
+
satlst: 41,
|
|
1528
|
+
clock: 41,
|
|
1529
|
+
satOld: 41,
|
|
1530
|
+
shiftClk: 4,
|
|
1531
|
+
psec: 57
|
|
1532
|
+
};
|
|
1533
|
+
let oldline = "&";
|
|
1534
|
+
let nsatOld = 0;
|
|
1535
|
+
let clk0 = { u: [0, 0, 0, 0], l: [0, 0, 0, 0] };
|
|
1536
|
+
let dy0 = [];
|
|
1537
|
+
let flag0 = [];
|
|
1538
|
+
let oldpsec = "";
|
|
1539
|
+
let clkOrderPrev = -1;
|
|
1540
|
+
const resetArcs = () => {
|
|
1541
|
+
oldline = "&";
|
|
1542
|
+
nsatOld = 0;
|
|
1543
|
+
clkOrderPrev = -1;
|
|
1544
|
+
};
|
|
1545
|
+
for (; ; ) {
|
|
1546
|
+
if (cursor.li >= rawLines.length) break;
|
|
1547
|
+
let epoch = rawLines[cursor.li];
|
|
1548
|
+
if (epoch === void 0) break;
|
|
1549
|
+
if (epoch === "" && cursor.li === rawLines.length - 1) break;
|
|
1550
|
+
cursor.li++;
|
|
1551
|
+
epoch = chop(epoch);
|
|
1552
|
+
if (epoch === "") continue;
|
|
1553
|
+
let newline;
|
|
1554
|
+
if (v2) {
|
|
1555
|
+
newline = epoch;
|
|
1556
|
+
} else {
|
|
1557
|
+
newline = epoch.length < 41 ? epoch.padEnd(41, " ") : epoch;
|
|
1558
|
+
}
|
|
1559
|
+
const eventFlag = parseInt(newline[off.event] ?? "0", 10) || 0;
|
|
1560
|
+
if (eventFlag > 1) {
|
|
1561
|
+
putEventData(rawLines, cursor, v2, newline, out, ntypeGnss, (n) => {
|
|
1562
|
+
ntype = n;
|
|
1563
|
+
});
|
|
1564
|
+
resetArcs();
|
|
1565
|
+
clk0 = { u: [0, 0, 0, 0], l: [0, 0, 0, 0] };
|
|
1566
|
+
dy0 = [];
|
|
1567
|
+
flag0 = [];
|
|
1568
|
+
continue;
|
|
1569
|
+
}
|
|
1570
|
+
let newpsec = "";
|
|
1571
|
+
if (rinexVersionFull >= 402 && newline.length === 62) {
|
|
1572
|
+
const psec = newline.slice(off.psec, off.psec + 5);
|
|
1573
|
+
if (/^\d{5}$/.test(psec)) newpsec = psec;
|
|
1574
|
+
newline = newline.slice(0, off.psec).replace(/\s+$/, "");
|
|
1575
|
+
}
|
|
1576
|
+
let clkOrder = -1;
|
|
1577
|
+
const clk1 = { u: [0, 0, 0, 0], l: [0, 0, 0, 0] };
|
|
1578
|
+
if (newline.length > off.clock) {
|
|
1579
|
+
clkOrder = readClock(
|
|
1580
|
+
newline.slice(off.clock),
|
|
1581
|
+
off.shiftClk,
|
|
1582
|
+
clk1,
|
|
1583
|
+
clkOrderPrev
|
|
1584
|
+
);
|
|
1585
|
+
if (clkOrder > -1) {
|
|
1586
|
+
newline = newline.slice(0, off.clock).replace(/\s+$/, "");
|
|
1587
|
+
if (!v2 && newline.length < 41) newline = newline.padEnd(41, " ");
|
|
1588
|
+
}
|
|
1589
|
+
}
|
|
1590
|
+
clkOrderPrev = clkOrder;
|
|
1591
|
+
const nsat = parseInt((newline.slice(off.nsat) || "0").trim(), 10) || 0;
|
|
1592
|
+
if (v2 && nsat > 12) {
|
|
1593
|
+
newline = readMoreSat(rawLines, cursor, nsat, newline);
|
|
1594
|
+
}
|
|
1595
|
+
const sats = [];
|
|
1596
|
+
const satIds = [];
|
|
1597
|
+
let bad = false;
|
|
1598
|
+
let satlist = v2 ? newline.slice(off.satlst, off.satlst + nsat * 3) : "";
|
|
1599
|
+
for (let i = 0; i < nsat; i++) {
|
|
1600
|
+
const r = readSat(rawLines, cursor, rinexVersion, ntype, ntypeGnss);
|
|
1601
|
+
if (!r) {
|
|
1602
|
+
bad = true;
|
|
1603
|
+
break;
|
|
1604
|
+
}
|
|
1605
|
+
sats.push(r.sat);
|
|
1606
|
+
satIds.push(v2 ? satlist.slice(i * 3, i * 3 + 3) : r.satId);
|
|
1607
|
+
}
|
|
1608
|
+
if (bad) continue;
|
|
1609
|
+
if (!v2) satlist = satIds.join("");
|
|
1610
|
+
const fullNew = v2 ? newline : newline.slice(0, 41) + satlist;
|
|
1611
|
+
const oldSatList = v2 ? oldline.slice(off.satOld, off.satOld + nsatOld * 3) : oldline.slice(off.satOld);
|
|
1612
|
+
const sattbl = [];
|
|
1613
|
+
const dup = /* @__PURE__ */ new Set();
|
|
1614
|
+
for (let i = 0; i < nsat; i++) {
|
|
1615
|
+
const id = satIds[i];
|
|
1616
|
+
if (dup.has(id)) {
|
|
1617
|
+
bad = true;
|
|
1618
|
+
break;
|
|
1619
|
+
}
|
|
1620
|
+
dup.add(id);
|
|
1621
|
+
let found = -1;
|
|
1622
|
+
for (let j = 0; j < nsatOld; j++) {
|
|
1623
|
+
if (oldSatList.slice(j * 3, j * 3 + 3) === id) {
|
|
1624
|
+
found = j;
|
|
1625
|
+
break;
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
sattbl.push(found);
|
|
1629
|
+
}
|
|
1630
|
+
if (bad) continue;
|
|
1631
|
+
out.push(strdiff(oldline, fullNew));
|
|
1632
|
+
let clockLine = "";
|
|
1633
|
+
if (clkOrder > -1) {
|
|
1634
|
+
if (clkOrder > 0) processClock(clk1, clk0, clkOrder);
|
|
1635
|
+
clockLine += putClock(clk1.u[clkOrder], clk1.l[clkOrder], clkOrder);
|
|
1636
|
+
}
|
|
1637
|
+
if (newpsec.length === 5) {
|
|
1638
|
+
clockLine += " " + strdiff(oldpsec, newpsec);
|
|
1639
|
+
}
|
|
1640
|
+
out.push(clockLine);
|
|
1641
|
+
const dataLines = buildData(sats, sattbl, dy0, flag0, rinexVersion);
|
|
1642
|
+
for (const dl of dataLines) out.push(dl);
|
|
1643
|
+
oldline = fullNew;
|
|
1644
|
+
nsatOld = nsat;
|
|
1645
|
+
clk0 = clk1;
|
|
1646
|
+
oldpsec = newpsec;
|
|
1647
|
+
dy0 = sats.map((s) => s.data);
|
|
1648
|
+
flag0 = sats.map((s) => s.flag);
|
|
1649
|
+
}
|
|
1650
|
+
return out.join("\n") + "\n";
|
|
1651
|
+
}
|
|
1652
|
+
function readClock(field, shiftClk, clk1, prevOrder) {
|
|
1653
|
+
const c = field.split("");
|
|
1654
|
+
if (c[2] !== ".") return -1;
|
|
1655
|
+
for (let k = 0; k < shiftClk; k++) c[2 + k] = c[3 + k];
|
|
1656
|
+
c[2 + shiftClk] = ".";
|
|
1657
|
+
const s = c.join("");
|
|
1658
|
+
const m = /(-?\d+)\.(\d+)/.exec(s);
|
|
1659
|
+
if (!m) return -1;
|
|
1660
|
+
clk1.u[0] = parseInt(m[1], 10);
|
|
1661
|
+
clk1.l[0] = parseInt(m[2], 10);
|
|
1662
|
+
if (c[0] === "-" || c[1] === "-") clk1.l[0] = -clk1.l[0];
|
|
1663
|
+
return Math.min(prevOrder + 1, ARC_ORDER);
|
|
1664
|
+
}
|
|
1665
|
+
function processClock(clk1, clk0, clkOrder) {
|
|
1666
|
+
for (let i = 0; i < clkOrder; i++) {
|
|
1667
|
+
clk1.u[i + 1] = clk1.u[i] - clk0.u[i];
|
|
1668
|
+
clk1.l[i + 1] = clk1.l[i] - clk0.l[i];
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
function takeDiff(py1, py0) {
|
|
1672
|
+
py1.order = py0.order;
|
|
1673
|
+
if (py1.order < ARC_ORDER) py1.order++;
|
|
1674
|
+
for (let k = 0; k < py1.order; k++) {
|
|
1675
|
+
py1.u[k + 1] = py1.u[k] - py0.u[k];
|
|
1676
|
+
py1.l[k + 1] = py1.l[k] - py0.l[k];
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
function buildData(sats, sattbl, dy0, flag0, rinexVersion) {
|
|
1680
|
+
const lines = [];
|
|
1681
|
+
for (let i = 0; i < sats.length; i++) {
|
|
1682
|
+
const sat = sats[i];
|
|
1683
|
+
const i0 = sattbl[i];
|
|
1684
|
+
const prevFlag = (i0 >= 0 ? flag0[i0] ?? "" : "").split("");
|
|
1685
|
+
let line = "";
|
|
1686
|
+
for (let j = 0; j < sat.ntypeRec; j++) {
|
|
1687
|
+
const py1 = sat.data[j];
|
|
1688
|
+
if (py1.order >= 0) {
|
|
1689
|
+
if (i0 < 0 || dy0[i0]?.[j]?.order === -1) {
|
|
1690
|
+
py1.order = 0;
|
|
1691
|
+
line += `${ARC_ORDER}&`;
|
|
1692
|
+
} else {
|
|
1693
|
+
takeDiff(py1, dy0[i0][j]);
|
|
1694
|
+
if (Math.abs(py1.u[py1.order]) > 1e5) {
|
|
1695
|
+
py1.order = 0;
|
|
1696
|
+
line += `${ARC_ORDER}&`;
|
|
1697
|
+
}
|
|
1698
|
+
}
|
|
1699
|
+
line += putdiff(py1.u[py1.order], py1.l[py1.order]);
|
|
1700
|
+
} else if (i0 >= 0 && rinexVersion === 2) {
|
|
1701
|
+
prevFlag[j * 2] = " ";
|
|
1702
|
+
prevFlag[j * 2 + 1] = " ";
|
|
1703
|
+
}
|
|
1704
|
+
line += " ";
|
|
1705
|
+
}
|
|
1706
|
+
if (i0 < 0 && rinexVersion !== 2) {
|
|
1707
|
+
for (const ch of sat.flag) line += ch === " " ? "&" : ch;
|
|
1708
|
+
} else {
|
|
1709
|
+
line += i0 < 0 ? strdiff("", sat.flag) : strdiff(prevFlag.join(""), sat.flag);
|
|
1710
|
+
line = line.replace(/ +$/, "");
|
|
1711
|
+
}
|
|
1712
|
+
lines.push(line);
|
|
1713
|
+
}
|
|
1714
|
+
return lines;
|
|
1715
|
+
}
|
|
1716
|
+
function putEventData(lines, cursor, v2, epochLine, out, ntypeGnss, setNtype) {
|
|
1717
|
+
if (v2) {
|
|
1718
|
+
out.push("&" + epochLine.slice(1));
|
|
1719
|
+
if (epochLine.length > 29) {
|
|
1720
|
+
const n = parseInt(epochLine.slice(29), 10) || 0;
|
|
1721
|
+
for (let i = 0; i < n; i++) {
|
|
1722
|
+
const l = chop(lines[cursor.li++] ?? "");
|
|
1723
|
+
out.push(l);
|
|
1724
|
+
if (l.slice(60).trimStart().startsWith("# / TYPES OF OBSERV") && l[5] !== " ") {
|
|
1725
|
+
setNtype(parseInt(l, 10));
|
|
1726
|
+
}
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1729
|
+
} else {
|
|
1730
|
+
out.push(epochLine.replace(/\s+$/, ""));
|
|
1731
|
+
const n = parseInt(epochLine.slice(32), 10) || 0;
|
|
1732
|
+
for (let i = 0; i < n; i++) {
|
|
1733
|
+
const l = chop(lines[cursor.li++] ?? "");
|
|
1734
|
+
out.push(l);
|
|
1735
|
+
if (l.slice(60).trimStart().startsWith("SYS / # / OBS TYPES") && l[0] !== " ") {
|
|
1736
|
+
ntypeGnss[l[0]] = parseInt(l.slice(3), 10);
|
|
1737
|
+
}
|
|
1738
|
+
}
|
|
1739
|
+
}
|
|
1740
|
+
}
|
|
1741
|
+
function readMoreSat(lines, cursor, n, epochLine) {
|
|
1742
|
+
let result = epochLine;
|
|
1743
|
+
let remaining = n;
|
|
1744
|
+
while (remaining > 12) {
|
|
1745
|
+
const l = lines[cursor.li++] ?? "";
|
|
1746
|
+
const chopped = chop(l);
|
|
1747
|
+
result += chopped[2] === " " ? chopped.slice(32) : chopped;
|
|
1748
|
+
remaining -= 12;
|
|
1749
|
+
}
|
|
1750
|
+
return result;
|
|
1751
|
+
}
|
|
1752
|
+
function readVersionFull(line) {
|
|
1753
|
+
if (line[5] === "2" && line[6] === " ") return 200;
|
|
1754
|
+
const d = (c) => c !== void 0 && c >= "0" && c <= "9";
|
|
1755
|
+
if (!d(line[5]) || line[6] !== "." || !d(line[7]) || !d(line[8])) return -1;
|
|
1756
|
+
return (line.charCodeAt(5) - 48) * 100 + (line.charCodeAt(7) - 48) * 10 + (line.charCodeAt(8) - 48);
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1312
1759
|
// src/rinex/format.ts
|
|
1313
1760
|
function padL(s, w) {
|
|
1314
1761
|
return s.length >= w ? s.slice(0, w) : s + " ".repeat(w - s.length);
|
|
@@ -6280,20 +6727,20 @@ var SIGNALS = {
|
|
|
6280
6727
|
// GLONASS L1OF, L2OF
|
|
6281
6728
|
};
|
|
6282
6729
|
function prnFor(gnssId, svId) {
|
|
6283
|
-
const
|
|
6730
|
+
const two7 = (n) => String(n).padStart(2, "0");
|
|
6284
6731
|
switch (gnssId) {
|
|
6285
6732
|
case 0:
|
|
6286
|
-
return svId >= 1 && svId <= 32 ? `G${
|
|
6733
|
+
return svId >= 1 && svId <= 32 ? `G${two7(svId)}` : null;
|
|
6287
6734
|
case 1:
|
|
6288
|
-
return svId >= 120 && svId <= 158 ? `S${
|
|
6735
|
+
return svId >= 120 && svId <= 158 ? `S${two7(svId - 100)}` : null;
|
|
6289
6736
|
case 2:
|
|
6290
|
-
return svId >= 1 && svId <= 36 ? `E${
|
|
6737
|
+
return svId >= 1 && svId <= 36 ? `E${two7(svId)}` : null;
|
|
6291
6738
|
case 3:
|
|
6292
|
-
return svId >= 1 && svId <= 63 ? `C${
|
|
6739
|
+
return svId >= 1 && svId <= 63 ? `C${two7(svId)}` : null;
|
|
6293
6740
|
case 5:
|
|
6294
|
-
return svId >= 1 && svId <= 10 ? `J${
|
|
6741
|
+
return svId >= 1 && svId <= 10 ? `J${two7(svId)}` : null;
|
|
6295
6742
|
case 6:
|
|
6296
|
-
return svId >= 1 && svId <= 32 ? `R${
|
|
6743
|
+
return svId >= 1 && svId <= 32 ? `R${two7(svId)}` : null;
|
|
6297
6744
|
default:
|
|
6298
6745
|
return null;
|
|
6299
6746
|
}
|
|
@@ -8680,20 +9127,1180 @@ function parseNovatelRange(data) {
|
|
|
8680
9127
|
return { epochs, messageCounts, obsCodes, badCrc };
|
|
8681
9128
|
}
|
|
8682
9129
|
|
|
9130
|
+
// src/trimble/frame.ts
|
|
9131
|
+
var STX = 2;
|
|
9132
|
+
var ETX = 3;
|
|
9133
|
+
var RAWDATA = 87;
|
|
9134
|
+
var RETSVDATA = 85;
|
|
9135
|
+
function* trimbleFrames(data, stats) {
|
|
9136
|
+
let i = 0;
|
|
9137
|
+
while (i + 6 <= data.length) {
|
|
9138
|
+
if (data[i] !== STX) {
|
|
9139
|
+
i++;
|
|
9140
|
+
continue;
|
|
9141
|
+
}
|
|
9142
|
+
const len = data[i + 3];
|
|
9143
|
+
const total = 4 + len + 2;
|
|
9144
|
+
if (i + total > data.length) {
|
|
9145
|
+
i++;
|
|
9146
|
+
continue;
|
|
9147
|
+
}
|
|
9148
|
+
if (data[i + total - 1] !== ETX) {
|
|
9149
|
+
i++;
|
|
9150
|
+
continue;
|
|
9151
|
+
}
|
|
9152
|
+
let cs = 0;
|
|
9153
|
+
for (let k = 1; k <= 3 + len; k++) cs = cs + data[i + k] & 255;
|
|
9154
|
+
if (cs !== data[i + 4 + len]) {
|
|
9155
|
+
stats.badChecksum++;
|
|
9156
|
+
i++;
|
|
9157
|
+
continue;
|
|
9158
|
+
}
|
|
9159
|
+
yield {
|
|
9160
|
+
start: i,
|
|
9161
|
+
status: data[i + 1],
|
|
9162
|
+
type: data[i + 2],
|
|
9163
|
+
len,
|
|
9164
|
+
payload: i + 4
|
|
9165
|
+
};
|
|
9166
|
+
i += total;
|
|
9167
|
+
}
|
|
9168
|
+
}
|
|
9169
|
+
|
|
9170
|
+
// src/trimble/nav.ts
|
|
9171
|
+
var GPS_EPOCH_MS13 = Date.UTC(1980, 0, 6);
|
|
9172
|
+
var SEC_PER_WEEK10 = 7 * 86400;
|
|
9173
|
+
var MS_PER_WEEK9 = SEC_PER_WEEK10 * 1e3;
|
|
9174
|
+
var GPS_PI2 = 3.1415926535898;
|
|
9175
|
+
var gpsMs3 = (week, sec) => GPS_EPOCH_MS13 + week * MS_PER_WEEK9 + sec * 1e3;
|
|
9176
|
+
var sowOf4 = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK10;
|
|
9177
|
+
var SUB_GPS_EPHEMERIS = 1;
|
|
9178
|
+
var SUB_ION_UTC = 3;
|
|
9179
|
+
function decodeGpsEphemeris2(data, view, base) {
|
|
9180
|
+
const prn = data[base + 5];
|
|
9181
|
+
if (prn < 1 || prn > 32) return null;
|
|
9182
|
+
const week = view.getUint16(base + 6, false);
|
|
9183
|
+
const iode = data[base + 11];
|
|
9184
|
+
const toc = view.getInt32(base + 16, false);
|
|
9185
|
+
const toe = view.getUint32(base + 20, false);
|
|
9186
|
+
const tgd = view.getFloat64(base + 24, false);
|
|
9187
|
+
const af2 = view.getFloat64(base + 32, false);
|
|
9188
|
+
const af1 = view.getFloat64(base + 40, false);
|
|
9189
|
+
const af0 = view.getFloat64(base + 48, false);
|
|
9190
|
+
const crs = view.getFloat64(base + 56, false);
|
|
9191
|
+
const deltaN = view.getFloat64(base + 64, false) * GPS_PI2;
|
|
9192
|
+
const m0 = view.getFloat64(base + 72, false) * GPS_PI2;
|
|
9193
|
+
const cuc = view.getFloat64(base + 80, false) * GPS_PI2;
|
|
9194
|
+
const e = view.getFloat64(base + 88, false);
|
|
9195
|
+
const cus = view.getFloat64(base + 96, false) * GPS_PI2;
|
|
9196
|
+
const sqrtA = view.getFloat64(base + 104, false);
|
|
9197
|
+
const cic = view.getFloat64(base + 112, false) * GPS_PI2;
|
|
9198
|
+
const omega0 = view.getFloat64(base + 120, false) * GPS_PI2;
|
|
9199
|
+
const cis = view.getFloat64(base + 128, false) * GPS_PI2;
|
|
9200
|
+
const i0 = view.getFloat64(base + 136, false) * GPS_PI2;
|
|
9201
|
+
const crc = view.getFloat64(base + 144, false);
|
|
9202
|
+
const omega = view.getFloat64(base + 152, false) * GPS_PI2;
|
|
9203
|
+
const omegaDot = view.getFloat64(base + 160, false) * GPS_PI2;
|
|
9204
|
+
const idot = view.getFloat64(base + 168, false) * GPS_PI2;
|
|
9205
|
+
const flags = view.getUint32(base + 176, false);
|
|
9206
|
+
return {
|
|
9207
|
+
system: "G",
|
|
9208
|
+
prn: `G${String(prn).padStart(2, "0")}`,
|
|
9209
|
+
toc: sowOf4(gpsMs3(week, toc)),
|
|
9210
|
+
tocDate: new Date(gpsMs3(week, toc)),
|
|
9211
|
+
af0,
|
|
9212
|
+
af1,
|
|
9213
|
+
af2,
|
|
9214
|
+
iode,
|
|
9215
|
+
crs,
|
|
9216
|
+
deltaN,
|
|
9217
|
+
m0,
|
|
9218
|
+
cuc,
|
|
9219
|
+
e,
|
|
9220
|
+
cus,
|
|
9221
|
+
sqrtA,
|
|
9222
|
+
toe,
|
|
9223
|
+
cic,
|
|
9224
|
+
omega0,
|
|
9225
|
+
cis,
|
|
9226
|
+
i0,
|
|
9227
|
+
crc,
|
|
9228
|
+
omega,
|
|
9229
|
+
omegaDot,
|
|
9230
|
+
idot,
|
|
9231
|
+
week,
|
|
9232
|
+
svHealth: flags >>> 4 & 127,
|
|
9233
|
+
tgd
|
|
9234
|
+
};
|
|
9235
|
+
}
|
|
9236
|
+
function parseTrimbleNav(data) {
|
|
9237
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
9238
|
+
const stats = { badChecksum: 0 };
|
|
9239
|
+
const ephemerides = [];
|
|
9240
|
+
const ionoCorrections = {};
|
|
9241
|
+
const retsvCounts = {};
|
|
9242
|
+
let leapSeconds = null;
|
|
9243
|
+
const lastIode = /* @__PURE__ */ new Map();
|
|
9244
|
+
for (const f of trimbleFrames(data, stats)) {
|
|
9245
|
+
if (f.type !== RETSVDATA) continue;
|
|
9246
|
+
const sub = data[f.payload];
|
|
9247
|
+
retsvCounts[sub] = (retsvCounts[sub] ?? 0) + 1;
|
|
9248
|
+
if (sub === SUB_GPS_EPHEMERIS && f.len >= 178) {
|
|
9249
|
+
const eph = decodeGpsEphemeris2(data, view, f.start);
|
|
9250
|
+
if (!eph) continue;
|
|
9251
|
+
if (lastIode.get(eph.prn) === eph.iode) continue;
|
|
9252
|
+
lastIode.set(eph.prn, eph.iode);
|
|
9253
|
+
ephemerides.push(eph);
|
|
9254
|
+
} else if (sub === SUB_ION_UTC && f.len >= 125) {
|
|
9255
|
+
const p = f.start;
|
|
9256
|
+
const alpha = [];
|
|
9257
|
+
const beta = [];
|
|
9258
|
+
for (let i = 0; i < 4; i++) {
|
|
9259
|
+
alpha.push(view.getFloat64(p + 6 + i * 8, false));
|
|
9260
|
+
beta.push(view.getFloat64(p + 38 + i * 8, false));
|
|
9261
|
+
}
|
|
9262
|
+
ionoCorrections["GPSA"] = alpha;
|
|
9263
|
+
ionoCorrections["GPSB"] = beta;
|
|
9264
|
+
leapSeconds = Math.trunc(view.getFloat64(p + 94, false));
|
|
9265
|
+
}
|
|
9266
|
+
}
|
|
9267
|
+
return {
|
|
9268
|
+
ephemerides,
|
|
9269
|
+
ionoCorrections,
|
|
9270
|
+
leapSeconds,
|
|
9271
|
+
retsvCounts,
|
|
9272
|
+
badChecksum: stats.badChecksum
|
|
9273
|
+
};
|
|
9274
|
+
}
|
|
9275
|
+
|
|
9276
|
+
// src/trimble/index.ts
|
|
9277
|
+
var GPS_EPOCH_MS14 = Date.UTC(1980, 0, 6);
|
|
9278
|
+
var MS_PER_WEEK10 = 7 * 864e5;
|
|
9279
|
+
var REC_TYPE_27 = 6;
|
|
9280
|
+
var SYS = {
|
|
9281
|
+
0: "G",
|
|
9282
|
+
// GPS
|
|
9283
|
+
1: "S",
|
|
9284
|
+
// SBAS
|
|
9285
|
+
2: "R",
|
|
9286
|
+
// GLONASS
|
|
9287
|
+
3: "E",
|
|
9288
|
+
// Galileo
|
|
9289
|
+
4: "J",
|
|
9290
|
+
// QZSS
|
|
9291
|
+
5: "C",
|
|
9292
|
+
// BeiDou (pre-ICD numbering)
|
|
9293
|
+
7: "C",
|
|
9294
|
+
// BeiDou (ICD numbering)
|
|
9295
|
+
9: "I",
|
|
9296
|
+
// NavIC / IRNSS
|
|
9297
|
+
10: "C"
|
|
9298
|
+
// BeiDou
|
|
9299
|
+
};
|
|
9300
|
+
var CODES = {
|
|
9301
|
+
"G0-0": "1C",
|
|
9302
|
+
"G0-20": "1L",
|
|
9303
|
+
"G1-2": "2W",
|
|
9304
|
+
"G1-5": "2L",
|
|
9305
|
+
"G2-6": "5I",
|
|
9306
|
+
"G2-7": "5Q",
|
|
9307
|
+
"G2-8": "5X",
|
|
9308
|
+
"R0-0": "1C",
|
|
9309
|
+
"R0-1": "1P",
|
|
9310
|
+
"R1-0": "2C",
|
|
9311
|
+
"R1-1": "2P",
|
|
9312
|
+
"E0-23": "1C",
|
|
9313
|
+
"E2-11": "5Q",
|
|
9314
|
+
"E3-11": "7Q",
|
|
9315
|
+
"E4-14": "8Q",
|
|
9316
|
+
"E5-36": "6C",
|
|
9317
|
+
"C0-20": "1P",
|
|
9318
|
+
"C2-8": "5P",
|
|
9319
|
+
"C3-6": "7D",
|
|
9320
|
+
"C6-26": "2I",
|
|
9321
|
+
"C7-29": "6I",
|
|
9322
|
+
"S0-0": "1C",
|
|
9323
|
+
"S2-6": "5I",
|
|
9324
|
+
"J0-0": "1C"
|
|
9325
|
+
};
|
|
9326
|
+
var BAND_DIGIT = {
|
|
9327
|
+
0: "1",
|
|
9328
|
+
// L1 / E1 / B1C (1575.42)
|
|
9329
|
+
1: "2",
|
|
9330
|
+
// L2 / G2 (1227.6)
|
|
9331
|
+
2: "5",
|
|
9332
|
+
// L5 / E5a (1176.45)
|
|
9333
|
+
3: "7",
|
|
9334
|
+
// E5b / B2b (1207.14)
|
|
9335
|
+
4: "8",
|
|
9336
|
+
// E5 AltBOC (1191.795)
|
|
9337
|
+
5: "6",
|
|
9338
|
+
// E6 (1278.75)
|
|
9339
|
+
6: "2",
|
|
9340
|
+
// B1I (1561.098)
|
|
9341
|
+
7: "6",
|
|
9342
|
+
// B3I (1268.52)
|
|
9343
|
+
8: "1",
|
|
9344
|
+
// BeiDou E1 (1589.742)
|
|
9345
|
+
9: "3",
|
|
9346
|
+
// GLONASS G3 CDMA (1202.025)
|
|
9347
|
+
11: "9"
|
|
9348
|
+
// NavIC S-band (2492.028)
|
|
9349
|
+
};
|
|
9350
|
+
function rinexCode(sys, band, track) {
|
|
9351
|
+
const key = `${sys}${band}-${track}`;
|
|
9352
|
+
return CODES[key] ?? `${BAND_DIGIT[band] ?? "?"}X`;
|
|
9353
|
+
}
|
|
9354
|
+
function rinexPrn(sys, svid) {
|
|
9355
|
+
let n = svid;
|
|
9356
|
+
if (sys === "S")
|
|
9357
|
+
n = svid - 100;
|
|
9358
|
+
else if (sys === "J" && svid >= 193) n = svid - 192;
|
|
9359
|
+
return `${sys}${String(n).padStart(2, "0")}`;
|
|
9360
|
+
}
|
|
9361
|
+
var readS16 = (dv, o) => dv.getInt16(o, false);
|
|
9362
|
+
function readS24(d, o) {
|
|
9363
|
+
const v = d[o] << 16 | d[o + 1] << 8 | d[o + 2];
|
|
9364
|
+
return v & 8388608 ? v - 16777216 : v;
|
|
9365
|
+
}
|
|
9366
|
+
function readS48(d, dv, o) {
|
|
9367
|
+
const hi = d[o] << 8 | d[o + 1];
|
|
9368
|
+
const lo = dv.getUint32(o + 2, false);
|
|
9369
|
+
const v = hi * 4294967296 + lo;
|
|
9370
|
+
return hi & 32768 ? v - 281474976710656 : v;
|
|
9371
|
+
}
|
|
9372
|
+
function parseTrimble(data) {
|
|
9373
|
+
const stats = { badChecksum: 0 };
|
|
9374
|
+
const epochs = [];
|
|
9375
|
+
const obsCodes = {};
|
|
9376
|
+
const recordCounts = {};
|
|
9377
|
+
const retsvCounts = {};
|
|
9378
|
+
let pages = [];
|
|
9379
|
+
let msgReply = -1;
|
|
9380
|
+
let lastPage = 0;
|
|
9381
|
+
let msgPages = 0;
|
|
9382
|
+
let epoch = null;
|
|
9383
|
+
const finalize = () => {
|
|
9384
|
+
if (epoch) decodeEpoch(epoch, epochs, obsCodes);
|
|
9385
|
+
epoch = null;
|
|
9386
|
+
};
|
|
9387
|
+
const onMessage = (content, reply) => {
|
|
9388
|
+
if (epoch && reply === epoch.reply) {
|
|
9389
|
+
epoch.chunks.push(content);
|
|
9390
|
+
return;
|
|
9391
|
+
}
|
|
9392
|
+
finalize();
|
|
9393
|
+
if (content.length < 12) return;
|
|
9394
|
+
const dv = new DataView(
|
|
9395
|
+
content.buffer,
|
|
9396
|
+
content.byteOffset,
|
|
9397
|
+
content.byteLength
|
|
9398
|
+
);
|
|
9399
|
+
const headerLen = content[0];
|
|
9400
|
+
const week = dv.getUint16(1, false);
|
|
9401
|
+
const towMs = dv.getUint32(3, false);
|
|
9402
|
+
const nsv = content[10];
|
|
9403
|
+
const eflags = content[11];
|
|
9404
|
+
if (week < 1024 || week > 4096 || headerLen < 12 || nsv === 0) return;
|
|
9405
|
+
let svStart = headerLen;
|
|
9406
|
+
if (eflags & 32 && svStart < content.length) svStart += content[svStart];
|
|
9407
|
+
epoch = {
|
|
9408
|
+
reply,
|
|
9409
|
+
week,
|
|
9410
|
+
towMs,
|
|
9411
|
+
nsv,
|
|
9412
|
+
chunks: [content.subarray(svStart)]
|
|
9413
|
+
};
|
|
9414
|
+
};
|
|
9415
|
+
const completeMessage = () => {
|
|
9416
|
+
const total = pages.reduce((a, c) => a + c.length, 0);
|
|
9417
|
+
const content = new Uint8Array(total);
|
|
9418
|
+
let o = 0;
|
|
9419
|
+
for (const c of pages) {
|
|
9420
|
+
content.set(c, o);
|
|
9421
|
+
o += c.length;
|
|
9422
|
+
}
|
|
9423
|
+
const reply = msgReply;
|
|
9424
|
+
pages = [];
|
|
9425
|
+
onMessage(content, reply);
|
|
9426
|
+
};
|
|
9427
|
+
for (const f of trimbleFrames(data, stats)) {
|
|
9428
|
+
if (f.type !== RAWDATA) {
|
|
9429
|
+
if (f.type === 85) {
|
|
9430
|
+
const sub = data[f.payload];
|
|
9431
|
+
retsvCounts[sub] = (retsvCounts[sub] ?? 0) + 1;
|
|
9432
|
+
}
|
|
9433
|
+
continue;
|
|
9434
|
+
}
|
|
9435
|
+
const recType = data[f.payload];
|
|
9436
|
+
recordCounts[recType] = (recordCounts[recType] ?? 0) + 1;
|
|
9437
|
+
if (recType !== REC_TYPE_27) continue;
|
|
9438
|
+
const pageByte = data[f.payload + 1];
|
|
9439
|
+
const page = pageByte >> 4;
|
|
9440
|
+
const pagesTotal = pageByte & 15;
|
|
9441
|
+
const reply = data[f.payload + 2];
|
|
9442
|
+
const content = data.subarray(f.payload + 4, f.payload + f.len);
|
|
9443
|
+
if (page === 1) {
|
|
9444
|
+
pages = [content];
|
|
9445
|
+
msgReply = reply;
|
|
9446
|
+
msgPages = pagesTotal;
|
|
9447
|
+
lastPage = 1;
|
|
9448
|
+
} else if (reply === msgReply && page === lastPage + 1) {
|
|
9449
|
+
pages.push(content);
|
|
9450
|
+
lastPage = page;
|
|
9451
|
+
} else {
|
|
9452
|
+
pages = [];
|
|
9453
|
+
continue;
|
|
9454
|
+
}
|
|
9455
|
+
if (lastPage === msgPages) completeMessage();
|
|
9456
|
+
}
|
|
9457
|
+
finalize();
|
|
9458
|
+
return {
|
|
9459
|
+
epochs,
|
|
9460
|
+
obsCodes,
|
|
9461
|
+
recordCounts,
|
|
9462
|
+
retsvCounts,
|
|
9463
|
+
badChecksum: stats.badChecksum
|
|
9464
|
+
};
|
|
9465
|
+
}
|
|
9466
|
+
function decodeEpoch(epoch, epochs, obsCodes) {
|
|
9467
|
+
const total = epoch.chunks.reduce((a, c) => a + c.length, 0);
|
|
9468
|
+
const M = new Uint8Array(total);
|
|
9469
|
+
let o = 0;
|
|
9470
|
+
for (const c of epoch.chunks) {
|
|
9471
|
+
M.set(c, o);
|
|
9472
|
+
o += c.length;
|
|
9473
|
+
}
|
|
9474
|
+
const dv = new DataView(M.buffer, M.byteOffset, M.byteLength);
|
|
9475
|
+
const timeMs = GPS_EPOCH_MS14 + epoch.week * MS_PER_WEEK10 + epoch.towMs;
|
|
9476
|
+
const meas = [];
|
|
9477
|
+
let q = 0;
|
|
9478
|
+
for (let sv = 0; sv < epoch.nsv && q + 8 <= M.length; sv++) {
|
|
9479
|
+
const svLen = M[q];
|
|
9480
|
+
if (svLen < 8 || q + svLen > M.length) break;
|
|
9481
|
+
const svid = M[q + 1];
|
|
9482
|
+
const sys = SYS[M[q + 2] & 63];
|
|
9483
|
+
const chan = M[q + 3] << 24 >> 24;
|
|
9484
|
+
const nblk = M[q + 4];
|
|
9485
|
+
const prn = sys ? rinexPrn(sys, svid) : null;
|
|
9486
|
+
const gloChannel = sys === "R" ? chan : null;
|
|
9487
|
+
let r = q + svLen;
|
|
9488
|
+
let pr0 = 0;
|
|
9489
|
+
for (let b = 0; b < nblk; b++) {
|
|
9490
|
+
if (r + 5 > M.length) break;
|
|
9491
|
+
const mLen = M[r];
|
|
9492
|
+
if (mLen < 5 || r + mLen > M.length) break;
|
|
9493
|
+
const band = M[r + 1];
|
|
9494
|
+
const track = M[r + 2];
|
|
9495
|
+
const cn0 = dv.getUint16(r + 3, false) / 10;
|
|
9496
|
+
let p = r + 5;
|
|
9497
|
+
let pr;
|
|
9498
|
+
if (b === 0) {
|
|
9499
|
+
const scale = sys === "S" || sys === "J" ? 64 : 128;
|
|
9500
|
+
pr = dv.getUint32(p, false) / scale;
|
|
9501
|
+
p += 4;
|
|
9502
|
+
pr0 = pr;
|
|
9503
|
+
} else {
|
|
9504
|
+
pr = pr0 + readS16(dv, p) / 256;
|
|
9505
|
+
p += 2;
|
|
9506
|
+
}
|
|
9507
|
+
const cp = -readS48(M, dv, p) / 32768;
|
|
9508
|
+
p += 6;
|
|
9509
|
+
const cycleSlipCount = M[p];
|
|
9510
|
+
p += 1;
|
|
9511
|
+
const mf = M[p];
|
|
9512
|
+
p += 1;
|
|
9513
|
+
let mf2 = 0;
|
|
9514
|
+
if (mf & 128) {
|
|
9515
|
+
mf2 = M[p];
|
|
9516
|
+
p += 1;
|
|
9517
|
+
let f = mf2;
|
|
9518
|
+
while (f & 128) {
|
|
9519
|
+
f = M[p];
|
|
9520
|
+
p += 1;
|
|
9521
|
+
}
|
|
9522
|
+
}
|
|
9523
|
+
if (mf2 & 1) p += 1;
|
|
9524
|
+
let doppler = null;
|
|
9525
|
+
if (mf & 4) doppler = readS24(M, p) / 256;
|
|
9526
|
+
if (prn && sys) {
|
|
9527
|
+
const code = rinexCode(sys, band, track);
|
|
9528
|
+
meas.push({
|
|
9529
|
+
prn,
|
|
9530
|
+
code,
|
|
9531
|
+
pr: mf & 2 ? pr : null,
|
|
9532
|
+
cp: mf & 1 ? cp : null,
|
|
9533
|
+
doppler: mf & 1 ? doppler : null,
|
|
9534
|
+
cn0,
|
|
9535
|
+
cycleSlipCount,
|
|
9536
|
+
cycleSlip: (mf & 8) !== 0,
|
|
9537
|
+
gloChannel
|
|
9538
|
+
});
|
|
9539
|
+
const list = obsCodes[sys] ??= [];
|
|
9540
|
+
if (!list.includes(code)) list.push(code);
|
|
9541
|
+
}
|
|
9542
|
+
r += mLen;
|
|
9543
|
+
}
|
|
9544
|
+
q = r;
|
|
9545
|
+
}
|
|
9546
|
+
epochs.push({ timeMs, meas });
|
|
9547
|
+
}
|
|
9548
|
+
|
|
9549
|
+
// src/binex/frame.ts
|
|
9550
|
+
var CRC16_TABLE = (() => {
|
|
9551
|
+
const t = new Uint16Array(256);
|
|
9552
|
+
for (let n = 0; n < 256; n++) {
|
|
9553
|
+
let c = n << 8;
|
|
9554
|
+
for (let k = 0; k < 8; k++)
|
|
9555
|
+
c = c & 32768 ? (c << 1 ^ 4129) & 65535 : c << 1 & 65535;
|
|
9556
|
+
t[n] = c;
|
|
9557
|
+
}
|
|
9558
|
+
return t;
|
|
9559
|
+
})();
|
|
9560
|
+
function binexCrc16(data, start, end) {
|
|
9561
|
+
let crc = 0;
|
|
9562
|
+
for (let i = start; i < end; i++)
|
|
9563
|
+
crc = (crc << 8 ^ CRC16_TABLE[(crc >> 8 ^ data[i]) & 255]) & 65535;
|
|
9564
|
+
return crc;
|
|
9565
|
+
}
|
|
9566
|
+
var CRC32_TABLE = (() => {
|
|
9567
|
+
const t = new Uint32Array(256);
|
|
9568
|
+
for (let n = 0; n < 256; n++) {
|
|
9569
|
+
let c = n << 24;
|
|
9570
|
+
for (let k = 0; k < 8; k++)
|
|
9571
|
+
c = c & 2147483648 ? c << 1 ^ 79764919 : c << 1;
|
|
9572
|
+
t[n] = c >>> 0;
|
|
9573
|
+
}
|
|
9574
|
+
return t;
|
|
9575
|
+
})();
|
|
9576
|
+
function binexCrc32(data, start, end) {
|
|
9577
|
+
let crc = 0;
|
|
9578
|
+
for (let i = start; i < end; i++)
|
|
9579
|
+
crc = (crc << 8 ^ CRC32_TABLE[(crc >>> 24 ^ data[i]) & 255]) >>> 0;
|
|
9580
|
+
return crc >>> 0;
|
|
9581
|
+
}
|
|
9582
|
+
function binexCsum8(data, start, end) {
|
|
9583
|
+
let cs = 0;
|
|
9584
|
+
for (let i = start; i < end; i++) cs ^= data[i];
|
|
9585
|
+
return cs & 255;
|
|
9586
|
+
}
|
|
9587
|
+
function getBnxi(data, pos) {
|
|
9588
|
+
let value = 0;
|
|
9589
|
+
for (let i = 0; i < 3; i++) {
|
|
9590
|
+
const b = data[pos + i] ?? 0;
|
|
9591
|
+
value = value * 128 + (b & 127);
|
|
9592
|
+
if (!(b & 128)) return { value, size: i + 1 };
|
|
9593
|
+
}
|
|
9594
|
+
value = value * 256 + (data[pos + 3] ?? 0);
|
|
9595
|
+
return { value, size: 4 };
|
|
9596
|
+
}
|
|
9597
|
+
var SYNC = /* @__PURE__ */ new Map([
|
|
9598
|
+
[226, { littleEndian: false, enhanced: false }],
|
|
9599
|
+
[194, { littleEndian: true, enhanced: false }],
|
|
9600
|
+
[232, { littleEndian: false, enhanced: true }],
|
|
9601
|
+
[200, { littleEndian: true, enhanced: true }]
|
|
9602
|
+
]);
|
|
9603
|
+
function csumWidth(covered, enhanced) {
|
|
9604
|
+
if (enhanced) {
|
|
9605
|
+
if (covered < 128) return 2;
|
|
9606
|
+
if (covered < 1048576) return 4;
|
|
9607
|
+
return 16;
|
|
9608
|
+
}
|
|
9609
|
+
if (covered < 128) return 1;
|
|
9610
|
+
if (covered < 4096) return 2;
|
|
9611
|
+
if (covered < 1048576) return 4;
|
|
9612
|
+
return 16;
|
|
9613
|
+
}
|
|
9614
|
+
function checksumOk(data, view, covStart, covEnd, width) {
|
|
9615
|
+
switch (width) {
|
|
9616
|
+
case 1:
|
|
9617
|
+
return binexCsum8(data, covStart, covEnd) === (data[covEnd] ?? -1);
|
|
9618
|
+
case 2:
|
|
9619
|
+
return binexCrc16(data, covStart, covEnd) === view.getUint16(covEnd);
|
|
9620
|
+
case 4:
|
|
9621
|
+
return binexCrc32(data, covStart, covEnd) === view.getUint32(covEnd);
|
|
9622
|
+
default:
|
|
9623
|
+
return false;
|
|
9624
|
+
}
|
|
9625
|
+
}
|
|
9626
|
+
function* binexRecords(data, view, stats) {
|
|
9627
|
+
let i = 0;
|
|
9628
|
+
while (i + 2 <= data.length) {
|
|
9629
|
+
const sync = SYNC.get(data[i]);
|
|
9630
|
+
if (!sync) {
|
|
9631
|
+
i++;
|
|
9632
|
+
continue;
|
|
9633
|
+
}
|
|
9634
|
+
const id = data[i + 1];
|
|
9635
|
+
const { value: len, size: lenH } = getBnxi(data, i + 2);
|
|
9636
|
+
const body = i + 2 + lenH;
|
|
9637
|
+
const covStart = i + 1;
|
|
9638
|
+
const covEnd = body + len;
|
|
9639
|
+
const covered = covEnd - covStart;
|
|
9640
|
+
const width = csumWidth(covered, sync.enhanced);
|
|
9641
|
+
if (width === 16 || covEnd + width > data.length) {
|
|
9642
|
+
i++;
|
|
9643
|
+
continue;
|
|
9644
|
+
}
|
|
9645
|
+
if (!checksumOk(data, view, covStart, covEnd, width)) {
|
|
9646
|
+
stats.badCrc++;
|
|
9647
|
+
i++;
|
|
9648
|
+
continue;
|
|
9649
|
+
}
|
|
9650
|
+
yield { id, start: i, body, len, ...sync };
|
|
9651
|
+
i = covEnd + width;
|
|
9652
|
+
}
|
|
9653
|
+
}
|
|
9654
|
+
|
|
9655
|
+
// src/binex/nav.ts
|
|
9656
|
+
var GPS_EPOCH_MS15 = Date.UTC(1980, 0, 6);
|
|
9657
|
+
var GLO_DAY0_MS = Date.UTC(1980, 0, 1);
|
|
9658
|
+
var BDT_EPOCH_MS4 = Date.UTC(2006, 0, 1);
|
|
9659
|
+
var SEC_PER_WEEK11 = 7 * 86400;
|
|
9660
|
+
var MS_PER_WEEK11 = SEC_PER_WEEK11 * 1e3;
|
|
9661
|
+
var SC2RAD = GPS_PI;
|
|
9662
|
+
var gpsMs4 = (week, sec) => GPS_EPOCH_MS15 + week * MS_PER_WEEK11 + sec * 1e3;
|
|
9663
|
+
var sowOf5 = (dateMs) => (dateMs / 1e3 % SEC_PER_WEEK11 + SEC_PER_WEEK11) % SEC_PER_WEEK11;
|
|
9664
|
+
var two5 = (n) => String(n).padStart(2, "0");
|
|
9665
|
+
var Reader = class {
|
|
9666
|
+
constructor(view, start, le) {
|
|
9667
|
+
this.view = view;
|
|
9668
|
+
this.le = le;
|
|
9669
|
+
this.p = start;
|
|
9670
|
+
}
|
|
9671
|
+
p;
|
|
9672
|
+
u1() {
|
|
9673
|
+
return this.view.getUint8(this.p++);
|
|
9674
|
+
}
|
|
9675
|
+
i1() {
|
|
9676
|
+
return this.view.getInt8(this.p++);
|
|
9677
|
+
}
|
|
9678
|
+
u2() {
|
|
9679
|
+
const v = this.view.getUint16(this.p, this.le);
|
|
9680
|
+
this.p += 2;
|
|
9681
|
+
return v;
|
|
9682
|
+
}
|
|
9683
|
+
i4() {
|
|
9684
|
+
const v = this.view.getInt32(this.p, this.le);
|
|
9685
|
+
this.p += 4;
|
|
9686
|
+
return v;
|
|
9687
|
+
}
|
|
9688
|
+
u4() {
|
|
9689
|
+
const v = this.view.getUint32(this.p, this.le);
|
|
9690
|
+
this.p += 4;
|
|
9691
|
+
return v;
|
|
9692
|
+
}
|
|
9693
|
+
r4() {
|
|
9694
|
+
const v = this.view.getFloat32(this.p, this.le);
|
|
9695
|
+
this.p += 4;
|
|
9696
|
+
return v;
|
|
9697
|
+
}
|
|
9698
|
+
r8() {
|
|
9699
|
+
const v = this.view.getFloat64(this.p, this.le);
|
|
9700
|
+
this.p += 8;
|
|
9701
|
+
return v;
|
|
9702
|
+
}
|
|
9703
|
+
};
|
|
9704
|
+
function readKeplerCore(r) {
|
|
9705
|
+
const deltaN = r.r4() * SC2RAD;
|
|
9706
|
+
const m0 = r.r8();
|
|
9707
|
+
const e = r.r8();
|
|
9708
|
+
const sqrtA = r.r8();
|
|
9709
|
+
const cic = r.r4();
|
|
9710
|
+
const crc = r.r4();
|
|
9711
|
+
const cis = r.r4();
|
|
9712
|
+
const crs = r.r4();
|
|
9713
|
+
const cuc = r.r4();
|
|
9714
|
+
const cus = r.r4();
|
|
9715
|
+
const omega0 = r.r8();
|
|
9716
|
+
const omega = r.r8();
|
|
9717
|
+
const i0 = r.r8();
|
|
9718
|
+
const omegaDot = r.r4() * SC2RAD;
|
|
9719
|
+
const idot = r.r4() * SC2RAD;
|
|
9720
|
+
return {
|
|
9721
|
+
deltaN,
|
|
9722
|
+
m0,
|
|
9723
|
+
e,
|
|
9724
|
+
sqrtA,
|
|
9725
|
+
cic,
|
|
9726
|
+
crc,
|
|
9727
|
+
cis,
|
|
9728
|
+
crs,
|
|
9729
|
+
cuc,
|
|
9730
|
+
cus,
|
|
9731
|
+
omega0,
|
|
9732
|
+
omega,
|
|
9733
|
+
i0,
|
|
9734
|
+
omegaDot,
|
|
9735
|
+
idot
|
|
9736
|
+
};
|
|
9737
|
+
}
|
|
9738
|
+
function decodeGpsQzss(view, p, le, sys) {
|
|
9739
|
+
const r = new Reader(view, p, le);
|
|
9740
|
+
const prnRaw = r.u1() + (sys === "G" ? 1 : 0);
|
|
9741
|
+
const prn = sys === "G" ? prnRaw : prnRaw - 192;
|
|
9742
|
+
if (sys === "G" && (prn < 1 || prn > 32)) return null;
|
|
9743
|
+
if (sys === "J" && (prn < 1 || prn > 10)) return null;
|
|
9744
|
+
const week = r.u2();
|
|
9745
|
+
r.i4();
|
|
9746
|
+
const toes = r.i4();
|
|
9747
|
+
const tgd = r.r4();
|
|
9748
|
+
r.i4();
|
|
9749
|
+
const af2 = r.r4();
|
|
9750
|
+
const af1 = r.r4();
|
|
9751
|
+
const af0 = r.r4();
|
|
9752
|
+
const iode = r.i4();
|
|
9753
|
+
const core = readKeplerCore(r);
|
|
9754
|
+
r.r4();
|
|
9755
|
+
const svHealth = r.u2();
|
|
9756
|
+
const tocDate = new Date(gpsMs4(week, toes));
|
|
9757
|
+
return {
|
|
9758
|
+
system: sys,
|
|
9759
|
+
prn: `${sys}${two5(prn)}`,
|
|
9760
|
+
toc: sowOf5(tocDate.getTime()),
|
|
9761
|
+
tocDate,
|
|
9762
|
+
af0,
|
|
9763
|
+
af1,
|
|
9764
|
+
af2,
|
|
9765
|
+
iode,
|
|
9766
|
+
...core,
|
|
9767
|
+
toe: toes,
|
|
9768
|
+
week,
|
|
9769
|
+
svHealth,
|
|
9770
|
+
tgd
|
|
9771
|
+
};
|
|
9772
|
+
}
|
|
9773
|
+
function decodeGalileo(view, p, le) {
|
|
9774
|
+
const r = new Reader(view, p, le);
|
|
9775
|
+
const prn = r.u1() + 1;
|
|
9776
|
+
if (prn < 1 || prn > 36) return null;
|
|
9777
|
+
const week = r.u2();
|
|
9778
|
+
r.i4();
|
|
9779
|
+
const toes = r.i4();
|
|
9780
|
+
const tgd = r.r4();
|
|
9781
|
+
r.r4();
|
|
9782
|
+
const iode = r.i4();
|
|
9783
|
+
const af2 = r.r4();
|
|
9784
|
+
const af1 = r.r4();
|
|
9785
|
+
const af0 = r.r4();
|
|
9786
|
+
const core = readKeplerCore(r);
|
|
9787
|
+
r.r4();
|
|
9788
|
+
const svHealth = r.u2();
|
|
9789
|
+
const tocDate = new Date(gpsMs4(week, toes));
|
|
9790
|
+
return {
|
|
9791
|
+
system: "E",
|
|
9792
|
+
prn: `E${two5(prn)}`,
|
|
9793
|
+
toc: sowOf5(tocDate.getTime()),
|
|
9794
|
+
tocDate,
|
|
9795
|
+
af0,
|
|
9796
|
+
af1,
|
|
9797
|
+
af2,
|
|
9798
|
+
iode,
|
|
9799
|
+
...core,
|
|
9800
|
+
toe: toes,
|
|
9801
|
+
week,
|
|
9802
|
+
svHealth,
|
|
9803
|
+
tgd
|
|
9804
|
+
};
|
|
9805
|
+
}
|
|
9806
|
+
function bdsTgd(tgd) {
|
|
9807
|
+
tgd &= 1023;
|
|
9808
|
+
return tgd & 512 ? -1e-10 * (~tgd & 511) : 1e-10 * (tgd & 511);
|
|
9809
|
+
}
|
|
9810
|
+
function decodeBeidou(view, p, le) {
|
|
9811
|
+
const r = new Reader(view, p, le);
|
|
9812
|
+
const prn = r.u1();
|
|
9813
|
+
if (prn < 1 || prn > 63) return null;
|
|
9814
|
+
const week = r.u2();
|
|
9815
|
+
r.i4();
|
|
9816
|
+
r.i4();
|
|
9817
|
+
const toes = r.i4();
|
|
9818
|
+
const af2 = r.r4();
|
|
9819
|
+
const af1 = r.r4();
|
|
9820
|
+
const af0 = r.r4();
|
|
9821
|
+
const core = readKeplerCore(r);
|
|
9822
|
+
const flag1 = r.u2();
|
|
9823
|
+
const flag2 = r.u4();
|
|
9824
|
+
const iode = flag1 >> 6 & 31;
|
|
9825
|
+
const svHealth = flag1 & 1;
|
|
9826
|
+
const tgd = bdsTgd(flag2 >> 4);
|
|
9827
|
+
const tocDate = new Date(BDT_EPOCH_MS4 + week * MS_PER_WEEK11 + toes * 1e3);
|
|
9828
|
+
return {
|
|
9829
|
+
system: "C",
|
|
9830
|
+
prn: `C${two5(prn)}`,
|
|
9831
|
+
toc: sowOf5(tocDate.getTime()),
|
|
9832
|
+
tocDate,
|
|
9833
|
+
af0,
|
|
9834
|
+
af1,
|
|
9835
|
+
af2,
|
|
9836
|
+
iode,
|
|
9837
|
+
...core,
|
|
9838
|
+
toe: toes,
|
|
9839
|
+
week,
|
|
9840
|
+
// RINEX BDS week field is the BDT week
|
|
9841
|
+
svHealth,
|
|
9842
|
+
tgd
|
|
9843
|
+
};
|
|
9844
|
+
}
|
|
9845
|
+
function decodeGlonass(view, p, le) {
|
|
9846
|
+
const r = new Reader(view, p, le);
|
|
9847
|
+
const slot = r.u1() + 1;
|
|
9848
|
+
if (slot < 1 || slot > 27) return null;
|
|
9849
|
+
const day = r.u2();
|
|
9850
|
+
const tod = r.u4();
|
|
9851
|
+
const tauN = r.r8();
|
|
9852
|
+
const gammaN = r.r8();
|
|
9853
|
+
const tof = r.u4();
|
|
9854
|
+
const x = r.r8();
|
|
9855
|
+
const xDot = r.r8();
|
|
9856
|
+
const xAcc = r.r8();
|
|
9857
|
+
const y = r.r8();
|
|
9858
|
+
const yDot = r.r8();
|
|
9859
|
+
const yAcc = r.r8();
|
|
9860
|
+
const z = r.r8();
|
|
9861
|
+
const zDot = r.r8();
|
|
9862
|
+
const zAcc = r.r8();
|
|
9863
|
+
const health = r.u1() & 1;
|
|
9864
|
+
const freqNum = r.i1();
|
|
9865
|
+
const tocDate = new Date(
|
|
9866
|
+
GLO_DAY0_MS + (day - 1) * 864e5 + (tod - 10800) * 1e3
|
|
9867
|
+
);
|
|
9868
|
+
return {
|
|
9869
|
+
system: "R",
|
|
9870
|
+
prn: `R${two5(slot)}`,
|
|
9871
|
+
tocDate,
|
|
9872
|
+
tauN,
|
|
9873
|
+
gammaN,
|
|
9874
|
+
messageFrameTime: tof,
|
|
9875
|
+
x,
|
|
9876
|
+
y,
|
|
9877
|
+
z,
|
|
9878
|
+
xDot,
|
|
9879
|
+
yDot,
|
|
9880
|
+
zDot,
|
|
9881
|
+
xAcc,
|
|
9882
|
+
yAcc,
|
|
9883
|
+
zAcc,
|
|
9884
|
+
health,
|
|
9885
|
+
freqNum
|
|
9886
|
+
};
|
|
9887
|
+
}
|
|
9888
|
+
function decodeSbas(view, p, le) {
|
|
9889
|
+
const r = new Reader(view, p, le);
|
|
9890
|
+
const prn = r.u1();
|
|
9891
|
+
const week = r.u2();
|
|
9892
|
+
const tow = r.u4();
|
|
9893
|
+
const af0 = r.r8();
|
|
9894
|
+
const af1 = r.r4();
|
|
9895
|
+
const toe = r.u4();
|
|
9896
|
+
const x = r.r8();
|
|
9897
|
+
const xDot = r.r8();
|
|
9898
|
+
const xAcc = r.r8();
|
|
9899
|
+
const y = r.r8();
|
|
9900
|
+
const yDot = r.r8();
|
|
9901
|
+
const yAcc = r.r8();
|
|
9902
|
+
const z = r.r8();
|
|
9903
|
+
const zDot = r.r8();
|
|
9904
|
+
const zAcc = r.r8();
|
|
9905
|
+
const health = r.u1();
|
|
9906
|
+
if (prn < 120 || prn > 158) return null;
|
|
9907
|
+
return {
|
|
9908
|
+
system: "S",
|
|
9909
|
+
prn: `S${two5(prn - 100)}`,
|
|
9910
|
+
tocDate: new Date(gpsMs4(week, toe)),
|
|
9911
|
+
tauN: af0,
|
|
9912
|
+
gammaN: af1,
|
|
9913
|
+
messageFrameTime: tow,
|
|
9914
|
+
x,
|
|
9915
|
+
y,
|
|
9916
|
+
z,
|
|
9917
|
+
xDot,
|
|
9918
|
+
yDot,
|
|
9919
|
+
zDot,
|
|
9920
|
+
xAcc,
|
|
9921
|
+
yAcc,
|
|
9922
|
+
zAcc,
|
|
9923
|
+
health,
|
|
9924
|
+
freqNum: 0
|
|
9925
|
+
};
|
|
9926
|
+
}
|
|
9927
|
+
function decodeBinexEph(view, body, len, le) {
|
|
9928
|
+
const sub = view.getUint8(body);
|
|
9929
|
+
const p = body + 1;
|
|
9930
|
+
const n = len - 1;
|
|
9931
|
+
switch (sub) {
|
|
9932
|
+
case 1:
|
|
9933
|
+
return n >= 127 ? decodeGpsQzss(view, p, le, "G") : null;
|
|
9934
|
+
case 2:
|
|
9935
|
+
return n >= 119 ? decodeGlonass(view, p, le) : null;
|
|
9936
|
+
case 3:
|
|
9937
|
+
return n >= 98 ? decodeSbas(view, p, le) : null;
|
|
9938
|
+
case 4:
|
|
9939
|
+
return n >= 127 ? decodeGalileo(view, p, le) : null;
|
|
9940
|
+
case 5:
|
|
9941
|
+
return n >= 117 ? decodeBeidou(view, p, le) : null;
|
|
9942
|
+
case 6:
|
|
9943
|
+
return n >= 127 ? decodeGpsQzss(view, p, le, "J") : null;
|
|
9944
|
+
default:
|
|
9945
|
+
return null;
|
|
9946
|
+
}
|
|
9947
|
+
}
|
|
9948
|
+
|
|
9949
|
+
// src/binex/index.ts
|
|
9950
|
+
var GPS_EPOCH_MS16 = Date.UTC(1980, 0, 6);
|
|
9951
|
+
var CLIGHT2 = 299792458;
|
|
9952
|
+
var OBS_CODES = {
|
|
9953
|
+
0: [
|
|
9954
|
+
"1C",
|
|
9955
|
+
"1C",
|
|
9956
|
+
"1P",
|
|
9957
|
+
"1W",
|
|
9958
|
+
"1Y",
|
|
9959
|
+
"1M",
|
|
9960
|
+
"1X",
|
|
9961
|
+
"1N",
|
|
9962
|
+
"",
|
|
9963
|
+
"",
|
|
9964
|
+
"2W",
|
|
9965
|
+
"2C",
|
|
9966
|
+
"2D",
|
|
9967
|
+
"2S",
|
|
9968
|
+
"2L",
|
|
9969
|
+
"2X",
|
|
9970
|
+
"2P",
|
|
9971
|
+
"2W",
|
|
9972
|
+
"2Y",
|
|
9973
|
+
"2M",
|
|
9974
|
+
"2N",
|
|
9975
|
+
"",
|
|
9976
|
+
"",
|
|
9977
|
+
"5X",
|
|
9978
|
+
"5I",
|
|
9979
|
+
"5Q",
|
|
9980
|
+
"5X"
|
|
9981
|
+
],
|
|
9982
|
+
// GPS
|
|
9983
|
+
1: [
|
|
9984
|
+
"1C",
|
|
9985
|
+
"1C",
|
|
9986
|
+
"1P",
|
|
9987
|
+
"",
|
|
9988
|
+
"",
|
|
9989
|
+
"",
|
|
9990
|
+
"",
|
|
9991
|
+
"",
|
|
9992
|
+
"",
|
|
9993
|
+
"",
|
|
9994
|
+
"2C",
|
|
9995
|
+
"2C",
|
|
9996
|
+
"2P",
|
|
9997
|
+
"3X",
|
|
9998
|
+
"3I",
|
|
9999
|
+
"3Q",
|
|
10000
|
+
"3X"
|
|
10001
|
+
],
|
|
10002
|
+
// GLONASS
|
|
10003
|
+
3: [
|
|
10004
|
+
"1C",
|
|
10005
|
+
"1A",
|
|
10006
|
+
"1B",
|
|
10007
|
+
"1C",
|
|
10008
|
+
"1X",
|
|
10009
|
+
"1Z",
|
|
10010
|
+
"5X",
|
|
10011
|
+
"5I",
|
|
10012
|
+
"5Q",
|
|
10013
|
+
"5X",
|
|
10014
|
+
"7X",
|
|
10015
|
+
"7I",
|
|
10016
|
+
"7Q",
|
|
10017
|
+
"7X",
|
|
10018
|
+
"8X",
|
|
10019
|
+
"8I",
|
|
10020
|
+
"8Q",
|
|
10021
|
+
"8X",
|
|
10022
|
+
"6X",
|
|
10023
|
+
"6A",
|
|
10024
|
+
"6B",
|
|
10025
|
+
"6C",
|
|
10026
|
+
"6X",
|
|
10027
|
+
"6Z"
|
|
10028
|
+
],
|
|
10029
|
+
// Galileo
|
|
10030
|
+
2: ["1C", "1C", "", "", "", "", "5X", "5I", "5Q", "5X"],
|
|
10031
|
+
// SBAS
|
|
10032
|
+
4: [
|
|
10033
|
+
"2X",
|
|
10034
|
+
"2I",
|
|
10035
|
+
"2Q",
|
|
10036
|
+
"2X",
|
|
10037
|
+
"7X",
|
|
10038
|
+
"7I",
|
|
10039
|
+
"7Q",
|
|
10040
|
+
"7X",
|
|
10041
|
+
"6X",
|
|
10042
|
+
"6I",
|
|
10043
|
+
"6Q",
|
|
10044
|
+
"6X",
|
|
10045
|
+
"1X",
|
|
10046
|
+
"1S",
|
|
10047
|
+
"1L",
|
|
10048
|
+
"1X"
|
|
10049
|
+
],
|
|
10050
|
+
// BeiDou
|
|
10051
|
+
5: [
|
|
10052
|
+
"1C",
|
|
10053
|
+
"1C",
|
|
10054
|
+
"1S",
|
|
10055
|
+
"1L",
|
|
10056
|
+
"1X",
|
|
10057
|
+
"",
|
|
10058
|
+
"",
|
|
10059
|
+
"2X",
|
|
10060
|
+
"2S",
|
|
10061
|
+
"2L",
|
|
10062
|
+
"2X",
|
|
10063
|
+
"",
|
|
10064
|
+
"",
|
|
10065
|
+
"5X",
|
|
10066
|
+
"5I",
|
|
10067
|
+
"5Q",
|
|
10068
|
+
"5X",
|
|
10069
|
+
"",
|
|
10070
|
+
"",
|
|
10071
|
+
"6X",
|
|
10072
|
+
"6S",
|
|
10073
|
+
"6L",
|
|
10074
|
+
"6X",
|
|
10075
|
+
"",
|
|
10076
|
+
"",
|
|
10077
|
+
"",
|
|
10078
|
+
"",
|
|
10079
|
+
"",
|
|
10080
|
+
"",
|
|
10081
|
+
"",
|
|
10082
|
+
"1Z"
|
|
10083
|
+
]
|
|
10084
|
+
// QZSS
|
|
10085
|
+
};
|
|
10086
|
+
var two6 = (n) => String(n).padStart(2, "0");
|
|
10087
|
+
function obsPrn(sys, prn) {
|
|
10088
|
+
switch (sys) {
|
|
10089
|
+
case 0:
|
|
10090
|
+
return prn >= 1 && prn <= 32 ? `G${two6(prn)}` : null;
|
|
10091
|
+
case 1:
|
|
10092
|
+
return prn >= 1 && prn <= 27 ? `R${two6(prn)}` : null;
|
|
10093
|
+
case 2:
|
|
10094
|
+
return prn >= 120 && prn <= 158 ? `S${two6(prn - 100)}` : null;
|
|
10095
|
+
case 3:
|
|
10096
|
+
return prn >= 1 && prn <= 36 ? `E${two6(prn)}` : null;
|
|
10097
|
+
case 4:
|
|
10098
|
+
return prn >= 1 && prn <= 63 ? `C${two6(prn)}` : null;
|
|
10099
|
+
case 5:
|
|
10100
|
+
if (prn >= 193 && prn <= 202) return `J${two6(prn - 192)}`;
|
|
10101
|
+
return prn >= 1 && prn <= 10 ? `J${two6(prn)}` : null;
|
|
10102
|
+
default:
|
|
10103
|
+
return null;
|
|
10104
|
+
}
|
|
10105
|
+
}
|
|
10106
|
+
function carrierFreq3(sys, code, fcn) {
|
|
10107
|
+
const band = code.charCodeAt(0) - 48;
|
|
10108
|
+
switch (sys) {
|
|
10109
|
+
case "G":
|
|
10110
|
+
case "J":
|
|
10111
|
+
if (band === 1) return 157542e4;
|
|
10112
|
+
if (band === 2) return 12276e5;
|
|
10113
|
+
if (band === 5) return 117645e4;
|
|
10114
|
+
if (band === 6) return 127875e4;
|
|
10115
|
+
return 0;
|
|
10116
|
+
case "R":
|
|
10117
|
+
if (band === 1) return fcn >= -7 ? 1602e6 + fcn * 562500 : 0;
|
|
10118
|
+
if (band === 2) return fcn >= -7 ? 1246e6 + fcn * 437500 : 0;
|
|
10119
|
+
if (band === 3) return 1202025e3;
|
|
10120
|
+
return 0;
|
|
10121
|
+
case "E":
|
|
10122
|
+
if (band === 1) return 157542e4;
|
|
10123
|
+
if (band === 5) return 117645e4;
|
|
10124
|
+
if (band === 6) return 127875e4;
|
|
10125
|
+
if (band === 7) return 120714e4;
|
|
10126
|
+
if (band === 8) return 1191795e3;
|
|
10127
|
+
return 0;
|
|
10128
|
+
case "C":
|
|
10129
|
+
if (band === 1) return 157542e4;
|
|
10130
|
+
if (band === 2) return 1561098e3;
|
|
10131
|
+
if (band === 5) return 117645e4;
|
|
10132
|
+
if (band === 6) return 126852e4;
|
|
10133
|
+
if (band === 7) return 120714e4;
|
|
10134
|
+
if (band === 8) return 1191795e3;
|
|
10135
|
+
return 0;
|
|
10136
|
+
case "S":
|
|
10137
|
+
if (band === 1) return 157542e4;
|
|
10138
|
+
if (band === 5) return 117645e4;
|
|
10139
|
+
return 0;
|
|
10140
|
+
default:
|
|
10141
|
+
return 0;
|
|
10142
|
+
}
|
|
10143
|
+
}
|
|
10144
|
+
var FCN_UNKNOWN = -100;
|
|
10145
|
+
function decodeObsSat(data, start, nobs, sys) {
|
|
10146
|
+
let p = start;
|
|
10147
|
+
let fcn = FCN_UNKNOWN;
|
|
10148
|
+
const obs = [];
|
|
10149
|
+
const block0Flags = [0, 0, 0, 0];
|
|
10150
|
+
let refRange = 0;
|
|
10151
|
+
for (let b = 0; b < nobs; b++) {
|
|
10152
|
+
const flags = b === 0 ? block0Flags : block0Flags.slice();
|
|
10153
|
+
const b0 = data[p++];
|
|
10154
|
+
const code = b0 & 31;
|
|
10155
|
+
const slip = (b0 >> 5 & 1) === 1;
|
|
10156
|
+
let more = b0 >> 7 & 1;
|
|
10157
|
+
while (more) {
|
|
10158
|
+
const fb = data[p++];
|
|
10159
|
+
flags[fb & 3] = fb & 127;
|
|
10160
|
+
more = fb & 128;
|
|
10161
|
+
}
|
|
10162
|
+
if (sys === 1 && flags[2] > 0 && (code === 1 || code === 2 || code === 11 || code === 12)) {
|
|
10163
|
+
fcn = getBitS(Uint8Array.of(flags[2]), 2, 4);
|
|
10164
|
+
}
|
|
10165
|
+
const acc = flags[0] & 32 ? 1e-4 : 2e-5;
|
|
10166
|
+
let cn0 = data[p++] * 0.4;
|
|
10167
|
+
let range;
|
|
10168
|
+
if (b === 0) {
|
|
10169
|
+
cn0 += getBitS(data, p * 8, 2) * 0.1;
|
|
10170
|
+
range = getBitU(data, p * 8 + 2, 38) * 1e-3;
|
|
10171
|
+
p += 5;
|
|
10172
|
+
refRange = range;
|
|
10173
|
+
} else if (flags[0] & 64) {
|
|
10174
|
+
cn0 += getBitS(data, p * 8, 2) * 0.1;
|
|
10175
|
+
range = refRange + getBitS(data, p * 8 + 4, 20) * 1e-3;
|
|
10176
|
+
p += 3;
|
|
10177
|
+
} else {
|
|
10178
|
+
range = refRange + getBitS(data, p * 8, 16) * 1e-3;
|
|
10179
|
+
p += 2;
|
|
10180
|
+
}
|
|
10181
|
+
let phase;
|
|
10182
|
+
if (flags[0] & 64) {
|
|
10183
|
+
phase = range + getBitS(data, p * 8, 24) * acc;
|
|
10184
|
+
p += 3;
|
|
10185
|
+
} else {
|
|
10186
|
+
cn0 += getBitS(data, p * 8, 2) * 0.1;
|
|
10187
|
+
phase = range + getBitS(data, p * 8 + 2, 22) * acc;
|
|
10188
|
+
p += 3;
|
|
10189
|
+
}
|
|
10190
|
+
let doppler = null;
|
|
10191
|
+
if (flags[0] & 4) {
|
|
10192
|
+
doppler = getBitS(data, p * 8, 24) / 256;
|
|
10193
|
+
p += 3;
|
|
10194
|
+
}
|
|
10195
|
+
if (flags[0] & 8) {
|
|
10196
|
+
p += flags[0] & 16 ? 2 : 1;
|
|
10197
|
+
}
|
|
10198
|
+
obs.push({ code, slip, pr: range, phase, cn0, doppler });
|
|
10199
|
+
}
|
|
10200
|
+
return { obs, fcn, next: p };
|
|
10201
|
+
}
|
|
10202
|
+
function decodeObsRecord(data, view, body, len, obsCodes) {
|
|
10203
|
+
let p = body + 1;
|
|
10204
|
+
const min = view.getUint32(p);
|
|
10205
|
+
p += 4;
|
|
10206
|
+
const msec = view.getUint16(p);
|
|
10207
|
+
p += 2;
|
|
10208
|
+
const timeMs = GPS_EPOCH_MS16 + min * 6e4 + msec;
|
|
10209
|
+
const flag = data[p++];
|
|
10210
|
+
const nsat = (flag & 63) + 1;
|
|
10211
|
+
if (flag & 128) p += 3;
|
|
10212
|
+
if (flag & 64) {
|
|
10213
|
+
const nsys = getBitU(data, p * 8, 4);
|
|
10214
|
+
p += 1;
|
|
10215
|
+
p += nsys * 4;
|
|
10216
|
+
}
|
|
10217
|
+
const end = body + len;
|
|
10218
|
+
const meas = [];
|
|
10219
|
+
for (let i = 0; i < nsat && p < end; i++) {
|
|
10220
|
+
const prn = data[p++];
|
|
10221
|
+
const b = data[p++];
|
|
10222
|
+
const nobs = b >> 4 & 7;
|
|
10223
|
+
const sys = b & 15;
|
|
10224
|
+
const sat = obsPrn(sys, prn);
|
|
10225
|
+
const { obs, fcn, next } = decodeObsSat(data, p, nobs, sys);
|
|
10226
|
+
p = next;
|
|
10227
|
+
if (p > end) return null;
|
|
10228
|
+
if (!sat) continue;
|
|
10229
|
+
const table = OBS_CODES[sys];
|
|
10230
|
+
const sysL = sat[0];
|
|
10231
|
+
for (const o of obs) {
|
|
10232
|
+
const code = table?.[o.code & 63] ?? "";
|
|
10233
|
+
if (!code) continue;
|
|
10234
|
+
const freq = carrierFreq3(sysL, code, fcn);
|
|
10235
|
+
meas.push({
|
|
10236
|
+
prn: sat,
|
|
10237
|
+
code,
|
|
10238
|
+
pr: o.pr,
|
|
10239
|
+
cp: freq > 0 ? o.phase * freq / CLIGHT2 : null,
|
|
10240
|
+
doppler: o.doppler,
|
|
10241
|
+
cn0: o.cn0,
|
|
10242
|
+
slip: o.slip
|
|
10243
|
+
});
|
|
10244
|
+
const codes = obsCodes[sysL] ??= [];
|
|
10245
|
+
if (!codes.includes(code)) codes.push(code);
|
|
10246
|
+
}
|
|
10247
|
+
}
|
|
10248
|
+
return { timeMs, meas };
|
|
10249
|
+
}
|
|
10250
|
+
function parseBinex(data) {
|
|
10251
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
10252
|
+
const epochs = [];
|
|
10253
|
+
const ephemerides = [];
|
|
10254
|
+
const messageCounts = {};
|
|
10255
|
+
const obsCodes = {};
|
|
10256
|
+
const stats = { badCrc: 0 };
|
|
10257
|
+
const lastKep = /* @__PURE__ */ new Map();
|
|
10258
|
+
const lastState = /* @__PURE__ */ new Map();
|
|
10259
|
+
const hex = (n) => `0x${n.toString(16).padStart(2, "0")}`;
|
|
10260
|
+
for (const rec of binexRecords(data, view, stats)) {
|
|
10261
|
+
const sub = rec.len > 0 ? data[rec.body] : 0;
|
|
10262
|
+
const key = rec.id === 1 || rec.id === 127 ? `${hex(rec.id)}-${sub.toString(16).padStart(2, "0")}` : hex(rec.id);
|
|
10263
|
+
messageCounts[key] = (messageCounts[key] ?? 0) + 1;
|
|
10264
|
+
if (rec.id === 127 && sub === 5 && rec.len >= 8 && !rec.littleEndian) {
|
|
10265
|
+
const epoch = decodeObsRecord(data, view, rec.body, rec.len, obsCodes);
|
|
10266
|
+
if (epoch) epochs.push(epoch);
|
|
10267
|
+
} else if (rec.id === 1 && rec.len >= 2) {
|
|
10268
|
+
const eph = decodeBinexEph(view, rec.body, rec.len, rec.littleEndian);
|
|
10269
|
+
if (!eph) continue;
|
|
10270
|
+
if ("iode" in eph) {
|
|
10271
|
+
const prev = lastKep.get(eph.prn);
|
|
10272
|
+
if (prev && prev.iode === eph.iode && prev.toe === eph.toe && prev.tocDate.getTime() === eph.tocDate.getTime()) {
|
|
10273
|
+
continue;
|
|
10274
|
+
}
|
|
10275
|
+
lastKep.set(eph.prn, eph);
|
|
10276
|
+
ephemerides.push(eph);
|
|
10277
|
+
} else {
|
|
10278
|
+
const prev = lastState.get(eph.prn);
|
|
10279
|
+
if (prev && Math.abs(prev.tocDate.getTime() - eph.tocDate.getTime()) < 1e3 && prev.health === eph.health) {
|
|
10280
|
+
continue;
|
|
10281
|
+
}
|
|
10282
|
+
lastState.set(eph.prn, eph);
|
|
10283
|
+
ephemerides.push(eph);
|
|
10284
|
+
}
|
|
10285
|
+
}
|
|
10286
|
+
}
|
|
10287
|
+
return { epochs, ephemerides, messageCounts, obsCodes, badCrc: stats.badCrc };
|
|
10288
|
+
}
|
|
10289
|
+
|
|
8683
10290
|
// src/orbit/almanac.ts
|
|
8684
10291
|
var GM_GPS = 3986005e8;
|
|
8685
10292
|
var GM_GAL = 3986004418e5;
|
|
8686
10293
|
var GM_BDS = 3986004418e5;
|
|
8687
|
-
var
|
|
8688
|
-
var
|
|
10294
|
+
var GPS_EPOCH_MS17 = Date.UTC(1980, 0, 6);
|
|
10295
|
+
var BDT_EPOCH_MS5 = Date.UTC(2006, 0, 1);
|
|
8689
10296
|
var WEEK_MS = 6048e5;
|
|
8690
10297
|
var BDT_MINUS_GPST_MS = 14e3;
|
|
8691
10298
|
var BDS_GEO_PRNS = /* @__PURE__ */ new Set([1, 2, 3, 4, 5, 59, 60, 61, 62, 63]);
|
|
8692
10299
|
function almanacEpochMs(alm) {
|
|
8693
10300
|
if (alm.system === "C") {
|
|
8694
|
-
return
|
|
10301
|
+
return BDT_EPOCH_MS5 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3 + BDT_MINUS_GPST_MS;
|
|
8695
10302
|
}
|
|
8696
|
-
return
|
|
10303
|
+
return GPS_EPOCH_MS17 + alm.weekAlm * WEEK_MS + alm.toaSec * 1e3;
|
|
8697
10304
|
}
|
|
8698
10305
|
function almanacSatPosition(alm, timeMs) {
|
|
8699
10306
|
const GM = alm.system === "E" ? GM_GAL : alm.system === "C" ? GM_BDS : GM_GPS;
|
|
@@ -9202,10 +10809,10 @@ function selectBest(ephs, timeMs) {
|
|
|
9202
10809
|
}
|
|
9203
10810
|
return best;
|
|
9204
10811
|
}
|
|
9205
|
-
var
|
|
9206
|
-
var
|
|
10812
|
+
var GPS_EPOCH_MS18 = START_GPS_TIME.getTime();
|
|
10813
|
+
var MS_PER_WEEK12 = 7 * 864e5;
|
|
9207
10814
|
var BDS_EPOCH_MS = START_BDS_TIME.getTime();
|
|
9208
|
-
var GAL_EPOCH_MS =
|
|
10815
|
+
var GAL_EPOCH_MS = GPS_EPOCH_MS18 + 1024 * MS_PER_WEEK12;
|
|
9209
10816
|
function ephInfoToEphemeris(info) {
|
|
9210
10817
|
const sys = info.prn.charAt(0);
|
|
9211
10818
|
if (sys === "R") {
|
|
@@ -9256,11 +10863,11 @@ function ephInfoToEphemeris(info) {
|
|
|
9256
10863
|
} else if (sys === "E") {
|
|
9257
10864
|
epochMs = GAL_EPOCH_MS;
|
|
9258
10865
|
} else {
|
|
9259
|
-
epochMs =
|
|
9260
|
-
const weeksNow = (info.lastReceived -
|
|
10866
|
+
epochMs = GPS_EPOCH_MS18;
|
|
10867
|
+
const weeksNow = (info.lastReceived - GPS_EPOCH_MS18) / MS_PER_WEEK12;
|
|
9261
10868
|
week += 1024 * Math.round((weeksNow - week) / 1024);
|
|
9262
10869
|
}
|
|
9263
|
-
const tocDate = new Date(epochMs + week *
|
|
10870
|
+
const tocDate = new Date(epochMs + week * MS_PER_WEEK12 + tocSec * 1e3);
|
|
9264
10871
|
return {
|
|
9265
10872
|
system: sys,
|
|
9266
10873
|
prn: info.prn,
|
|
@@ -13314,6 +14921,10 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
13314
14921
|
analyzeQuality,
|
|
13315
14922
|
applyHelmert,
|
|
13316
14923
|
applyIonoDcb,
|
|
14924
|
+
binexCrc16,
|
|
14925
|
+
binexCrc32,
|
|
14926
|
+
binexCsum8,
|
|
14927
|
+
binexRecords,
|
|
13317
14928
|
buildGloChannelMap,
|
|
13318
14929
|
buildObsIndices,
|
|
13319
14930
|
clampUnit,
|
|
@@ -13334,6 +14945,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
13334
14945
|
crxDecompress,
|
|
13335
14946
|
crxRepair,
|
|
13336
14947
|
dateToEpoch,
|
|
14948
|
+
decodeBinexEph,
|
|
13337
14949
|
decodeEphemeris,
|
|
13338
14950
|
decodeMsmFull,
|
|
13339
14951
|
deg2dms,
|
|
@@ -13355,6 +14967,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
13355
14967
|
geodeticToUtm,
|
|
13356
14968
|
getAer,
|
|
13357
14969
|
getBdsTime,
|
|
14970
|
+
getBnxi,
|
|
13358
14971
|
getDateFromBdsTime,
|
|
13359
14972
|
getDateFromDayOfWeek,
|
|
13360
14973
|
getDateFromDayOfYear,
|
|
@@ -13428,6 +15041,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
13428
15041
|
padL,
|
|
13429
15042
|
padR,
|
|
13430
15043
|
parseAntex,
|
|
15044
|
+
parseBinex,
|
|
13431
15045
|
parseCrxDataLine,
|
|
13432
15046
|
parseIonex,
|
|
13433
15047
|
parseNavFile,
|
|
@@ -13447,6 +15061,8 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
13447
15061
|
parseSinexBiasDcb,
|
|
13448
15062
|
parseSourcetable,
|
|
13449
15063
|
parseSp3,
|
|
15064
|
+
parseTrimble,
|
|
15065
|
+
parseTrimbleNav,
|
|
13450
15066
|
parseUbxCnav,
|
|
13451
15067
|
parseUbxIonoUtc,
|
|
13452
15068
|
parseUbxNav,
|
|
@@ -13477,11 +15093,13 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
13477
15093
|
systemName,
|
|
13478
15094
|
toRtkEpoch,
|
|
13479
15095
|
transformFrame,
|
|
15096
|
+
trimbleFrames,
|
|
13480
15097
|
ubxFrames,
|
|
13481
15098
|
updateStationMeta,
|
|
13482
15099
|
updateStreamStats,
|
|
13483
15100
|
verifyChecksum,
|
|
13484
15101
|
vincenty,
|
|
15102
|
+
writeCrx,
|
|
13485
15103
|
writeModernObsBlob,
|
|
13486
15104
|
writeRinex2ObsBlob,
|
|
13487
15105
|
writeRinex4ObsBlob,
|