示例#1
0
def read_logger_file(file, verbose=False):

    # init gps container
    gps = gps_data()

    if isinstance(file, list):

        for f in file:
            gps = gps + read_logger_file(f)

    else:

        print('Reads ' + file)

        gpsfile = pynmea2.NMEAFile(file)

        data = pd.DataFrame()
        for d in gpsfile:
            if verbose:
                print(d)
            time = datetime.datetime.combine(d.datestamp, d.timestamp)
            data = data.append({'lon': d.longitude, 'lat': d.latitude, 'time': time}, ignore_index=True)
        #
        gps.d = data.set_index('time')

    return gps
示例#2
0
def read_gps_alees(file, label='gps', verbose=False):

    # init gps container
    gp = gps(label=label)
    if isinstance(file, list):
        for f in file:
            gp = gp + read_gps_alees(f, verbose=verbose)
    else:
        print('Reads ' + file)
        gpsfile = pynmea2.NMEAFile(file)
        data = pd.DataFrame()
        for d in gpsfile:
            if verbose:
                print(d)
            if all([d.datestamp, d.timestamp]):
                time = datetime.datetime.combine(d.datestamp, d.timestamp)
                data = data.append({'lon': d.longitude,
                                    'lat': d.latitude,
                                    'time': time
                                    },
                                    ignore_index=True)
        #
        gp.d = data.set_index('time')

    return gp
示例#3
0
def test_file():
    nmeafile = pynmea2.NMEAFile(StringIO(TEST_DATA))

    nmea_strings = nmeafile.read()
    assert len(nmea_strings) == 10
    assert all([isinstance(s, pynmea2.NMEASentence) for s in nmea_strings])
    del nmeafile

    with pynmea2.NMEAFile(StringIO(TEST_DATA)) as _f:
        nmea_strings = [_f.readline() for i in range(10)]
    assert len(nmea_strings) == 10
    assert all([isinstance(s, pynmea2.NMEASentence) for s in nmea_strings])

    with pynmea2.NMEAFile(StringIO(TEST_DATA)) as _f:
        nmea_strings = [s for s in _f]
    assert len(nmea_strings) == 10
    assert all([isinstance(s, pynmea2.NMEASentence) for s in nmea_strings])

    with pynmea2.NMEAFile(StringIO(TEST_DATA)) as _f:
        nmea_strings = [_f.next() for i in range(10)]
    assert len(nmea_strings) == 10
    assert all([isinstance(s, pynmea2.NMEASentence) for s in nmea_strings])
示例#4
0
def load_nmea(file: Path,
              in_cols: Optional[Sequence[str]] = None) -> pd.DataFrame:
    """
    NMEA to DataFrame convertor
    :param file: NMEA file Path
    :param in_cols: attributes to search in pynmea2 NMEASentences (corresponded to needed data in NMEA strings)
    :return: pandas DataFrame with in_cols columns (except columns for which no data found) with 'datetime' index
    """
    if in_cols is None:
        search_fields = (
            'latitude', 'longitude', 'spd_over_grnd', 'true_course',
            'depth_meters'
        )  # not includes index. Also Magnetic Variation ('mag_variation') may be useful for ADCP proc
        index = 'datetime'  # todo: also try 'timestamp' if 'datetime' not found, will requre to add date
    else:
        index, *search_fields = in_cols
    rows = []
    d = {}
    b_have_time = False
    with pynmea2.NMEAFile(file.open(mode='r')) as _f:
        while True:  # to continue on error
            try:
                for nmea_sentence in _f:  # best method because with _f.readline() need to check for EOF, nmea_sentences = _f.read() fails when tries to read all at once
                    try:
                        t = getattr(nmea_sentence, index)
                        if b_have_time:
                            rows.append(d)
                            d = {index: t}  # new time row begin
                        else:
                            d[index] = t
                            b_have_time = True
                    except AttributeError:
                        pass

                    for f in search_fields:  # all except index
                        try:
                            d[f] = getattr(nmea_sentence, f)
                        except AttributeError:
                            continue

            except pynmea2.ParseError:
                continue
            break
    if not rows:  # from_records() gets strange output on empty input so we force returning empty dataframe:
        return pd.DataFrame()
    df = pd.DataFrame.from_records(rows, index=[index], coerce_float=True)
    # arg columns=search_fields not works, coerce_float is needed because eliminates objects that we can not write to HDF5
    return df
