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/index.d.cts CHANGED
@@ -4,7 +4,7 @@ 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 { CompactEpoch, CrxField, DiffState, EMPTY_WARNINGS, Nav4Input, RinexWarning, RinexWarnings, Sp3File, Sp3Sample, WarningAccumulator, WarningSeverity, createGzipLineSink, crxDecompress, crxRepair, fmtD, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseSp3, sp3Position, stationHeaderLines, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob } from './rinex.cjs';
7
+ export { CompactEpoch, CrxField, DiffState, EMPTY_WARNINGS, Nav4Input, RinexWarning, RinexWarnings, Sp3File, Sp3Sample, WarningAccumulator, WarningSeverity, WriteCrxOptions, createGzipLineSink, crxDecompress, crxRepair, fmtD, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseSp3, sp3Position, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, 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 { C as CnavEphemeris, E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, R as RinexCnavEphemeris, p as parseNavFile } from './nav-DImXUdbp.cjs';
10
10
  export { I as IonexGrid, p as parseIonex } from './ionex-DaW5x9nq.cjs';
@@ -13,6 +13,8 @@ export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES,
13
13
  export { UbxCnavResult, UbxFrame, UbxIonoUtcResult, UbxMeasurement, UbxNavOptions, UbxNavResult, UbxParseResult, UbxRawNavOptions, UbxRawNavResult, UbxRawxEpoch, parseUbxCnav, parseUbxIonoUtc, parseUbxNav, parseUbxRawNav, parseUbxRawx, ubxFrames } from './ubx.cjs';
14
14
  export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGloNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfParseResult, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, sbfCrc16, scanSbfFrames } from './sbf.cjs';
15
15
  export { NovatelEpoch, NovatelMeasurement, NovatelNavResult, NovatelParseResult, OEM4_HLEN, Oem4Frame, crc32, oem4Frames, parseNovatelNav, parseNovatelRange } from './novatel.cjs';
