gnss-js 1.0.0 → 1.0.1
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/analysis.cjs +140 -33
- package/dist/analysis.js +3 -3
- package/dist/{chunk-SDRRAJT5.js → chunk-4YN353Q7.js} +16 -9
- package/dist/{chunk-WR7LCB52.js → chunk-BJHTBYNG.js} +15 -4
- package/dist/{chunk-CB6EOOLA.js → chunk-HBLU2EJ4.js} +70 -21
- package/dist/{chunk-354IRDOG.js → chunk-LWNTWBHB.js} +36 -7
- package/dist/{chunk-K7WZQFBV.js → chunk-MIIM4LDY.js} +4 -1
- package/dist/{chunk-Y3R57B5P.js → chunk-SO3POWWR.js} +37 -8
- package/dist/{chunk-IS4UUDBV.js → chunk-W4YMQKWH.js} +54 -9
- package/dist/{chunk-PRSZIWKM.js → chunk-WP2JFDLA.js} +21 -28
- package/dist/constants.cjs +36 -7
- package/dist/constants.js +1 -1
- package/dist/coordinates.cjs +4 -1
- package/dist/coordinates.js +1 -1
- package/dist/{ephemeris-BUWzfmBy.d.cts → ephemeris-C10stHhM.d.cts} +1 -1
- package/dist/{ephemeris-BUWzfmBy.d.ts → ephemeris-C10stHhM.d.ts} +1 -1
- package/dist/index.cjs +249 -83
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +8 -8
- package/dist/ntrip.cjs +15 -4
- package/dist/ntrip.js +1 -1
- package/dist/orbit.cjs +16 -9
- package/dist/orbit.d.cts +1 -1
- package/dist/orbit.d.ts +1 -1
- package/dist/orbit.js +1 -1
- package/dist/rinex.cjs +123 -29
- package/dist/rinex.js +3 -3
- package/dist/rtcm3.cjs +20 -27
- package/dist/rtcm3.d.cts +2 -2
- package/dist/rtcm3.d.ts +2 -2
- package/dist/rtcm3.js +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -299,8 +299,20 @@ var C_LIGHT = 299792458;
|
|
|
299
299
|
var FREQ = {
|
|
300
300
|
G: { "1": 157542e4, "2": 12276e5, "5": 117645e4 },
|
|
301
301
|
R: { "3": 1202025e3 },
|
|
302
|
-
E: {
|
|
303
|
-
|
|
302
|
+
E: {
|
|
303
|
+
"1": 157542e4,
|
|
304
|
+
"5": 117645e4,
|
|
305
|
+
"6": 127875e4,
|
|
306
|
+
"7": 120714e4,
|
|
307
|
+
"8": 1191795e3
|
|
308
|
+
},
|
|
309
|
+
C: {
|
|
310
|
+
"1": 157542e4,
|
|
311
|
+
"2": 1561098e3,
|
|
312
|
+
"5": 117645e4,
|
|
313
|
+
"6": 126852e4,
|
|
314
|
+
"7": 120714e4
|
|
315
|
+
},
|
|
304
316
|
J: { "1": 157542e4, "2": 12276e5, "5": 117645e4, "6": 127875e4 },
|
|
305
317
|
I: { "5": 117645e4, "9": 2492028e3 },
|
|
306
318
|
S: { "1": 157542e4, "5": 117645e4 }
|
|
@@ -315,11 +327,28 @@ var BAND_LABELS = {
|
|
|
315
327
|
S: { "1": "L1", "5": "L5" }
|
|
316
328
|
};
|
|
317
329
|
var DUAL_FREQ_PAIRS = {
|
|
318
|
-
G: [
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
330
|
+
G: [
|
|
331
|
+
["1", "2"],
|
|
332
|
+
["1", "5"]
|
|
333
|
+
],
|
|
334
|
+
R: [
|
|
335
|
+
["1", "2"],
|
|
336
|
+
["1", "3"]
|
|
337
|
+
],
|
|
338
|
+
E: [
|
|
339
|
+
["1", "5"],
|
|
340
|
+
["1", "7"],
|
|
341
|
+
["1", "6"]
|
|
342
|
+
],
|
|
343
|
+
C: [
|
|
344
|
+
["2", "7"],
|
|
345
|
+
["2", "6"],
|
|
346
|
+
["1", "5"]
|
|
347
|
+
],
|
|
348
|
+
J: [
|
|
349
|
+
["1", "2"],
|
|
350
|
+
["1", "5"]
|
|
351
|
+
],
|
|
323
352
|
I: [["5", "9"]],
|
|
324
353
|
S: [["1", "5"]]
|
|
325
354
|
};
|
|
@@ -964,7 +993,10 @@ function vincenty(lat1, lon1, lat2, lon2) {
|
|
|
964
993
|
const cosLat2 = Math.cos(lat2), sinLat2 = Math.sin(lat2);
|
|
965
994
|
const dLon = lon2 - lon1;
|
|
966
995
|
sigma = Math.acos(
|
|
967
|
-
Math.min(
|
|
996
|
+
Math.min(
|
|
997
|
+
1,
|
|
998
|
+
Math.max(-1, sinLat1 * sinLat2 + cosLat1 * cosLat2 * Math.cos(dLon))
|
|
999
|
+
)
|
|
968
1000
|
);
|
|
969
1001
|
const distance2 = WGS84_SEMI_MAJOR_AXIS * sigma;
|
|
970
1002
|
const ib = Math.atan2(
|
|
@@ -1162,10 +1194,20 @@ function parseCrxDataLine(line, ntype) {
|
|
|
1162
1194
|
if (token.length >= 3 && token[1] === "&") {
|
|
1163
1195
|
const arcOrder = parseInt(token[0]);
|
|
1164
1196
|
const value = parseInt(token.substring(2));
|
|
1165
|
-
fields.push({
|
|
1197
|
+
fields.push({
|
|
1198
|
+
empty: false,
|
|
1199
|
+
init: true,
|
|
1200
|
+
arcOrder,
|
|
1201
|
+
value: isNaN(value) ? 0 : value
|
|
1202
|
+
});
|
|
1166
1203
|
} else {
|
|
1167
1204
|
const value = parseInt(token);
|
|
1168
|
-
fields.push({
|
|
1205
|
+
fields.push({
|
|
1206
|
+
empty: false,
|
|
1207
|
+
init: false,
|
|
1208
|
+
arcOrder: -1,
|
|
1209
|
+
value: isNaN(value) ? 0 : value
|
|
1210
|
+
});
|
|
1169
1211
|
}
|
|
1170
1212
|
}
|
|
1171
1213
|
const flagStr = pos < line.length ? line.substring(pos) : "";
|
|
@@ -1175,7 +1217,10 @@ function crxDecompress(prev, field) {
|
|
|
1175
1217
|
if (field.init) {
|
|
1176
1218
|
const a = new Array(Math.max(field.arcOrder + 1, 1)).fill(0);
|
|
1177
1219
|
a[0] = field.value;
|
|
1178
|
-
return {
|
|
1220
|
+
return {
|
|
1221
|
+
state: { accum: a, order: 0, arcOrder: field.arcOrder },
|
|
1222
|
+
result: field.value
|
|
1223
|
+
};
|
|
1179
1224
|
}
|
|
1180
1225
|
if (!prev) {
|
|
1181
1226
|
return { state: { accum: [0], order: 0, arcOrder: 0 }, result: 0 };
|
|
@@ -1188,7 +1233,10 @@ function crxDecompress(prev, field) {
|
|
|
1188
1233
|
for (let k = order; k >= 1; k--) {
|
|
1189
1234
|
accum[k - 1] += accum[k];
|
|
1190
1235
|
}
|
|
1191
|
-
return {
|
|
1236
|
+
return {
|
|
1237
|
+
state: { accum, order, arcOrder: prev.arcOrder },
|
|
1238
|
+
result: accum[0]
|
|
1239
|
+
};
|
|
1192
1240
|
}
|
|
1193
1241
|
|
|
1194
1242
|
// src/rinex/format.ts
|
|
@@ -1210,7 +1258,9 @@ var CHUNK_SIZE = 2 * 1024 * 1024;
|
|
|
1210
1258
|
var yieldToMain = () => new Promise((r) => setTimeout(r, 0));
|
|
1211
1259
|
var noYield = () => Promise.resolve();
|
|
1212
1260
|
var SYSTEM_ORDER = ["G", "R", "E", "C", "J", "I", "S"];
|
|
1213
|
-
var SYSTEM_RANK = Object.fromEntries(
|
|
1261
|
+
var SYSTEM_RANK = Object.fromEntries(
|
|
1262
|
+
SYSTEM_ORDER.map((s, i) => [s, i])
|
|
1263
|
+
);
|
|
1214
1264
|
function systemCmp(a, b) {
|
|
1215
1265
|
const ra = SYSTEM_RANK[a.charAt(0)] ?? 99;
|
|
1216
1266
|
const rb = SYSTEM_RANK[b.charAt(0)] ?? 99;
|
|
@@ -1396,7 +1446,11 @@ function parseEpochLine3(line) {
|
|
|
1396
1446
|
const wholeSec = Math.floor(sc);
|
|
1397
1447
|
const ms = Math.round((sc - wholeSec) * 1e3);
|
|
1398
1448
|
const time = Date.UTC(yr, mo - 1, dy, hr, mn, wholeSec, ms);
|
|
1399
|
-
return {
|
|
1449
|
+
return {
|
|
1450
|
+
time,
|
|
1451
|
+
flag: isNaN(flag) ? 0 : flag,
|
|
1452
|
+
numSats: isNaN(numSats) ? 0 : numSats
|
|
1453
|
+
};
|
|
1400
1454
|
}
|
|
1401
1455
|
function parseEpochLine2(line) {
|
|
1402
1456
|
const yr2 = parseInt(line.substring(1, 3));
|
|
@@ -1418,7 +1472,12 @@ function parseEpochLine2(line) {
|
|
|
1418
1472
|
const id = satPart.substring(i, i + 3).trim();
|
|
1419
1473
|
if (id) satIds.push(id);
|
|
1420
1474
|
}
|
|
1421
|
-
return {
|
|
1475
|
+
return {
|
|
1476
|
+
time,
|
|
1477
|
+
flag: isNaN(flag) ? 0 : flag,
|
|
1478
|
+
numSats: isNaN(numSats) ? 0 : numSats,
|
|
1479
|
+
satIds
|
|
1480
|
+
};
|
|
1422
1481
|
}
|
|
1423
1482
|
async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode) {
|
|
1424
1483
|
const skipEpochs = !!workerMode;
|
|
@@ -1471,16 +1530,19 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
|
|
|
1471
1530
|
if (!skipEpochs) {
|
|
1472
1531
|
const snrBySys = {};
|
|
1473
1532
|
for (const [sys, vals] of Object.entries(snrPerSystemAccum)) {
|
|
1474
|
-
if (vals.length > 0)
|
|
1533
|
+
if (vals.length > 0)
|
|
1534
|
+
snrBySys[sys] = vals.reduce((a, b) => a + b, 0) / vals.length;
|
|
1475
1535
|
}
|
|
1476
1536
|
const meanSnr = snrValues.length > 0 ? snrValues.reduce((a, b) => a + b, 0) / snrValues.length : null;
|
|
1477
1537
|
const snrPerSat = {};
|
|
1478
1538
|
for (const [prn, vals] of Object.entries(snrPerSatAccum)) {
|
|
1479
|
-
if (vals.length > 0)
|
|
1539
|
+
if (vals.length > 0)
|
|
1540
|
+
snrPerSat[prn] = vals.reduce((a, b) => a + b, 0) / vals.length;
|
|
1480
1541
|
}
|
|
1481
1542
|
const snrPerSatBand = {};
|
|
1482
1543
|
for (const [key, vals] of Object.entries(snrPerSatBandAccum)) {
|
|
1483
|
-
if (vals.length > 0)
|
|
1544
|
+
if (vals.length > 0)
|
|
1545
|
+
snrPerSatBand[key] = vals.reduce((a, b) => a + b, 0) / vals.length;
|
|
1484
1546
|
}
|
|
1485
1547
|
epochs.push({
|
|
1486
1548
|
time: epochInfo.time,
|
|
@@ -1525,7 +1587,8 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
|
|
|
1525
1587
|
const codes = header.obsTypes[sys] ?? [];
|
|
1526
1588
|
if (onSatObs && epochInfo) {
|
|
1527
1589
|
const values = new Array(codes.length);
|
|
1528
|
-
for (let i = 0; i < codes.length; i++)
|
|
1590
|
+
for (let i = 0; i < codes.length; i++)
|
|
1591
|
+
values[i] = readObsValue(obsLine, i);
|
|
1529
1592
|
if (!skipEpochs) {
|
|
1530
1593
|
for (const { idx, band } of getSnrIndices(sys)) {
|
|
1531
1594
|
const val = values[idx] ?? null;
|
|
@@ -1762,7 +1825,10 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
|
|
|
1762
1825
|
v2SnrBandInfo = snrIndicesWithBandV2(header.obsTypes);
|
|
1763
1826
|
v2SatIndex = 0;
|
|
1764
1827
|
v2CurrentSatLine = 0;
|
|
1765
|
-
const continuationLines = Math.max(
|
|
1828
|
+
const continuationLines = Math.max(
|
|
1829
|
+
0,
|
|
1830
|
+
Math.ceil((info.numSats - 12) / 12)
|
|
1831
|
+
);
|
|
1766
1832
|
if (continuationLines > 0) {
|
|
1767
1833
|
v2ContinuationSatsRemaining = continuationLines;
|
|
1768
1834
|
} else {
|
|
@@ -1802,7 +1868,9 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
|
|
|
1802
1868
|
const magic = new Uint8Array(await file.slice(0, 2).arrayBuffer());
|
|
1803
1869
|
const isGz = magic[0] === 31 && magic[1] === 139;
|
|
1804
1870
|
if (magic[0] === 31 && magic[1] === 157) {
|
|
1805
|
-
throw new Error(
|
|
1871
|
+
throw new Error(
|
|
1872
|
+
"Unix compress (.Z) files are not supported. Please decompress first (e.g. uncompress or gzip -d)."
|
|
1873
|
+
);
|
|
1806
1874
|
}
|
|
1807
1875
|
if (isGz) {
|
|
1808
1876
|
let bytesRead = 0;
|
|
@@ -1818,7 +1886,9 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
|
|
|
1818
1886
|
if (done) break;
|
|
1819
1887
|
bytesRead += value.byteLength;
|
|
1820
1888
|
processChunkText(decoder.decode(value, { stream: true }), false);
|
|
1821
|
-
onProgress?.(
|
|
1889
|
+
onProgress?.(
|
|
1890
|
+
Math.min(99, Math.round(bytesRead / (file.size * 4) * 100))
|
|
1891
|
+
);
|
|
1822
1892
|
await yield_();
|
|
1823
1893
|
}
|
|
1824
1894
|
processChunkText(decoder.decode(), true);
|
|
@@ -1828,7 +1898,10 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
|
|
|
1828
1898
|
const end = Math.min(offset + CHUNK_SIZE, file.size);
|
|
1829
1899
|
const slice = file.slice(offset, end);
|
|
1830
1900
|
const arrayBuf = await slice.arrayBuffer();
|
|
1831
|
-
processChunkText(
|
|
1901
|
+
processChunkText(
|
|
1902
|
+
decoder.decode(arrayBuf, { stream: end < file.size }),
|
|
1903
|
+
false
|
|
1904
|
+
);
|
|
1832
1905
|
onProgress?.(Math.min(99, Math.round(end / file.size * 100)));
|
|
1833
1906
|
await yield_();
|
|
1834
1907
|
}
|
|
@@ -1836,19 +1909,27 @@ async function parseRinexStream(file, onProgress, signal, onSatObs, workerMode)
|
|
|
1836
1909
|
processChunkText("", true);
|
|
1837
1910
|
}
|
|
1838
1911
|
}
|
|
1839
|
-
if (epochInfo && satLinesRemaining === 0 && crxPhase === "epoch")
|
|
1840
|
-
|
|
1912
|
+
if (epochInfo && satLinesRemaining === 0 && crxPhase === "epoch")
|
|
1913
|
+
finishEpoch();
|
|
1914
|
+
if (!header)
|
|
1915
|
+
throw new Error("No valid RINEX header found (missing END OF HEADER).");
|
|
1841
1916
|
onProgress?.(100);
|
|
1842
|
-
return {
|
|
1917
|
+
return {
|
|
1918
|
+
header,
|
|
1919
|
+
epochs,
|
|
1920
|
+
stats: computeStats(header, epochs, satellitesSeen)
|
|
1921
|
+
};
|
|
1843
1922
|
}
|
|
1844
1923
|
function computeStats(header, epochs, satellitesSeen) {
|
|
1845
1924
|
const n = epochs.length;
|
|
1846
1925
|
const startTime = n > 0 ? new Date(epochs[0].time) : header.timeOfFirstObs;
|
|
1847
1926
|
const endTime = n > 0 ? new Date(epochs[n - 1].time) : header.timeOfLastObs;
|
|
1848
1927
|
let duration = null;
|
|
1849
|
-
if (startTime && endTime)
|
|
1928
|
+
if (startTime && endTime)
|
|
1929
|
+
duration = (endTime.getTime() - startTime.getTime()) / 1e3;
|
|
1850
1930
|
let interval = header.interval;
|
|
1851
|
-
if (interval === null && n >= 2)
|
|
1931
|
+
if (interval === null && n >= 2)
|
|
1932
|
+
interval = (epochs[1].time - epochs[0].time) / 1e3;
|
|
1852
1933
|
const uniqueSatsPerSystem = {};
|
|
1853
1934
|
let totalUnique = 0;
|
|
1854
1935
|
const systems = [];
|
|
@@ -1903,10 +1984,18 @@ var WarningAccumulator = class {
|
|
|
1903
1984
|
);
|
|
1904
1985
|
}
|
|
1905
1986
|
if (!header.antType) {
|
|
1906
|
-
this.add(
|
|
1987
|
+
this.add(
|
|
1988
|
+
"MISSING_ANT_TYPE",
|
|
1989
|
+
"info",
|
|
1990
|
+
"Missing antenna type (ANT # / TYPE)"
|
|
1991
|
+
);
|
|
1907
1992
|
}
|
|
1908
1993
|
if (!header.receiverType) {
|
|
1909
|
-
this.add(
|
|
1994
|
+
this.add(
|
|
1995
|
+
"MISSING_REC_TYPE",
|
|
1996
|
+
"info",
|
|
1997
|
+
"Missing receiver type (REC # / TYPE / VERS)"
|
|
1998
|
+
);
|
|
1910
1999
|
}
|
|
1911
2000
|
if (!header.markerName) {
|
|
1912
2001
|
this.add("MISSING_MARKER", "info", "Missing marker name (MARKER NAME)");
|
|
@@ -1915,7 +2004,11 @@ var WarningAccumulator = class {
|
|
|
1915
2004
|
this.add("MISSING_INTERVAL", "info", "No observation interval in header");
|
|
1916
2005
|
}
|
|
1917
2006
|
if (Object.keys(header.obsTypes).length === 0) {
|
|
1918
|
-
this.add(
|
|
2007
|
+
this.add(
|
|
2008
|
+
"NO_OBS_TYPES",
|
|
2009
|
+
"error",
|
|
2010
|
+
"No observation types defined in header"
|
|
2011
|
+
);
|
|
1919
2012
|
}
|
|
1920
2013
|
}
|
|
1921
2014
|
setInterval(intervalMs) {
|
|
@@ -1982,7 +2075,12 @@ var WarningAccumulator = class {
|
|
|
1982
2075
|
};
|
|
1983
2076
|
const range = ranges[sys];
|
|
1984
2077
|
if (!range) {
|
|
1985
|
-
this.add(
|
|
2078
|
+
this.add(
|
|
2079
|
+
"UNKNOWN_SYSTEM",
|
|
2080
|
+
"info",
|
|
2081
|
+
"Unknown satellite system letter",
|
|
2082
|
+
prn
|
|
2083
|
+
);
|
|
1986
2084
|
} else if (num < range[0] || num > range[1]) {
|
|
1987
2085
|
this.add(
|
|
1988
2086
|
"PRN_OUT_OF_RANGE",
|
|
@@ -2072,7 +2170,15 @@ var R4_MSG_LINES = {
|
|
|
2072
2170
|
EOP: 3,
|
|
2073
2171
|
ION: 3
|
|
2074
2172
|
};
|
|
2075
|
-
var SUPPORTED_EPH_MSGS = /* @__PURE__ */ new Set([
|
|
2173
|
+
var SUPPORTED_EPH_MSGS = /* @__PURE__ */ new Set([
|
|
2174
|
+
"LNAV",
|
|
2175
|
+
"INAV",
|
|
2176
|
+
"FNAV",
|
|
2177
|
+
"D1",
|
|
2178
|
+
"D2",
|
|
2179
|
+
"SBAS",
|
|
2180
|
+
"FDMA"
|
|
2181
|
+
]);
|
|
2076
2182
|
function parseFloat19(s) {
|
|
2077
2183
|
return parseFloat(s.trim().replace(/[dD]/g, "E"));
|
|
2078
2184
|
}
|
|
@@ -2279,9 +2385,25 @@ function parseNavFile(text) {
|
|
|
2279
2385
|
}
|
|
2280
2386
|
if (dataLines2.length === numDataLines2) {
|
|
2281
2387
|
if (sys2 === "R" || sys2 === "S") {
|
|
2282
|
-
ephemerides.push(
|
|
2388
|
+
ephemerides.push(
|
|
2389
|
+
buildStateVectorEphemeris(
|
|
2390
|
+
sys2,
|
|
2391
|
+
prn2,
|
|
2392
|
+
parsed.date,
|
|
2393
|
+
parsed.values,
|
|
2394
|
+
dataLines2
|
|
2395
|
+
)
|
|
2396
|
+
);
|
|
2283
2397
|
} else if (sys2 === "G" || sys2 === "E" || sys2 === "C" || sys2 === "J" || sys2 === "I") {
|
|
2284
|
-
ephemerides.push(
|
|
2398
|
+
ephemerides.push(
|
|
2399
|
+
buildKeplerEphemeris(
|
|
2400
|
+
sys2,
|
|
2401
|
+
prn2,
|
|
2402
|
+
parsed.date,
|
|
2403
|
+
parsed.values,
|
|
2404
|
+
dataLines2
|
|
2405
|
+
)
|
|
2406
|
+
);
|
|
2285
2407
|
}
|
|
2286
2408
|
}
|
|
2287
2409
|
i++;
|
|
@@ -2317,9 +2439,13 @@ function parseNavFile(text) {
|
|
|
2317
2439
|
}
|
|
2318
2440
|
if (dataLines.length === numDataLines) {
|
|
2319
2441
|
if (sys === "R" || sys === "S") {
|
|
2320
|
-
ephemerides.push(
|
|
2442
|
+
ephemerides.push(
|
|
2443
|
+
buildStateVectorEphemeris(sys, prn, date, epochVals, dataLines)
|
|
2444
|
+
);
|
|
2321
2445
|
} else if (sys === "G" || sys === "E" || sys === "C" || sys === "J" || sys === "I") {
|
|
2322
|
-
ephemerides.push(
|
|
2446
|
+
ephemerides.push(
|
|
2447
|
+
buildKeplerEphemeris(sys, prn, date, epochVals, dataLines)
|
|
2448
|
+
);
|
|
2323
2449
|
}
|
|
2324
2450
|
}
|
|
2325
2451
|
i++;
|
|
@@ -2436,21 +2562,18 @@ var BitReader = class {
|
|
|
2436
2562
|
constructor(data) {
|
|
2437
2563
|
this.data = data;
|
|
2438
2564
|
}
|
|
2439
|
-
/** Read `n` bits as unsigned integer (max
|
|
2565
|
+
/** Read `n` bits as unsigned integer (max 53). */
|
|
2440
2566
|
readU(n) {
|
|
2441
2567
|
if (n === 0) return 0;
|
|
2442
2568
|
let val = 0;
|
|
2443
2569
|
for (let i = 0; i < n; i++) {
|
|
2444
2570
|
const byteIdx = this.bitPos + i >> 3;
|
|
2445
2571
|
const bitIdx = 7 - (this.bitPos + i & 7);
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
} else {
|
|
2449
|
-
val <<= 1;
|
|
2450
|
-
}
|
|
2572
|
+
const bit = byteIdx < this.data.length ? this.data[byteIdx] >> bitIdx & 1 : 0;
|
|
2573
|
+
val = val * 2 + bit;
|
|
2451
2574
|
}
|
|
2452
2575
|
this.bitPos += n;
|
|
2453
|
-
return val
|
|
2576
|
+
return val;
|
|
2454
2577
|
}
|
|
2455
2578
|
/** Read `n` bits as signed (two's complement) integer. */
|
|
2456
2579
|
readS(n) {
|
|
@@ -2461,9 +2584,9 @@ var BitReader = class {
|
|
|
2461
2584
|
/** Read `n` bits as sign-magnitude integer (MSB = sign, rest = magnitude). */
|
|
2462
2585
|
readSM(n) {
|
|
2463
2586
|
const val = this.readU(n);
|
|
2464
|
-
const
|
|
2465
|
-
const mag = val
|
|
2466
|
-
return
|
|
2587
|
+
const half = 2 ** (n - 1);
|
|
2588
|
+
const mag = val % half;
|
|
2589
|
+
return val >= half ? -mag : mag;
|
|
2467
2590
|
}
|
|
2468
2591
|
/** Skip `n` bits. */
|
|
2469
2592
|
skip(n) {
|
|
@@ -3250,17 +3373,14 @@ var BitReader2 = class {
|
|
|
3250
3373
|
this.data = data;
|
|
3251
3374
|
this.pos = startBit;
|
|
3252
3375
|
}
|
|
3253
|
-
/** Read unsigned value of numBits bits */
|
|
3376
|
+
/** Read unsigned value of numBits bits (max 53) */
|
|
3254
3377
|
u(numBits) {
|
|
3255
3378
|
let val = 0;
|
|
3256
3379
|
for (let i = 0; i < numBits; i++) {
|
|
3257
3380
|
const byteIdx = this.pos + i >>> 3;
|
|
3258
3381
|
const bitIdx = 7 - (this.pos + i & 7);
|
|
3259
|
-
|
|
3260
|
-
|
|
3261
|
-
} else {
|
|
3262
|
-
val <<= 1;
|
|
3263
|
-
}
|
|
3382
|
+
const bit = byteIdx < this.data.length ? this.data[byteIdx] >>> bitIdx & 1 : 0;
|
|
3383
|
+
val = val * 2 + bit;
|
|
3264
3384
|
}
|
|
3265
3385
|
this.pos += numBits;
|
|
3266
3386
|
return val;
|
|
@@ -3268,8 +3388,8 @@ var BitReader2 = class {
|
|
|
3268
3388
|
/** Read signed value (two's complement) */
|
|
3269
3389
|
s(numBits) {
|
|
3270
3390
|
const raw = this.u(numBits);
|
|
3271
|
-
const
|
|
3272
|
-
return
|
|
3391
|
+
const half = 2 ** (numBits - 1);
|
|
3392
|
+
return raw >= half ? raw - 2 ** numBits : raw;
|
|
3273
3393
|
}
|
|
3274
3394
|
/** Skip bits */
|
|
3275
3395
|
skip(n) {
|
|
@@ -3404,7 +3524,6 @@ function decodeMsmFull(frame) {
|
|
|
3404
3524
|
const rdop = new Float64Array(numSat);
|
|
3405
3525
|
if (variant === 4 || variant === 6) {
|
|
3406
3526
|
for (let j = 0; j < numSat; j++) rrint[j] = bits.u(8);
|
|
3407
|
-
for (let j = 0; j < numSat; j++) extsat[j] = bits.u(4);
|
|
3408
3527
|
for (let j = 0; j < numSat; j++) rrmod[j] = bits.u(10) / 1024;
|
|
3409
3528
|
} else {
|
|
3410
3529
|
for (let j = 0; j < numSat; j++) rrint[j] = bits.u(8);
|
|
@@ -3430,27 +3549,27 @@ function decodeMsmFull(frame) {
|
|
|
3430
3549
|
cp.fill(-1e30);
|
|
3431
3550
|
dop.fill(-1e30);
|
|
3432
3551
|
if (variant === 4) {
|
|
3433
|
-
for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) /
|
|
3434
|
-
for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) /
|
|
3552
|
+
for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) / 2 ** 24;
|
|
3553
|
+
for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) / 2 ** 29;
|
|
3435
3554
|
for (let i = 0; i < activeCells; i++) ll[i] = bits.u(4);
|
|
3436
3555
|
for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
|
|
3437
3556
|
for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(6);
|
|
3438
3557
|
} else if (variant === 5) {
|
|
3439
|
-
for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) /
|
|
3440
|
-
for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) /
|
|
3558
|
+
for (let i = 0; i < activeCells; i++) psr[i] = bits.s(15) / 2 ** 24;
|
|
3559
|
+
for (let i = 0; i < activeCells; i++) cp[i] = bits.s(22) / 2 ** 29;
|
|
3441
3560
|
for (let i = 0; i < activeCells; i++) ll[i] = bits.u(4);
|
|
3442
3561
|
for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
|
|
3443
3562
|
for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(6);
|
|
3444
3563
|
for (let i = 0; i < activeCells; i++) dop[i] = bits.s(15) * 1e-4;
|
|
3445
3564
|
} else if (variant === 6) {
|
|
3446
|
-
for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) /
|
|
3447
|
-
for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) /
|
|
3565
|
+
for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) / 2 ** 29;
|
|
3566
|
+
for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) / 2 ** 31;
|
|
3448
3567
|
for (let i = 0; i < activeCells; i++) ll[i] = bits.u(10);
|
|
3449
3568
|
for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
|
|
3450
3569
|
for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(10) / 16;
|
|
3451
3570
|
} else {
|
|
3452
|
-
for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) /
|
|
3453
|
-
for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) /
|
|
3571
|
+
for (let i = 0; i < activeCells; i++) psr[i] = bits.s(20) / 2 ** 29;
|
|
3572
|
+
for (let i = 0; i < activeCells; i++) cp[i] = bits.s(24) / 2 ** 31;
|
|
3454
3573
|
for (let i = 0; i < activeCells; i++) ll[i] = bits.u(10);
|
|
3455
3574
|
for (let i = 0; i < activeCells; i++) hc[i] = bits.u(1);
|
|
3456
3575
|
for (let i = 0; i < activeCells; i++) cnr[i] = bits.u(10) / 16;
|
|
@@ -3919,10 +4038,7 @@ function keplerPosition(eph, t) {
|
|
|
3919
4038
|
}
|
|
3920
4039
|
const sinE = Math.sin(Ek);
|
|
3921
4040
|
const cosE = Math.cos(Ek);
|
|
3922
|
-
const vk = Math.atan2(
|
|
3923
|
-
Math.sqrt(1 - eph.e * eph.e) * sinE,
|
|
3924
|
-
cosE - eph.e
|
|
3925
|
-
);
|
|
4041
|
+
const vk = Math.atan2(Math.sqrt(1 - eph.e * eph.e) * sinE, cosE - eph.e);
|
|
3926
4042
|
const phik = vk + eph.omega;
|
|
3927
4043
|
const sin2phi = Math.sin(2 * phik);
|
|
3928
4044
|
const cos2phi = Math.cos(2 * phik);
|
|
@@ -4085,7 +4201,10 @@ function invert4x4(m) {
|
|
|
4085
4201
|
let det = a[0] * inv[0] + a[1] * inv[4] + a[2] * inv[8] + a[3] * inv[12];
|
|
4086
4202
|
if (Math.abs(det) < 1e-20) return null;
|
|
4087
4203
|
det = 1 / det;
|
|
4088
|
-
const result = Array.from(
|
|
4204
|
+
const result = Array.from(
|
|
4205
|
+
{ length: 4 },
|
|
4206
|
+
() => new Array(4).fill(0)
|
|
4207
|
+
);
|
|
4089
4208
|
for (let i = 0; i < 4; i++) {
|
|
4090
4209
|
for (let j = 0; j < 4; j++) {
|
|
4091
4210
|
result[i][j] = inv[i * 4 + j] * det;
|
|
@@ -4202,10 +4321,16 @@ var GAL_EPOCH_MS = GPS_EPOCH_MS;
|
|
|
4202
4321
|
function ephInfoToEphemeris(info) {
|
|
4203
4322
|
const sys = info.prn.charAt(0);
|
|
4204
4323
|
if (sys === "R") {
|
|
4205
|
-
if (info.x === void 0 || info.y === void 0 || info.z === void 0)
|
|
4206
|
-
|
|
4324
|
+
if (info.x === void 0 || info.y === void 0 || info.z === void 0)
|
|
4325
|
+
return null;
|
|
4326
|
+
if (info.vx === void 0 || info.vy === void 0 || info.vz === void 0)
|
|
4327
|
+
return null;
|
|
4207
4328
|
const now = new Date(info.lastReceived);
|
|
4208
|
-
const utcMidnight = Date.UTC(
|
|
4329
|
+
const utcMidnight = Date.UTC(
|
|
4330
|
+
now.getUTCFullYear(),
|
|
4331
|
+
now.getUTCMonth(),
|
|
4332
|
+
now.getUTCDate()
|
|
4333
|
+
);
|
|
4209
4334
|
const tbSec = (info.tb ?? 0) * 900;
|
|
4210
4335
|
const moscowOffset = 3 * 3600;
|
|
4211
4336
|
const tocMs = utcMidnight + (tbSec - moscowOffset) * 1e3;
|
|
@@ -4230,7 +4355,8 @@ function ephInfoToEphemeris(info) {
|
|
|
4230
4355
|
freqNum: info.freqChannel ?? 0
|
|
4231
4356
|
};
|
|
4232
4357
|
}
|
|
4233
|
-
if (info.sqrtA === void 0 || info.eccentricity === void 0 || info.inclination === void 0 || info.omega0 === void 0 || info.argPerigee === void 0 || info.meanAnomaly === void 0 || info.toe === void 0 || info.week === void 0)
|
|
4358
|
+
if (info.sqrtA === void 0 || info.eccentricity === void 0 || info.inclination === void 0 || info.omega0 === void 0 || info.argPerigee === void 0 || info.meanAnomaly === void 0 || info.toe === void 0 || info.week === void 0)
|
|
4359
|
+
return null;
|
|
4234
4360
|
let epochMs;
|
|
4235
4361
|
const tocSec = info.toc ?? info.toe;
|
|
4236
4362
|
if (sys === "C") {
|
|
@@ -4406,14 +4532,18 @@ async function ntripFetch(proxyUrl, path, headers, signal) {
|
|
|
4406
4532
|
} catch (err) {
|
|
4407
4533
|
if (err instanceof Error && err.name === "AbortError") throw err;
|
|
4408
4534
|
const message = err instanceof Error ? err.message : "The service may be temporarily unavailable.";
|
|
4409
|
-
throw new Error(`Could not reach the NTRIP proxy: ${message}`, {
|
|
4535
|
+
throw new Error(`Could not reach the NTRIP proxy: ${message}`, {
|
|
4536
|
+
cause: err
|
|
4537
|
+
});
|
|
4410
4538
|
}
|
|
4411
4539
|
}
|
|
4412
4540
|
async function fetchSourcetable(proxyUrl, info, signal) {
|
|
4413
4541
|
const headers = ntripHeaders(info);
|
|
4414
4542
|
const res = await ntripFetch(proxyUrl, "/", headers, signal);
|
|
4415
4543
|
if (res.status === 401) {
|
|
4416
|
-
throw new Error(
|
|
4544
|
+
throw new Error(
|
|
4545
|
+
"Authentication required. Please provide valid credentials."
|
|
4546
|
+
);
|
|
4417
4547
|
}
|
|
4418
4548
|
if (!res.ok) {
|
|
4419
4549
|
throw new Error(`Caster returned ${res.status} ${res.statusText}`);
|
|
@@ -4425,7 +4555,12 @@ async function connectToMountpoint(proxyUrl, info, signal) {
|
|
|
4425
4555
|
const headers = ntripHeaders(info);
|
|
4426
4556
|
const controller = new AbortController();
|
|
4427
4557
|
const combinedSignal = signal ? AbortSignal.any([signal, controller.signal]) : controller.signal;
|
|
4428
|
-
const res = await ntripFetch(
|
|
4558
|
+
const res = await ntripFetch(
|
|
4559
|
+
proxyUrl,
|
|
4560
|
+
`/${info.mountpoint}`,
|
|
4561
|
+
headers,
|
|
4562
|
+
combinedSignal
|
|
4563
|
+
);
|
|
4429
4564
|
if (res.status === 401) {
|
|
4430
4565
|
throw new Error("Authentication required for this mountpoint.");
|
|
4431
4566
|
}
|
|
@@ -4436,7 +4571,9 @@ async function connectToMountpoint(proxyUrl, info, signal) {
|
|
|
4436
4571
|
throw new Error(`Caster returned ${res.status} ${res.statusText}`);
|
|
4437
4572
|
}
|
|
4438
4573
|
if (!res.body) {
|
|
4439
|
-
throw new Error(
|
|
4574
|
+
throw new Error(
|
|
4575
|
+
"No response body \u2014 streaming not supported by this environment."
|
|
4576
|
+
);
|
|
4440
4577
|
}
|
|
4441
4578
|
return {
|
|
4442
4579
|
reader: res.body.getReader(),
|
|
@@ -4530,8 +4667,18 @@ var MultipathAccumulator = class {
|
|
|
4530
4667
|
time: t,
|
|
4531
4668
|
mp: arc.rawMp[i] - mean
|
|
4532
4669
|
}));
|
|
4533
|
-
const rms = Math.sqrt(
|
|
4534
|
-
|
|
4670
|
+
const rms = Math.sqrt(
|
|
4671
|
+
points.reduce((s, p) => s + p.mp * p.mp, 0) / points.length
|
|
4672
|
+
);
|
|
4673
|
+
this.results.push({
|
|
4674
|
+
prn,
|
|
4675
|
+
system: sys,
|
|
4676
|
+
band,
|
|
4677
|
+
refBand,
|
|
4678
|
+
label: label2,
|
|
4679
|
+
points,
|
|
4680
|
+
rms
|
|
4681
|
+
});
|
|
4535
4682
|
}
|
|
4536
4683
|
state.arc = { times: [], rawMp: [] };
|
|
4537
4684
|
}
|
|
@@ -4685,10 +4832,20 @@ var CycleSlipAccumulator = class {
|
|
|
4685
4832
|
const sigKey = `${sys}:${signal}`;
|
|
4686
4833
|
this.countEpoch(sigKey);
|
|
4687
4834
|
const stddev = mwSmoothStddev(prevSmooth);
|
|
4688
|
-
const threshold = Math.max(
|
|
4835
|
+
const threshold = Math.max(
|
|
4836
|
+
MW_MIN_THRESHOLD,
|
|
4837
|
+
MW_SIGMA_FACTOR * stddev
|
|
4838
|
+
);
|
|
4689
4839
|
const deviation = Math.abs(mw - prevSmooth.mean);
|
|
4690
4840
|
if (deviation > threshold) {
|
|
4691
|
-
this.recordSlip(
|
|
4841
|
+
this.recordSlip(
|
|
4842
|
+
sigKey,
|
|
4843
|
+
time,
|
|
4844
|
+
prn,
|
|
4845
|
+
signal,
|
|
4846
|
+
deviation,
|
|
4847
|
+
/* @__PURE__ */ new Set([b1, b2])
|
|
4848
|
+
);
|
|
4692
4849
|
mwSmooth.set(pairKey, mwSmoothInit(mw));
|
|
4693
4850
|
} else {
|
|
4694
4851
|
mwSmooth.set(pairKey, mwSmoothUpdate(prevSmooth, mw));
|
|
@@ -4743,7 +4900,13 @@ var CycleSlipAccumulator = class {
|
|
|
4743
4900
|
}
|
|
4744
4901
|
}
|
|
4745
4902
|
}
|
|
4746
|
-
this.prev.set(prn, {
|
|
4903
|
+
this.prev.set(prn, {
|
|
4904
|
+
time,
|
|
4905
|
+
mwSmooth,
|
|
4906
|
+
gf: gfMap,
|
|
4907
|
+
phase: phaseM,
|
|
4908
|
+
code: codeM
|
|
4909
|
+
});
|
|
4747
4910
|
};
|
|
4748
4911
|
finalize() {
|
|
4749
4912
|
const satSlipCounts = {};
|
|
@@ -4751,7 +4914,10 @@ var CycleSlipAccumulator = class {
|
|
|
4751
4914
|
satSlipCounts[ev.prn] = (satSlipCounts[ev.prn] ?? 0) + 1;
|
|
4752
4915
|
}
|
|
4753
4916
|
const signalStats = [];
|
|
4754
|
-
const allKeys = /* @__PURE__ */ new Set([
|
|
4917
|
+
const allKeys = /* @__PURE__ */ new Set([
|
|
4918
|
+
...this.signalEpochs.keys(),
|
|
4919
|
+
...this.signalSlips.keys()
|
|
4920
|
+
]);
|
|
4755
4921
|
for (const sigKey of allKeys) {
|
|
4756
4922
|
const [sys, ...rest] = sigKey.split(":");
|
|
4757
4923
|
const signal = rest.join(":");
|
package/dist/index.d.cts
CHANGED
|
@@ -7,7 +7,7 @@ export { c as clampUnit, e as ecefToGeodetic, g as geodeticToEcef, a as getAer,
|
|
|
7
7
|
export { CrxField, DiffState, EMPTY_WARNINGS, RinexWarning, RinexWarnings, WarningAccumulator, WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, writeRinexNav } from './rinex.cjs';
|
|
8
8
|
export { E as EpochSummary, P as ParseOptions, R as RinexHeader, a as RinexResult, b as RinexStats, S as SYSTEM_ORDER, c as SatObsCallback, p as parseRinexStream, s as systemCmp, d as systemName } from './parser-JPjjFgeP.cjs';
|
|
9
9
|
export { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, p as parseNavFile } from './nav-BAI1a9vK.cjs';
|
|
10
|
-
export { B as BitReader, E as EphemerisInfo, R as Rtcm3Decoder, a as Rtcm3Frame, d as decodeEphemeris, r as readString } from './ephemeris-
|
|
10
|
+
export { B as BitReader, E as EphemerisInfo, R as Rtcm3Decoder, a as Rtcm3Frame, d as decodeEphemeris, r as readString } from './ephemeris-C10stHhM.cjs';
|
|
11
11
|
export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, updateStationMeta, updateStreamStats } from './rtcm3.cjs';
|
|
12
12
|
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, ecefToAzEl, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris } from './orbit.cjs';
|
|
13
13
|
export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export { c as clampUnit, e as ecefToGeodetic, g as geodeticToEcef, a as getAer,
|
|
|
7
7
|
export { CrxField, DiffState, EMPTY_WARNINGS, RinexWarning, RinexWarnings, WarningAccumulator, WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, writeRinexNav } from './rinex.js';
|
|
8
8
|
export { E as EpochSummary, P as ParseOptions, R as RinexHeader, a as RinexResult, b as RinexStats, S as SYSTEM_ORDER, c as SatObsCallback, p as parseRinexStream, s as systemCmp, d as systemName } from './parser-JPjjFgeP.js';
|
|
9
9
|
export { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, p as parseNavFile } from './nav-BAI1a9vK.js';
|
|
10
|
-
export { B as BitReader, E as EphemerisInfo, R as Rtcm3Decoder, a as Rtcm3Frame, d as decodeEphemeris, r as readString } from './ephemeris-
|
|
10
|
+
export { B as BitReader, E as EphemerisInfo, R as Rtcm3Decoder, a as Rtcm3Frame, d as decodeEphemeris, r as readString } from './ephemeris-C10stHhM.js';
|
|
11
11
|
export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, updateStationMeta, updateStreamStats } from './rtcm3.js';
|
|
12
12
|
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, ecefToAzEl, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris } from './orbit.js';
|
|
13
13
|
export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.js';
|