gnss-js 1.65.0 → 2.0.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/README.md +144 -132
- package/dist/{chunk-TWAC2BZF.js → chunk-2CMAFEHI.js} +1 -1
- package/dist/{chunk-MRC6LIPM.js → chunk-GH7MYXON.js} +1 -1
- package/dist/chunk-S624C5AC.js +269 -0
- package/dist/{chunk-REULRNJ5.js → chunk-WVTDVPKA.js} +151 -188
- package/dist/{chunk-UHLUAU6H.js → chunk-WW3DKCDN.js} +4 -4
- package/dist/constants.js +6 -6
- package/dist/{ephemeris-Ohl6NAfw.d.cts → ephemeris-BAnBLLB9.d.cts} +0 -1
- package/dist/{ephemeris-Ohl6NAfw.d.ts → ephemeris-BAnBLLB9.d.ts} +0 -1
- package/dist/index.cjs +427 -188
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +121 -101
- package/dist/novatel.js +3 -3
- package/dist/orbit.d.cts +1 -1
- package/dist/orbit.d.ts +1 -1
- package/dist/orbit.js +3 -3
- package/dist/positioning.d.cts +1 -1
- package/dist/positioning.d.ts +1 -1
- package/dist/positioning.js +4 -4
- package/dist/rtcm2.cjs +300 -0
- package/dist/rtcm2.d.cts +116 -0
- package/dist/rtcm2.d.ts +116 -0
- package/dist/rtcm2.js +20 -0
- package/dist/rtcm3.cjs +181 -217
- package/dist/rtcm3.d.cts +28 -15
- package/dist/rtcm3.d.ts +28 -15
- package/dist/rtcm3.js +5 -3
- package/dist/sbf.js +4 -4
- package/dist/ubx.js +4 -4
- package/package.json +6 -1
- package/dist/{chunk-FA2UTLEQ.js → chunk-3KSDL3CO.js} +3 -3
- package/dist/{chunk-MHGNKSSH.js → chunk-JYWYQ7DW.js} +3 -3
- package/dist/{chunk-KUTNIP3O.js → chunk-SEYH4BEN.js} +3 -3
package/dist/rtcm2.cjs
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/rtcm2/index.ts
|
|
21
|
+
var rtcm2_exports = {};
|
|
22
|
+
__export(rtcm2_exports, {
|
|
23
|
+
RTCM2_MESSAGE_NAMES: () => RTCM2_MESSAGE_NAMES,
|
|
24
|
+
Rtcm2Decoder: () => Rtcm2Decoder,
|
|
25
|
+
looksLikeRtcm2: () => looksLikeRtcm2,
|
|
26
|
+
rtcm2Dgps: () => rtcm2Dgps,
|
|
27
|
+
rtcm2Observation: () => rtcm2Observation,
|
|
28
|
+
rtcm2Station: () => rtcm2Station,
|
|
29
|
+
rtcm2Text: () => rtcm2Text,
|
|
30
|
+
rtcm2Time: () => rtcm2Time
|
|
31
|
+
});
|
|
32
|
+
module.exports = __toCommonJS(rtcm2_exports);
|
|
33
|
+
var RTCM2_PREAMBLE = 102;
|
|
34
|
+
var HAMMING = [
|
|
35
|
+
3139384448,
|
|
36
|
+
1569692224,
|
|
37
|
+
2932329728,
|
|
38
|
+
1466164864,
|
|
39
|
+
1806824256,
|
|
40
|
+
2340063680
|
|
41
|
+
];
|
|
42
|
+
function getbitu(buff, pos, len) {
|
|
43
|
+
let v = 0;
|
|
44
|
+
for (let i = pos; i < pos + len; i++)
|
|
45
|
+
v = v * 2 + (buff[i >> 3] >> 7 - (i & 7) & 1);
|
|
46
|
+
return v >>> 0;
|
|
47
|
+
}
|
|
48
|
+
function getbits(buff, pos, len) {
|
|
49
|
+
const v = getbitu(buff, pos, len);
|
|
50
|
+
return v & 1 << len - 1 ? v - 2 ** len : v;
|
|
51
|
+
}
|
|
52
|
+
function decodeWord(w) {
|
|
53
|
+
let word = w >>> 0;
|
|
54
|
+
if (word & 1073741824) word = (word ^ 1073741760) >>> 0;
|
|
55
|
+
let parity = 0;
|
|
56
|
+
for (let i = 0; i < 6; i++) {
|
|
57
|
+
parity <<= 1;
|
|
58
|
+
let x = (word & HAMMING[i]) >>> 6;
|
|
59
|
+
while (x) {
|
|
60
|
+
parity ^= x & 1;
|
|
61
|
+
x >>>= 1;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
if (parity >>> 0 !== (word & 63)) return null;
|
|
65
|
+
return [word >>> 22 & 255, word >>> 14 & 255, word >>> 6 & 255];
|
|
66
|
+
}
|
|
67
|
+
var Rtcm2Decoder = class {
|
|
68
|
+
word = 0;
|
|
69
|
+
nbyte = 0;
|
|
70
|
+
nbit = 0;
|
|
71
|
+
len = 0;
|
|
72
|
+
buff = new Uint8Array(256);
|
|
73
|
+
/** Reset the framer (e.g. after a stream reconnect). */
|
|
74
|
+
reset() {
|
|
75
|
+
this.word = 0;
|
|
76
|
+
this.nbyte = 0;
|
|
77
|
+
this.nbit = 0;
|
|
78
|
+
this.len = 0;
|
|
79
|
+
}
|
|
80
|
+
decode(bytes) {
|
|
81
|
+
const frames = [];
|
|
82
|
+
for (const raw of bytes) {
|
|
83
|
+
if ((raw & 192) !== 64) continue;
|
|
84
|
+
let data = raw;
|
|
85
|
+
for (let i = 0; i < 6; i++, data >>= 1) {
|
|
86
|
+
this.word = (this.word << 1 | data & 1) >>> 0;
|
|
87
|
+
if (this.nbyte === 0) {
|
|
88
|
+
let preamb = this.word >>> 22 & 255;
|
|
89
|
+
if (this.word & 1073741824) preamb ^= 255;
|
|
90
|
+
if (preamb !== RTCM2_PREAMBLE) continue;
|
|
91
|
+
const d2 = decodeWord(this.word);
|
|
92
|
+
if (!d2) continue;
|
|
93
|
+
this.buff[0] = d2[0];
|
|
94
|
+
this.buff[1] = d2[1];
|
|
95
|
+
this.buff[2] = d2[2];
|
|
96
|
+
this.nbyte = 3;
|
|
97
|
+
this.nbit = 0;
|
|
98
|
+
continue;
|
|
99
|
+
}
|
|
100
|
+
if (++this.nbit < 30) continue;
|
|
101
|
+
this.nbit = 0;
|
|
102
|
+
const d = decodeWord(this.word);
|
|
103
|
+
if (!d) {
|
|
104
|
+
this.nbyte = 0;
|
|
105
|
+
this.word &= 3;
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
this.buff[this.nbyte] = d[0];
|
|
109
|
+
this.buff[this.nbyte + 1] = d[1];
|
|
110
|
+
this.buff[this.nbyte + 2] = d[2];
|
|
111
|
+
this.nbyte += 3;
|
|
112
|
+
if (this.nbyte === 6) this.len = (this.buff[5] >> 3) * 3 + 6;
|
|
113
|
+
if (this.nbyte < this.len) continue;
|
|
114
|
+
frames.push(this.readHeader(this.buff.slice(0, this.len)));
|
|
115
|
+
this.nbyte = 0;
|
|
116
|
+
this.word &= 3;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return frames;
|
|
120
|
+
}
|
|
121
|
+
readHeader(payload) {
|
|
122
|
+
return {
|
|
123
|
+
messageType: getbitu(payload, 8, 6),
|
|
124
|
+
stationId: getbitu(payload, 14, 10),
|
|
125
|
+
zcountSec: getbitu(payload, 24, 13) * 0.6,
|
|
126
|
+
sequenceNo: getbitu(payload, 37, 3),
|
|
127
|
+
lengthWords: payload[5] >> 3,
|
|
128
|
+
health: getbitu(payload, 45, 3),
|
|
129
|
+
payload
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
function rtcm2Station(frame) {
|
|
134
|
+
const p = frame.payload;
|
|
135
|
+
const nbit = frame.lengthWords * 24;
|
|
136
|
+
if (frame.messageType === 3) {
|
|
137
|
+
if (nbit < 96) return null;
|
|
138
|
+
return {
|
|
139
|
+
position: [
|
|
140
|
+
getbits(p, 48, 32) * 0.01,
|
|
141
|
+
getbits(p, 80, 32) * 0.01,
|
|
142
|
+
getbits(p, 112, 32) * 0.01
|
|
143
|
+
]
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (frame.messageType === 22) {
|
|
147
|
+
if (nbit < 24) return null;
|
|
148
|
+
const l1 = [
|
|
149
|
+
getbits(p, 48, 8) / 25600,
|
|
150
|
+
getbits(p, 56, 8) / 25600,
|
|
151
|
+
getbits(p, 64, 8) / 25600
|
|
152
|
+
];
|
|
153
|
+
let height;
|
|
154
|
+
if (nbit >= 48) {
|
|
155
|
+
const noh = getbits(p, 48 + 24 + 5, 1);
|
|
156
|
+
height = noh ? 0 : getbitu(p, 48 + 24 + 6, 18) / 25600;
|
|
157
|
+
}
|
|
158
|
+
return { l1Offset: l1, height };
|
|
159
|
+
}
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
function rtcm2Observation(frame) {
|
|
163
|
+
const t = frame.messageType;
|
|
164
|
+
if (t !== 18 && t !== 19) return null;
|
|
165
|
+
const p = frame.payload;
|
|
166
|
+
const nbit = frame.lengthWords * 24 + 48;
|
|
167
|
+
let i = 48;
|
|
168
|
+
if (i + 24 > nbit) return null;
|
|
169
|
+
const fRaw = getbitu(p, i, 2);
|
|
170
|
+
i += 4;
|
|
171
|
+
const microSec = getbitu(p, i, 20);
|
|
172
|
+
i += 20;
|
|
173
|
+
if (fRaw & 1) return null;
|
|
174
|
+
const freq = fRaw >> 1;
|
|
175
|
+
let sync = false;
|
|
176
|
+
const records = [];
|
|
177
|
+
while (i + 48 <= nbit) {
|
|
178
|
+
sync = getbitu(p, i, 1) === 1;
|
|
179
|
+
i += 1;
|
|
180
|
+
const code = getbitu(p, i, 1);
|
|
181
|
+
i += 1;
|
|
182
|
+
const sys = getbitu(p, i, 1);
|
|
183
|
+
i += 1;
|
|
184
|
+
let prn = getbitu(p, i, 5);
|
|
185
|
+
i += 5;
|
|
186
|
+
let loss;
|
|
187
|
+
if (t === 18) {
|
|
188
|
+
i += 3;
|
|
189
|
+
loss = getbitu(p, i, 5);
|
|
190
|
+
i += 5;
|
|
191
|
+
} else {
|
|
192
|
+
i += 8;
|
|
193
|
+
}
|
|
194
|
+
const val = t === 18 ? getbits(p, i, 32) : getbitu(p, i, 32);
|
|
195
|
+
i += 32;
|
|
196
|
+
if (prn === 0) prn = 32;
|
|
197
|
+
const system = sys ? "R" : "G";
|
|
198
|
+
const rec = {
|
|
199
|
+
prn: `${system}${String(prn).padStart(2, "0")}`,
|
|
200
|
+
system,
|
|
201
|
+
freq,
|
|
202
|
+
code: code ? "P" : "C/A",
|
|
203
|
+
lossOfLock: loss
|
|
204
|
+
};
|
|
205
|
+
if (t === 18)
|
|
206
|
+
rec.phaseCycles = -val / 256;
|
|
207
|
+
else rec.pseudorangeM = val * 0.02;
|
|
208
|
+
records.push(rec);
|
|
209
|
+
}
|
|
210
|
+
return { freq, sync, microSec, records };
|
|
211
|
+
}
|
|
212
|
+
function rtcm2Dgps(frame) {
|
|
213
|
+
const t = frame.messageType;
|
|
214
|
+
if (t !== 1 && t !== 9 && t !== 31) return null;
|
|
215
|
+
const system = t === 31 ? "R" : "G";
|
|
216
|
+
const p = frame.payload;
|
|
217
|
+
const nbit = frame.lengthWords * 24 + 48;
|
|
218
|
+
let i = 48;
|
|
219
|
+
const corrections = [];
|
|
220
|
+
while (i + 40 <= nbit) {
|
|
221
|
+
const fact = getbitu(p, i, 1);
|
|
222
|
+
i += 1;
|
|
223
|
+
const udre = getbitu(p, i, 2);
|
|
224
|
+
i += 2;
|
|
225
|
+
let prn = getbitu(p, i, 5);
|
|
226
|
+
i += 5;
|
|
227
|
+
const prc = getbits(p, i, 16);
|
|
228
|
+
i += 16;
|
|
229
|
+
const rrc = getbits(p, i, 8);
|
|
230
|
+
i += 8;
|
|
231
|
+
const iod = getbits(p, i, 8);
|
|
232
|
+
i += 8;
|
|
233
|
+
if (prn === 0) prn = 32;
|
|
234
|
+
corrections.push({
|
|
235
|
+
prn: `${system}${String(prn).padStart(2, "0")}`,
|
|
236
|
+
prc: prc * (fact ? 0.32 : 0.02),
|
|
237
|
+
rrc: rrc * (fact ? 0.032 : 2e-3),
|
|
238
|
+
iod,
|
|
239
|
+
udre
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
return { system, corrections };
|
|
243
|
+
}
|
|
244
|
+
function rtcm2Time(frame) {
|
|
245
|
+
if (frame.messageType !== 14) return null;
|
|
246
|
+
const p = frame.payload;
|
|
247
|
+
if (frame.lengthWords * 24 < 24) return null;
|
|
248
|
+
return {
|
|
249
|
+
zcountSec: getbitu(p, 24, 13) * 0.6,
|
|
250
|
+
week: getbitu(p, 48, 10),
|
|
251
|
+
hour: getbitu(p, 58, 8),
|
|
252
|
+
leapSeconds: getbitu(p, 66, 6)
|
|
253
|
+
};
|
|
254
|
+
}
|
|
255
|
+
function rtcm2Text(frame) {
|
|
256
|
+
if (frame.messageType !== 16) return null;
|
|
257
|
+
const p = frame.payload;
|
|
258
|
+
const nbit = frame.lengthWords * 24 + 48;
|
|
259
|
+
let s = "";
|
|
260
|
+
for (let i = 48; i + 8 <= nbit; i += 8) {
|
|
261
|
+
const c = getbitu(p, i, 8);
|
|
262
|
+
if (c === 0) break;
|
|
263
|
+
s += String.fromCharCode(c);
|
|
264
|
+
}
|
|
265
|
+
return s;
|
|
266
|
+
}
|
|
267
|
+
var RTCM2_MESSAGE_NAMES = {
|
|
268
|
+
1: "GPS differential corrections",
|
|
269
|
+
3: "Reference station parameters (ARP)",
|
|
270
|
+
9: "GPS partial correction set",
|
|
271
|
+
14: "GPS time of week",
|
|
272
|
+
16: "GPS special message (text)",
|
|
273
|
+
17: "GPS ephemerides",
|
|
274
|
+
18: "RTK uncorrected carrier phase",
|
|
275
|
+
19: "RTK uncorrected pseudorange",
|
|
276
|
+
22: "Extended reference station parameters",
|
|
277
|
+
23: "Antenna type definition",
|
|
278
|
+
24: "Antenna reference point (ARP)",
|
|
279
|
+
31: "GLONASS differential corrections",
|
|
280
|
+
32: "GLONASS reference station parameters",
|
|
281
|
+
34: "GLONASS partial correction set",
|
|
282
|
+
36: "GLONASS special message"
|
|
283
|
+
};
|
|
284
|
+
function looksLikeRtcm2(bytes) {
|
|
285
|
+
const n = Math.min(bytes.length, 4096);
|
|
286
|
+
if (n < 12) return false;
|
|
287
|
+
for (let i = 0; i < n; i++) if ((bytes[i] & 192) !== 64) return false;
|
|
288
|
+
return new Rtcm2Decoder().decode(bytes.subarray(0, n)).length >= 2;
|
|
289
|
+
}
|
|
290
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
291
|
+
0 && (module.exports = {
|
|
292
|
+
RTCM2_MESSAGE_NAMES,
|
|
293
|
+
Rtcm2Decoder,
|
|
294
|
+
looksLikeRtcm2,
|
|
295
|
+
rtcm2Dgps,
|
|
296
|
+
rtcm2Observation,
|
|
297
|
+
rtcm2Station,
|
|
298
|
+
rtcm2Text,
|
|
299
|
+
rtcm2Time
|
|
300
|
+
});
|
package/dist/rtcm2.d.cts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTCM 2.x decoder (RTCM 10402.3). A wholly different wire format from RTCM3:
|
|
3
|
+
* a stream of 30-bit GPS-style words (24 data + 6 parity bits), each carried in
|
|
4
|
+
* the low 6 bits of successive bytes ("6-of-8" — every byte has its top two
|
|
5
|
+
* bits set to 01, so 0x40–0x7F). Words are parity-checked and their D30* bit
|
|
6
|
+
* inverts the following data, exactly like the GPS LNAV navigation message.
|
|
7
|
+
*
|
|
8
|
+
* Framing/parity are a faithful port of RTKLIB `input_rtcm2` + `decode_word`.
|
|
9
|
+
* {@link Rtcm2Decoder.decode} strips the encoding, parity-checks, syncs on the
|
|
10
|
+
* 0x66 preamble and returns the message frames (header + the packed 24-bit-word
|
|
11
|
+
* body); the per-type body decoders (`rtcm2Station`, `rtcm2Observation`,
|
|
12
|
+
* `rtcm2Dgps`, `rtcm2Time`, `rtcm2Text`) read that body.
|
|
13
|
+
*
|
|
14
|
+
* Nearly extinct in favour of RTCM3, but still broadcast by some legacy CORS.
|
|
15
|
+
*/
|
|
16
|
+
/** One decoded RTCM 2.x message frame (header + packed 24-bit-word body). */
|
|
17
|
+
interface Rtcm2Frame {
|
|
18
|
+
messageType: number;
|
|
19
|
+
stationId: number;
|
|
20
|
+
/** Modified Z-count, seconds within the hour (0–3599.4). */
|
|
21
|
+
zcountSec: number;
|
|
22
|
+
sequenceNo: number;
|
|
23
|
+
/** Station health (3-bit). */
|
|
24
|
+
health: number;
|
|
25
|
+
/** Number of 24-bit data words after the 2-word header. */
|
|
26
|
+
lengthWords: number;
|
|
27
|
+
/** The parity-stripped message: header + data words, 24 bits per word packed
|
|
28
|
+
* MSB-first into bytes (message type at bit 8, body from bit 48). */
|
|
29
|
+
payload: Uint8Array;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Streaming RTCM 2.x framer. Feed bytes; get back complete, parity-valid
|
|
33
|
+
* message frames. Retains partial-word state across calls.
|
|
34
|
+
*/
|
|
35
|
+
declare class Rtcm2Decoder {
|
|
36
|
+
private word;
|
|
37
|
+
private nbyte;
|
|
38
|
+
private nbit;
|
|
39
|
+
private len;
|
|
40
|
+
private buff;
|
|
41
|
+
/** Reset the framer (e.g. after a stream reconnect). */
|
|
42
|
+
reset(): void;
|
|
43
|
+
decode(bytes: Uint8Array): Rtcm2Frame[];
|
|
44
|
+
private readHeader;
|
|
45
|
+
}
|
|
46
|
+
/** Reference-station coordinates from Type 3 (ARP) or Type 22 (extension). */
|
|
47
|
+
interface Rtcm2Station {
|
|
48
|
+
/** ECEF position (m) — Type 3. */
|
|
49
|
+
position?: [number, number, number];
|
|
50
|
+
/** L1 phase-centre → ARP offset (m) — Type 22. */
|
|
51
|
+
l1Offset?: [number, number, number];
|
|
52
|
+
/** Antenna height above the monument (m) — Type 22. */
|
|
53
|
+
height?: number;
|
|
54
|
+
}
|
|
55
|
+
/** Decode Type 3 (reference station ARP) or Type 22 (extended parameters). */
|
|
56
|
+
declare function rtcm2Station(frame: Rtcm2Frame): Rtcm2Station | null;
|
|
57
|
+
/** One raw observation record from a Type 18/19 message. */
|
|
58
|
+
interface Rtcm2ObsRecord {
|
|
59
|
+
prn: string;
|
|
60
|
+
system: 'G' | 'R';
|
|
61
|
+
/** Frequency: 0 = L1, 1 = L2. */
|
|
62
|
+
freq: number;
|
|
63
|
+
code: 'C/A' | 'P';
|
|
64
|
+
/** Carrier phase (cycles) — Type 18. */
|
|
65
|
+
phaseCycles?: number;
|
|
66
|
+
/** Pseudorange (m) — Type 19. */
|
|
67
|
+
pseudorangeM?: number;
|
|
68
|
+
/** Loss-of-lock indicator (Type 18). */
|
|
69
|
+
lossOfLock?: number;
|
|
70
|
+
}
|
|
71
|
+
/** Decode a Type 18 (carrier phase) or Type 19 (pseudorange) message into its
|
|
72
|
+
* per-satellite records. Returns the frequency, the multiple-message sync flag
|
|
73
|
+
* and the records; the caller pairs 18+19 across an epoch to form observations.
|
|
74
|
+
* Returns null for other types or an L2-frequency variant we don't map. */
|
|
75
|
+
declare function rtcm2Observation(frame: Rtcm2Frame): {
|
|
76
|
+
freq: number;
|
|
77
|
+
sync: boolean;
|
|
78
|
+
microSec: number;
|
|
79
|
+
records: Rtcm2ObsRecord[];
|
|
80
|
+
} | null;
|
|
81
|
+
/** One differential correction from a Type 1/9 (GPS) or Type 31 (GLONASS). */
|
|
82
|
+
interface Rtcm2Correction {
|
|
83
|
+
prn: string;
|
|
84
|
+
/** Pseudorange correction (m). */
|
|
85
|
+
prc: number;
|
|
86
|
+
/** Range-rate correction (m/s). */
|
|
87
|
+
rrc: number;
|
|
88
|
+
/** Issue of data. */
|
|
89
|
+
iod: number;
|
|
90
|
+
/** UDRE scale index (0–3). */
|
|
91
|
+
udre: number;
|
|
92
|
+
}
|
|
93
|
+
/** Decode differential corrections — Type 1/9 (GPS) or Type 31 (GLONASS). */
|
|
94
|
+
declare function rtcm2Dgps(frame: Rtcm2Frame): {
|
|
95
|
+
system: 'G' | 'R';
|
|
96
|
+
corrections: Rtcm2Correction[];
|
|
97
|
+
} | null;
|
|
98
|
+
/** Decode Type 14 — GPS time of week (week/hour + leap seconds). */
|
|
99
|
+
declare function rtcm2Time(frame: Rtcm2Frame): {
|
|
100
|
+
week: number;
|
|
101
|
+
hour: number;
|
|
102
|
+
zcountSec: number;
|
|
103
|
+
leapSeconds: number;
|
|
104
|
+
} | null;
|
|
105
|
+
/** Decode Type 16 — GPS special (ASCII text) message. */
|
|
106
|
+
declare function rtcm2Text(frame: Rtcm2Frame): string | null;
|
|
107
|
+
/** RTCM 2.x message-type names for the census/inspector. */
|
|
108
|
+
declare const RTCM2_MESSAGE_NAMES: Record<number, string>;
|
|
109
|
+
/**
|
|
110
|
+
* Heuristic: does this buffer look like an RTCM 2.x stream? Every byte must be
|
|
111
|
+
* 6-of-8 (top two bits 01), and the framer must extract at least two
|
|
112
|
+
* parity-valid frames from the head.
|
|
113
|
+
*/
|
|
114
|
+
declare function looksLikeRtcm2(bytes: Uint8Array): boolean;
|
|
115
|
+
|
|
116
|
+
export { RTCM2_MESSAGE_NAMES, type Rtcm2Correction, Rtcm2Decoder, type Rtcm2Frame, type Rtcm2ObsRecord, type Rtcm2Station, looksLikeRtcm2, rtcm2Dgps, rtcm2Observation, rtcm2Station, rtcm2Text, rtcm2Time };
|
package/dist/rtcm2.d.ts
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* RTCM 2.x decoder (RTCM 10402.3). A wholly different wire format from RTCM3:
|
|
3
|
+
* a stream of 30-bit GPS-style words (24 data + 6 parity bits), each carried in
|
|
4
|
+
* the low 6 bits of successive bytes ("6-of-8" — every byte has its top two
|
|
5
|
+
* bits set to 01, so 0x40–0x7F). Words are parity-checked and their D30* bit
|
|
6
|
+
* inverts the following data, exactly like the GPS LNAV navigation message.
|
|
7
|
+
*
|
|
8
|
+
* Framing/parity are a faithful port of RTKLIB `input_rtcm2` + `decode_word`.
|
|
9
|
+
* {@link Rtcm2Decoder.decode} strips the encoding, parity-checks, syncs on the
|
|
10
|
+
* 0x66 preamble and returns the message frames (header + the packed 24-bit-word
|
|
11
|
+
* body); the per-type body decoders (`rtcm2Station`, `rtcm2Observation`,
|
|
12
|
+
* `rtcm2Dgps`, `rtcm2Time`, `rtcm2Text`) read that body.
|
|
13
|
+
*
|
|
14
|
+
* Nearly extinct in favour of RTCM3, but still broadcast by some legacy CORS.
|
|
15
|
+
*/
|
|
16
|
+
/** One decoded RTCM 2.x message frame (header + packed 24-bit-word body). */
|
|
17
|
+
interface Rtcm2Frame {
|
|
18
|
+
messageType: number;
|
|
19
|
+
stationId: number;
|
|
20
|
+
/** Modified Z-count, seconds within the hour (0–3599.4). */
|
|
21
|
+
zcountSec: number;
|
|
22
|
+
sequenceNo: number;
|
|
23
|
+
/** Station health (3-bit). */
|
|
24
|
+
health: number;
|
|
25
|
+
/** Number of 24-bit data words after the 2-word header. */
|
|
26
|
+
lengthWords: number;
|
|
27
|
+
/** The parity-stripped message: header + data words, 24 bits per word packed
|
|
28
|
+
* MSB-first into bytes (message type at bit 8, body from bit 48). */
|
|
29
|
+
payload: Uint8Array;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Streaming RTCM 2.x framer. Feed bytes; get back complete, parity-valid
|
|
33
|
+
* message frames. Retains partial-word state across calls.
|
|
34
|
+
*/
|
|
35
|
+
declare class Rtcm2Decoder {
|
|
36
|
+
private word;
|
|
37
|
+
private nbyte;
|
|
38
|
+
private nbit;
|
|
39
|
+
private len;
|
|
40
|
+
private buff;
|
|
41
|
+
/** Reset the framer (e.g. after a stream reconnect). */
|
|
42
|
+
reset(): void;
|
|
43
|
+
decode(bytes: Uint8Array): Rtcm2Frame[];
|
|
44
|
+
private readHeader;
|
|
45
|
+
}
|
|
46
|
+
/** Reference-station coordinates from Type 3 (ARP) or Type 22 (extension). */
|
|
47
|
+
interface Rtcm2Station {
|
|
48
|
+
/** ECEF position (m) — Type 3. */
|
|
49
|
+
position?: [number, number, number];
|
|
50
|
+
/** L1 phase-centre → ARP offset (m) — Type 22. */
|
|
51
|
+
l1Offset?: [number, number, number];
|
|
52
|
+
/** Antenna height above the monument (m) — Type 22. */
|
|
53
|
+
height?: number;
|
|
54
|
+
}
|
|
55
|
+
/** Decode Type 3 (reference station ARP) or Type 22 (extended parameters). */
|
|
56
|
+
declare function rtcm2Station(frame: Rtcm2Frame): Rtcm2Station | null;
|
|
57
|
+
/** One raw observation record from a Type 18/19 message. */
|
|
58
|
+
interface Rtcm2ObsRecord {
|
|
59
|
+
prn: string;
|
|
60
|
+
system: 'G' | 'R';
|
|
61
|
+
/** Frequency: 0 = L1, 1 = L2. */
|
|
62
|
+
freq: number;
|
|
63
|
+
code: 'C/A' | 'P';
|
|
64
|
+
/** Carrier phase (cycles) — Type 18. */
|
|
65
|
+
phaseCycles?: number;
|
|
66
|
+
/** Pseudorange (m) — Type 19. */
|
|
67
|
+
pseudorangeM?: number;
|
|
68
|
+
/** Loss-of-lock indicator (Type 18). */
|
|
69
|
+
lossOfLock?: number;
|
|
70
|
+
}
|
|
71
|
+
/** Decode a Type 18 (carrier phase) or Type 19 (pseudorange) message into its
|
|
72
|
+
* per-satellite records. Returns the frequency, the multiple-message sync flag
|
|
73
|
+
* and the records; the caller pairs 18+19 across an epoch to form observations.
|
|
74
|
+
* Returns null for other types or an L2-frequency variant we don't map. */
|
|
75
|
+
declare function rtcm2Observation(frame: Rtcm2Frame): {
|
|
76
|
+
freq: number;
|
|
77
|
+
sync: boolean;
|
|
78
|
+
microSec: number;
|
|
79
|
+
records: Rtcm2ObsRecord[];
|
|
80
|
+
} | null;
|
|
81
|
+
/** One differential correction from a Type 1/9 (GPS) or Type 31 (GLONASS). */
|
|
82
|
+
interface Rtcm2Correction {
|
|
83
|
+
prn: string;
|
|
84
|
+
/** Pseudorange correction (m). */
|
|
85
|
+
prc: number;
|
|
86
|
+
/** Range-rate correction (m/s). */
|
|
87
|
+
rrc: number;
|
|
88
|
+
/** Issue of data. */
|
|
89
|
+
iod: number;
|
|
90
|
+
/** UDRE scale index (0–3). */
|
|
91
|
+
udre: number;
|
|
92
|
+
}
|
|
93
|
+
/** Decode differential corrections — Type 1/9 (GPS) or Type 31 (GLONASS). */
|
|
94
|
+
declare function rtcm2Dgps(frame: Rtcm2Frame): {
|
|
95
|
+
system: 'G' | 'R';
|
|
96
|
+
corrections: Rtcm2Correction[];
|
|
97
|
+
} | null;
|
|
98
|
+
/** Decode Type 14 — GPS time of week (week/hour + leap seconds). */
|
|
99
|
+
declare function rtcm2Time(frame: Rtcm2Frame): {
|
|
100
|
+
week: number;
|
|
101
|
+
hour: number;
|
|
102
|
+
zcountSec: number;
|
|
103
|
+
leapSeconds: number;
|
|
104
|
+
} | null;
|
|
105
|
+
/** Decode Type 16 — GPS special (ASCII text) message. */
|
|
106
|
+
declare function rtcm2Text(frame: Rtcm2Frame): string | null;
|
|
107
|
+
/** RTCM 2.x message-type names for the census/inspector. */
|
|
108
|
+
declare const RTCM2_MESSAGE_NAMES: Record<number, string>;
|
|
109
|
+
/**
|
|
110
|
+
* Heuristic: does this buffer look like an RTCM 2.x stream? Every byte must be
|
|
111
|
+
* 6-of-8 (top two bits 01), and the framer must extract at least two
|
|
112
|
+
* parity-valid frames from the head.
|
|
113
|
+
*/
|
|
114
|
+
declare function looksLikeRtcm2(bytes: Uint8Array): boolean;
|
|
115
|
+
|
|
116
|
+
export { RTCM2_MESSAGE_NAMES, type Rtcm2Correction, Rtcm2Decoder, type Rtcm2Frame, type Rtcm2ObsRecord, type Rtcm2Station, looksLikeRtcm2, rtcm2Dgps, rtcm2Observation, rtcm2Station, rtcm2Text, rtcm2Time };
|
package/dist/rtcm2.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import {
|
|
2
|
+
RTCM2_MESSAGE_NAMES,
|
|
3
|
+
Rtcm2Decoder,
|
|
4
|
+
looksLikeRtcm2,
|
|
5
|
+
rtcm2Dgps,
|
|
6
|
+
rtcm2Observation,
|
|
7
|
+
rtcm2Station,
|
|
8
|
+
rtcm2Text,
|
|
9
|
+
rtcm2Time
|
|
10
|
+
} from "./chunk-S624C5AC.js";
|
|
11
|
+
export {
|
|
12
|
+
RTCM2_MESSAGE_NAMES,
|
|
13
|
+
Rtcm2Decoder,
|
|
14
|
+
looksLikeRtcm2,
|
|
15
|
+
rtcm2Dgps,
|
|
16
|
+
rtcm2Observation,
|
|
17
|
+
rtcm2Station,
|
|
18
|
+
rtcm2Text,
|
|
19
|
+
rtcm2Time
|
|
20
|
+
};
|