C# List 列表综合运用实例⁓Hypak原始数据处理编程小结

devtools/2025/2/8 3:00:13/

C# List 列表综合运用实例⁓Hypak原始数据处理编程小结

  • 1、一个数组解决很麻烦引出的问题
    • 1.1、RAW 文件尾部数据如下:
    • 1.2、自定义标头 ADD 或 DEL 的数据结构如下:
  • 2、程序 C# 源代码的编写和剖析
  • 2.1、使用 ref 关键字,通过引用将参数传递,以返回需要的数据行 List<string>
  • 2.2、使用 return 关键字,采用函数返回需要的数据行 List<string>
  • 3、程序过程编程小结

1、一个数组解决很麻烦引出的问题

春节期间,单身程序猿在家,咸的无聊,折腾编了很久的程序,一个 Hypack 测量成果 RAW 文件的处理程序,其中关于手工鼠标添加和删除打标记录,遇到一个数组解决很麻烦的问题,选择部分RAW 文件尾部作为示例。

1.1、RAW 文件尾部数据如下:

FIX 99 37639.880 115 626269.893 3216969.963
EC1 1 37640.137 1.560
POS 0 37640.200 626269.880 3216970.131
QUA 0 37640.200 7 3.000 1.000 9.000 2.000 0.000 0.000 0.000
RAW 0 37640.200 4 290379.29870 1121779.71130 9.88800 22720.20000
MSG 0 37640.137 $GPGGA,022720.20,2903.792987,N,11217.797113,E,2,09,1.0,9.888,M,0.0,M,8.0,0643*7A
MSG 0 37640.179 $GPVTG,355.0,T,,M,0.97,N,1.80,K,P*18
MSG 0 37640.199 $GPZDA,022720.20,27,03,2024,00,00*63
......
......
EC1 1 37641.138 1.320
POS 0 37641.200 626269.879 3216970.530
QUA 0 37641.200 7 3.000 1.000 8.000 2.000 0.000 0.000 0.000
RAW 0 37641.200 4 290379.32030 1121779.71150 9.92700 22721.20000
MSG 0 37641.138 $GPGGA,022721.20,2903.793203,N,11217.797115,E,2,08,1.0,9.927,M,0.0,M,4.0,0643*72
MSG 0 37641.181 $GPVTG,9.1,T,,M,0.68,N,1.26,K,P*1F
MSG 0 37641.199 $GPZDA,022721.20,27,03,2024,00,00*62
FIX 99 37641.316 116 626269.879 3216970.530

固定了 SP-6050 GPS 和 HY1603 测深仪的测量船,在航行中测量时,Hypack 软件产生原始成果 RAW 文件,其尾部数据与上雷同。

RAW 文件数据说明:

FIX 标识是某一时刻 Hypack 利用 HY1603 测深仪进行水下地形测量记录的固定打标点数据,
EC1 标识是某一时刻测量记录的水深数据,
POS 标识是某一时刻测量记录的 GPS 平面坐标数据,
QUA 标识是某一时刻测量记录的 GPS 坐标数据质量与精度,
RAW 标识是某一时刻测量记录的 GPS 坐标 WGS84 原始数据,
MSG 标识是某一时刻测量记录的 GPS 输出的各类原始消息(如 GPGGA、GPVTG、GPZDA),

在测量过程中受地形变化,FIX 固定打标点数据不能控制地形图的精度,需要手动添加地形变化显著的突出测量点,或删除多余的平坦测量点,这些工作可以通过自编程序进行处理和计算,通过自编程序向原始成果 RAW 文件尾部加入自定义标头为 ADD 或 DEL 的数据,以指示需要添加或删除某一时刻的 FIX 固定打标点数据。

1.2、自定义标头 ADD 或 DEL 的数据结构如下:

ADD FIX 37530.812 117 626281.983 3216777.812
DEL FIX 37616.237 110
DEL FIX 37539.000 80 
DEL FIX 37530.812 117
DEL FIX 37530.812 117
Add 118 38203.57 11.75
Add 129 38260.5 5.35
Add 129 38260.5 5.35
Add 130 38247.56 10.59
Del 130 38247.56 10.59
Del 129 38260.5 5.35
Del 129 38260.5 5.35
Del 117 37530.812 6.88

