ootk-core
Version:
Orbital Object Toolkit. A modern typed replacement for satellite.js including SGP4 propagation, TLE parsing, Sun and Moon calculations, and more.
184 lines • 8.18 kB
JavaScript
/**
* @author Theodore Kruczek.
* @license MIT
* @copyright (c) 2022-2025 Theodore Kruczek Permission is
* hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the "Software"), to deal in the
* Software without restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
import { Tle } from '../main.js';
/**
* A class containing static methods for formatting TLEs (Two-Line Elements).
*/
export class FormatTle {
constructor() {
// Static class
}
/**
* Creates a TLE (Two-Line Element) string based on the provided TleParams.
* @param tleParams - The parameters used to generate the TLE.
* @returns An object containing the TLE strings tle1 and tle2.
*/
static createTle(tleParams) {
const { inc, meanmo, rasc, argPe, meana, ecen, epochyr, epochday, intl } = tleParams;
const scc = Tle.convert6DigitToA5(tleParams.scc);
const epochYrStr = epochyr.padStart(2, '0');
const epochdayStr = parseFloat(epochday).toFixed(8).padStart(12, '0');
const incStr = FormatTle.inclination(inc);
const meanmoStr = FormatTle.meanMotion(meanmo);
const rascStr = FormatTle.rightAscension(rasc);
const argPeStr = FormatTle.argumentOfPerigee(argPe);
const meanaStr = FormatTle.meanAnomaly(meana);
const ecenStr = FormatTle.eccentricity(ecen);
const intlStr = intl.padEnd(8, ' ');
// M' and M'' are both set to 0 to put the object in a perfect stable orbit
let TLE1Ending = tleParams.sat ? tleParams.sat.tle1.substring(32, 71) : ' +.00000000 +00000+0 +00000-0 0 9990';
// Add explicit positive/negative signs
TLE1Ending = TLE1Ending[1] === ' ' ? FormatTle.setCharAt(TLE1Ending, 1, '+') : TLE1Ending;
TLE1Ending = TLE1Ending[12] === ' ' ? FormatTle.setCharAt(TLE1Ending, 12, '+') : TLE1Ending;
TLE1Ending = TLE1Ending[21] === ' ' ? FormatTle.setCharAt(TLE1Ending, 21, '+') : TLE1Ending;
TLE1Ending = TLE1Ending[32] === ' ' ? FormatTle.setCharAt(TLE1Ending, 32, '0') : TLE1Ending;
const tle1 = `1 ${scc}U ${intlStr} ${epochYrStr}${epochdayStr}${TLE1Ending}`;
const tle2 = `2 ${scc} ${incStr} ${rascStr} ${ecenStr} ${argPeStr} ${meanaStr} ${meanmoStr} 00010`;
return { tle1: tle1, tle2: tle2 };
}
/**
* Converts the argument of perigee to a stringified number.
* @param argPe - The argument of perigee to be converted. Can be either a number or a string.
* @returns The argument of perigee as a stringified number.
* @throws Error if the length of the argument of perigee is not 8.
*/
static argumentOfPerigee(argPe) {
if (typeof argPe === 'number') {
argPe = argPe.toString();
}
const argPeNum = parseFloat(argPe).toFixed(4);
const argPe0 = argPeNum.padStart(8, '0');
if (argPe0.length !== 8) {
throw new Error('argPe length is not 8');
}
return argPe0;
}
/**
* Returns the eccentricity value of a given string.
* @param ecen - The string representing the eccentricity.
* @returns The eccentricity value.
* @throws Error if the length of the eccentricity string is not 7.
*/
static eccentricity(ecen) {
let ecen0 = ecen.padEnd(9, '0');
if (ecen0[1] === '.') {
ecen0 = ecen0.substring(2);
}
else {
ecen0 = ecen0.substring(0, 7);
}
if (ecen0.length !== 7) {
throw new Error('ecen length is not 7');
}
return ecen0;
}
/**
* Converts the inclination value to a string representation.
* @param inc - The inclination value to be converted.
* @returns The string representation of the inclination value.
* @throws Error if the length of the converted value is not 8.
*/
static inclination(inc) {
if (typeof inc === 'number') {
inc = inc.toString();
}
const incNum = parseFloat(inc).toFixed(4);
const inc0 = incNum.padStart(8, '0');
if (inc0.length !== 8) {
throw new Error('inc length is not 8');
}
return inc0;
}
/**
* Converts the mean anomaly to a string representation with 8 digits, padded with leading zeros.
* @param meana - The mean anomaly to be converted. Can be either a number or a string.
* @returns The mean anomaly as a string with 8 digits, padded with leading zeros.
* @throws Error if the length of the mean anomaly is not 8.
*/
static meanAnomaly(meana) {
if (typeof meana === 'number') {
meana = meana.toString();
}
const meanaNum = parseFloat(meana).toFixed(4);
const meana0 = meanaNum.padStart(8, '0');
if (meana0.length !== 8) {
throw new Error('meana length is not 8');
}
return meana0;
}
/**
* Converts the mean motion value to a string representation with 8 decimal
* places. If the input is a number, it is converted to a string. If the input
* is already a string, it is parsed as a float and then converted to a string
* with 8 decimal places. The resulting string is padded with leading zeros to
* ensure a length of 11 characters. Throws an error if the resulting string
* does not have a length of 11 characters.
* @param meanmo - The mean motion value to be converted.
* @returns The string representation of the mean motion value with 8 decimal
* places and padded with leading zeros.
* @throws Error if the resulting string does not have a length of 11
* characters.
*/
static meanMotion(meanmo) {
if (typeof meanmo === 'number') {
meanmo = meanmo.toString();
}
const meanmoNum = parseFloat(meanmo).toFixed(8);
const meanmo0 = meanmoNum.padStart(11, '0');
if (meanmo0.length !== 11) {
throw new Error('meanmo length is not 11');
}
return meanmo0;
}
/**
* Converts the right ascension value to a stringified number.
* @param rasc - The right ascension value to convert.
* @returns The stringified number representation of the right ascension.
* @throws Error if the length of the converted right ascension is not 8.
*/
static rightAscension(rasc) {
if (typeof rasc === 'number') {
rasc = rasc.toString();
}
const rascNum = parseFloat(rasc).toFixed(4);
const rasc0 = rascNum.padStart(8, '0');
if (rasc0.length !== 8) {
throw new Error('rasc length is not 8');
}
return rasc0;
}
/**
* Sets a character at a specific index in a string. If the index is out of range, the original string is returned.
* @param str - The input string.
* @param index - The index at which to set the character.
* @param chr - The character to set at the specified index.
* @returns The modified string with the character set at the specified index.
*/
static setCharAt(str, index, chr) {
if (index > str.length - 1) {
return str;
}
return `${str.substring(0, index)}${chr}${str.substring(index + 1)}`;
}
}
//# sourceMappingURL=FormatTle.js.map