def read(filename):
    records = []        #解析列表
    gga_sumcount = 0    #gga语句总统计值
    gga_validcount = 0  #gga有效语句统计值(固定且差分延迟小于20秒)
    hgts = []           #高程值列表
    hgt_sum = 0.0       #高程累加值
    hgt_min = 0.0       #高程最小值
    hgt_max = 0.0       #高程最大值
    hgt_ud2cm_count = 0 #±2cm数据条数
    hgt_ud1cm_count = 0 #±1cm数据条数

    print('Parse file path:',filename)
    start_time = time.time()
    
    with pynmea2.NMEAFile(filename) as nmea_file:
        for record in nmea_file:
            records.append(record)
            if(record.sentence_type == 'GGA'):#统计GGA语句条数
                gga_sumcount += 1
                if((record.gps_qual == 4) and (float(record.age_gps_data) < 20)):#固定解且差分延迟小于20秒,累加高程值
                    hgts.append(float(record.altitude))#将固定解高程值添加至列表
                    hgt_sum += float(record.altitude)
                    gga_validcount += 1
                   
    end_time = time.time()
    print('Parse used time:%.2f(s)' % (end_time - start_time))
    
    print('1.Total counts of records:', len(records))

    print('2.GGA total counts: %d, fixed counts: %d, fixed percent:%.2f(%%)' % (gga_sumcount, gga_validcount, (gga_validcount / gga_sumcount)*100 ))

    if gga_validcount != 0:
        hgt_avg = hgt_sum / gga_validcount
        print('3.Hgt average:%.4f(m),' % hgt_avg, end = ' ')
        detla_1cm = 0.01
        detla_2cm = 0.02
        for i in range(len(hgts)):
            if (hgts[i] <= hgt_avg + detla_2cm) and (hgts[i] >= hgt_avg - detla_2cm):
                hgt_ud2cm_count += 1
            if (hgts[i] <= hgt_avg + detla_1cm) and (hgts[i] >= hgt_avg - detla_1cm):
                hgt_ud1cm_count += 1  
    else:
        print('3.Hgt average:Invalid,' , end = ' ')

    if len(hgts) != 0:
        print('range ±2cm percent:%.2f(%%), range ±1cm percent:%.2f(%%), max-min:%.4f(m)' % ((hgt_ud2cm_count / len(hgts)) * 100, (hgt_ud1cm_count / len(hgts)) * 100, max(hgts) - min(hgts)))
    else:
        print('range ±2cm percent:Invalid, range ±1cm percent:Invalid, max-min:Invalid')
示例#6
0
def read_gps_lops(file, label='gps', verbose=False):

    # init gps container
    gp = gps(label=label)
    if isinstance(file, list):
        for f in file:
            gp = gp + read_gps_lops(f, verbose=verbose)
    else:
        print('Reads ' + file)
        gpsfile = pynmea2.NMEAFile(file)
        data = pd.DataFrame()
        t = None
        for s in gpsfile:
            if verbose:
                print(s)
            if len(s.fields)>0 and hasattr(s, 'is_valid') and s.is_valid:
                d = parse_nmea_sentence(s, t=t)
                data = data.append(d, ignore_index=True)
                t = d['time']
        #
        gp.d = data.set_index('time')

    return gp
示例#7
0
def load_nmea(file, cfg):
    with pynmea2.NMEAFile(file) as _f:
        nmea_sentences = _f.read()
        #nmea_strings = [_f.readline() for i in range(10)]
        #msg = pynmea2.ptarse('$SDDBT,665.4,f,202.8,M,110.9,F*06')
    return nmea_sentences
