gnss-js 1.16.0 → 1.17.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-R33A2VA7.js → chunk-7QR2KPDU.js} +188 -12
- package/dist/{chunk-6CX6EXRK.js → chunk-IG5CDNDS.js} +58 -23
- package/dist/{chunk-4LVD4DYL.js → chunk-REYOYF7O.js} +1 -0
- package/dist/{chunk-YPOVPXNK.js → chunk-ZNCQNHNI.js} +34 -0
- package/dist/index.cjs +283 -37
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -4
- package/dist/novatel.cjs +187 -11
- package/dist/novatel.d.cts +36 -13
- package/dist/novatel.d.ts +36 -13
- package/dist/novatel.js +2 -2
- package/dist/sbf.cjs +35 -0
- package/dist/sbf.d.cts +41 -1
- package/dist/sbf.d.ts +41 -1
- package/dist/sbf.js +3 -1
- package/dist/ubx.cjs +57 -22
- package/dist/ubx.d.cts +42 -2
- package/dist/ubx.d.ts +42 -2
- package/dist/ubx.js +4 -2
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
decodeGpsLnavFrame
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-REYOYF7O.js";
|
|
4
4
|
import {
|
|
5
5
|
getUtcDate
|
|
6
6
|
} from "./chunk-HVXYFUCB.js";
|
|
@@ -50,11 +50,26 @@ function* oem4Frames(data, view, stats) {
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
// src/novatel/nav.ts
|
|
53
|
+
var ID_IONUTC = 8;
|
|
53
54
|
var ID_RAWEPHEM = 41;
|
|
54
55
|
var ID_GLOEPHEMERIS = 723;
|
|
56
|
+
var ID_GALEPHEMERIS = 1122;
|
|
57
|
+
var ID_QZSSEPHEMERIS = 1336;
|
|
58
|
+
var ID_BDSEPHEMERIS = 1696;
|
|
55
59
|
var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
|
|
60
|
+
var BDT_EPOCH_MS = Date.UTC(2006, 0, 1);
|
|
56
61
|
var SEC_PER_WEEK = 7 * 86400;
|
|
57
62
|
var SEC_PER_DAY = 86400;
|
|
63
|
+
var MS_PER_WEEK = SEC_PER_WEEK * 1e3;
|
|
64
|
+
var gpsMs = (week, sec) => GPS_EPOCH_MS + week * MS_PER_WEEK + sec * 1e3;
|
|
65
|
+
var sowOf = (dateMs) => dateMs / 1e3 % SEC_PER_WEEK;
|
|
66
|
+
function nearWeekMs(refMs, sow) {
|
|
67
|
+
const refWeek = Math.floor((refMs - GPS_EPOCH_MS) / MS_PER_WEEK);
|
|
68
|
+
let ms = gpsMs(refWeek, sow);
|
|
69
|
+
if (ms < refMs - MS_PER_WEEK / 2) ms += MS_PER_WEEK;
|
|
70
|
+
else if (ms > refMs + MS_PER_WEEK / 2) ms -= MS_PER_WEEK;
|
|
71
|
+
return ms;
|
|
72
|
+
}
|
|
58
73
|
function decodeRawEphem(data, view, p) {
|
|
59
74
|
const prn = view.getUint32(p, true);
|
|
60
75
|
if (prn < 1 || prn > 32) return null;
|
|
@@ -100,23 +115,184 @@ function decodeGloEphemeris(view, p) {
|
|
|
100
115
|
freqNum
|
|
101
116
|
};
|
|
102
117
|
}
|
|
118
|
+
function decodeGalEphemeris(view, p, headerMs) {
|
|
119
|
+
const prn = view.getUint32(p, true);
|
|
120
|
+
if (prn < 1 || prn > 36) return null;
|
|
121
|
+
const fnav = (view.getUint32(p + 4, true) & 1) !== 0;
|
|
122
|
+
const svhE1b = view.getUint8(p + 12) & 3;
|
|
123
|
+
const svhE5a = view.getUint8(p + 13) & 3;
|
|
124
|
+
const svhE5b = view.getUint8(p + 14) & 3;
|
|
125
|
+
const dvsE1b = view.getUint8(p + 15) & 1;
|
|
126
|
+
const dvsE5a = view.getUint8(p + 16) & 1;
|
|
127
|
+
const dvsE5b = view.getUint8(p + 17) & 1;
|
|
128
|
+
const iodNav = view.getUint32(p + 20, true);
|
|
129
|
+
const toes = view.getUint32(p + 24, true);
|
|
130
|
+
const c = fnav ? p + 148 : p + 176;
|
|
131
|
+
const tocs = view.getUint32(c, true);
|
|
132
|
+
const toeMs = nearWeekMs(headerMs, toes);
|
|
133
|
+
const tocDate = new Date(nearWeekMs(headerMs, tocs));
|
|
134
|
+
return {
|
|
135
|
+
fnav,
|
|
136
|
+
eph: {
|
|
137
|
+
system: "E",
|
|
138
|
+
prn: `E${String(prn).padStart(2, "0")}`,
|
|
139
|
+
toc: sowOf(tocDate.getTime()),
|
|
140
|
+
tocDate,
|
|
141
|
+
af0: view.getFloat64(c + 4, true),
|
|
142
|
+
af1: view.getFloat64(c + 12, true),
|
|
143
|
+
af2: view.getFloat64(c + 20, true),
|
|
144
|
+
iode: iodNav,
|
|
145
|
+
crs: view.getFloat64(p + 92, true),
|
|
146
|
+
deltaN: view.getFloat64(p + 36, true),
|
|
147
|
+
m0: view.getFloat64(p + 44, true),
|
|
148
|
+
cuc: view.getFloat64(p + 68, true),
|
|
149
|
+
e: view.getFloat64(p + 52, true),
|
|
150
|
+
cus: view.getFloat64(p + 76, true),
|
|
151
|
+
sqrtA: view.getFloat64(p + 28, true),
|
|
152
|
+
toe: toes,
|
|
153
|
+
cic: view.getFloat64(p + 100, true),
|
|
154
|
+
omega0: view.getFloat64(p + 132, true),
|
|
155
|
+
cis: view.getFloat64(p + 108, true),
|
|
156
|
+
i0: view.getFloat64(p + 116, true),
|
|
157
|
+
crc: view.getFloat64(p + 84, true),
|
|
158
|
+
omega: view.getFloat64(p + 60, true),
|
|
159
|
+
omegaDot: view.getFloat64(p + 140, true),
|
|
160
|
+
idot: view.getFloat64(p + 124, true),
|
|
161
|
+
week: Math.floor((toeMs - GPS_EPOCH_MS) / MS_PER_WEEK),
|
|
162
|
+
// RINEX Galileo SVH bit layout (E1B DVS/HS in bits 0-2, E5a in
|
|
163
|
+
// 3-5, E5b in 6-8) — same packing as RTKLIB.
|
|
164
|
+
svHealth: svhE5b << 7 | dvsE5b << 6 | svhE5a << 4 | dvsE5a << 3 | svhE1b << 1 | dvsE1b,
|
|
165
|
+
tgd: view.getFloat64(p + 204, true)
|
|
166
|
+
// BGD E5a/E1 (RINEX slot)
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
function decodeBdsEphemeris(view, p) {
|
|
171
|
+
const prn = view.getUint32(p, true);
|
|
172
|
+
if (prn < 1 || prn > 63) return null;
|
|
173
|
+
const week = view.getUint32(p + 4, true);
|
|
174
|
+
const health = view.getUint32(p + 16, true) & 1;
|
|
175
|
+
const tgd1 = view.getFloat64(p + 20, true);
|
|
176
|
+
const tocs = view.getUint32(p + 40, true);
|
|
177
|
+
const toes = view.getUint32(p + 72, true);
|
|
178
|
+
const tocDate = new Date(BDT_EPOCH_MS + week * MS_PER_WEEK + tocs * 1e3);
|
|
179
|
+
return {
|
|
180
|
+
system: "C",
|
|
181
|
+
prn: `C${String(prn).padStart(2, "0")}`,
|
|
182
|
+
toc: sowOf(tocDate.getTime()),
|
|
183
|
+
tocDate,
|
|
184
|
+
af0: view.getFloat64(p + 44, true),
|
|
185
|
+
af1: view.getFloat64(p + 52, true),
|
|
186
|
+
af2: view.getFloat64(p + 60, true),
|
|
187
|
+
iode: view.getUint32(p + 68, true),
|
|
188
|
+
// AODE
|
|
189
|
+
crs: view.getFloat64(p + 172, true),
|
|
190
|
+
deltaN: view.getFloat64(p + 100, true),
|
|
191
|
+
m0: view.getFloat64(p + 108, true),
|
|
192
|
+
cuc: view.getFloat64(p + 148, true),
|
|
193
|
+
e: view.getFloat64(p + 84, true),
|
|
194
|
+
cus: view.getFloat64(p + 156, true),
|
|
195
|
+
sqrtA: view.getFloat64(p + 76, true),
|
|
196
|
+
toe: toes,
|
|
197
|
+
cic: view.getFloat64(p + 180, true),
|
|
198
|
+
omega0: view.getFloat64(p + 116, true),
|
|
199
|
+
cis: view.getFloat64(p + 188, true),
|
|
200
|
+
i0: view.getFloat64(p + 132, true),
|
|
201
|
+
crc: view.getFloat64(p + 164, true),
|
|
202
|
+
omega: view.getFloat64(p + 92, true),
|
|
203
|
+
omegaDot: view.getFloat64(p + 124, true),
|
|
204
|
+
idot: view.getFloat64(p + 140, true),
|
|
205
|
+
week,
|
|
206
|
+
// RINEX BDS week field is the BDT week
|
|
207
|
+
svHealth: health,
|
|
208
|
+
tgd: tgd1
|
|
209
|
+
// TGD1 (B1) — RINEX slot
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
function decodeQzssEphemeris(view, p) {
|
|
213
|
+
const prn = view.getUint32(p, true);
|
|
214
|
+
if (prn < 193 || prn > 202) return null;
|
|
215
|
+
const health = view.getUint32(p + 12, true) & 63;
|
|
216
|
+
const iode1 = view.getUint32(p + 16, true);
|
|
217
|
+
const week = view.getUint32(p + 24, true);
|
|
218
|
+
const toes = view.getFloat64(p + 32, true);
|
|
219
|
+
const toeMs = gpsMs(week, toes);
|
|
220
|
+
const tocs = view.getFloat64(p + 164, true);
|
|
221
|
+
const tocDate = new Date(nearWeekMs(toeMs, tocs));
|
|
222
|
+
return {
|
|
223
|
+
system: "J",
|
|
224
|
+
prn: `J${String(prn - 192).padStart(2, "0")}`,
|
|
225
|
+
toc: sowOf(tocDate.getTime()),
|
|
226
|
+
tocDate,
|
|
227
|
+
af0: view.getFloat64(p + 180, true),
|
|
228
|
+
af1: view.getFloat64(p + 188, true),
|
|
229
|
+
af2: view.getFloat64(p + 196, true),
|
|
230
|
+
iode: iode1,
|
|
231
|
+
crs: view.getFloat64(p + 104, true),
|
|
232
|
+
deltaN: view.getFloat64(p + 48, true),
|
|
233
|
+
m0: view.getFloat64(p + 56, true),
|
|
234
|
+
cuc: view.getFloat64(p + 80, true),
|
|
235
|
+
e: view.getFloat64(p + 64, true),
|
|
236
|
+
cus: view.getFloat64(p + 88, true),
|
|
237
|
+
sqrtA: Math.sqrt(view.getFloat64(p + 40, true)),
|
|
238
|
+
toe: toes,
|
|
239
|
+
cic: view.getFloat64(p + 112, true),
|
|
240
|
+
omega0: view.getFloat64(p + 144, true),
|
|
241
|
+
cis: view.getFloat64(p + 120, true),
|
|
242
|
+
i0: view.getFloat64(p + 128, true),
|
|
243
|
+
crc: view.getFloat64(p + 96, true),
|
|
244
|
+
omega: view.getFloat64(p + 72, true),
|
|
245
|
+
omegaDot: view.getFloat64(p + 152, true),
|
|
246
|
+
idot: view.getFloat64(p + 136, true),
|
|
247
|
+
week,
|
|
248
|
+
svHealth: health,
|
|
249
|
+
tgd: view.getFloat64(p + 172, true)
|
|
250
|
+
};
|
|
251
|
+
}
|
|
103
252
|
function parseNovatelNav(data) {
|
|
104
253
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
105
254
|
const stats = { badCrc: 0 };
|
|
106
255
|
const ephemerides = [];
|
|
107
|
-
const
|
|
256
|
+
const ionoCorrections = {};
|
|
257
|
+
let leapSeconds = null;
|
|
258
|
+
const lastKep = /* @__PURE__ */ new Map();
|
|
108
259
|
const lastGlo = /* @__PURE__ */ new Map();
|
|
260
|
+
const pushKepler = (key, eph) => {
|
|
261
|
+
const prev = lastKep.get(key);
|
|
262
|
+
if (prev && prev.iode === eph.iode && prev.toe === eph.toe && prev.tocDate.getTime() === eph.tocDate.getTime()) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
lastKep.set(key, eph);
|
|
266
|
+
ephemerides.push(eph);
|
|
267
|
+
};
|
|
109
268
|
for (const frame of oem4Frames(data, view, stats)) {
|
|
110
269
|
if (!frame.binary) continue;
|
|
111
270
|
if (frame.id === ID_RAWEPHEM && frame.msgLen >= 102) {
|
|
112
271
|
const eph = decodeRawEphem(data, view, frame.payload);
|
|
113
|
-
if (
|
|
114
|
-
|
|
115
|
-
if (
|
|
116
|
-
|
|
272
|
+
if (eph) pushKepler(eph.prn, eph);
|
|
273
|
+
} else if (frame.id === ID_GALEPHEMERIS && frame.msgLen >= 220) {
|
|
274
|
+
if (frame.week === 0) continue;
|
|
275
|
+
const headerMs = gpsMs(frame.week, frame.towMs / 1e3);
|
|
276
|
+
const dec = decodeGalEphemeris(view, frame.payload, headerMs);
|
|
277
|
+
if (dec)
|
|
278
|
+
pushKepler(`${dec.eph.prn}:${dec.fnav ? "fnav" : "inav"}`, dec.eph);
|
|
279
|
+
} else if (frame.id === ID_BDSEPHEMERIS && frame.msgLen >= 196) {
|
|
280
|
+
const eph = decodeBdsEphemeris(view, frame.payload);
|
|
281
|
+
if (eph) pushKepler(eph.prn, eph);
|
|
282
|
+
} else if (frame.id === ID_QZSSEPHEMERIS && frame.msgLen >= 204) {
|
|
283
|
+
const eph = decodeQzssEphemeris(view, frame.payload);
|
|
284
|
+
if (eph) pushKepler(eph.prn, eph);
|
|
285
|
+
} else if (frame.id === ID_IONUTC && frame.msgLen >= 108) {
|
|
286
|
+
const p = frame.payload;
|
|
287
|
+
const alpha = [];
|
|
288
|
+
const beta = [];
|
|
289
|
+
for (let i = 0; i < 4; i++) {
|
|
290
|
+
alpha.push(view.getFloat64(p + i * 8, true));
|
|
291
|
+
beta.push(view.getFloat64(p + 32 + i * 8, true));
|
|
117
292
|
}
|
|
118
|
-
|
|
119
|
-
|
|
293
|
+
ionoCorrections["GPSA"] = alpha;
|
|
294
|
+
ionoCorrections["GPSB"] = beta;
|
|
295
|
+
leapSeconds = view.getInt32(p + 96, true);
|
|
120
296
|
} else if (frame.id === ID_GLOEPHEMERIS && frame.msgLen >= 144) {
|
|
121
297
|
const eph = decodeGloEphemeris(view, frame.payload);
|
|
122
298
|
if (!eph) continue;
|
|
@@ -128,12 +304,12 @@ function parseNovatelNav(data) {
|
|
|
128
304
|
ephemerides.push(eph);
|
|
129
305
|
}
|
|
130
306
|
}
|
|
131
|
-
return { ephemerides, badCrc: stats.badCrc };
|
|
307
|
+
return { ephemerides, ionoCorrections, leapSeconds, badCrc: stats.badCrc };
|
|
132
308
|
}
|
|
133
309
|
|
|
134
310
|
// src/novatel/index.ts
|
|
135
311
|
var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
|
|
136
|
-
var
|
|
312
|
+
var MS_PER_WEEK2 = 7 * 864e5;
|
|
137
313
|
var HDR = 28;
|
|
138
314
|
var ID_RANGE = 43;
|
|
139
315
|
var ID_RANGECMP = 140;
|
|
@@ -302,7 +478,7 @@ function parseNovatelRange(data) {
|
|
|
302
478
|
if (!codes.includes(code)) codes.push(code);
|
|
303
479
|
}
|
|
304
480
|
epochs.push({
|
|
305
|
-
timeMs: GPS_EPOCH_MS2 + week *
|
|
481
|
+
timeMs: GPS_EPOCH_MS2 + week * MS_PER_WEEK2 + towMs,
|
|
306
482
|
meas
|
|
307
483
|
});
|
|
308
484
|
}
|
|
@@ -354,7 +530,7 @@ function parseNovatelRange(data) {
|
|
|
354
530
|
if (!codes.includes(code)) codes.push(code);
|
|
355
531
|
}
|
|
356
532
|
epochs.push({
|
|
357
|
-
timeMs: GPS_EPOCH_MS2 + week *
|
|
533
|
+
timeMs: GPS_EPOCH_MS2 + week * MS_PER_WEEK2 + towMs,
|
|
358
534
|
meas
|
|
359
535
|
});
|
|
360
536
|
}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
decodeGpsLnavFrame,
|
|
3
|
+
getBitS,
|
|
3
4
|
getBitU,
|
|
4
5
|
setBitU
|
|
5
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-REYOYF7O.js";
|
|
6
7
|
|
|
7
8
|
// src/ubx/frame.ts
|
|
8
9
|
function* ubxFrames(data, stats = { badChecksums: 0 }) {
|
|
@@ -38,6 +39,30 @@ function* ubxFrames(data, stats = { badChecksums: 0 }) {
|
|
|
38
39
|
|
|
39
40
|
// src/ubx/nav.ts
|
|
40
41
|
var PREAMB_CNAV = 139;
|
|
42
|
+
function readLnavSubframe(view, f) {
|
|
43
|
+
const p = f.payload;
|
|
44
|
+
if (p.length < 8) return null;
|
|
45
|
+
const gnssId = p[0];
|
|
46
|
+
const svId = p[1];
|
|
47
|
+
let prn;
|
|
48
|
+
if (gnssId === 0 && svId >= 1 && svId <= 32) {
|
|
49
|
+
prn = `G${String(svId).padStart(2, "0")}`;
|
|
50
|
+
} else if (gnssId === 5 && svId >= 1 && svId <= 10) {
|
|
51
|
+
if (p.length === 44) return null;
|
|
52
|
+
prn = `J${String(svId).padStart(2, "0")}`;
|
|
53
|
+
} else {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
if (p.length < 8 + 40) return null;
|
|
57
|
+
const base = f.payloadStart + 8;
|
|
58
|
+
if (view.getUint32(base, true) >>> 24 === PREAMB_CNAV) return null;
|
|
59
|
+
const buff = new Uint8Array(30);
|
|
60
|
+
for (let k = 0; k < 10; k++) {
|
|
61
|
+
const dwrd = view.getUint32(base + 4 * k, true);
|
|
62
|
+
setBitU(buff, 24 * k, 24, dwrd >>> 6 & 16777215);
|
|
63
|
+
}
|
|
64
|
+
return { prn, gnssId, svId, buff, id: getBitU(buff, 43, 3) };
|
|
65
|
+
}
|
|
41
66
|
function parseUbxNav(data, opts = {}) {
|
|
42
67
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
43
68
|
const ephemerides = [];
|
|
@@ -59,28 +84,9 @@ function parseUbxNav(data, opts = {}) {
|
|
|
59
84
|
const last = /* @__PURE__ */ new Map();
|
|
60
85
|
for (const f of ubxFrames(data)) {
|
|
61
86
|
if (f.msgClass !== 2 || f.msgId !== 19) continue;
|
|
62
|
-
const
|
|
63
|
-
if (
|
|
64
|
-
const gnssId =
|
|
65
|
-
const svId = p[1];
|
|
66
|
-
let prn;
|
|
67
|
-
if (gnssId === 0 && svId >= 1 && svId <= 32) {
|
|
68
|
-
prn = `G${String(svId).padStart(2, "0")}`;
|
|
69
|
-
} else if (gnssId === 5 && svId >= 1 && svId <= 10) {
|
|
70
|
-
if (p.length === 44) continue;
|
|
71
|
-
prn = `J${String(svId).padStart(2, "0")}`;
|
|
72
|
-
} else {
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
if (p.length < 8 + 40) continue;
|
|
76
|
-
const base = f.payloadStart + 8;
|
|
77
|
-
if (view.getUint32(base, true) >>> 24 === PREAMB_CNAV) continue;
|
|
78
|
-
const buff = new Uint8Array(30);
|
|
79
|
-
for (let k = 0; k < 10; k++) {
|
|
80
|
-
const dwrd = view.getUint32(base + 4 * k, true);
|
|
81
|
-
setBitU(buff, 24 * k, 24, dwrd >>> 6 & 16777215);
|
|
82
|
-
}
|
|
83
|
-
const id = getBitU(buff, 43, 3);
|
|
87
|
+
const lnav = readLnavSubframe(view, f);
|
|
88
|
+
if (!lnav) continue;
|
|
89
|
+
const { prn, gnssId, svId, buff, id } = lnav;
|
|
84
90
|
if (id < 1 || id > 5) {
|
|
85
91
|
badParity++;
|
|
86
92
|
continue;
|
|
@@ -110,6 +116,34 @@ function parseUbxNav(data, opts = {}) {
|
|
|
110
116
|
return { ephemerides, badParity };
|
|
111
117
|
}
|
|
112
118
|
|
|
119
|
+
// src/ubx/iono.ts
|
|
120
|
+
function parseUbxIonoUtc(data) {
|
|
121
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
122
|
+
const ionoCorrections = {};
|
|
123
|
+
let leapSeconds = null;
|
|
124
|
+
for (const f of ubxFrames(data)) {
|
|
125
|
+
if (f.msgClass !== 2 || f.msgId !== 19) continue;
|
|
126
|
+
const sf = readLnavSubframe(view, f);
|
|
127
|
+
if (!sf || sf.gnssId !== 0 || sf.id !== 4) continue;
|
|
128
|
+
const b = sf.buff;
|
|
129
|
+
if (getBitU(b, 48, 2) !== 1 || getBitU(b, 50, 6) !== 56) continue;
|
|
130
|
+
ionoCorrections["GPSA"] = [
|
|
131
|
+
getBitS(b, 56, 8) * 2 ** -30,
|
|
132
|
+
getBitS(b, 64, 8) * 2 ** -27,
|
|
133
|
+
getBitS(b, 72, 8) * 2 ** -24,
|
|
134
|
+
getBitS(b, 80, 8) * 2 ** -24
|
|
135
|
+
];
|
|
136
|
+
ionoCorrections["GPSB"] = [
|
|
137
|
+
getBitS(b, 88, 8) * 2 ** 11,
|
|
138
|
+
getBitS(b, 96, 8) * 2 ** 14,
|
|
139
|
+
getBitS(b, 104, 8) * 2 ** 16,
|
|
140
|
+
getBitS(b, 112, 8) * 2 ** 16
|
|
141
|
+
];
|
|
142
|
+
leapSeconds = getBitS(b, 192, 8);
|
|
143
|
+
}
|
|
144
|
+
return { ionoCorrections, leapSeconds };
|
|
145
|
+
}
|
|
146
|
+
|
|
113
147
|
// src/ubx/index.ts
|
|
114
148
|
var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
|
|
115
149
|
var MS_PER_WEEK = 7 * 864e5;
|
|
@@ -206,5 +240,6 @@ function parseUbxRawx(data) {
|
|
|
206
240
|
export {
|
|
207
241
|
ubxFrames,
|
|
208
242
|
parseUbxNav,
|
|
243
|
+
parseUbxIonoUtc,
|
|
209
244
|
parseUbxRawx
|
|
210
245
|
};
|
|
@@ -371,6 +371,39 @@ function parseSbfAlmanac(data) {
|
|
|
371
371
|
return { almanacs, badCrc };
|
|
372
372
|
}
|
|
373
373
|
|
|
374
|
+
// src/sbf/iono.ts
|
|
375
|
+
var F4_DNU2 = -2e10;
|
|
376
|
+
function parseSbfIonoUtc(data) {
|
|
377
|
+
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
378
|
+
const ionoCorrections = {};
|
|
379
|
+
let leapSeconds = null;
|
|
380
|
+
const f4s = (b, n) => {
|
|
381
|
+
const out = [];
|
|
382
|
+
for (let k = 0; k < n; k++) {
|
|
383
|
+
const v = view.getFloat32(b + 4 * k, true);
|
|
384
|
+
if (v === F4_DNU2) return null;
|
|
385
|
+
out.push(v);
|
|
386
|
+
}
|
|
387
|
+
return out;
|
|
388
|
+
};
|
|
389
|
+
scanSbfFrames(data, view, (id, b, len) => {
|
|
390
|
+
if ((id === 5893 || id === 4120) && len >= 48) {
|
|
391
|
+
const alpha = f4s(b + 16, 4);
|
|
392
|
+
const beta = f4s(b + 32, 4);
|
|
393
|
+
if (!alpha || !beta) return;
|
|
394
|
+
const sys = id === 5893 ? "GPS" : "BDS";
|
|
395
|
+
ionoCorrections[`${sys}A`] = alpha;
|
|
396
|
+
ionoCorrections[`${sys}B`] = beta;
|
|
397
|
+
} else if (id === 4030 && len >= 28) {
|
|
398
|
+
const ai = f4s(b + 16, 3);
|
|
399
|
+
if (ai) ionoCorrections["GAL"] = ai;
|
|
400
|
+
} else if (id === 5894 && len >= 37) {
|
|
401
|
+
leapSeconds = view.getInt8(b + 33);
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
return { ionoCorrections, leapSeconds };
|
|
405
|
+
}
|
|
406
|
+
|
|
374
407
|
// src/sbf/index.ts
|
|
375
408
|
var CLIGHT = 299792458;
|
|
376
409
|
var GPS_EPOCH_MS2 = Date.UTC(1980, 0, 6);
|
|
@@ -1044,5 +1077,6 @@ export {
|
|
|
1044
1077
|
scanSbfFrames,
|
|
1045
1078
|
parseSbfNav,
|
|
1046
1079
|
parseSbfAlmanac,
|
|
1080
|
+
parseSbfIonoUtc,
|
|
1047
1081
|
parseSbfMeas
|
|
1048
1082
|
};
|