gnss-js 0.1.2 → 1.0.1
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/LICENSE +23 -0
- package/README.md +171 -5
- package/dist/analysis.cjs +1488 -0
- package/dist/analysis.d.cts +211 -0
- package/dist/analysis.d.ts +211 -0
- package/dist/analysis.js +14 -0
- package/dist/antex.cjs +239 -0
- package/dist/antex.d.cts +77 -0
- package/dist/antex.d.ts +77 -0
- package/dist/antex.js +8 -0
- package/dist/chunk-37QNKGTC.js +65 -0
- package/dist/chunk-4YN353Q7.js +440 -0
- package/dist/chunk-5CMSYIYM.js +214 -0
- package/dist/chunk-5S5MONFK.js +0 -0
- package/dist/chunk-6FAL6P4G.js +12 -0
- package/dist/chunk-7NOFXKET.js +433 -0
- package/dist/chunk-BJHTBYNG.js +154 -0
- package/dist/chunk-HBLU2EJ4.js +802 -0
- package/dist/chunk-HKN3PUGN.js +800 -0
- package/dist/chunk-LEEU5OIO.js +75 -0
- package/dist/chunk-LWNTWBHB.js +268 -0
- package/dist/chunk-MIIM4LDY.js +239 -0
- package/dist/chunk-SO3POWWR.js +502 -0
- package/dist/chunk-W4YMQKWH.js +622 -0
- package/dist/chunk-WP2JFDLA.js +1475 -0
- package/dist/chunk-YDMYO3YK.js +220 -0
- package/dist/constants.cjs +423 -0
- package/dist/constants.d.cts +14 -0
- package/dist/constants.d.ts +14 -0
- package/dist/constants.js +103 -0
- package/dist/coordinates.cjs +337 -0
- package/dist/coordinates.d.cts +81 -0
- package/dist/coordinates.d.ts +81 -0
- package/dist/coordinates.js +39 -0
- package/dist/ecef-CF0uAysr.d.cts +40 -0
- package/dist/ecef-CF0uAysr.d.ts +40 -0
- package/dist/ephemeris-C10stHhM.d.cts +114 -0
- package/dist/ephemeris-C10stHhM.d.ts +114 -0
- package/dist/gnss-BT6ulR17.d.cts +56 -0
- package/dist/gnss-C-tgoYNa.d.ts +56 -0
- package/dist/index.cjs +5940 -78
- package/dist/index.d.cts +17 -96
- package/dist/index.d.ts +17 -96
- package/dist/index.js +352 -415
- package/dist/nav-BAI1a9vK.d.cts +108 -0
- package/dist/nav-BAI1a9vK.d.ts +108 -0
- package/dist/nmea.cjs +247 -0
- package/dist/nmea.d.cts +37 -0
- package/dist/nmea.d.ts +37 -0
- package/dist/nmea.js +12 -0
- package/dist/ntrip.cjs +180 -0
- package/dist/ntrip.d.cts +98 -0
- package/dist/ntrip.d.ts +98 -0
- package/dist/ntrip.js +10 -0
- package/dist/orbit.cjs +511 -0
- package/dist/orbit.d.cts +117 -0
- package/dist/orbit.d.ts +117 -0
- package/dist/orbit.js +29 -0
- package/dist/parser-JPjjFgeP.d.cts +73 -0
- package/dist/parser-JPjjFgeP.d.ts +73 -0
- package/dist/rinex.cjs +1469 -0
- package/dist/rinex.d.cts +116 -0
- package/dist/rinex.d.ts +116 -0
- package/dist/rinex.js +37 -0
- package/dist/rtcm3.cjs +1512 -0
- package/dist/rtcm3.d.cts +143 -0
- package/dist/rtcm3.d.ts +143 -0
- package/dist/rtcm3.js +31 -0
- package/dist/signals.cjs +858 -0
- package/dist/signals.d.cts +93 -0
- package/dist/signals.d.ts +93 -0
- package/dist/signals.js +70 -0
- package/dist/time-DnI1VpE8.d.cts +33 -0
- package/dist/time-DnI1VpE8.d.ts +33 -0
- package/dist/time.cjs +585 -0
- package/dist/time.d.cts +307 -0
- package/dist/time.d.ts +307 -0
- package/dist/time.js +154 -0
- package/package.json +112 -14
- package/.prettierrc +0 -5
- package/jest.config.ts +0 -9
- package/test/functions.test.ts +0 -63
- package/test/gnss-scales.test.ts +0 -95
- package/test/julian.test.ts +0 -145
- package/test/rinex.test.ts +0 -11
- package/test/test.ts +0 -10
- package/test/utc.test.ts +0 -25
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
// src/constants/time.ts
|
|
2
|
+
var SECONDS_IN_WEEK = 604800;
|
|
3
|
+
var SECONDS_IN_DAY = 86400;
|
|
4
|
+
var SECONDS_IN_HOUR = 3600;
|
|
5
|
+
var SECONDS_IN_MINUTE = 60;
|
|
6
|
+
var MILLISECONDS_IN_WEEK = 6048e5;
|
|
7
|
+
var MILLISECONDS_IN_DAY = 864e5;
|
|
8
|
+
var MILLISECONDS_IN_HOUR = 36e5;
|
|
9
|
+
var MILLISECONDS_IN_MINUTE = 6e4;
|
|
10
|
+
var MILLISECONDS_IN_SECOND = 1e3;
|
|
11
|
+
var MILLISECONDS_TT_TAI = 32184;
|
|
12
|
+
var MILLISECONDS_GPS_TAI = 19e3;
|
|
13
|
+
var START_GPS_TIME = /* @__PURE__ */ new Date("1980-01-06T00:00:00Z");
|
|
14
|
+
var START_GAL_TIME = /* @__PURE__ */ new Date("1999-08-22T00:00:00Z");
|
|
15
|
+
var START_BDS_TIME = /* @__PURE__ */ new Date("2006-01-01T00:00:14Z");
|
|
16
|
+
var START_UNIX_TIME = /* @__PURE__ */ new Date("1969-12-31T23:59:49Z");
|
|
17
|
+
var START_NTP_TIME = /* @__PURE__ */ new Date("1900-01-01T00:00:00Z");
|
|
18
|
+
var START_GLO_LEAP = /* @__PURE__ */ new Date("1996-01-01T00:00:00Z");
|
|
19
|
+
var START_TAI_TIME = /* @__PURE__ */ new Date("1957-12-31T23:59:41Z");
|
|
20
|
+
var RINEX_CODES = [
|
|
21
|
+
"a",
|
|
22
|
+
"b",
|
|
23
|
+
"c",
|
|
24
|
+
"d",
|
|
25
|
+
"e",
|
|
26
|
+
"f",
|
|
27
|
+
"g",
|
|
28
|
+
"h",
|
|
29
|
+
"i",
|
|
30
|
+
"j",
|
|
31
|
+
"k",
|
|
32
|
+
"l",
|
|
33
|
+
"m",
|
|
34
|
+
"n",
|
|
35
|
+
"o",
|
|
36
|
+
"p",
|
|
37
|
+
"q",
|
|
38
|
+
"r",
|
|
39
|
+
"s",
|
|
40
|
+
"t",
|
|
41
|
+
"u",
|
|
42
|
+
"v",
|
|
43
|
+
"w",
|
|
44
|
+
"x"
|
|
45
|
+
];
|
|
46
|
+
var START_JULIAN_TAI = 24362045e-1;
|
|
47
|
+
var DAYS_MJD_JULIAN = 24000005e-1;
|
|
48
|
+
var DAYS_MJD2000_MJD = 51544.5;
|
|
49
|
+
var START_MJD_UNIX_SECONDS = 40587;
|
|
50
|
+
|
|
51
|
+
export {
|
|
52
|
+
SECONDS_IN_WEEK,
|
|
53
|
+
SECONDS_IN_DAY,
|
|
54
|
+
SECONDS_IN_HOUR,
|
|
55
|
+
SECONDS_IN_MINUTE,
|
|
56
|
+
MILLISECONDS_IN_WEEK,
|
|
57
|
+
MILLISECONDS_IN_DAY,
|
|
58
|
+
MILLISECONDS_IN_HOUR,
|
|
59
|
+
MILLISECONDS_IN_MINUTE,
|
|
60
|
+
MILLISECONDS_IN_SECOND,
|
|
61
|
+
MILLISECONDS_TT_TAI,
|
|
62
|
+
MILLISECONDS_GPS_TAI,
|
|
63
|
+
START_GPS_TIME,
|
|
64
|
+
START_GAL_TIME,
|
|
65
|
+
START_BDS_TIME,
|
|
66
|
+
START_UNIX_TIME,
|
|
67
|
+
START_NTP_TIME,
|
|
68
|
+
START_GLO_LEAP,
|
|
69
|
+
START_TAI_TIME,
|
|
70
|
+
RINEX_CODES,
|
|
71
|
+
START_JULIAN_TAI,
|
|
72
|
+
DAYS_MJD_JULIAN,
|
|
73
|
+
DAYS_MJD2000_MJD,
|
|
74
|
+
START_MJD_UNIX_SECONDS
|
|
75
|
+
};
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
// src/constants/gnss.ts
|
|
2
|
+
var SYSTEM_NAMES = {
|
|
3
|
+
G: "GPS",
|
|
4
|
+
R: "GLONASS",
|
|
5
|
+
E: "Galileo",
|
|
6
|
+
C: "BeiDou",
|
|
7
|
+
J: "QZSS",
|
|
8
|
+
I: "NavIC",
|
|
9
|
+
S: "SBAS"
|
|
10
|
+
};
|
|
11
|
+
var SYS_SHORT = {
|
|
12
|
+
G: "GPS",
|
|
13
|
+
R: "GLO",
|
|
14
|
+
E: "GAL",
|
|
15
|
+
C: "BDS",
|
|
16
|
+
J: "QZS",
|
|
17
|
+
I: "NIC",
|
|
18
|
+
S: "SBS"
|
|
19
|
+
};
|
|
20
|
+
var C_LIGHT = 299792458;
|
|
21
|
+
var FREQ = {
|
|
22
|
+
G: { "1": 157542e4, "2": 12276e5, "5": 117645e4 },
|
|
23
|
+
R: { "3": 1202025e3 },
|
|
24
|
+
E: {
|
|
25
|
+
"1": 157542e4,
|
|
26
|
+
"5": 117645e4,
|
|
27
|
+
"6": 127875e4,
|
|
28
|
+
"7": 120714e4,
|
|
29
|
+
"8": 1191795e3
|
|
30
|
+
},
|
|
31
|
+
C: {
|
|
32
|
+
"1": 157542e4,
|
|
33
|
+
"2": 1561098e3,
|
|
34
|
+
"5": 117645e4,
|
|
35
|
+
"6": 126852e4,
|
|
36
|
+
"7": 120714e4
|
|
37
|
+
},
|
|
38
|
+
J: { "1": 157542e4, "2": 12276e5, "5": 117645e4, "6": 127875e4 },
|
|
39
|
+
I: { "5": 117645e4, "9": 2492028e3 },
|
|
40
|
+
S: { "1": 157542e4, "5": 117645e4 }
|
|
41
|
+
};
|
|
42
|
+
var BAND_LABELS = {
|
|
43
|
+
G: { "1": "L1", "2": "L2", "5": "L5" },
|
|
44
|
+
R: { "1": "G1", "2": "G2", "3": "G3" },
|
|
45
|
+
E: { "1": "E1", "5": "E5a", "6": "E6", "7": "E5b", "8": "E5" },
|
|
46
|
+
C: { "1": "B1C", "2": "B1I", "5": "B2a", "6": "B3I", "7": "B2I" },
|
|
47
|
+
J: { "1": "L1", "2": "L2", "5": "L5", "6": "L6" },
|
|
48
|
+
I: { "5": "L5", "9": "S" },
|
|
49
|
+
S: { "1": "L1", "5": "L5" }
|
|
50
|
+
};
|
|
51
|
+
var DUAL_FREQ_PAIRS = {
|
|
52
|
+
G: [
|
|
53
|
+
["1", "2"],
|
|
54
|
+
["1", "5"]
|
|
55
|
+
],
|
|
56
|
+
R: [
|
|
57
|
+
["1", "2"],
|
|
58
|
+
["1", "3"]
|
|
59
|
+
],
|
|
60
|
+
E: [
|
|
61
|
+
["1", "5"],
|
|
62
|
+
["1", "7"],
|
|
63
|
+
["1", "6"]
|
|
64
|
+
],
|
|
65
|
+
C: [
|
|
66
|
+
["2", "7"],
|
|
67
|
+
["2", "6"],
|
|
68
|
+
["1", "5"]
|
|
69
|
+
],
|
|
70
|
+
J: [
|
|
71
|
+
["1", "2"],
|
|
72
|
+
["1", "5"]
|
|
73
|
+
],
|
|
74
|
+
I: [["5", "9"]],
|
|
75
|
+
S: [["1", "5"]]
|
|
76
|
+
};
|
|
77
|
+
var GLO_F1_BASE = 1602e6;
|
|
78
|
+
var GLO_F1_STEP = 562500;
|
|
79
|
+
var GLO_F2_BASE = 1246e6;
|
|
80
|
+
var GLO_F2_STEP = 437500;
|
|
81
|
+
var GLO_F3 = 1202025e3;
|
|
82
|
+
var GLO_CHANNEL_FALLBACK = {
|
|
83
|
+
R01: 1,
|
|
84
|
+
R02: -4,
|
|
85
|
+
R03: 5,
|
|
86
|
+
R04: 6,
|
|
87
|
+
R05: 1,
|
|
88
|
+
R06: -4,
|
|
89
|
+
R07: 5,
|
|
90
|
+
R08: 6,
|
|
91
|
+
R09: -2,
|
|
92
|
+
R10: -7,
|
|
93
|
+
R11: 0,
|
|
94
|
+
R12: -1,
|
|
95
|
+
R13: -2,
|
|
96
|
+
R14: -7,
|
|
97
|
+
R15: 0,
|
|
98
|
+
R16: -1,
|
|
99
|
+
R17: 4,
|
|
100
|
+
R18: -3,
|
|
101
|
+
R19: 3,
|
|
102
|
+
R20: 2,
|
|
103
|
+
R21: 4,
|
|
104
|
+
R22: -3,
|
|
105
|
+
R23: 3,
|
|
106
|
+
R24: 2
|
|
107
|
+
};
|
|
108
|
+
function buildGloChannelMap(slots) {
|
|
109
|
+
if (Object.keys(slots).length === 0) return { ...GLO_CHANNEL_FALLBACK };
|
|
110
|
+
const map = {};
|
|
111
|
+
for (const [slot, k] of Object.entries(slots)) {
|
|
112
|
+
map[`R${String(slot).padStart(2, "0")}`] = k;
|
|
113
|
+
}
|
|
114
|
+
return map;
|
|
115
|
+
}
|
|
116
|
+
function gloFreq(gloChannels, prn, band) {
|
|
117
|
+
const k = gloChannels[prn];
|
|
118
|
+
if (k === void 0) return void 0;
|
|
119
|
+
if (band === "1") return GLO_F1_BASE + k * GLO_F1_STEP;
|
|
120
|
+
if (band === "2") return GLO_F2_BASE + k * GLO_F2_STEP;
|
|
121
|
+
if (band === "3") return GLO_F3;
|
|
122
|
+
return void 0;
|
|
123
|
+
}
|
|
124
|
+
function getFreq(gloChannels, prn, band) {
|
|
125
|
+
const sys = prn[0];
|
|
126
|
+
if (sys === "R") return gloFreq(gloChannels, prn, band);
|
|
127
|
+
return FREQ[sys]?.[band];
|
|
128
|
+
}
|
|
129
|
+
var BDS_SATELLITES = [
|
|
130
|
+
{ prn: "C01", phase: "BDS-2", orbit: "GEO" },
|
|
131
|
+
{ prn: "C02", phase: "BDS-2", orbit: "GEO" },
|
|
132
|
+
{ prn: "C03", phase: "BDS-2", orbit: "GEO" },
|
|
133
|
+
{ prn: "C04", phase: "BDS-2", orbit: "GEO" },
|
|
134
|
+
{ prn: "C05", phase: "BDS-2", orbit: "GEO" },
|
|
135
|
+
{ prn: "C06", phase: "BDS-2", orbit: "IGSO" },
|
|
136
|
+
{ prn: "C07", phase: "BDS-2", orbit: "IGSO" },
|
|
137
|
+
{ prn: "C08", phase: "BDS-2", orbit: "IGSO" },
|
|
138
|
+
{ prn: "C09", phase: "BDS-2", orbit: "IGSO" },
|
|
139
|
+
{ prn: "C10", phase: "BDS-2", orbit: "IGSO" },
|
|
140
|
+
{ prn: "C13", phase: "BDS-2", orbit: "IGSO" },
|
|
141
|
+
{ prn: "C16", phase: "BDS-2", orbit: "IGSO" },
|
|
142
|
+
{ prn: "C11", phase: "BDS-2", orbit: "MEO" },
|
|
143
|
+
{ prn: "C12", phase: "BDS-2", orbit: "MEO" },
|
|
144
|
+
{ prn: "C14", phase: "BDS-2", orbit: "MEO" },
|
|
145
|
+
{ prn: "C19", phase: "BDS-3", orbit: "MEO" },
|
|
146
|
+
{ prn: "C20", phase: "BDS-3", orbit: "MEO" },
|
|
147
|
+
{ prn: "C21", phase: "BDS-3", orbit: "MEO" },
|
|
148
|
+
{ prn: "C22", phase: "BDS-3", orbit: "MEO" },
|
|
149
|
+
{ prn: "C23", phase: "BDS-3", orbit: "MEO" },
|
|
150
|
+
{ prn: "C24", phase: "BDS-3", orbit: "MEO" },
|
|
151
|
+
{ prn: "C25", phase: "BDS-3", orbit: "MEO" },
|
|
152
|
+
{ prn: "C26", phase: "BDS-3", orbit: "MEO" },
|
|
153
|
+
{ prn: "C27", phase: "BDS-3", orbit: "MEO" },
|
|
154
|
+
{ prn: "C28", phase: "BDS-3", orbit: "MEO" },
|
|
155
|
+
{ prn: "C29", phase: "BDS-3", orbit: "MEO" },
|
|
156
|
+
{ prn: "C30", phase: "BDS-3", orbit: "MEO" },
|
|
157
|
+
{ prn: "C32", phase: "BDS-3", orbit: "MEO" },
|
|
158
|
+
{ prn: "C33", phase: "BDS-3", orbit: "MEO" },
|
|
159
|
+
{ prn: "C34", phase: "BDS-3", orbit: "MEO" },
|
|
160
|
+
{ prn: "C35", phase: "BDS-3", orbit: "MEO" },
|
|
161
|
+
{ prn: "C36", phase: "BDS-3", orbit: "MEO" },
|
|
162
|
+
{ prn: "C37", phase: "BDS-3", orbit: "MEO" },
|
|
163
|
+
{ prn: "C41", phase: "BDS-3", orbit: "MEO" },
|
|
164
|
+
{ prn: "C42", phase: "BDS-3", orbit: "MEO" },
|
|
165
|
+
{ prn: "C43", phase: "BDS-3", orbit: "MEO" },
|
|
166
|
+
{ prn: "C44", phase: "BDS-3", orbit: "MEO" },
|
|
167
|
+
{ prn: "C45", phase: "BDS-3", orbit: "MEO" },
|
|
168
|
+
{ prn: "C46", phase: "BDS-3", orbit: "MEO" },
|
|
169
|
+
{ prn: "C38", phase: "BDS-3", orbit: "IGSO" },
|
|
170
|
+
{ prn: "C39", phase: "BDS-3", orbit: "IGSO" },
|
|
171
|
+
{ prn: "C40", phase: "BDS-3", orbit: "IGSO" },
|
|
172
|
+
{ prn: "C59", phase: "BDS-3", orbit: "GEO" },
|
|
173
|
+
{ prn: "C60", phase: "BDS-3", orbit: "GEO" },
|
|
174
|
+
{ prn: "C61", phase: "BDS-3", orbit: "GEO" }
|
|
175
|
+
];
|
|
176
|
+
var ATTR_PRIORITY = {
|
|
177
|
+
X: 8,
|
|
178
|
+
C: 7,
|
|
179
|
+
S: 6,
|
|
180
|
+
L: 6,
|
|
181
|
+
Q: 6,
|
|
182
|
+
I: 5,
|
|
183
|
+
B: 5,
|
|
184
|
+
D: 4,
|
|
185
|
+
Z: 3,
|
|
186
|
+
P: 2,
|
|
187
|
+
W: 1
|
|
188
|
+
};
|
|
189
|
+
function attrRank(code) {
|
|
190
|
+
return ATTR_PRIORITY[code[2] ?? ""] ?? 3;
|
|
191
|
+
}
|
|
192
|
+
function buildObsIndices(header) {
|
|
193
|
+
const result = /* @__PURE__ */ new Map();
|
|
194
|
+
for (const [sys, codes] of Object.entries(header.obsTypes)) {
|
|
195
|
+
if (sys === "_v2") continue;
|
|
196
|
+
const lIdx = /* @__PURE__ */ new Map();
|
|
197
|
+
const lRank = /* @__PURE__ */ new Map();
|
|
198
|
+
const cIdx = /* @__PURE__ */ new Map();
|
|
199
|
+
const cRank = /* @__PURE__ */ new Map();
|
|
200
|
+
for (let i = 0; i < codes.length; i++) {
|
|
201
|
+
const code = codes[i];
|
|
202
|
+
const type = code[0];
|
|
203
|
+
const band = code[1];
|
|
204
|
+
if (!band) continue;
|
|
205
|
+
const rank = attrRank(code);
|
|
206
|
+
if (type === "L" && rank > (lRank.get(band) ?? -1)) {
|
|
207
|
+
lIdx.set(band, i);
|
|
208
|
+
lRank.set(band, rank);
|
|
209
|
+
}
|
|
210
|
+
if ((type === "C" || type === "P") && rank > (cRank.get(band) ?? -1)) {
|
|
211
|
+
cIdx.set(band, i);
|
|
212
|
+
cRank.set(band, rank);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
const bandMap = /* @__PURE__ */ new Map();
|
|
216
|
+
for (const [band, li] of lIdx) {
|
|
217
|
+
bandMap.set(band, { L: li, C: cIdx.get(band) ?? null });
|
|
218
|
+
}
|
|
219
|
+
if (bandMap.size > 0) result.set(sys, bandMap);
|
|
220
|
+
}
|
|
221
|
+
const v2codes = header.obsTypes["_v2"];
|
|
222
|
+
if (v2codes) {
|
|
223
|
+
const lIdx = /* @__PURE__ */ new Map();
|
|
224
|
+
const cIdx = /* @__PURE__ */ new Map();
|
|
225
|
+
for (let i = 0; i < v2codes.length; i++) {
|
|
226
|
+
const code = v2codes[i];
|
|
227
|
+
const type = code[0];
|
|
228
|
+
const band = code[1];
|
|
229
|
+
if (!band) continue;
|
|
230
|
+
if (type === "L" && !lIdx.has(band)) lIdx.set(band, i);
|
|
231
|
+
if ((type === "C" || type === "P") && !cIdx.has(band)) cIdx.set(band, i);
|
|
232
|
+
}
|
|
233
|
+
const bandMap = /* @__PURE__ */ new Map();
|
|
234
|
+
for (const [band, li] of lIdx) {
|
|
235
|
+
bandMap.set(band, { L: li, C: cIdx.get(band) ?? null });
|
|
236
|
+
}
|
|
237
|
+
if (bandMap.size > 0) result.set("_v2", bandMap);
|
|
238
|
+
}
|
|
239
|
+
return result;
|
|
240
|
+
}
|
|
241
|
+
var ARC_GAP_FACTOR = 5;
|
|
242
|
+
var DEFAULT_ELEV_MASK_DEG = 5;
|
|
243
|
+
function formatUTCTime(d) {
|
|
244
|
+
return `${String(d.getUTCHours()).padStart(2, "0")}:${String(d.getUTCMinutes()).padStart(2, "0")}:${String(d.getUTCSeconds()).padStart(2, "0")}`;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
export {
|
|
248
|
+
SYSTEM_NAMES,
|
|
249
|
+
SYS_SHORT,
|
|
250
|
+
C_LIGHT,
|
|
251
|
+
FREQ,
|
|
252
|
+
BAND_LABELS,
|
|
253
|
+
DUAL_FREQ_PAIRS,
|
|
254
|
+
GLO_F1_BASE,
|
|
255
|
+
GLO_F1_STEP,
|
|
256
|
+
GLO_F2_BASE,
|
|
257
|
+
GLO_F2_STEP,
|
|
258
|
+
GLO_F3,
|
|
259
|
+
GLO_CHANNEL_FALLBACK,
|
|
260
|
+
buildGloChannelMap,
|
|
261
|
+
gloFreq,
|
|
262
|
+
getFreq,
|
|
263
|
+
BDS_SATELLITES,
|
|
264
|
+
buildObsIndices,
|
|
265
|
+
ARC_GAP_FACTOR,
|
|
266
|
+
DEFAULT_ELEV_MASK_DEG,
|
|
267
|
+
formatUTCTime
|
|
268
|
+
};
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WGS84_ECCENTRICITY_SQUARED,
|
|
3
|
+
WGS84_FLATTENING,
|
|
4
|
+
WGS84_SEMI_MAJOR_AXIS,
|
|
5
|
+
WGS84_SEMI_MINOR_AXIS
|
|
6
|
+
} from "./chunk-6FAL6P4G.js";
|
|
7
|
+
|
|
8
|
+
// src/coordinates/units.ts
|
|
9
|
+
function rad2deg(radians) {
|
|
10
|
+
return radians * 180 / Math.PI;
|
|
11
|
+
}
|
|
12
|
+
function deg2rad(degrees) {
|
|
13
|
+
return degrees * Math.PI / 180;
|
|
14
|
+
}
|
|
15
|
+
function deg2dms(deg) {
|
|
16
|
+
deg = Math.abs(deg);
|
|
17
|
+
let d = Math.floor(deg);
|
|
18
|
+
let m = Math.floor(deg * 60) % 60;
|
|
19
|
+
let s = deg * 3600 % 60;
|
|
20
|
+
if (s >= 59.9995) {
|
|
21
|
+
m += 1;
|
|
22
|
+
s = 0;
|
|
23
|
+
}
|
|
24
|
+
if (m === 60) {
|
|
25
|
+
d += 1;
|
|
26
|
+
m = 0;
|
|
27
|
+
}
|
|
28
|
+
return [d, m, s];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// src/coordinates/geodesy.ts
|
|
32
|
+
function vincenty(lat1, lon1, lat2, lon2) {
|
|
33
|
+
const U1 = Math.atan((1 - WGS84_FLATTENING) * Math.tan(lat1));
|
|
34
|
+
const U2 = Math.atan((1 - WGS84_FLATTENING) * Math.tan(lat2));
|
|
35
|
+
const sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
|
|
36
|
+
const sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
|
|
37
|
+
let lambda = lon2 - lon1;
|
|
38
|
+
let lambdaPrev;
|
|
39
|
+
let sinSigma, cosSigma, sigma;
|
|
40
|
+
let sinAlpha, cos2Alpha, cos2SigmaM;
|
|
41
|
+
let C;
|
|
42
|
+
let iter = 0;
|
|
43
|
+
do {
|
|
44
|
+
const sinLambda2 = Math.sin(lambda);
|
|
45
|
+
const cosLambda2 = Math.cos(lambda);
|
|
46
|
+
sinSigma = Math.sqrt(
|
|
47
|
+
(cosU2 * sinLambda2) ** 2 + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda2) ** 2
|
|
48
|
+
);
|
|
49
|
+
if (sinSigma === 0) {
|
|
50
|
+
return { distance: 0, initialBearing: 0, finalBearing: 0 };
|
|
51
|
+
}
|
|
52
|
+
cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda2;
|
|
53
|
+
sigma = Math.atan2(sinSigma, cosSigma);
|
|
54
|
+
sinAlpha = cosU1 * cosU2 * sinLambda2 / sinSigma;
|
|
55
|
+
cos2Alpha = 1 - sinAlpha ** 2;
|
|
56
|
+
cos2SigmaM = cos2Alpha !== 0 ? cosSigma - 2 * sinU1 * sinU2 / cos2Alpha : 0;
|
|
57
|
+
C = WGS84_FLATTENING / 16 * cos2Alpha * (4 + WGS84_FLATTENING * (4 - 3 * cos2Alpha));
|
|
58
|
+
lambdaPrev = lambda;
|
|
59
|
+
lambda = lon2 - lon1 + (1 - C) * WGS84_FLATTENING * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM ** 2)));
|
|
60
|
+
} while (Math.abs(lambda - lambdaPrev) > 1e-12 && ++iter < 200);
|
|
61
|
+
if (iter >= 200) {
|
|
62
|
+
const cosLat1 = Math.cos(lat1), sinLat1 = Math.sin(lat1);
|
|
63
|
+
const cosLat2 = Math.cos(lat2), sinLat2 = Math.sin(lat2);
|
|
64
|
+
const dLon = lon2 - lon1;
|
|
65
|
+
sigma = Math.acos(
|
|
66
|
+
Math.min(
|
|
67
|
+
1,
|
|
68
|
+
Math.max(-1, sinLat1 * sinLat2 + cosLat1 * cosLat2 * Math.cos(dLon))
|
|
69
|
+
)
|
|
70
|
+
);
|
|
71
|
+
const distance2 = WGS84_SEMI_MAJOR_AXIS * sigma;
|
|
72
|
+
const ib = Math.atan2(
|
|
73
|
+
cosLat2 * Math.sin(dLon),
|
|
74
|
+
cosLat1 * sinLat2 - sinLat1 * cosLat2 * Math.cos(dLon)
|
|
75
|
+
);
|
|
76
|
+
const fb = Math.atan2(
|
|
77
|
+
cosLat1 * Math.sin(-dLon),
|
|
78
|
+
-sinLat1 * cosLat2 + cosLat1 * sinLat2 * Math.cos(-dLon)
|
|
79
|
+
);
|
|
80
|
+
return { distance: distance2, initialBearing: ib, finalBearing: fb };
|
|
81
|
+
}
|
|
82
|
+
const uSq = cos2Alpha * (WGS84_SEMI_MAJOR_AXIS ** 2 - WGS84_SEMI_MINOR_AXIS ** 2) / WGS84_SEMI_MINOR_AXIS ** 2;
|
|
83
|
+
const A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
|
|
84
|
+
const B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
|
|
85
|
+
const deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM ** 2) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma ** 2) * (-3 + 4 * cos2SigmaM ** 2)));
|
|
86
|
+
const distance = WGS84_SEMI_MINOR_AXIS * A * (sigma - deltaSigma);
|
|
87
|
+
const sinLambda = Math.sin(lambda);
|
|
88
|
+
const cosLambda = Math.cos(lambda);
|
|
89
|
+
const initialBearing = Math.atan2(
|
|
90
|
+
cosU2 * sinLambda,
|
|
91
|
+
cosU1 * sinU2 - sinU1 * cosU2 * cosLambda
|
|
92
|
+
);
|
|
93
|
+
const finalBearing = Math.atan2(
|
|
94
|
+
cosU1 * sinLambda,
|
|
95
|
+
-sinU1 * cosU2 + cosU1 * sinU2 * cosLambda
|
|
96
|
+
);
|
|
97
|
+
return { distance, initialBearing, finalBearing };
|
|
98
|
+
}
|
|
99
|
+
function rhumbLine(lat1, lon1, lat2, lon2) {
|
|
100
|
+
const dLat = lat2 - lat1;
|
|
101
|
+
let dLon = lon2 - lon1;
|
|
102
|
+
const MAX_LAT = Math.PI / 2 - 1e-10;
|
|
103
|
+
const isometricLat = (lat) => {
|
|
104
|
+
const clampedLat = Math.max(-MAX_LAT, Math.min(MAX_LAT, lat));
|
|
105
|
+
const sinLat = Math.sin(clampedLat);
|
|
106
|
+
const e = Math.sqrt(WGS84_ECCENTRICITY_SQUARED);
|
|
107
|
+
return Math.log(
|
|
108
|
+
Math.tan(Math.PI / 4 + clampedLat / 2) * ((1 - e * sinLat) / (1 + e * sinLat)) ** (e / 2)
|
|
109
|
+
);
|
|
110
|
+
};
|
|
111
|
+
const psi1 = isometricLat(lat1);
|
|
112
|
+
const psi2 = isometricLat(lat2);
|
|
113
|
+
const dPsi = psi2 - psi1;
|
|
114
|
+
const q = Math.abs(dPsi) > 1e-12 ? dLat / dPsi : Math.cos(lat1);
|
|
115
|
+
if (Math.abs(dLon) > Math.PI) {
|
|
116
|
+
dLon = dLon > 0 ? -(2 * Math.PI - dLon) : 2 * Math.PI + dLon;
|
|
117
|
+
}
|
|
118
|
+
const bearing = Math.atan2(dLon, dPsi);
|
|
119
|
+
const e22 = WGS84_ECCENTRICITY_SQUARED;
|
|
120
|
+
const e4 = e22 * e22;
|
|
121
|
+
const e6 = e4 * e22;
|
|
122
|
+
const meridionalRadius = WGS84_SEMI_MAJOR_AXIS * (1 - e22) * (1 + 3 / 4 * e22 + 45 / 64 * e4 + 175 / 256 * e6);
|
|
123
|
+
const distance = Math.sqrt(dLat ** 2 + q ** 2 * dLon ** 2) * meridionalRadius;
|
|
124
|
+
return { distance, bearing };
|
|
125
|
+
}
|
|
126
|
+
function euclidean3D(x1, y1, z1, x2, y2, z2) {
|
|
127
|
+
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2 + (z2 - z1) ** 2);
|
|
128
|
+
}
|
|
129
|
+
function greatCircleMidpoint(lat1, lon1, lat2, lon2) {
|
|
130
|
+
const dLon = lon2 - lon1;
|
|
131
|
+
const Bx = Math.cos(lat2) * Math.cos(dLon);
|
|
132
|
+
const By = Math.cos(lat2) * Math.sin(dLon);
|
|
133
|
+
const sumX = Math.cos(lat1) + Bx;
|
|
134
|
+
const denom = Math.sqrt(sumX ** 2 + By ** 2);
|
|
135
|
+
if (denom < 1e-15) {
|
|
136
|
+
return [(lat1 + lat2) / 2, lon1];
|
|
137
|
+
}
|
|
138
|
+
const latMid = Math.atan2(Math.sin(lat1) + Math.sin(lat2), denom);
|
|
139
|
+
const lonMid = lon1 + Math.atan2(By, sumX);
|
|
140
|
+
return [latMid, lonMid];
|
|
141
|
+
}
|
|
142
|
+
function horizonDistance(heightMeters) {
|
|
143
|
+
if (heightMeters <= 0) return 0;
|
|
144
|
+
const k = 0.13;
|
|
145
|
+
const R = WGS84_SEMI_MAJOR_AXIS;
|
|
146
|
+
const Re = R / (1 - k);
|
|
147
|
+
return Math.sqrt(2 * Re * heightMeters + heightMeters ** 2);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// src/coordinates/projections.ts
|
|
151
|
+
var e2 = WGS84_ECCENTRICITY_SQUARED;
|
|
152
|
+
var k0 = 0.9996;
|
|
153
|
+
function geodeticToUtm(lat, lon) {
|
|
154
|
+
const MAX_UTM_LAT = 84 * (Math.PI / 180);
|
|
155
|
+
lat = Math.max(-MAX_UTM_LAT, Math.min(MAX_UTM_LAT, lat));
|
|
156
|
+
const latDeg = lat * 180 / Math.PI;
|
|
157
|
+
const lonDeg = lon * 180 / Math.PI;
|
|
158
|
+
const zone = Math.floor((lonDeg + 180) / 6) + 1;
|
|
159
|
+
const lon0 = ((zone - 1) * 6 - 180 + 3) * (Math.PI / 180);
|
|
160
|
+
const ep2 = e2 / (1 - e2);
|
|
161
|
+
const N = WGS84_SEMI_MAJOR_AXIS / Math.sqrt(1 - e2 * Math.sin(lat) ** 2);
|
|
162
|
+
const T = Math.tan(lat) ** 2;
|
|
163
|
+
const C = ep2 * Math.cos(lat) ** 2;
|
|
164
|
+
const A = Math.cos(lat) * (lon - lon0);
|
|
165
|
+
const M = WGS84_SEMI_MAJOR_AXIS * ((1 - e2 / 4 - 3 * e2 ** 2 / 64 - 5 * e2 ** 3 / 256) * lat - (3 * e2 / 8 + 3 * e2 ** 2 / 32 + 45 * e2 ** 3 / 1024) * Math.sin(2 * lat) + (15 * e2 ** 2 / 256 + 45 * e2 ** 3 / 1024) * Math.sin(4 * lat) - 35 * e2 ** 3 / 3072 * Math.sin(6 * lat));
|
|
166
|
+
const easting = k0 * N * (A + (1 - T + C) * A ** 3 / 6 + (5 - 18 * T + T ** 2 + 72 * C - 58 * ep2) * A ** 5 / 120) + 5e5;
|
|
167
|
+
let northing = k0 * (M + N * Math.tan(lat) * (A ** 2 / 2 + (5 - T + 9 * C + 4 * C ** 2) * A ** 4 / 24 + (61 - 58 * T + T ** 2 + 600 * C - 330 * ep2) * A ** 6 / 720));
|
|
168
|
+
const hemisphere = latDeg >= 0 ? "N" : "S";
|
|
169
|
+
if (hemisphere === "S") {
|
|
170
|
+
northing += 1e7;
|
|
171
|
+
}
|
|
172
|
+
return { easting, northing, zone, hemisphere };
|
|
173
|
+
}
|
|
174
|
+
function geodeticToMaidenhead(lat, lon) {
|
|
175
|
+
const latDeg = Math.max(0, Math.min(179.999999, lat * 180 / Math.PI + 90));
|
|
176
|
+
const lonDeg = Math.max(0, Math.min(359.999999, lon * 180 / Math.PI + 180));
|
|
177
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWX";
|
|
178
|
+
const idx = (i) => Math.max(0, Math.min(23, i));
|
|
179
|
+
const a1 = chars[idx(Math.floor(lonDeg / 20))];
|
|
180
|
+
const a2 = chars[idx(Math.floor(latDeg / 10))];
|
|
181
|
+
const a3 = Math.floor(lonDeg % 20 / 2);
|
|
182
|
+
const a4 = Math.floor(latDeg % 10);
|
|
183
|
+
const a5 = chars[idx(Math.floor(lonDeg % 2 * 12))];
|
|
184
|
+
const a6 = chars[idx(Math.floor(latDeg % 1 * 24))];
|
|
185
|
+
return `${a1}${a2}${a3}${a4}${a5.toLowerCase()}${a6.toLowerCase()}`;
|
|
186
|
+
}
|
|
187
|
+
function geodeticToGeohash(lat, lon, precision = 8) {
|
|
188
|
+
const latDeg = lat * 180 / Math.PI;
|
|
189
|
+
const lonDeg = lon * 180 / Math.PI;
|
|
190
|
+
const base32 = "0123456789bcdefghjkmnpqrstuvwxyz";
|
|
191
|
+
let minLat = -90, maxLat = 90;
|
|
192
|
+
let minLon = -180, maxLon = 180;
|
|
193
|
+
let hash = "";
|
|
194
|
+
let bit = 0;
|
|
195
|
+
let ch = 0;
|
|
196
|
+
let isLon = true;
|
|
197
|
+
while (hash.length < precision) {
|
|
198
|
+
if (isLon) {
|
|
199
|
+
const mid = (minLon + maxLon) / 2;
|
|
200
|
+
if (lonDeg >= mid) {
|
|
201
|
+
ch = ch | 1 << 4 - bit;
|
|
202
|
+
minLon = mid;
|
|
203
|
+
} else {
|
|
204
|
+
maxLon = mid;
|
|
205
|
+
}
|
|
206
|
+
} else {
|
|
207
|
+
const mid = (minLat + maxLat) / 2;
|
|
208
|
+
if (latDeg >= mid) {
|
|
209
|
+
ch = ch | 1 << 4 - bit;
|
|
210
|
+
minLat = mid;
|
|
211
|
+
} else {
|
|
212
|
+
maxLat = mid;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
isLon = !isLon;
|
|
216
|
+
if (bit < 4) {
|
|
217
|
+
bit++;
|
|
218
|
+
} else {
|
|
219
|
+
hash += base32[ch];
|
|
220
|
+
bit = 0;
|
|
221
|
+
ch = 0;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return hash;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
export {
|
|
228
|
+
rad2deg,
|
|
229
|
+
deg2rad,
|
|
230
|
+
deg2dms,
|
|
231
|
+
vincenty,
|
|
232
|
+
rhumbLine,
|
|
233
|
+
euclidean3D,
|
|
234
|
+
greatCircleMidpoint,
|
|
235
|
+
horizonDistance,
|
|
236
|
+
geodeticToUtm,
|
|
237
|
+
geodeticToMaidenhead,
|
|
238
|
+
geodeticToGeohash
|
|
239
|
+
};
|