it编程 > 编程语言 > Asp.net

C#代码实现解析WTGPS和BD数据

17人参与 2025-06-04 Asp.net

在现代的导航与定位应用中,准确解析 gps 和北斗(bd)等卫星定位数据至关重要。今天,我们来探讨如何使用 c# 语言对 wtgps+bd 数据进行解析。

一、代码结构概览

首先,我们有一个witgpsparser类,这个类主要负责解析原始的 gps 数据。它包含了一些关键的字段和方法:

using system;
using system.linq;


public class witgpsparser
{
    // 经纬度标记
    private readonly string gnzda = "gnzda";
    // 时间戳标记
    private readonly string gngga = "gngga";
    private readonly stringsplitoptions options = stringsplitoptions.removeemptyentries;
   
   // ...
}

其中,gnzda和gngga分别用于标识不同类型的 gps 数据语句,options则用于在分割字符串时去除空元素。

1. 核心解析方法

parse方法是整个解析过程的入口:

public location parse(string raw)
{
   var separator = new char[] { '\n' };
   var raws = raw.split(separator, options);

​​​​​​​   var r1 = raws.where(r => r.contains(this.gngga)).firstordefault();
   var location = this.tolocation(r1);
   
   var r2 = raws.where(r => r.contains(this.gnzda)).firstordefault();
   var date = this.todateandtimestamp(r2);
   if (location != null)
   {
       location.date = date.item1;
       location.timestamp = (double)date.item2;
   }
   
   return location;
}

它首先将输入的原始数据按行分割,然后分别查找包含gngga和gnzda的行。gngga语句通常包含位置信息,而gnzda语句包含日期和时间信息。通过调用tolocation和todateandtimestamp方法,分别解析出位置和时间信息,并将它们组装到location对象中返回。

2. 位置信息解析

tolocation方法负责从gngga语句中提取并解析位置相关信息:

private location tolocation(string raw)
{
   if (string.isnullorwhitespace(raw))
   {
       return null;
   }


   var raws = raw.split(new char[] { ',' });

   // 验证数据完整
   if (raws.length < 6 || raws.skip(1).take(5).all(r => string.isnullorwhitespace(r)))
   {
       return null;
   }


   var latitude = this.tolatitude(raws[2]);
   var longitude = this.tolongitude(raws[4]);
   var flag = int.parse($"0{raws[6]}");
   
   var numsv = 0;
   if (raws.length >= 8)
   {
       numsv = int.parse($"0{raws[7]}");
   }


   var altitude = 0.0;
   if (raws.length >= 10)
   {
       altitude = double.parse($"0{raws[9]}");
   }


   return new location
   {
       altitude = altitude,
       flag = flag,
       latitude = latitude,
       longitude = longitude,
       numsv = numsv,
   };
}

在这个方法中,首先检查输入数据是否为空或不完整。然后,通过调用tolatitude和tolongitude方法,将字符串形式的经纬度转换为实际的数值。同时,提取定位标志(flag)、卫星数量(numsv)和海拔高度(altitude)等信息,最后构建并返回location对象。

3. 经纬度转换方法

tolatitude和tolongitude方法用于将特定格式的经纬度字符串转换为实际的度数:

private double tolongitude(string l)
{
   if (string.isnullorwhitespace(l) || l.length < 8)
   {
       return 0;
   }

   var l1 = double.parse(l.substring(0, 3));
   var l2 = double.parse(l.substring(3, 5));
   return l1 + l2 / 60;
}


private double tolatitude(string l)
{
   if (string.isnullorwhitespace(l) || l.length < 9)
   {
       return 0;
   }

   var l1 = double.parse(l.substring(0, 2));
   var l2 = double.parse(l.substring(2, 7));

   return l1 + l2 / 60;
}

例如,对于经度字符串,前三位表示度数,后面五位表示分,通过特定的计算将其转换为以度为单位的数值。

4. 日期和时间戳解析

todateandtimestamp方法负责从gnzda语句中解析出日期和时间戳:

private (string, decimal) todateandtimestamp(string raw)
{
   if (string.isnullorwhitespace(raw))
   {
       return ("", 0);
   }

   var separator = new char[] { ',' };
   var date = raw.split(separator, options);
   if (date.length < 2)
   {
       return ("", 0);
   }

   var utcdate = date[1];
   if (utcdate == null || utcdate.length != 9)
   {
       return ("", 0);
   }


   var hour = utcdate.substring(0, 2);
   hour = (int.parse(hour) + 8).tostring();
   hour = this.removezero(hour);
   var minute = utcdate.substring(2, 2);
   minute = this.removezero(minute);
   var second = utcdate.substring(4, 2);
   second = this.removezero(second);
   var day = date[2];
   day = this.removezero(day);
   var month = date[3];
   month = this.removezero(month);
   var year = date[4];
   var datetime = $"{year}.{month}.{day} {hour}:{minute}";


   // 时间戳
   var datetimewithsecond = $"{datetime}:{second}";
   var timestamp = this.totimestamp(convert.todatetime(datetimewithsecond));
   return (datetime, timestamp);
}

该方法首先检查数据的完整性,然后提取出 utc 时间、日、月、年等信息。由于 gps 数据中的时间通常是 utc 时间,这里将其转换为本地时间(这里简单地加了 8 小时)。最后,构建出日期字符串和对应的时间戳。

5. 辅助方法

removezero方法用于去除字符串开头的零:

private string removezero(string s)
{
   if (s.startswith("0"))
   {
       return s.substring(1, 1);
   }

   return s;
}

totimestamp方法将datetime对象转换为时间戳:

private decimal totimestamp(datetime d)
{
   if (d.touniversaltime() <= datetimeoffset.minvalue.utcdatetime)
   {
       return 0;
   }


   var milliseconds = (decimal)(new datetimeoffset(d).tounixtimemilliseconds());
   return milliseconds / 1000.0m;
}

二、location类定义

location类用于存储解析后的位置信息:

public class location
{
   /// <summary>
   /// 车辆高程
   /// </summary>
   public double altitude { get; set; }

   /// <summary>
   /// 日期
   /// </summary>
   public string date { get; set; }

   /// <summary>
   /// 标志
   /// </summary>
   public int flag { get; set; }

   /// <summary>
   /// 纬度
   /// </summary>
   public double latitude { get; set; }

   /// <summary>
   /// 经度
   /// </summary>
   public double longitude { get; set; }

   /// <summary>
   /// 卫星数量
   /// </summary>
   public int numsv { get; set; }

   /// <summary>
   /// 时间戳
   /// </summary>
   public double timestamp { get; set; }
}

它包含了海拔、日期、定位标志、经纬度、卫星数量和时间戳等属性,方便在后续的应用中使用这些解析后的数据。

三、参考与拓展

(0)

您想发表意见!!点此发布评论

推荐阅读

C#使用BarcodeLib生成条形码的完整代码

06-04

C#实现Struct结构体与IntPtr转换的示例详解

06-05

C#基于Whisper.net实现语音识别功能的示例详解

06-03

跑分惊人! Core Ultra 9 285HX搭配RTX 5090移动版组装机性能有多强?

06-02

Core i5-12400F搭配RX 9070 XT组装会拖后腿吗? 多款游戏性能测试对比

06-02

C#封装HttpClient实现HTTP请求处理

06-06

猜你喜欢

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论