File size: 4,349 Bytes
fcec389 0587a5f fcec389 0587a5f fcec389 0587a5f fcec389 0587a5f fcec389 0587a5f fcec389 0587a5f fcec389 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
import os
import streamlit as st
from skyfield.api import Topos, load, EarthSatellite
import requests
import pandas as pd
import numpy as np
from datetime import datetime
import pytz
def get_cardinal_direction(azimuth_degrees):
"""
Converts azimuth degrees to cardinal direction.
"""
directions = ['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N']
index = int((azimuth_degrees + 22.5) // 45)
return directions[index % 8]
def compute_ephemeris(satellite_url, latitude, longitude, start_date_utc, start_time, end_time, timezone_str, custom_tle=None):
"""
Computes the ephemeris for the satellite and converts times to local time.
"""
try:
ts = load.timescale()
year, month, day = map(int, start_date_utc.split('-'))
observer = Topos(latitude, longitude)
start_hour, start_minute = start_time.hour, start_time.minute
end_hour, end_minute = end_time.hour, end_time.minute
start_datetime = datetime(year, month, day, start_hour, start_minute)
end_datetime = datetime(year, month, day, end_hour, end_minute)
total_minutes = int((end_datetime - start_datetime).total_seconds() // 60)
times = ts.utc(year, month, day, [start_hour] * total_minutes, np.arange(start_minute, start_minute + total_minutes))
# Fetch TLE data for custom satellite or use predefined URL
if custom_tle:
satellites = [EarthSatellite(custom_tle[1], custom_tle[2], custom_tle[0], ts)]
else:
r = requests.get(satellite_url)
with open('satellite_data.txt', 'wb') as f:
f.write(r.content)
satellites = load.tle_file('satellite_data.txt')
# Prepare the ephemeris data
ephemeris_data = []
local_tz = pytz.timezone(timezone_str)
for satellite in satellites:
difference = satellite - observer
for ti in times:
topocentric = difference.at(ti)
ra, dec, distance = topocentric.radec()
alt, az, distance = topocentric.altaz()
if alt.degrees > 0: # Check if the satellite is above the horizon
azimuth_degrees = az.degrees
cardinal_direction = get_cardinal_direction(azimuth_degrees)
# Convert UTC time to local time
local_time = ti.utc_datetime().replace(tzinfo=pytz.utc).astimezone(local_tz)
ephemeris_data.append({
"Date (Local Time)": local_time.strftime('%Y-%m-%d %H:%M:%S'),
"R.A.": str(ra),
"Dec": str(dec),
"Altitude": f"{alt.degrees:.2f}°",
"Azimuth": f"{azimuth_degrees:.2f}° ({cardinal_direction})"
})
# Convert ephemeris data to DataFrame for display
ephemeris_df = pd.DataFrame(ephemeris_data)
if not custom_tle:
os.remove('satellite_data.txt')
return ephemeris_df
except Exception as e:
st.error(f"Error computing ephemeris: {str(e)}")
return pd.DataFrame() # Return an empty DataFrame on error
def fetch_custom_tle(satellite_name_or_id):
"""
Fetches TLE data for a custom satellite by name or NORAD ID.
"""
try:
if satellite_name_or_id.isdigit():
celestrak_url = f'https://celestrak.org/NORAD/elements/gp.php?CATNR={satellite_name_or_id}'
else:
celestrak_url = f'https://celestrak.org/NORAD/elements/gp.php?NAME={satellite_name_or_id}&FORMAT=TLE'
with st.spinner("Fetching TLE data..."):
response = requests.get(celestrak_url)
if response.status_code == 200 and len(response.text.splitlines()) >= 2:
lines = response.text.splitlines()
st.success("TLE data fetched successfully!")
st.text(f"Name: {lines[0].strip()}\nTLE Line 1: {lines[1].strip()}\nTLE Line 2: {lines[2].strip()}")
return lines[0].strip(), lines[1].strip(), lines[2].strip() # Name, TLE line 1, TLE line 2
else:
st.error("TLE data could not be fetched. Please check the satellite name or NORAD ID.")
return None
except Exception as e:
st.error(f"Error fetching TLE data: {str(e)}")
return None
|