示例#8
0
def read(filename):
    records = []  #解析列表
    gga_sumcount = 0  #gga语句总统计值
    gga_validcount = 0  #gga有效语句统计值(固定且差分延迟小于20秒)
    hgts = []  #高程值列表
    hgt_sum = 0.0  #高程累加值
    hgt_min = 0.0  #高程最小值
    hgt_max = 0.0  #高程最大值
    hgt_ud2cm_count = 0  #±2cm数据条数
    hgt_ud1cm_count = 0  #±1cm数据条数
    lat_list = []  #lat列表(有效数据)
    lon_list = []  #lon列表(有效数据)

    print('Parse file path:', filename)
    start_time = time.time()

    #使用上下文解析nmea文本数据
    with pynmea2.NMEAFile(filename) as nmea_file:
        for record in nmea_file:
            records.append(record)
            if (record.sentence_type == 'GGA'):  #统计GGA语句条数
                gga_sumcount += 1
                if ((record.gps_qual == 4) and
                    (float(record.age_gps_data) < 20)):  #固定解且差分延迟小于20秒,累加高程值
                    hgts.append(float(record.altitude))  #将固定解高程值添加至列表
                    lon_list.append(record.longitude)  #将固定解经度值添加至列表
                    lat_list.append(record.latitude)  #将固定解纬度值添加至列表
                    hgt_sum += float(record.altitude)
                    gga_validcount += 1

    end_time = time.time()
    print('Parse used time:%.2f(s)' % (end_time - start_time))

    print('1.Total counts of records:', len(records))

    print('2.GGA total counts: %d, fixed counts: %d, fixed percent:%.2f(%%)' %
          (gga_sumcount, gga_validcount,
           (gga_validcount / gga_sumcount) * 100))

    if gga_validcount != 0:
        hgt_avg = hgt_sum / gga_validcount
        print('3.Hgt average:%.4f(m),' % hgt_avg, end=' ')
        detla_1cm = 0.01
        detla_2cm = 0.02
        for i in range(len(hgts)):
            if (hgts[i] <= hgt_avg + detla_2cm) and (hgts[i] >=
                                                     hgt_avg - detla_2cm):
                hgt_ud2cm_count += 1
            if (hgts[i] <= hgt_avg + detla_1cm) and (hgts[i] >=
                                                     hgt_avg - detla_1cm):
                hgt_ud1cm_count += 1
    else:
        print('3.Hgt average:Invalid,', end=' ')

    if len(hgts) != 0:
        print(
            'range ±2cm percent:%.2f(%%), range ±1cm percent:%.2f(%%), max-min:%.4f(m)'
            % ((hgt_ud2cm_count / len(hgts)) * 100,
               (hgt_ud1cm_count / len(hgts)) * 100, max(hgts) - min(hgts)))
    else:
        print(
            'range ±2cm percent:Invalid, range ±1cm percent:Invalid, max-min:Invalid'
        )
    '''
    绘制高程值趋势图(实际变化值/平均值/平均值+2cm/平均值-2cm四条曲线)
    '''
    if (gga_validcount != 0) and (len(hgts) != 0):
        print('4.Draw plot')
        hgt_avg_list = []
        hgt_u2cm_list = []
        hgt_d2cm_list = []
        for i in range(len(hgts)):
            hgt_avg_list.append(hgt_avg)
            hgt_u2cm_list.append(hgt_avg + detla_2cm)
            hgt_d2cm_list.append(hgt_avg - detla_2cm)

        avg_y = hgt_avg_list
        u2cm_y = hgt_u2cm_list
        d2cm_y = hgt_d2cm_list

        #WGS84经纬度转米勒投影XY坐标系
        miller_x = []
        miller_y = []
        for i in range(len(lon_list)):
            millerToXY(lon_list[i], lat_list[i])  #经纬度转换为米勒投影坐标xy
            miller_x.append(xy_coordinate[i][0])  #x
            miller_y.append(xy_coordinate[i][1])  #y

        #WGS84经纬度转CGCS2000坐标系
        '''
        Beijing 1954 / Gauss-Kruger CM 117E
        EPSG:21460 with transformation: 15921
        Area of use: China - onshore between 114°E and 120°E
        '''
        cgcs2000_x = []
        cgcs2000_y = []
        transformer = Transformer.from_crs(
            'epsg:4326', 'epsg:4479'
        )  #WGS84转CGCS2000坐标系(epsg:4326为WGS84坐标系编号,epsg:4479为CGCS2000坐标系编号)
        for i in range(len(lon_list)):
            cgc_x, cgc_y, cgc_z = transformer.transform(
                lat_list[i], lon_list[i], hgts[i])
            cgcs2000_xy.append((cgc_x, cgc_y, cgc_z))  #形成多个元组坐标组成的列表
            cgcs2000_x.append(cgc_x)
            cgcs2000_y.append(cgc_y)


