gnss-js 1.25.0 → 1.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/binex.cjs +799 -0
- package/dist/binex.d.cts +189 -0
- package/dist/binex.d.ts +189 -0
- package/dist/binex.js +19 -0
- package/dist/{chunk-VTX3VCL4.js → chunk-5AUK42AL.js} +4 -2
- package/dist/{chunk-WZDFZ76K.js → chunk-726LQBGM.js} +8 -148
- package/dist/{chunk-PZNVFCKJ.js → chunk-AFEDNWXI.js} +5 -3
- package/dist/chunk-CKRNXZHT.js +424 -0
- package/dist/{chunk-7RKLWE6R.js → chunk-F4CM6Q4F.js} +4 -2
- package/dist/{chunk-MCAVU3XL.js → chunk-FEOMYZEU.js} +5 -3
- package/dist/chunk-IQ5OIMQD.js +148 -0
- package/dist/chunk-OK4GGNOO.js +756 -0
- package/dist/{chunk-NOQAAUGY.js → chunk-QVNNHACQ.js} +441 -2
- package/dist/index.cjs +1635 -17
- package/dist/index.d.cts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +43 -16
- package/dist/novatel.js +3 -2
- package/dist/rinex.cjs +438 -0
- package/dist/rinex.d.cts +27 -1
- package/dist/rinex.d.ts +27 -1
- package/dist/rinex.js +5 -2
- package/dist/sbf.js +4 -3
- package/dist/trimble.cjs +452 -0
- package/dist/trimble.d.cts +147 -0
- package/dist/trimble.d.ts +147 -0
- package/dist/trimble.js +10 -0
- package/dist/ubx.js +4 -3
- package/package.json +11 -1
package/dist/binex.d.cts
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { E as Ephemeris } from './nav-DImXUdbp.cjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BINEX (BINary EXchange) framing, shared by the observation and
|
|
5
|
+
* navigation decoders.
|
|
6
|
+
*
|
|
7
|
+
* A forward-readable record is: a 1-byte sync that encodes byte order and
|
|
8
|
+
* checksum model, a record ID (ubnxi), a message length (ubnxi), the
|
|
9
|
+
* message body, then a trailing checksum whose width depends on the
|
|
10
|
+
* covered-byte count. Sync bytes (ref [1] §"Format Details"):
|
|
11
|
+
*
|
|
12
|
+
* 0xC2 little-endian, regular CRC (forward)
|
|
13
|
+
* 0xE2 big-endian, regular CRC (forward)
|
|
14
|
+
* 0xC8 little-endian, enhanced CRC (forward)
|
|
15
|
+
* 0xE8 big-endian, enhanced CRC (forward)
|
|
16
|
+
*
|
|
17
|
+
* The reverse-readable variants (0xD2/0xF2/0xD8/0xF8 leading and
|
|
18
|
+
* 0xB4/0xB0/0xE4/0xE0 terminating) are NOT decoded here (deferred).
|
|
19
|
+
*
|
|
20
|
+
* Checksum widths over the covered bytes N = recordID + lengthField +
|
|
21
|
+
* body (regular model): N ≤ 127 → 1-byte XOR; 128–4095 → CRC16
|
|
22
|
+
* (x^16+x^12+x^5+1, i.e. poly 0x1021 MSB-first, init 0); 4096–1048575 →
|
|
23
|
+
* CRC32 (poly 0x04C11DB7 MSB-first); ≥ 1048576 → 16-byte MD5. Enhanced
|
|
24
|
+
* model shifts every threshold up one step (CRC16 from 0 bytes, no XOR).
|
|
25
|
+
* The 16-byte MD5 case is not implemented (records that large do not
|
|
26
|
+
* occur in GNSS obs/eph streams); such a record is treated as bad.
|
|
27
|
+
*
|
|
28
|
+
* ubnxi (1–4 byte unsigned) and the field layouts are ported from RTKLIB
|
|
29
|
+
* demo5/2.4.3 src/rcv/binex.c (getbnxi, decode_bnx, Copyright (c)
|
|
30
|
+
* 2013-2018 T. Takasu, BSD-2-Clause) and cross-checked against the
|
|
31
|
+
* EarthScope/UNAVCO BINEX definition [1].
|
|
32
|
+
*
|
|
33
|
+
* [1] UNAVCO/EarthScope, BINEX: Binary exchange format
|
|
34
|
+
* (http://binex.unavco.org/binex.html).
|
|
35
|
+
*/
|
|
36
|
+
/** BINEX 2-byte CRC (x^16+x^12+x^5+1), init 0, MSB-first. */
|
|
37
|
+
declare function binexCrc16(data: Uint8Array, start: number, end: number): number;
|
|
38
|
+
/**
|
|
39
|
+
* BINEX 4-byte CRC (poly 0x04C11DB7), init 0, MSB-first. Not exercised
|
|
40
|
+
* by any known fixture (obs/eph records use XOR-8 or CRC16); implemented
|
|
41
|
+
* to spec but fixture-unverified.
|
|
42
|
+
*/
|
|
43
|
+
declare function binexCrc32(data: Uint8Array, start: number, end: number): number;
|
|
44
|
+
/** 8-bit XOR checksum of `data[start, end)`. */
|
|
45
|
+
declare function binexCsum8(data: Uint8Array, start: number, end: number): number;
|
|
46
|
+
/**
|
|
47
|
+
* Decode a BINEX ubnxi (1–4 byte unsigned integer, MSB-first) at
|
|
48
|
+
* `data[pos]`. The first up-to-three bytes contribute their low 7 bits
|
|
49
|
+
* with the high bit as a continuation flag; a fourth byte (reached only
|
|
50
|
+
* when the first three all continue) contributes all 8 bits. Returns the
|
|
51
|
+
* value and the number of bytes consumed (1–4). Ported from RTKLIB
|
|
52
|
+
* getbnxi.
|
|
53
|
+
*/
|
|
54
|
+
declare function getBnxi(data: Uint8Array, pos: number): {
|
|
55
|
+
value: number;
|
|
56
|
+
size: number;
|
|
57
|
+
};
|
|
58
|
+
/** One checksum-valid forward BINEX record located in a byte stream. */
|
|
59
|
+
interface BinexRecord {
|
|
60
|
+
/** Record ID (e.g. 0x01, 0x7f). */
|
|
61
|
+
id: number;
|
|
62
|
+
/** Offset of the sync byte. */
|
|
63
|
+
start: number;
|
|
64
|
+
/** Offset of the message body (first byte after the length field). */
|
|
65
|
+
body: number;
|
|
66
|
+
/** Message body length in bytes. */
|
|
67
|
+
len: number;
|
|
68
|
+
/** True when the sync selects little-endian field byte order. */
|
|
69
|
+
littleEndian: boolean;
|
|
70
|
+
/** True when the sync selects the enhanced-CRC model. */
|
|
71
|
+
enhanced: boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Iterate every checksum-valid forward BINEX record in `data`. Corrupt
|
|
75
|
+
* or truncated candidates resync at the next byte; checksum failures
|
|
76
|
+
* additionally increment `stats.badCrc`. Reverse-readable records are
|
|
77
|
+
* not recognised.
|
|
78
|
+
*/
|
|
79
|
+
declare function binexRecords(data: Uint8Array, view: DataView, stats: {
|
|
80
|
+
badCrc: number;
|
|
81
|
+
}): Generator<BinexRecord>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* BINEX record 0x01 — decoded GNSS ephemeris — with the per-constellation
|
|
85
|
+
* subrecords laid out in RTKLIB src/rcv/binex.c:
|
|
86
|
+
*
|
|
87
|
+
* 0x01-01 GPS LNAV (decode_bnx_01_01)
|
|
88
|
+
* 0x01-02 GLONASS (decode_bnx_01_02)
|
|
89
|
+
* 0x01-03 SBAS (decode_bnx_01_03)
|
|
90
|
+
* 0x01-04 Galileo (decode_bnx_01_04)
|
|
91
|
+
* 0x01-05 BeiDou-2/3 (decode_bnx_01_05)
|
|
92
|
+
* 0x01-06 QZSS (decode_bnx_01_06)
|
|
93
|
+
*
|
|
94
|
+
* Ported from RTKLIB demo5/2.4.3 src/rcv/binex.c (Copyright (c) 2013-2018
|
|
95
|
+
* T. Takasu, BSD-2-Clause) and cross-checked against the EarthScope/UNAVCO
|
|
96
|
+
* BINEX definition and its reference RINEX fixtures.
|
|
97
|
+
*
|
|
98
|
+
* Output records mirror what `parseNavFile` produces for the equivalent
|
|
99
|
+
* RINEX navigation file, exactly like the SBF/NovAtel decoders:
|
|
100
|
+
* - the Keplerian angles M0/Ω0/ω/i0 arrive as radians on the wire (R8),
|
|
101
|
+
* while the rate terms Δn/Ω̇/İ arrive as semicircles (R4) and are
|
|
102
|
+
* scaled by π (IS-GPS-200 SC2RAD);
|
|
103
|
+
* - BeiDou epochs and weeks stay on the BDT scale (no BDT→GPST shift),
|
|
104
|
+
* matching a RINEX BDS record and the NovAtel decoder;
|
|
105
|
+
* - GLONASS state vectors are in km (PZ-90), the clock is −τ_n (the
|
|
106
|
+
* RINEX sign), the reference epoch is UTC, and `messageFrameTime` is
|
|
107
|
+
* the frame time `tof` as broadcast (seconds of day);
|
|
108
|
+
* - deferred subrecords: 0x01-00 (raw-byte ephemeris) and 0x01-14 (a
|
|
109
|
+
* newer Galileo encoding not covered by RTKLIB).
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Decode a record-0x01 ephemeris body. `body` points at the subrecord-ID
|
|
114
|
+
* byte. Returns the decoded `Ephemeris`, or null for an unsupported or
|
|
115
|
+
* malformed subrecord. Minimum body lengths mirror RTKLIB's guards.
|
|
116
|
+
*/
|
|
117
|
+
declare function decodeBinexEph(view: DataView, body: number, len: number, le: boolean): Ephemeris | null;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* BINEX (BINary EXchange) decoding — the path from a receiver BINEX log
|
|
121
|
+
* to RINEX-grade observables and broadcast ephemerides, mirroring the
|
|
122
|
+
* SBF and NovAtel decoders in this package.
|
|
123
|
+
*
|
|
124
|
+
* `parseBinex` runs a single framing pass over the byte stream and emits
|
|
125
|
+
* both observation epochs (record 0x7f-05, the obs record `convbin`
|
|
126
|
+
* reads) and decoded `Ephemeris` records (record 0x01, per-constellation
|
|
127
|
+
* subrecords). Frame walking, the ubnxi variable-length integer, the
|
|
128
|
+
* XOR-8/CRC16/CRC32 checksum models and the field layouts are ported
|
|
129
|
+
* from RTKLIB demo5/2.4.3 src/rcv/binex.c (Copyright (c) 2013-2018
|
|
130
|
+
* T. Takasu, BSD-2-Clause) and cross-checked against the
|
|
131
|
+
* EarthScope/UNAVCO BINEX definition and its reference RINEX fixtures.
|
|
132
|
+
*
|
|
133
|
+
* Framing (forward records only): a sync byte (0xE2 big-endian /
|
|
134
|
+
* 0xC2 little-endian, regular CRC; 0xE8/0xC8 enhanced CRC), the record
|
|
135
|
+
* ID, the message length (ubnxi), the body, then the checksum. The
|
|
136
|
+
* subrecord ID is the first body byte. Reverse-readable records
|
|
137
|
+
* (0xD2/0xF2/0xD8/0xF8 and terminating variants) are NOT decoded.
|
|
138
|
+
*
|
|
139
|
+
* Implemented: 0x7f-05 observations (multi-GNSS pseudorange, carrier
|
|
140
|
+
* phase, Doppler, C/N0, slip) and 0x01-01…06 ephemeris (GPS, GLONASS,
|
|
141
|
+
* SBAS, Galileo, BeiDou, QZSS). Deferred (counted, skipped): 0x00 site
|
|
142
|
+
* metadata, 0x02/0x03 generalized data, 0x7d/0x7e prototyping, the
|
|
143
|
+
* 0x7f-00…04 obs prototypes, 0x01-00 raw-byte ephemeris and 0x01-14.
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
interface BinexMeasurement {
|
|
147
|
+
/** RINEX PRN, e.g. "G04", "R11", "S23", "J01". */
|
|
148
|
+
prn: string;
|
|
149
|
+
/** RINEX band+attribute, e.g. "1C", "2W", "5Q", "2I". */
|
|
150
|
+
code: string;
|
|
151
|
+
/** Pseudorange (m). */
|
|
152
|
+
pr: number | null;
|
|
153
|
+
/** Carrier phase (cycles, RINEX sign), null when the frequency is unknown. */
|
|
154
|
+
cp: number | null;
|
|
155
|
+
/** Doppler (Hz), null when the record carries none for the signal. */
|
|
156
|
+
doppler: number | null;
|
|
157
|
+
/** C/N0 (dB-Hz). */
|
|
158
|
+
cn0: number | null;
|
|
159
|
+
/** Loss-of-lock / cycle-slip flag. */
|
|
160
|
+
slip: boolean;
|
|
161
|
+
}
|
|
162
|
+
interface BinexEpoch {
|
|
163
|
+
/** Receiver epoch (GPS-scale ms — same convention as the RINEX parser). */
|
|
164
|
+
timeMs: number;
|
|
165
|
+
meas: BinexMeasurement[];
|
|
166
|
+
}
|
|
167
|
+
interface BinexParseResult {
|
|
168
|
+
/** Observation epochs (record 0x7f-05), one per record. */
|
|
169
|
+
epochs: BinexEpoch[];
|
|
170
|
+
/** Broadcast ephemerides (record 0x01), duplicates suppressed. */
|
|
171
|
+
ephemerides: Ephemeris[];
|
|
172
|
+
/** Count per record/subrecord, keyed "0x7f-05" / "0x01-01" style. */
|
|
173
|
+
messageCounts: Record<string, number>;
|
|
174
|
+
/** Observation codes seen per system letter, in first-seen order. */
|
|
175
|
+
obsCodes: Record<string, string[]>;
|
|
176
|
+
/** Records whose checksum failed (corruption indicator). */
|
|
177
|
+
badCrc: number;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Decode every supported BINEX record in a byte stream: 0x7f-05
|
|
181
|
+
* observation epochs and 0x01-01…06 broadcast ephemerides. Repeated
|
|
182
|
+
* broadcasts of an unchanged ephemeris are suppressed the way RTKLIB
|
|
183
|
+
* does: GPS/Galileo/QZSS/BeiDou by issue of data (iode) plus toe and toc,
|
|
184
|
+
* GLONASS/SBAS by reference epoch and health. Other records are counted
|
|
185
|
+
* and skipped; checksum failures resync at the next byte.
|
|
186
|
+
*/
|
|
187
|
+
declare function parseBinex(data: Uint8Array): BinexParseResult;
|
|
188
|
+
|
|
189
|
+
export { type BinexEpoch, type BinexMeasurement, type BinexParseResult, type BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex };
|
package/dist/binex.d.ts
ADDED
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import { E as Ephemeris } from './nav-DImXUdbp.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* BINEX (BINary EXchange) framing, shared by the observation and
|
|
5
|
+
* navigation decoders.
|
|
6
|
+
*
|
|
7
|
+
* A forward-readable record is: a 1-byte sync that encodes byte order and
|
|
8
|
+
* checksum model, a record ID (ubnxi), a message length (ubnxi), the
|
|
9
|
+
* message body, then a trailing checksum whose width depends on the
|
|
10
|
+
* covered-byte count. Sync bytes (ref [1] §"Format Details"):
|
|
11
|
+
*
|
|
12
|
+
* 0xC2 little-endian, regular CRC (forward)
|
|
13
|
+
* 0xE2 big-endian, regular CRC (forward)
|
|
14
|
+
* 0xC8 little-endian, enhanced CRC (forward)
|
|
15
|
+
* 0xE8 big-endian, enhanced CRC (forward)
|
|
16
|
+
*
|
|
17
|
+
* The reverse-readable variants (0xD2/0xF2/0xD8/0xF8 leading and
|
|
18
|
+
* 0xB4/0xB0/0xE4/0xE0 terminating) are NOT decoded here (deferred).
|
|
19
|
+
*
|
|
20
|
+
* Checksum widths over the covered bytes N = recordID + lengthField +
|
|
21
|
+
* body (regular model): N ≤ 127 → 1-byte XOR; 128–4095 → CRC16
|
|
22
|
+
* (x^16+x^12+x^5+1, i.e. poly 0x1021 MSB-first, init 0); 4096–1048575 →
|
|
23
|
+
* CRC32 (poly 0x04C11DB7 MSB-first); ≥ 1048576 → 16-byte MD5. Enhanced
|
|
24
|
+
* model shifts every threshold up one step (CRC16 from 0 bytes, no XOR).
|
|
25
|
+
* The 16-byte MD5 case is not implemented (records that large do not
|
|
26
|
+
* occur in GNSS obs/eph streams); such a record is treated as bad.
|
|
27
|
+
*
|
|
28
|
+
* ubnxi (1–4 byte unsigned) and the field layouts are ported from RTKLIB
|
|
29
|
+
* demo5/2.4.3 src/rcv/binex.c (getbnxi, decode_bnx, Copyright (c)
|
|
30
|
+
* 2013-2018 T. Takasu, BSD-2-Clause) and cross-checked against the
|
|
31
|
+
* EarthScope/UNAVCO BINEX definition [1].
|
|
32
|
+
*
|
|
33
|
+
* [1] UNAVCO/EarthScope, BINEX: Binary exchange format
|
|
34
|
+
* (http://binex.unavco.org/binex.html).
|
|
35
|
+
*/
|
|
36
|
+
/** BINEX 2-byte CRC (x^16+x^12+x^5+1), init 0, MSB-first. */
|
|
37
|
+
declare function binexCrc16(data: Uint8Array, start: number, end: number): number;
|
|
38
|
+
/**
|
|
39
|
+
* BINEX 4-byte CRC (poly 0x04C11DB7), init 0, MSB-first. Not exercised
|
|
40
|
+
* by any known fixture (obs/eph records use XOR-8 or CRC16); implemented
|
|
41
|
+
* to spec but fixture-unverified.
|
|
42
|
+
*/
|
|
43
|
+
declare function binexCrc32(data: Uint8Array, start: number, end: number): number;
|
|
44
|
+
/** 8-bit XOR checksum of `data[start, end)`. */
|
|
45
|
+
declare function binexCsum8(data: Uint8Array, start: number, end: number): number;
|
|
46
|
+
/**
|
|
47
|
+
* Decode a BINEX ubnxi (1–4 byte unsigned integer, MSB-first) at
|
|
48
|
+
* `data[pos]`. The first up-to-three bytes contribute their low 7 bits
|
|
49
|
+
* with the high bit as a continuation flag; a fourth byte (reached only
|
|
50
|
+
* when the first three all continue) contributes all 8 bits. Returns the
|
|
51
|
+
* value and the number of bytes consumed (1–4). Ported from RTKLIB
|
|
52
|
+
* getbnxi.
|
|
53
|
+
*/
|
|
54
|
+
declare function getBnxi(data: Uint8Array, pos: number): {
|
|
55
|
+
value: number;
|
|
56
|
+
size: number;
|
|
57
|
+
};
|
|
58
|
+
/** One checksum-valid forward BINEX record located in a byte stream. */
|
|
59
|
+
interface BinexRecord {
|
|
60
|
+
/** Record ID (e.g. 0x01, 0x7f). */
|
|
61
|
+
id: number;
|
|
62
|
+
/** Offset of the sync byte. */
|
|
63
|
+
start: number;
|
|
64
|
+
/** Offset of the message body (first byte after the length field). */
|
|
65
|
+
body: number;
|
|
66
|
+
/** Message body length in bytes. */
|
|
67
|
+
len: number;
|
|
68
|
+
/** True when the sync selects little-endian field byte order. */
|
|
69
|
+
littleEndian: boolean;
|
|
70
|
+
/** True when the sync selects the enhanced-CRC model. */
|
|
71
|
+
enhanced: boolean;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Iterate every checksum-valid forward BINEX record in `data`. Corrupt
|
|
75
|
+
* or truncated candidates resync at the next byte; checksum failures
|
|
76
|
+
* additionally increment `stats.badCrc`. Reverse-readable records are
|
|
77
|
+
* not recognised.
|
|
78
|
+
*/
|
|
79
|
+
declare function binexRecords(data: Uint8Array, view: DataView, stats: {
|
|
80
|
+
badCrc: number;
|
|
81
|
+
}): Generator<BinexRecord>;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* BINEX record 0x01 — decoded GNSS ephemeris — with the per-constellation
|
|
85
|
+
* subrecords laid out in RTKLIB src/rcv/binex.c:
|
|
86
|
+
*
|
|
87
|
+
* 0x01-01 GPS LNAV (decode_bnx_01_01)
|
|
88
|
+
* 0x01-02 GLONASS (decode_bnx_01_02)
|
|
89
|
+
* 0x01-03 SBAS (decode_bnx_01_03)
|
|
90
|
+
* 0x01-04 Galileo (decode_bnx_01_04)
|
|
91
|
+
* 0x01-05 BeiDou-2/3 (decode_bnx_01_05)
|
|
92
|
+
* 0x01-06 QZSS (decode_bnx_01_06)
|
|
93
|
+
*
|
|
94
|
+
* Ported from RTKLIB demo5/2.4.3 src/rcv/binex.c (Copyright (c) 2013-2018
|
|
95
|
+
* T. Takasu, BSD-2-Clause) and cross-checked against the EarthScope/UNAVCO
|
|
96
|
+
* BINEX definition and its reference RINEX fixtures.
|
|
97
|
+
*
|
|
98
|
+
* Output records mirror what `parseNavFile` produces for the equivalent
|
|
99
|
+
* RINEX navigation file, exactly like the SBF/NovAtel decoders:
|
|
100
|
+
* - the Keplerian angles M0/Ω0/ω/i0 arrive as radians on the wire (R8),
|
|
101
|
+
* while the rate terms Δn/Ω̇/İ arrive as semicircles (R4) and are
|
|
102
|
+
* scaled by π (IS-GPS-200 SC2RAD);
|
|
103
|
+
* - BeiDou epochs and weeks stay on the BDT scale (no BDT→GPST shift),
|
|
104
|
+
* matching a RINEX BDS record and the NovAtel decoder;
|
|
105
|
+
* - GLONASS state vectors are in km (PZ-90), the clock is −τ_n (the
|
|
106
|
+
* RINEX sign), the reference epoch is UTC, and `messageFrameTime` is
|
|
107
|
+
* the frame time `tof` as broadcast (seconds of day);
|
|
108
|
+
* - deferred subrecords: 0x01-00 (raw-byte ephemeris) and 0x01-14 (a
|
|
109
|
+
* newer Galileo encoding not covered by RTKLIB).
|
|
110
|
+
*/
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Decode a record-0x01 ephemeris body. `body` points at the subrecord-ID
|
|
114
|
+
* byte. Returns the decoded `Ephemeris`, or null for an unsupported or
|
|
115
|
+
* malformed subrecord. Minimum body lengths mirror RTKLIB's guards.
|
|
116
|
+
*/
|
|
117
|
+
declare function decodeBinexEph(view: DataView, body: number, len: number, le: boolean): Ephemeris | null;
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* BINEX (BINary EXchange) decoding — the path from a receiver BINEX log
|
|
121
|
+
* to RINEX-grade observables and broadcast ephemerides, mirroring the
|
|
122
|
+
* SBF and NovAtel decoders in this package.
|
|
123
|
+
*
|
|
124
|
+
* `parseBinex` runs a single framing pass over the byte stream and emits
|
|
125
|
+
* both observation epochs (record 0x7f-05, the obs record `convbin`
|
|
126
|
+
* reads) and decoded `Ephemeris` records (record 0x01, per-constellation
|
|
127
|
+
* subrecords). Frame walking, the ubnxi variable-length integer, the
|
|
128
|
+
* XOR-8/CRC16/CRC32 checksum models and the field layouts are ported
|
|
129
|
+
* from RTKLIB demo5/2.4.3 src/rcv/binex.c (Copyright (c) 2013-2018
|
|
130
|
+
* T. Takasu, BSD-2-Clause) and cross-checked against the
|
|
131
|
+
* EarthScope/UNAVCO BINEX definition and its reference RINEX fixtures.
|
|
132
|
+
*
|
|
133
|
+
* Framing (forward records only): a sync byte (0xE2 big-endian /
|
|
134
|
+
* 0xC2 little-endian, regular CRC; 0xE8/0xC8 enhanced CRC), the record
|
|
135
|
+
* ID, the message length (ubnxi), the body, then the checksum. The
|
|
136
|
+
* subrecord ID is the first body byte. Reverse-readable records
|
|
137
|
+
* (0xD2/0xF2/0xD8/0xF8 and terminating variants) are NOT decoded.
|
|
138
|
+
*
|
|
139
|
+
* Implemented: 0x7f-05 observations (multi-GNSS pseudorange, carrier
|
|
140
|
+
* phase, Doppler, C/N0, slip) and 0x01-01…06 ephemeris (GPS, GLONASS,
|
|
141
|
+
* SBAS, Galileo, BeiDou, QZSS). Deferred (counted, skipped): 0x00 site
|
|
142
|
+
* metadata, 0x02/0x03 generalized data, 0x7d/0x7e prototyping, the
|
|
143
|
+
* 0x7f-00…04 obs prototypes, 0x01-00 raw-byte ephemeris and 0x01-14.
|
|
144
|
+
*/
|
|
145
|
+
|
|
146
|
+
interface BinexMeasurement {
|
|
147
|
+
/** RINEX PRN, e.g. "G04", "R11", "S23", "J01". */
|
|
148
|
+
prn: string;
|
|
149
|
+
/** RINEX band+attribute, e.g. "1C", "2W", "5Q", "2I". */
|
|
150
|
+
code: string;
|
|
151
|
+
/** Pseudorange (m). */
|
|
152
|
+
pr: number | null;
|
|
153
|
+
/** Carrier phase (cycles, RINEX sign), null when the frequency is unknown. */
|
|
154
|
+
cp: number | null;
|
|
155
|
+
/** Doppler (Hz), null when the record carries none for the signal. */
|
|
156
|
+
doppler: number | null;
|
|
157
|
+
/** C/N0 (dB-Hz). */
|
|
158
|
+
cn0: number | null;
|
|
159
|
+
/** Loss-of-lock / cycle-slip flag. */
|
|
160
|
+
slip: boolean;
|
|
161
|
+
}
|
|
162
|
+
interface BinexEpoch {
|
|
163
|
+
/** Receiver epoch (GPS-scale ms — same convention as the RINEX parser). */
|
|
164
|
+
timeMs: number;
|
|
165
|
+
meas: BinexMeasurement[];
|
|
166
|
+
}
|
|
167
|
+
interface BinexParseResult {
|
|
168
|
+
/** Observation epochs (record 0x7f-05), one per record. */
|
|
169
|
+
epochs: BinexEpoch[];
|
|
170
|
+
/** Broadcast ephemerides (record 0x01), duplicates suppressed. */
|
|
171
|
+
ephemerides: Ephemeris[];
|
|
172
|
+
/** Count per record/subrecord, keyed "0x7f-05" / "0x01-01" style. */
|
|
173
|
+
messageCounts: Record<string, number>;
|
|
174
|
+
/** Observation codes seen per system letter, in first-seen order. */
|
|
175
|
+
obsCodes: Record<string, string[]>;
|
|
176
|
+
/** Records whose checksum failed (corruption indicator). */
|
|
177
|
+
badCrc: number;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Decode every supported BINEX record in a byte stream: 0x7f-05
|
|
181
|
+
* observation epochs and 0x01-01…06 broadcast ephemerides. Repeated
|
|
182
|
+
* broadcasts of an unchanged ephemeris are suppressed the way RTKLIB
|
|
183
|
+
* does: GPS/Galileo/QZSS/BeiDou by issue of data (iode) plus toe and toc,
|
|
184
|
+
* GLONASS/SBAS by reference epoch and health. Other records are counted
|
|
185
|
+
* and skipped; checksum failures resync at the next byte.
|
|
186
|
+
*/
|
|
187
|
+
declare function parseBinex(data: Uint8Array): BinexParseResult;
|
|
188
|
+
|
|
189
|
+
export { type BinexEpoch, type BinexMeasurement, type BinexParseResult, type BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex };
|
package/dist/binex.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
binexCrc16,
|
|
3
|
+
binexCrc32,
|
|
4
|
+
binexCsum8,
|
|
5
|
+
binexRecords,
|
|
6
|
+
decodeBinexEph,
|
|
7
|
+
getBnxi,
|
|
8
|
+
parseBinex
|
|
9
|
+
} from "./chunk-OK4GGNOO.js";
|
|
10
|
+
import "./chunk-IQ5OIMQD.js";
|
|
11
|
+
export {
|
|
12
|
+
binexCrc16,
|
|
13
|
+
binexCrc32,
|
|
14
|
+
binexCsum8,
|
|
15
|
+
binexRecords,
|
|
16
|
+
decodeBinexEph,
|
|
17
|
+
getBnxi,
|
|
18
|
+
parseBinex
|
|
19
|
+
};
|
|
@@ -1,147 +1,12 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
let bits = 0;
|
|
7
|
-
for (let i = pos; i < pos + len; i++) {
|
|
8
|
-
bits = bits * 2 + (buff[i >> 3] >> 7 - (i & 7) & 1);
|
|
9
|
-
}
|
|
10
|
-
return bits;
|
|
11
|
-
}
|
|
12
|
-
function getBitS(buff, pos, len) {
|
|
13
|
-
const bits = getBitU(buff, pos, len);
|
|
14
|
-
if (len <= 0 || bits < 2 ** (len - 1)) return bits;
|
|
15
|
-
return bits - 2 ** len;
|
|
16
|
-
}
|
|
17
|
-
function setBitU(buff, pos, len, data) {
|
|
18
|
-
let mask = 2 ** (len - 1);
|
|
19
|
-
for (let i = pos; i < pos + len; i++, mask /= 2) {
|
|
20
|
-
if (data >= mask) {
|
|
21
|
-
buff[i >> 3] |= 1 << 7 - (i & 7);
|
|
22
|
-
data -= mask;
|
|
23
|
-
} else {
|
|
24
|
-
buff[i >> 3] &= ~(1 << 7 - (i & 7));
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
function decodeGpsLnavFrame(subframes, opts = {}) {
|
|
29
|
-
if (subframes.length < 90) return null;
|
|
30
|
-
const b = subframes;
|
|
31
|
-
let i = 24;
|
|
32
|
-
const tow1 = getBitU(b, i, 17) * 6;
|
|
33
|
-
i += 17 + 2;
|
|
34
|
-
const id1 = getBitU(b, i, 3);
|
|
35
|
-
i += 3 + 2;
|
|
36
|
-
const week10 = getBitU(b, i, 10);
|
|
37
|
-
i += 10;
|
|
38
|
-
i += 2;
|
|
39
|
-
i += 4;
|
|
40
|
-
const svHealth = getBitU(b, i, 6);
|
|
41
|
-
i += 6;
|
|
42
|
-
const iodc0 = getBitU(b, i, 2);
|
|
43
|
-
i += 2;
|
|
44
|
-
i += 1 + 87;
|
|
45
|
-
const tgdRaw = getBitS(b, i, 8);
|
|
46
|
-
i += 8;
|
|
47
|
-
const iodc1 = getBitU(b, i, 8);
|
|
48
|
-
i += 8;
|
|
49
|
-
const tocSec = getBitU(b, i, 16) * 16;
|
|
50
|
-
i += 16;
|
|
51
|
-
const af2 = getBitS(b, i, 8) * 2 ** -55;
|
|
52
|
-
i += 8;
|
|
53
|
-
const af1 = getBitS(b, i, 16) * 2 ** -43;
|
|
54
|
-
i += 16;
|
|
55
|
-
const af0 = getBitS(b, i, 22) * 2 ** -31;
|
|
56
|
-
i = 240 + 24;
|
|
57
|
-
i += 17 + 2;
|
|
58
|
-
const id2 = getBitU(b, i, 3);
|
|
59
|
-
i += 3 + 2;
|
|
60
|
-
const iode = getBitU(b, i, 8);
|
|
61
|
-
i += 8;
|
|
62
|
-
const crs = getBitS(b, i, 16) * 2 ** -5;
|
|
63
|
-
i += 16;
|
|
64
|
-
const deltaN = getBitS(b, i, 16) * 2 ** -43 * GPS_PI;
|
|
65
|
-
i += 16;
|
|
66
|
-
const m0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
|
|
67
|
-
i += 32;
|
|
68
|
-
const cuc = getBitS(b, i, 16) * 2 ** -29;
|
|
69
|
-
i += 16;
|
|
70
|
-
const e = getBitU(b, i, 32) * 2 ** -33;
|
|
71
|
-
i += 32;
|
|
72
|
-
const cus = getBitS(b, i, 16) * 2 ** -29;
|
|
73
|
-
i += 16;
|
|
74
|
-
const sqrtA = getBitU(b, i, 32) * 2 ** -19;
|
|
75
|
-
i += 32;
|
|
76
|
-
const toes = getBitU(b, i, 16) * 16;
|
|
77
|
-
i = 480 + 24;
|
|
78
|
-
i += 17 + 2;
|
|
79
|
-
const id3 = getBitU(b, i, 3);
|
|
80
|
-
i += 3 + 2;
|
|
81
|
-
const cic = getBitS(b, i, 16) * 2 ** -29;
|
|
82
|
-
i += 16;
|
|
83
|
-
const omega0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
|
|
84
|
-
i += 32;
|
|
85
|
-
const cis = getBitS(b, i, 16) * 2 ** -29;
|
|
86
|
-
i += 16;
|
|
87
|
-
const i0 = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
|
|
88
|
-
i += 32;
|
|
89
|
-
const crc = getBitS(b, i, 16) * 2 ** -5;
|
|
90
|
-
i += 16;
|
|
91
|
-
const omega = getBitS(b, i, 32) * 2 ** -31 * GPS_PI;
|
|
92
|
-
i += 32;
|
|
93
|
-
const omegaDot = getBitS(b, i, 24) * 2 ** -43 * GPS_PI;
|
|
94
|
-
i += 24;
|
|
95
|
-
const iode3 = getBitU(b, i, 8);
|
|
96
|
-
i += 8;
|
|
97
|
-
const idot = getBitS(b, i, 14) * 2 ** -43 * GPS_PI;
|
|
98
|
-
const iodc = iodc0 * 256 + iodc1;
|
|
99
|
-
if (id1 !== 1 || id2 !== 2 || id3 !== 3) return null;
|
|
100
|
-
if (iode3 !== iode || iode !== (iodc & 255)) return null;
|
|
101
|
-
const ref = opts.refWeek ?? Math.floor((Date.now() - GPS_EPOCH_MS) / 1e3 / SEC_PER_WEEK);
|
|
102
|
-
let week = week10 + 1024 * Math.round((ref - week10) / 1024);
|
|
103
|
-
if (toes < tow1 - 302400) week++;
|
|
104
|
-
else if (toes > tow1 + 302400) week--;
|
|
105
|
-
const prn = opts.prn ?? "G00";
|
|
106
|
-
const tocDate = new Date(
|
|
107
|
-
GPS_EPOCH_MS + (week * SEC_PER_WEEK + tocSec) * 1e3
|
|
108
|
-
);
|
|
109
|
-
return {
|
|
110
|
-
system: prn[0] === "J" ? "J" : "G",
|
|
111
|
-
prn,
|
|
112
|
-
tocDate,
|
|
113
|
-
// Same seconds-of-week convention as parseNavFile (rinex/nav.ts).
|
|
114
|
-
toc: tocDate.getTime() / 1e3 % SEC_PER_WEEK,
|
|
115
|
-
af0,
|
|
116
|
-
af1,
|
|
117
|
-
af2,
|
|
118
|
-
iode,
|
|
119
|
-
crs,
|
|
120
|
-
deltaN,
|
|
121
|
-
m0,
|
|
122
|
-
cuc,
|
|
123
|
-
e,
|
|
124
|
-
cus,
|
|
125
|
-
sqrtA,
|
|
126
|
-
toe: toes,
|
|
127
|
-
cic,
|
|
128
|
-
omega0,
|
|
129
|
-
cis,
|
|
130
|
-
i0,
|
|
131
|
-
crc,
|
|
132
|
-
omega,
|
|
133
|
-
omegaDot,
|
|
134
|
-
idot,
|
|
135
|
-
week,
|
|
136
|
-
svHealth,
|
|
137
|
-
tgd: tgdRaw === -128 ? 0 : tgdRaw * 2 ** -31
|
|
138
|
-
// IS-GPS-200: -128 reserved
|
|
139
|
-
};
|
|
140
|
-
}
|
|
1
|
+
import {
|
|
2
|
+
GPS_PI,
|
|
3
|
+
getBitS,
|
|
4
|
+
getBitU
|
|
5
|
+
} from "./chunk-IQ5OIMQD.js";
|
|
141
6
|
|
|
142
7
|
// src/navbits/cnav.ts
|
|
143
|
-
var
|
|
144
|
-
var
|
|
8
|
+
var GPS_EPOCH_MS = Date.UTC(1980, 0, 6);
|
|
9
|
+
var SEC_PER_WEEK = 7 * 86400;
|
|
145
10
|
var HALF_WEEK = 302400;
|
|
146
11
|
var CNAV_PREAMBLE = 139;
|
|
147
12
|
var CNAV_A_REF = 26559710;
|
|
@@ -245,7 +110,7 @@ function resolveWeek(week, towSec, sec) {
|
|
|
245
110
|
return week;
|
|
246
111
|
}
|
|
247
112
|
function gpsDate(week, sec) {
|
|
248
|
-
return new Date(
|
|
113
|
+
return new Date(GPS_EPOCH_MS + (week * SEC_PER_WEEK + sec) * 1e3);
|
|
249
114
|
}
|
|
250
115
|
var CnavAssembler = class {
|
|
251
116
|
sats = /* @__PURE__ */ new Map();
|
|
@@ -336,11 +201,6 @@ var CnavAssembler = class {
|
|
|
336
201
|
};
|
|
337
202
|
|
|
338
203
|
export {
|
|
339
|
-
GPS_PI,
|
|
340
|
-
getBitU,
|
|
341
|
-
getBitS,
|
|
342
|
-
setBitU,
|
|
343
|
-
decodeGpsLnavFrame,
|
|
344
204
|
CNAV_A_REF,
|
|
345
205
|
CNAV_OMEGA_DOT_REF,
|
|
346
206
|
crc24q,
|
|
@@ -7,14 +7,16 @@ import {
|
|
|
7
7
|
galFnavPageCrcOk,
|
|
8
8
|
galInavPageCrcOk,
|
|
9
9
|
testGloString
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-5AUK42AL.js";
|
|
11
11
|
import {
|
|
12
12
|
CnavAssembler,
|
|
13
13
|
cnavCrcOk,
|
|
14
|
-
crc24q
|
|
14
|
+
crc24q
|
|
15
|
+
} from "./chunk-726LQBGM.js";
|
|
16
|
+
import {
|
|
15
17
|
getBitS,
|
|
16
18
|
getBitU
|
|
17
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-IQ5OIMQD.js";
|
|
18
20
|
import {
|
|
19
21
|
getGpsLeap
|
|
20
22
|
} from "./chunk-HVXYFUCB.js";
|