gnss-js 1.11.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-LKFSXVIZ.js → chunk-E5CP37P2.js} +1 -1
- package/dist/{chunk-77VUSDNI.js → chunk-HXF7XVW7.js} +499 -1
- package/dist/{chunk-DMNFB7Q6.js → chunk-VAHMHYID.js} +9 -2
- package/dist/index.cjs +517 -3
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +23 -5
- package/dist/orbit.cjs +9 -1
- package/dist/orbit.d.cts +8 -1
- package/dist/orbit.d.ts +8 -1
- package/dist/orbit.js +3 -1
- package/dist/positioning.js +2 -2
- package/dist/rinex.cjs +508 -2
- package/dist/rinex.d.cts +129 -1
- package/dist/rinex.d.ts +129 -1
- package/dist/rinex.js +19 -3
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -117,7 +117,9 @@ __export(src_exports, {
|
|
|
117
117
|
computeSatPosition: () => computeSatPosition,
|
|
118
118
|
computeStats: () => computeStats2,
|
|
119
119
|
computeVisibility: () => computeVisibility,
|
|
120
|
+
computeVisibilityFromPositions: () => computeVisibilityFromPositions,
|
|
120
121
|
connectToMountpoint: () => connectToMountpoint,
|
|
122
|
+
createGzipLineSink: () => createGzipLineSink,
|
|
121
123
|
createStationMeta: () => createStationMeta,
|
|
122
124
|
createStreamStats: () => createStreamStats,
|
|
123
125
|
crxDecompress: () => crxDecompress,
|
|
@@ -216,6 +218,7 @@ __export(src_exports, {
|
|
|
216
218
|
parseRinexStream: () => parseRinexStream,
|
|
217
219
|
parseSinexBiasDcb: () => parseSinexBiasDcb,
|
|
218
220
|
parseSourcetable: () => parseSourcetable,
|
|
221
|
+
parseSp3: () => parseSp3,
|
|
219
222
|
phiAltBOC: () => phiAltBOC,
|
|
220
223
|
phiBOCc: () => phiBOCc,
|
|
221
224
|
phiBOCs: () => phiBOCs,
|
|
@@ -232,6 +235,8 @@ __export(src_exports, {
|
|
|
232
235
|
setGloFreqNumber: () => setGloFreqNumber,
|
|
233
236
|
setRtcm3DebugHandler: () => setRtcm3DebugHandler,
|
|
234
237
|
solveSpp: () => solveSpp,
|
|
238
|
+
sp3Position: () => sp3Position,
|
|
239
|
+
stationHeaderLines: () => stationHeaderLines,
|
|
235
240
|
systemCmp: () => systemCmp,
|
|
236
241
|
systemName: () => systemName,
|
|
237
242
|
transformFrame: () => transformFrame,
|
|
@@ -239,7 +244,11 @@ __export(src_exports, {
|
|
|
239
244
|
updateStreamStats: () => updateStreamStats,
|
|
240
245
|
verifyChecksum: () => verifyChecksum,
|
|
241
246
|
vincenty: () => vincenty,
|
|
242
|
-
|
|
247
|
+
writeModernObsBlob: () => writeModernObsBlob,
|
|
248
|
+
writeRinex2ObsBlob: () => writeRinex2ObsBlob,
|
|
249
|
+
writeRinex4ObsBlob: () => writeRinex4ObsBlob,
|
|
250
|
+
writeRinexNav: () => writeRinexNav,
|
|
251
|
+
writeRinexObsBlob: () => writeRinexObsBlob
|
|
243
252
|
});
|
|
244
253
|
module.exports = __toCommonJS(src_exports);
|
|
245
254
|
|
|
@@ -2665,6 +2674,496 @@ function parseIonex(text) {
|
|
|
2665
2674
|
return { epochs, lats, lons, maps };
|
|
2666
2675
|
}
|
|
2667
2676
|
|
|
2677
|
+
// src/rinex/sp3.ts
|
|
2678
|
+
var BAD_CLOCK = 999999.999999;
|
|
2679
|
+
function parseSp3(text) {
|
|
2680
|
+
const lines = text.split("\n");
|
|
2681
|
+
const epochs = [];
|
|
2682
|
+
const satellites = {};
|
|
2683
|
+
let version = "";
|
|
2684
|
+
let intervalSec = 0;
|
|
2685
|
+
let timeSystem = "GPS";
|
|
2686
|
+
let timeSystemSet = false;
|
|
2687
|
+
let epochIdx = -1;
|
|
2688
|
+
for (const line of lines) {
|
|
2689
|
+
if (!version && line.startsWith("#") && line.charAt(1) !== "#") {
|
|
2690
|
+
version = line.charAt(1);
|
|
2691
|
+
}
|
|
2692
|
+
if (line.startsWith("##")) {
|
|
2693
|
+
const f = line.slice(2).trim().split(/\s+/);
|
|
2694
|
+
intervalSec = Number(f[2]) || 0;
|
|
2695
|
+
} else if (line.startsWith("%c") && !timeSystemSet) {
|
|
2696
|
+
const sys = line.slice(9, 12).trim();
|
|
2697
|
+
if (sys && !/^c+$/.test(sys)) {
|
|
2698
|
+
timeSystem = sys;
|
|
2699
|
+
timeSystemSet = true;
|
|
2700
|
+
}
|
|
2701
|
+
} else if (line.startsWith("*")) {
|
|
2702
|
+
const f = line.slice(1).trim().split(/\s+/).map(Number);
|
|
2703
|
+
if (f.length >= 6 && f.every(Number.isFinite)) {
|
|
2704
|
+
const sec = f[5];
|
|
2705
|
+
epochs.push(
|
|
2706
|
+
Date.UTC(
|
|
2707
|
+
f[0],
|
|
2708
|
+
f[1] - 1,
|
|
2709
|
+
f[2],
|
|
2710
|
+
f[3],
|
|
2711
|
+
f[4],
|
|
2712
|
+
Math.floor(sec),
|
|
2713
|
+
Math.round(sec % 1 * 1e3)
|
|
2714
|
+
)
|
|
2715
|
+
);
|
|
2716
|
+
epochIdx++;
|
|
2717
|
+
}
|
|
2718
|
+
} else if (line.startsWith("P") && epochIdx >= 0) {
|
|
2719
|
+
const prn = line.slice(1, 4).replace(/\s/g, "0");
|
|
2720
|
+
const f = line.slice(4).trim().split(/\s+/).map(Number);
|
|
2721
|
+
if (f.length < 3) continue;
|
|
2722
|
+
const [xKm, yKm, zKm] = f;
|
|
2723
|
+
let arr = satellites[prn];
|
|
2724
|
+
if (!arr) satellites[prn] = arr = [];
|
|
2725
|
+
while (arr.length < epochIdx) arr.push(null);
|
|
2726
|
+
if (xKm === 0 && yKm === 0 && zKm === 0) {
|
|
2727
|
+
arr.push(null);
|
|
2728
|
+
continue;
|
|
2729
|
+
}
|
|
2730
|
+
const clkUs = f[3];
|
|
2731
|
+
arr.push({
|
|
2732
|
+
x: xKm * 1e3,
|
|
2733
|
+
y: yKm * 1e3,
|
|
2734
|
+
z: zKm * 1e3,
|
|
2735
|
+
clk: clkUs !== void 0 && Math.abs(clkUs) < BAD_CLOCK ? clkUs * 1e-6 : null
|
|
2736
|
+
});
|
|
2737
|
+
}
|
|
2738
|
+
}
|
|
2739
|
+
for (const arr of Object.values(satellites)) {
|
|
2740
|
+
while (arr.length < epochs.length) arr.push(null);
|
|
2741
|
+
}
|
|
2742
|
+
return { version, epochs, intervalSec, timeSystem, satellites };
|
|
2743
|
+
}
|
|
2744
|
+
function sp3Position(sp3, prn, tMs, order = 9) {
|
|
2745
|
+
const samples = sp3.satellites[prn];
|
|
2746
|
+
const { epochs } = sp3;
|
|
2747
|
+
const n = epochs.length;
|
|
2748
|
+
if (!samples || n < order) return null;
|
|
2749
|
+
if (tMs < epochs[0] || tMs > epochs[n - 1]) return null;
|
|
2750
|
+
let lo = 0;
|
|
2751
|
+
let hi = n - 1;
|
|
2752
|
+
while (lo < hi) {
|
|
2753
|
+
const mid = lo + hi + 1 >> 1;
|
|
2754
|
+
if (epochs[mid] <= tMs) lo = mid;
|
|
2755
|
+
else hi = mid - 1;
|
|
2756
|
+
}
|
|
2757
|
+
let start = lo - (order >> 1) + (order % 2 === 0 ? 1 : 0);
|
|
2758
|
+
start = Math.max(0, Math.min(n - order, start));
|
|
2759
|
+
for (let i = start; i < start + order; i++) {
|
|
2760
|
+
if (!samples[i]) return null;
|
|
2761
|
+
}
|
|
2762
|
+
const t0 = epochs[start];
|
|
2763
|
+
const t = (tMs - t0) / 1e3;
|
|
2764
|
+
let x = 0;
|
|
2765
|
+
let y = 0;
|
|
2766
|
+
let z = 0;
|
|
2767
|
+
for (let i = 0; i < order; i++) {
|
|
2768
|
+
const ti = (epochs[start + i] - t0) / 1e3;
|
|
2769
|
+
let w = 1;
|
|
2770
|
+
for (let j = 0; j < order; j++) {
|
|
2771
|
+
if (j === i) continue;
|
|
2772
|
+
const tj = (epochs[start + j] - t0) / 1e3;
|
|
2773
|
+
w *= (t - tj) / (ti - tj);
|
|
2774
|
+
}
|
|
2775
|
+
const s = samples[start + i];
|
|
2776
|
+
x += w * s.x;
|
|
2777
|
+
y += w * s.y;
|
|
2778
|
+
z += w * s.z;
|
|
2779
|
+
}
|
|
2780
|
+
let clk = null;
|
|
2781
|
+
const a = samples[lo];
|
|
2782
|
+
const b = samples[Math.min(lo + 1, n - 1)];
|
|
2783
|
+
if (a?.clk != null && b?.clk != null) {
|
|
2784
|
+
const span = epochs[Math.min(lo + 1, n - 1)] - epochs[lo];
|
|
2785
|
+
const f = span > 0 ? (tMs - epochs[lo]) / span : 0;
|
|
2786
|
+
clk = a.clk * (1 - f) + b.clk * f;
|
|
2787
|
+
} else if (a?.clk != null) {
|
|
2788
|
+
clk = a.clk;
|
|
2789
|
+
}
|
|
2790
|
+
return { x, y, z, clk };
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2793
|
+
// src/rinex/obs-writer-common.ts
|
|
2794
|
+
function createGzipLineSink() {
|
|
2795
|
+
const encoder = new TextEncoder();
|
|
2796
|
+
const compressor = new CompressionStream("gzip");
|
|
2797
|
+
const writer = compressor.writable.getWriter();
|
|
2798
|
+
const compressedChunks = [];
|
|
2799
|
+
const readerDone = (async () => {
|
|
2800
|
+
const reader = compressor.readable.getReader();
|
|
2801
|
+
for (; ; ) {
|
|
2802
|
+
const { done, value } = await reader.read();
|
|
2803
|
+
if (done) break;
|
|
2804
|
+
compressedChunks.push(value);
|
|
2805
|
+
}
|
|
2806
|
+
})();
|
|
2807
|
+
let batch = [];
|
|
2808
|
+
async function flush() {
|
|
2809
|
+
if (batch.length === 0) return;
|
|
2810
|
+
await writer.write(encoder.encode(batch.join("\n") + "\n"));
|
|
2811
|
+
batch = [];
|
|
2812
|
+
}
|
|
2813
|
+
return {
|
|
2814
|
+
push(line) {
|
|
2815
|
+
batch.push(line);
|
|
2816
|
+
},
|
|
2817
|
+
flush,
|
|
2818
|
+
async finish() {
|
|
2819
|
+
await flush();
|
|
2820
|
+
await writer.close();
|
|
2821
|
+
await readerDone;
|
|
2822
|
+
return new Blob(compressedChunks, {
|
|
2823
|
+
type: "application/gzip"
|
|
2824
|
+
});
|
|
2825
|
+
}
|
|
2826
|
+
};
|
|
2827
|
+
}
|
|
2828
|
+
function stationHeaderLines(header) {
|
|
2829
|
+
const pos = header.approxPosition ?? [0, 0, 0];
|
|
2830
|
+
const delta = header.antDelta ?? [0, 0, 0];
|
|
2831
|
+
return [
|
|
2832
|
+
hdrLine(header.markerName || "UNKNOWN", "MARKER NAME"),
|
|
2833
|
+
hdrLine("", "MARKER NUMBER"),
|
|
2834
|
+
hdrLine(
|
|
2835
|
+
`${padL(header.observer || "", 20)}${padL(header.agency || "", 40)}`,
|
|
2836
|
+
"OBSERVER / AGENCY"
|
|
2837
|
+
),
|
|
2838
|
+
hdrLine(
|
|
2839
|
+
`${padL(header.receiverNumber || "", 20)}${padL(header.receiverType || "", 20)}${padL(header.receiverVersion || "", 20)}`,
|
|
2840
|
+
"REC # / TYPE / VERS"
|
|
2841
|
+
),
|
|
2842
|
+
hdrLine(
|
|
2843
|
+
`${padL(header.antNumber || "", 20)}${padL(header.antType || "", 20)}`,
|
|
2844
|
+
"ANT # / TYPE"
|
|
2845
|
+
),
|
|
2846
|
+
hdrLine(
|
|
2847
|
+
`${fmtF(pos[0], 14, 4)}${fmtF(pos[1], 14, 4)}${fmtF(pos[2], 14, 4)}`,
|
|
2848
|
+
"APPROX POSITION XYZ"
|
|
2849
|
+
),
|
|
2850
|
+
hdrLine(
|
|
2851
|
+
`${fmtF(delta[0], 14, 4)}${fmtF(delta[1], 14, 4)}${fmtF(delta[2], 14, 4)}`,
|
|
2852
|
+
"ANTENNA: DELTA H/E/N"
|
|
2853
|
+
)
|
|
2854
|
+
];
|
|
2855
|
+
}
|
|
2856
|
+
|
|
2857
|
+
// src/rinex/obs-writer.ts
|
|
2858
|
+
function writeRinexObsBlob(header, epochs, obsTypes) {
|
|
2859
|
+
return writeModernObsBlob(header, epochs, obsTypes, {
|
|
2860
|
+
version: "3.04",
|
|
2861
|
+
comment: "Merged from multiple RINEX files"
|
|
2862
|
+
});
|
|
2863
|
+
}
|
|
2864
|
+
async function writeModernObsBlob(header, epochs, obsTypes, opts) {
|
|
2865
|
+
if (epochs.length === 0) return new Blob([], { type: "application/gzip" });
|
|
2866
|
+
const sink = createGzipLineSink();
|
|
2867
|
+
const BATCH = 200;
|
|
2868
|
+
const systems = [...obsTypes.keys()];
|
|
2869
|
+
const sysChar = systems.length === 1 ? systems[0] : "M";
|
|
2870
|
+
sink.push(
|
|
2871
|
+
hdrLine(
|
|
2872
|
+
` ${opts.version} OBSERVATION DATA ${sysChar}`,
|
|
2873
|
+
"RINEX VERSION / TYPE"
|
|
2874
|
+
)
|
|
2875
|
+
);
|
|
2876
|
+
const now = /* @__PURE__ */ new Date();
|
|
2877
|
+
const dateStr = `${now.getUTCFullYear()}${String(now.getUTCMonth() + 1).padStart(2, "0")}${String(now.getUTCDate()).padStart(2, "0")} ${String(now.getUTCHours()).padStart(2, "0")}${String(now.getUTCMinutes()).padStart(2, "0")}${String(now.getUTCSeconds()).padStart(2, "0")} UTC`;
|
|
2878
|
+
sink.push(
|
|
2879
|
+
hdrLine(
|
|
2880
|
+
`${padL("GNSSCalc", 20)}${padL("", 20)}${dateStr}`,
|
|
2881
|
+
"PGM / RUN BY / DATE"
|
|
2882
|
+
)
|
|
2883
|
+
);
|
|
2884
|
+
sink.push(hdrLine(opts.comment, "COMMENT"));
|
|
2885
|
+
for (const line of stationHeaderLines(header)) sink.push(line);
|
|
2886
|
+
for (const [sys, types] of obsTypes) {
|
|
2887
|
+
for (let i = 0; i < types.length; i += 13) {
|
|
2888
|
+
const chunk = types.slice(i, i + 13);
|
|
2889
|
+
let content;
|
|
2890
|
+
if (i === 0) {
|
|
2891
|
+
content = `${sys} ${padR(String(types.length), 3)}`;
|
|
2892
|
+
} else {
|
|
2893
|
+
content = " ";
|
|
2894
|
+
}
|
|
2895
|
+
content += chunk.map((t) => ` ${padL(t, 3)}`).join("");
|
|
2896
|
+
sink.push(hdrLine(content, "SYS / # / OBS TYPES"));
|
|
2897
|
+
}
|
|
2898
|
+
}
|
|
2899
|
+
const timeSys = systems.includes("R") && systems.length === 1 ? "GLO" : "GPS";
|
|
2900
|
+
const obsTimeLine = (d) => ` ${d.getUTCFullYear()} ${String(d.getUTCMonth() + 1).padStart(2)} ${String(d.getUTCDate()).padStart(2)} ${String(d.getUTCHours()).padStart(2)} ${String(d.getUTCMinutes()).padStart(2)} ${(d.getUTCSeconds() + d.getUTCMilliseconds() / 1e3).toFixed(7).padStart(10)} ${timeSys}`;
|
|
2901
|
+
sink.push(
|
|
2902
|
+
hdrLine(obsTimeLine(new Date(epochs[0].time)), "TIME OF FIRST OBS")
|
|
2903
|
+
);
|
|
2904
|
+
sink.push(
|
|
2905
|
+
hdrLine(
|
|
2906
|
+
obsTimeLine(new Date(epochs[epochs.length - 1].time)),
|
|
2907
|
+
"TIME OF LAST OBS"
|
|
2908
|
+
)
|
|
2909
|
+
);
|
|
2910
|
+
if (epochs.length >= 2) {
|
|
2911
|
+
const interval = (epochs[1].time - epochs[0].time) / 1e3;
|
|
2912
|
+
if (interval > 0 && interval < 3600) {
|
|
2913
|
+
sink.push(hdrLine(fmtF(interval, 10, 3), "INTERVAL"));
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
if (header.glonassSlots && Object.keys(header.glonassSlots).length > 0) {
|
|
2917
|
+
const entries = Object.entries(header.glonassSlots).sort(
|
|
2918
|
+
([a], [b]) => Number(a) - Number(b)
|
|
2919
|
+
);
|
|
2920
|
+
for (let i = 0; i < entries.length; i += 8) {
|
|
2921
|
+
const chunk = entries.slice(i, i + 8);
|
|
2922
|
+
let content = i === 0 ? padR(String(entries.length), 3) + " " : " ";
|
|
2923
|
+
for (const [slot, freq] of chunk) {
|
|
2924
|
+
content += `R${padR(slot, 2)} ${padR(String(freq), 2)} `;
|
|
2925
|
+
}
|
|
2926
|
+
sink.push(hdrLine(content, "GLONASS SLOT / FRQ #"));
|
|
2927
|
+
}
|
|
2928
|
+
}
|
|
2929
|
+
sink.push(hdrLine("", "END OF HEADER"));
|
|
2930
|
+
await sink.flush();
|
|
2931
|
+
let epochCount = 0;
|
|
2932
|
+
for (const epoch of epochs) {
|
|
2933
|
+
const t = new Date(epoch.time);
|
|
2934
|
+
const sec = t.getUTCSeconds() + t.getUTCMilliseconds() / 1e3;
|
|
2935
|
+
const prns = [...epoch.sats.keys()].sort();
|
|
2936
|
+
sink.push(
|
|
2937
|
+
`> ${t.getUTCFullYear()} ${String(t.getUTCMonth() + 1).padStart(2, "0")} ${String(t.getUTCDate()).padStart(2, "0")} ${String(t.getUTCHours()).padStart(2, "0")} ${String(t.getUTCMinutes()).padStart(2, "0")}${fmtF(sec, 11, 7)} 0${padR(String(prns.length), 3)}`
|
|
2938
|
+
);
|
|
2939
|
+
for (const prn of prns) {
|
|
2940
|
+
const sys = prn[0];
|
|
2941
|
+
const sysTypes = obsTypes.get(sys);
|
|
2942
|
+
if (!sysTypes) continue;
|
|
2943
|
+
const valArr = epoch.sats.get(prn);
|
|
2944
|
+
let line = prn;
|
|
2945
|
+
for (let i = 0; i < sysTypes.length; i++) {
|
|
2946
|
+
const val = i < valArr.length ? valArr[i] : NaN;
|
|
2947
|
+
if (!isNaN(val)) {
|
|
2948
|
+
line += fmtF(val, 14, 3) + " ";
|
|
2949
|
+
} else {
|
|
2950
|
+
line += " ".repeat(16);
|
|
2951
|
+
}
|
|
2952
|
+
}
|
|
2953
|
+
sink.push(line);
|
|
2954
|
+
}
|
|
2955
|
+
epochCount++;
|
|
2956
|
+
if (epochCount % BATCH === 0) await sink.flush();
|
|
2957
|
+
}
|
|
2958
|
+
return sink.finish();
|
|
2959
|
+
}
|
|
2960
|
+
|
|
2961
|
+
// src/rinex/obs-writer-v2.ts
|
|
2962
|
+
var V3_TO_V2 = {
|
|
2963
|
+
// GPS
|
|
2964
|
+
C1C: "C1",
|
|
2965
|
+
C1S: "C1",
|
|
2966
|
+
C1L: "C1",
|
|
2967
|
+
C1X: "C1",
|
|
2968
|
+
C1W: "P1",
|
|
2969
|
+
C1P: "P1",
|
|
2970
|
+
C2C: "C2",
|
|
2971
|
+
C2S: "P2",
|
|
2972
|
+
C2L: "P2",
|
|
2973
|
+
C2X: "P2",
|
|
2974
|
+
C2W: "P2",
|
|
2975
|
+
C2P: "P2",
|
|
2976
|
+
C5I: "C5",
|
|
2977
|
+
C5Q: "C5",
|
|
2978
|
+
C5X: "C5",
|
|
2979
|
+
L1C: "L1",
|
|
2980
|
+
L1S: "L1",
|
|
2981
|
+
L1L: "L1",
|
|
2982
|
+
L1X: "L1",
|
|
2983
|
+
L1W: "L1",
|
|
2984
|
+
L1P: "L1",
|
|
2985
|
+
L2C: "L2",
|
|
2986
|
+
L2S: "L2",
|
|
2987
|
+
L2L: "L2",
|
|
2988
|
+
L2X: "L2",
|
|
2989
|
+
L2W: "L2",
|
|
2990
|
+
L2P: "L2",
|
|
2991
|
+
L5I: "L5",
|
|
2992
|
+
L5Q: "L5",
|
|
2993
|
+
L5X: "L5",
|
|
2994
|
+
D1C: "D1",
|
|
2995
|
+
D1S: "D1",
|
|
2996
|
+
D1L: "D1",
|
|
2997
|
+
D1X: "D1",
|
|
2998
|
+
D1W: "D1",
|
|
2999
|
+
D1P: "D1",
|
|
3000
|
+
D2C: "D2",
|
|
3001
|
+
D2S: "D2",
|
|
3002
|
+
D2L: "D2",
|
|
3003
|
+
D2X: "D2",
|
|
3004
|
+
D2W: "D2",
|
|
3005
|
+
D2P: "D2",
|
|
3006
|
+
D5I: "D5",
|
|
3007
|
+
D5Q: "D5",
|
|
3008
|
+
D5X: "D5",
|
|
3009
|
+
S1C: "S1",
|
|
3010
|
+
S1S: "S1",
|
|
3011
|
+
S1L: "S1",
|
|
3012
|
+
S1X: "S1",
|
|
3013
|
+
S1W: "S1",
|
|
3014
|
+
S1P: "S1",
|
|
3015
|
+
S2C: "S2",
|
|
3016
|
+
S2S: "S2",
|
|
3017
|
+
S2L: "S2",
|
|
3018
|
+
S2X: "S2",
|
|
3019
|
+
S2W: "S2",
|
|
3020
|
+
S2P: "S2",
|
|
3021
|
+
S5I: "S5",
|
|
3022
|
+
S5Q: "S5",
|
|
3023
|
+
S5X: "S5"
|
|
3024
|
+
};
|
|
3025
|
+
function v3ToV2Code(code3) {
|
|
3026
|
+
return V3_TO_V2[code3] ?? null;
|
|
3027
|
+
}
|
|
3028
|
+
async function writeRinex2ObsBlob(header, epochs, obsTypes) {
|
|
3029
|
+
if (epochs.length === 0) return new Blob([], { type: "application/gzip" });
|
|
3030
|
+
const gpsCodes = obsTypes.get("G") ?? obsTypes.get("R") ?? [];
|
|
3031
|
+
const v2Codes = [];
|
|
3032
|
+
const v2CodeSet = /* @__PURE__ */ new Set();
|
|
3033
|
+
const v3ToV2Map = /* @__PURE__ */ new Map();
|
|
3034
|
+
for (const code3 of gpsCodes) {
|
|
3035
|
+
const code2 = v3ToV2Code(code3);
|
|
3036
|
+
if (!code2) continue;
|
|
3037
|
+
if (!v2CodeSet.has(code2)) {
|
|
3038
|
+
v2CodeSet.add(code2);
|
|
3039
|
+
v3ToV2Map.set(code3, v2Codes.length);
|
|
3040
|
+
v2Codes.push(code2);
|
|
3041
|
+
} else {
|
|
3042
|
+
v3ToV2Map.set(code3, v2Codes.indexOf(code2));
|
|
3043
|
+
}
|
|
3044
|
+
}
|
|
3045
|
+
const gloCodes = obsTypes.get("R") ?? [];
|
|
3046
|
+
for (const code3 of gloCodes) {
|
|
3047
|
+
const code2 = v3ToV2Code(code3);
|
|
3048
|
+
if (!code2) continue;
|
|
3049
|
+
if (!v2CodeSet.has(code2)) {
|
|
3050
|
+
v2CodeSet.add(code2);
|
|
3051
|
+
v3ToV2Map.set(code3, v2Codes.length);
|
|
3052
|
+
v2Codes.push(code2);
|
|
3053
|
+
} else if (!v3ToV2Map.has(code3)) {
|
|
3054
|
+
v3ToV2Map.set(code3, v2Codes.indexOf(code2));
|
|
3055
|
+
}
|
|
3056
|
+
}
|
|
3057
|
+
const sink = createGzipLineSink();
|
|
3058
|
+
const BATCH = 200;
|
|
3059
|
+
const hasSystems = /* @__PURE__ */ new Set();
|
|
3060
|
+
for (const epoch of epochs) {
|
|
3061
|
+
for (const prn of epoch.sats.keys()) {
|
|
3062
|
+
const sys = prn[0];
|
|
3063
|
+
if (sys === "G" || sys === "R") hasSystems.add(sys);
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
const sysChar = hasSystems.has("G") && hasSystems.has("R") ? "M" : hasSystems.has("R") ? "R" : "G";
|
|
3067
|
+
sink.push(
|
|
3068
|
+
hdrLine(
|
|
3069
|
+
` 2.11 OBSERVATION DATA ${sysChar}`,
|
|
3070
|
+
"RINEX VERSION / TYPE"
|
|
3071
|
+
)
|
|
3072
|
+
);
|
|
3073
|
+
const now = /* @__PURE__ */ new Date();
|
|
3074
|
+
const dateStr = `${now.getUTCFullYear()}-${String(now.getUTCMonth() + 1).padStart(2, "0")}-${String(now.getUTCDate()).padStart(2, "0")} ${String(now.getUTCHours()).padStart(2, "0")}:${String(now.getUTCMinutes()).padStart(2, "0")}:${String(now.getUTCSeconds()).padStart(2, "0")}`;
|
|
3075
|
+
sink.push(
|
|
3076
|
+
hdrLine(
|
|
3077
|
+
`${padL("GNSSCalc", 20)}${padL("", 20)}${dateStr}`,
|
|
3078
|
+
"PGM / RUN BY / DATE"
|
|
3079
|
+
)
|
|
3080
|
+
);
|
|
3081
|
+
sink.push(hdrLine("Converted from RINEX 3 by GNSSCalc", "COMMENT"));
|
|
3082
|
+
for (const line of stationHeaderLines(header)) sink.push(line);
|
|
3083
|
+
sink.push(hdrLine(" 1 1", "WAVELENGTH FACT L1/2"));
|
|
3084
|
+
for (let i = 0; i < v2Codes.length; i += 9) {
|
|
3085
|
+
const chunk = v2Codes.slice(i, i + 9);
|
|
3086
|
+
let content;
|
|
3087
|
+
if (i === 0) {
|
|
3088
|
+
content = padR(String(v2Codes.length), 6);
|
|
3089
|
+
} else {
|
|
3090
|
+
content = " ";
|
|
3091
|
+
}
|
|
3092
|
+
content += chunk.map((c) => padR(c, 6)).join("");
|
|
3093
|
+
sink.push(hdrLine(content, "# / TYPES OF OBSERV"));
|
|
3094
|
+
}
|
|
3095
|
+
const first = new Date(epochs[0].time);
|
|
3096
|
+
const timeSys = sysChar === "R" ? "GLO" : "GPS";
|
|
3097
|
+
sink.push(
|
|
3098
|
+
hdrLine(
|
|
3099
|
+
` ${first.getUTCFullYear()} ${String(first.getUTCMonth() + 1).padStart(2)} ${String(first.getUTCDate()).padStart(2)} ${String(first.getUTCHours()).padStart(2)} ${String(first.getUTCMinutes()).padStart(2)} ${(first.getUTCSeconds() + first.getUTCMilliseconds() / 1e3).toFixed(7).padStart(10)} ${timeSys}`,
|
|
3100
|
+
"TIME OF FIRST OBS"
|
|
3101
|
+
)
|
|
3102
|
+
);
|
|
3103
|
+
sink.push(hdrLine("", "END OF HEADER"));
|
|
3104
|
+
await sink.flush();
|
|
3105
|
+
let epochCount = 0;
|
|
3106
|
+
for (const epoch of epochs) {
|
|
3107
|
+
const t = new Date(epoch.time);
|
|
3108
|
+
const sec = t.getUTCSeconds() + t.getUTCMilliseconds() / 1e3;
|
|
3109
|
+
const prns = [...epoch.sats.keys()].filter((p) => p[0] === "G" || p[0] === "R").sort();
|
|
3110
|
+
if (prns.length === 0) continue;
|
|
3111
|
+
const yy = t.getUTCFullYear() % 100;
|
|
3112
|
+
const yyS = padR(String(yy), 2);
|
|
3113
|
+
const moS = padR(String(t.getUTCMonth() + 1), 2);
|
|
3114
|
+
const ddS = padR(String(t.getUTCDate()), 2);
|
|
3115
|
+
const hhS = padR(String(t.getUTCHours()), 2);
|
|
3116
|
+
const mmS = padR(String(t.getUTCMinutes()), 2);
|
|
3117
|
+
const secS = fmtF(sec, 11, 7);
|
|
3118
|
+
const nSats = padR(String(prns.length), 3);
|
|
3119
|
+
let epochLine = ` ${yyS} ${moS} ${ddS} ${hhS} ${mmS}${secS} 0${nSats}`;
|
|
3120
|
+
for (let i = 0; i < prns.length; i++) {
|
|
3121
|
+
if (i > 0 && i % 12 === 0) {
|
|
3122
|
+
sink.push(epochLine);
|
|
3123
|
+
epochLine = " ".repeat(32);
|
|
3124
|
+
}
|
|
3125
|
+
epochLine += prns[i];
|
|
3126
|
+
}
|
|
3127
|
+
sink.push(epochLine);
|
|
3128
|
+
for (const prn of prns) {
|
|
3129
|
+
const sys = prn[0];
|
|
3130
|
+
const sysCodes3 = obsTypes.get(sys) ?? [];
|
|
3131
|
+
const valArr = epoch.sats.get(prn);
|
|
3132
|
+
const v2Vals = new Array(v2Codes.length).fill(NaN);
|
|
3133
|
+
for (let j = 0; j < sysCodes3.length; j++) {
|
|
3134
|
+
const v2Idx = v3ToV2Map.get(sysCodes3[j]);
|
|
3135
|
+
if (v2Idx != null && j < valArr.length && !isNaN(valArr[j])) {
|
|
3136
|
+
v2Vals[v2Idx] = valArr[j];
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
let line = "";
|
|
3140
|
+
for (let j = 0; j < v2Codes.length; j++) {
|
|
3141
|
+
const val = v2Vals[j];
|
|
3142
|
+
if (!isNaN(val)) {
|
|
3143
|
+
line += fmtF(val, 14, 3) + " ";
|
|
3144
|
+
} else {
|
|
3145
|
+
line += " ".repeat(16);
|
|
3146
|
+
}
|
|
3147
|
+
if ((j + 1) % 5 === 0 || j === v2Codes.length - 1) {
|
|
3148
|
+
sink.push(line);
|
|
3149
|
+
line = "";
|
|
3150
|
+
}
|
|
3151
|
+
}
|
|
3152
|
+
}
|
|
3153
|
+
epochCount++;
|
|
3154
|
+
if (epochCount % BATCH === 0) await sink.flush();
|
|
3155
|
+
}
|
|
3156
|
+
return sink.finish();
|
|
3157
|
+
}
|
|
3158
|
+
|
|
3159
|
+
// src/rinex/obs-writer-v4.ts
|
|
3160
|
+
function writeRinex4ObsBlob(header, epochs, obsTypes) {
|
|
3161
|
+
return writeModernObsBlob(header, epochs, obsTypes, {
|
|
3162
|
+
version: "4.01",
|
|
3163
|
+
comment: "Converted to RINEX 4 by GNSSCalc"
|
|
3164
|
+
});
|
|
3165
|
+
}
|
|
3166
|
+
|
|
2668
3167
|
// src/rtcm3/decoder.ts
|
|
2669
3168
|
var debugHandler = null;
|
|
2670
3169
|
function setRtcm3DebugHandler(fn) {
|
|
@@ -4585,8 +5084,14 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
4585
5084
|
const stepMs = stepSec * 1e3;
|
|
4586
5085
|
const times = [];
|
|
4587
5086
|
for (let t = startMs; t <= endMs; t += stepMs) times.push(t);
|
|
5087
|
+
return computeVisibilityFromPositions(
|
|
5088
|
+
computeAllPositions(ephemerides, times, rxPos),
|
|
5089
|
+
elevationMaskDeg
|
|
5090
|
+
);
|
|
5091
|
+
}
|
|
5092
|
+
function computeVisibilityFromPositions(all, elevationMaskDeg = 10) {
|
|
5093
|
+
const times = all.times;
|
|
4588
5094
|
const maskRadFor = maskRadForAzimuth(elevationMaskDeg);
|
|
4589
|
-
const all = computeAllPositions(ephemerides, times, rxPos);
|
|
4590
5095
|
const elevation = {};
|
|
4591
5096
|
const azimuth = {};
|
|
4592
5097
|
const subLat = {};
|
|
@@ -7487,7 +7992,9 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
7487
7992
|
computeSatPosition,
|
|
7488
7993
|
computeStats,
|
|
7489
7994
|
computeVisibility,
|
|
7995
|
+
computeVisibilityFromPositions,
|
|
7490
7996
|
connectToMountpoint,
|
|
7997
|
+
createGzipLineSink,
|
|
7491
7998
|
createStationMeta,
|
|
7492
7999
|
createStreamStats,
|
|
7493
8000
|
crxDecompress,
|
|
@@ -7586,6 +8093,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
7586
8093
|
parseRinexStream,
|
|
7587
8094
|
parseSinexBiasDcb,
|
|
7588
8095
|
parseSourcetable,
|
|
8096
|
+
parseSp3,
|
|
7589
8097
|
phiAltBOC,
|
|
7590
8098
|
phiBOCc,
|
|
7591
8099
|
phiBOCs,
|
|
@@ -7602,6 +8110,8 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
7602
8110
|
setGloFreqNumber,
|
|
7603
8111
|
setRtcm3DebugHandler,
|
|
7604
8112
|
solveSpp,
|
|
8113
|
+
sp3Position,
|
|
8114
|
+
stationHeaderLines,
|
|
7605
8115
|
systemCmp,
|
|
7606
8116
|
systemName,
|
|
7607
8117
|
transformFrame,
|
|
@@ -7609,5 +8119,9 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
7609
8119
|
updateStreamStats,
|
|
7610
8120
|
verifyChecksum,
|
|
7611
8121
|
vincenty,
|
|
7612
|
-
|
|
8122
|
+
writeModernObsBlob,
|
|
8123
|
+
writeRinex2ObsBlob,
|
|
8124
|
+
writeRinex4ObsBlob,
|
|
8125
|
+
writeRinexNav,
|
|
8126
|
+
writeRinexObsBlob
|
|
7613
8127
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -4,12 +4,12 @@ export { A as ARC_GAP_FACTOR, B as BAND_LABELS, a as BDS_SATELLITES, b as BdsSat
|
|
|
4
4
|
export { Scale, getBdsTime, getDateFromBdsTime, getDateFromDayOfWeek, getDateFromDayOfYear, getDateFromGalTime, getDateFromGloN, getDateFromGpsData, getDateFromGpsTime, getDateFromHourCode, getDateFromJulianDate, getDateFromMJD, getDateFromMJD2000, getDateFromRINEX, getDateFromTai, getDateFromTimeOfDay, getDateFromTt, getDateFromUnixTime, getDateFromUtc, getDayOfWeek, getDayOfYear, getGalTime, getGloN4, getGloNA, getGpsLeap, getGpsTime, getHourCode, getHoursFromTimeDifference, getJulianDate, getLeap, getMJD, getMJD2000, getMinutesFromTimeDifference, getNtpTime, getRINEX, getSecondsFromTimeDifference, getTaiDate, getTimeDifference, getTimeDifferenceFromDays, getTimeDifferenceFromHours, getTimeDifferenceFromMinutes, getTimeDifferenceFromObject, getTimeDifferenceFromSeconds, getTimeOfDay, getTimeOfWeek, getTotalDaysFromTimeDifference, getTtDate, getUnixTime, getUtcDate, getWeekNumber, getWeekOfYear } from './time.cjs';
|
|
5
5
|
export { deg2dms, deg2rad, euclidean3D, geodeticToGeohash, geodeticToMaidenhead, geodeticToUtm, greatCircleMidpoint, horizonDistance, rad2deg, rhumbLine, vincenty } from './coordinates.cjs';
|
|
6
6
|
export { c as clampUnit, e as ecefToGeodetic, g as geodeticToEcef, a as getAer, b as getEnuDifference } from './ecef-CF0uAysr.cjs';
|
|
7
|
-
export { CrxField, DiffState, EMPTY_WARNINGS, IonexGrid, RinexWarning, RinexWarnings, WarningAccumulator, WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseIonex, writeRinexNav } from './rinex.cjs';
|
|
7
|
+
export { CompactEpoch, CrxField, DiffState, EMPTY_WARNINGS, IonexGrid, RinexWarning, RinexWarnings, Sp3File, Sp3Sample, WarningAccumulator, WarningSeverity, createGzipLineSink, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseIonex, parseSp3, sp3Position, stationHeaderLines, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexObsBlob } 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
10
|
export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.cjs';
|
|
11
11
|
export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.cjs';
|
|
12
|
-
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.cjs';
|
|
12
|
+
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, computeVisibilityFromPositions, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.cjs';
|
|
13
13
|
export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.cjs';
|
|
14
14
|
export { KlobucharCoeffs, SppOptions, SppSolution, ionoFree, klobucharDelay, satClockCorrection, solveSpp } from './positioning.cjs';
|
|
15
15
|
export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -4,12 +4,12 @@ export { A as ARC_GAP_FACTOR, B as BAND_LABELS, a as BDS_SATELLITES, b as BdsSat
|
|
|
4
4
|
export { Scale, getBdsTime, getDateFromBdsTime, getDateFromDayOfWeek, getDateFromDayOfYear, getDateFromGalTime, getDateFromGloN, getDateFromGpsData, getDateFromGpsTime, getDateFromHourCode, getDateFromJulianDate, getDateFromMJD, getDateFromMJD2000, getDateFromRINEX, getDateFromTai, getDateFromTimeOfDay, getDateFromTt, getDateFromUnixTime, getDateFromUtc, getDayOfWeek, getDayOfYear, getGalTime, getGloN4, getGloNA, getGpsLeap, getGpsTime, getHourCode, getHoursFromTimeDifference, getJulianDate, getLeap, getMJD, getMJD2000, getMinutesFromTimeDifference, getNtpTime, getRINEX, getSecondsFromTimeDifference, getTaiDate, getTimeDifference, getTimeDifferenceFromDays, getTimeDifferenceFromHours, getTimeDifferenceFromMinutes, getTimeDifferenceFromObject, getTimeDifferenceFromSeconds, getTimeOfDay, getTimeOfWeek, getTotalDaysFromTimeDifference, getTtDate, getUnixTime, getUtcDate, getWeekNumber, getWeekOfYear } from './time.js';
|
|
5
5
|
export { deg2dms, deg2rad, euclidean3D, geodeticToGeohash, geodeticToMaidenhead, geodeticToUtm, greatCircleMidpoint, horizonDistance, rad2deg, rhumbLine, vincenty } from './coordinates.js';
|
|
6
6
|
export { c as clampUnit, e as ecefToGeodetic, g as geodeticToEcef, a as getAer, b as getEnuDifference } from './ecef-CF0uAysr.js';
|
|
7
|
-
export { CrxField, DiffState, EMPTY_WARNINGS, IonexGrid, RinexWarning, RinexWarnings, WarningAccumulator, WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseIonex, writeRinexNav } from './rinex.js';
|
|
7
|
+
export { CompactEpoch, CrxField, DiffState, EMPTY_WARNINGS, IonexGrid, RinexWarning, RinexWarnings, Sp3File, Sp3Sample, WarningAccumulator, WarningSeverity, createGzipLineSink, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseIonex, parseSp3, sp3Position, stationHeaderLines, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexObsBlob } 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
10
|
export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.js';
|
|
11
11
|
export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.js';
|
|
12
|
-
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.js';
|
|
12
|
+
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, computeVisibilityFromPositions, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.js';
|
|
13
13
|
export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.js';
|
|
14
14
|
export { KlobucharCoeffs, SppOptions, SppSolution, ionoFree, klobucharDelay, satClockCorrection, solveSpp } from './positioning.js';
|
|
15
15
|
export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.js';
|