#        print('cgcs2000:',cgcs2000_xy) #打印转换后的cgcs2000坐标点集

        x = range(0, len(hgts))
        hgt_y = hgts
        plt.figure(num=1)

        plt.subplot(311)  #3行1列 第1行
        plt.title('Position Chart')
        plt.plot(x, miller_x, label='E-W(m)', linestyle=':')  #绘制longitude实际值趋势
        plt.xlabel('X-Points')
        plt.ylabel('Y')
        plt.grid()
        plt.legend()

        plt.subplot(312)  #3行1列 第2行
        plt.plot(x, miller_y, label='N-S(m)', linestyle=':')  #绘制latitude实际值趋势
        plt.xlabel('X-Points')
        plt.ylabel('Y')
        plt.grid()
        plt.legend()

        plt.subplot(313)  #3行1列 第3行
        plt.plot(x, hgt_y, label='rt hgt', linestyle=':')  #绘制实际值趋势
        plt.plot(x, avg_y, label='avg hgt')  #绘制平均值直线
        plt.plot(x, u2cm_y, label='avg+2cm hgt')  #绘制平均值+2cm直线
        plt.plot(x, d2cm_y, label='avg-2cm hgt')  #绘制平均值-2cm直线
        plt.xlabel('X-Points')
        plt.ylabel('Y-Height(m)')
        plt.grid()
        plt.legend()

        plt.figure(num=2)
        plt.plot(lon_list, lat_list, linestyle=':')  #绘制经纬度分布图
        plt.xlabel('X-Longitude')
        plt.ylabel('Y-Latitude')
        plt.title('Lon-Lat Chart')
        plt.grid()

        plt.figure(num=3)
        plt.plot(miller_x, miller_y, linestyle=':')  #绘制米勒投影XY分布图
        plt.xlabel('X(m)')
        plt.ylabel('Y(m)')
        plt.title('Miller_XY Chart')
        plt.grid()

        plt.figure(num=4)
        plt.plot(cgcs2000_x, cgcs2000_y, linestyle=':')  #绘制CGCS2000坐标系XY分布图
        plt.xlabel('X(m)')
        plt.ylabel('Y(m)')
        plt.title('CGCS2000_XY Chart')
        plt.grid()

        plt.show()
    else:
        print('4.Data invalid,do not draw plot')