以上数据以空格分隔;以分隔表示一行数据的列定义。
以上数据中全大写字母 ADD 或 DEL 是新的定义格式,按固定打标 FIX 标识的新规范制定;
以上数据存在新旧标识数据,以便程序兼容旧标识数据,能识别和处理旧标识数据。

Add 或 Del 是旧的定义格式,按固定打标 FIX 标识的旧规范制定。

ADD 新定义格式:标头,固定,时间,事件号,东坐标,北坐标
DEL 新定义格式:标头,固定,时间,事件号
Add 旧定义格式:标头,事件号,时间,水深
Del 旧定义格式: 标头,事件号,时间,水深

以上数据有意添加了重复的数据行,是因为程序处理中。或可能产生此类数据。需要在新程序中更新该类错误。

产生此类数据的原则和前提:
1、添加 ADD 和删除 DEL 数据行,第 3 列和第 4 列不能相同,不可重复,即添加和删除了同一个数据点,应该抵消,无需存在。

如下数据,不应该出现在以上 1.2 节示例数据中:

Add 130 38247.56 10.59
Del 130 38247.56 10.59

2、相同标识的数据行,第 3 列和第 4 列相同的只能存在一个,添加 ADD 和删除 DEL 标识的唯一性。
如下数据,第二行和第三行不重复,是正确的,可以追加写入到原始成果 RAW 文件尾部:

ADD FIX 38203.570 118
DEL FIX 37539.000 80
DEL FIX 37616.237 110

3、为了向下兼容,新和旧定义格式混合时,相同标识的数据行,时间和事件相同的不应该存在。

DEL FIX 37530.812 117
Del 117 37530.812 6.88

2、程序 C# 源代码的编写和剖析

2.1、使用 ref 关键字,通过引用将参数传递,以返回需要的数据行 List

采用方法过程,void 关键字返回类型,指定该方法不返回值,采用 ref 关键字参数传递数据。
完整处理和分析过程如下:

        /// <summary>删除重复,重建添加删除打标记录</summary>/// <param name="ListAddOrDelMarks">返回符合自定义规范的 List数据列</param>private void RebuildDuplicateMarkings(ref List<string> ListAddOrDelMarks)//放入其它类使用 public static 替代 private {if (ListAddOrDelMarks.Count > 1)//有2行数据才进行处理{ListAddOrDelMarks = ListAddOrDelMarks.Distinct().ToList();//返回非重复的数列,删除相同的ADD或DEL行// foreach (string ListRow in ListAddOrDelMarksRows){Console.WriteLine(String.Join(", ", ListRow));}Console.WriteLine();for (int i = 0; i < ListAddOrDelMarks.Count; i++)//转换 Add 和 Del 行到新标准格式(DEL FIX 37616.237 110和ADD FIX 37530.812 117){string ListRowData = ListAddOrDelMarks[i];if (ListRowData.Substring(0, 3) == "Del"){string[] SplitListRow = ListRowData.Split(' ');ListAddOrDelMarks[i] = $"DEL FIX {Convert.ToDouble(SplitListRow[2]).ToString("0.000")} {SplitListRow[1]}";//Console.WriteLine($"DEL FIX {SplitListRow[2]} {SplitListRow[1]}");}else if (ListRowData.Substring(0, 3) == "Add"){string[] SplitListRow = ListRowData.Split(' ');ListAddOrDelMarks[i] = $"ADD FIX {Convert.ToDouble(SplitListRow[2]).ToString("0.000")} {SplitListRow[1]}";//Console.WriteLine($"ADD FIX {SplitListRow[2]} {SplitListRow[1]}");}}ListAddOrDelMarks.Sort();//LIST排序//foreach (string ListRow in ListAddOrDelMarksRows) { Console.WriteLine(ListRow); } Console.WriteLine();List<List<string>> TwoDimensionalList = new List<List<string>>();//新建二维LIST 以处理其它去重复foreach (string ListRowData in ListAddOrDelMarks){List<string> OneDimensionalList = new List<string>(ListRowData.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));//行数据分裂为LIST<string>TwoDimensionalList.Add(OneDimensionalList);//将一维 LIST 添加到二维 LIST}int columnIndex = 2;// 检查第3列(索引从0开始)List<string> duplicates = TwoDimensionalList.GroupBy(list => list[columnIndex])// 获取该列的所有值及其出现的次数.Where(group => group.Count() > 1).Select(group => group.Key).ToList();TwoDimensionalList.RemoveAll(list => duplicates.Contains(list[columnIndex]));// 移除TwoDimensionalList二维LIST所有第3列包含重复值的行List<string> NewListAddOrDelMarksRows = new List<string>();//新建一维列表 Listforeach (List<string> ListRow in TwoDimensionalList){NewListAddOrDelMarksRows.Add(String.Join(" ", ListRow));//二维 List 转换为一维列表 List // Console.WriteLine(String.Join(" ", ListRow));}ListAddOrDelMarks = NewListAddOrDelMarksRows;//返回符合规则的数列NewListAddOrDelMarksRows.Clear();//删除使用过的数列,释放内存占用duplicates.Clear();TwoDimensionalList.Clear();}}

