C#纵横断面计算(测绘程序设计)

读取道路关键点数据和散点数据,进行道路纵断面、横断面的相关点位计算,以及断面面积计算,将输出成果保存到指定的文件中。

1.类的定义

class KeyPoint
    {
        public string Name;
        public double X;
        public double Y;
        public double H;
        public KeyPoint(string name, double x, double y, double h)
        {
            this.Name = name;
            this.X = x;
            this.Y = y;
            this.H = h;
        }
    }

    class DiscretePoint
    {
        public string Name;
        public double X;
        public double Y;
        public double H;
        public double dis;
        public DiscretePoint(string name, double x, double y, double h)
        {
            this.Name = name;
            this.X = x;
            this.Y = y;
            this.H = h;
        }
    }

    class InsertPoint
    {
        public string[] index;
        public double X;
        public double Y;
        public double H;
        public InsertPoint(List<DiscretePoint> Dp, double X, double Y, double L, double alpha)
        {
            this.X = X + L * Math.Cos(alpha);
            this.Y = Y + L * Math.Sin(alpha);
            index = SelectIndex(Dp, this.X, this.Y, 5);
            H = InsertHeigh(Dp, this.X, this.Y, 5);
        }

        public double InsertHeigh(List<DiscretePoint> Dp, double X, double Y, int num)
        { 
            double d = 0;
            for (int i = 0; i < Dp.Count(); i++)
            {
                Dp[i].dis = Math.Sqrt(Math.Pow(X - Dp[i].X, 2) + Math.Pow(Y - Dp[i].Y, 2));
            }
            Dp = Dp.OrderBy(o => o.dis).ToList();

            double total_h = 0, total_1 = 0;
            for (int j = 0; j < num; j++)
            {
                d = Math.Sqrt(Math.Pow(X - Dp[j].X, 2) + Math.Pow(Y - Dp[j].Y, 2));
                total_h += Dp[j].H / d;
                total_1 += 1 / d;
            }
            return total_h / total_1;
        }

        public string[] SelectIndex(List<DiscretePoint> Dp, double X, double Y, int num)
        {
            string[] ind = new string[num];
            for (int i = 0; i < Dp.Count(); i++)
            {
                Dp[i].dis = Math.Sqrt(Math.Pow(X - Dp[i].X, 2) + Math.Pow(Y - Dp[i].Y, 2));
            }
            Dp = Dp.OrderBy(o => o.dis).ToList();
            for (int k = 0; k < num; k++)
            {
                ind[k] = Dp[k].Name;
            }
            return ind;
        }
    }


    class CenterPoint
    {
        public double X;
        public double Y;
        public List<InsertPoint> insert = new List<InsertPoint>();
        public CenterPoint(double X, double Y)
        {
            this.X = X;
            this.Y = Y;
        }

    }

    class ABpoint
    {
        public string Name;
        public double X;
        public double Y;
    }

