Python解析FSX的FLT文件DMS坐标转十进制度数异常排查
问题根因
你写的字符串切片逻辑和当前FLT文件的存储结构完全不匹配:
str.find()找不到目标子串时会返回整数-1,你用逗号作为经度字段的结束标记,但你导出的FLT里经纬度是单独占行的,根本没有逗号,所以longend拿到的是-1,后续切片取到的内容完全不对,强转float自然报错。- 你代码里除以120000的转换逻辑,是适配老版本FSX存储的整数型坐标数据的,和你当前文件里带方向、度分秒符号的文本格式完全不适用。
正确实现方案
字段读取逻辑
不要硬编码字符偏移量做切片,先定位到[SimVars.0]配置段,再逐行匹配对应键值对,容错性更高,哪怕FLT文件其他段顺序调整也不会读错。
DMS转十进制度逻辑
转换公式固定为:十进制度 = 度数值 + 分数值/60 + 秒数值/3600
如果坐标方向是南纬(S)、西经(W),最终结果要取负值。
可直接复用的代码片段
import re # 读取FLT文件,若报编码错误可将encoding替换为gbk重试 with open("HMS Bounty.FLT", "r", encoding="utf-8") as f: file_content = f.read() # 定位SimVars.0段的起止范围 seg_start = file_content.find("[SimVars.0]") seg_end = file_content.find("[", seg_start + 1) simvar_seg = file_content[seg_start : seg_end if seg_end != -1 else None] lat_raw = "" lon_raw = "" alt_raw = "" # 逐行提取目标字段 for line in simvar_seg.splitlines(): line = line.strip() if line.startswith("Latitude="): lat_raw = line.split("=", 1)[1] elif line.startswith("Longitude="): lon_raw = line.split("=", 1)[1] elif line.startswith("Altitude="): alt_raw = line.split("=", 1)[1] # DMS格式转十进制度通用函数 def dms_to_dd(dms_text): # 正则提取方向、度、分、秒,自动兼容符号间的多空格情况 match_result = re.match(r"([NSEW])(\d+)°\s*(\d+)'\s*([\d.]+)\"", dms_text.strip()) if not match_result: raise ValueError(f"DMS格式不符合预期,解析失败: {dms_text}") direction, deg, minute, second = match_result.groups() dd_value = float(deg) + float(minute)/60 + float(second)/3600 # 南纬、西经结果取负 if direction in ("S", "W"): dd_value = -dd_value return dd_value # 最终得到可用的数值变量 latitude = dms_to_dd(lat_raw) longitude = dms_to_dd(lon_raw) altitude = float(alt_raw) # 测试打印:用你提供的示例值,会输出 纬度21.346489, 经度-157.456444, 海拔4.93 print(f"解析结果:纬度{latitude:.6f},经度{longitude:.6f},海拔{altitude}") # 后续直接用这三个变量拼接生成startup.ssc即可
注意事项
- 正则匹配已做空格兼容,度分秒符号之间的空格数量变化不会影响解析结果。
- 后续需要读取时间等其他字段时,用同样的逐行匹配逻辑在
SimVars.0段内提取即可,不要用硬编码偏移的切片方式。 - 若启动Stellarium时需要时区参数,FSX里的时间默认是UTC时间,直接传给Stellarium不需要做时区偏移。
内容的提问来源于stack exchange,提问作者Calvin
相关产品推荐
相关产品推荐

