You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python新手求助:NMEA日志坐标保存至CSV文件报错解决

解决NMEA数据CSV保存错误并实现KML导出

首先,咱们先拆解你遇到的问题:TypeError: write() argument must be str, not list 是因为你直接把列表传给了文件的write()方法,但它只接受字符串。而且你的CSV处理逻辑还有几个小疏漏:

  • 每次循环都创建空的coord_list,还在for i in message里重复执行写入,这会导致同一行数据被重复写入N次(N是该行字符数)
  • 每次写入后立刻f.close(),这会导致后续数据完全无法写入——文件已经被关闭了

接下来咱们一步步修正代码,同时实现KML导出功能:

1. 修正CSV保存逻辑

我们用Python内置的csv.writer来处理CSV写入,它会自动帮我们处理逗号分隔、字符串转义这些细节,比手动拼接字符串靠谱得多。另外用with语句管理文件,不用手动关闭,程序结束时会自动处理文件资源。

2. 实现KML导出功能

KML是基于XML的格式,对于简单的轨迹场景,我们可以用Python的xml.etree.ElementTree构建标准的KML结构,生成的文件可以直接用Google Earth或其他GIS软件打开。

完整修正代码

import serial
from pynmea import nmea
import csv
from xml.etree.ElementTree import Element, SubElement, tostring

def create_kml(coords_list):
    # 创建KML根元素,指定命名空间
    kml = Element('kml', xmlns='http://www.opengis.net/kml/2.2')
    document = SubElement(kml, 'Document')
    
    # 创建轨迹线图层
    placemark = SubElement(document, 'Placemark')
    name = SubElement(placemark, 'Name')
    name.text = 'NMEA GPS轨迹'
    line_string = SubElement(placemark, 'LineString')
    # 设置轨迹样式(可选)
    style_url = SubElement(placemark, 'styleUrl')
    style_url.text = '#blueLine'
    
    # 定义蓝色轨迹样式
    style = SubElement(document, 'Style', id='blueLine')
    line_style = SubElement(style, 'LineStyle')
    color = SubElement(line_style, 'color')
    color.text = 'ff0000ff'  # 蓝色(KML颜色格式:AARRGGBB)
    width = SubElement(line_style, 'width')
    width.text = '3'
    
    # 处理坐标:KML格式是 经度,纬度,海拔,这里忽略海拔填0
    coordinates = SubElement(line_string, 'coordinates')
    coords_text = '\n'.join([f"{lon},{lat},0" for lat, lon in coords_list])
    coordinates.text = coords_text
    
    # 转为带XML声明的字符串
    kml_str = '<?xml version="1.0" encoding="UTF-8"?>\n' + tostring(kml, encoding='unicode')
    return kml_str

try:
    # 初始化串口,直接指定波特率更简洁
    ser = serial.Serial('COM4', baudrate=4800)
    print('Waiting for data')
    
    # 存储所有坐标,用于生成KML
    all_coords = []
    
    # 用with语句管理CSV文件,自动处理关闭
    with open('coord_list.csv', 'w', newline='', encoding='utf-8') as csv_file:
        writer = csv.writer(csv_file)
        # 写入CSV表头
        writer.writerow(['Latitude', 'Longitude'])
        
        while True:
            message = ser.readline().decode().strip()
            if '$GPGGA' in message:
                print(message)
                gpgga = nmea.GPGGA()
                gpgga.parse(message)
                
                # 把NMEA的DDMM.MMMM格式转为通用的十进制DD.DDDDD格式
                # 比如5335.6665N → 53 + 35.6665/60 ≈ 53.594442°
                lat_deg = float(gpgga.latitude[:2]) + float(gpgga.latitude[2:])/60
                lon_deg = float(gpgga.longitude[:3]) + float(gpgga.longitude[3:])/60
                # 处理南北纬、东西经的正负符号
                if gpgga.lat_dir == 'S':
                    lat_deg = -lat_deg
                if gpgga.lon_dir == 'W':
                    lon_deg = -lon_deg
                
                print(f"Lat {lat_deg:.6f} Long {lon_deg:.6f}")
                
                # 写入CSV一行数据
                writer.writerow([lat_deg, lon_deg])
                # 刷新缓冲区,确保数据实时写入文件
                csv_file.flush()
                
                # 保存坐标到列表,用于后续生成KML
                all_coords.append((lat_deg, lon_deg))
                
except KeyboardInterrupt:
    print("\n程序中断,正在保存KML文件...")
    # 只有收集到坐标时才生成KML
    if all_coords:
        kml_content = create_kml(all_coords)
        with open('gps轨迹.kml', 'w', encoding='utf-8') as kml_file:
            kml_file.write(kml_content)
        print("KML文件已保存")
    finally:
        ser.close()
        print("串口已关闭")

关键改动说明:

  • CSV处理优化:

    • 用csv.writer替代手动写入,避免格式错误
    • 移除了无用的for i in message循环,避免重复写入
    • 把原始的DDMM.MMMM格式坐标转为通用的十进制格式(这是大多数GIS工具需要的格式)
  • KML实现细节:

    • 新增create_kml函数构建标准KML结构,包含轨迹样式定义
    • 在程序通过Ctrl+C中断时,自动将所有收集到的坐标写入KML文件
    • 遵循KML坐标格式要求:经度,纬度,海拔
  • 其他细节优化:

    • 串口初始化时直接指定波特率,代码更简洁
    • 处理了南北纬、东西经的符号,生成正确的正负坐标
    • 每次CSV写入后调用flush(),避免程序意外退出时丢失数据

现在运行代码,CSV文件会正常保存坐标,程序中断时还会自动生成带样式的KML轨迹文件,直接用Google Earth打开就能看到你的GPS轨迹啦。

内容的提问来源于stack exchange,提问作者fuji_doji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:47:47