2.计算部分实现

 class Cal
    {
        //方位角计算
        public static double amuzith(double deltaY,double deltaX)
        {
            if (deltaX > 0)
            {
                return Math.Atan(deltaY / deltaX);
            }
            else
            {
                return Math.Atan(deltaY / deltaX) + Math.PI;
            }
        }
        //纵断面分段长度计算
        public static double[] divideLenth(List<KeyPoint> Kp)
        {
            double[] Lenth = new double[Kp.Count() - 1];
            for(int i = 0; i < Kp.Count()-1; i++)
            {
                Lenth[i]= Math.Sqrt(Math.Pow(Kp[i + 1].X - Kp[i].X, 2) + Math.Pow(Kp[i + 1].Y - Kp[i].Y, 2));
            }
            return Lenth;
        }
        //纵断面总长度计算
        public static double totalLenth(double[] Lenth)
        {
            double totalLenth = 0;
            for(int i = 0; i < Lenth.Count(); i++)
            {
                totalLenth += Lenth[i];
            }
            return totalLenth;
        }
        //添加内插点
        public static List<InsertPoint> Insertpoint(List<KeyPoint> Kp,List<DiscretePoint> Dp,double[] Lenth)
        {
            List<InsertPoint> Ip = new List<InsertPoint>();
            double L = 10;
            for(int i = 0; i < Kp.Count() - 1; i++)
            {
                double deltaY = Kp[i + 1].Y - Kp[i].Y;
                double deltaX = Kp[i + 1].X - Kp[i].X;
                double sigma = amuzith(deltaY, deltaX);
                for(int j = 0; j < Lenth[i] / 10 - 1; j++)
                {
                    InsertPoint Inp = new InsertPoint(Dp, Kp[i].X, Kp[i].Y, L, sigma);
                    Ip.Add(Inp);
                    L += 10;
                }
                L -= Lenth[i];
            }
            return Ip;
        }
        //断面面积计算
        public static double Area(List<InsertPoint> Ip,List<KeyPoint> Kp,double L,double h0,double[] Lenth) 
        {
            double S = 0;
            for (int i = 0; i < Ip.Count(); i++)
            {
                if (i == 0)
                    S += (Ip[0].H + Kp[0].H - 2 * h0) / 2 * 10;
                if (i == 3)
                    S += (Kp[1].H + Ip[3].H - 2 * h0) / 2 * (Lenth[0] % 10);
                if (i == 4)
                    S += (Kp[1].H + Ip[4].H - 2 * h0) / 2 * (10 - Lenth[0] % 10);
                if (i == Ip.Count() - 1)
                    S += (Kp[2].H + Ip[i].H - 2 * h0) / 2 * (Lenth[1] % 10);
                else
                    S += (Ip[i].H + Ip[i + 1].H - 2 * h0) / 2 * 10;
            }
            return S;
        }

        //横断面中心点坐标
        public static List<CenterPoint> Centerpoint(List<KeyPoint> Kp)
        {
            List<CenterPoint> Cp = new List<CenterPoint>();
            double x = 0, y = 0;
            for(int i = 0; i < Kp.Count()-1; i++)
            {
                x = (Kp[i].X + Kp[i + 1].X) / 2;
                y = (Kp[i].Y + Kp[i + 1].Y) / 2;
                CenterPoint cp = new CenterPoint(x, y);
                Cp.Add(cp);
            }
            return Cp;
        }
        //横断面内插点
        public static List<CenterPoint> InsertPoint2(List<CenterPoint> Cp,List<KeyPoint> Kp,List<DiscretePoint> Dp)
        {
            for(int i = 0; i < Cp.Count(); i++)
            {
                double distance = -25;
                double deltaY = Kp[i + 1].Y - Kp[i].Y;
                double deltaX = Kp[i + 1].X - Kp[i].X;
                double alaph = amuzith(deltaY, deltaX) + Math.PI / 2;
                for(int j = 0; j <= 25 * 2 / 5; j++)
                {
                    InsertPoint insertpoint = new InsertPoint(Dp, Cp[i].X, Cp[i].Y, distance, alaph);
                    Cp[i].insert.Add(insertpoint);
                    distance += 5;
                }
            }
            return Cp;
        }
        //横断面面积
        public static double[] crossArea(List<CenterPoint> Cp,double h0)
        {
            double[] S = new double[Cp.Count()];
            for(int i = 0; i < Cp.Count(); i++)
            {
                for(int j = 0; j < Cp[i].insert.Count() - 1; j++)
                {
                    S[i] += (Cp[i].insert[j].H + Cp[i].insert[j + 1].H - 2 * h0) / 2 * 5;
                }
            }
            return S;
        }
    }

这里纵断面的计算个人感觉有些问题,使用了比较呆的办法,最后算出来的结果也不一定正确。

