gnss-js 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-TBRZDWDE.js → chunk-647YMBJV.js} +41 -4
- package/dist/{chunk-W4YMQKWH.js → chunk-77VUSDNI.js} +87 -1
- package/dist/{chunk-7M7UJJIA.js → chunk-ZRBRVNHK.js} +1 -1
- package/dist/index.cjs +129 -4
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -3
- package/dist/orbit.cjs +42 -4
- package/dist/orbit.d.cts +18 -3
- package/dist/orbit.d.ts +18 -3
- package/dist/orbit.js +3 -1
- package/dist/positioning.js +2 -2
- package/dist/rinex.cjs +87 -0
- package/dist/rinex.d.cts +23 -1
- package/dist/rinex.d.ts +23 -1
- package/dist/rinex.js +3 -1
- package/package.json +1 -1
|
@@ -437,13 +437,33 @@ function computeLiveSkyPositions(ephemerides, rxPos, cn0Map) {
|
|
|
437
437
|
}
|
|
438
438
|
return result;
|
|
439
439
|
}
|
|
440
|
+
function maskRadForAzimuth(maskDeg) {
|
|
441
|
+
if (typeof maskDeg === "number") {
|
|
442
|
+
const m = maskDeg * Math.PI / 180;
|
|
443
|
+
return () => m;
|
|
444
|
+
}
|
|
445
|
+
const n = maskDeg.length;
|
|
446
|
+
if (n === 0) return () => 0;
|
|
447
|
+
return (azRad) => {
|
|
448
|
+
const azDeg = (azRad * 180 / Math.PI % 360 + 360) % 360;
|
|
449
|
+
const pos = azDeg / 360 * n;
|
|
450
|
+
const i = Math.floor(pos) % n;
|
|
451
|
+
const f = pos - Math.floor(pos);
|
|
452
|
+
const a = maskDeg[i];
|
|
453
|
+
const b = maskDeg[(i + 1) % n];
|
|
454
|
+
return ((1 - f) * a + f * b) * Math.PI / 180;
|
|
455
|
+
};
|
|
456
|
+
}
|
|
440
457
|
function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, elevationMaskDeg = 10) {
|
|
441
458
|
const stepMs = stepSec * 1e3;
|
|
442
459
|
const times = [];
|
|
443
460
|
for (let t = startMs; t <= endMs; t += stepMs) times.push(t);
|
|
444
|
-
const
|
|
461
|
+
const maskRadFor = maskRadForAzimuth(elevationMaskDeg);
|
|
445
462
|
const all = computeAllPositions(ephemerides, times, rxPos);
|
|
446
463
|
const elevation = {};
|
|
464
|
+
const azimuth = {};
|
|
465
|
+
const subLat = {};
|
|
466
|
+
const subLon = {};
|
|
447
467
|
const visibleCount = new Array(times.length).fill(0);
|
|
448
468
|
const pdop = new Array(times.length).fill(null);
|
|
449
469
|
const gdop = new Array(times.length).fill(null);
|
|
@@ -453,9 +473,12 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
453
473
|
for (const prn of all.prns) {
|
|
454
474
|
const series = all.positions[prn];
|
|
455
475
|
elevation[prn] = series.map((p) => p ? p.el : null);
|
|
476
|
+
azimuth[prn] = series.map((p) => p ? p.az : null);
|
|
477
|
+
subLat[prn] = series.map((p) => p ? p.lat : null);
|
|
478
|
+
subLon[prn] = series.map((p) => p ? p.lon : null);
|
|
456
479
|
for (let i = 0; i < series.length; i++) {
|
|
457
480
|
const p = series[i];
|
|
458
|
-
if (p && p.el >=
|
|
481
|
+
if (p && p.el >= maskRadFor(p.az)) {
|
|
459
482
|
visibleCount[i]++;
|
|
460
483
|
visiblePerEpoch[i].push({ az: p.az, el: p.el });
|
|
461
484
|
}
|
|
@@ -476,7 +499,8 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
476
499
|
let peakTime = 0;
|
|
477
500
|
for (let i = 0; i <= els.length; i++) {
|
|
478
501
|
const el = i < els.length ? els[i] : null;
|
|
479
|
-
const
|
|
502
|
+
const az = all.positions[prn][i]?.az ?? 0;
|
|
503
|
+
const above = el !== null && el !== void 0 && el >= maskRadFor(az);
|
|
480
504
|
if (above) {
|
|
481
505
|
if (start === -1) {
|
|
482
506
|
start = i;
|
|
@@ -500,7 +524,19 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
500
524
|
}
|
|
501
525
|
}
|
|
502
526
|
passes.sort((a, b) => a.rise - b.rise);
|
|
503
|
-
return {
|
|
527
|
+
return {
|
|
528
|
+
times,
|
|
529
|
+
elevation,
|
|
530
|
+
azimuth,
|
|
531
|
+
subLat,
|
|
532
|
+
subLon,
|
|
533
|
+
visibleCount,
|
|
534
|
+
pdop,
|
|
535
|
+
gdop,
|
|
536
|
+
hdop,
|
|
537
|
+
vdop,
|
|
538
|
+
passes
|
|
539
|
+
};
|
|
504
540
|
}
|
|
505
541
|
|
|
506
542
|
export {
|
|
@@ -514,5 +550,6 @@ export {
|
|
|
514
550
|
computeAllPositions,
|
|
515
551
|
ephInfoToEphemeris,
|
|
516
552
|
computeLiveSkyPositions,
|
|
553
|
+
maskRadForAzimuth,
|
|
517
554
|
computeVisibility
|
|
518
555
|
};
|
|
@@ -610,6 +610,91 @@ function writeRinexNav(nav) {
|
|
|
610
610
|
return header + records.join("\n") + "\n";
|
|
611
611
|
}
|
|
612
612
|
|
|
613
|
+
// src/rinex/ionex.ts
|
|
614
|
+
function gridRange(l1, l2, dl) {
|
|
615
|
+
const out = [];
|
|
616
|
+
const n = Math.round((l2 - l1) / dl) + 1;
|
|
617
|
+
for (let i = 0; i < n; i++) out.push(l1 + i * dl);
|
|
618
|
+
return out;
|
|
619
|
+
}
|
|
620
|
+
function parseIonex(text) {
|
|
621
|
+
const lines = text.split("\n");
|
|
622
|
+
let exponent = -1;
|
|
623
|
+
let lats = [];
|
|
624
|
+
let lons = [];
|
|
625
|
+
const epochs = [];
|
|
626
|
+
const maps = [];
|
|
627
|
+
let i = 0;
|
|
628
|
+
for (; i < lines.length; i++) {
|
|
629
|
+
const line = lines[i];
|
|
630
|
+
const label = line.slice(60).trim();
|
|
631
|
+
if (label === "EXPONENT") {
|
|
632
|
+
exponent = parseInt(line.slice(0, 60).trim(), 10);
|
|
633
|
+
} else if (label === "LAT1 / LAT2 / DLAT") {
|
|
634
|
+
const [a, b, d] = line.trim().split(/\s+/).map(Number);
|
|
635
|
+
lats = gridRange(a, b, d);
|
|
636
|
+
} else if (label === "LON1 / LON2 / DLON") {
|
|
637
|
+
const [a, b, d] = line.trim().split(/\s+/).map(Number);
|
|
638
|
+
lons = gridRange(a, b, d);
|
|
639
|
+
} else if (label === "END OF HEADER") {
|
|
640
|
+
i++;
|
|
641
|
+
break;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
if (lats.length === 0 || lons.length === 0) {
|
|
645
|
+
throw new Error("IONEX: missing grid definition");
|
|
646
|
+
}
|
|
647
|
+
const scale = Math.pow(10, exponent);
|
|
648
|
+
while (i < lines.length) {
|
|
649
|
+
const line = lines[i];
|
|
650
|
+
const label = line.slice(60).trim();
|
|
651
|
+
if (label === "START OF TEC MAP") {
|
|
652
|
+
const map = new Float32Array(lats.length * lons.length).fill(NaN);
|
|
653
|
+
let epochMs = 0;
|
|
654
|
+
i++;
|
|
655
|
+
while (i < lines.length) {
|
|
656
|
+
const l = lines[i];
|
|
657
|
+
const lab = l.slice(60).trim();
|
|
658
|
+
if (lab === "EPOCH OF CURRENT MAP") {
|
|
659
|
+
const f = l.slice(0, 60).trim().split(/\s+/).map(Number);
|
|
660
|
+
epochMs = Date.UTC(f[0], f[1] - 1, f[2], f[3], f[4], f[5]);
|
|
661
|
+
i++;
|
|
662
|
+
} else if (lab === "LAT/LON1/LON2/DLON/H") {
|
|
663
|
+
const lat = parseFloat(l.slice(2, 8));
|
|
664
|
+
const latIdx = lats.findIndex((v) => Math.abs(v - lat) < 1e-6);
|
|
665
|
+
i++;
|
|
666
|
+
let lonIdx = 0;
|
|
667
|
+
while (lonIdx < lons.length && i < lines.length) {
|
|
668
|
+
const row = lines[i];
|
|
669
|
+
for (let c = 0; c + 5 <= 80 && lonIdx < lons.length; c += 5) {
|
|
670
|
+
const vStr = row.slice(c, c + 5).trim();
|
|
671
|
+
if (vStr === "") continue;
|
|
672
|
+
const v = parseInt(vStr, 10);
|
|
673
|
+
if (latIdx >= 0) {
|
|
674
|
+
map[latIdx * lons.length + lonIdx] = v === 9999 ? NaN : v * scale;
|
|
675
|
+
}
|
|
676
|
+
lonIdx++;
|
|
677
|
+
}
|
|
678
|
+
i++;
|
|
679
|
+
}
|
|
680
|
+
} else if (lab === "END OF TEC MAP") {
|
|
681
|
+
i++;
|
|
682
|
+
break;
|
|
683
|
+
} else {
|
|
684
|
+
i++;
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
epochs.push(epochMs);
|
|
688
|
+
maps.push(map);
|
|
689
|
+
} else if (label === "START OF RMS MAP" || label === "END OF FILE") {
|
|
690
|
+
break;
|
|
691
|
+
} else {
|
|
692
|
+
i++;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
return { epochs, lats, lons, maps };
|
|
696
|
+
}
|
|
697
|
+
|
|
613
698
|
export {
|
|
614
699
|
padL,
|
|
615
700
|
padR,
|
|
@@ -618,5 +703,6 @@ export {
|
|
|
618
703
|
EMPTY_WARNINGS,
|
|
619
704
|
WarningAccumulator,
|
|
620
705
|
parseNavFile,
|
|
621
|
-
writeRinexNav
|
|
706
|
+
writeRinexNav,
|
|
707
|
+
parseIonex
|
|
622
708
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -200,6 +200,7 @@ __export(src_exports, {
|
|
|
200
200
|
horizonDistance: () => horizonDistance,
|
|
201
201
|
ionoFree: () => ionoFree,
|
|
202
202
|
keplerPosition: () => keplerPosition,
|
|
203
|
+
maskRadForAzimuth: () => maskRadForAzimuth,
|
|
203
204
|
msmEpochToDate: () => msmEpochToDate,
|
|
204
205
|
navTimesFromEph: () => navTimesFromEph,
|
|
205
206
|
nmeaCoordToDecimal: () => nmeaCoordToDecimal,
|
|
@@ -207,6 +208,7 @@ __export(src_exports, {
|
|
|
207
208
|
padR: () => padR,
|
|
208
209
|
parseAntex: () => parseAntex,
|
|
209
210
|
parseCrxDataLine: () => parseCrxDataLine,
|
|
211
|
+
parseIonex: () => parseIonex,
|
|
210
212
|
parseNavFile: () => parseNavFile,
|
|
211
213
|
parseNmeaFile: () => parseNmeaFile,
|
|
212
214
|
parseRinexStream: () => parseRinexStream,
|
|
@@ -2575,6 +2577,91 @@ function writeRinexNav(nav) {
|
|
|
2575
2577
|
return header + records.join("\n") + "\n";
|
|
2576
2578
|
}
|
|
2577
2579
|
|
|
2580
|
+
// src/rinex/ionex.ts
|
|
2581
|
+
function gridRange(l1, l2, dl) {
|
|
2582
|
+
const out = [];
|
|
2583
|
+
const n = Math.round((l2 - l1) / dl) + 1;
|
|
2584
|
+
for (let i = 0; i < n; i++) out.push(l1 + i * dl);
|
|
2585
|
+
return out;
|
|
2586
|
+
}
|
|
2587
|
+
function parseIonex(text) {
|
|
2588
|
+
const lines = text.split("\n");
|
|
2589
|
+
let exponent = -1;
|
|
2590
|
+
let lats = [];
|
|
2591
|
+
let lons = [];
|
|
2592
|
+
const epochs = [];
|
|
2593
|
+
const maps = [];
|
|
2594
|
+
let i = 0;
|
|
2595
|
+
for (; i < lines.length; i++) {
|
|
2596
|
+
const line = lines[i];
|
|
2597
|
+
const label2 = line.slice(60).trim();
|
|
2598
|
+
if (label2 === "EXPONENT") {
|
|
2599
|
+
exponent = parseInt(line.slice(0, 60).trim(), 10);
|
|
2600
|
+
} else if (label2 === "LAT1 / LAT2 / DLAT") {
|
|
2601
|
+
const [a, b, d] = line.trim().split(/\s+/).map(Number);
|
|
2602
|
+
lats = gridRange(a, b, d);
|
|
2603
|
+
} else if (label2 === "LON1 / LON2 / DLON") {
|
|
2604
|
+
const [a, b, d] = line.trim().split(/\s+/).map(Number);
|
|
2605
|
+
lons = gridRange(a, b, d);
|
|
2606
|
+
} else if (label2 === "END OF HEADER") {
|
|
2607
|
+
i++;
|
|
2608
|
+
break;
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
if (lats.length === 0 || lons.length === 0) {
|
|
2612
|
+
throw new Error("IONEX: missing grid definition");
|
|
2613
|
+
}
|
|
2614
|
+
const scale = Math.pow(10, exponent);
|
|
2615
|
+
while (i < lines.length) {
|
|
2616
|
+
const line = lines[i];
|
|
2617
|
+
const label2 = line.slice(60).trim();
|
|
2618
|
+
if (label2 === "START OF TEC MAP") {
|
|
2619
|
+
const map = new Float32Array(lats.length * lons.length).fill(NaN);
|
|
2620
|
+
let epochMs = 0;
|
|
2621
|
+
i++;
|
|
2622
|
+
while (i < lines.length) {
|
|
2623
|
+
const l = lines[i];
|
|
2624
|
+
const lab = l.slice(60).trim();
|
|
2625
|
+
if (lab === "EPOCH OF CURRENT MAP") {
|
|
2626
|
+
const f = l.slice(0, 60).trim().split(/\s+/).map(Number);
|
|
2627
|
+
epochMs = Date.UTC(f[0], f[1] - 1, f[2], f[3], f[4], f[5]);
|
|
2628
|
+
i++;
|
|
2629
|
+
} else if (lab === "LAT/LON1/LON2/DLON/H") {
|
|
2630
|
+
const lat = parseFloat(l.slice(2, 8));
|
|
2631
|
+
const latIdx = lats.findIndex((v) => Math.abs(v - lat) < 1e-6);
|
|
2632
|
+
i++;
|
|
2633
|
+
let lonIdx = 0;
|
|
2634
|
+
while (lonIdx < lons.length && i < lines.length) {
|
|
2635
|
+
const row = lines[i];
|
|
2636
|
+
for (let c = 0; c + 5 <= 80 && lonIdx < lons.length; c += 5) {
|
|
2637
|
+
const vStr = row.slice(c, c + 5).trim();
|
|
2638
|
+
if (vStr === "") continue;
|
|
2639
|
+
const v = parseInt(vStr, 10);
|
|
2640
|
+
if (latIdx >= 0) {
|
|
2641
|
+
map[latIdx * lons.length + lonIdx] = v === 9999 ? NaN : v * scale;
|
|
2642
|
+
}
|
|
2643
|
+
lonIdx++;
|
|
2644
|
+
}
|
|
2645
|
+
i++;
|
|
2646
|
+
}
|
|
2647
|
+
} else if (lab === "END OF TEC MAP") {
|
|
2648
|
+
i++;
|
|
2649
|
+
break;
|
|
2650
|
+
} else {
|
|
2651
|
+
i++;
|
|
2652
|
+
}
|
|
2653
|
+
}
|
|
2654
|
+
epochs.push(epochMs);
|
|
2655
|
+
maps.push(map);
|
|
2656
|
+
} else if (label2 === "START OF RMS MAP" || label2 === "END OF FILE") {
|
|
2657
|
+
break;
|
|
2658
|
+
} else {
|
|
2659
|
+
i++;
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
return { epochs, lats, lons, maps };
|
|
2663
|
+
}
|
|
2664
|
+
|
|
2578
2665
|
// src/rtcm3/decoder.ts
|
|
2579
2666
|
var debugHandler = null;
|
|
2580
2667
|
function setRtcm3DebugHandler(fn) {
|
|
@@ -4427,13 +4514,33 @@ function computeLiveSkyPositions(ephemerides, rxPos, cn0Map) {
|
|
|
4427
4514
|
}
|
|
4428
4515
|
return result;
|
|
4429
4516
|
}
|
|
4517
|
+
function maskRadForAzimuth(maskDeg) {
|
|
4518
|
+
if (typeof maskDeg === "number") {
|
|
4519
|
+
const m = maskDeg * Math.PI / 180;
|
|
4520
|
+
return () => m;
|
|
4521
|
+
}
|
|
4522
|
+
const n = maskDeg.length;
|
|
4523
|
+
if (n === 0) return () => 0;
|
|
4524
|
+
return (azRad) => {
|
|
4525
|
+
const azDeg = (azRad * 180 / Math.PI % 360 + 360) % 360;
|
|
4526
|
+
const pos = azDeg / 360 * n;
|
|
4527
|
+
const i = Math.floor(pos) % n;
|
|
4528
|
+
const f = pos - Math.floor(pos);
|
|
4529
|
+
const a = maskDeg[i];
|
|
4530
|
+
const b = maskDeg[(i + 1) % n];
|
|
4531
|
+
return ((1 - f) * a + f * b) * Math.PI / 180;
|
|
4532
|
+
};
|
|
4533
|
+
}
|
|
4430
4534
|
function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, elevationMaskDeg = 10) {
|
|
4431
4535
|
const stepMs = stepSec * 1e3;
|
|
4432
4536
|
const times = [];
|
|
4433
4537
|
for (let t = startMs; t <= endMs; t += stepMs) times.push(t);
|
|
4434
|
-
const
|
|
4538
|
+
const maskRadFor = maskRadForAzimuth(elevationMaskDeg);
|
|
4435
4539
|
const all = computeAllPositions(ephemerides, times, rxPos);
|
|
4436
4540
|
const elevation = {};
|
|
4541
|
+
const azimuth = {};
|
|
4542
|
+
const subLat = {};
|
|
4543
|
+
const subLon = {};
|
|
4437
4544
|
const visibleCount = new Array(times.length).fill(0);
|
|
4438
4545
|
const pdop = new Array(times.length).fill(null);
|
|
4439
4546
|
const gdop = new Array(times.length).fill(null);
|
|
@@ -4443,9 +4550,12 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
4443
4550
|
for (const prn of all.prns) {
|
|
4444
4551
|
const series = all.positions[prn];
|
|
4445
4552
|
elevation[prn] = series.map((p) => p ? p.el : null);
|
|
4553
|
+
azimuth[prn] = series.map((p) => p ? p.az : null);
|
|
4554
|
+
subLat[prn] = series.map((p) => p ? p.lat : null);
|
|
4555
|
+
subLon[prn] = series.map((p) => p ? p.lon : null);
|
|
4446
4556
|
for (let i = 0; i < series.length; i++) {
|
|
4447
4557
|
const p = series[i];
|
|
4448
|
-
if (p && p.el >=
|
|
4558
|
+
if (p && p.el >= maskRadFor(p.az)) {
|
|
4449
4559
|
visibleCount[i]++;
|
|
4450
4560
|
visiblePerEpoch[i].push({ az: p.az, el: p.el });
|
|
4451
4561
|
}
|
|
@@ -4466,7 +4576,8 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
4466
4576
|
let peakTime = 0;
|
|
4467
4577
|
for (let i = 0; i <= els.length; i++) {
|
|
4468
4578
|
const el = i < els.length ? els[i] : null;
|
|
4469
|
-
const
|
|
4579
|
+
const az = all.positions[prn][i]?.az ?? 0;
|
|
4580
|
+
const above = el !== null && el !== void 0 && el >= maskRadFor(az);
|
|
4470
4581
|
if (above) {
|
|
4471
4582
|
if (start === -1) {
|
|
4472
4583
|
start = i;
|
|
@@ -4490,7 +4601,19 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
4490
4601
|
}
|
|
4491
4602
|
}
|
|
4492
4603
|
passes.sort((a, b) => a.rise - b.rise);
|
|
4493
|
-
return {
|
|
4604
|
+
return {
|
|
4605
|
+
times,
|
|
4606
|
+
elevation,
|
|
4607
|
+
azimuth,
|
|
4608
|
+
subLat,
|
|
4609
|
+
subLon,
|
|
4610
|
+
visibleCount,
|
|
4611
|
+
pdop,
|
|
4612
|
+
gdop,
|
|
4613
|
+
hdop,
|
|
4614
|
+
vdop,
|
|
4615
|
+
passes
|
|
4616
|
+
};
|
|
4494
4617
|
}
|
|
4495
4618
|
|
|
4496
4619
|
// src/frames/index.ts
|
|
@@ -7341,6 +7464,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
7341
7464
|
horizonDistance,
|
|
7342
7465
|
ionoFree,
|
|
7343
7466
|
keplerPosition,
|
|
7467
|
+
maskRadForAzimuth,
|
|
7344
7468
|
msmEpochToDate,
|
|
7345
7469
|
navTimesFromEph,
|
|
7346
7470
|
nmeaCoordToDecimal,
|
|
@@ -7348,6 +7472,7 @@ function computePsdDb(centerMHz, halfSpanChips, numPoints, psdFn, f0 = 1023e3, f
|
|
|
7348
7472
|
padR,
|
|
7349
7473
|
parseAntex,
|
|
7350
7474
|
parseCrxDataLine,
|
|
7475
|
+
parseIonex,
|
|
7351
7476
|
parseNavFile,
|
|
7352
7477
|
parseNmeaFile,
|
|
7353
7478
|
parseRinexStream,
|
package/dist/index.d.cts
CHANGED
|
@@ -4,12 +4,12 @@ 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 { CrxField, DiffState, EMPTY_WARNINGS, RinexWarning, RinexWarnings, WarningAccumulator, WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, writeRinexNav } from './rinex.cjs';
|
|
7
|
+
export { CrxField, DiffState, EMPTY_WARNINGS, IonexGrid, RinexWarning, RinexWarnings, WarningAccumulator, WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseIonex, writeRinexNav } 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 { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, p as parseNavFile } from './nav-BAI1a9vK.cjs';
|
|
10
10
|
export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.cjs';
|
|
11
11
|
export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.cjs';
|
|
12
|
-
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris } from './orbit.cjs';
|
|
12
|
+
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, selectEphemeris } from './orbit.cjs';
|
|
13
13
|
export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.cjs';
|
|
14
14
|
export { SppOptions, SppSolution, ionoFree, satClockCorrection, solveSpp } from './positioning.cjs';
|
|
15
15
|
export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -4,12 +4,12 @@ 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 { CrxField, DiffState, EMPTY_WARNINGS, RinexWarning, RinexWarnings, WarningAccumulator, WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, writeRinexNav } from './rinex.js';
|
|
7
|
+
export { CrxField, DiffState, EMPTY_WARNINGS, IonexGrid, RinexWarning, RinexWarnings, WarningAccumulator, WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseIonex, writeRinexNav } 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 { E as Ephemeris, G as GlonassEphemeris, K as KeplerEphemeris, N as NavHeader, a as NavResult, p as parseNavFile } from './nav-BAI1a9vK.js';
|
|
10
10
|
export { B as BitReader, E as EphemerisInfo, R as Rtcm3DebugHandler, a as Rtcm3Decoder, b as Rtcm3Frame, d as decodeEphemeris, r as readString, c as reportDecodeError, s as setRtcm3DebugHandler } from './ephemeris-Ohl6NAfw.js';
|
|
11
11
|
export { MessageTypeStats, MsmEpoch, MsmSatObs, MsmSignal, RTCM3_MESSAGE_NAMES, SatCn0, SignalCn0, StationMeta, StreamStats, createStationMeta, createStreamStats, decodeMsmFull, msmEpochToDate, resetGloFreqCache, rtcm3Constellation, setGloFreqNumber, updateStationMeta, updateStreamStats } from './rtcm3.js';
|
|
12
|
-
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris } from './orbit.js';
|
|
12
|
+
export { AllPositionsData, DopValues, EpochSkyData, SatAzEl, SatPoint, SatPosition, VisibilityPass, VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, selectEphemeris } from './orbit.js';
|
|
13
13
|
export { Helmert14, REFERENCE_FRAMES, ReferenceFrame, applyHelmert, dateToEpoch, transformFrame } from './frames.js';
|
|
14
14
|
export { SppOptions, SppSolution, ionoFree, satClockCorrection, solveSpp } from './positioning.js';
|
|
15
15
|
export { NtripCaster, NtripConnectionInfo, NtripNetwork, NtripStream, NtripStreamConnection, NtripVersion, Sourcetable, SourcetableEntry, connectToMountpoint, fetchSourcetable, parseSourcetable } from './ntrip.js';
|
package/dist/index.js
CHANGED
|
@@ -102,7 +102,7 @@ import {
|
|
|
102
102
|
ionoFree,
|
|
103
103
|
satClockCorrection,
|
|
104
104
|
solveSpp
|
|
105
|
-
} from "./chunk-
|
|
105
|
+
} from "./chunk-ZRBRVNHK.js";
|
|
106
106
|
import {
|
|
107
107
|
computeAllPositions,
|
|
108
108
|
computeDop,
|
|
@@ -113,9 +113,10 @@ import {
|
|
|
113
113
|
ephInfoToEphemeris,
|
|
114
114
|
glonassPosition,
|
|
115
115
|
keplerPosition,
|
|
116
|
+
maskRadForAzimuth,
|
|
116
117
|
navTimesFromEph,
|
|
117
118
|
selectEphemeris
|
|
118
|
-
} from "./chunk-
|
|
119
|
+
} from "./chunk-647YMBJV.js";
|
|
119
120
|
import {
|
|
120
121
|
getBdsTime,
|
|
121
122
|
getDateFromBdsTime,
|
|
@@ -172,9 +173,10 @@ import {
|
|
|
172
173
|
hdrLine,
|
|
173
174
|
padL,
|
|
174
175
|
padR,
|
|
176
|
+
parseIonex,
|
|
175
177
|
parseNavFile,
|
|
176
178
|
writeRinexNav
|
|
177
|
-
} from "./chunk-
|
|
179
|
+
} from "./chunk-77VUSDNI.js";
|
|
178
180
|
import {
|
|
179
181
|
SYSTEM_ORDER,
|
|
180
182
|
crxDecompress,
|
|
@@ -431,6 +433,7 @@ export {
|
|
|
431
433
|
horizonDistance,
|
|
432
434
|
ionoFree,
|
|
433
435
|
keplerPosition,
|
|
436
|
+
maskRadForAzimuth,
|
|
434
437
|
msmEpochToDate,
|
|
435
438
|
navTimesFromEph,
|
|
436
439
|
nmeaCoordToDecimal,
|
|
@@ -438,6 +441,7 @@ export {
|
|
|
438
441
|
padR,
|
|
439
442
|
parseAntex,
|
|
440
443
|
parseCrxDataLine,
|
|
444
|
+
parseIonex,
|
|
441
445
|
parseNavFile,
|
|
442
446
|
parseNmeaFile,
|
|
443
447
|
parseRinexStream,
|
package/dist/orbit.cjs
CHANGED
|
@@ -31,6 +31,7 @@ __export(orbit_exports, {
|
|
|
31
31
|
geodeticToEcef: () => geodeticToEcef,
|
|
32
32
|
glonassPosition: () => glonassPosition,
|
|
33
33
|
keplerPosition: () => keplerPosition,
|
|
34
|
+
maskRadForAzimuth: () => maskRadForAzimuth,
|
|
34
35
|
navTimesFromEph: () => navTimesFromEph,
|
|
35
36
|
selectEphemeris: () => selectEphemeris
|
|
36
37
|
});
|
|
@@ -590,13 +591,33 @@ function computeLiveSkyPositions(ephemerides, rxPos, cn0Map) {
|
|
|
590
591
|
}
|
|
591
592
|
return result;
|
|
592
593
|
}
|
|
594
|
+
function maskRadForAzimuth(maskDeg) {
|
|
595
|
+
if (typeof maskDeg === "number") {
|
|
596
|
+
const m = maskDeg * Math.PI / 180;
|
|
597
|
+
return () => m;
|
|
598
|
+
}
|
|
599
|
+
const n = maskDeg.length;
|
|
600
|
+
if (n === 0) return () => 0;
|
|
601
|
+
return (azRad) => {
|
|
602
|
+
const azDeg = (azRad * 180 / Math.PI % 360 + 360) % 360;
|
|
603
|
+
const pos = azDeg / 360 * n;
|
|
604
|
+
const i = Math.floor(pos) % n;
|
|
605
|
+
const f = pos - Math.floor(pos);
|
|
606
|
+
const a = maskDeg[i];
|
|
607
|
+
const b = maskDeg[(i + 1) % n];
|
|
608
|
+
return ((1 - f) * a + f * b) * Math.PI / 180;
|
|
609
|
+
};
|
|
610
|
+
}
|
|
593
611
|
function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, elevationMaskDeg = 10) {
|
|
594
612
|
const stepMs = stepSec * 1e3;
|
|
595
613
|
const times = [];
|
|
596
614
|
for (let t = startMs; t <= endMs; t += stepMs) times.push(t);
|
|
597
|
-
const
|
|
615
|
+
const maskRadFor = maskRadForAzimuth(elevationMaskDeg);
|
|
598
616
|
const all = computeAllPositions(ephemerides, times, rxPos);
|
|
599
617
|
const elevation = {};
|
|
618
|
+
const azimuth = {};
|
|
619
|
+
const subLat = {};
|
|
620
|
+
const subLon = {};
|
|
600
621
|
const visibleCount = new Array(times.length).fill(0);
|
|
601
622
|
const pdop = new Array(times.length).fill(null);
|
|
602
623
|
const gdop = new Array(times.length).fill(null);
|
|
@@ -606,9 +627,12 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
606
627
|
for (const prn of all.prns) {
|
|
607
628
|
const series = all.positions[prn];
|
|
608
629
|
elevation[prn] = series.map((p) => p ? p.el : null);
|
|
630
|
+
azimuth[prn] = series.map((p) => p ? p.az : null);
|
|
631
|
+
subLat[prn] = series.map((p) => p ? p.lat : null);
|
|
632
|
+
subLon[prn] = series.map((p) => p ? p.lon : null);
|
|
609
633
|
for (let i = 0; i < series.length; i++) {
|
|
610
634
|
const p = series[i];
|
|
611
|
-
if (p && p.el >=
|
|
635
|
+
if (p && p.el >= maskRadFor(p.az)) {
|
|
612
636
|
visibleCount[i]++;
|
|
613
637
|
visiblePerEpoch[i].push({ az: p.az, el: p.el });
|
|
614
638
|
}
|
|
@@ -629,7 +653,8 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
629
653
|
let peakTime = 0;
|
|
630
654
|
for (let i = 0; i <= els.length; i++) {
|
|
631
655
|
const el = i < els.length ? els[i] : null;
|
|
632
|
-
const
|
|
656
|
+
const az = all.positions[prn][i]?.az ?? 0;
|
|
657
|
+
const above = el !== null && el !== void 0 && el >= maskRadFor(az);
|
|
633
658
|
if (above) {
|
|
634
659
|
if (start === -1) {
|
|
635
660
|
start = i;
|
|
@@ -653,7 +678,19 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
653
678
|
}
|
|
654
679
|
}
|
|
655
680
|
passes.sort((a, b) => a.rise - b.rise);
|
|
656
|
-
return {
|
|
681
|
+
return {
|
|
682
|
+
times,
|
|
683
|
+
elevation,
|
|
684
|
+
azimuth,
|
|
685
|
+
subLat,
|
|
686
|
+
subLon,
|
|
687
|
+
visibleCount,
|
|
688
|
+
pdop,
|
|
689
|
+
gdop,
|
|
690
|
+
hdop,
|
|
691
|
+
vdop,
|
|
692
|
+
passes
|
|
693
|
+
};
|
|
657
694
|
}
|
|
658
695
|
// Annotate the CommonJS export names for ESM import in node:
|
|
659
696
|
0 && (module.exports = {
|
|
@@ -668,6 +705,7 @@ function computeVisibility(ephemerides, rxPos, startMs, endMs, stepSec = 300, el
|
|
|
668
705
|
geodeticToEcef,
|
|
669
706
|
glonassPosition,
|
|
670
707
|
keplerPosition,
|
|
708
|
+
maskRadForAzimuth,
|
|
671
709
|
navTimesFromEph,
|
|
672
710
|
selectEphemeris
|
|
673
711
|
});
|
package/dist/orbit.d.cts
CHANGED
|
@@ -133,6 +133,12 @@ interface VisibilityResult {
|
|
|
133
133
|
times: number[];
|
|
134
134
|
/** Elevation (radians) per PRN per epoch; null when no valid ephemeris. */
|
|
135
135
|
elevation: Record<string, (number | null)[]>;
|
|
136
|
+
/** Azimuth (radians) per PRN per epoch; null when no valid ephemeris. */
|
|
137
|
+
azimuth: Record<string, (number | null)[]>;
|
|
138
|
+
/** Sub-satellite latitude (radians) per PRN per epoch. */
|
|
139
|
+
subLat: Record<string, (number | null)[]>;
|
|
140
|
+
/** Sub-satellite longitude (radians) per PRN per epoch. */
|
|
141
|
+
subLon: Record<string, (number | null)[]>;
|
|
136
142
|
/** Number of satellites at or above the mask, per epoch. */
|
|
137
143
|
visibleCount: number[];
|
|
138
144
|
/** PDOP per epoch (null when < 4 satellites above the mask). */
|
|
@@ -146,6 +152,12 @@ interface VisibilityResult {
|
|
|
146
152
|
/** Discrete above-mask passes, sorted by rise time. */
|
|
147
153
|
passes: VisibilityPass[];
|
|
148
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Build a mask lookup (radians) from a scalar or per-azimuth array of
|
|
157
|
+
* mask values in degrees. Array entries span 0–360° uniformly and are
|
|
158
|
+
* linearly interpolated.
|
|
159
|
+
*/
|
|
160
|
+
declare function maskRadForAzimuth(maskDeg: number | number[]): (azRad: number) => number;
|
|
149
161
|
/**
|
|
150
162
|
* Predict satellite visibility and DOP over a time window for a fixed
|
|
151
163
|
* receiver location.
|
|
@@ -155,8 +167,11 @@ interface VisibilityResult {
|
|
|
155
167
|
* @param startMs Window start (Unix ms).
|
|
156
168
|
* @param endMs Window end (Unix ms).
|
|
157
169
|
* @param stepSec Sample spacing in seconds (default 300).
|
|
158
|
-
* @param elevationMaskDeg Elevation mask in degrees (default 10)
|
|
170
|
+
* @param elevationMaskDeg Elevation mask in degrees (default 10) — a
|
|
171
|
+
* scalar, or an array of per-azimuth mask values in degrees
|
|
172
|
+
* (uniformly spanning 0–360°, e.g. 36 sectors of 10°) describing a
|
|
173
|
+
* local horizon/obstruction profile.
|
|
159
174
|
*/
|
|
160
|
-
declare function computeVisibility(ephemerides: Ephemeris[], rxPos: [number, number, number], startMs: number, endMs: number, stepSec?: number, elevationMaskDeg?: number): VisibilityResult;
|
|
175
|
+
declare function computeVisibility(ephemerides: Ephemeris[], rxPos: [number, number, number], startMs: number, endMs: number, stepSec?: number, elevationMaskDeg?: number | number[]): VisibilityResult;
|
|
161
176
|
|
|
162
|
-
export { type AllPositionsData, type DopValues, type EpochSkyData, type SatAzEl, type SatPoint, type SatPosition, type VisibilityPass, type VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris };
|
|
177
|
+
export { type AllPositionsData, type DopValues, type EpochSkyData, type SatAzEl, type SatPoint, type SatPosition, type VisibilityPass, type VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, selectEphemeris };
|
package/dist/orbit.d.ts
CHANGED
|
@@ -133,6 +133,12 @@ interface VisibilityResult {
|
|
|
133
133
|
times: number[];
|
|
134
134
|
/** Elevation (radians) per PRN per epoch; null when no valid ephemeris. */
|
|
135
135
|
elevation: Record<string, (number | null)[]>;
|
|
136
|
+
/** Azimuth (radians) per PRN per epoch; null when no valid ephemeris. */
|
|
137
|
+
azimuth: Record<string, (number | null)[]>;
|
|
138
|
+
/** Sub-satellite latitude (radians) per PRN per epoch. */
|
|
139
|
+
subLat: Record<string, (number | null)[]>;
|
|
140
|
+
/** Sub-satellite longitude (radians) per PRN per epoch. */
|
|
141
|
+
subLon: Record<string, (number | null)[]>;
|
|
136
142
|
/** Number of satellites at or above the mask, per epoch. */
|
|
137
143
|
visibleCount: number[];
|
|
138
144
|
/** PDOP per epoch (null when < 4 satellites above the mask). */
|
|
@@ -146,6 +152,12 @@ interface VisibilityResult {
|
|
|
146
152
|
/** Discrete above-mask passes, sorted by rise time. */
|
|
147
153
|
passes: VisibilityPass[];
|
|
148
154
|
}
|
|
155
|
+
/**
|
|
156
|
+
* Build a mask lookup (radians) from a scalar or per-azimuth array of
|
|
157
|
+
* mask values in degrees. Array entries span 0–360° uniformly and are
|
|
158
|
+
* linearly interpolated.
|
|
159
|
+
*/
|
|
160
|
+
declare function maskRadForAzimuth(maskDeg: number | number[]): (azRad: number) => number;
|
|
149
161
|
/**
|
|
150
162
|
* Predict satellite visibility and DOP over a time window for a fixed
|
|
151
163
|
* receiver location.
|
|
@@ -155,8 +167,11 @@ interface VisibilityResult {
|
|
|
155
167
|
* @param startMs Window start (Unix ms).
|
|
156
168
|
* @param endMs Window end (Unix ms).
|
|
157
169
|
* @param stepSec Sample spacing in seconds (default 300).
|
|
158
|
-
* @param elevationMaskDeg Elevation mask in degrees (default 10)
|
|
170
|
+
* @param elevationMaskDeg Elevation mask in degrees (default 10) — a
|
|
171
|
+
* scalar, or an array of per-azimuth mask values in degrees
|
|
172
|
+
* (uniformly spanning 0–360°, e.g. 36 sectors of 10°) describing a
|
|
173
|
+
* local horizon/obstruction profile.
|
|
159
174
|
*/
|
|
160
|
-
declare function computeVisibility(ephemerides: Ephemeris[], rxPos: [number, number, number], startMs: number, endMs: number, stepSec?: number, elevationMaskDeg?: number): VisibilityResult;
|
|
175
|
+
declare function computeVisibility(ephemerides: Ephemeris[], rxPos: [number, number, number], startMs: number, endMs: number, stepSec?: number, elevationMaskDeg?: number | number[]): VisibilityResult;
|
|
161
176
|
|
|
162
|
-
export { type AllPositionsData, type DopValues, type EpochSkyData, type SatAzEl, type SatPoint, type SatPosition, type VisibilityPass, type VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, navTimesFromEph, selectEphemeris };
|
|
177
|
+
export { type AllPositionsData, type DopValues, type EpochSkyData, type SatAzEl, type SatPoint, type SatPosition, type VisibilityPass, type VisibilityResult, computeAllPositions, computeDop, computeLiveSkyPositions, computeSatPosition, computeVisibility, ecefToAzEl, ephInfoToEphemeris, glonassPosition, keplerPosition, maskRadForAzimuth, navTimesFromEph, selectEphemeris };
|
package/dist/orbit.js
CHANGED
|
@@ -8,9 +8,10 @@ import {
|
|
|
8
8
|
ephInfoToEphemeris,
|
|
9
9
|
glonassPosition,
|
|
10
10
|
keplerPosition,
|
|
11
|
+
maskRadForAzimuth,
|
|
11
12
|
navTimesFromEph,
|
|
12
13
|
selectEphemeris
|
|
13
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-647YMBJV.js";
|
|
14
15
|
import "./chunk-HVXYFUCB.js";
|
|
15
16
|
import {
|
|
16
17
|
ecefToGeodetic,
|
|
@@ -31,6 +32,7 @@ export {
|
|
|
31
32
|
geodeticToEcef,
|
|
32
33
|
glonassPosition,
|
|
33
34
|
keplerPosition,
|
|
35
|
+
maskRadForAzimuth,
|
|
34
36
|
navTimesFromEph,
|
|
35
37
|
selectEphemeris
|
|
36
38
|
};
|
package/dist/positioning.js
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
ionoFree,
|
|
3
3
|
satClockCorrection,
|
|
4
4
|
solveSpp
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-ZRBRVNHK.js";
|
|
6
|
+
import "./chunk-647YMBJV.js";
|
|
7
7
|
import "./chunk-HVXYFUCB.js";
|
|
8
8
|
import "./chunk-37QNKGTC.js";
|
|
9
9
|
import "./chunk-6FAL6P4G.js";
|
package/dist/rinex.cjs
CHANGED
|
@@ -30,6 +30,7 @@ __export(rinex_exports, {
|
|
|
30
30
|
padL: () => padL,
|
|
31
31
|
padR: () => padR,
|
|
32
32
|
parseCrxDataLine: () => parseCrxDataLine,
|
|
33
|
+
parseIonex: () => parseIonex,
|
|
33
34
|
parseNavFile: () => parseNavFile,
|
|
34
35
|
parseRinexStream: () => parseRinexStream,
|
|
35
36
|
systemCmp: () => systemCmp,
|
|
@@ -1449,6 +1450,91 @@ function writeRinexNav(nav) {
|
|
|
1449
1450
|
);
|
|
1450
1451
|
return header + records.join("\n") + "\n";
|
|
1451
1452
|
}
|
|
1453
|
+
|
|
1454
|
+
// src/rinex/ionex.ts
|
|
1455
|
+
function gridRange(l1, l2, dl) {
|
|
1456
|
+
const out = [];
|
|
1457
|
+
const n = Math.round((l2 - l1) / dl) + 1;
|
|
1458
|
+
for (let i = 0; i < n; i++) out.push(l1 + i * dl);
|
|
1459
|
+
return out;
|
|
1460
|
+
}
|
|
1461
|
+
function parseIonex(text) {
|
|
1462
|
+
const lines = text.split("\n");
|
|
1463
|
+
let exponent = -1;
|
|
1464
|
+
let lats = [];
|
|
1465
|
+
let lons = [];
|
|
1466
|
+
const epochs = [];
|
|
1467
|
+
const maps = [];
|
|
1468
|
+
let i = 0;
|
|
1469
|
+
for (; i < lines.length; i++) {
|
|
1470
|
+
const line = lines[i];
|
|
1471
|
+
const label = line.slice(60).trim();
|
|
1472
|
+
if (label === "EXPONENT") {
|
|
1473
|
+
exponent = parseInt(line.slice(0, 60).trim(), 10);
|
|
1474
|
+
} else if (label === "LAT1 / LAT2 / DLAT") {
|
|
1475
|
+
const [a, b, d] = line.trim().split(/\s+/).map(Number);
|
|
1476
|
+
lats = gridRange(a, b, d);
|
|
1477
|
+
} else if (label === "LON1 / LON2 / DLON") {
|
|
1478
|
+
const [a, b, d] = line.trim().split(/\s+/).map(Number);
|
|
1479
|
+
lons = gridRange(a, b, d);
|
|
1480
|
+
} else if (label === "END OF HEADER") {
|
|
1481
|
+
i++;
|
|
1482
|
+
break;
|
|
1483
|
+
}
|
|
1484
|
+
}
|
|
1485
|
+
if (lats.length === 0 || lons.length === 0) {
|
|
1486
|
+
throw new Error("IONEX: missing grid definition");
|
|
1487
|
+
}
|
|
1488
|
+
const scale = Math.pow(10, exponent);
|
|
1489
|
+
while (i < lines.length) {
|
|
1490
|
+
const line = lines[i];
|
|
1491
|
+
const label = line.slice(60).trim();
|
|
1492
|
+
if (label === "START OF TEC MAP") {
|
|
1493
|
+
const map = new Float32Array(lats.length * lons.length).fill(NaN);
|
|
1494
|
+
let epochMs = 0;
|
|
1495
|
+
i++;
|
|
1496
|
+
while (i < lines.length) {
|
|
1497
|
+
const l = lines[i];
|
|
1498
|
+
const lab = l.slice(60).trim();
|
|
1499
|
+
if (lab === "EPOCH OF CURRENT MAP") {
|
|
1500
|
+
const f = l.slice(0, 60).trim().split(/\s+/).map(Number);
|
|
1501
|
+
epochMs = Date.UTC(f[0], f[1] - 1, f[2], f[3], f[4], f[5]);
|
|
1502
|
+
i++;
|
|
1503
|
+
} else if (lab === "LAT/LON1/LON2/DLON/H") {
|
|
1504
|
+
const lat = parseFloat(l.slice(2, 8));
|
|
1505
|
+
const latIdx = lats.findIndex((v) => Math.abs(v - lat) < 1e-6);
|
|
1506
|
+
i++;
|
|
1507
|
+
let lonIdx = 0;
|
|
1508
|
+
while (lonIdx < lons.length && i < lines.length) {
|
|
1509
|
+
const row = lines[i];
|
|
1510
|
+
for (let c = 0; c + 5 <= 80 && lonIdx < lons.length; c += 5) {
|
|
1511
|
+
const vStr = row.slice(c, c + 5).trim();
|
|
1512
|
+
if (vStr === "") continue;
|
|
1513
|
+
const v = parseInt(vStr, 10);
|
|
1514
|
+
if (latIdx >= 0) {
|
|
1515
|
+
map[latIdx * lons.length + lonIdx] = v === 9999 ? NaN : v * scale;
|
|
1516
|
+
}
|
|
1517
|
+
lonIdx++;
|
|
1518
|
+
}
|
|
1519
|
+
i++;
|
|
1520
|
+
}
|
|
1521
|
+
} else if (lab === "END OF TEC MAP") {
|
|
1522
|
+
i++;
|
|
1523
|
+
break;
|
|
1524
|
+
} else {
|
|
1525
|
+
i++;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
epochs.push(epochMs);
|
|
1529
|
+
maps.push(map);
|
|
1530
|
+
} else if (label === "START OF RMS MAP" || label === "END OF FILE") {
|
|
1531
|
+
break;
|
|
1532
|
+
} else {
|
|
1533
|
+
i++;
|
|
1534
|
+
}
|
|
1535
|
+
}
|
|
1536
|
+
return { epochs, lats, lons, maps };
|
|
1537
|
+
}
|
|
1452
1538
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1453
1539
|
0 && (module.exports = {
|
|
1454
1540
|
EMPTY_WARNINGS,
|
|
@@ -1461,6 +1547,7 @@ function writeRinexNav(nav) {
|
|
|
1461
1547
|
padL,
|
|
1462
1548
|
padR,
|
|
1463
1549
|
parseCrxDataLine,
|
|
1550
|
+
parseIonex,
|
|
1464
1551
|
parseNavFile,
|
|
1465
1552
|
parseRinexStream,
|
|
1466
1553
|
systemCmp,
|
package/dist/rinex.d.cts
CHANGED
|
@@ -113,4 +113,26 @@ declare class WarningAccumulator {
|
|
|
113
113
|
*/
|
|
114
114
|
declare function writeRinexNav(nav: NavResult): string;
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
/**
|
|
117
|
+
* IONEX 1.0 parser — global ionosphere maps (GIMs) as published by
|
|
118
|
+
* the IGS analysis centres (e.g. ESA0OPSRAP_*_GIM.INX).
|
|
119
|
+
*
|
|
120
|
+
* Returns the TEC maps in TECU on a regular lat/lon grid, one map per
|
|
121
|
+
* epoch. RMS maps and the DCB auxiliary block are skipped.
|
|
122
|
+
*/
|
|
123
|
+
interface IonexGrid {
|
|
124
|
+
/** Map epochs (Unix ms, UTC). */
|
|
125
|
+
epochs: number[];
|
|
126
|
+
/** Grid latitudes (degrees), in file order (typically 87.5 → −87.5). */
|
|
127
|
+
lats: number[];
|
|
128
|
+
/** Grid longitudes (degrees), in file order (typically −180 → 180). */
|
|
129
|
+
lons: number[];
|
|
130
|
+
/**
|
|
131
|
+
* TEC maps in TECU: maps[epochIdx][latIdx * lons.length + lonIdx].
|
|
132
|
+
* NaN where the file marks no value (9999).
|
|
133
|
+
*/
|
|
134
|
+
maps: Float32Array[];
|
|
135
|
+
}
|
|
136
|
+
declare function parseIonex(text: string): IonexGrid;
|
|
137
|
+
|
|
138
|
+
export { type CrxField, type DiffState, EMPTY_WARNINGS, type IonexGrid, NavResult, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseIonex, writeRinexNav };
|
package/dist/rinex.d.ts
CHANGED
|
@@ -113,4 +113,26 @@ declare class WarningAccumulator {
|
|
|
113
113
|
*/
|
|
114
114
|
declare function writeRinexNav(nav: NavResult): string;
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
/**
|
|
117
|
+
* IONEX 1.0 parser — global ionosphere maps (GIMs) as published by
|
|
118
|
+
* the IGS analysis centres (e.g. ESA0OPSRAP_*_GIM.INX).
|
|
119
|
+
*
|
|
120
|
+
* Returns the TEC maps in TECU on a regular lat/lon grid, one map per
|
|
121
|
+
* epoch. RMS maps and the DCB auxiliary block are skipped.
|
|
122
|
+
*/
|
|
123
|
+
interface IonexGrid {
|
|
124
|
+
/** Map epochs (Unix ms, UTC). */
|
|
125
|
+
epochs: number[];
|
|
126
|
+
/** Grid latitudes (degrees), in file order (typically 87.5 → −87.5). */
|
|
127
|
+
lats: number[];
|
|
128
|
+
/** Grid longitudes (degrees), in file order (typically −180 → 180). */
|
|
129
|
+
lons: number[];
|
|
130
|
+
/**
|
|
131
|
+
* TEC maps in TECU: maps[epochIdx][latIdx * lons.length + lonIdx].
|
|
132
|
+
* NaN where the file marks no value (9999).
|
|
133
|
+
*/
|
|
134
|
+
maps: Float32Array[];
|
|
135
|
+
}
|
|
136
|
+
declare function parseIonex(text: string): IonexGrid;
|
|
137
|
+
|
|
138
|
+
export { type CrxField, type DiffState, EMPTY_WARNINGS, type IonexGrid, NavResult, RinexHeader, type RinexWarning, type RinexWarnings, WarningAccumulator, type WarningSeverity, crxDecompress, crxRepair, fmtF, hdrLine, padL, padR, parseCrxDataLine, parseIonex, writeRinexNav };
|
package/dist/rinex.js
CHANGED
|
@@ -5,9 +5,10 @@ import {
|
|
|
5
5
|
hdrLine,
|
|
6
6
|
padL,
|
|
7
7
|
padR,
|
|
8
|
+
parseIonex,
|
|
8
9
|
parseNavFile,
|
|
9
10
|
writeRinexNav
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-77VUSDNI.js";
|
|
11
12
|
import {
|
|
12
13
|
SYSTEM_ORDER,
|
|
13
14
|
crxDecompress,
|
|
@@ -29,6 +30,7 @@ export {
|
|
|
29
30
|
padL,
|
|
30
31
|
padR,
|
|
31
32
|
parseCrxDataLine,
|
|
33
|
+
parseIonex,
|
|
32
34
|
parseNavFile,
|
|
33
35
|
parseRinexStream,
|
|
34
36
|
systemCmp,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gnss-js",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"description": "Comprehensive GNSS library for JavaScript — time scales, coordinates, RINEX parsing, RTCM3 decoding, orbit computation, and signal analysis",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|