2.2、使用 return 关键字,采用函数返回需要的数据行 List

采用函数返回值,可以封装到引用类中,以方便引用。
完整处理和分析过程如下:

  /// <summary>删除重复,重建添加删除打标记录</summary>/// <param name="ListAddOrDelMarks">添加或删除的重复打标记录</param>/// <returns>返回符合自定义规范的 List数据列</returns>public static List<string> RebuildDuplicateMarkings(List<string> ListAddOrDelMarks){if (ListAddOrDelMarks.Count > 1){ListAddOrDelMarks = ListAddOrDelMarks.Distinct().ToList();//返回非重复的数列,删除相同的ADD或DELfor (int i = 0; i < ListAddOrDelMarks.Count; i++)//转换Add和Del行为标准格式(DEL FIX 37616.237 110和ADD FIX 37530.812 117){string ListRowData = ListAddOrDelMarks[i];if (ListRowData.Substring(0, 3) == "Del"){string[] SplitListRow = ListRowData.Split(' ');ListAddOrDelMarks[i] = $"DEL FIX {Convert.ToDouble(SplitListRow[2]).ToString("0.000")} {SplitListRow[1]}";}else if (ListRowData.Substring(0, 3) == "Add"){string[] SplitListRow = ListRowData.Split(' ');ListAddOrDelMarks[i] = $"ADD FIX {Convert.ToDouble(SplitListRow[2]).ToString("0.000")} {SplitListRow[1]}";}}ListAddOrDelMarks.Sort();//LIST排序List<List<string>> TwoDimensionalList = new List<List<string>>();//新建二维LISTforeach (string ListRowData in ListAddOrDelMarks){List<string> OneDimensionalList = new List<string>(ListRowData.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));//行数据分裂为LISTTwoDimensionalList.Add(OneDimensionalList);//将一维LIST添加到二维LIST}int columnIndex = 2;// 检查第3列时间值(索引从0开始)List<string> duplicates = TwoDimensionalList.GroupBy(list => list[columnIndex])// 获取该列的所有值及其出现的次数.Where(group => group.Count() > 1).Select(group => group.Key).ToList();TwoDimensionalList.RemoveAll(list => duplicates.Contains(list[columnIndex]));// 移除TwoDimensionalList二维LIST所有3列包含重复值的行List<string> NewListAddOrDelMarksRows = new List<string>(); //新建一维LIST,将二维LIST转换为一维LISTforeach (List<string> ListRow in TwoDimensionalList){NewListAddOrDelMarksRows.Add(String.Join(" ", ListRow));}duplicates.Clear();TwoDimensionalList.Clear();return NewListAddOrDelMarksRows;//返回一维LIST}else{return null; //返回空}}

3、程序过程编程小结