3.Form.cs

   public partial class Form1 : Form
    {
        List<DiscretePoint> Dp = new List<DiscretePoint>();
        List<KeyPoint> Kp = new List<KeyPoint>();
        List<InsertPoint> Ip = new List<InsertPoint>();
        List<CenterPoint> Cp = new List<CenterPoint>();
        List<ABpoint> AB = new List<ABpoint>();
        double H0;
        string report = null;

        public Form1()
        {
            InitializeComponent();
        }

        private void 读取文件数据ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog op = new OpenFileDialog();
                op.Filter = "文本文件(*.txt)|*.txt";
                if (op.ShowDialog() == DialogResult.OK)
                {
                    string filepath = op.FileName;
                    StreamReader sr = new StreamReader(filepath);
                    string[] Info = sr.ReadLine().Split(',');
                    H0 = Convert.ToDouble(Info[1]);
                    sr.ReadLine();
                    //A B
                    for (int i = 0; i < 2; i++)
                    {
                        ABpoint ab = new ABpoint();
                        Info = sr.ReadLine().Split(',');
                        ab.Name = Convert.ToString(Info[0]);
                        ab.X = Convert.ToDouble(Info[1]);
                        ab.Y = Convert.ToDouble(Info[2]);
                        AB.Add(ab);
                    }
                    sr.ReadLine();
                    //提取离散点数据和关键点
                    while (!sr.EndOfStream)
                    {
                        Info = sr.ReadLine().Split(',');
                        string Name = Info[0];
                        double X = Convert.ToDouble(Info[1]);
                        double Y = Convert.ToDouble(Info[2]);
                        double H = Convert.ToDouble(Info[3]);
                        if (Regex.IsMatch(Name, @"K\d"))
                        {
                            KeyPoint K = new KeyPoint(Name, X, Y, H);
                            Kp.Add(K);
                        }
                        else
                        {
                            DiscretePoint D = new DiscretePoint(Name, X, Y, H);
                            Dp.Add(D);
                        }
                    }
                    MessageBox.Show("读取成功!");
                    ShowData(Kp, Dp);                  
                }
            }
            catch
            {
                throw;
            }
        }

        private void 纵断面计算ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                double[] Lenth = Cal.divideLenth(Kp);
                double total = Cal.totalLenth(Lenth);
                report += "\t----------------------------纵断面长度----------------------------\n";
                foreach (var item in Lenth)
                {
                    report += "\t分长度:" + item.ToString("0.000") + "\t";
                }
                report += "\n\t总长度:" + total.ToString("0.000") + "\t\n";

                Ip = Cal.Insertpoint(Kp, Dp, Lenth);
                report += "\t-----------------------------内插点-----------------------------\n";
                report += "\t关键点\n " + "\t" + "X坐标(m)" + "\t" + "Y坐标(m)" + "\t" + "H坐标(m)\n";
                foreach (InsertPoint item in Ip)
                {
                    report += "\t" + item.X.ToString("0.000") + "\t" + item.Y.ToString("0.000") + "\t" + item.H.ToString("0.000") + "\n";
                }

                double S = Cal.Area(Ip, Kp, 10, H0, Lenth);
                report += "\t---------------------------纵断面面积-----------------------------\n";
                report += "\t" + S.ToString("0.000") + "\n";

                richTextBox2.Text = report;
                tabControl1.SelectedIndex = 1;
            }
            catch
            {
                throw;
            }
        }

        private void 横断面计算ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                Cp = Cal.Centerpoint(Kp);
                report += "\t-----------------------------中心点-----------------------------\n";
                report += "\tX坐标(m)" + "\t" + "Y坐标(m)" + "\t" + "\n";
                foreach (CenterPoint item in Cp)
                {
                    report += "\t" + item.X.ToString("0.000") + "\t" + item.Y.ToString("0.000") + "\t" + "\n";
                }

                Cp = Cal.InsertPoint2(Cp, Kp, Dp);
                report += "\t----------------------------横断内插点----------------------------\n";
                report += "\tX坐标(m)" + "\t" + "Y坐标(m)" + "\t" + "H坐标(m)\n";
                foreach (CenterPoint item in Cp)
                {
                    for (int j = 0; j < item.insert.Count(); j++)
                    {
                        report += "\tP" + j.ToString("0") + "\t" + item.insert[j].X.ToString("0.000") + "\t" + item.insert[j].Y.ToString("0.000") + "\t" + item.insert[j].H.ToString("0.000") + "\t最近五个离散点点号:";
                        report += "\t" + item.insert[j].index[0] + "    " + item.insert[j].index[1] + "    " + item.insert[j].index[2] + "    " + item.insert[j].index[3] + "    " + item.insert[j].index[4] + "\n";
                    }
                    report += "\n";
                }

                double[] S = Cal.crossArea(Cp, H0);
                report += "\t----------------------------横断面面积----------------------------\n";
                foreach (double item in S)
                {
                    report += "\t分断面面积:" + item.ToString("0.000") + "\t";
                }
                richTextBox2.Text = report;
                tabControl1.SelectedIndex = 1;
            }
            catch
            {
                throw;
            }

        }

        private void 导出RToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                SaveFileDialog sf = new SaveFileDialog();
                sf.Filter = "文本文件(*.txt)|*.txt";
                if (sf.ShowDialog() == DialogResult.OK)
                {
                    string filepath = sf.FileName;
                    StreamWriter sw = new StreamWriter(filepath);
                    sw.Write(report);
                    sw.Close();
                }
                MessageBox.Show("导出成功!");
            }
            catch
            {

            }
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            读取文件数据ToolStripMenuItem_Click(sender, e);
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            try
            {
                纵断面计算ToolStripMenuItem_Click(sender, e);
                横断面计算ToolStripMenuItem_Click(sender, e);
            }
            catch
            {
                throw;
            }
        }

        private void toolStripButton3_Click(object sender, EventArgs e)
        {
            MessageBox.Show("按提示进行操作!");
        }

        private void toolStripButton4_Click(object sender, EventArgs e)
        {
            导出RToolStripMenuItem_Click(sender, e);
        }

        private void toolStripButton5_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void ShowData(List<KeyPoint> Ks,List<DiscretePoint> Ds)
        {
            try
            {
                string report = null;
                report = "\t----------------------------读取结果----------------------------\n";
                report += "\t关键点\n\t点名 \tX坐标(m)\tY坐标(m)\tH坐标(m)\n";
                foreach (KeyPoint item in Ks)
                {
                    report += "\t" + item.Name + "\t" + item.X.ToString("0.000") + "\t" + item.Y.ToString("0.000") + "\t" + item.H.ToString("0.000") + "\n";
                }
                report += "\t离散点\n\t点名 \tX坐标(m)\tY坐标(m)\tH坐标(m)\n";
                foreach (DiscretePoint item in Ds)
                {
                    report += "\t" + item.Name + "\t" + item.X.ToString("0.000") + "\t" + item.Y.ToString("0.000") + "\t" + item.H.ToString("0.000") + "\n";
                }
                richTextBox1.Text = report;
                toolStripStatusLabel1.Text = "状态:读取成功!";
            }
            catch
            {

            }
        }


    }

运行过程如图所示

 附带功能是计算以及保存,由于赛制的变更以及自身实力有限所以没有做相关的绘图功能,欢迎各位探讨,源码我会放在资源里。

  • 4
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

湫秋刀鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值