ParseUtils.java
- /* Copyright 2002-2024 CS GROUP
- * Licensed to CS GROUP (CS) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package org.orekit.propagation.analytical.tle;
- import java.util.Arrays;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import org.orekit.errors.OrekitException;
- import org.orekit.errors.OrekitMessages;
- /** Utility class for TLE parsing, including alpha-5 TLE satellites IDs handling.
- * <p>
- * Alpha-5 extends the range of existing 5 digits TLE satellite numbers
- * by allowing the first digit to be an upper case letter, ignoring 'I'
- * and 'O' to avoid confusion with numbers '1' and '0'.
- * </p>
- * @see <a href="https://www.space-track.org/documentation#tle-alpha5>TLE-alpha5</a>
- * @author Mark rutten
- */
- class ParseUtils {
- /** Letter-number map for satellite number. */
- private static final int MAX_NUMERIC_SATNUM = 99999;
- /** Letter-number map for satellite number. */
- private static final Map<Character, Integer> ALPHA5_NUMBERS;
- /** Number-letter map for satellite number. */
- private static final Map<Integer, Character> ALPHA5_LETTERS;
- /** Scaling factor for alpha5 numbers. */
- private static final int ALPHA5_SCALING = 10000;
- static {
- // Generate maps between TLE satellite alphabetic characters and integers.
- final List<Character> alpha5Letters =
- Arrays.asList('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J',
- 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T',
- 'U', 'V', 'W', 'X', 'Y', 'Z');
- ALPHA5_NUMBERS = new HashMap<>(alpha5Letters.size());
- ALPHA5_LETTERS = new HashMap<>(alpha5Letters.size());
- for (int i = 0; i < alpha5Letters.size(); ++i) {
- ALPHA5_NUMBERS.put(alpha5Letters.get(i), i + 10);
- ALPHA5_LETTERS.put(i + 10, alpha5Letters.get(i));
- }
- }
- /** Private constructor for a utility class. */
- private ParseUtils() {
- // nothing to do
- }
- /** Build an alpha5 satellite number.
- * @param satelliteNumber satellite number, that may exceed the 99999 limit
- * @param name parameter name
- * @return satellite number in alpha5 representation
- */
- public static String buildSatelliteNumber(final int satelliteNumber, final String name) {
- if (satelliteNumber > MAX_NUMERIC_SATNUM) {
- final int highDigits = satelliteNumber / ALPHA5_SCALING;
- final int lowDigits = satelliteNumber - highDigits * ALPHA5_SCALING;
- final Character alpha = ALPHA5_LETTERS.get(highDigits);
- if (alpha == null) {
- throw new OrekitException(OrekitMessages.TLE_INVALID_PARAMETER,
- satelliteNumber, name, "null");
- }
- return alpha + addPadding(name, lowDigits, '0', 4, true, satelliteNumber);
- } else {
- return addPadding(name, satelliteNumber, '0', 5, true, satelliteNumber);
- }
- }
- /** Add padding characters before an integer.
- * @param name parameter name
- * @param k integer to pad
- * @param c padding character
- * @param size desired size
- * @param rightJustified if true, the resulting string is
- * right justified (i.e. space are added to the left)
- * @param satelliteNumber satellite number
- * @return padded string
- */
- public static String addPadding(final String name, final int k, final char c,
- final int size, final boolean rightJustified,
- final int satelliteNumber) {
- return addPadding(name, Integer.toString(k), c, size, rightJustified, satelliteNumber);
- }
- /** Add padding characters to a string.
- * @param name parameter name
- * @param string string to pad
- * @param c padding character
- * @param size desired size
- * @param rightJustified if true, the resulting string is
- * right justified (i.e. space are added to the left)
- * @param satelliteNumber satellite number
- * @return padded string
- */
- public static String addPadding(final String name, final String string, final char c,
- final int size, final boolean rightJustified,
- final int satelliteNumber) {
- if (string.length() > size) {
- throw new OrekitException(OrekitMessages.TLE_INVALID_PARAMETER,
- satelliteNumber, name, string);
- }
- final StringBuilder padding = new StringBuilder();
- for (int i = 0; i < size; ++i) {
- padding.append(c);
- }
- if (rightJustified) {
- final String concatenated = padding + string;
- final int l = concatenated.length();
- return concatenated.substring(l - size, l);
- }
- return (string + padding).substring(0, size);
- }
- /** Parse a double.
- * @param line line to parse
- * @param start start index of the first character
- * @param length length of the string
- * @return value of the double
- */
- public static double parseDouble(final String line, final int start, final int length) {
- final String string = line.substring(start, start + length).trim();
- return string.length() > 0 ? Double.parseDouble(string.replace(' ', '0')) : 0;
- }
- /** Parse an integer.
- * @param line line to parse
- * @param start start index of the first character
- * @param length length of the string
- * @return value of the integer
- */
- public static int parseInteger(final String line, final int start, final int length) {
- final String field = line.substring(start, start + length).trim();
- return field.length() > 0 ? Integer.parseInt(field.replace(' ', '0')) : 0;
- }
- /** Parse a satellite number.
- * @param line line to parse
- * @param start start index of the first character
- * @param length length of the string
- * @return value of the integer
- */
- public static int parseSatelliteNumber(final String line, final int start, final int length) {
- String field = line.substring(start, start + length);
- int satelliteNumber;
- final Integer alpha = ALPHA5_NUMBERS.get(field.charAt(0));
- if (alpha != null) {
- satelliteNumber = Integer.parseInt(field.substring(1));
- satelliteNumber += alpha * ALPHA5_SCALING;
- } else {
- field = field.trim();
- satelliteNumber = field.length() > 0 ? Integer.parseInt(field.replace(' ', '0')) : 0;
- }
- return satelliteNumber;
- }
- /** Parse a year written on 2 digits.
- * @param line line to parse
- * @param start start index of the first character
- * @return value of the year
- */
- public static int parseYear(final String line, final int start) {
- final int year = 2000 + parseInteger(line, start, 2);
- return (year > 2056) ? (year - 100) : year;
- }
- }