通过以上程序处理,1.2 节的示例数据输出结构如下

ADD FIX 38203.570 118
DEL FIX 37539.000 80
DEL FIX 37616.237 110

返回的 List 数据符合自定义要求,程序设计思路更加清晰,解决了数组很难处理的麻烦,而且程序代码行数量不大,代码简洁,运行速度提升。

处理了不符合定义要求的重复数据行,通过鼠标左右双击添加 ADD 和删除 DEL 固定打标点的程序代码,就不会出错了,就加快了编写和优化 FIX 固定打标点数据的图形展示、数据表显示的进度。


http://www.ppmy.cn/devtools/157003.html

相关文章

DeepSeek与llama本地部署(含WebUI)

DeepSeek从2025年1月起开始火爆&#xff0c;成为全球最炙手可热的大模型&#xff0c;各大媒体争相报道。我们可以和文心一言一样去官网进行DeepSeek的使用&#xff0c;那如果有读者希望将大模型部署在本地应该怎么做呢&#xff1f;本篇文章将会教你如何在本地傻瓜式的部署我们的…

spacemacs gnuplot

个人博客地址&#xff1a;spacemacs gnuplot | 一张假钞的真实世界 环境 Ubuntu 16.10Emacs 24 安装过程 spacemacs安装 安装Emacs sudo apt-get install emacs 安装spacemacs &#xff08;1&#xff09;如果已经存在Emacs配置文件&#xff0c;首先备份&#xff1a; c…

Oracle(windows安装遇到的ORA-12545、ORA-12154、ORA-12541、ORA-12514等问题)

其实出现该问题就是监听或者服务没有配好。 G:\xiaowangzhenshuai\software\Oracle\product\11.2.0\dbhome_1\NETWORK\ADMINlistener.ora SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME CLRExtProc)(ORACLE_HOME G:\xiaowangzhenshuai\software\Oracle\product\11.2.0\d…

实施工程师:面试基础宝典

一.运维工程师和实施工程师的区别&#xff1a;工作内容不同、职能不同、工作形式不同 1.工作内容不同&#xff1a; 运维工程师要对公司硬件和软件进行维护。 硬件包括&#xff1a;机房、机柜、网线光纤、PDU、服 务器、网络设备、安全设备等。 实施工程师包括常用操作系统、应…

OS10 固件更新步骤-U 盘方式

OS10 固件更新步骤-U 盘方式 1.准备工作 (1)将 U 盘格式化成 FAT32 格式 ,大小不超过16G.当然也可以使用FTP/TFTP 等方式上传文件,U盘是最方便的一种方式. (2)将 OS10 下载下来之后,解压文件,将最大的文件,后缀名:.bin 文件放在 U 盘的根目录(一定要放在 U 盘根目录…

Nginx中替换即将到期的SSL/TLS证书

在 Nginx 中替换即将到期的 SSL/TLS 证书是一个常见的运维任务。以下是详细的步骤 1. 准备新证书 确保您已经获取了新的 SSL/TLS 证书文件和私钥文件。通常,证书颁发机构(CA)会提供以下文件: 证书文件 :通常是 .crt 或 .pem 文件(例如 example.com.crt)。私钥文件 :通…

一文讲解Spring中应用的设计模式

我们都知道Spring 框架中用了蛮多设计模式的&#xff1a; 工厂模式呢&#xff0c;就是用来创建对象的&#xff0c;把对象的创建和使用分开&#xff0c;这样代码更灵活。代理模式呢&#xff0c;是用一个代理对象来控制对真实对象的访问&#xff0c;可以在访问前后做一些处理。单…

最新码支付个人免签支付系统源码 三网免挂版本 兼容易支付

介绍: 最新码支付个人免签支付系统源码 三网免挂版本 兼容易支付 本系统是基于thinkphp5.0 FastAdmin 开发的一套新型聚合收款、聚合支付系统 一款专业的聚合免签收款系统,无需对接其余平台,个码就可收款,灰常的方便快捷,集成实现三网免挂功能, 无需挂繁琐的监控软件就可实…