Python卫星位置检测项目报错:TypeError:列表索引需为整数或切片而非字符串
卫星位置检测项目Python报错解决
错误信息
Traceback (most recent call last): File "C:\Users\soumy\OneDrive\Desktop\PySatelliteFinder\main.py", line 50, in <module> calculate_and_display_position(name.upper()) # Convert to uppercase for TLE lookup ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\soumy\OneDrive\Desktop\PySatelliteFinder\main.py", line 15, in calculate_and_display_position satellite = ts[name] ~~^^^^^^ TypeError: list indices must be integers or slices, not str
问题代码
import turtle from datetime import datetime from skyfield.api import Topos, load # Function to calculate and display satellite position def calculate_and_display_position(name): # Clear previous drawing screen.clear() # Load TLE data ts = load.tle_file('stations.txt') try: satellite = ts[name] except KeyError: screen.write(f"Satellite '{name}' not found.", align="center", font=("Arial", 16, "normal")) return # Get current UTC time current_time = datetime.utcnow() # Calculate satellite position topos = satellite.at(ts.utc(current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second)) alt, az, _ = topos.observe(observer_location).apparent().altaz() # Display satellite name, position, and local time screen.write(f"Satellite: {name}\n" f"Altitude: {alt.degrees:.2f} degrees\n" f"Azimuth: {az.degrees:.2f} degrees\n" f"Local Time: {current_time}", align="left", font=("Arial", 16, "normal")) # Create a Turtle screen screen = turtle.Screen() screen.bgpic("world_map.gif") # You'll need to provide a world map image # Create an observer location observer_location = Topos(latitude_degrees=23.247921, longitude_degrees=87.871365) # Initialize the Turtle satellite_turtle = turtle.Turtle() satellite_turtle.penup() satellite_turtle.goto(0, 200) satellite_turtle.hideturtle() # Input box for satellite name name = screen.textinput("Enter Satellite Name", "Enter the satellite name:") if name: calculate_and_display_position(name.upper()) # Convert to uppercase for TLE lookup # Listen for clicks to change satellite screen.onclick(lambda x, y: calculate_and_display_position(screen.textinput("Enter Satellite Name", "Enter the satellite name:").upper())) # Close the window when clicked screen.exitonclick()
问题分析
- 变量名冲突:代码中把
load.tle_file()返回的卫星列表命名为ts,但Skyfield中ts通常指代时间尺度对象(load.timescale()),后续调用ts.utc()会引发逻辑错误,同时导致变量混淆。 - 列表无法通过字符串索引:
load.tle_file()返回的是卫星对象的列表,只能用整数索引,无法直接通过卫星名称(字符串)获取对应对象,这是触发当前报错的直接原因。
解决方案
- 分离变量名:将TLE加载的卫星列表命名为
satellites_list,单独加载时间尺度对象为ts,避免命名冲突。 - 转换卫星列表为字典:用字典推导式将卫星列表转为以卫星名称大写为键的字典,匹配输入的大写格式,方便通过名称快速索引。
- 修正时间计算逻辑:使用正确的时间尺度对象
ts生成Skyfield可识别的时间格式。 - 增加卫星标记逻辑:将卫星经纬度转换为海龟屏幕坐标,在地图上用红色标记卫星位置并显示名称。
修正后完整代码
import turtle from datetime import datetime from skyfield.api import Topos, load # 预加载时间尺度和TLE数据,避免重复加载提升效率 ts = load.timescale() satellites_list = load.tle_file('stations.txt') # 转换为大写名称为键的字典,匹配输入格式 satellites_dict = {sat.name.upper(): sat for sat in satellites_list} # 地图坐标转换参数(根据你的世界地图实际尺寸调整) MAP_WIDTH = 800 MAP_HEIGHT = 600 LON_SCALE = MAP_WIDTH / 360 LAT_SCALE = MAP_HEIGHT / 180 def calculate_and_display_position(name): # 清空之前的绘制内容 screen.clear() satellite_turtle.clear() satellite_turtle.penup() satellite_turtle.hideturtle() try: satellite = satellites_dict[name] except KeyError: screen.write(f"Satellite '{name}' not found.", align="center", font=("Arial", 16, "normal")) return # 获取当前UTC时间并转换为Skyfield时间格式 current_time = datetime.utcnow() skyfield_time = ts.utc(current_time.year, current_time.month, current_time.day, current_time.hour, current_time.minute, current_time.second) # 计算卫星的地面投影位置 geocentric = satellite.at(skyfield_time) subpoint = geocentric.subpoint() lat = subpoint.latitude.degrees lon = subpoint.longitude.degrees # 计算卫星相对于观测者的高度和方位角 alt, az, _ = geocentric.observe(observer_location).apparent().altaz() # 将经纬度转换为海龟屏幕坐标 x = lon * LON_SCALE y = lat * LAT_SCALE # 用红色标记卫星位置并显示名称 satellite_turtle.goto(x, y) satellite_turtle.dot(10, 'red') satellite_turtle.write(name, align="center", font=("Arial", 12, "bold")) # 显示卫星详细信息 screen.write(f"Satellite: {name}\n" f"Latitude: {lat:.2f}°\n" f"Longitude: {lon:.2f}°\n" f"Altitude: {alt.degrees:.2f}°\n" f"Azimuth: {az.degrees:.2f}°\n" f"UTC Time: {current_time}", align="left", font=("Arial", 16, "normal")) # 创建海龟绘图窗口 screen = turtle.Screen() screen.setup(width=MAP_WIDTH, height=MAP_HEIGHT) screen.bgpic("world_map.gif") # 确保世界地图图片路径正确 # 设置观测者位置 observer_location = Topos(latitude_degrees=23.247921, longitude_degrees=87.871365) # 初始化卫星标记海龟 satellite_turtle = turtle.Turtle() satellite_turtle.penup() satellite_turtle.hideturtle() # 弹出卫星名称输入框 name = screen.textinput("Enter Satellite Name", "Enter the satellite name:") if name: calculate_and_display_position(name.upper()) # 点击窗口触发新的卫星查询 def on_click(x, y): new_name = screen.textinput("Enter Satellite Name", "Enter the satellite name:") if new_name: calculate_and_display_position(new_name.upper()) screen.onclick(on_click) # 点击窗口关闭程序 screen.exitonclick()
说明
- 预加载TLE数据和时间尺度,避免每次调用函数重复加载,提升运行效率。
- 地图坐标转换参数可根据你的世界地图实际尺寸调整,确保卫星位置标记准确。
- 实现了红色标记卫星位置、显示卫星名称及详细参数的功能。
内容的提问来源于stack exchange,提问作者epubby sudsou
相关产品推荐
相关产品推荐

