UNPKG

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
/** * @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