C#代碼實現(xiàn)解析WTGPS和BD數(shù)據(jù)
在現(xiàn)代的導航與定位應(yīng)用中,準確解析 GPS 和北斗(BD)等衛(wèi)星定位數(shù)據(jù)至關(guān)重要。今天,我們來探討如何使用 C# 語言對 WTGPS+BD 數(shù)據(jù)進行解析。
一、代碼結(jié)構(gòu)概覽
首先,我們有一個WitGpsParser類,這個類主要負責解析原始的 GPS 數(shù)據(jù)。它包含了一些關(guān)鍵的字段和方法:
using System; using System.Linq; public class WitGpsParser { // 經(jīng)緯度標記 private readonly string gnzda = "GNZDA"; // 時間戳標記 private readonly string gngga = "GNGGA"; private readonly StringSplitOptions options = StringSplitOptions.RemoveEmptyEntries; // ... }
其中,gnzda和gngga分別用于標識不同類型的 GPS 數(shù)據(jù)語句,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; }
它首先將輸入的原始數(shù)據(jù)按行分割,然后分別查找包含GNGGA和GNZDA的行。GNGGA語句通常包含位置信息,而GNZDA語句包含日期和時間信息。通過調(diào)用ToLocation和ToDateAndTimestamp方法,分別解析出位置和時間信息,并將它們組裝到Location對象中返回。
2. 位置信息解析
ToLocation方法負責從GNGGA語句中提取并解析位置相關(guān)信息:
private Location ToLocation(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return null; } var raws = raw.Split(new char[] { ',' }); // 驗證數(shù)據(jù)完整 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, }; }
在這個方法中,首先檢查輸入數(shù)據(jù)是否為空或不完整。然后,通過調(diào)用ToLatitude和ToLongitude方法,將字符串形式的經(jīng)緯度轉(zhuǎn)換為實際的數(shù)值。同時,提取定位標志(flag)、衛(wèi)星數(shù)量(numSV)和海拔高度(altitude)等信息,最后構(gòu)建并返回Location對象。
3. 經(jīng)緯度轉(zhuǎn)換方法
ToLatitude和ToLongitude方法用于將特定格式的經(jīng)緯度字符串轉(zhuǎn)換為實際的度數(shù):
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; }
例如,對于經(jīng)度字符串,前三位表示度數(shù),后面五位表示分,通過特定的計算將其轉(zhuǎn)換為以度為單位的數(shù)值。
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); }
該方法首先檢查數(shù)據(jù)的完整性,然后提取出 UTC 時間、日、月、年等信息。由于 GPS 數(shù)據(jù)中的時間通常是 UTC 時間,這里將其轉(zhuǎn)換為本地時間(這里簡單地加了 8 小時)。最后,構(gòu)建出日期字符串和對應(yīng)的時間戳。
5. 輔助方法
RemoveZero方法用于去除字符串開頭的零:
private string RemoveZero(string s) { if (s.StartsWith("0")) { return s.Substring(1, 1); } return s; }
ToTimestamp方法將DateTime對象轉(zhuǎn)換為時間戳:
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> /// 經(jīng)度 /// </summary> public double Longitude { get; set; } /// <summary> /// 衛(wèi)星數(shù)量 /// </summary> public int NumSV { get; set; } /// <summary> /// 時間戳 /// </summary> public double TimeStamp { get; set; } }
它包含了海拔、日期、定位標志、經(jīng)緯度、衛(wèi)星數(shù)量和時間戳等屬性,方便在后續(xù)的應(yīng)用中使用這些解析后的數(shù)據(jù)。
三、參考與拓展
更多關(guān)于 WTGPS+BD 數(shù)據(jù)解析的詳細信息,可以參考Wit Motion 的官方文檔。在實際應(yīng)用中,可能還需要根據(jù)具體的業(yè)務(wù)需求,對解析后的數(shù)據(jù)進行進一步的處理和分析,例如結(jié)合地圖進行可視化展示,或者用于軌跡跟蹤等功能。
通過上述代碼和分析,我們可以看到如何在 C# 中有效地解析 WTGPS+BD 數(shù)據(jù),為開發(fā)高精度的定位相關(guān)應(yīng)用奠定了基礎(chǔ)。
到此這篇關(guān)于C#代碼實現(xiàn)解析WTGPS和BD數(shù)據(jù)的文章就介紹到這了,更多相關(guān)C#解析數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#實現(xiàn)漢字轉(zhuǎn)拼音(多音字)功能詳解
這篇文章主要為大家詳細介紹了如何利用C#實現(xiàn)漢字轉(zhuǎn)拼音(支持多音字)的功能,文中的示例代碼講解詳細,對我們學習C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2023-02-02C#判斷文件夾是否存在,并執(zhí)行刪除、創(chuàng)建操作方式
這篇文章主要介紹了C#判斷文件夾是否存在,并執(zhí)行刪除、創(chuàng)建操作方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-04-04c# 使用特定帳號密碼訪問Windows網(wǎng)路共享
這篇文章主要介紹了c# 使用特定帳號密碼訪問Windows網(wǎng)路共享的方法,幫助大家更好的理解和學習使用c#,感興趣的朋友可以了解下2021-03-03C#中使用async和await實現(xiàn)異步Udp通訊的示例代碼
本文主要介紹了C#中使用async和await實現(xiàn)異步Udp通訊的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-07-07