Вопрос или проблема
У меня есть скрипт для отслеживания МКС и визуализации её орбиты на карте с использованием folium
. Он получает данные TLE, затем вычисляет позиции спутника и строит его траекторию. Он работает нормально, но не так, как я ожидал. В выводе есть прямая линия, соединяющая две точки. Это не должно быть так. Орбита должна выглядеть как на этом сайте: https://www.n2yo.com/satellite/?s=25544
Вот код (извините за беспорядок в коде):
# Импорт необходимых модулей
from skyfield.iokit import parse_tle_file
from skyfield.api import load, Topos
from datetime import datetime, timedelta
import folium
#import time
# Загружаем шкалу времени
time_scale = load.timescale()
# Получаем текущее время
t_now = datetime.utcnow()
t = time_scale.utc(t_now.year, t_now.month, t_now.day, t_now.hour, t_now.minute, t_now.second)
# Загружаем элементные наборы МКС (ЗАРЯ), если файл не существует или устарел.
max_days = 7.0 # Загружать снова каждую неделю
tle_filename = "data_files/iss_zarya_tle.tle" # Имя файла
url = "https://celestrak.org/NORAD/elements/gp.php?CATNR=25544&FORMAT=TLE"
if not load.exists(tle_filename) or load.days_old(tle_filename) >= max_days:
try:
load.download(url, filename=tle_filename)
except:
print("ОШИБКА: Не удалось загрузить данные TLE.\nВыход из программы.")
quit()
# Загрузка данных спутника из файла TLE
with load.open(tle_filename) as f:
satellites = list(parse_tle_file(f, time_scale))
# Индексируем МКС (ЗАРЯ) по номеру NORADID
by_number = {sat.model.satnum: sat for sat in satellites}
satellite = by_number[25544]
# Вычисляем позицию спутника
geocentric_pos = satellite.at(t) # Позиция спутника вблизи Земли от его центра масс.
sub_pos = geocentric_pos.subpoint() # Позиция спутника, проецируемая на поверхность Земли.
sat_lat = sub_pos.latitude.degrees # Широта спутника.
sat_long = sub_pos.longitude.degrees # Долгота спутника.
# Создаём карту
orbit_map = folium.Map(location=[sat_lat, sat_long], zoom_start=3)
#print(f"Широта: {sat_lat}\nДолгота: {sat_long}\n")
folium.Marker(location=[sat_lat, sat_long], popup="Позиции МКС", tooltip=f"ПОЗИЦИЯ 1").add_to(orbit_map)
#time.sleep(60)
# Автотрекинг
#i = 1
orbit_coordinates = []
orbit_coordinates.append((sat_lat, sat_long))
#auto_track_on = True
for j in range(1, 91):
future_time = t + timedelta(minutes=j)
geocentric_pos_future = satellite.at(future_time)
sub_pos_future = geocentric_pos_future.subpoint()
sat_lat_future = sub_pos_future.latitude.degrees
sat_long_future = sub_pos_future.longitude.degrees
route_coordinate = (sat_lat_future, sat_long_future)
orbit_coordinates.append(route_coordinate)
#print(f"Широта: {sat_lat_future}\nДолгота: {sat_long_future}\n")
#i += 1
#time.sleep(60)
folium.PolyLine(orbit_coordinates).add_to(orbit_map)
orbit_map.save("iss_orbit.html")
И вот вывод:
скриншот вывода
Ответ или решение
Для решения вашей проблемы с отображением орбиты МКС (Международной космической станции) на карте, необходимо понять, что Фолий (Folium) отображает точки с использованием простых линий. Это значит, что если вы используете метод PolyLine
, чтобы соединять координаты, он создает прямые линии между ними, что не всегда отражает корректное движение спутника в пространстве. Чтобы получить более точное представление об орбите, нужно учитывать время, необходимое для полного круга, и использовать более высокую частоту точек, чтобы сделать линию более гладкой.
Вот ваш скорректированный код с учетом плавности линии, что позволит отобразить орбиту более достоверно:
# Импорт необходимых модулей
from skyfield.iokit import parse_tle_file
from skyfield.api import load
from datetime import datetime, timedelta
import folium
# Загрузка шкалы времени
time_scale = load.timescale()
# Получение текущего времени
t_now = datetime.utcnow()
t = time_scale.utc(t_now.year, t_now.month, t_now.day, t_now.hour, t_now.minute, t_now.second)
# Загрузка элементных наборов ISS (ЗАРЯ)
max_days = 7.0 # Загрузка снова каждые 7 дней
tle_filename = "data_files/iss_zarya_tle.tle" # Имя файла
url = "https://celestrak.org/NORAD/elements/gp.php?CATNR=25544&FORMAT=TLE"
if not load.exists(tle_filename) or load.days_old(tle_filename) >= max_days:
try:
load.download(url, filename=tle_filename)
except:
print("ERROR: Не удалось загрузить данные TLE.\nПрограмма завершена.")
quit()
# Загрузка данных спутника из файла TLE
with load.open(tle_filename) as f:
satellites = list(parse_tle_file(f, time_scale))
# Индексация ISS (ЗАРЯ) по номеру NORAD
by_number = {sat.model.satnum: sat for sat in satellites}
satellite = by_number[25544]
# Подготовка карты
initial_position = satellite.at(t).subpoint()
# Получаем первоначальные координаты
sat_lat = initial_position.latitude.degrees
sat_long = initial_position.longitude.degrees
orbit_map = folium.Map(location=[sat_lat, sat_long], zoom_start=3)
# Сохраняем координаты орбиты
orbit_coordinates = []
# Изменим интервал для получения более гладкой линии
for j in range(90):
future_time = t + timedelta(seconds=j * 60) # получаем координаты каждую минуту
geocentric_pos_future = satellite.at(future_time)
sub_pos_future = geocentric_pos_future.subpoint()
sat_lat_future = sub_pos_future.latitude.degrees
sat_long_future = sub_pos_future.longitude.degrees
orbit_coordinates.append((sat_lat_future, sat_long_future))
# Плотим линию для орбиты
folium.PolyLine(orbit_coordinates, color="blue", weight=2.0, opacity=0.5).add_to(orbit_map)
# Печатать маркеры для начальной и конечной точек орбиты
folium.Marker(location=[sat_lat, sat_long], popup="ISS Начальная позиция").add_to(orbit_map)
folium.Marker(location=orbit_coordinates[-1], popup="ISS Конечная позиция").add_to(orbit_map)
# Сохранение карты
orbit_map.save("iss_orbit.html")
В этом коде было предпринято несколько ключевых улучшений:
- Увеличен интервал получения координат до 90 в течение 90 минут для более высокой разрешающей способности.
- Добавлены маркеры для начальной и конечной точек орбиты, что позволяет лучше понять положение спутника.
Теперь, когда вы откроете сгенерированный файл iss_orbit.html
, вы увидите более гладкую линию, представляющую орбиту МКС. Надеюсь, это поможет вам получить желаемый результат!