gnss-js 1.1.0 → 1.3.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 CHANGED
@@ -51,6 +51,44 @@ const { distance } = vincenty(
51
51
  // distance in meters, angles in radians
52
52
  ```
53
53
 
54
+ ### Visibility / pass prediction
55
+
56
+ ```ts
57
+ import { computeVisibility } from 'gnss-js/orbit';
58
+
59
+ const vis = computeVisibility(ephemerides, rxEcef, startMs, endMs, 300, 10);
60
+ // vis.passes: rise/peak/set per satellite; vis.pdop / vis.visibleCount
61
+ // per epoch; vis.elevation[prn]: elevation timeline for plotting.
62
+ ```
63
+
64
+ ### Single-point positioning
65
+
66
+ ```ts
67
+ import { solveSpp, ionoFree } from 'gnss-js/positioning';
68
+
69
+ const sol = solveSpp(pseudoranges, ephemerides, epochMs);
70
+ // sol.position (ECEF m), per-system clock biases, DOP, residuals,
71
+ // rejected outliers. ~10 m single-frequency; use ionoFree(p1, p2, f1, f2)
72
+ // pseudoranges for metre-level.
73
+ ```
74
+
75
+ ### Reference frame transformations
76
+
77
+ ```ts
78
+ import { transformFrame, dateToEpoch } from 'gnss-js/frames';
79
+
80
+ // ETRS89 (ETRF2000) station coordinates → ITRF2020 at epoch 2010.5
81
+ const itrf = transformFrame(
82
+ [3924687.7039, 301132.7618, 5001910.7712],
83
+ 'ETRF2000',
84
+ 'ITRF2020',
85
+ 2010.5
86
+ );
87
+ // Time-dependent 14-parameter Helmert (IERS/EPSG parameters);
88
+ // supports ITRF88–ITRF2020, ETRF2000/2014/2020, NAD83(2011).
89
+ // 'WGS84' is treated as an ITRF2020 alias (standard GNSS practice).
90
+ ```
91
+
54
92
  ### RINEX parsing
55
93
 
56
94
  ```ts
@@ -1,6 +1,4 @@
1
1
  import {
2
- DAYS_MJD2000_MJD,
3
- DAYS_MJD_JULIAN,
4
2
  MILLISECONDS_GPS_TAI,
5
3
  MILLISECONDS_IN_DAY,
6
4
  MILLISECONDS_IN_HOUR,
@@ -8,98 +6,13 @@ import {
8
6
  MILLISECONDS_IN_SECOND,
9
7
  MILLISECONDS_IN_WEEK,
10
8
  MILLISECONDS_TT_TAI,
11
- RINEX_CODES,
12
9
  START_BDS_TIME,
13
10
  START_GAL_TIME,
14
11
  START_GLO_LEAP,
15
12
  START_GPS_TIME,
16
- START_JULIAN_TAI,
17
- START_NTP_TIME,
18
- START_TAI_TIME
13
+ START_NTP_TIME
19
14
  } from "./chunk-LEEU5OIO.js";
20
15
 
21
- // src/types/enums.ts
22
- var Scale = /* @__PURE__ */ ((Scale2) => {
23
- Scale2[Scale2["TAI"] = 0] = "TAI";
24
- Scale2[Scale2["TT"] = 1] = "TT";
25
- Scale2[Scale2["GPS"] = 2] = "GPS";
26
- Scale2[Scale2["UTC"] = 3] = "UTC";
27
- return Scale2;
28
- })(Scale || {});
29
-
30
- // src/time/functions.ts
31
- function getTimeOfDay(date) {
32
- return date.getTime() - Date.UTC(
33
- date.getUTCFullYear(),
34
- date.getUTCMonth(),
35
- date.getUTCDate(),
36
- 0,
37
- 0,
38
- 0
39
- );
40
- }
41
- function getDateFromTimeOfDay(timeOfDay, dateRaw) {
42
- return new Date(
43
- Date.UTC(
44
- dateRaw.getUTCFullYear(),
45
- dateRaw.getUTCMonth(),
46
- dateRaw.getUTCDate(),
47
- 0,
48
- 0,
49
- 0
50
- ) + timeOfDay
51
- );
52
- }
53
- function getDayOfYear(date) {
54
- return Math.floor(
55
- (date.getTime() - Date.UTC(date.getUTCFullYear())) / MILLISECONDS_IN_DAY
56
- ) + 1;
57
- }
58
- function getDateFromDayOfYear(dayOfYear, date) {
59
- return new Date(
60
- Date.UTC(
61
- date.getUTCFullYear(),
62
- 0,
63
- 1,
64
- date.getUTCHours(),
65
- date.getUTCMinutes(),
66
- date.getUTCSeconds(),
67
- date.getUTCMilliseconds()
68
- ) + (dayOfYear - 1) * MILLISECONDS_IN_DAY
69
- );
70
- }
71
- function getDayOfWeek(date) {
72
- return date.getUTCDay();
73
- }
74
- function getDateFromDayOfWeek(dayOfWeek, dateRaw) {
75
- if (dayOfWeek < 0 || dayOfWeek > 6)
76
- throw new Error("Day of week must be a value between 0 and 7");
77
- return new Date(
78
- dateRaw.getTime() + (dayOfWeek - dateRaw.getUTCDay()) * MILLISECONDS_IN_DAY
79
- );
80
- }
81
- function getDateFromHourCode(hourCode, date) {
82
- const hour = RINEX_CODES.indexOf(hourCode);
83
- if (hour === -1)
84
- throw new Error("Hour code must be a lowercase letter between a and x");
85
- const newDate = new Date(date.getTime());
86
- newDate.setUTCHours(hour);
87
- return newDate;
88
- }
89
- function getHourCode(date) {
90
- return RINEX_CODES[date.getUTCHours()];
91
- }
92
- function getWeekOfYear(date) {
93
- const target = new Date(
94
- Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())
95
- );
96
- const dayNr = (target.getUTCDay() + 6) % 7;
97
- target.setUTCDate(target.getUTCDate() - dayNr + 3);
98
- const firstThursday = new Date(Date.UTC(target.getUTCFullYear(), 0, 4));
99
- const dayDiff = (target.getTime() - firstThursday.getTime()) / (86400 * 1e3);
100
- return 1 + Math.floor(dayDiff / 7) + 1;
101
- }
102
-
103
16
  // src/time/time-difference.ts
104
17
  function getTimeDifference(startDate, finalDate) {
105
18
  return Math.floor(finalDate.getTime() - startDate.getTime());
@@ -139,6 +52,76 @@ function getTimeDifferenceFromObject(timeDifferenceObject) {
139
52
  return getTimeDifferenceFromSeconds(seconds) + getTimeDifferenceFromMinutes(minutes) + getTimeDifferenceFromHours(hours) + getTimeDifferenceFromDays(days);
140
53
  }
141
54
 
55
+ // src/time/gnss.ts
56
+ function getGpsTime(date) {
57
+ return date.getTime() - START_GPS_TIME.getTime();
58
+ }
59
+ function getDateFromGpsTime(gpsTime) {
60
+ return new Date(gpsTime + START_GPS_TIME.getTime());
61
+ }
62
+ function getGalTime(date) {
63
+ return date.getTime() - START_GAL_TIME.getTime();
64
+ }
65
+ function getDateFromGalTime(galTime) {
66
+ return new Date(galTime + START_GAL_TIME.getTime());
67
+ }
68
+ function getBdsTime(date) {
69
+ return date.getTime() - START_BDS_TIME.getTime();
70
+ }
71
+ function getDateFromBdsTime(bdsTime) {
72
+ return new Date(bdsTime + START_BDS_TIME.getTime());
73
+ }
74
+ function getUnixTime(date) {
75
+ const utc_date = getUtcDate(date);
76
+ return utc_date.getTime();
77
+ }
78
+ function getDateFromUnixTime(unixTime) {
79
+ return getDateFromUtc(new Date(unixTime));
80
+ }
81
+ function getWeekNumber(date) {
82
+ return Math.floor(getGpsTime(date) / MILLISECONDS_IN_WEEK);
83
+ }
84
+ function getTimeOfWeek(date) {
85
+ return getGpsTime(date) % MILLISECONDS_IN_WEEK;
86
+ }
87
+ function getDateFromGpsData(weekNumber, timeOfWeek) {
88
+ return new Date(
89
+ weekNumber * MILLISECONDS_IN_WEEK + timeOfWeek + START_GPS_TIME.getTime()
90
+ );
91
+ }
92
+ function getTaiDate(date) {
93
+ return new Date(date.getTime() + MILLISECONDS_GPS_TAI);
94
+ }
95
+ function getDateFromTai(tai_date) {
96
+ return new Date(tai_date.getTime() - MILLISECONDS_GPS_TAI);
97
+ }
98
+ function getTtDate(date) {
99
+ return new Date(date.getTime() + MILLISECONDS_GPS_TAI + MILLISECONDS_TT_TAI);
100
+ }
101
+ function getDateFromTt(tt_date) {
102
+ return new Date(
103
+ tt_date.getTime() - MILLISECONDS_GPS_TAI - MILLISECONDS_TT_TAI
104
+ );
105
+ }
106
+ function getGloN4(date) {
107
+ return Math.floor((date.getUTCFullYear() - START_GLO_LEAP.getFullYear()) / 4);
108
+ }
109
+ function getGloNA(date) {
110
+ const n4 = getGloN4(date);
111
+ const init4YearPeriod = new Date(START_GLO_LEAP);
112
+ init4YearPeriod.setUTCFullYear(init4YearPeriod.getUTCFullYear() + n4 * 4);
113
+ return Math.floor(getTimeDifference(init4YearPeriod, date) / MILLISECONDS_IN_DAY) + 1;
114
+ }
115
+ function getDateFromGloN(n4, na, tod) {
116
+ const date = new Date(START_GLO_LEAP);
117
+ date.setFullYear(date.getUTCFullYear() + n4 * 4);
118
+ date.setTime(date.getTime() + (na - 1) * MILLISECONDS_IN_DAY + tod);
119
+ return date;
120
+ }
121
+ function getNtpTime(date) {
122
+ return getTaiDate(date).getTime() - START_NTP_TIME.getTime();
123
+ }
124
+
142
125
  // src/time/utc.ts
143
126
  var LEAP_SECONDS_TABLE = [
144
127
  [3692217600, 37],
@@ -228,167 +211,7 @@ function getDateFromUtc(utc_date) {
228
211
  return gps_date;
229
212
  }
230
213
 
231
- // src/time/gnss.ts
232
- function getGpsTime(date) {
233
- return date.getTime() - START_GPS_TIME.getTime();
234
- }
235
- function getDateFromGpsTime(gpsTime) {
236
- return new Date(gpsTime + START_GPS_TIME.getTime());
237
- }
238
- function getGalTime(date) {
239
- return date.getTime() - START_GAL_TIME.getTime();
240
- }
241
- function getDateFromGalTime(galTime) {
242
- return new Date(galTime + START_GAL_TIME.getTime());
243
- }
244
- function getBdsTime(date) {
245
- return date.getTime() - START_BDS_TIME.getTime();
246
- }
247
- function getDateFromBdsTime(bdsTime) {
248
- return new Date(bdsTime + START_BDS_TIME.getTime());
249
- }
250
- function getUnixTime(date) {
251
- const utc_date = getUtcDate(date);
252
- return utc_date.getTime();
253
- }
254
- function getDateFromUnixTime(unixTime) {
255
- return getDateFromUtc(new Date(unixTime));
256
- }
257
- function getWeekNumber(date) {
258
- return Math.floor(getGpsTime(date) / MILLISECONDS_IN_WEEK);
259
- }
260
- function getTimeOfWeek(date) {
261
- return getGpsTime(date) % MILLISECONDS_IN_WEEK;
262
- }
263
- function getDateFromGpsData(weekNumber, timeOfWeek) {
264
- return new Date(
265
- weekNumber * MILLISECONDS_IN_WEEK + timeOfWeek + START_GPS_TIME.getTime()
266
- );
267
- }
268
- function getTaiDate(date) {
269
- return new Date(date.getTime() + MILLISECONDS_GPS_TAI);
270
- }
271
- function getDateFromTai(tai_date) {
272
- return new Date(tai_date.getTime() - MILLISECONDS_GPS_TAI);
273
- }
274
- function getTtDate(date) {
275
- return new Date(date.getTime() + MILLISECONDS_GPS_TAI + MILLISECONDS_TT_TAI);
276
- }
277
- function getDateFromTt(tt_date) {
278
- return new Date(
279
- tt_date.getTime() - MILLISECONDS_GPS_TAI - MILLISECONDS_TT_TAI
280
- );
281
- }
282
- function getGloN4(date) {
283
- return Math.floor((date.getUTCFullYear() - START_GLO_LEAP.getFullYear()) / 4);
284
- }
285
- function getGloNA(date) {
286
- const n4 = getGloN4(date);
287
- const init4YearPeriod = new Date(START_GLO_LEAP);
288
- init4YearPeriod.setUTCFullYear(init4YearPeriod.getUTCFullYear() + n4 * 4);
289
- return Math.floor(getTimeDifference(init4YearPeriod, date) / MILLISECONDS_IN_DAY) + 1;
290
- }
291
- function getDateFromGloN(n4, na, tod) {
292
- const date = new Date(START_GLO_LEAP);
293
- date.setFullYear(date.getUTCFullYear() + n4 * 4);
294
- date.setTime(date.getTime() + (na - 1) * MILLISECONDS_IN_DAY + tod);
295
- return date;
296
- }
297
- function getNtpTime(date) {
298
- return getTaiDate(date).getTime() - START_NTP_TIME.getTime();
299
- }
300
-
301
- // src/time/rinex.ts
302
- function getRINEX(date) {
303
- const seconds = date.getUTCSeconds();
304
- const milliseconds = date.getUTCMilliseconds();
305
- const fractionalSeconds = (milliseconds / MILLISECONDS_IN_SECOND).toFixed(7).slice(1);
306
- const formatted = `> ${date.getUTCFullYear()} ${String(
307
- date.getUTCMonth() + 1
308
- ).padStart(2, "0")} ${String(date.getUTCDate()).padStart(2, "0")} ${String(
309
- date.getUTCHours()
310
- ).padStart(2, "0")} ${String(date.getUTCMinutes()).padStart(
311
- 2,
312
- "0"
313
- )} ${String(seconds).padStart(2, "0")}${fractionalSeconds}`;
314
- return formatted;
315
- }
316
- function getDateFromRINEX(rinex) {
317
- const year = Number.parseInt(rinex.substring(2, 6));
318
- const month = Number.parseInt(rinex.substring(7, 9)) - 1;
319
- const day = Number.parseInt(rinex.substring(10, 12));
320
- const hour = Number.parseInt(rinex.substring(13, 15));
321
- const minute = Number.parseInt(rinex.substring(16, 18));
322
- const second = Number.parseInt(rinex.substring(19, 21));
323
- const millisecond = Number.parseInt(rinex.substring(22, 29)) / 1e4;
324
- const date = new Date(
325
- Date.UTC(year, month, day, hour, minute, second, millisecond)
326
- );
327
- return date;
328
- }
329
-
330
- // src/time/julian.ts
331
- function getJulianDate(date, scale = 1 /* TT */) {
332
- if (scale === 0 /* TAI */) {
333
- return (date.getTime() - START_TAI_TIME.getTime()) / MILLISECONDS_IN_DAY + START_JULIAN_TAI;
334
- }
335
- if (scale === 2 /* GPS */) {
336
- return (date.getTime() - START_TAI_TIME.getTime() - MILLISECONDS_GPS_TAI) / MILLISECONDS_IN_DAY + START_JULIAN_TAI;
337
- }
338
- if (scale === 3 /* UTC */) {
339
- return (date.getTime() - START_TAI_TIME.getTime() - getLeap(date) * MILLISECONDS_IN_SECOND) / MILLISECONDS_IN_DAY + START_JULIAN_TAI;
340
- }
341
- return (date.getTime() - START_TAI_TIME.getTime() + MILLISECONDS_TT_TAI) / MILLISECONDS_IN_DAY + START_JULIAN_TAI;
342
- }
343
- function getDateFromJulianDate(julianDate, scale = 1 /* TT */) {
344
- if (scale === 0 /* TAI */) {
345
- return new Date(
346
- (julianDate - START_JULIAN_TAI) * MILLISECONDS_IN_DAY + START_TAI_TIME.getTime()
347
- );
348
- }
349
- if (scale === 2 /* GPS */) {
350
- return new Date(
351
- (julianDate - START_JULIAN_TAI) * MILLISECONDS_IN_DAY + START_TAI_TIME.getTime() + MILLISECONDS_GPS_TAI
352
- );
353
- }
354
- if (scale === 3 /* UTC */) {
355
- const utc_date = new Date(
356
- (julianDate - START_JULIAN_TAI) * MILLISECONDS_IN_DAY + START_TAI_TIME.getTime()
357
- );
358
- const tai_date = new Date(
359
- utc_date.getTime() + getLeap(utc_date) * MILLISECONDS_IN_SECOND
360
- );
361
- const leap_seconds = getLeap(getDateFromTai(tai_date));
362
- return new Date(utc_date.getTime() + leap_seconds * MILLISECONDS_IN_SECOND);
363
- }
364
- return new Date(
365
- (julianDate - START_JULIAN_TAI) * MILLISECONDS_IN_DAY + START_TAI_TIME.getTime() - MILLISECONDS_TT_TAI
366
- );
367
- }
368
- function getMJD(date, scale = 1 /* TT */) {
369
- return getJulianDate(date, scale) - DAYS_MJD_JULIAN;
370
- }
371
- function getDateFromMJD(mjd, scale = 1 /* TT */) {
372
- return getDateFromJulianDate(mjd + DAYS_MJD_JULIAN, scale);
373
- }
374
- function getMJD2000(date, scale = 1 /* TT */) {
375
- return getMJD(date, scale) - DAYS_MJD2000_MJD;
376
- }
377
- function getDateFromMJD2000(mjd2000, scale = 1 /* TT */) {
378
- return getDateFromMJD(mjd2000 + DAYS_MJD2000_MJD, scale);
379
- }
380
-
381
214
  export {
382
- Scale,
383
- getTimeOfDay,
384
- getDateFromTimeOfDay,
385
- getDayOfYear,
386
- getDateFromDayOfYear,
387
- getDayOfWeek,
388
- getDateFromDayOfWeek,
389
- getDateFromHourCode,
390
- getHourCode,
391
- getWeekOfYear,
392
215
  getTimeDifference,
393
216
  getSecondsFromTimeDifference,
394
217
  getMinutesFromTimeDifference,
@@ -421,13 +244,5 @@ export {
421
244
  getGloN4,
422
245
  getGloNA,
423
246
  getDateFromGloN,
424
- getNtpTime,
425
- getRINEX,
426
- getDateFromRINEX,
427
- getJulianDate,
428
- getDateFromJulianDate,
429
- getMJD,
430
- getDateFromMJD,
431
- getMJD2000,
432
- getDateFromMJD2000
247
+ getNtpTime
433
248
  };
@@ -0,0 +1,198 @@
1
+ import {
2
+ getDateFromTai,
3
+ getLeap
4
+ } from "./chunk-HVXYFUCB.js";
5
+ import {
6
+ DAYS_MJD2000_MJD,
7
+ DAYS_MJD_JULIAN,
8
+ MILLISECONDS_GPS_TAI,
9
+ MILLISECONDS_IN_DAY,
10
+ MILLISECONDS_IN_SECOND,
11
+ MILLISECONDS_TT_TAI,
12
+ RINEX_CODES,
13
+ START_JULIAN_TAI,
14
+ START_TAI_TIME
15
+ } from "./chunk-LEEU5OIO.js";
16
+
17
+ // src/types/enums.ts
18
+ var Scale = /* @__PURE__ */ ((Scale2) => {
19
+ Scale2[Scale2["TAI"] = 0] = "TAI";
20
+ Scale2[Scale2["TT"] = 1] = "TT";
21
+ Scale2[Scale2["GPS"] = 2] = "GPS";
22
+ Scale2[Scale2["UTC"] = 3] = "UTC";
23
+ return Scale2;
24
+ })(Scale || {});
25
+
26
+ // src/time/functions.ts
27
+ function getTimeOfDay(date) {
28
+ return date.getTime() - Date.UTC(
29
+ date.getUTCFullYear(),
30
+ date.getUTCMonth(),
31
+ date.getUTCDate(),
32
+ 0,
33
+ 0,
34
+ 0
35
+ );
36
+ }
37
+ function getDateFromTimeOfDay(timeOfDay, dateRaw) {
38
+ return new Date(
39
+ Date.UTC(
40
+ dateRaw.getUTCFullYear(),
41
+ dateRaw.getUTCMonth(),
42
+ dateRaw.getUTCDate(),
43
+ 0,
44
+ 0,
45
+ 0
46
+ ) + timeOfDay
47
+ );
48
+ }
49
+ function getDayOfYear(date) {
50
+ return Math.floor(
51
+ (date.getTime() - Date.UTC(date.getUTCFullYear())) / MILLISECONDS_IN_DAY
52
+ ) + 1;
53
+ }
54
+ function getDateFromDayOfYear(dayOfYear, date) {
55
+ return new Date(
56
+ Date.UTC(
57
+ date.getUTCFullYear(),
58
+ 0,
59
+ 1,
60
+ date.getUTCHours(),
61
+ date.getUTCMinutes(),
62
+ date.getUTCSeconds(),
63
+ date.getUTCMilliseconds()
64
+ ) + (dayOfYear - 1) * MILLISECONDS_IN_DAY
65
+ );
66
+ }
67
+ function getDayOfWeek(date) {
68
+ return date.getUTCDay();
69
+ }
70
+ function getDateFromDayOfWeek(dayOfWeek, dateRaw) {
71
+ if (dayOfWeek < 0 || dayOfWeek > 6)
72
+ throw new Error("Day of week must be a value between 0 and 7");
73
+ return new Date(
74
+ dateRaw.getTime() + (dayOfWeek - dateRaw.getUTCDay()) * MILLISECONDS_IN_DAY
75
+ );
76
+ }
77
+ function getDateFromHourCode(hourCode, date) {
78
+ const hour = RINEX_CODES.indexOf(hourCode);
79
+ if (hour === -1)
80
+ throw new Error("Hour code must be a lowercase letter between a and x");
81
+ const newDate = new Date(date.getTime());
82
+ newDate.setUTCHours(hour);
83
+ return newDate;
84
+ }
85
+ function getHourCode(date) {
86
+ return RINEX_CODES[date.getUTCHours()];
87
+ }
88
+ function getWeekOfYear(date) {
89
+ const target = new Date(
90
+ Date.UTC(date.getFullYear(), date.getMonth(), date.getDate())
91
+ );
92
+ const dayNr = (target.getUTCDay() + 6) % 7;
93
+ target.setUTCDate(target.getUTCDate() - dayNr + 3);
94
+ const firstThursday = new Date(Date.UTC(target.getUTCFullYear(), 0, 4));
95
+ const dayDiff = (target.getTime() - firstThursday.getTime()) / (86400 * 1e3);
96
+ return 1 + Math.floor(dayDiff / 7) + 1;
97
+ }
98
+
99
+ // src/time/rinex.ts
100
+ function getRINEX(date) {
101
+ const seconds = date.getUTCSeconds();
102
+ const milliseconds = date.getUTCMilliseconds();
103
+ const fractionalSeconds = (milliseconds / MILLISECONDS_IN_SECOND).toFixed(7).slice(1);
104
+ const formatted = `> ${date.getUTCFullYear()} ${String(
105
+ date.getUTCMonth() + 1
106
+ ).padStart(2, "0")} ${String(date.getUTCDate()).padStart(2, "0")} ${String(
107
+ date.getUTCHours()
108
+ ).padStart(2, "0")} ${String(date.getUTCMinutes()).padStart(
109
+ 2,
110
+ "0"
111
+ )} ${String(seconds).padStart(2, "0")}${fractionalSeconds}`;
112
+ return formatted;
113
+ }
114
+ function getDateFromRINEX(rinex) {
115
+ const year = Number.parseInt(rinex.substring(2, 6));
116
+ const month = Number.parseInt(rinex.substring(7, 9)) - 1;
117
+ const day = Number.parseInt(rinex.substring(10, 12));
118
+ const hour = Number.parseInt(rinex.substring(13, 15));
119
+ const minute = Number.parseInt(rinex.substring(16, 18));
120
+ const second = Number.parseInt(rinex.substring(19, 21));
121
+ const millisecond = Number.parseInt(rinex.substring(22, 29)) / 1e4;
122
+ const date = new Date(
123
+ Date.UTC(year, month, day, hour, minute, second, millisecond)
124
+ );
125
+ return date;
126
+ }
127
+
128
+ // src/time/julian.ts
129
+ function getJulianDate(date, scale = 1 /* TT */) {
130
+ if (scale === 0 /* TAI */) {
131
+ return (date.getTime() - START_TAI_TIME.getTime()) / MILLISECONDS_IN_DAY + START_JULIAN_TAI;
132
+ }
133
+ if (scale === 2 /* GPS */) {
134
+ return (date.getTime() - START_TAI_TIME.getTime() - MILLISECONDS_GPS_TAI) / MILLISECONDS_IN_DAY + START_JULIAN_TAI;
135
+ }
136
+ if (scale === 3 /* UTC */) {
137
+ return (date.getTime() - START_TAI_TIME.getTime() - getLeap(date) * MILLISECONDS_IN_SECOND) / MILLISECONDS_IN_DAY + START_JULIAN_TAI;
138
+ }
139
+ return (date.getTime() - START_TAI_TIME.getTime() + MILLISECONDS_TT_TAI) / MILLISECONDS_IN_DAY + START_JULIAN_TAI;
140
+ }
141
+ function getDateFromJulianDate(julianDate, scale = 1 /* TT */) {
142
+ if (scale === 0 /* TAI */) {
143
+ return new Date(
144
+ (julianDate - START_JULIAN_TAI) * MILLISECONDS_IN_DAY + START_TAI_TIME.getTime()
145
+ );
146
+ }
147
+ if (scale === 2 /* GPS */) {
148
+ return new Date(
149
+ (julianDate - START_JULIAN_TAI) * MILLISECONDS_IN_DAY + START_TAI_TIME.getTime() + MILLISECONDS_GPS_TAI
150
+ );
151
+ }
152
+ if (scale === 3 /* UTC */) {
153
+ const utc_date = new Date(
154
+ (julianDate - START_JULIAN_TAI) * MILLISECONDS_IN_DAY + START_TAI_TIME.getTime()
155
+ );
156
+ const tai_date = new Date(
157
+ utc_date.getTime() + getLeap(utc_date) * MILLISECONDS_IN_SECOND
158
+ );
159
+ const leap_seconds = getLeap(getDateFromTai(tai_date));
160
+ return new Date(utc_date.getTime() + leap_seconds * MILLISECONDS_IN_SECOND);
161
+ }
162
+ return new Date(
163
+ (julianDate - START_JULIAN_TAI) * MILLISECONDS_IN_DAY + START_TAI_TIME.getTime() - MILLISECONDS_TT_TAI
164
+ );
165
+ }
166
+ function getMJD(date, scale = 1 /* TT */) {
167
+ return getJulianDate(date, scale) - DAYS_MJD_JULIAN;
168
+ }
169
+ function getDateFromMJD(mjd, scale = 1 /* TT */) {
170
+ return getDateFromJulianDate(mjd + DAYS_MJD_JULIAN, scale);
171
+ }
172
+ function getMJD2000(date, scale = 1 /* TT */) {
173
+ return getMJD(date, scale) - DAYS_MJD2000_MJD;
174
+ }
175
+ function getDateFromMJD2000(mjd2000, scale = 1 /* TT */) {
176
+ return getDateFromMJD(mjd2000 + DAYS_MJD2000_MJD, scale);
177
+ }
178
+
179
+ export {
180
+ Scale,
181
+ getTimeOfDay,
182
+ getDateFromTimeOfDay,
183
+ getDayOfYear,
184
+ getDateFromDayOfYear,
185
+ getDayOfWeek,
186
+ getDateFromDayOfWeek,
187
+ getDateFromHourCode,
188
+ getHourCode,
189
+ getWeekOfYear,
190
+ getRINEX,
191
+ getDateFromRINEX,
192
+ getJulianDate,
193
+ getDateFromJulianDate,
194
+ getMJD,
195
+ getDateFromMJD,
196
+ getMJD2000,
197
+ getDateFromMJD2000
198
+ };
@@ -1,3 +1,6 @@
1
+ import {
2
+ getGpsLeap
3
+ } from "./chunk-HVXYFUCB.js";
1
4
  import {
2
5
  ecefToGeodetic
3
6
  } from "./chunk-37QNKGTC.js";
@@ -230,7 +233,8 @@ function selectEphemeris(ephemerides, prn, timeMs) {
230
233
  }
231
234
  function computeSatPosition(eph, timeMs) {
232
235
  if (eph.system === "R" || eph.system === "S") {
233
- return glonassPosition(eph, timeMs / 1e3);
236
+ const leapMs = getGpsLeap(new Date(timeMs)) * 1e3;
237
+ return glonassPosition(eph, (timeMs - leapMs) / 1e3);
234
238
  }
235
239
  const GPS_EPOCH = START_GPS_TIME.getTime();
236
240
  const gpsSeconds = (timeMs - GPS_EPOCH) / 1e3;
@@ -403,7 +407,7 @@ function ephInfoToEphemeris(info) {
403
407
  };
404
408
  }
405
409
  function computeLiveSkyPositions(ephemerides, rxPos, cn0Map) {
406
- const now = Date.now();
410
+ const now = Date.now() + getGpsLeap(/* @__PURE__ */ new Date()) * 1e3;
407
411
  const result = [];
408
412
  const [rxX, rxY, rxZ] = rxPos;
409
413
  const [rxLat, rxLon] = ecefToGeodetic(rxX, rxY, rxZ);
@@ -436,6 +440,65 @@ function computeLiveSkyPositions(ephemerides, rxPos, cn0Map) {
436
440
  }
437
441
  return result;
438
442
  }
443
+ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, elevationMaskDeg = 10) {
444
+ const stepMs = stepSec * 1e3;
445
+ const times = [];
446
+ for (let t = startMs; t <= endMs; t += stepMs) times.push(t);
447
+ const maskRad = elevationMaskDeg * Math.PI / 180;
448
+ const all = computeAllPositions(ephemerides, times, rxPos);
449
+ const elevation = {};
450
+ const visibleCount = new Array(times.length).fill(0);
451
+ const pdop = new Array(times.length).fill(null);
452
+ const visiblePerEpoch = times.map(() => []);
453
+ for (const prn of all.prns) {
454
+ const series = all.positions[prn];
455
+ elevation[prn] = series.map((p) => p ? p.el : null);
456
+ for (let i = 0; i < series.length; i++) {
457
+ const p = series[i];
458
+ if (p && p.el >= maskRad) {
459
+ visibleCount[i]++;
460
+ visiblePerEpoch[i].push({ az: p.az, el: p.el });
461
+ }
462
+ }
463
+ }
464
+ for (let i = 0; i < times.length; i++) {
465
+ const dop = computeDop(visiblePerEpoch[i]);
466
+ pdop[i] = dop ? dop.pdop : null;
467
+ }
468
+ const passes = [];
469
+ for (const prn of all.prns) {
470
+ const els = elevation[prn];
471
+ let start = -1;
472
+ let peakEl = -Infinity;
473
+ let peakTime = 0;
474
+ for (let i = 0; i <= els.length; i++) {
475
+ const el = i < els.length ? els[i] : null;
476
+ const above = el !== null && el !== void 0 && el >= maskRad;
477
+ if (above) {
478
+ if (start === -1) {
479
+ start = i;
480
+ peakEl = -Infinity;
481
+ }
482
+ if (el > peakEl) {
483
+ peakEl = el;
484
+ peakTime = times[i];
485
+ }
486
+ } else if (start !== -1) {
487
+ passes.push({
488
+ prn,
489
+ system: prn[0],
490
+ rise: times[start],
491
+ set: times[i - 1],
492
+ peakTime,
493
+ peakEl
494
+ });
495
+ start = -1;
496
+ }
497
+ }
498
+ }
499
+ passes.sort((a, b) => a.rise - b.rise);
500
+ return { times, elevation, visibleCount, pdop, passes };
501
+ }
439
502
 
440
503
  export {
441
504
  keplerPosition,
@@ -446,5 +509,6 @@ export {
446
509
  computeSatPosition,
447
510
  navTimesFromEph,
448
511
  computeAllPositions,
449
- computeLiveSkyPositions
512
+ computeLiveSkyPositions,
513
+ computeVisibility
450
514
  };