gnss-js 0.1.2 → 1.0.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/LICENSE +23 -0
- package/README.md +171 -5
- package/dist/analysis.cjs +1381 -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-354IRDOG.js +239 -0
- package/dist/chunk-37QNKGTC.js +65 -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-CB6EOOLA.js +753 -0
- package/dist/chunk-HKN3PUGN.js +800 -0
- package/dist/chunk-IS4UUDBV.js +577 -0
- package/dist/chunk-K7WZQFBV.js +236 -0
- package/dist/chunk-LEEU5OIO.js +75 -0
- package/dist/chunk-PRSZIWKM.js +1482 -0
- package/dist/chunk-SDRRAJT5.js +433 -0
- package/dist/chunk-WR7LCB52.js +143 -0
- package/dist/chunk-Y3R57B5P.js +473 -0
- package/dist/chunk-YDMYO3YK.js +220 -0
- package/dist/constants.cjs +394 -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 +334 -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-BUWzfmBy.d.cts +114 -0
- package/dist/ephemeris-BUWzfmBy.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 +5774 -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 +169 -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 +504 -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 +1375 -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 +1519 -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,334 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/coordinates/index.ts
|
|
21
|
+
var coordinates_exports = {};
|
|
22
|
+
__export(coordinates_exports, {
|
|
23
|
+
clampUnit: () => clampUnit,
|
|
24
|
+
deg2dms: () => deg2dms,
|
|
25
|
+
deg2rad: () => deg2rad,
|
|
26
|
+
ecefToGeodetic: () => ecefToGeodetic,
|
|
27
|
+
euclidean3D: () => euclidean3D,
|
|
28
|
+
geodeticToEcef: () => geodeticToEcef,
|
|
29
|
+
geodeticToGeohash: () => geodeticToGeohash,
|
|
30
|
+
geodeticToMaidenhead: () => geodeticToMaidenhead,
|
|
31
|
+
geodeticToUtm: () => geodeticToUtm,
|
|
32
|
+
getAer: () => getAer,
|
|
33
|
+
getEnuDifference: () => getEnuDifference,
|
|
34
|
+
greatCircleMidpoint: () => greatCircleMidpoint,
|
|
35
|
+
horizonDistance: () => horizonDistance,
|
|
36
|
+
rad2deg: () => rad2deg,
|
|
37
|
+
rhumbLine: () => rhumbLine,
|
|
38
|
+
vincenty: () => vincenty
|
|
39
|
+
});
|
|
40
|
+
module.exports = __toCommonJS(coordinates_exports);
|
|
41
|
+
|
|
42
|
+
// src/coordinates/units.ts
|
|
43
|
+
function rad2deg(radians) {
|
|
44
|
+
return radians * 180 / Math.PI;
|
|
45
|
+
}
|
|
46
|
+
function deg2rad(degrees) {
|
|
47
|
+
return degrees * Math.PI / 180;
|
|
48
|
+
}
|
|
49
|
+
function deg2dms(deg) {
|
|
50
|
+
deg = Math.abs(deg);
|
|
51
|
+
let d = Math.floor(deg);
|
|
52
|
+
let m = Math.floor(deg * 60) % 60;
|
|
53
|
+
let s = deg * 3600 % 60;
|
|
54
|
+
if (s >= 59.9995) {
|
|
55
|
+
m += 1;
|
|
56
|
+
s = 0;
|
|
57
|
+
}
|
|
58
|
+
if (m === 60) {
|
|
59
|
+
d += 1;
|
|
60
|
+
m = 0;
|
|
61
|
+
}
|
|
62
|
+
return [d, m, s];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// src/constants/wgs84.ts
|
|
66
|
+
var WGS84_SEMI_MAJOR_AXIS = 6378137;
|
|
67
|
+
var WGS84_SEMI_MINOR_AXIS = 6356752314245e-6;
|
|
68
|
+
var WGS84_FLATTENING = 1 / 298.257223563;
|
|
69
|
+
var WGS84_ECCENTRICITY_SQUARED = 0.006694379990197;
|
|
70
|
+
|
|
71
|
+
// src/coordinates/ecef.ts
|
|
72
|
+
function clampUnit(x) {
|
|
73
|
+
return x < -1 ? -1 : x > 1 ? 1 : x;
|
|
74
|
+
}
|
|
75
|
+
function geodeticToEcef(lat, lon, h) {
|
|
76
|
+
const N = WGS84_SEMI_MAJOR_AXIS / Math.sqrt(1 - WGS84_ECCENTRICITY_SQUARED * Math.sin(lat) ** 2);
|
|
77
|
+
const x = (N + h) * Math.cos(lat) * Math.cos(lon);
|
|
78
|
+
const y = (N + h) * Math.cos(lat) * Math.sin(lon);
|
|
79
|
+
const z = ((1 - WGS84_ECCENTRICITY_SQUARED) * N + h) * Math.sin(lat);
|
|
80
|
+
return [x, y, z];
|
|
81
|
+
}
|
|
82
|
+
function ecefToGeodetic(x, y, z) {
|
|
83
|
+
const lon = Math.atan2(y, x);
|
|
84
|
+
const p = Math.sqrt(x * x + y * y);
|
|
85
|
+
if (p < 1e-10) {
|
|
86
|
+
const b = WGS84_SEMI_MAJOR_AXIS * Math.sqrt(1 - WGS84_ECCENTRICITY_SQUARED);
|
|
87
|
+
const lat2 = z >= 0 ? Math.PI / 2 : -Math.PI / 2;
|
|
88
|
+
const alt2 = Math.abs(z) - b;
|
|
89
|
+
return [lat2, lon, alt2];
|
|
90
|
+
}
|
|
91
|
+
let lat = Math.atan2(z, p * (1 - WGS84_ECCENTRICITY_SQUARED));
|
|
92
|
+
let N;
|
|
93
|
+
for (let i = 0; i < 10; i++) {
|
|
94
|
+
const sinLat2 = Math.sin(lat);
|
|
95
|
+
N = WGS84_SEMI_MAJOR_AXIS / Math.sqrt(1 - WGS84_ECCENTRICITY_SQUARED * sinLat2 * sinLat2);
|
|
96
|
+
const prevLat = lat;
|
|
97
|
+
lat = Math.atan2(z + WGS84_ECCENTRICITY_SQUARED * N * sinLat2, p);
|
|
98
|
+
if (Math.abs(lat - prevLat) < 1e-15) break;
|
|
99
|
+
}
|
|
100
|
+
const sinLat = Math.sin(lat);
|
|
101
|
+
N = WGS84_SEMI_MAJOR_AXIS / Math.sqrt(1 - WGS84_ECCENTRICITY_SQUARED * sinLat * sinLat);
|
|
102
|
+
const alt = p / Math.cos(lat) - N;
|
|
103
|
+
return [lat, lon, alt];
|
|
104
|
+
}
|
|
105
|
+
function getEnuDifference(x, y, z, xRef, yRef, zRef) {
|
|
106
|
+
const [latRef, lonRef] = ecefToGeodetic(xRef, yRef, zRef);
|
|
107
|
+
const deltaX = x - xRef;
|
|
108
|
+
const deltaY = y - yRef;
|
|
109
|
+
const deltaZ = z - zRef;
|
|
110
|
+
const deltaE = -Math.sin(lonRef) * deltaX + Math.cos(lonRef) * deltaY;
|
|
111
|
+
const deltaN = -Math.cos(lonRef) * Math.sin(latRef) * deltaX - Math.sin(lonRef) * Math.sin(latRef) * deltaY + Math.cos(latRef) * deltaZ;
|
|
112
|
+
const deltaU = Math.cos(lonRef) * Math.cos(latRef) * deltaX + Math.sin(lonRef) * Math.cos(latRef) * deltaY + Math.sin(latRef) * deltaZ;
|
|
113
|
+
return [deltaE, deltaN, deltaU];
|
|
114
|
+
}
|
|
115
|
+
function getAer(x, y, z, xRef, yRef, zRef) {
|
|
116
|
+
const slant = Math.sqrt((x - xRef) ** 2 + (y - yRef) ** 2 + (z - zRef) ** 2);
|
|
117
|
+
if (!slant) return [0, 0, 0];
|
|
118
|
+
const [deltaE, deltaN, deltaU] = getEnuDifference(x, y, z, xRef, yRef, zRef);
|
|
119
|
+
const elevation = Math.asin(clampUnit(deltaU / slant));
|
|
120
|
+
const azimuth = Math.atan2(deltaE, deltaN);
|
|
121
|
+
return [elevation, azimuth, slant];
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// src/coordinates/geodesy.ts
|
|
125
|
+
function vincenty(lat1, lon1, lat2, lon2) {
|
|
126
|
+
const U1 = Math.atan((1 - WGS84_FLATTENING) * Math.tan(lat1));
|
|
127
|
+
const U2 = Math.atan((1 - WGS84_FLATTENING) * Math.tan(lat2));
|
|
128
|
+
const sinU1 = Math.sin(U1), cosU1 = Math.cos(U1);
|
|
129
|
+
const sinU2 = Math.sin(U2), cosU2 = Math.cos(U2);
|
|
130
|
+
let lambda = lon2 - lon1;
|
|
131
|
+
let lambdaPrev;
|
|
132
|
+
let sinSigma, cosSigma, sigma;
|
|
133
|
+
let sinAlpha, cos2Alpha, cos2SigmaM;
|
|
134
|
+
let C;
|
|
135
|
+
let iter = 0;
|
|
136
|
+
do {
|
|
137
|
+
const sinLambda2 = Math.sin(lambda);
|
|
138
|
+
const cosLambda2 = Math.cos(lambda);
|
|
139
|
+
sinSigma = Math.sqrt(
|
|
140
|
+
(cosU2 * sinLambda2) ** 2 + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda2) ** 2
|
|
141
|
+
);
|
|
142
|
+
if (sinSigma === 0) {
|
|
143
|
+
return { distance: 0, initialBearing: 0, finalBearing: 0 };
|
|
144
|
+
}
|
|
145
|
+
cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda2;
|
|
146
|
+
sigma = Math.atan2(sinSigma, cosSigma);
|
|
147
|
+
sinAlpha = cosU1 * cosU2 * sinLambda2 / sinSigma;
|
|
148
|
+
cos2Alpha = 1 - sinAlpha ** 2;
|
|
149
|
+
cos2SigmaM = cos2Alpha !== 0 ? cosSigma - 2 * sinU1 * sinU2 / cos2Alpha : 0;
|
|
150
|
+
C = WGS84_FLATTENING / 16 * cos2Alpha * (4 + WGS84_FLATTENING * (4 - 3 * cos2Alpha));
|
|
151
|
+
lambdaPrev = lambda;
|
|
152
|
+
lambda = lon2 - lon1 + (1 - C) * WGS84_FLATTENING * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM ** 2)));
|
|
153
|
+
} while (Math.abs(lambda - lambdaPrev) > 1e-12 && ++iter < 200);
|
|
154
|
+
if (iter >= 200) {
|
|
155
|
+
const cosLat1 = Math.cos(lat1), sinLat1 = Math.sin(lat1);
|
|
156
|
+
const cosLat2 = Math.cos(lat2), sinLat2 = Math.sin(lat2);
|
|
157
|
+
const dLon = lon2 - lon1;
|
|
158
|
+
sigma = Math.acos(
|
|
159
|
+
Math.min(1, Math.max(-1, sinLat1 * sinLat2 + cosLat1 * cosLat2 * Math.cos(dLon)))
|
|
160
|
+
);
|
|
161
|
+
const distance2 = WGS84_SEMI_MAJOR_AXIS * sigma;
|
|
162
|
+
const ib = Math.atan2(
|
|
163
|
+
cosLat2 * Math.sin(dLon),
|
|
164
|
+
cosLat1 * sinLat2 - sinLat1 * cosLat2 * Math.cos(dLon)
|
|
165
|
+
);
|
|
166
|
+
const fb = Math.atan2(
|
|
167
|
+
cosLat1 * Math.sin(-dLon),
|
|
168
|
+
-sinLat1 * cosLat2 + cosLat1 * sinLat2 * Math.cos(-dLon)
|
|
169
|
+
);
|
|
170
|
+
return { distance: distance2, initialBearing: ib, finalBearing: fb };
|
|
171
|
+
}
|
|
172
|
+
const uSq = cos2Alpha * (WGS84_SEMI_MAJOR_AXIS ** 2 - WGS84_SEMI_MINOR_AXIS ** 2) / WGS84_SEMI_MINOR_AXIS ** 2;
|
|
173
|
+
const A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq)));
|
|
174
|
+
const B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq)));
|
|
175
|
+
const deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM ** 2) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma ** 2) * (-3 + 4 * cos2SigmaM ** 2)));
|
|
176
|
+
const distance = WGS84_SEMI_MINOR_AXIS * A * (sigma - deltaSigma);
|
|
177
|
+
const sinLambda = Math.sin(lambda);
|
|
178
|
+
const cosLambda = Math.cos(lambda);
|
|
179
|
+
const initialBearing = Math.atan2(
|
|
180
|
+
cosU2 * sinLambda,
|
|
181
|
+
cosU1 * sinU2 - sinU1 * cosU2 * cosLambda
|
|
182
|
+
);
|
|
183
|
+
const finalBearing = Math.atan2(
|
|
184
|
+
cosU1 * sinLambda,
|
|
185
|
+
-sinU1 * cosU2 + cosU1 * sinU2 * cosLambda
|
|
186
|
+
);
|
|
187
|
+
return { distance, initialBearing, finalBearing };
|
|
188
|
+
}
|
|
189
|
+
function rhumbLine(lat1, lon1, lat2, lon2) {
|
|
190
|
+
const dLat = lat2 - lat1;
|
|
191
|
+
let dLon = lon2 - lon1;
|
|
192
|
+
const MAX_LAT = Math.PI / 2 - 1e-10;
|
|
193
|
+
const isometricLat = (lat) => {
|
|
194
|
+
const clampedLat = Math.max(-MAX_LAT, Math.min(MAX_LAT, lat));
|
|
195
|
+
const sinLat = Math.sin(clampedLat);
|
|
196
|
+
const e = Math.sqrt(WGS84_ECCENTRICITY_SQUARED);
|
|
197
|
+
return Math.log(
|
|
198
|
+
Math.tan(Math.PI / 4 + clampedLat / 2) * ((1 - e * sinLat) / (1 + e * sinLat)) ** (e / 2)
|
|
199
|
+
);
|
|
200
|
+
};
|
|
201
|
+
const psi1 = isometricLat(lat1);
|
|
202
|
+
const psi2 = isometricLat(lat2);
|
|
203
|
+
const dPsi = psi2 - psi1;
|
|
204
|
+
const q = Math.abs(dPsi) > 1e-12 ? dLat / dPsi : Math.cos(lat1);
|
|
205
|
+
if (Math.abs(dLon) > Math.PI) {
|
|
206
|
+
dLon = dLon > 0 ? -(2 * Math.PI - dLon) : 2 * Math.PI + dLon;
|
|
207
|
+
}
|
|
208
|
+
const bearing = Math.atan2(dLon, dPsi);
|
|
209
|
+
const e22 = WGS84_ECCENTRICITY_SQUARED;
|
|
210
|
+
const e4 = e22 * e22;
|
|
211
|
+
const e6 = e4 * e22;
|
|
212
|
+
const meridionalRadius = WGS84_SEMI_MAJOR_AXIS * (1 - e22) * (1 + 3 / 4 * e22 + 45 / 64 * e4 + 175 / 256 * e6);
|
|
213
|
+
const distance = Math.sqrt(dLat ** 2 + q ** 2 * dLon ** 2) * meridionalRadius;
|
|
214
|
+
return { distance, bearing };
|
|
215
|
+
}
|
|
216
|
+
function euclidean3D(x1, y1, z1, x2, y2, z2) {
|
|
217
|
+
return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2 + (z2 - z1) ** 2);
|
|
218
|
+
}
|
|
219
|
+
function greatCircleMidpoint(lat1, lon1, lat2, lon2) {
|
|
220
|
+
const dLon = lon2 - lon1;
|
|
221
|
+
const Bx = Math.cos(lat2) * Math.cos(dLon);
|
|
222
|
+
const By = Math.cos(lat2) * Math.sin(dLon);
|
|
223
|
+
const sumX = Math.cos(lat1) + Bx;
|
|
224
|
+
const denom = Math.sqrt(sumX ** 2 + By ** 2);
|
|
225
|
+
if (denom < 1e-15) {
|
|
226
|
+
return [(lat1 + lat2) / 2, lon1];
|
|
227
|
+
}
|
|
228
|
+
const latMid = Math.atan2(Math.sin(lat1) + Math.sin(lat2), denom);
|
|
229
|
+
const lonMid = lon1 + Math.atan2(By, sumX);
|
|
230
|
+
return [latMid, lonMid];
|
|
231
|
+
}
|
|
232
|
+
function horizonDistance(heightMeters) {
|
|
233
|
+
if (heightMeters <= 0) return 0;
|
|
234
|
+
const k = 0.13;
|
|
235
|
+
const R = WGS84_SEMI_MAJOR_AXIS;
|
|
236
|
+
const Re = R / (1 - k);
|
|
237
|
+
return Math.sqrt(2 * Re * heightMeters + heightMeters ** 2);
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
// src/coordinates/projections.ts
|
|
241
|
+
var e2 = WGS84_ECCENTRICITY_SQUARED;
|
|
242
|
+
var k0 = 0.9996;
|
|
243
|
+
function geodeticToUtm(lat, lon) {
|
|
244
|
+
const MAX_UTM_LAT = 84 * (Math.PI / 180);
|
|
245
|
+
lat = Math.max(-MAX_UTM_LAT, Math.min(MAX_UTM_LAT, lat));
|
|
246
|
+
const latDeg = lat * 180 / Math.PI;
|
|
247
|
+
const lonDeg = lon * 180 / Math.PI;
|
|
248
|
+
const zone = Math.floor((lonDeg + 180) / 6) + 1;
|
|
249
|
+
const lon0 = ((zone - 1) * 6 - 180 + 3) * (Math.PI / 180);
|
|
250
|
+
const ep2 = e2 / (1 - e2);
|
|
251
|
+
const N = WGS84_SEMI_MAJOR_AXIS / Math.sqrt(1 - e2 * Math.sin(lat) ** 2);
|
|
252
|
+
const T = Math.tan(lat) ** 2;
|
|
253
|
+
const C = ep2 * Math.cos(lat) ** 2;
|
|
254
|
+
const A = Math.cos(lat) * (lon - lon0);
|
|
255
|
+
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));
|
|
256
|
+
const easting = k0 * N * (A + (1 - T + C) * A ** 3 / 6 + (5 - 18 * T + T ** 2 + 72 * C - 58 * ep2) * A ** 5 / 120) + 5e5;
|
|
257
|
+
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));
|
|
258
|
+
const hemisphere = latDeg >= 0 ? "N" : "S";
|
|
259
|
+
if (hemisphere === "S") {
|
|
260
|
+
northing += 1e7;
|
|
261
|
+
}
|
|
262
|
+
return { easting, northing, zone, hemisphere };
|
|
263
|
+
}
|
|
264
|
+
function geodeticToMaidenhead(lat, lon) {
|
|
265
|
+
const latDeg = Math.max(0, Math.min(179.999999, lat * 180 / Math.PI + 90));
|
|
266
|
+
const lonDeg = Math.max(0, Math.min(359.999999, lon * 180 / Math.PI + 180));
|
|
267
|
+
const chars = "ABCDEFGHIJKLMNOPQRSTUVWX";
|
|
268
|
+
const idx = (i) => Math.max(0, Math.min(23, i));
|
|
269
|
+
const a1 = chars[idx(Math.floor(lonDeg / 20))];
|
|
270
|
+
const a2 = chars[idx(Math.floor(latDeg / 10))];
|
|
271
|
+
const a3 = Math.floor(lonDeg % 20 / 2);
|
|
272
|
+
const a4 = Math.floor(latDeg % 10);
|
|
273
|
+
const a5 = chars[idx(Math.floor(lonDeg % 2 * 12))];
|
|
274
|
+
const a6 = chars[idx(Math.floor(latDeg % 1 * 24))];
|
|
275
|
+
return `${a1}${a2}${a3}${a4}${a5.toLowerCase()}${a6.toLowerCase()}`;
|
|
276
|
+
}
|
|
277
|
+
function geodeticToGeohash(lat, lon, precision = 8) {
|
|
278
|
+
const latDeg = lat * 180 / Math.PI;
|
|
279
|
+
const lonDeg = lon * 180 / Math.PI;
|
|
280
|
+
const base32 = "0123456789bcdefghjkmnpqrstuvwxyz";
|
|
281
|
+
let minLat = -90, maxLat = 90;
|
|
282
|
+
let minLon = -180, maxLon = 180;
|
|
283
|
+
let hash = "";
|
|
284
|
+
let bit = 0;
|
|
285
|
+
let ch = 0;
|
|
286
|
+
let isLon = true;
|
|
287
|
+
while (hash.length < precision) {
|
|
288
|
+
if (isLon) {
|
|
289
|
+
const mid = (minLon + maxLon) / 2;
|
|
290
|
+
if (lonDeg >= mid) {
|
|
291
|
+
ch = ch | 1 << 4 - bit;
|
|
292
|
+
minLon = mid;
|
|
293
|
+
} else {
|
|
294
|
+
maxLon = mid;
|
|
295
|
+
}
|
|
296
|
+
} else {
|
|
297
|
+
const mid = (minLat + maxLat) / 2;
|
|
298
|
+
if (latDeg >= mid) {
|
|
299
|
+
ch = ch | 1 << 4 - bit;
|
|
300
|
+
minLat = mid;
|
|
301
|
+
} else {
|
|
302
|
+
maxLat = mid;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
isLon = !isLon;
|
|
306
|
+
if (bit < 4) {
|
|
307
|
+
bit++;
|
|
308
|
+
} else {
|
|
309
|
+
hash += base32[ch];
|
|
310
|
+
bit = 0;
|
|
311
|
+
ch = 0;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return hash;
|
|
315
|
+
}
|
|
316
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
317
|
+
0 && (module.exports = {
|
|
318
|
+
clampUnit,
|
|
319
|
+
deg2dms,
|
|
320
|
+
deg2rad,
|
|
321
|
+
ecefToGeodetic,
|
|
322
|
+
euclidean3D,
|
|
323
|
+
geodeticToEcef,
|
|
324
|
+
geodeticToGeohash,
|
|
325
|
+
geodeticToMaidenhead,
|
|
326
|
+
geodeticToUtm,
|
|
327
|
+
getAer,
|
|
328
|
+
getEnuDifference,
|
|
329
|
+
greatCircleMidpoint,
|
|
330
|
+
horizonDistance,
|
|
331
|
+
rad2deg,
|
|
332
|
+
rhumbLine,
|
|
333
|
+
vincenty
|
|
334
|
+
});
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export { c as clampUnit, e as ecefToGeodetic, g as geodeticToEcef, a as getAer, b as getEnuDifference } from './ecef-CF0uAysr.cjs';
|
|
2
|
+
|
|
3
|
+
/** Convert radians to degrees. */
|
|
4
|
+
declare function rad2deg(radians: number): number;
|
|
5
|
+
/** Convert degrees to radians. */
|
|
6
|
+
declare function deg2rad(degrees: number): number;
|
|
7
|
+
/**
|
|
8
|
+
* Convert decimal degrees to [degrees, minutes, seconds].
|
|
9
|
+
* Always returns positive values (use the sign of the input separately).
|
|
10
|
+
*/
|
|
11
|
+
declare function deg2dms(deg: number): [number, number, number];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Vincenty's inverse formula — orthodromic (great-circle) distance,
|
|
15
|
+
* initial bearing, and final bearing on the WGS84 ellipsoid.
|
|
16
|
+
* All angles in radians.
|
|
17
|
+
* @returns { distance (m), initialBearing (rad), finalBearing (rad) }
|
|
18
|
+
*/
|
|
19
|
+
declare function vincenty(lat1: number, lon1: number, lat2: number, lon2: number): {
|
|
20
|
+
distance: number;
|
|
21
|
+
initialBearing: number;
|
|
22
|
+
finalBearing: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Loxodromic (rhumb line) distance and constant bearing on the WGS84 ellipsoid.
|
|
26
|
+
* Uses the ellipsoidal rhumb-line formula with isometric latitudes.
|
|
27
|
+
* All angles in radians.
|
|
28
|
+
* @param lat1 Start latitude (rad)
|
|
29
|
+
* @param lon1 Start longitude (rad)
|
|
30
|
+
* @param lat2 End latitude (rad)
|
|
31
|
+
* @param lon2 End longitude (rad)
|
|
32
|
+
* @returns {distance: meters, bearing: radians}
|
|
33
|
+
*/
|
|
34
|
+
declare function rhumbLine(lat1: number, lon1: number, lat2: number, lon2: number): {
|
|
35
|
+
distance: number;
|
|
36
|
+
bearing: number;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* 3D Euclidean (straight-line, through-the-earth) distance between two ECEF positions.
|
|
40
|
+
* @returns Distance in meters
|
|
41
|
+
*/
|
|
42
|
+
declare function euclidean3D(x1: number, y1: number, z1: number, x2: number, y2: number, z2: number): number;
|
|
43
|
+
/**
|
|
44
|
+
* Geodetic midpoint along the great-circle arc.
|
|
45
|
+
* @returns [lat, lon] in radians
|
|
46
|
+
*/
|
|
47
|
+
declare function greatCircleMidpoint(lat1: number, lon1: number, lat2: number, lon2: number): [number, number];
|
|
48
|
+
/**
|
|
49
|
+
* Geometric horizon distance from a given height above the ellipsoid.
|
|
50
|
+
* Uses the simple geometric formula with refraction coefficient k = 0.13 (standard atmosphere).
|
|
51
|
+
* @param heightMeters Height above ellipsoid in meters
|
|
52
|
+
* @returns Distance in meters
|
|
53
|
+
*/
|
|
54
|
+
declare function horizonDistance(heightMeters: number): number;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Convert geodetic coordinates to UTM.
|
|
58
|
+
* @param lat Latitude in radians
|
|
59
|
+
* @param lon Longitude in radians
|
|
60
|
+
*/
|
|
61
|
+
declare function geodeticToUtm(lat: number, lon: number): {
|
|
62
|
+
easting: number;
|
|
63
|
+
northing: number;
|
|
64
|
+
zone: number;
|
|
65
|
+
hemisphere: 'N' | 'S';
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Maidenhead grid locator (6 characters) from geodetic coordinates.
|
|
69
|
+
* @param lat Latitude in radians
|
|
70
|
+
* @param lon Longitude in radians
|
|
71
|
+
*/
|
|
72
|
+
declare function geodeticToMaidenhead(lat: number, lon: number): string;
|
|
73
|
+
/**
|
|
74
|
+
* Geohash encoding from geodetic coordinates.
|
|
75
|
+
* @param lat Latitude in radians
|
|
76
|
+
* @param lon Longitude in radians
|
|
77
|
+
* @param precision Number of characters (default 8)
|
|
78
|
+
*/
|
|
79
|
+
declare function geodeticToGeohash(lat: number, lon: number, precision?: number): string;
|
|
80
|
+
|
|
81
|
+
export { deg2dms, deg2rad, euclidean3D, geodeticToGeohash, geodeticToMaidenhead, geodeticToUtm, greatCircleMidpoint, horizonDistance, rad2deg, rhumbLine, vincenty };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
export { c as clampUnit, e as ecefToGeodetic, g as geodeticToEcef, a as getAer, b as getEnuDifference } from './ecef-CF0uAysr.js';
|
|
2
|
+
|
|
3
|
+
/** Convert radians to degrees. */
|
|
4
|
+
declare function rad2deg(radians: number): number;
|
|
5
|
+
/** Convert degrees to radians. */
|
|
6
|
+
declare function deg2rad(degrees: number): number;
|
|
7
|
+
/**
|
|
8
|
+
* Convert decimal degrees to [degrees, minutes, seconds].
|
|
9
|
+
* Always returns positive values (use the sign of the input separately).
|
|
10
|
+
*/
|
|
11
|
+
declare function deg2dms(deg: number): [number, number, number];
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Vincenty's inverse formula — orthodromic (great-circle) distance,
|
|
15
|
+
* initial bearing, and final bearing on the WGS84 ellipsoid.
|
|
16
|
+
* All angles in radians.
|
|
17
|
+
* @returns { distance (m), initialBearing (rad), finalBearing (rad) }
|
|
18
|
+
*/
|
|
19
|
+
declare function vincenty(lat1: number, lon1: number, lat2: number, lon2: number): {
|
|
20
|
+
distance: number;
|
|
21
|
+
initialBearing: number;
|
|
22
|
+
finalBearing: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Loxodromic (rhumb line) distance and constant bearing on the WGS84 ellipsoid.
|
|
26
|
+
* Uses the ellipsoidal rhumb-line formula with isometric latitudes.
|
|
27
|
+
* All angles in radians.
|
|
28
|
+
* @param lat1 Start latitude (rad)
|
|
29
|
+
* @param lon1 Start longitude (rad)
|
|
30
|
+
* @param lat2 End latitude (rad)
|
|
31
|
+
* @param lon2 End longitude (rad)
|
|
32
|
+
* @returns {distance: meters, bearing: radians}
|
|
33
|
+
*/
|
|
34
|
+
declare function rhumbLine(lat1: number, lon1: number, lat2: number, lon2: number): {
|
|
35
|
+
distance: number;
|
|
36
|
+
bearing: number;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* 3D Euclidean (straight-line, through-the-earth) distance between two ECEF positions.
|
|
40
|
+
* @returns Distance in meters
|
|
41
|
+
*/
|
|
42
|
+
declare function euclidean3D(x1: number, y1: number, z1: number, x2: number, y2: number, z2: number): number;
|
|
43
|
+
/**
|
|
44
|
+
* Geodetic midpoint along the great-circle arc.
|
|
45
|
+
* @returns [lat, lon] in radians
|
|
46
|
+
*/
|
|
47
|
+
declare function greatCircleMidpoint(lat1: number, lon1: number, lat2: number, lon2: number): [number, number];
|
|
48
|
+
/**
|
|
49
|
+
* Geometric horizon distance from a given height above the ellipsoid.
|
|
50
|
+
* Uses the simple geometric formula with refraction coefficient k = 0.13 (standard atmosphere).
|
|
51
|
+
* @param heightMeters Height above ellipsoid in meters
|
|
52
|
+
* @returns Distance in meters
|
|
53
|
+
*/
|
|
54
|
+
declare function horizonDistance(heightMeters: number): number;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Convert geodetic coordinates to UTM.
|
|
58
|
+
* @param lat Latitude in radians
|
|
59
|
+
* @param lon Longitude in radians
|
|
60
|
+
*/
|
|
61
|
+
declare function geodeticToUtm(lat: number, lon: number): {
|
|
62
|
+
easting: number;
|
|
63
|
+
northing: number;
|
|
64
|
+
zone: number;
|
|
65
|
+
hemisphere: 'N' | 'S';
|
|
66
|
+
};
|
|
67
|
+
/**
|
|
68
|
+
* Maidenhead grid locator (6 characters) from geodetic coordinates.
|
|
69
|
+
* @param lat Latitude in radians
|
|
70
|
+
* @param lon Longitude in radians
|
|
71
|
+
*/
|
|
72
|
+
declare function geodeticToMaidenhead(lat: number, lon: number): string;
|
|
73
|
+
/**
|
|
74
|
+
* Geohash encoding from geodetic coordinates.
|
|
75
|
+
* @param lat Latitude in radians
|
|
76
|
+
* @param lon Longitude in radians
|
|
77
|
+
* @param precision Number of characters (default 8)
|
|
78
|
+
*/
|
|
79
|
+
declare function geodeticToGeohash(lat: number, lon: number, precision?: number): string;
|
|
80
|
+
|
|
81
|
+
export { deg2dms, deg2rad, euclidean3D, geodeticToGeohash, geodeticToMaidenhead, geodeticToUtm, greatCircleMidpoint, horizonDistance, rad2deg, rhumbLine, vincenty };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import {
|
|
2
|
+
deg2dms,
|
|
3
|
+
deg2rad,
|
|
4
|
+
euclidean3D,
|
|
5
|
+
geodeticToGeohash,
|
|
6
|
+
geodeticToMaidenhead,
|
|
7
|
+
geodeticToUtm,
|
|
8
|
+
greatCircleMidpoint,
|
|
9
|
+
horizonDistance,
|
|
10
|
+
rad2deg,
|
|
11
|
+
rhumbLine,
|
|
12
|
+
vincenty
|
|
13
|
+
} from "./chunk-K7WZQFBV.js";
|
|
14
|
+
import {
|
|
15
|
+
clampUnit,
|
|
16
|
+
ecefToGeodetic,
|
|
17
|
+
geodeticToEcef,
|
|
18
|
+
getAer,
|
|
19
|
+
getEnuDifference
|
|
20
|
+
} from "./chunk-37QNKGTC.js";
|
|
21
|
+
import "./chunk-6FAL6P4G.js";
|
|
22
|
+
export {
|
|
23
|
+
clampUnit,
|
|
24
|
+
deg2dms,
|
|
25
|
+
deg2rad,
|
|
26
|
+
ecefToGeodetic,
|
|
27
|
+
euclidean3D,
|
|
28
|
+
geodeticToEcef,
|
|
29
|
+
geodeticToGeohash,
|
|
30
|
+
geodeticToMaidenhead,
|
|
31
|
+
geodeticToUtm,
|
|
32
|
+
getAer,
|
|
33
|
+
getEnuDifference,
|
|
34
|
+
greatCircleMidpoint,
|
|
35
|
+
horizonDistance,
|
|
36
|
+
rad2deg,
|
|
37
|
+
rhumbLine,
|
|
38
|
+
vincenty
|
|
39
|
+
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clamp value to [-1, 1] to prevent NaN from asin/acos rounding errors.
|
|
3
|
+
* @param x Value to clamp
|
|
4
|
+
* @returns Clamped value in [-1, 1]
|
|
5
|
+
*/
|
|
6
|
+
declare function clampUnit(x: number): number;
|
|
7
|
+
/**
|
|
8
|
+
* Convert geodetic coordinates to ECEF (Earth-Centered, Earth-Fixed).
|
|
9
|
+
* @param lat Latitude in radians
|
|
10
|
+
* @param lon Longitude in radians
|
|
11
|
+
* @param h Ellipsoidal height in meters
|
|
12
|
+
* @returns [X, Y, Z] in meters
|
|
13
|
+
*/
|
|
14
|
+
declare function geodeticToEcef(lat: number, lon: number, h: number): [number, number, number];
|
|
15
|
+
/**
|
|
16
|
+
* Convert ECEF coordinates to geodetic (iterative Bowring method).
|
|
17
|
+
* @param x X in meters
|
|
18
|
+
* @param y Y in meters
|
|
19
|
+
* @param z Z in meters
|
|
20
|
+
* @returns [lat (rad), lon (rad), height (m)]
|
|
21
|
+
*/
|
|
22
|
+
declare function ecefToGeodetic(x: number, y: number, z: number): [number, number, number];
|
|
23
|
+
/**
|
|
24
|
+
* Compute ENU (East, North, Up) difference between a point and a reference in ECEF.
|
|
25
|
+
* @param x Target X in meters (ECEF)
|
|
26
|
+
* @param y Target Y in meters (ECEF)
|
|
27
|
+
* @param z Target Z in meters (ECEF)
|
|
28
|
+
* @param xRef Reference X in meters (ECEF)
|
|
29
|
+
* @param yRef Reference Y in meters (ECEF)
|
|
30
|
+
* @param zRef Reference Z in meters (ECEF)
|
|
31
|
+
* @returns [deltaE, deltaN, deltaU] in meters
|
|
32
|
+
*/
|
|
33
|
+
declare function getEnuDifference(x: number, y: number, z: number, xRef: number, yRef: number, zRef: number): [number, number, number];
|
|
34
|
+
/**
|
|
35
|
+
* Compute Azimuth, Elevation, and Range from a reference point to a target in ECEF.
|
|
36
|
+
* @returns [elevation (rad), azimuth (rad), slant range (m)]
|
|
37
|
+
*/
|
|
38
|
+
declare function getAer(x: number, y: number, z: number, xRef: number, yRef: number, zRef: number): [number, number, number];
|
|
39
|
+
|
|
40
|
+
export { getAer as a, getEnuDifference as b, clampUnit as c, ecefToGeodetic as e, geodeticToEcef as g };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Clamp value to [-1, 1] to prevent NaN from asin/acos rounding errors.
|
|
3
|
+
* @param x Value to clamp
|
|
4
|
+
* @returns Clamped value in [-1, 1]
|
|
5
|
+
*/
|
|
6
|
+
declare function clampUnit(x: number): number;
|
|
7
|
+
/**
|
|
8
|
+
* Convert geodetic coordinates to ECEF (Earth-Centered, Earth-Fixed).
|
|
9
|
+
* @param lat Latitude in radians
|
|
10
|
+
* @param lon Longitude in radians
|
|
11
|
+
* @param h Ellipsoidal height in meters
|
|
12
|
+
* @returns [X, Y, Z] in meters
|
|
13
|
+
*/
|
|
14
|
+
declare function geodeticToEcef(lat: number, lon: number, h: number): [number, number, number];
|
|
15
|
+
/**
|
|
16
|
+
* Convert ECEF coordinates to geodetic (iterative Bowring method).
|
|
17
|
+
* @param x X in meters
|
|
18
|
+
* @param y Y in meters
|
|
19
|
+
* @param z Z in meters
|
|
20
|
+
* @returns [lat (rad), lon (rad), height (m)]
|
|
21
|
+
*/
|
|
22
|
+
declare function ecefToGeodetic(x: number, y: number, z: number): [number, number, number];
|
|
23
|
+
/**
|
|
24
|
+
* Compute ENU (East, North, Up) difference between a point and a reference in ECEF.
|
|
25
|
+
* @param x Target X in meters (ECEF)
|
|
26
|
+
* @param y Target Y in meters (ECEF)
|
|
27
|
+
* @param z Target Z in meters (ECEF)
|
|
28
|
+
* @param xRef Reference X in meters (ECEF)
|
|
29
|
+
* @param yRef Reference Y in meters (ECEF)
|
|
30
|
+
* @param zRef Reference Z in meters (ECEF)
|
|
31
|
+
* @returns [deltaE, deltaN, deltaU] in meters
|
|
32
|
+
*/
|
|
33
|
+
declare function getEnuDifference(x: number, y: number, z: number, xRef: number, yRef: number, zRef: number): [number, number, number];
|
|
34
|
+
/**
|
|
35
|
+
* Compute Azimuth, Elevation, and Range from a reference point to a target in ECEF.
|
|
36
|
+
* @returns [elevation (rad), azimuth (rad), slant range (m)]
|
|
37
|
+
*/
|
|
38
|
+
declare function getAer(x: number, y: number, z: number, xRef: number, yRef: number, zRef: number): [number, number, number];
|
|
39
|
+
|
|
40
|
+
export { getAer as a, getEnuDifference as b, clampUnit as c, ecefToGeodetic as e, geodeticToEcef as g };
|