示例#9
0
def read(filename):
    records = []  #解析列表
    gga_count = [0, 0, 0, 0, 0, 0]  #GGA总数/固定解点数/浮动解点数/差分解点数/单点解点数/未定位点数
    hgts = []  #高程值列表
    hgt_sum = 0.0  #高程累加值
    hgt_min = 0.0  #高程最小值
    hgt_max = 0.0  #高程最大值
    hgt_ud2cm_count = 0  #±2cm数据条数
    hgt_ud1cm_count = 0  #±1cm数据条数
    lat_list = []  #lat列表(有效数据)
    lon_list = []  #lon列表(有效数据)
    sv_list = []  #可用卫星颗数(有效数据)
    diff_delay_list = []  #差分延迟列表(有效数据)

    print('Parse file path:', filename)
    start_time = time.time()

    #使用上下文解析nmea文本数据
    with pynmea2.NMEAFile(filename) as nmea_file:
        for record in nmea_file:
            records.append(record)
            if (record.sentence_type == 'GGA'):  #统计GGA语句条数
                gga_count[0] += 1
                if (record.gps_qual == 4):
                    #if(float(record.age_gps_data) < 20)): #差分延迟小于20秒,累加高程值
                    hgts.append(float(record.altitude))  #将固定解高程值添加至列表
                    lon_list.append(record.longitude)  #将固定解经度值添加至列表
                    lat_list.append(record.latitude)  #将固定解纬度值添加至列表
                    sv_list.append(int(record.num_sats))  #将固定解可用卫星颗数添加至列表
                    diff_delay_list.append(float(
                        record.age_gps_data))  #将固定解差分延迟添加至列表
                    hgt_sum += float(record.altitude)
                    gga_count[1] += 1
                elif (record.gps_qual == 5):  #浮动解
                    gga_count[2] += 1
                elif (record.gps_qual == 2):  #差分解
                    gga_count[3] += 1
                elif (record.gps_qual == 1):  #单点解
                    gga_count[4] += 1
                else:  #未定位
                    gga_count[5] += 1

    end_time = time.time()
    print('Parse used time:%.2f(s)' % (end_time - start_time))

    print('1.Total counts of records:', len(records))

    if gga_count[0] != 0:
        print(
            '2.GGA total counts:%d, Fixed:%d(%.2f%%), Float:%d(%.2f%%), DGPS:%d(%.2f%%), Single:%d(%.2f%%), NoPos:%d(%.2f%%)'
            % (gga_count[0], gga_count[1],
               (gga_count[1] / gga_count[0]) * 100, gga_count[2],
               (gga_count[2] / gga_count[0]) * 100, gga_count[3],
               (gga_count[3] / gga_count[0]) * 100, gga_count[4],
               (gga_count[4] / gga_count[0]) * 100, gga_count[5],
               (gga_count[5] / gga_count[0]) * 100))
    else:
        print('2.Not parsed any GGA sentence')

    if gga_count[1] != 0:
        hgt_avg = hgt_sum / gga_count[1]
        print('3.Hgt average:%.4f(m),' % hgt_avg, end=' ')
        detla_1cm = 0.01
        detla_2cm = 0.02
        for i in range(len(hgts)):
            if (hgts[i] <= hgt_avg + detla_2cm) and (hgts[i] >=
                                                     hgt_avg - detla_2cm):
                hgt_ud2cm_count += 1
            if (hgts[i] <= hgt_avg + detla_1cm) and (hgts[i] >=
                                                     hgt_avg - detla_1cm):
                hgt_ud1cm_count += 1

        print(
            'range ±2cm percent:%.2f(%%), range ±1cm percent:%.2f(%%), max-min:%.4f(m)'
            % ((hgt_ud2cm_count / len(hgts)) * 100,
               (hgt_ud1cm_count / len(hgts)) * 100, max(hgts) - min(hgts)))
    else:
        print('3.Hgt average:Invalid,', end=' ')
        print(
            'range ±2cm percent:Invalid, range ±1cm percent:Invalid, max-min:Invalid'
        )
    '''
    绘制高程值趋势图(实际变化值/平均值/平均值+2cm/平均值-2cm四条曲线)
    '''
    if gga_count[1] != 0:
        print('4.Draw plot')
        hgt_avg_list = []
        hgt_u2cm_list = []
        hgt_d2cm_list = []
        for i in range(len(hgts)):
            hgt_avg_list.append(hgt_avg)
            hgt_u2cm_list.append(hgt_avg + detla_2cm)
            hgt_d2cm_list.append(hgt_avg - detla_2cm)

        avg_y = hgt_avg_list
        u2cm_y = hgt_u2cm_list
        d2cm_y = hgt_d2cm_list

        #WGS84经纬度转米勒投影XY坐标系
        miller_x = []
        miller_y = []
        for i in range(len(lon_list)):
            millerToXY(lon_list[i], lat_list[i])  #经纬度转换为米勒投影坐标xy
            miller_x.append(xy_coordinate[i][0])  #x
            miller_y.append(xy_coordinate[i][1])  #y

        #WGS84经纬度转CGCS2000坐标系
        '''
        Beijing 1954 / Gauss-Kruger CM 117E
        EPSG:21460 with transformation: 15921
        Area of use: China - onshore between 114°E and 120°E
        '''
        cgcs2000_x = []
        cgcs2000_y = []
        transformer = Transformer.from_crs(
            'epsg:4326', 'epsg:4479'
        )  #WGS84转CGCS2000坐标系(epsg:4326为WGS84坐标系编号,epsg:4479为CGCS2000坐标系编号)
        for i in range(len(lon_list)):
            cgc_x, cgc_y, cgc_z = transformer.transform(
                lat_list[i], lon_list[i], hgts[i])
            cgcs2000_xy.append((cgc_x, cgc_y, cgc_z))  #形成多个元组坐标组成的列表
            cgcs2000_x.append(cgc_x)
            cgcs2000_y.append(cgc_y)


