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则用于在分割字符串时去除空元素。
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对象中返回。
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对象。
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; }
例如,对于经度字符串,前三位表示度数,后面五位表示分,通过特定的计算将其转换为以度为单位的数值。
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 小时)。最后,构建出日期字符串和对应的时间戳。
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类用于存储解析后的位置信息:
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; } }
它包含了海拔、日期、定位标志、经纬度、卫星数量和时间戳等属性,方便在后续的应用中使用这些解析后的数据。
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论