Source code for opengnc.ssa.tle_interface

"""
TLE Catalog Interface and Utilities.
"""

from ..propagators.sgp4_propagator import Sgp4Propagator


[docs] class TLEEntity: """ Representation of a Two-Line Element (TLE) set for a satellite. Parameters ---------- name : str Common name of the satellite. line1 : str First line of the TLE. line2 : str Second line of the TLE. """ def __init__(self, name: str, line1: str, line2: str) -> None: """Initialize TLE entity and parse metadata.""" self.name = name.strip() self.line1 = line1.rstrip() self.line2 = line2.rstrip() self.norad_id = self._parse_norad_id() def _parse_norad_id(self) -> str: """Extract NORAD catalog ID from Line 1.""" if len(self.line1) > 7: return self.line1[2:7].strip() return "00000"
[docs] def get_propagator(self) -> Sgp4Propagator: """ Create a propagator instance for this TLE. Returns ------- Sgp4Propagator SGP4 propagator initialized with TLE lines. """ return Sgp4Propagator(self.line1, self.line2)
[docs] class TLECatalog: """ Catalog for managing and searching a collection of satellite TLEs. """ def __init__(self) -> None: """Initialize empty catalog.""" self.satellites: list[TLEEntity] = [] self._by_id: dict[str, TLEEntity] = {} self._by_name: dict[str, TLEEntity] = {}
[docs] def add_tle(self, name: str, line1: str, line2: str) -> None: """ Register a new TLE in the catalog. Parameters ---------- name : str Satellite name. line1, line2 : str TLE data. """ entity = TLEEntity(name, line1, line2) self.satellites.append(entity) self._by_id[entity.norad_id] = entity self._by_name[entity.name.upper()] = entity
[docs] def load_from_txt(self, filepath: str) -> None: """ Load TLE data from a standard text file. Supports both 2-line and 3-line (with name) TLE formats. Parameters ---------- filepath : str Path to the TLE file. """ with open(filepath) as f: lines = [l.strip() for l in f.readlines() if l.strip()] i = 0 while i < len(lines) - 1: l1, l2 = lines[i], lines[i+1] if l1.startswith("1") and l2.startswith("2"): # 3-line format (Name above 1/2) or 2rd/3rd line of 3-line if i > 0 and not lines[i-1].startswith(("1", "2")): name = lines[i-1] else: name = f"SAT_{l1[2:7]}" self.add_tle(name, l1, l2) i += 2 else: i += 1
[docs] def get_by_norad_id(self, norad_id: str | int) -> TLEEntity | None: """Lookup satellite by catalog ID.""" return self._by_id.get(str(norad_id).strip())
[docs] def get_by_name(self, name: str) -> TLEEntity | None: """Lookup satellite by name (case-insensitive).""" return self._by_name.get(name.strip().upper())
[docs] def list_satellites(self) -> list[str]: """List names of all registered satellites.""" return [s.name for s in self.satellites]