Satellogic's Open Satellite Feed
Satellogic's Open Satellite Feed
Satellogic is a satellite designer, manufacturer and constellation operator. They were founded in 2010 and have offices in Argentina, Uruguay, Spain and the US. They launched three prototype Cube satellites between 2013 and 2014, using China and Russia as
tech.marksblogg.com
지난번 작성했던 1편 이후 다시 할 줄 몰랐습니다. 어느 정도 하다가 원하는 데이터는 얻은 거 같아서 멈추고 있었는데 우연히 X에서 추천받은 게시물을 보고 사이트를 기웃거리다 전문가가 만들어 놓은 글이 있었습니다. 그분의 이력을 보니 관련 업무로 컨설팅을 하시는 외국인 형님이더라고요. 그걸 보자마자 또 해보고 싶어서 따라 했습니다. 그리고 4시간이 없어졌습니다. 반만 완성한 상태인데, 역시 비전공자에게는 어려운 코딩의 영역입니다.
세틀로직 EarthView에 접근해보기
"Satellogic EarthView 데이터셋, 이제 AWS 오픈 데이터 레지스트리를 통해 공개적으로 접근 가능" "Satellogic EarthView 데이터셋, 이제 AWS 오픈 데이터 레지스트리를 통해 공개적으로 접근 가능"*25년 2월 27
myview7144.tistory.com
1. 기본 설치 프로그램
필요한 프로그램
파이썬 : 다운로드
Download Python
The official home of the Python Programming Language
www.python.org
Visual Studio Build Tools : 다운로드
Visual Studio Tools 다운로드 - Windows, Mac, Linux용 무료 설치
Visual Studio IDE 또는 VS Code를 무료로 다운로드하세요. Windows 또는 Mac에서 Visual Studio Professional 또는 Enterprise Edition을 사용해 보세요.
visualstudio.microsoft.com
다운로드 시 필수 선택 :
"MSVC v143 - VS 2022 C++ x64/x86 build tools" (최신 버전 권장)
"Windows 10/11 SDK" (최신 버전)
"English language pack" (선택 사항
Anaconda : 다운로드
Anaconda | Built to Advance Open Source AI
Anaconda simplifies, safeguards, and accelerates open-source AI with a trusted platform, enabling secure scaling, real-time insights, and community collaboration.
www.anaconda.com
OSGeo4 W : 다운로드
설치 옵션 선택:
"Advanced Install"을 선택하고 "Next" 클릭.
"Install from Internet" 선택 (기본값 유지).
설치 경로 설정: 기본값(C:\OSGeo4 W)을 사용하거나 원하는 경로로 변경.
패키지 선택: "Search" 필드에 gdal 입력. 결과 목록에서 gdal과 관련 패키지(예: gdal-python, gdal-devel)를 찾아 "Skip"을 클릭해 버전을 선 택(최신 버전 추천).
필요한 경우 Python과 연동하려면 python3-gdal도 추가.
의존성 자동 설치: 필요한 의존성 패키지가 자동으로 선택됩니다. "Next"를 눌러 진행.
다운로드 및 설치: 인터넷에서 파일을 다운로드한 후 설치가 완료될 때까지 기다립니다.
OSGeo4W
OSGeo4W Japanese French Polish Deutsch This is the web site, wiki and issue tracking database for the OSGeo4W project. OSGeo4W is a binary distribution of a broad set of open source geospatial software for Windows environments (Windows 11 down to 7). OSGeo
trac.osgeo.org
기본적으로 필요한 프로그램 위 4가지입니다. 사실 파이썬을 제외하고는 저도 처음 설치하고 만져보는 것들이라 많이 낯설었습니다. 일단 블로그에 기재된 글을 기준으로 하나씩 만들어 나가야 하는데 제일 먼저 해야 하는 것이 라이브러리 구성을 해야 합니다. 저는 실행 프로그램으로 conda를 사용했습니다.
2. 프로그램 모듈 설치
프로그램을 실행하고 아래의 명령어를 넣어 라이브러리 설치를 진행해야 합니다.
conda activate satl
python -m pip install astropy awscli html2text requests rich sgp4 utm
명령어 의미
~/. satl : 가상 환경 디렉터리 생성
source ~/. satl/bin/activate : 가상 환경 활성
설치된 라이브러리
astropy : 천문학 계산(위성 궤적 계산에 사용 가능)
awscli : AWS S3에서 데이터 다운로드
sgp4 : 위성 위치 계산을 위한 TLE 처리
utm : 좌표 변환
설치가 정상적으로 진행이 되었다면, DuckDB 모듈을 설치해야 합니다. 설치가 완료된 창을 닫거나 새로운 프롬프트 창을 열어서 아래의 코드를 실행합니다.
pip install duckdb
DuckDB는 빠른 데이터 분석을 위한 인메모리 데이터베이스입니다. 이 모듈이 설치되어야 후에 진행하는 것과 연계하여 프로그램이 정상적으로 구동됩니다.
이후에는 gdal이라는 모듈을 설치해야 합니다. 제가 이 설치에서 거의 1시간 이상을 잡아먹었습니다. 계속해서 에러가 뜨더군요. 일단은 명령창을 새로 열어서 아래의 코드를 실행합니다. 실행해서 되면 정상적으로 작동을 하고, 아니라면 원인을 계속 파악해야 합니다.
pip install gdal
저의 경우에는 계속해서 Visual Code와 에러가 떴습니다. 그래서 이를 해결한 방법은 Conda에서 gdal을 설치한 것입니다. Conda에서 가상화를 통한 설치 방법입니다. 아래의 코드를 이용해서 직접 설치를 진행합니다.
conda activate satl
conda install gdal -c conda-forge -y
그리고 설치 확인을 위해서 아래의 코드를 또 실행합니다.
python -c "from osgeo import gdal; print(gdal.__version__)"
정상적으로 실행이 되면 gdal의 버전이 출력됩니다. 이렇게 되면 정상적으로 설치가 완료되었습니다. 하지만 다른 문제점들이 나올 수 있는데 그러한 경우에는 직접 검색을 통한 해결 외에는 방법이 없습니다.
그리고 gdal의 경우에는 python 버전과 동일하게 출력이 되어야 합니다. 해당 출력을 확인하기 위해서 다음 코드를 실행합니다.
gdalinfo --version
python -c "from osgeo import gdal; print(gdal.__version__)"
저의 경우에는 python 3.10.x / gdal 3.10.2 버전입니다. 앞에 큰 버전의 숫자만 일치하면 됩니다. 그리고 이제는 TLE 데이터 추출을 위한 코드를 작성합니다. 아래의 코드를 작성하여 fetch_tle.py로 저장합니다. 위성의 움직임 날짜는 임의로 25년 3월 1일부터 3월 5일까지로 세팅이 되어 있습니다.
import json
import requests
from rich.progress import track
import time
from random import randint
from datetime import datetime, timedelta
from astropy import units as u
from astropy.time import Time
from astropy.coordinates import ITRS, TEME, CartesianDifferential, CartesianRepresentation
from sgp4.api import Satrec, SGP4_ERRORS
# NORAD ID 리스트
norad_ids = [48682, 48629, 48627, 48633, 48631, 48630, 48640, 48635, 48636, 48632, 48619,
52168, 52178, 52171, 52184, 52172, 52747, 52764, 52760, 52745, 52752, 59604,
59602, 52071, 56943, 56946, 56936, 59129, 59122, 60489, 60500, 60493, 48274,
45017, 45018, 48629]
# 1. Celestrak에서 최신 TLE 데이터 자동 다운로드
print("Downloading TLE data from Celestrak...")
url = "https://celestrak.org/NORAD/elements/gp.php?GROUP=active&FORMAT=tle"
response = requests.get(url)
if response.status_code == 200:
with open("celestrak_tle.txt", "w", encoding="utf-8") as f:
f.write(response.text)
print("TLE data downloaded and saved to celestrak_tle.txt")
else:
print(f"Failed to download TLE data from Celestrak, Status Code: {response.status_code}")
exit(1)
# 2. Celestrak TLE 데이터 파싱
with open("celestrak_tle.txt", "r") as f:
lines = [line.strip() for line in f.readlines() if line.strip()] # 빈 줄 제거
tles = {}
found_norad_ids = set()
for i in range(0, len(lines), 3):
if i + 2 >= len(lines): # 파일 끝에 도달하면 중단
break
name = lines[i]
line1 = lines[i+1]
line2 = lines[i+2]
# TLE 데이터 유효성 검사
if not name or not line1 or not line2: # 빈 줄 체크
print(f"Skipping invalid TLE entry at line {i}: Empty name, line1, or line2")
continue
if not line1.startswith("1 ") or not line2.startswith("2 "): # TLE 형식 체크
print(f"Skipping invalid TLE entry at line {i}: Incorrect TLE format")
continue
try:
# NORAD ID 추출 (Line 1에서 2-7번째 문자)
norad_id = int(line1[2:7])
except ValueError as e:
print(f"Skipping invalid TLE entry at line {i}: Invalid NORAD ID - {e}")
continue
# 디버깅: 발견된 NORAD ID 출력
found_norad_ids.add(norad_id)
# 우리의 NORAD ID 리스트에 있는 경우만 저장
if norad_id in norad_ids:
tles[norad_id] = {
"name": name,
"tle": [line1, line2]
}
# 디버깅: 발견된 NORAD ID와 매칭 확인
missing_ids = set(norad_ids) - found_norad_ids
if missing_ids:
print(f"These NORAD IDs were not found in Celestrak data: {missing_ids}")
else:
print("All NORAD IDs were found in Celestrak data.")
# TLE 데이터가 비어 있는지 확인
if not tles:
print("No valid TLE data found for the given NORAD IDs in Celestrak data.")
print("Please verify the NORAD IDs or use a different TLE data source (e.g., Space-Track.org).")
exit(1)
# 3. 위성 이름 매핑 (이미지와 일치하도록)
name_mapping = {
"NUSAT-25": "NUSAT-25 (MARIA TELKES)",
"NUSAT-26": "NUSAT-26 (SOMERVILLE)",
"NUSAT-28": "NUSAT-28 (ALICE LEE)",
"NUSAT-29": "NUSAT-29 (EDITH CLARKE)",
"NUSAT-30": "NUSAT-30 (SHOEMAKER)",
"NUSAT-31": "NUSAT-31 (RUBY PAYNE-S)",
"NUSAT-32": "NUSAT-32 (M WONENBURGER)",
"NUSAT-33": "NUSAT-33 (ALBANIA-2)",
"NUSAT-34": "NUSAT-34 (AMELIA EARHART)",
"NUSAT-35": "NUSAT-35 (WILLAMINA)",
"NUSAT-36": "NUSAT-36 (MARIA AGNESI)",
"NUSAT-37": "NUSAT-37 (JOAN CLARKE)",
"NUSAT-38": "NUSAT-38 (ANNIE CANNON)",
"NUSAT-39": "NUSAT-39 (TIYAK ALPHER)",
"NUSAT-40": "NUSAT-40 (VON NEUMANN)",
"NUSAT-41": "NUSAT-41 (RUBY PAYNE-S)",
"NUSAT-42": "NUSAT-42 (M WONENBURGER)",
"NUSAT-43": "NUSAT-43 (DIENG-KUNTZ)",
"NUSAT-44": "NUSAT-44 (MARIA MITCHELL)",
"NUSAT-48": "NUSAT-48 (H. LEAVITT)",
"NUSAT-49": "NUSAT-49 (VON NEUMANN)",
"NUSAT-50": "NUSAT-50 (NANCY ROMAN)",
}
# 이름 매핑 적용
for norad_id in tles:
original_name = tles[norad_id]["name"]
tles[norad_id]["name"] = name_mapping.get(original_name, original_name)
# TLE 데이터를 JSON 파일에 저장
with open("tles.json", "w", encoding="utf-8") as f:
json.dump(tles, f, indent=4)
print("TLE data from Celestrak saved to tles.json")
# 4. 시간 범위 설정: 2025년 3월 1일부터 3월 5일까지 (하루 간격)
start_date = Time("2025-03-01T00:00:00", format='isot', scale='utc')
end_date = Time("2025-03-05T23:59:59", format='isot', scale='utc')
time_steps = []
current_date = start_date
while current_date <= end_date:
time_steps.append(current_date)
current_date += 86400 * u.s # 하루 간격 (86400초)
# 5. 위치 계산 및 CSV 파일 작성
with open('locations.csv', 'w') as f:
f.write("WKT,name,time\n")
for norad_id in tles:
name = tles[norad_id]['name']
line1 = tles[norad_id]['tle'][0]
line2 = tles[norad_id]['tle'][1]
satellite = Satrec.twoline2rv(line1, line2)
for t in time_steps:
error_code, teme_p, teme_v = satellite.sgp4(t.jd1, t.jd2)
if error_code != 0:
print(f"SGP4 Error for NORAD ID {norad_id} at {t}: {SGP4_ERRORS[error_code]}")
continue
teme_p = CartesianRepresentation(teme_p * u.km)
teme_v = CartesianDifferential(teme_v * u.km / u.s)
teme = TEME(teme_p.with_differentials(teme_v), obstime=t)
itrs_geo = teme.transform_to(ITRS(obstime=t))
location = itrs_geo.earth_location
loc = location.geodetic
lat = loc.lat.deg
lon = loc.lon.deg
if not (-90 <= lat <= 90 and -180 <= lon <= 180):
print(f"Invalid location for NORAD ID {norad_id} at {t}: lat={lat}, lon={lon}")
continue
f.write("%s,%s,%s\n" % (
"POINT (%f %f)" % (lon, lat),
name.strip(),
t.iso
))
print("Location data saved to locations.csv")
그리고 이후 가상환경(satl)이 진행된 상태에서 해당 프로그램을 실행합니다. 정상 실행이 되었다면 아래와 같이 Location data saved to locations.csv 파일이 생성됩니다. 이 파일에서는 현재 상공을 돌고 있는 위성의 위치와 이름을 확인할 수 있습니다. 의도하지는 않았지만 다른 위성들도 나왔네요. 여기까지 한다고 너무 어려웠지만, 그래도 보람이 있었습니다. 물론, 뒷 과정이 훨씬 남아 있을 것으로 생각되지만 기록용으로 글을 쓰는 거라 따라 할 사람은 없단 걸 알고 있습니다. 다음에는 프로그램에 해당 위성의 위치를 남기는 것부터 작성할 예정입니다. 오늘 끝!
python fetch_tle.py
'참고하면 좋은 것들 > 위성 사업 트래킹' 카테고리의 다른 글
Black Sky 24 Q4 실적 및 어닝 콜 요약 (0) | 2025.03.07 |
---|---|
지구 관측 기술의 혁신: 광물 자원 탐사 효율성 25배 향상 (1) | 2025.03.03 |
NOAA 구조 조정과 ACES 축소: 우주 산업의 빛과 그림자 (1) | 2025.03.01 |
세틀로직 EarthView에 접근해보기 (0) | 2025.02.27 |
Satellogic EarthView 데이터셋, 이제 AWS 오픈 데이터 레지스트리를 통해 공개적으로 접근 가능 (0) | 2025.02.27 |