C#进阶(一)——TXT文件处理:以导线网近似平差为例
生活随笔
收集整理的这篇文章主要介绍了
C#进阶(一)——TXT文件处理:以导线网近似平差为例
小编觉得挺不错的,现在分享给大家,帮大家做个参考.
目录
引用及预处理方法的设计
引用
读取方法
相关类及方法的设计
窗体类后续方法的设计及调用
完整的窗体类设计
首先展示一下此程序可读取的.txt文件的正确格式
6,3,2 A,3143.237,5260.334 B,4609.361,5025.696 C,4157.197,8853.254 D,3822.911,9795.726 A B,L,0 P1,L,44.0545 P1,S,2185.070 B P1,L,0 A,L,93.1043 P1 A,L,0 B,L,42.4327 B,S,1522.853 P2,L,244.3218 P2,S,1500.017 P2 P1,L,0 C,L,201.5734 C,S,1009.021 C P2,L,0 D,L,168.0145引用及预处理方法的设计
引用
读取.txt后缀文件,需要作引用,需要引用的内容如下:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;注意,这是程序能正常运行的完整引用,并不只是处理.txt文件所需的引用。
读取方法
接下来就是读取,这里在对应的窗体类中设计一个void函数来进行读取:
/// <summary> /// 读取文件 /// </summary> /// <returns></returns> private void ReadDoc() {observedDatas = new List<ObservedData>();OpenFileDialog open = new OpenFileDialog();if (open.ShowDialog() != DialogResult.OK){return;}StreamReader reader = new StreamReader(open.FileName);//读取已知数据string[] s = reader.ReadLine().Split(',');knownData = new KnownData(Convert.ToDouble(s[0]), Convert.ToDouble(s[1]), Convert.ToDouble(s[2]));while (true){s = reader.ReadLine().Split(',');if (s.Length != 3) break;knownData.pointDatas.Add(new PointData(s[0], Convert.ToDouble(s[1]), Convert.ToDouble(s[2])));}while (!reader.EndOfStream){ObservedData observedData = new ObservedData(s[0]);while (!reader.EndOfStream){s = reader.ReadLine().Split(',');if (s.Length != 3) break;observedData.originalDatas.Add(new OriginalData(s[0], s[1], Convert.ToDouble(s[2])));}observedDatas.Add(observedData);}DataTable table = new DataTable(); }相关类及方法的设计
这个方法中,有自主设计的类,KnowData类、ObservedData类。此外还有需要在近似平差中使用的PointData类,其设计及内置方法如下所示:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 水平网平差程序 {/// <summary>/// 已知数据/// </summary>class KnownData{public double directionError, sideError, ratioError;public List<PointData> pointDatas;public KnownData(double directionError, double sideError, double ratioError){this.directionError = directionError;this.sideError = sideError;this.ratioError = ratioError;this.pointDatas = new List<PointData>();}}/// <summary>/// 已知点数据/// </summary>class PointData{public string id;public double x, y;public PointData(string id, double x, double y){this.id = id;this.x = x;this.y = y;}}/// <summary>/// 观测数据/// </summary>class ObservedData{public string testSiteNum;public List<OriginalData> originalDatas;public ObservedData(string testSiteNum){this.testSiteNum = testSiteNum;this.originalDatas = new List<OriginalData>();}}/// <summary>/// 照准点数据/// </summary>class OriginalData{public string id;public string type;public double value;public OriginalData(string id, string type, double value){this.id = id;this.type = type;this.value = value;}} }之后设计角度等的简单计算:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace 水平网平差程序 {/// <summary>/// 基本运算/// 包括:角度弧度互化、坐标方位角计算/// </summary>class BasicCal{/// <summary>/// 角度转弧度/// 适用于格式为dd.mmss/// </summary>/// <param name="dms"></param>/// <returns></returns>public static double Dms2rad(double dms){double d = Math.Floor(dms);double m = Math.Floor((dms - d) * 100.0);double s = (dms - d - m / 100.0) * 10000.0;return (d + m / 60.0 + s / 3600.0) * Math.PI / 180.0;}/// <summary>/// 弧度转角度/// </summary>/// <param name="rad"></param>/// <returns></returns>public static double Rad2dms(double rad){double temp = rad * 180 / Math.PI;double d = Math.Floor(temp);double m = Math.Floor((temp - d) * 60);double s = Math.Floor((temp - d - m / 60.0) * 3600);return d + m / 100.0 + s / 10000.0;}/// <summary>/// 求坐标方位角/// </summary>/// <param name="xA"></param>/// <param name="yA"></param>/// <param name="xB"></param>/// <param name="yB"></param>/// <returns></returns>public static double CoordinateAzimuth(double xA, double yA, double xB, double yB){if (yB - yA < 0){return Math.Atan2(yB - yA, xB - xA) + 2.0 * Math.PI;}if (xB - xA == 0 && yB - yA >= 0){return Math.PI / 2.0;}if (xB - xA == 0 && yB - yA < 0){return Math.PI * 3.0 / 2.0;}return Math.Atan2(yB - yA, xB - xA);}} }最后是近似平差类及方法:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 水平网平差程序 {/// <summary>/// 导线网近似坐标计算/// </summary>class ApproximateCoordinate{public List<PointData> points;public ApproximateCoordinate(KnownData knownData, List<ObservedData> observedDatas){this.points = new List<PointData>();foreach (ObservedData observedData in observedDatas){//从已知数据中寻找相应点号坐标PointData pA = knownData.pointDatas.Find(item => item.id == observedData.testSiteNum);if (pA == null){//若已知数据不存在相应点号,则到已算近似坐标中寻找pA = points.Find(item => item.id == observedData.testSiteNum);if (pA == null){//若已知数据和已算近视坐标均找不到则数据有误MessageBox.Show("数据有误");return;}}//同理查找第一个照准点PointData pB = knownData.pointDatas.Find(item => item.id == observedData.originalDatas[0].id);//points.Add(pB);if (pB == null){pB = points.Find(item => item.id == observedData.originalDatas[0].id);if (pB == null){MessageBox.Show("数据有误");return;}}//计算AB的坐标方位角double alphaAB = BasicCal.CoordinateAzimuth(pA.x, pA.y, pB.x, pB.y) - observedData.originalDatas[0].value;//循环计算该组数据的其他照准点近似坐标for (int i = 1; i < observedData.originalDatas.Count; i++){//若为已知数据直接加入PointData tempP = knownData.pointDatas.Find(item => item.id == observedData.originalDatas[i].id);if (tempP != null){//points.Add(tempP);continue;}//只要角度观测值if (knownData.pointDatas.Exists(item => item.id == observedData.originalDatas[i].id) || observedData.originalDatas[i].type == "S" || points.Exists(item => item.id == observedData.originalDatas[i].id)){continue;}//计算近似点坐标double xA = pA.x;double yA = pA.y;double sAP = observedData.originalDatas.Find(item => item.id == observedData.originalDatas[i].id && item.type == "S").value;double AlphaAP = alphaAB + BasicCal.Dms2rad(observedData.originalDatas[i].value);double cosAlphaAP = Math.Cos(AlphaAP);double sinAlphaAP = Math.Sin(AlphaAP);points.Add(new PointData(observedData.originalDatas[i].id, xA + sAP * cosAlphaAP, yA + sAP * sinAlphaAP));}}}} }窗体类后续方法的设计及调用
这里采取Datagridview控件储存及处理数据
设计两个Name属性分别为 已知点 和 观测值 的Datagirdview在窗体内,不做其他设计,之后在窗体中设计ShowTable方法,用于将数据读入控件:
private void ShowTable() {//已知数据显示DataTable table1 = new DataTable();table1.Columns.Add("已知点点号");table1.Columns.Add("X坐标");table1.Columns.Add("Y坐标");foreach (PointData p in knownData.pointDatas){DataRow row = table1.NewRow();row["已知点点号"] = p.id;row["X坐标"] = p.x;row["Y坐标"] = p.y;table1.Rows.Add(row);}已知点.DataSource = table1;//观测数据显示DataTable table2 = new DataTable();table2.Columns.Add("观测点点号");table2.Columns.Add("照准点点号");table2.Columns.Add("观测值类型");table2.Columns.Add("观测值");foreach (ObservedData observedData in observedDatas){foreach (OriginalData P in observedData.originalDatas){DataRow row = table2.NewRow();row["观测点点号"] = observedData.testSiteNum;row["照准点点号"] = P.id;row["观测值类型"] = P.type;row["观测值"] = P.value;table2.Rows.Add(row);}}已知点.DataSource = table1;观测值.DataSource = table2; }在点击 打开 按钮时调用:
private void 打开_Click(object sender, EventArgs e) {try{ReadDoc();ShowTable();}catch{MessageBox.Show("文件格式不符");} }之后是在单击某个控件时进行计算,这里使用Name为 计算 的 按钮 控件:
private void 计算_Click(object sender, EventArgs e) {try{approximateCoordinate = new ApproximateCoordinate(knownData, observedDatas);ShowText();}catch{MessageBox.Show("计算错误");} }接下来,是将计算结果写入某控件,这里采取的是 Name 属性为 报告 的 richtextbox:
private void ShowText() {报告.Text += " 近似坐标值:\n";报告.Text += string.Format("{0,14}", "点名") + string.Format("{0,14}", "X坐标") + string.Format("{0,14}", "Y坐标") + "\n";foreach (PointData pointData in knownData.pointDatas){报告.Text += string.Format("{0,16}", pointData.id) + string.Format("{0,16}", pointData.x) + string.Format("{0,16}", pointData.y) + "\n";}foreach (PointData pointData in approximateCoordinate.points){报告.Text += string.Format("{0,16}", pointData.id) + string.Format("{0,16}", pointData.x.ToString("0.000")) + string.Format("{0,16}", pointData.y.ToString("0.000")) + "\n";} }最后则是将结果写入.txt文件,同样在单击按钮时进行:
private void 保存_Click(object sender, EventArgs e) {SaveFileDialog save = new SaveFileDialog();save.Filter = "(文本文件)|.txt";if (save.ShowDialog() == DialogResult.OK){StreamWriter sw = new StreamWriter(save.FileName);sw.Write(报告.Text);sw.Close();} }完整的窗体类设计
完整的窗体类设计如下所示:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms;namespace 水平网平差程序 {public partial class 导线网近似平差 : Form{public 导线网近似平差(){InitializeComponent();StartPosition = FormStartPosition.CenterScreen;}KnownData knownData;List<ObservedData> observedDatas;ApproximateCoordinate approximateCoordinate;IndirectAdjustment indirectAdjustment;private void 打开_Click(object sender, EventArgs e){try{ReadDoc();ShowTable();}catch{MessageBox.Show("文件格式不符");}}private void 计算_Click(object sender, EventArgs e){try{approximateCoordinate = new ApproximateCoordinate(knownData, observedDatas);ShowText();展示框.SelectedTab = 报告页;}catch{MessageBox.Show("计算错误");}}private void 保存_Click(object sender, EventArgs e){SaveFileDialog save = new SaveFileDialog();save.Filter = "(文本文件)|.txt";if (save.ShowDialog() == DialogResult.OK){StreamWriter sw = new StreamWriter(save.FileName);sw.Write(报告.Text);sw.Close();}}/// <summary>/// 读取文件/// </summary>/// <returns></returns>private void ReadDoc(){observedDatas = new List<ObservedData>();OpenFileDialog open = new OpenFileDialog();if (open.ShowDialog() != DialogResult.OK){return;}StreamReader reader = new StreamReader(open.FileName);//读取已知数据string[] s = reader.ReadLine().Split(',');knownData = new KnownData(Convert.ToDouble(s[0]), Convert.ToDouble(s[1]), Convert.ToDouble(s[2]));while (true){s = reader.ReadLine().Split(',');if (s.Length != 3) break;knownData.pointDatas.Add(new PointData(s[0], Convert.ToDouble(s[1]), Convert.ToDouble(s[2])));}while (!reader.EndOfStream){ObservedData observedData = new ObservedData(s[0]);while (!reader.EndOfStream){s = reader.ReadLine().Split(',');if (s.Length != 3) break;observedData.originalDatas.Add(new OriginalData(s[0], s[1], Convert.ToDouble(s[2])));}observedDatas.Add(observedData);}DataTable table = new DataTable();}private void ShowTable(){//已知数据显示DataTable table1 = new DataTable();table1.Columns.Add("已知点点号");table1.Columns.Add("X坐标");table1.Columns.Add("Y坐标");foreach (PointData p in knownData.pointDatas){DataRow row = table1.NewRow();row["已知点点号"] = p.id;row["X坐标"] = p.x;row["Y坐标"] = p.y;table1.Rows.Add(row);}已知点.DataSource = table1;//观测数据显示DataTable table2 = new DataTable();table2.Columns.Add("观测点点号");table2.Columns.Add("照准点点号");table2.Columns.Add("观测值类型");table2.Columns.Add("观测值");foreach (ObservedData observedData in observedDatas){foreach (OriginalData P in observedData.originalDatas){DataRow row = table2.NewRow();row["观测点点号"] = observedData.testSiteNum;row["照准点点号"] = P.id;row["观测值类型"] = P.type;row["观测值"] = P.value;table2.Rows.Add(row);}}已知点.DataSource = table1;观测值.DataSource = table2;}private void ShowText(){报告.Text += " 近似坐标值:\n";报告.Text += string.Format("{0,14}", "点名") + string.Format("{0,14}", "X坐标") + string.Format("{0,14}", "Y坐标") + "\n";foreach (PointData pointData in knownData.pointDatas){报告.Text += string.Format("{0,16}", pointData.id) + string.Format("{0,16}", pointData.x) + string.Format("{0,16}", pointData.y) + "\n";}foreach (PointData pointData in approximateCoordinate.points){报告.Text += string.Format("{0,16}", pointData.id) + string.Format("{0,16}", pointData.x.ToString("0.000")) + string.Format("{0,16}", pointData.y.ToString("0.000")) + "\n";}}} }总结
以上是生活随笔为你收集整理的C#进阶(一)——TXT文件处理:以导线网近似平差为例的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: 风压和功率计算公式轴流式_离心风机风压计
- 下一篇: Unity3d C#实现语音合成(TTS