#        print('cgcs2000:',cgcs2000_xy) #打印转换后的cgcs2000坐标点集

        x = range(0, len(hgts))
        hgt_y = hgts

        print('gga_count', gga_count)

        GGAPercentN = 5

        percent = [0 for i in range(GGAPercentN)]

        percent[0] = gga_count[1] / gga_count[0]
        percent[1] = gga_count[2] / gga_count[0]
        percent[2] = gga_count[3] / gga_count[0]
        percent[3] = gga_count[4] / gga_count[0]
        percent[4] = gga_count[5] / gga_count[0]

        #print('GGAPercentN',GGAPercentN)

        #绘制解状态占比及Avg±2cm Avg±1cm占比条形图
        fig = plt.figure(num=0)
        #fig.subplots_adjust(bottom=0.025, left=0.025, top = 0.975, right=0.975)
        fig.subplots_adjust(bottom=0.1, left=0.025, top=0.975, right=0.975)
        plt.title('Summary Chart')

        plt.subplot(211)  #1行2列 第1列
        X1 = np.arange(GGAPercentN)
        Y1 = percent * np.ones(GGAPercentN)

        #plt.axes([0.025,0.025,0.95,0.95]) #设置坐标轴
        plt.bar(X1,
                Y1,
                width=0.5,
                facecolor='#9999ff',
                edgecolor='black',
                label='Solution Percent')  #绘制条形码
        plt.legend(loc='upper right')

        solution_text = [
            'Fix(4)', 'Float(5)', 'DGPS(2)', 'Single(1)', 'NoPos(0)'
        ]

        for x1, y1 in zip(X1, Y1):
            plt.text(x1,
                     y1 + 0.1,
                     '%.2f(%%)' % float(y1 * 100.00),
                     ha='center',
                     va='top')  #在对应条形码上方放置条形码数值

        for i in range(GGAPercentN):
            plt.text(i, -0.15, solution_text[i], ha='center',
                     va='bottom')  #在对应条形码下方放置类型

        # 设置横纵坐标上下限及记号
        #plt.xlim(-.5,GGAPercentN), plt.xticks([])
        plt.ylim(-.2, +1.15), plt.yticks([])
        plt.xticks([]), plt.yticks([])

        plt.subplot(212)  #1行2列 第2列

        HgtPercentN = 2

        hgtpercent = [0 for i in range(HgtPercentN)]

        hgtpercent[0] = hgt_ud2cm_count / len(hgts)
        hgtpercent[1] = hgt_ud1cm_count / len(hgts)

        X2 = np.arange(HgtPercentN)
        Y2 = hgtpercent * np.ones(HgtPercentN)

        # plt.axes([0.025,0.025,0.95,0.95]) #设置坐标轴
        plt.bar(X2,
                Y2,
                width=0.3,
                facecolor='#ff9999',
                edgecolor='black',
                label='Avg Percent')  #绘制条形码
        plt.legend(loc='upper right')

        range_text = ['Avg±2cm', 'Avg±1cm']

        for x2, y2 in zip(X2, Y2):
            plt.text(x2,
                     y2 + 0.1,
                     '%.2f(%%)' % float(y2 * 100.00),
                     ha='center',
                     va='top')  #在对应条形码上方放置条形码数值

        for i in range(HgtPercentN):
            plt.text(i, -0.15, range_text[i], ha='center',
                     va='bottom')  #在对应条形码下方放置类型

        # 设置横纵坐标上下限及记号
        #plt.xlim(-.5,HgtPercentN), plt.xticks([])
        plt.ylim(-.2, +1.15), plt.yticks([])
        plt.xticks([]), plt.yticks([])

        plt.figure(num=1)
        plt.subplot(211)  #2行1列 第1行
        plt.title('Position Chart')
        plt.plot(x,
                 miller_x,
                 linewidth=1.0,
                 color="blue",
                 label='E-W(m)',
                 linestyle=':')  #绘制longitude实际值趋势
        plt.xlabel('Points')
        plt.ylabel('Longitude')
        plt.grid()
        plt.legend()

        plt.subplot(212)  #2行1列 第2行
        plt.plot(x,
                 miller_y,
                 linewidth=1.0,
                 color="red",
                 label='N-S(m)',
                 linestyle=':')  #绘制latitude实际值趋势
        plt.xlabel('Points')
        plt.ylabel('Latitude')
        plt.grid()
        plt.legend()

        plt.figure(num=2)
        plt.title('Height Chart')
        plt.plot(x,
                 hgt_y,
                 linewidth=1.0,
                 color="blue",
                 label='rt hgt',
                 linestyle=':')  #绘制实际值趋势
        plt.plot(x, avg_y, linewidth=1.0, color="green",
                 label='avg hgt')  #绘制平均值直线
        plt.plot(x, u2cm_y, linewidth=1.0, color="red",
                 label='avg+2cm hgt')  #绘制平均值+2cm直线
        plt.plot(x,
                 d2cm_y,
                 linewidth=1.0,
                 color="magenta",
                 label='avg-2cm hgt')  #绘制平均值-2cm直线
        plt.xlabel('Points')
        plt.ylabel('Height(m)')
        plt.grid()
        plt.legend()

        plt.figure(num=3)
        plt.plot(x, sv_list, linewidth=1.0, color="green",
                 linestyle='-')  #绘制可用卫星颗数分布图
        plt.xlabel('Points')
        plt.ylabel('SV')
        plt.title('Satellite In Used Chart')
        plt.grid()

        plt.figure(num=4)
        plt.plot(x, diff_delay_list, linewidth=1.0, color="red",
                 linestyle='-')  #绘制差分延迟分布图
        plt.xlabel('Points')
        plt.ylabel('Diff Age(s)')
        plt.title('Diff Age Chart')
        plt.grid()

        plt.figure(num=5)
        plt.plot(lon_list, lat_list, linewidth=1.0, linestyle=':')  #绘制经纬度分布图
        plt.xlabel('Longitude')
        plt.ylabel('Latitude')
        plt.xticks(rotation='45')  #x轴标签旋转45度
        plt.title('Lon-Lat Chart')
        plt.grid()

        plt.figure(num=6)
        plt.plot(miller_x, miller_y, linewidth=1.0,
                 linestyle=':')  #绘制米勒投影XY分布图
        plt.xlabel('Miller-X(m)')
        plt.ylabel('Miller-Y(m)')
        plt.title('Miller_XY Chart')
        plt.grid()

        plt.figure(num=7)
        plt.plot(cgcs2000_x, cgcs2000_y, linewidth=1.0,
                 linestyle=':')  #绘制CGCS2000坐标系XY分布图
        plt.xlabel('CGCS2000-X(m)')
        plt.ylabel('CGCS2000-Y(m)')
        plt.title('CGCS2000_XY Chart')
        plt.grid()

        plt.show()
    else:
        print('4.Data invalid,do not draw plot')