16
+ export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, TrimbleParseResult, parseTrimble, parseTrimbleNav, trimbleFrames } from './trimble.cjs';
17
+ export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.cjs';
16
18
  export { AllPositionsData, AlmanacPosition, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, almanacEpochMs, almanacSatPosition, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, computeVisibilityFromPositions, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassAlmanacEpochMs, glonassAlmanacPosition, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.cjs';
17
19
  export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.cjs';
18
20
  export { DgnssOptions, DgnssSolution, EphemerisSource, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, SppOptions, SppSolution, gimSlantIonoDelayL1, gimVerticalTec, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, satClockCorrection, solveDgnss, solveSpp, toRtkEpoch } from './positioning.cjs';
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ 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 { CompactEpoch, CrxField, DiffState, EMPTY_WARNINGS, Nav4Input, RinexWarning, RinexWarnings, Sp3File, Sp3Sample, WarningAccumulator, WarningSeverity, createGzipLineSink, crxDecompress, crxRepair, fmtD, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseSp3, sp3Position, stationHeaderLines, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, writeRinexObsBlob } from './rinex.js';
7
+ export { CompactEpoch, CrxField, DiffState, EMPTY_WARNINGS, Nav4Input, RinexWarning, RinexWarnings, Sp3File, Sp3Sample, WarningAccumulator, WarningSeverity, WriteCrxOptions, createGzipLineSink, crxDecompress, crxRepair, fmtD, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseSp3, sp3Position, stationHeaderLines, writeCrx, writeModernObsBlob, writeRinex2ObsBlob, writeRinex4ObsBlob, writeRinexNav, writeRinexNav4, 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 { C as CnavEphemeris, E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, R as RinexCnavEphemeris, p as parseNavFile } from './nav-DImXUdbp.js';
10
10
  export { I as IonexGrid, p as parseIonex } from './ionex-DaW5x9nq.js';
@@ -13,6 +13,8 @@ export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES,
13
13
  export { UbxCnavResult, UbxFrame, UbxIonoUtcResult, UbxMeasurement, UbxNavOptions, UbxNavResult, UbxParseResult, UbxRawNavOptions, UbxRawNavResult, UbxRawxEpoch, parseUbxCnav, parseUbxIonoUtc, parseUbxNav, parseUbxRawNav, parseUbxRawx, ubxFrames } from './ubx.js';
14
14
  export { HasMessage, SbfBdsNavResult, SbfCnavEphemeris, SbfCnavResult, SbfGalEphemeris, SbfGalNavResult, SbfGloNavResult, SbfHasMessage, SbfHasResult, SbfIonoUtcResult, SbfMeasEpoch, SbfMeasurement, SbfParseResult, parseSbfBdsNav, parseSbfCnav, parseSbfGalNav, parseSbfGloNav, parseSbfHas, parseSbfIonoUtc, parseSbfMeas, sbfCrc16, scanSbfFrames } from './sbf.js';
15
15
  export { NovatelEpoch, NovatelMeasurement, NovatelNavResult, NovatelParseResult, OEM4_HLEN, Oem4Frame, crc32, oem4Frames, parseNovatelNav, parseNovatelRange } from './novatel.js';
16
+ export { TrimbleEpoch, TrimbleFrame, TrimbleMeasurement, TrimbleNavResult, TrimbleParseResult, parseTrimble, parseTrimbleNav, trimbleFrames } from './trimble.js';
17
+ export { BinexEpoch, BinexMeasurement, BinexParseResult, BinexRecord, binexCrc16, binexCrc32, binexCsum8, binexRecords, decodeBinexEph, getBnxi, parseBinex } from './binex.js';
16
18
  export { AllPositionsData, AlmanacPosition, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, almanacEpochMs, almanacSatPosition, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, computeVisibilityFromPositions, dopplerHz, ecefToAzEl, ephInfoToEphemeris, glonassAlmanacEpochMs, glonassAlmanacPosition, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, rangeRate, selectEphemeris } from './orbit.js';
17
19
  export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.js';
18
20
  export { DgnssOptions, DgnssSolution, EphemerisSource, IONO_L1_M_PER_TECU, KlobucharCoeffs, LambdaResult, RawObservation, RtkEpochMeasurements, RtkFloatEngine, RtkFloatOptions, RtkFloatSolution, RtkMeasurement, SppOptions, SppSolution, gimSlantIonoDelayL1, gimVerticalTec, ionoFree, klobucharDelay, lambdaReduction, lambdaSearch, satClockCorrection, solveDgnss, solveSpp, toRtkEpoch } from './positioning.js';
package/dist/index.js CHANGED
@@ -1,3 +1,13 @@
1
+ import {
2
+ frequencyLabel,
3
+ parseAntex
4
+ } from "./chunk-5CMSYIYM.js";
5
+ import {
6
+ computeStats,
7
+ nmeaCoordToDecimal,
8
+ parseNmeaFile,
9
+ verifyChecksum
10
+ } from "./chunk-YDMYO3YK.js";
1
11
  import {
2
12
  BAND_PRESETS,
3
13
  CONSTELLATIONS,
@@ -40,7 +50,7 @@ import {
40
50
  parseUbxRawNav,
41
51
  parseUbxRawx,
42
52
  ubxFrames
43
- } from "./chunk-MCAVU3XL.js";
53
+ } from "./chunk-FEOMYZEU.js";
44
54
  import {
45
55
  crc16,
46
56
  parseSbfAlmanac,
@@ -53,15 +63,29 @@ import {
53
63
  parseSbfMeas,
54
64
  parseSbfNav,
55
65
  scanSbfFrames
56
- } from "./chunk-PZNVFCKJ.js";
57
- import "./chunk-VTX3VCL4.js";
66
+ } from "./chunk-AFEDNWXI.js";
67
+ import "./chunk-5AUK42AL.js";
58
68
  import {
59
69
  OEM4_HLEN,
60
70
  crc32,
61
71
  oem4Frames,
62
72
  parseNovatelNav,
63
73
  parseNovatelRange
64
- } from "./chunk-7RKLWE6R.js";
74
+ } from "./chunk-F4CM6Q4F.js";
75
+ import {
76
+ parseTrimble,
77
+ parseTrimbleNav,
78
+ trimbleFrames
79
+ } from "./chunk-CKRNXZHT.js";
80
+ import {
81
+ binexCrc16,
82
+ binexCrc32,
83
+ binexCsum8,
84
+ binexRecords,
85
+ decodeBinexEph,
86
+ getBnxi,
87
+ parseBinex
88
+ } from "./chunk-OK4GGNOO.js";
65
89
  import {
66
90
  connectToMountpoint,
67
91
  fetchSourcetable,
@@ -78,16 +102,6 @@ import {
78
102
  detrendIonoArcs,
79
103
  parseSinexBiasDcb
80
104
  } from "./chunk-Z5UZUNCB.js";
81
- import {
82
- frequencyLabel,
83
- parseAntex
84
- } from "./chunk-5CMSYIYM.js";
85
- import {
86
- computeStats,
87
- nmeaCoordToDecimal,
88
- parseNmeaFile,
89
- verifyChecksum
90
- } from "./chunk-YDMYO3YK.js";
91
105
  import {
92
106
  Scale,
93
107
  getDateFromDayOfWeek,
@@ -190,14 +204,16 @@ import {
190
204
  parseSp3,
191
205
  sp3Position,
192
206
  stationHeaderLines,
207
+ writeCrx,
193
208
  writeModernObsBlob,
194
209
  writeRinex2ObsBlob,
195
210
  writeRinex4ObsBlob,
196
211
  writeRinexNav,
197
212
  writeRinexNav4,
198
213
  writeRinexObsBlob
199
- } from "./chunk-NOQAAUGY.js";
200
- import "./chunk-WZDFZ76K.js";
214
+ } from "./chunk-QVNNHACQ.js";
215
+ import "./chunk-726LQBGM.js";
216
+ import "./chunk-IQ5OIMQD.js";
201
217
  import {
202
218
  SYSTEM_ORDER,
203
219
  crxDecompress,
@@ -400,6 +416,10 @@ export {
400
416
  analyzeQuality,
401
417
  applyHelmert,
402
418
  applyIonoDcb,
419
+ binexCrc16,
420
+ binexCrc32,
421
+ binexCsum8,
422
+ binexRecords,
403
423
  buildGloChannelMap,
404
424
  buildObsIndices,
405
425
  clampUnit,
@@ -420,6 +440,7 @@ export {
420
440
  crxDecompress,
421
441
  crxRepair,
422
442
  dateToEpoch,
443
+ decodeBinexEph,
423
444
  decodeEphemeris,
424
445
  decodeMsmFull,
425
446
  deg2dms,
@@ -441,6 +462,7 @@ export {
441
462
  geodeticToUtm,
442
463
  getAer,
443
464
  getBdsTime,
465
+ getBnxi,
444
466
  getDateFromBdsTime,
445
467
  getDateFromDayOfWeek,
446
468
  getDateFromDayOfYear,
@@ -514,6 +536,7 @@ export {
514
536
  padL,
515
537
  padR,
516
538
  parseAntex,
539
+ parseBinex,
517
540
  parseCrxDataLine,
518
541
  parseIonex,
519
542
  parseNavFile,
@@ -533,6 +556,8 @@ export {
533
556
  parseSinexBiasDcb,
534
557
  parseSourcetable,
535
558
  parseSp3,
559
+ parseTrimble,
560
+ parseTrimbleNav,
536
561
  parseUbxCnav,
537
562
  parseUbxIonoUtc,
538
563
  parseUbxNav,
@@ -563,11 +588,13 @@ export {
563
588
  systemName,
564
589
  toRtkEpoch,
565
590
  transformFrame,
591
+ trimbleFrames,
566
592
  ubxFrames,
567
593
  updateStationMeta,
568
594
  updateStreamStats,
569
595
  verifyChecksum,
570
596
  vincenty,
597
+ writeCrx,
571
598
  writeModernObsBlob,
572
599
  writeRinex2ObsBlob,
573
600
  writeRinex4ObsBlob,
package/dist/novatel.js CHANGED
@@ -4,8 +4,9 @@ import {
4
4
  oem4Frames,
5
5
  parseNovatelNav,
6
6
  parseNovatelRange
7
- } from "./chunk-7RKLWE6R.js";
8
- import "./chunk-WZDFZ76K.js";
7
+ } from "./chunk-F4CM6Q4F.js";
8
+ import "./chunk-726LQBGM.js";
9
+ import "./chunk-IQ5OIMQD.js";
9
10
  import "./chunk-HVXYFUCB.js";
10
11
  import "./chunk-LEEU5OIO.js";
11
12
  export {
package/dist/rinex.cjs CHANGED
@@ -40,6 +40,7 @@ __export(rinex_exports, {
40
40
  stationHeaderLines: () => stationHeaderLines,
41
41
  systemCmp: () => systemCmp,
42
42
  systemName: () => systemName,
43
+ writeCrx: () => writeCrx,
43
44
  writeModernObsBlob: () => writeModernObsBlob,
44
45
  writeRinex2ObsBlob: () => writeRinex2ObsBlob,
45
46
  writeRinex4ObsBlob: () => writeRinex4ObsBlob,
@@ -134,6 +135,442 @@ function crxDecompress(prev, field) {
134
135
  };
135
136
  }
136
137
 
138
+ // src/rinex/crx-writer.ts
139
+ var ARC_ORDER = 3;
140
+ function emptyData() {
141
+ return { u: [0, 0, 0, 0], l: [0, 0, 0, 0], order: -1 };
142
+ }
143
+ function cAtol(s) {
144
+ let i = 0;
145
+ while (i < s.length && (s[i] === " " || s[i] === " ")) i++;
146
+ let sign = 1;
147
+ if (s[i] === "+" || s[i] === "-") {
148
+ if (s[i] === "-") sign = -1;
149
+ i++;
150
+ }
151
+ let n = 0;
152
+ let any = false;
153
+ while (i < s.length && s[i] >= "0" && s[i] <= "9") {
154
+ n = n * 10 + (s.charCodeAt(i) - 48);
155
+ i++;
156
+ any = true;
157
+ }
158
+ return any ? sign * n : 0;
159
+ }
160
+ function strdiff(s1, s2) {
161
+ let ds = "";
162
+ const n = Math.min(s1.length, s2.length);
163
+ let i = 0;
164
+ for (; i < n; i++) {
165
+ if (s2[i] === s1[i]) ds += " ";
166
+ else if (s2[i] === " ") ds += "&";
167
+ else ds += s2[i];
168
+ }
169
+ if (s1.length > s2.length) {
170
+ for (let k = i; k < s1.length; k++) ds += s1[k] === " " ? " " : "&";
171
+ } else if (s2.length > s1.length) {
172
+ ds += s2.slice(i);
173
+ }
174
+ let end = ds.length;
175
+ while (end > 0 && ds[end - 1] === " ") end--;
176
+ return ds.slice(0, end);
177
+ }
178
+ function readValue(field14) {
179
+ const c = field14.padEnd(14, " ").split("");
180
+ const p7 = c[7];
181
+ c[10] = c[9];
182
+ c[9] = c[8];
183
+ let l = cAtol(c.slice(9, 14).join(""));
184
+ let u;
185
+ if (p7 === " ") {
186
+ u = 0;
187
+ } else if (p7 === "-") {
188
+ u = 0;
189
+ l = -l;
190
+ } else {
191
+ c[8] = ".";
192
+ u = cAtol(c.slice(0, 14).join(""));
193
+ if (u < 0) l = -l;
194
+ }
195
+ return { u, l };
196
+ }
197
+ function putdiff(dddu, dddl) {
198
+ dddu += Math.trunc(dddl / 1e5);
199
+ dddl %= 1e5;
200
+ if (dddu < 0 && dddl > 0) {
201
+ dddu++;
202
+ dddl -= 1e5;
203
+ } else if (dddu > 0 && dddl < 0) {
204
+ dddu--;
205
+ dddl += 1e5;
206
+ }
207
+ if (dddu === 0) return String(dddl);
208
+ return `${dddu}${String(Math.abs(dddl)).padStart(5, "0")}`;
209
+ }
210
+ function putClock(du, dl, cOrder) {
211
+ du += Math.trunc(dl / 1e8);
212
+ dl %= 1e8;
213
+ if (du < 0 && dl > 0) {
214
+ du++;
215
+ dl -= 1e8;
216
+ } else if (du > 0 && dl < 0) {
217
+ du--;
218
+ dl += 1e8;
219
+ }
220
+ let out = "";
221
+ if (cOrder === 0) out += `${ARC_ORDER}&`;
222
+ if (du === 0) out += String(dl);
223
+ else out += `${du}${String(Math.abs(dl)).padStart(8, "0")}`;
224
+ return out;
225
+ }
226
+ function chop(line) {
227
+ let end = line.length;
228
+ if (end > 0 && line[end - 1] === "\r") end--;
229
+ while (end > 0 && line[end - 1] === " ") end--;
230
+ return line.slice(0, end);
231
+ }
232
+ function readSat(lines, cursor, rinexVersion, ntype, ntypeGnss) {
233
+ let line = chop(lines[cursor.li++] ?? "");
234
+ let maxField;
235
+ let ntypeRec;
236
+ let firstRec;
237
+ let satId = "";
238
+ if (rinexVersion === 2) {
239
+ maxField = 5;
240
+ ntypeRec = ntype;
241
+ firstRec = 0;
242
+ } else {
243
+ satId = line.slice(0, 3);
244
+ const sys = line[0];
245
+ maxField = ntypeRec = ntypeGnss[sys] ?? -1;
246
+ if (maxField < 0) return null;
247
+ firstRec = 3;
248
+ }
249
+ const data = [];
250
+ let flag = "";
251
+ for (let i = 0; i < ntypeRec; i += maxField) {
252
+ const nfield = Math.min(ntypeRec - i, maxField);
253
+ const need = firstRec + 16 * nfield;
254
+ let body = line;
255
+ if (body.length < need) body = body.padEnd(need, " ");
256
+ for (let j = 0; j < nfield; j++) {
257
+ const p = firstRec + j * 16;
258
+ const rec = body.slice(p, p + 16);
259
+ const d = emptyData();
260
+ if (rec[10] === ".") {
261
+ flag += rec[14] ?? " ";
262
+ flag += rec[15] ?? " ";
263
+ const v = readValue(rec.slice(0, 14));
264
+ d.u[0] = v.u;
265
+ d.l[0] = v.l;
266
+ d.order = 0;
267
+ } else if (rec.slice(0, 14).trim() === "") {
268
+ flag += rec[14] ?? " ";
269
+ flag += rec[15] ?? " ";
270
+ d.order = -1;
271
+ } else {
272
+ return null;
273
+ }
274
+ data.push(d);
275
+ }
276
+ if (i + maxField < ntypeRec) {
277
+ line = chop(lines[cursor.li++] ?? "");
278
+ }
279
+ }
280
+ return { sat: { data, flag, ntypeRec }, satId };
281
+ }
282
+ var MONTHS = [
283
+ "Jan",
284
+ "Feb",
285
+ "Mar",
286
+ "Apr",
287
+ "May",
288
+ "Jun",
289
+ "Jul",
290
+ "Aug",
291
+ "Sep",
292
+ "Oct",
293
+ "Nov",
294
+ "Dec"
295
+ ];
296
+ function crinexDate() {
297
+ const d = /* @__PURE__ */ new Date();
298
+ const dd = String(d.getUTCDate()).padStart(2, "0");
299
+ const mon = MONTHS[d.getUTCMonth()];
300
+ const yy = String(d.getUTCFullYear() % 100).padStart(2, "0");
301
+ const hh = String(d.getUTCHours()).padStart(2, "0");
302
+ const mm = String(d.getUTCMinutes()).padStart(2, "0");
303
+ return `${dd}-${mon}-${yy} ${hh}:${mm}`;
304
+ }
305
+ function writeCrx(rinexText, opts = {}) {
306
+ const rawLines = rinexText.split("\n");
307
+ const cursor = { li: 0 };
308
+ const out = [];
309
+ const firstLine = chop(rawLines[cursor.li++] ?? "");
310
+ if (firstLine.slice(60, 80) !== "RINEX VERSION / TYPE" || firstLine[20] !== "O") {
311
+ throw new Error("writeCrx: not a RINEX observation file");
312
+ }
313
+ const rinexVersion = parseInt(firstLine, 10);
314
+ const rinexVersionFull = readVersionFull(firstLine);
315
+ if (rinexVersionFull < 0) throw new Error("writeCrx: invalid RINEX version");
316
+ const crxVersion = rinexVersionFull >= 402 ? "3.1" : rinexVersion === 2 ? "1.0" : "3.0";
317
+ out.push(
318
+ `${crxVersion.padEnd(20)}${"COMPACT RINEX FORMAT".padEnd(40)}${"CRINEX VERS / TYPE".padEnd(20)}`
319
+ );
320
+ const prog = (opts.prog ?? "gnss-js writeCrx").slice(0, 40);
321
+ const date = opts.date ?? crinexDate();
322
+ out.push(`${prog.padEnd(40)}${date.padEnd(20)}CRINEX PROG / DATE`);
323
+ out.push(firstLine);
324
+ let ntype = 0;
325
+ const ntypeGnss = {};
326
+ let line;
327
+ do {
328
+ line = chop(rawLines[cursor.li++] ?? "");
329
+ out.push(line);
330
+ const label = line.slice(60).trimStart();
331
+ if (label.startsWith("# / TYPES OF OBSERV") && line[5] !== " ") {
332
+ ntype = parseInt(line, 10);
333
+ } else if (label.startsWith("SYS / # / OBS TYPES") && line[0] !== " ") {
334
+ ntypeGnss[line[0]] = parseInt(line.slice(3), 10);
335
+ }
336
+ if (cursor.li >= rawLines.length) break;
337
+ } while (!line.slice(60).trimStart().startsWith("END OF HEADER"));
338
+ const v2 = rinexVersion === 2;
339
+ const off = v2 ? { event: 28, nsat: 29, satlst: 32, clock: 68, satOld: 32, shiftClk: 1 } : {
340
+ event: 31,
341
+ nsat: 32,
342
+ satlst: 41,
343
+ clock: 41,
344
+ satOld: 41,
345
+ shiftClk: 4,
346
+ psec: 57
347
+ };
348
+ let oldline = "&";
349
+ let nsatOld = 0;
350
+ let clk0 = { u: [0, 0, 0, 0], l: [0, 0, 0, 0] };
351
+ let dy0 = [];
352
+ let flag0 = [];
353
+ let oldpsec = "";
354
+ let clkOrderPrev = -1;
355
+ const resetArcs = () => {
356
+ oldline = "&";
357
+ nsatOld = 0;
358
+ clkOrderPrev = -1;
359
+ };
360
+ for (; ; ) {
361
+ if (cursor.li >= rawLines.length) break;
362
+ let epoch = rawLines[cursor.li];
363
+ if (epoch === void 0) break;
364
+ if (epoch === "" && cursor.li === rawLines.length - 1) break;
365
+ cursor.li++;
366
+ epoch = chop(epoch);
367
+ if (epoch === "") continue;
368
+ let newline;
369
+ if (v2) {
370
+ newline = epoch;
371
+ } else {
372
+ newline = epoch.length < 41 ? epoch.padEnd(41, " ") : epoch;
373
+ }
374
+ const eventFlag = parseInt(newline[off.event] ?? "0", 10) || 0;
375
+ if (eventFlag > 1) {
376
+ putEventData(rawLines, cursor, v2, newline, out, ntypeGnss, (n) => {
377
+ ntype = n;
378
+ });
379
+ resetArcs();
380
+ clk0 = { u: [0, 0, 0, 0], l: [0, 0, 0, 0] };
381
+ dy0 = [];
382
+ flag0 = [];
383
+ continue;
384
+ }
385
+ let newpsec = "";
386
+ if (rinexVersionFull >= 402 && newline.length === 62) {
387
+ const psec = newline.slice(off.psec, off.psec + 5);
388
+ if (/^\d{5}$/.test(psec)) newpsec = psec;
389
+ newline = newline.slice(0, off.psec).replace(/\s+$/, "");
390
+ }
391
+ let clkOrder = -1;
392
+ const clk1 = { u: [0, 0, 0, 0], l: [0, 0, 0, 0] };
393
+ if (newline.length > off.clock) {
394
+ clkOrder = readClock(
395
+ newline.slice(off.clock),
396
+ off.shiftClk,
397
+ clk1,
398
+ clkOrderPrev
399
+ );
400
+ if (clkOrder > -1) {
401
+ newline = newline.slice(0, off.clock).replace(/\s+$/, "");
402
+ if (!v2 && newline.length < 41) newline = newline.padEnd(41, " ");
403
+ }
404
+ }
405
+ clkOrderPrev = clkOrder;
406
+ const nsat = parseInt((newline.slice(off.nsat) || "0").trim(), 10) || 0;
407
+ if (v2 && nsat > 12) {
408
+ newline = readMoreSat(rawLines, cursor, nsat, newline);
409
+ }
410
+ const sats = [];
411
+ const satIds = [];
412
+ let bad = false;
413
+ let satlist = v2 ? newline.slice(off.satlst, off.satlst + nsat * 3) : "";
414
+ for (let i = 0; i < nsat; i++) {
415
+ const r = readSat(rawLines, cursor, rinexVersion, ntype, ntypeGnss);
416
+ if (!r) {
417
+ bad = true;
418
+ break;
419
+ }
420
+ sats.push(r.sat);
421
+ satIds.push(v2 ? satlist.slice(i * 3, i * 3 + 3) : r.satId);
422
+ }
423
+ if (bad) continue;
424
+ if (!v2) satlist = satIds.join("");
425
+ const fullNew = v2 ? newline : newline.slice(0, 41) + satlist;
426
+ const oldSatList = v2 ? oldline.slice(off.satOld, off.satOld + nsatOld * 3) : oldline.slice(off.satOld);
427
+ const sattbl = [];
428
+ const dup = /* @__PURE__ */ new Set();
429
+ for (let i = 0; i < nsat; i++) {
430
+ const id = satIds[i];
431
+ if (dup.has(id)) {
432
+ bad = true;
433
+ break;
434
+ }
435
+ dup.add(id);
436
+ let found = -1;
437
+ for (let j = 0; j < nsatOld; j++) {
438
+ if (oldSatList.slice(j * 3, j * 3 + 3) === id) {
439
+ found = j;
440
+ break;
441
+ }
442
+ }
443
+ sattbl.push(found);
444
+ }
445
+ if (bad) continue;
446
+ out.push(strdiff(oldline, fullNew));
447
+ let clockLine = "";
448
+ if (clkOrder > -1) {
449
+ if (clkOrder > 0) processClock(clk1, clk0, clkOrder);
450
+ clockLine += putClock(clk1.u[clkOrder], clk1.l[clkOrder], clkOrder);
451
+ }
452
+ if (newpsec.length === 5) {
453
+ clockLine += " " + strdiff(oldpsec, newpsec);
454
+ }
455
+ out.push(clockLine);
456
+ const dataLines = buildData(sats, sattbl, dy0, flag0, rinexVersion);
457
+ for (const dl of dataLines) out.push(dl);
458
+ oldline = fullNew;
459
+ nsatOld = nsat;
460
+ clk0 = clk1;
461
+ oldpsec = newpsec;
462
+ dy0 = sats.map((s) => s.data);
463
+ flag0 = sats.map((s) => s.flag);
464
+ }
465
+ return out.join("\n") + "\n";
466
+ }
467
+ function readClock(field, shiftClk, clk1, prevOrder) {
468
+ const c = field.split("");
469
+ if (c[2] !== ".") return -1;
470
+ for (let k = 0; k < shiftClk; k++) c[2 + k] = c[3 + k];
471
+ c[2 + shiftClk] = ".";
472
+ const s = c.join("");
473
+ const m = /(-?\d+)\.(\d+)/.exec(s);
474
+ if (!m) return -1;
475
+ clk1.u[0] = parseInt(m[1], 10);
476
+ clk1.l[0] = parseInt(m[2], 10);
477
+ if (c[0] === "-" || c[1] === "-") clk1.l[0] = -clk1.l[0];
478
+ return Math.min(prevOrder + 1, ARC_ORDER);
479
+ }
480
+ function processClock(clk1, clk0, clkOrder) {
481
+ for (let i = 0; i < clkOrder; i++) {
482
+ clk1.u[i + 1] = clk1.u[i] - clk0.u[i];
483
+ clk1.l[i + 1] = clk1.l[i] - clk0.l[i];
484
+ }
485
+ }
486
+ function takeDiff(py1, py0) {
487
+ py1.order = py0.order;
488
+ if (py1.order < ARC_ORDER) py1.order++;
489
+ for (let k = 0; k < py1.order; k++) {
490
+ py1.u[k + 1] = py1.u[k] - py0.u[k];
491
+ py1.l[k + 1] = py1.l[k] - py0.l[k];
492
+ }
493
+ }
494
+ function buildData(sats, sattbl, dy0, flag0, rinexVersion) {
495
+ const lines = [];
496
+ for (let i = 0; i < sats.length; i++) {
497
+ const sat = sats[i];
498
+ const i0 = sattbl[i];
499
+ const prevFlag = (i0 >= 0 ? flag0[i0] ?? "" : "").split("");
500
+ let line = "";
501
+ for (let j = 0; j < sat.ntypeRec; j++) {
502
+ const py1 = sat.data[j];
503
+ if (py1.order >= 0) {
504
+ if (i0 < 0 || dy0[i0]?.[j]?.order === -1) {
505
+ py1.order = 0;
506
+ line += `${ARC_ORDER}&`;
507
+ } else {
508
+ takeDiff(py1, dy0[i0][j]);
509
+ if (Math.abs(py1.u[py1.order]) > 1e5) {
510
+ py1.order = 0;
511
+ line += `${ARC_ORDER}&`;
512
+ }
513
+ }
514
+ line += putdiff(py1.u[py1.order], py1.l[py1.order]);
515
+ } else if (i0 >= 0 && rinexVersion === 2) {
516
+ prevFlag[j * 2] = " ";
517
+ prevFlag[j * 2 + 1] = " ";
518
+ }
519
+ line += " ";
520
+ }
521
+ if (i0 < 0 && rinexVersion !== 2) {
522
+ for (const ch of sat.flag) line += ch === " " ? "&" : ch;
523
+ } else {
524
+ line += i0 < 0 ? strdiff("", sat.flag) : strdiff(prevFlag.join(""), sat.flag);
525
+ line = line.replace(/ +$/, "");
526
+ }
527
+ lines.push(line);
528
+ }
529
+ return lines;
530
+ }
531
+ function putEventData(lines, cursor, v2, epochLine, out, ntypeGnss, setNtype) {
532
+ if (v2) {
533
+ out.push("&" + epochLine.slice(1));
534
+ if (epochLine.length > 29) {
535
+ const n = parseInt(epochLine.slice(29), 10) || 0;
536
+ for (let i = 0; i < n; i++) {
537
+ const l = chop(lines[cursor.li++] ?? "");
538
+ out.push(l);
539
+ if (l.slice(60).trimStart().startsWith("# / TYPES OF OBSERV") && l[5] !== " ") {
540
+ setNtype(parseInt(l, 10));
541
+ }
542
+ }
543
+ }
544
+ } else {
545
+ out.push(epochLine.replace(/\s+$/, ""));
546
+ const n = parseInt(epochLine.slice(32), 10) || 0;
547
+ for (let i = 0; i < n; i++) {
548
+ const l = chop(lines[cursor.li++] ?? "");
549
+ out.push(l);
550
+ if (l.slice(60).trimStart().startsWith("SYS / # / OBS TYPES") && l[0] !== " ") {
551
+ ntypeGnss[l[0]] = parseInt(l.slice(3), 10);
552
+ }
553
+ }
554
+ }
555
+ }
556
+ function readMoreSat(lines, cursor, n, epochLine) {
557
+ let result = epochLine;
558
+ let remaining = n;
559
+ while (remaining > 12) {
560
+ const l = lines[cursor.li++] ?? "";
561
+ const chopped = chop(l);
562
+ result += chopped[2] === " " ? chopped.slice(32) : chopped;
563
+ remaining -= 12;
564
+ }
565
+ return result;
566
+ }
567
+ function readVersionFull(line) {
568
+ if (line[5] === "2" && line[6] === " ") return 200;
569
+ const d = (c) => c !== void 0 && c >= "0" && c <= "9";
570
+ if (!d(line[5]) || line[6] !== "." || !d(line[7]) || !d(line[8])) return -1;
571
+ return (line.charCodeAt(5) - 48) * 100 + (line.charCodeAt(7) - 48) * 10 + (line.charCodeAt(8) - 48);
572
+ }
573
+
137
574
  // src/rinex/format.ts
138
575
  function padL(s, w) {
139
576
  return s.length >= w ? s.slice(0, w) : s + " ".repeat(w - s.length);
@@ -2346,6 +2783,7 @@ function writeRinex4ObsBlob(header, epochs, obsTypes) {
2346
2783
  stationHeaderLines,
2347
2784
  systemCmp,
2348
2785
  systemName,
2786
+ writeCrx,
2349
2787
  writeModernObsBlob,
2350
2788
  writeRinex2ObsBlob,
2351
2789
  writeRinex4ObsBlob,