基于python的gps数据解析

基于python的gps数据解析

gps从卫星接收信号后将其转出成一定格式的数据,按照这种格式写入到内存中特定的txt文本中。
其中有以下几种格式:

data="$GPGGA,121253.000,3937.3090,N,11611.6057,E,1,06,1.2,44.6,M,-5.7,M,0000*72’

data="$GPGSV,3,3,10,29,07,074,30,07,163,28*7D "

data= “223610,13,04,05,00,29,25,26,00,29,39,36,25,22,22,26,00,23,33,25,31,00,39,30,00,00”

分别对应

  1. ‘UTC时间’,‘定位状态’,‘纬度’,‘纬度半球’,‘经度’,‘经度半球’,‘地面速率’,‘地面航向’, ‘UTC日期’,‘磁偏角’,‘磁偏角方向’

2.GSV语句总数’,‘GSV编号’,‘可见卫星’,‘卫星编号’,‘卫星仰角’,‘卫星方位角’,‘信噪比’,‘卫星编号’,‘卫星仰角’,‘卫星方位角’,‘信噪比’,‘卫星编号’,‘卫星仰角’,‘卫星方位角’,‘信噪比’,‘卫星编号’,‘卫星仰角’,‘卫星方位角’,‘信噪比’
3.时间,卫星总数,每个卫星数量,卫星信号强度

若解析以上格式的信号,可以说比较简单:

  1. python file = open(“test.txt”, “r”) 打开文本,按照每一行进行遍历
GPS = open(r"./GPS.txt", "r")  # 只读方式打开
print("open", GPS_RAW.name, "successful!")
_head = "$GNGGA"
_head2 = "$GPGSV"
#cnt=0
# 文件写入到txt
res_file = open("result.txt", "w+")  # 追加存入txt
for line in GPS_RAW.readlines():
    line = line.strip()
  1. 用分隔符函数 line.split(",")进行分割开,存入列表
 l = line.split(",")
  1. 取列表的每一行第一个元素进行头字符匹配判定解析的是哪一行
 _head2 == line[0:6]

数据解析

这里着重说一下数据解析遇到的问题:

  • 转化utc时间要每个小时加8,但要防止超过24小时,所以只需要time=(T+8)%24
  • 经纬度转化根据公式转化。(问度娘)
  • 最重要的是解析对于代码稳定性和兼容性是一个挑战。分别有以下几种情况:
    1.对于解析的数据,上述data3这种数据,没有帧头,只能按固定行查找,但是有时候会出现gps信号弱,不解析,偶尔这一行不存在,导致下面串行。(解决办法见代码)
    2.数据中间突然乱码导致数据转化出错,程序终止
    3.某个地方没有信号,导致出现空行,导致程序出错
    4.出现重复的两行,然后按行查找出现错位
    以上都是需要去解决的
    实际遇到很多问题,但最终都解决了,目前已打包exe,可自动解析文本转化成excle表格(带表头哦)
    下面贴出代码:
    本程序用到python的csv模块 openpyxl
import string
import csv
GPS_RAW = open(r"./GPS_RAW.txt", "r")  # 只读方式打开
print("open", GPS_RAW.name, "successful!")
_head = "$GNGGA"
_head2 = "$GPGSV"
flag = False
#cnt=0
# 文件写入到txt
res_file = open("result.txt", "w+")  # 追加存入txt
for line in GPS.readlines():
    line = line.strip()
    l = line.split(",")
   # print(line[0:6])
    if((line[0:3].isdigit() or _head2 == line[0:6]) and len(l)>9):
        if(_head2 == line[0:6]):
            SUM = int(l[2])+int(l[3])+int(l[4])
            Best = l[4:]
            Best.sort(reverse=True)
            if(flag == True):
                Effect_data2 = str(SUM)+';'+str(l[2])+';'+str(l[3])+';'+str(l[4])+';'+str(
                Best[0])+';'+str(Best[1])+';'+str(Best[2])+';'+str(Best[3])+'\n'  # 格式转化 方便处理
                res_file.write(Effect_data2)
                flag = False
            else:
                Effect_data2 ="0"
            print(Effect_data2)
        else:
            SUM = int(l[1])+int(l[2])+int(l[3])
            Best = l[3:]
            Best.sort(reverse=True)
            if(flag == True):
                Effect_data2 = str(SUM)+';'+str(l[1])+';'+str(l[2])+';'+str(l[3])+';'+str(
                Best[0])+';'+str(Best[1])+';'+str(Best[2])+';'+str(Best[3])+'\n'  # 格式转化 方便处理
                res_file.write(Effect_data2)
                flag = False
            else:
                Effect_data2 ="0"
            print(Effect_data2)
    if _head == line[0:6]:  # 帧头匹配成功
        str_temp = line  # 将要用到的串
        Data_result = str_temp.split(",")  # 串转化列表,便于操作

        ##分离数据##
        _time = Data_result[1]  # 时间
        str1=Data_result[2]
        if(str1[:2].isdigit() and len(Data_result)==15):
            _latitude = float(Data_result[2])  # 纬度
            _longitude = float(Data_result[4])  # 经度
            _Clock = int(_time[0:2])
            _Minute = _time[2:4]
            _Second = _time[4:6]
            flag_1=False
        else:
            _latitude=0
            _longitude=0
            _Clock = 0
            _Minute = "0"
            _Second = "0"
            flag_1=True

     #************分离时,分,秒*********#    
        # print(_Clock)
        # print(_Minute)
        # print(_Second)                              #测试
        _Clock = _Clock+8  # UTC时间转化
        if(_Clock >= 24):
            _Clock = _Clock % 24  # 防止超过24
        _Clock = str(_Clock)
        Effect_time = _Clock+':'+_Minute+':'+_Second  # 最终获得时间
        Effect_latitude = int(_latitude/100)+((_latitude % 100)/60)  # 最终获得纬度
        Effect_longitude = int(_longitude/100)+((_longitude % 100)/60)  # 最终获经度
        Effect_data1 = str(Effect_latitude)+';' + \
            str(Effect_longitude)+';'+Effect_time+';'
        
        if(flag == False and flag_1==False):
            res_file.write(Effect_data1)
            res_file.flush()
            flag = True
            
           
   # cnt=cnt+1
   # print(cnt)

res_file.close()

GPS_RAW.close()

with open('./result/result.csv', 'w+', newline='') as csvfile:
    spamwriter = csv.writer(csvfile, dialect='excel')
    spamwriter.writerow(["纬度", "经度", "北京时间", "总卫星数", "GPS",
                         "北斗", "格洛纳斯", "最佳卫星1", "最佳卫星2", "最佳卫星3", "最佳卫星4"])
# 读要转换的txt文件,文件每行各词间以字符分隔]
    with open('result.txt', 'r', encoding='utf-8') as filein:
        for line in filein:
            line_list = line.strip('\n').split(';')  # 我这里的数据之间是以 ; 间隔的
            if(len(line_list)>6):
                spamwriter.writerow(line_list)
    print('''
            **************************
            ##########################
            *******转换完成!!*******
            ##########################
            **************************
            ''')
input()

你可能感兴趣的:(工具,python,pycharm,编辑器)