示例#10
0
#使用pynmea2库对nmea数据文件进行解析,然后打印每一条数据.
'''
参考网址:http://gnss.help/2018/03/01/pynmea2-readme/index.html

1.安装pynmea2模块
    pip install pynmea2
2.导入pynmea2
    import pynmea2
3.使用NMEAFile()解析文件

修改文件目录('H:/python study/gps_line.txt')即可解析不同NMEA文件
'''

import pynmea2

records = []

nmeafilepath = 'H:/python study/gps_line.txt'

with pynmea2.NMEAFile(nmeafilepath) as nmea_file:
    for record in nmea_file:
        records.append(record)

print('Parse nmea file path:', nmeafilepath)

print('Count of records:', len(records))

for i in range(len(records)):
    print('\n%d nmea sentence:' % i)
    print(repr(records[i]))
def read(filename):
    records = []  #解析列表
    gga_sumcount = 0  #gga语句总统计值
    gga_validcount = 0  #gga有效语句统计值(固定且差分延迟小于20秒)
    hgts = []  #高程值列表
    hgt_sum = 0.0  #高程累加值
    hgt_min = 0.0  #高程最小值
    hgt_max = 0.0  #高程最大值
    hgt_ud2cm_count = 0  #±2cm数据条数
    hgt_ud1cm_count = 0  #±1cm数据条数
    lat_list = []  #lat列表(有效数据)
    lon_list = []  #lon列表(有效数据)

    print('Parse file path:', filename)
    start_time = time.time()

    #使用上下文解析nmea文本数据
    with pynmea2.NMEAFile(filename) as nmea_file:
        for record in nmea_file:
            records.append(record)
            if (record.sentence_type == 'GGA'):  #统计GGA语句条数
                gga_sumcount += 1
                if ((record.gps_qual == 4) and
                    (float(record.age_gps_data) < 20)):  #固定解且差分延迟小于20秒,累加高程值
                    hgts.append(float(record.altitude))  #将固定解高程值添加至列表
                    lon_list.append(record.longitude)  #将固定解经度值添加至列表
                    lat_list.append(record.latitude)  #将固定解纬度值添加至列表
                    hgt_sum += float(record.altitude)
                    gga_validcount += 1

    end_time = time.time()
    print('Parse used time:%.2f(s)' % (end_time - start_time))

    print('1.Total counts of records:', len(records))

    print('2.GGA total counts: %d, fixed counts: %d, fixed percent:%.2f(%%)' %
          (gga_sumcount, gga_validcount,
           (gga_validcount / gga_sumcount) * 100))

    if gga_validcount != 0:
        hgt_avg = hgt_sum / gga_validcount
        print('3.Hgt average:%.4f(m),' % hgt_avg, end=' ')
        detla_1cm = 0.01
        detla_2cm = 0.02
        for i in range(len(hgts)):
            if (hgts[i] <= hgt_avg + detla_2cm) and (hgts[i] >=
                                                     hgt_avg - detla_2cm):
                hgt_ud2cm_count += 1
            if (hgts[i] <= hgt_avg + detla_1cm) and (hgts[i] >=
                                                     hgt_avg - detla_1cm):
                hgt_ud1cm_count += 1
    else:
        print('3.Hgt average:Invalid,', end=' ')

    if len(hgts) != 0:
        print(
            'range ±2cm percent:%.2f(%%), range ±1cm percent:%.2f(%%), max-min:%.4f(m)'
            % ((hgt_ud2cm_count / len(hgts)) * 100,
               (hgt_ud1cm_count / len(hgts)) * 100, max(hgts) - min(hgts)))
    else:
        print(
            'range ±2cm percent:Invalid, range ±1cm percent:Invalid, max-min:Invalid'
        )
    '''
    绘制高程值趋势图(实际变化值/平均值/平均值+2cm/平均值-2cm四条曲线)
    '''
    if (gga_validcount != 0) and (len(hgts) != 0):
        print('4.Draw plot')
        hgt_avg_list = []
        hgt_u2cm_list = []
        hgt_d2cm_list = []
        for i in range(len(hgts)):
            hgt_avg_list.append(hgt_avg)
            hgt_u2cm_list.append(hgt_avg + detla_2cm)
            hgt_d2cm_list.append(hgt_avg - detla_2cm)

        avg_y = hgt_avg_list
        u2cm_y = hgt_u2cm_list
        d2cm_y = hgt_d2cm_list

        miller_x = []
        miller_y = []
        for i in range(len(lon_list)):
            millerToXY(lon_list[i], lat_list[i])  #经纬度转换为米勒投影坐标xy
            miller_x.append(xy_coordinate[i][0])  #x
            miller_y.append(xy_coordinate[i][1])  #y

        x = range(0, len(hgts))
        hgt_y = hgts
        plt.figure(num=1)
        plt.plot(x, hgt_y)  #绘制实际值趋势
        plt.plot(x, avg_y)  #绘制平均值直线
        plt.plot(x, u2cm_y)  #绘制平均值+2cm直线
        plt.plot(x, d2cm_y)  #绘制平均值-2cm直线
        plt.figure(num=2)
        plt.plot(lon_list, lat_list)  #绘制经纬度分布图
        plt.figure(num=3)
        plt.plot(miller_x, miller_y)  #绘制XY分布图
        plt.show()
    else:
        print('4.Data invalid,do not draw plot')
示例#12
0
def dump_file(filename):
    with pynmea2.NMEAFile(filename) as file:
        for msg in file:
            print("%r\n" % msg)