c#编写闭合导线简易平差程序

1、功能简介

  本程序是使用c#语言编写的winform程序,使用VS2012开发,可实现闭合导线的观测数据导入、平差、结果显示、数据超限检查、平差结果导出到Excel表格、导线路线示意图绘制与导出。

2、平差原理

  在闭合导线内业平差计算时,存在两种情况:
(1)由一个已知点出发,并已知该点上方位角,本报告将其简称为“一点一方向”;其示意图如下图。
在这里插入图片描述

(2)由两个已知点出发,本报告将其简称为“两个已知点”。其示意图如下图。
在这里插入图片描述
  根据《城市测量规范》(CJJT 8-2011)相关要求,导线测量主要技术要求如下表。
在这里插入图片描述
  闭合导线的计算步骤如下:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3、程序界面设计

  本程序界面主要分两大模块:计算部分和绘图部分。使用tabControl控件实现两个部分的切换。界面样式使用IrisSkin4.dll插件进行美化,该插件下载和使用方法可自行百度。
计算部分界面设计见下图:
在这里插入图片描述

  导入数据、导出结果、使用说明等功能采用menuStrip控件放置。数据采用dataGridView控件以表格显示,依次显示点号、角度观测值、改正数、改正后角度、方位角、水平距离、坐标增量、坐标增量改正数、改正后坐标增量、坐标X、坐标Y。参数选择使用comboBox空间提供选择。例外还有一个由richTextBox空间组成的信息框,主要用来显示闭合差、导线全长相对闭合差等数据。
  绘图部分界面设计见下图:
在这里插入图片描述

  绘图部分比较简单,只有绘图按钮、保存按钮、以及使用pictureBox控件组成的绘图框,其中绘图框只有在执行绘图后才会显示出来。

4、程序运行

  导入观测数据前,需要先选择转折角类型、导线等级、导线类型,如果存在参数未选择,点击“导入数据”按钮会弹出提示并停止导入。
  点击“转折角类型:”标签旁的下拉框,即可选择转折角类型,转折类型提供“左角”和“右角”两种选择,如下图:
在这里插入图片描述
  点击“导线类型:”标签旁的下拉框,即可选择导线类型,导线类型提供“闭合导线(一点一方向)”和“闭合导线(两个已知点)”两种选择。
  点击“导线等级:”标签旁的下拉框,可选择导线等级,导线等级提供“三等”、“四等”、“一级”、“二级”和“三级”共五种选择。
  选择好导线参数后,即可开始进行平差。首先点击“导入数据”按钮导入数据。导入数据通过txt文件导入,不同的导线类型对应不同的数据格式,如果导入的数据格式存在问题,会弹出提示并停止导入,数据格式说明如下:
(1)闭合导线(一点一方向)数据格式
  闭合导线(一点一方向)第一行数据为已知点数据,格式为“点号,已知方位角,x,y”,数据用英文逗号隔开,下同。从第二行开始为待求点数据,格式为“点号,观测角度,与上一点平距”,其中角度格式为“度.分秒”,如“19,0434”表示19度4分34秒。示例数据如下图:
在这里插入图片描述
(2)闭合导线(两个已知点)两个已知点数据格式
  闭合导线(两个已知点)数据第一行为第一个已知点数据,格式为“点号,x,y”,第二行为第二个已知点数据,格式为“点号,观测角度,x,y”,从第三行开始为待求点数据,格式为“点号,观测角度,与上一点平距”。其中角度格式为“度.分秒”。其示例数据如下图:
在这里插入图片描述
  由于导入数据后各种类型导线的操作基本一致,故这里只使用“闭合导线(一点一方向)”类型的数据进行展示,这里选择的导线等级为“三级”,转折角类型为“左角”。
通过txt文件导入观测数据后,会在程序中的表格中显示观测数据。点击“计算”,即可自动完成导线平差,完成平差后会在程序中的表格中显示平差数据,同时在“信息列表”模块会显示平差的限差信息,如下图:
在这里插入图片描述
  表格显示观测数据与平差数据效果如下图:
在这里插入图片描述
  表格按列展示数据,从第一列开始,展示的数据依次为:点号、角度观测值(° ′ ″)、角度改正数(”)、改正后角度(° ′ ″)、方位角(° ′ ″)、水平距离(m)、坐标增量(m)(Δx,Δy)、坐标增量改正数(m)(x,y)、改正后坐标增量(m)(Δx,Δy)、坐标X(m)、坐标Y(m)。
  点击“导出结果”—“导出到TXT”,设置好文件名,可将平差结果导出为txt文件,若导出失败会弹出提示。其导出数据与导入数据顺序一致,均为已知点数据加待求导线点数据。导出的已知点数据格式与导入的已知点数据格式基本一致,只是角度格式变为“度,分,秒”,导出的待求导线点数据格式为“点号,方位角,X,Y”,其中,方位角格式为“度,分,秒”,导出到txt文件的数据示例如下图:
在这里插入图片描述
  导出结果为txt文件是为了应付学校要求,所以写得比较简单。下面重点讲讲怎么将平差结果导出为Excel表格。
首先,在VS导航栏点击“项目”—“添加引用”,在程序集里搜索“Microsoft.Office.Interop.Excel”,如下图:
在这里插入图片描述
  添加这个引用,然后在主窗体代码最上面添加引用代码,如下:

using Excel = Microsoft.Office.Interop.Excel;

  调用Excel写入平差数据的类如下:

 public bool DataGridviewShowToExcel(DataGridView dgv, bool isShowExcle)//导出到Excel
        {
            if (dgv.Rows.Count == 0)
                return false;
            //建立Excel对象
            Excel.Application excel = new Excel.Application();
            excel.Application.Workbooks.Add(true);
            excel.Visible = isShowExcle;
            //生成字段名称
            for (int i = 0; i < dgv.ColumnCount; i++)
            {
                excel.Cells[1, i + 1] = dgv.Columns[i].HeaderText.ToString();
            }
            //填充数据
            for (int i = 0; i < dgv.RowCount - 1; i++)
            {
                for (int j = 0; j < dgv.ColumnCount; j++)
                {
                    if (dgv[j, i].Value == null)
                    {
                        excel.Cells[i + 2, j + 1] = "";
                    }
                    else
                    {
                        excel.Cells[i + 2, j + 1] = dgv[j, i].Value.ToString();
                    }
                }
            }
            excel.Columns.AutoFit();//调整excle列宽自适应数据
            excel.Cells.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;//平差数水平居中  
            Excel.Range range = excel.Range["A" + (dgv.RowCount + 2), "K" + (dgv.RowCount + 12)];//指定表格后一片区域
            range.Merge();//将指定区域单元格合并
            range.Value = text;//在合并的单元格加上平差限差信息,text是string类型数据,存储限差信息
            range.HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft;//限差信息左对齐
            return true;
        }

  调用上面的类的代码如下:

private void 输出结果ToolStripMenuItem_Click(object sender, EventArgs e)//导出结果到excel
        {
            try
            {
                bool isShowExcle = true;
                DataGridviewShowToExcel(dataGridView1, isShowExcle);
            }
            catch
            {
                MessageBox.Show("操作失败,您的电脑可能没有安装Microsoft Excel。");
            }
        }

  点击“导出结果”—“导出到Excel”,程序会自动将平差数据写入Microsoft Excel表格,如果您的电脑系统未安装Microsoft Excel程序,会弹出提示并停止导出。导出的数据格式与程序自带表格显示的数据格式一致,并且会附带平差的限差信息。导出到Excel的示例数据如下图:
在这里插入图片描述
  点击顶层导航栏的“绘图”按钮,即可切换到绘图模块,在平差完成后,切换到绘图模块,点击“绘图”按钮,即可绘制导线路线示意图并在程序界面显示,如下图:
在这里插入图片描述
  图中,蓝色三角形图标代表已知点,绿色圆心图标代表待求导线点,每个点上面均标注了点号与坐标。如果没有平差数据,点击“绘图”按钮会弹出提示并停止绘图。点击“保存”按钮,设置好文件名,可将绘制的导线路线示意图保存为jpg格式的图片。
  绘图的基本思路就是根据平差出来的坐标获取坐标范围的长宽值,然后根据pictureBox的长宽值确定坐标值缩放比例。
  点击“使用说明”按钮,会打开本程序的使用说明,使用说明为PDF格式。
程序使用GIF图如下:
在这里插入图片描述

5、程序源代码

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;
using System.Reflection;
using Excel = Microsoft.Office.Interop.Excel;


namespace 导线内业平差
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            this.skinEngine1 = new Sunisoft.IrisSkin.SkinEngine(((System.ComponentModel.Component)(this)));//调用IrisSkin绘制皮肤
            this.skinEngine1.SkinFile = Application.StartupPath + @"\skins\office2007.ssk";
            Sunisoft.IrisSkin.SkinEngine se = null;
            se = new Sunisoft.IrisSkin.SkinEngine();
            InitializeComponent();
        }

        List<Point> Points = new List<Point>();//储存观测值
        List<Point> PointsA = new List<Point>();//储存已知点坐标数据
        class Point//储存观测数据
        {
            public string dianhao;
            //原始度数数据
            public double Ddegree;//十进制角度
            public int degree;//度
            public int minute;//分
            public double second;//秒
            //改正后的度数数据
            public double GDdegree;//十进制角度
            public int Gdegree;//度
            public int Gminute;//分
            public double Gsecond;//秒
            //方位角
            public int Fdegree;//角度制方位角
            public int Fminute;
            public double Fsecond;
            public double FDdegree;//十进制角度方位角
            public double rad = 0;//弧度制方位角
            public double AngleGai;//角度闭合差改正值(单位为分)
            public double AngleGai2;//角度闭合差改正值(单位为度,采用十进制度数)
            public double pingju;//上一点与该点的平距
            public double DeltaX;//坐标增量
            public double DeltaY;
            public double Xgai;//坐标闭合差改正数
            public double Ygai;
            public double DeltaXgai;//改正后坐标增量
            public double DeltaYgai;
            public double x;//平差后坐标值
            public double y;
        }




      public  string text;//记录超限数据
       
      
        private void button1_Click(object sender, EventArgs e)//计算
        {
            string s = comboBox2.Text;
            string s2=comboBox1.Text;
            string s3 = comboBox3.Text;
            double JDBH;//角度闭合差限差
            double QCBH;//导线全长相对闭合差;            
            double f;//坐标闭合差平方         
            //计算坐标增量
            //如果使用double类型,分配坐标闭合差时会存在误差,所以这里使用decimal类型增加计算精度
            decimal  Xcha = 0.0m;//坐标闭合差
            decimal  Ycha = 0.0m;
            double sum_ping = 0.0;//平距和
            decimal sum_x = 0.0m;//已分配的坐标闭合差和
            decimal sum_y = 0.0m;
              double Angle_sum=0.0;//理论角度和
        double Angle_sum2 = 0.0;//真实角度和
         double Angle_cha=0.0;//角度闭合差
         double Angle_cha2=0.0;//已分配的角度闭合差(秒)
            switch (s)
            {
                case "闭合导线(一点一方向)":


                    //计算、分配角度闭合差
                    Angle_sum = (Points.Count() - 2) * 180.0;//计算理论角度和
                    for (int i = 0; i < Points.Count(); i++)
                    {
                        Angle_sum2 += Points[i].Ddegree;//计算真实角度和
                    }
                    Angle_cha = Angle_sum2 - Angle_sum;//计算角度闭合差
                    for (int i = 0; i < Points.Count()-1; i++)//分配角度闭合差
                    {
                        Points[i].AngleGai2 = - Angle_cha / Convert.ToDouble(Points.Count());//角度闭合差(度)
                        Points[i].AngleGai =Math.Round( Points[i].AngleGai2 * 3600.0);//角度闭合性差(秒)
                        Angle_cha2 += Points[i].AngleGai;//已分配的角度闭合差
                        Points[i].GDdegree = Points[i].Ddegree + Points[i].AngleGai/3600.0;
                        Points[i].Gdegree = Convert.ToInt32(Math.Floor(Points[i].GDdegree));
                        Points[i].Gminute = Convert.ToInt32(Math.Floor((Points[i].GDdegree - Points[i].Gdegree) * 60));
                        Points[i].Gsecond = Math.Round(Points[i].GDdegree * 3600.0 - Points[i].Gdegree * 3600.0 - Points[i].Gminute * 60.0, 3);
                    }

                     Points[Points.Count()-1].AngleGai =Math.Round(- Angle_cha *3600.0-Angle_cha2);//角度闭合性差(秒)

                     Points[Points.Count() - 1].GDdegree = Points[Points.Count() - 1].Ddegree + Points[Points.Count() - 1].AngleGai/3600.0;
                     Points[Points.Count() - 1].Gdegree = Convert.ToInt32(Math.Floor(Points[Points.Count() - 1].GDdegree));
                     Points[Points.Count() - 1].Gminute = Convert.ToInt32(Math.Floor((Points[Points.Count() - 1].GDdegree - Points[Points.Count() - 1].Gdegree) * 60));
                     Points[Points.Count() - 1].Gsecond = Math.Round(Points[Points.Count() - 1].GDdegree * 3600.0 - Points[Points.Count() - 1].Gdegree * 3600.0 - Points[Points.Count() - 1].Gminute * 60.0, 3);

                    //方位角传递
                    for (int i = 0; i < Points.Count()-1; i++)//分配角度闭合差
                    {
                         s2 = comboBox1.Text;
                        if (i == 0)
                        {
                            switch(s2)
                            {
                                case "左角":
                            Points[i].FDdegree = PointsA[0].FDdegree + 180.0 + Points[i].GDdegree;
                            break;
                                case "右角":
                            Points[i].FDdegree = PointsA[0].FDdegree + 180.0 - Points[i].GDdegree;
                            break;

                            default:
                            MessageBox.Show("请选择转折角类型");
                            return;
                        }
                        }
                        else
                        {
                            switch (s2)
                            {
                                case "左角":
                                    Points[i].FDdegree = Points[i - 1].FDdegree + 180.0 + Points[i].GDdegree;
                                    break;
                                case "右角":
                                    Points[i].FDdegree = Points[i - 1].FDdegree + 180.0 - Points[i].GDdegree;
                                    break;
                                default:
                                    MessageBox.Show("请选择转折角类型");
                                    return;
                            }
                        }
                        if (Points[i].FDdegree < 0)
                        {
                            Points[i].FDdegree = Points[i].FDdegree + 360.0;
                        }
                        else if (Points[i].FDdegree > 360.0)
                        {

                            Points[i].FDdegree = Points[i].FDdegree - 360.0;
                        }
                        else
                        {
                            Points[i].FDdegree = Points[i].FDdegree;
                        }
                        Points[i].Fdegree = Convert.ToInt32(Math.Floor(Points[i].FDdegree));
                        Points[i].Fminute = Convert.ToInt32(Math.Floor(((Points[i].FDdegree - Points[i].Fdegree) * 60)));
                        Points[i].Fsecond = Math.Round(Points[i].FDdegree * 3600.0 - Points[i].Fdegree * 3600.0 - Points[i].Fminute * 60.0, 3);
                        Points[i].rad = (Points[i].FDdegree / 180.0) * Math.PI;
                    }
                    if (PointsA[0].FDdegree <= 90.0)
                    {
                        Points[0].DeltaX = Math.Round(Math.Abs(Points[0].pingju * Math.Cos(PointsA[0].rad)), 3);
                        Points[0].DeltaY = Math.Round(Math.Abs(Points[0].pingju * Math.Sin(PointsA[0].rad)), 3);
                    }
                    else if (PointsA[0].FDdegree > 90.0 && PointsA[0].FDdegree <= 180.0)
                    {
                        Points[0].DeltaX = Math.Round(-Math.Abs(Points[0].pingju * Math.Cos(PointsA[0].rad)), 3);
                        Points[0].DeltaY = Math.Round(Math.Abs(Points[0].pingju * Math.Sin(PointsA[0].rad)), 3);
                    }
                    else if (PointsA[0].FDdegree > 180.0 && PointsA[0].FDdegree <= 270.0)
                    {
                        Points[0].DeltaX = Math.Round(-Math.Abs(Points[0].pingju * Math.Cos(PointsA[0].rad)), 3);
                        Points[0].DeltaY = Math.Round(-Math.Abs(Points[0].pingju * Math.Sin(PointsA[0].rad)), 3);
                    }
                    else if (PointsA[0].FDdegree > 270.0 && PointsA[0].FDdegree <= 360.0)
                    {
                        Points[0].DeltaX = Math.Round(Math.Abs(Points[0].pingju * Math.Cos(PointsA[0].rad)), 3);
                        Points[0].DeltaY = Math.Round(-Math.Abs(Points[0].pingju * Math.Sin(PointsA[0].rad)), 3);
                    }
                    else
                    {
                        MessageBox.Show("存在超出范围的方位角,数据存在问题!");

                    }
                    Xcha +=Convert.ToDecimal(Points[0].DeltaX);
                    Ycha += Convert.ToDecimal(Points[0].DeltaY);
                    sum_ping += Points[0].pingju;
                    for (int i = 1; i < Points.Count(); i++)//计算坐标增量
                    {
                        if (Points[i - 1].FDdegree <= 90.0)
                        {
                            Points[i].DeltaX = Math.Round(Math.Abs(Points[i].pingju * Math.Cos(Points[i - 1].rad)), 3);
                            Points[i].DeltaY = Math.Round(Math.Abs(Points[i].pingju * Math.Sin(Points[i - 1].rad)), 3);
                        }
                        else if (Points[i - 1].FDdegree > 90.0 && Points[i - 1].FDdegree <= 180.0)
                        {
                            Points[i].DeltaX = Math.Round(-Math.Abs(Points[i].pingju * Math.Cos(Points[i - 1].rad)), 3);
                            Points[i].DeltaY = Math.Round(Math.Abs(Points[i].pingju * Math.Sin(Points[i - 1].rad)), 3);
                        }
                        else if (Points[i - 1].FDdegree > 180.0 && Points[i - 1].FDdegree <= 270.0)
                        {
                            Points[i].DeltaX = Math.Round(-Math.Abs(Points[i].pingju * Math.Cos(Points[i - 1].rad)), 3);
                            Points[i].DeltaY = Math.Round(-Math.Abs(Points[i].pingju * Math.Sin(Points[i - 1].rad)), 3);
                        }
                        else if (Points[i - 1].FDdegree > 270.0 && Points[i - 1].FDdegree <= 360.0)
                        {
                            Points[i].DeltaX = Math.Round(Math.Abs(Points[i].pingju * Math.Cos(Points[i - 1].rad)), 3);
                            Points[i].DeltaY = Math.Round(-Math.Abs(Points[i].pingju * Math.Sin(Points[i - 1].rad)), 3);
                        }
                        else
                        {
                            MessageBox.Show("存在超出范围的方位角,数据存在问题!");
                            break;
                        }
                        Xcha += Convert.ToDecimal( Points[i].DeltaX);
                        Ycha +=Convert.ToDecimal(Points[i].DeltaY);
                        sum_ping += Points[i].pingju;
                    }
                    for (int i = 0; i < Points.Count() - 1; i++)//分配坐标闭合差
                    {
                        Points[i].Xgai = Math.Round(-Convert.ToDouble(Xcha) * (Points[i].pingju / sum_ping), 3);
                        Points[i].Ygai = Math.Round(-Convert.ToDouble(Ycha) * (Points[i].pingju / sum_ping), 3);
                        sum_x += Convert.ToDecimal(Points[i].Xgai);
                        sum_y +=Convert.ToDecimal(Points[i].Ygai);
                    }
                    Points[Points.Count() - 1].Xgai = Convert.ToDouble(-Xcha - sum_x);
                    Points[Points.Count() - 1].Ygai =Convert.ToDouble( -Ycha - sum_y);
                    for (int i = 0; i < Points.Count(); i++)//计算改正后坐标增量,j计算改正后坐标
                    {
                        if (i == 0)
                        {
                            Points[i].DeltaXgai = Math.Round(Points[i].DeltaX + Points[i].Xgai, 4);
                            Points[i].DeltaYgai = Math.Round(Points[i].DeltaY + Points[i].Ygai, 4);
                            Points[i].x = PointsA[0].x + Points[i].DeltaXgai;
                            Points[i].y = PointsA[0].y + Points[i].DeltaYgai;
                        }
                        else
                        {
                            Points[i].DeltaXgai = Math.Round(Points[i].DeltaX + Points[i].Xgai, 4);
                            Points[i].DeltaYgai = Math.Round(Points[i].DeltaY + Points[i].Ygai, 4);
                            Points[i].x = Points[i - 1].x + Points[i].DeltaXgai;
                            Points[i].y = Points[i - 1].y + Points[i].DeltaYgai;
                        }
                    }
                    //判断是否超限
                    switch (s3)
                    {
                        case "三等":
                            text = "导线计算结果如下:"+"\r\n";
                            text += "当前导线模式为:" + "闭合导线(一点一方向)" + "\r\n";
                            text += "当前导线等级为:" + "三等"  + "\r\n";
                            if (sum_ping / 1000.0 > 15.0)
                            {
                                text += "导线长度为:" + sum_ping/1000.0 + "(km)" + ">15(km)" + "  (超限)" + "\r\n";
                            }
                            else
                            {
                                text += text += "导线长度为:" + sum_ping/1000.0 + "(km)" + "<=15(km)" + "  (合格)" + "\r\n";
                            }
                            if (Math.Abs(Angle_cha * 3600.0) > Math.Sqrt(Points.Count() + 1) * 3.0)
                            {
                                text += "方位角闭合差为:" +Math.Round( Angle_cha  * 3600.0,3) + "(秒)" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 3.0 + "(秒)(超限)" + "\r\n";

                            }
                            else
                            {
                                text += "方位角闭合差为:" +Math.Round( Angle_cha  * 3600.0,3) + "秒" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 3.0 + "(合格)" + "\r\n";
                            }
                          f=Math.Pow(Convert.ToDouble(Xcha),2)+Math.Pow(Convert.ToDouble (Ycha),2.0);
                            text+="X闭合差:"+Xcha+"(m)"+"\r\n"+"Y闭合差:"+Ycha+"(m)"+"\r\n"+"坐标闭合差f:"+Math.Sqrt(f)+"(m)"+"\r\n";
                             QCBH=sum_ping/Math.Sqrt(f);//导线全长相对闭合差的倒数
                             if (QCBH < 60000.0)
                             {
                                 text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/60000(超限)" + "\r\n";
                             }
                             else
                             {
                                 text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/60000(合格)" + "\r\n";
                             }

                            break;
                        case"四等":
                             text = "导线计算结果如下:"+"\r\n";
                            text += "当前导线模式为:" + "闭合导线(一点一方向)" + "\r\n";
                            text += "当前导线等级为:" + "四等"  + "\r\n";
                            if (sum_ping / 1000.0 > 10.0)
                            {
                                text += "导线长度为:" + sum_ping/1000.0 + "(km)" + ">10(km)" + "  (超限)" + "\r\n";
                            }
                            else
                            {
                                text += text += "导线长度为:" + sum_ping/1000.0 + "(km)" + "<=10(km)" + "  (合格)" + "\r\n";
                            }
                            if (Math.Abs(Angle_cha * 3600.0) > Math.Sqrt(Points.Count() + 1) * 5.0)
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha  * 3600.0,3) + "(秒)" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 5.0 + "(秒)(超限)" + "\r\n";

                            }
                            else
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha  * 3600.0,3) + "秒" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 5.0 + "(合格)" + "\r\n";
                            }
                          f=Math.Pow(Convert.ToDouble(Xcha),2)+Math.Pow(Convert.ToDouble (Ycha),2.0);
                            text+="X闭合差:"+Xcha+"(m)"+"\r\n"+"Y闭合差:"+Ycha+"(m)"+"\r\n"+"坐标闭合差f:"+Math.Sqrt(f)+"(m)"+"\r\n";
                             QCBH=sum_ping/Math.Sqrt(f);//导线全长相对闭合差的倒数
                             if (QCBH < 40000.0)
                             {
                                 text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/40000(超限)" + "\r\n";
                             }
                             else
                             {
                                 text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/40000(合格)" + "\r\n";
                             }
                             break;
                        case"一级":
                             text = "导线计算结果如下:"+"\r\n";
                            text += "当前导线模式为:" + "闭合导线(一点一方向)" + "\r\n";
                            text += "当前导线等级为:" + "一级"  + "\r\n";
                            if (sum_ping / 1000.0 > 3.6)
                            {
                                text += "导线长度为:" + sum_ping/1000.0 + "(km)" + ">3.6(km)" + "  (超限)" + "\r\n";
                            }
                            else
                            {
                                text += text += "导线长度为:" + sum_ping/1000.0 + "(km)" + "<=3.6(km)" + "  (合格)" + "\r\n";
                            }
                            if (Math.Abs(Angle_cha * 3600.0) > Math.Sqrt(Points.Count() + 1) * 10.0)
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha  * 3600.0,3) + "(秒)" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 10.0 + "(秒)(超限)" + "\r\n";

                            }
                            else
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha  * 3600.0,3) + "秒" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 10.0 + "(合格)" + "\r\n";
                            }
                          f=Math.Pow(Convert.ToDouble(Xcha),2)+Math.Pow(Convert.ToDouble (Ycha),2.0);
                            text+="X闭合差:"+Xcha+"(m)"+"\r\n"+"Y闭合差:"+Ycha+"(m)"+"\r\n"+"坐标闭合差f:"+Math.Sqrt(f)+"(m)"+"\r\n";
                             QCBH=sum_ping/Math.Sqrt(f);//导线全长相对闭合差的倒数
                             if (QCBH < 14000.0)
                             {
                                 text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/14000(超限)" + "\r\n";
                             }
                             else
                             {
                                 text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/14000(合格)" + "\r\n";
                             }
                             break;
                        case"二级":
                             text = "导线计算结果如下:"+"\r\n";
                            text += "当前导线模式为:" + "闭合导线(一点一方向)" + "\r\n";
                            text += "当前导线等级为:" + "二级"  + "\r\n";
                            if (sum_ping / 1000.0 >2.4)
                            {
                                text += "导线长度为:" + sum_ping/1000.0 + "(km)" + ">2.4(km)" + "  (超限)" + "\r\n";
                            }
                            else
                            {
                                text += text += "导线长度为:" + sum_ping/1000.0 + "(km)" + "<=2.4(km)" + "  (合格)" + "\r\n";
                            }
                            if (Math.Abs(Angle_cha * 3600.0) > Math.Sqrt(Points.Count() + 1) * 16.0)
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha  * 3600.0,3) + "(秒)" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 16.0 + "(秒)(超限)" + "\r\n";

                            }
                            else
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha  * 3600.0,3) + "秒" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 16.0 + "(合格)" + "\r\n";
                            }
                          f=Math.Pow(Convert.ToDouble(Xcha),2)+Math.Pow(Convert.ToDouble (Ycha),2.0);
                            text+="X闭合差:"+Xcha+"(m)"+"\r\n"+"Y闭合差:"+Ycha+"(m)"+"\r\n"+"坐标闭合差f:"+Math.Sqrt(f)+"(m)"+"\r\n";
                             QCBH=sum_ping/Math.Sqrt(f);//导线全长相对闭合差的倒数
                             if (QCBH < 10000.0)
                             {
                                 text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/10000(超限)" + "\r\n";
                             }
                             else
                             {
                                 text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/10000(合格)" + "\r\n";
                             }
                             break;
                        case"三级":
                               text = "导线计算结果如下:"+"\r\n";
                            text += "当前导线模式为:" + "闭合导线(一点一方向)" + "\r\n";
                            text += "当前导线等级为:" + "三级"  + "\r\n";
                            if (sum_ping / 1000.0 >1.5)
                            {
                                text += "导线长度为:" + sum_ping/1000.0 + "(km)" + ">1.5(km)" + "  (超限)" + "\r\n";
                            }
                            else
                            {
                                text += text += "导线长度为:" + sum_ping/1000.0 + "(km)" + "<=1.5(km)" + "  (合格)" + "\r\n";
                            }
                            if (Math.Abs(Angle_cha * 3600.0) > Math.Sqrt(Points.Count() + 1) * 24.0)
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha  * 3600.0,3) + "(秒)" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 24.0 + "(秒)(超限)" + "\r\n";

                            }
                            else
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha  * 3600.0,3) + "秒" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 24.0 + "(合格)" + "\r\n";
                            }
                          f=Math.Pow(Convert.ToDouble(Xcha),2)+Math.Pow(Convert.ToDouble (Ycha),2.0);
                            text+="X闭合差:"+Xcha+"(m)"+"\r\n"+"Y闭合差:"+Ycha+"(m)"+"\r\n"+"坐标闭合差f:"+Math.Sqrt(f)+"(m)"+"\r\n";
                             QCBH=sum_ping/Math.Sqrt(f);//导线全长相对闭合差的倒数
                             if (QCBH < 6000.0)
                             {
                                 text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/6000(超限)" + "\r\n";
                             }
                             else
                             {
                                 text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/6000(合格)" + "\r\n";
                             }
                             break;



                        default:
                            MessageBox.Show("请选择导线等级!");
                            return;
                    }

                    richTextBox1.Text += text;
                    break;

                case "闭合导线(两个已知点)":
                    //根据已知点计算方位角
          
                    double x3, y3;
                    y3 = PointsA[1].y - PointsA[0].y;
                    x3 = PointsA[1].x - PointsA[0].x;

                    if (x3 > 0 && y3 >= 0)//x、y差都大于0,方位角等于atan
                    {
                        PointsA[0].rad = Math.Atan(Math.Abs(y3 / x3));
                    }
                    else if (x3 < 0 && y3 >= 0) //x差小于0,y差大于或等于0,方位角等于PI减atan
                    {
                        PointsA[0].rad = Math.PI - Math.Atan(Math.Abs(y3 / x3));
                    }
                    else if (x3 > 0 && y3 < 0) //x差大于0,y差小于0,方位角等于2PI减atan
                    {
                        PointsA[0].rad = 2 * Math.PI - Math.Atan(Math.Abs(y3 / x3));
                    }
                    else if (x3 < 0 && y3 < 0)//x、y差都小于0,方位角等于PI加atan
                    {
                        PointsA[0].rad = Math.PI + Math.Atan(Math.Abs(y3 / x3));
                    }
                    else
                    {
                        PointsA[0].rad = 2 * Math.PI - Math.Atan(Math.Abs(y3 / x3));
                    }
                    PointsA[0].FDdegree = PointsA[0].rad / Math.PI * 180.0;
                    PointsA[0].Fdegree = Convert.ToInt32(Math.Floor(PointsA[0].FDdegree));
                      PointsA[0].Fminute = Convert.ToInt32(Math.Floor(((PointsA[0].FDdegree - PointsA[0].Fdegree) * 60)));
                        PointsA[0].Fsecond = Math.Round(PointsA[0].FDdegree * 3600.0 - PointsA[0].Fdegree * 3600.0 - PointsA[0].Fminute * 60.0, 3);
                     
                
                
                
                
                //计算、分配角度闭合差
                    sum_ping = 0.0;//平距和
                    Angle_cha2 = 0.0;//已分配角度闭合差(秒)
                    Angle_sum = (Points.Count() - 2) * 180.0;//计算理论角度和
                    for (int i = 0; i < Points.Count(); i++)
                    {
                        Angle_sum2 += Points[i].Ddegree;//计算真实角度和
                    }
                    for (int i = 0; i < Points.Count(); i++)//计算平距和
                    {
                        sum_ping += Points[i].pingju;
                    }
                    Angle_cha = Angle_sum2 - Angle_sum;//计算角度闭合差
                    for (int i = 0; i < Points.Count()-1; i++)//分配角度闭合差
                    {
                        Points[i].AngleGai2 = -Angle_cha / Convert.ToDouble(Points.Count());//角度闭合差(度)
                        Points[i].AngleGai = Math.Round(Points[i].AngleGai2 * 3600.0);//角度闭合性差(秒)
                        Angle_cha2 += Points[i].AngleGai;//已分配的角度闭合差
                  
                        Points[i].GDdegree = Points[i].Ddegree + Points[i].AngleGai/3600.0;
                        Points[i].Gdegree = Convert.ToInt32(Math.Floor(Points[i].GDdegree));
                        Points[i].Gminute = Convert.ToInt32(Math.Floor((Points[i].GDdegree - Points[i].Gdegree) * 60));
                        Points[i].Gsecond = Math.Round(Points[i].GDdegree * 3600.0 - Points[i].Gdegree * 3600.0 - Points[i].Gminute * 60.0, 3);
                    }
                    Points[Points.Count() - 1].AngleGai2 = -Angle_cha - Angle_cha2 / 3600.0;
                     Points[ Points.Count()-1].AngleGai = Math.Round(Points[ Points.Count()-1].AngleGai2 * 3600.0, 3);//角度闭合性差(秒)
                     Points[Points.Count() - 1].GDdegree = Points[Points.Count() - 1].Ddegree + Points[Points.Count() - 1].AngleGai2;
                     Points[Points.Count() - 1].Gdegree = Convert.ToInt32(Math.Floor(Points[Points.Count() - 1].GDdegree));
                     Points[Points.Count() - 1].Gminute = Convert.ToInt32(Math.Floor((Points[Points.Count() - 1].GDdegree - Points[Points.Count() - 1].Gdegree) * 60));
                     Points[Points.Count() - 1].Gsecond = Math.Round(Points[Points.Count() - 1].GDdegree * 3600.0 - Points[Points.Count() - 1].Gdegree * 3600.0 - Points[Points.Count() - 1].Gminute * 60.0, 3);

                    //方位角传递
                     s2 = comboBox1.Text;
                    switch(s2)
                    {
                        case"右角":
                    PointsA[1].FDdegree = PointsA[0].FDdegree + 180.0 - PointsA[1].Ddegree;
                    break;
                        case"左角":
                    PointsA[1].FDdegree = PointsA[0].FDdegree + 180.0 +PointsA[1].Ddegree;
                    break;
                        default:
                    MessageBox.Show("已知点方位角传递出现错误");
                    return;
            }
                    if (PointsA[1].FDdegree < 0)
                    {
                        PointsA[1].FDdegree = PointsA[1].FDdegree + 360.0;
                    }
                    else if (PointsA[1].FDdegree > 360.0)
                    {

                        PointsA[1].FDdegree = PointsA[1].FDdegree - 360.0;
                    }
                    else
                    {
                        PointsA[1].FDdegree = PointsA[1].FDdegree;
                    }
                     PointsA[1].Fdegree = Convert.ToInt32(Math.Floor(PointsA[1].FDdegree));
                        PointsA[1].Fminute = Convert.ToInt32(Math.Floor(((PointsA[1].FDdegree - PointsA[1].Fdegree) * 60)));
                        PointsA[1].Fsecond = Math.Round(PointsA[1].FDdegree * 3600.0 - PointsA[1].Fdegree * 3600.0 - PointsA[1].Fminute * 60.0, 3);
                        PointsA[1].rad = (PointsA[1].FDdegree / 180.0) * Math.PI;
                    for (int i = 0; i < Points.Count()-1; i++)//
                    {
                        if (i == 0)
                        {
                            switch (s2)
                            {
                                case "右角":
                                    Points[i].FDdegree = PointsA[1].FDdegree + 180.0 - Points[i].GDdegree;
                                    break;
                                case "左角":
                                    Points[i].FDdegree = PointsA[1].FDdegree + 180.0 + Points[i].GDdegree;
                                    break;

                                default:
                                    MessageBox.Show("请选择转折角类型");
                                    return;
                            }
                        }
                        else
                        {
                            switch (s2)
                            {
                                case "右角":
                                    Points[i].FDdegree = Points[i - 1].FDdegree + 180.0 - Points[i].GDdegree;
                                    break;
                                case "左角":
                                    Points[i].FDdegree = Points[i - 1].FDdegree + 180.0 +Points[i].GDdegree;
                                    break;

                                default:
                                    MessageBox.Show("请选择转折角类型");
                                    return;
                            }
                        }
                        if (Points[i].FDdegree < 0)
                        {
                            Points[i].FDdegree = Points[i].FDdegree + 360.0;
                        }
                        else if (Points[i].FDdegree > 360.0)
                        {

                            Points[i].FDdegree = Points[i].FDdegree - 360.0;
                        }
                        else
                        {
                            Points[i].FDdegree = Points[i].FDdegree;
                        }
                        Points[i].Fdegree = Convert.ToInt32(Math.Floor(Points[i].FDdegree));
                        Points[i].Fminute = Convert.ToInt32(Math.Floor(((Points[i].FDdegree - Points[i].Fdegree) * 60)));
                        Points[i].Fsecond = Math.Round(Points[i].FDdegree * 3600.0 - Points[i].Fdegree * 3600.0 - Points[i].Fminute * 60.0, 3);
                        Points[i].rad = (Points[i].FDdegree / 180.0) * Math.PI;

                    }
                    if (PointsA[1].FDdegree <= 90.0)
                    {
                        Points[0].DeltaX = Math.Round(Math.Abs(Points[0].pingju * Math.Cos(PointsA[1].rad)), 4);
                        Points[0].DeltaY = Math.Round(Math.Abs(Points[0].pingju * Math.Sin(PointsA[1].rad)), 4);
                    }
                    else if (PointsA[1].FDdegree > 90.0 && PointsA[0].FDdegree <= 180.0)
                    {
                        Points[0].DeltaX = Math.Round(-Math.Abs(Points[0].pingju * Math.Cos(PointsA[1].rad)), 4);
                        Points[0].DeltaY = Math.Round(Math.Abs(Points[0].pingju * Math.Sin(PointsA[1].rad)), 4);
                    }
                    else if (PointsA[1].FDdegree > 180.0 && PointsA[1].FDdegree <= 270.0)
                    {
                        Points[0].DeltaX = Math.Round(-Math.Abs(Points[0].pingju * Math.Cos(PointsA[1].rad)), 4);
                        Points[0].DeltaY = Math.Round(-Math.Abs(Points[0].pingju * Math.Sin(PointsA[1].rad)), 4);
                    }
                    else if (PointsA[1].FDdegree > 270.0 && PointsA[1].FDdegree <= 360.0)
                    {
                        Points[0].DeltaX = Math.Round(Math.Abs(Points[0].pingju * Math.Cos(PointsA[1].rad)), 4);
                        Points[0].DeltaY = Math.Round(-Math.Abs(Points[0].pingju * Math.Sin(PointsA[1].rad)), 4);
                    }
                    else
                    {
                        MessageBox.Show("存在超出范围的方位角,数据存在问题!");

                    }
                    Xcha +=Convert.ToDecimal( Points[0].DeltaX);
                    Ycha +=Convert.ToDecimal( Points[0].DeltaY);                    
                    for (int i = 1; i < Points.Count(); i++)//计算坐标增量
                    {
                        if (Points[i - 1].FDdegree <= 90.0)
                        {
                            Points[i].DeltaX = Math.Round(Math.Abs(Points[i].pingju * Math.Cos(Points[i - 1].rad)), 4);
                            Points[i].DeltaY = Math.Round(Math.Abs(Points[i].pingju * Math.Sin(Points[i - 1].rad)), 4);
                        }
                        else if (Points[i - 1].FDdegree > 90.0 && Points[i - 1].FDdegree <= 180.0)
                        {
                            Points[i].DeltaX = Math.Round(-Math.Abs(Points[i].pingju * Math.Cos(Points[i - 1].rad)), 4);
                            Points[i].DeltaY = Math.Round(Math.Abs(Points[i].pingju * Math.Sin(Points[i - 1].rad)), 4);
                        }
                        else if (Points[i - 1].FDdegree > 180.0 && Points[i - 1].FDdegree <= 270.0)
                        {
                            Points[i].DeltaX = Math.Round(-Math.Abs(Points[i].pingju * Math.Cos(Points[i - 1].rad)), 4);
                            Points[i].DeltaY = Math.Round(-Math.Abs(Points[i].pingju * Math.Sin(Points[i - 1].rad)), 4);
                        }
                        else if (Points[i - 1].FDdegree > 270.0 && Points[i - 1].FDdegree <= 360.0)
                        {
                            Points[i].DeltaX = Math.Round(Math.Abs(Points[i].pingju * Math.Cos(Points[i - 1].rad)), 4);
                            Points[i].DeltaY = Math.Round(-Math.Abs(Points[i].pingju * Math.Sin(Points[i - 1].rad)), 4);
                        }
                        else
                        {
                            MessageBox.Show("存在超出范围的方位角,数据存在问题!");
                            break;
                        }
                        Xcha +=Math.Round( Convert.ToDecimal(Points[i].DeltaX),4);
                        Ycha +=Math.Round( Convert.ToDecimal(Points[i].DeltaY),4);                      
                    }
                    for (int i = 0; i < Points.Count()-1; i++)//分配坐标闭合差
                    {
                        Points[i].Xgai = Math.Round(-Convert.ToDouble(Xcha) * (Points[i].pingju / sum_ping), 4);
                        Points[i].Ygai = Math.Round(-Convert.ToDouble(Ycha) * (Points[i].pingju / sum_ping), 4);
                        sum_x += Math.Round(Convert.ToDecimal(Points[i].Xgai),4);
                        sum_y +=Math.Round(Convert.ToDecimal(Points[i].Ygai),4);
                    }
                    Points[Points.Count() - 1].Xgai = Math.Round(Convert.ToDouble(-Xcha - sum_x), 4);
                   Points[Points.Count() -1].Ygai = Math.Round(Convert.ToDouble(-Ycha - sum_y),4);
                    for (int i = 0; i < Points.Count(); i++)//计算改正后坐标增量,j计算改正后坐标
                    {
                        if (i == 0)
                        {
                            Points[i].DeltaXgai = Math.Round(Points[i].DeltaX + Points[i].Xgai, 4);
                            Points[i].DeltaYgai = Math.Round(Points[i].DeltaY + Points[i].Ygai, 4);
                            Points[i].x =Math.Round( PointsA[1].x + Points[i].DeltaXgai,4);
                            Points[i].y = Math.Round(PointsA[1].y + Points[i].DeltaYgai,4);
                        }
                        else
                        {
                            Points[i].DeltaXgai = Math.Round(Points[i].DeltaX + Points[i].Xgai, 4);
                            Points[i].DeltaYgai = Math.Round(Points[i].DeltaY + Points[i].Ygai, 4);
                            Points[i].x = Math.Round(Points[i - 1].x + Points[i].DeltaXgai,4);
                            Points[i].y = Math.Round(Points[i - 1].y + Points[i].DeltaYgai,4);
                        }
                    }
                    //判断是否超限
                    //判断是否超限
                    switch (s3)
                    {
                        case "三等":
                            text = "导线计算结果如下:" + "\r\n";
                            text += "当前导线模式为:" + "闭合导线(一点一方向)" + "\r\n";
                            text += "当前导线等级为:" + "三等" + "\r\n";
                            if (sum_ping / 1000.0 > 15.0)
                            {
                                text += "导线长度为:" + sum_ping / 1000.0 + "(km)" + ">15(km)" + "  (超限)" + "\r\n";
                            }
                            else
                            {
                                text += text += "导线长度为:" + sum_ping / 1000.0 + "(km)" + "<=15(km)" + "  (合格)" + "\r\n";
                            }
                            if (Math.Abs(Angle_cha * 3600.0) > Math.Sqrt(Points.Count() + 1) * 3.0)
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha * 3600.0, 3) + "(秒)" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 3.0 + "(秒)(超限)" + "\r\n";

                            }
                            else
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha * 3600.0, 3) + "秒" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 3.0 + "(合格)" + "\r\n";
                            }
                            f = Math.Pow(Convert.ToDouble(Xcha), 2) + Math.Pow(Convert.ToDouble(Ycha), 2.0);
                            text += "X闭合差:" + Xcha + "(m)" + "\r\n" + "Y闭合差:" + Ycha + "(m)" + "\r\n" + "坐标闭合差f:" + Math.Sqrt(f) + "(m)" + "\r\n";
                            QCBH = sum_ping / Math.Sqrt(f);//导线全长相对闭合差的倒数
                            if (QCBH < 60000.0)
                            {
                                text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/60000(超限)" + "\r\n";
                            }
                            else
                            {
                                text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/60000(合格)" + "\r\n";
                            }

                            break;
                        case "四等":
                            text = "导线计算结果如下:" + "\r\n";
                            text += "当前导线模式为:" + "闭合导线(一点一方向)" + "\r\n";
                            text += "当前导线等级为:" + "四等" + "\r\n";
                            if (sum_ping / 1000.0 > 10.0)
                            {
                                text += "导线长度为:" + sum_ping / 1000.0 + "(km)" + ">10(km)" + "  (超限)" + "\r\n";
                            }
                            else
                            {
                                text += text += "导线长度为:" + sum_ping / 1000.0 + "(km)" + "<=10(km)" + "  (合格)" + "\r\n";
                            }
                            if (Math.Abs(Angle_cha * 3600.0) > Math.Sqrt(Points.Count() + 1) * 5.0)
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha * 3600.0, 3) + "(秒)" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 5.0 + "(秒)(超限)" + "\r\n";

                            }
                            else
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha * 3600.0, 3) + "秒" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 5.0 + "(合格)" + "\r\n";
                            }
                            f = Math.Pow(Convert.ToDouble(Xcha), 2) + Math.Pow(Convert.ToDouble(Ycha), 2.0);
                            text += "X闭合差:" + Xcha + "(m)" + "\r\n" + "Y闭合差:" + Ycha + "(m)" + "\r\n" + "坐标闭合差f:" + Math.Sqrt(f) + "(m)" + "\r\n";
                            QCBH = sum_ping / Math.Sqrt(f);//导线全长相对闭合差的倒数
                            if (QCBH < 40000.0)
                            {
                                text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/40000(超限)" + "\r\n";
                            }
                            else
                            {
                                text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/40000(合格)" + "\r\n";
                            }
                            break;
                        case "一级":
                            text = "导线计算结果如下:" + "\r\n";
                            text += "当前导线模式为:" + "闭合导线(一点一方向)" + "\r\n";
                            text += "当前导线等级为:" + "一级" + "\r\n";
                            if (sum_ping / 1000.0 > 3.6)
                            {
                                text += "导线长度为:" + sum_ping / 1000.0 + "(km)" + ">3.6(km)" + "  (超限)" + "\r\n";
                            }
                            else
                            {
                                text += text += "导线长度为:" + sum_ping / 1000.0 + "(km)" + "<=3.6(km)" + "  (合格)" + "\r\n";
                            }
                            if (Math.Abs(Angle_cha * 3600.0) > Math.Sqrt(Points.Count() + 1) * 10.0)
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha * 3600.0, 3) + "(秒)" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 10.0 + "(秒)(超限)" + "\r\n";

                            }
                            else
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha * 3600.0, 3) + "秒" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 10.0 + "(合格)" + "\r\n";
                            }
                            f = Math.Pow(Convert.ToDouble(Xcha), 2) + Math.Pow(Convert.ToDouble(Ycha), 2.0);
                            text += "X闭合差:" + Xcha + "(m)" + "\r\n" + "Y闭合差:" + Ycha + "(m)" + "\r\n" + "坐标闭合差f:" + Math.Sqrt(f) + "(m)" + "\r\n";
                            QCBH = sum_ping / Math.Sqrt(f);//导线全长相对闭合差的倒数
                            if (QCBH < 14000.0)
                            {
                                text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/14000(超限)" + "\r\n";
                            }
                            else
                            {
                                text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/14000(合格)" + "\r\n";
                            }
                            break;
                        case "二级":
                            text = "导线计算结果如下:" + "\r\n";
                            text += "当前导线模式为:" + "闭合导线(一点一方向)" + "\r\n";
                            text += "当前导线等级为:" + "二级" + "\r\n";
                            if (sum_ping / 1000.0 > 2.4)
                            {
                                text += "导线长度为:" + sum_ping / 1000.0 + "(km)" + ">2.4(km)" + "  (超限)" + "\r\n";
                            }
                            else
                            {
                                text += text += "导线长度为:" + sum_ping / 1000.0 + "(km)" + "<=2.4(km)" + "  (合格)" + "\r\n";
                            }
                            if (Math.Abs(Angle_cha * 3600.0) > Math.Sqrt(Points.Count() + 1) * 16.0)
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha * 3600.0, 3) + "(秒)" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 16.0 + "(秒)(超限)" + "\r\n";

                            }
                            else
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha * 3600.0, 3) + "秒" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 16.0 + "(合格)" + "\r\n";
                            }
                            f = Math.Pow(Convert.ToDouble(Xcha), 2) + Math.Pow(Convert.ToDouble(Ycha), 2.0);
                            text += "X闭合差:" + Xcha + "(m)" + "\r\n" + "Y闭合差:" + Ycha + "(m)" + "\r\n" + "坐标闭合差f:" + Math.Sqrt(f) + "(m)" + "\r\n";
                            QCBH = sum_ping / Math.Sqrt(f);//导线全长相对闭合差的倒数
                            if (QCBH < 10000.0)
                            {
                                text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/10000(超限)" + "\r\n";
                            }
                            else
                            {
                                text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/10000(合格)" + "\r\n";
                            }
                            break;
                        case "三级":
                            text = "导线计算结果如下:" + "\r\n";
                            text += "当前导线模式为:" + "闭合导线(一点一方向)" + "\r\n";
                            text += "当前导线等级为:" + "三级" + "\r\n";
                            if (sum_ping / 1000.0 > 1.5)
                            {
                                text += "导线长度为:" + sum_ping / 1000.0 + "(km)" + ">1.5(km)" + "  (超限)" + "\r\n";
                            }
                            else
                            {
                                text += text += "导线长度为:" + sum_ping / 1000.0 + "(km)" + "<=1.5(km)" + "  (合格)" + "\r\n";
                            }
                            if (Math.Abs(Angle_cha * 3600.0) > Math.Sqrt(Points.Count() + 1) * 24.0)
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha * 3600.0, 3) + "(秒)" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 24.0 + "(秒)(超限)" + "\r\n";

                            }
                            else
                            {
                                text += "方位角闭合差为:" + Math.Round(Angle_cha * 3600.0, 3) + "秒" + "  限差为:" + Math.Sqrt(Points.Count() + 1) * 24.0 + "(合格)" + "\r\n";
                            }
                            f = Math.Pow(Convert.ToDouble(Xcha), 2) + Math.Pow(Convert.ToDouble(Ycha), 2.0);
                            text += "X闭合差:" + Xcha + "(m)" + "\r\n" + "Y闭合差:" + Ycha + "(m)" + "\r\n" + "坐标闭合差f:" + Math.Sqrt(f) + "(m)" + "\r\n";
                            QCBH = sum_ping / Math.Sqrt(f);//导线全长相对闭合差的倒数
                            if (QCBH < 6000.0)
                            {
                                text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/6000(超限)" + "\r\n";
                            }
                            else
                            {
                                text += "导线全长相对闭合差:" + "1/" + QCBH + "限差为:1/6000(合格)" + "\r\n";
                            }
                            break;



                        default:
                            MessageBox.Show("请选择导线等级!");
                            return;
                    }

                    richTextBox1.Text += text;
                    
                 
                    break;



                default:
                    MessageBox.Show("无法完成计算!");
                    break;

            }




            GridBuild2();//显示计算结果
        }
        public void GridBuild2()//显示数据
        {
            string Datatype = comboBox2.Text;
            
            switch (Datatype)
            {
                case "闭合导线(一点一方向)":
                     
                    for (int i = 0; i < Points.Count(); i++)
                    {

                        dataGridView1.Rows[2 * i + 2].Cells[3].Value = Points[i].Gdegree + " " + Points[i].Gminute + " " + Points[i].Gsecond + " ";
                        dataGridView1.Rows[2 * i + 2].Cells[2].Value = Points[i].AngleGai;
                        dataGridView1.Rows[2 * i + 1].Cells[6].Value = "(" + Points[i].DeltaX + "," + Points[i].DeltaY + ")";
                        dataGridView1.Rows[2 * i + 1].Cells[7].Value = "(" + Points[i].Xgai + "," + Points[i].Ygai + ")";
                        dataGridView1.Rows[2 * i + 1].Cells[8].Value = "(" + Points[i].DeltaXgai + "," + Points[i].DeltaYgai + ")";
                        dataGridView1.Rows[2 * i + 2].Cells[9].Value = Points[i].x.ToString("0.0000");
                        dataGridView1.Rows[2 * i + 2].Cells[10].Value = Points[i].y.ToString("0.0000");
                    }
                    for (int i = 0; i < Points.Count()-1; i++)
                    {
                       
                        dataGridView1.Rows[2 * i + 3].Cells[4].Value = Points[i].Fdegree + " " + Points[i].Fminute + " " + Points[i].Fsecond + " ";
                        
                    }
                    break;
                case "闭合导线(两个已知点)":

                    for (int i = 0; i < Points.Count()-1; i++)
                    {
                        dataGridView1.Rows[2*i + 4].Cells[2].Value = Points[i].AngleGai;
                        dataGridView1.Rows[2*i + 4].Cells[3].Value = Points[i].Gdegree + " " + Points[i].Gminute + " " + Points[i].Gsecond + " ";
                        dataGridView1.Rows[2 * i  + 3].Cells[4].Value = Points[i].Fdegree + " " + Points[i].Fminute + " " + Points[i].Fsecond + " ";
                        dataGridView1.Rows[2*i + 3].Cells[6].Value = "(" + Points[i].DeltaX + "," + Points[i].DeltaY + ")";
                        dataGridView1.Rows[2*i + 3].Cells[7].Value = "(" + Points[i].Xgai + "," + Points[i].Ygai + ")";
                        dataGridView1.Rows[2*i + 3].Cells[8].Value = "(" + Points[i].DeltaXgai + "," + Points[i].DeltaYgai + ")";
                        dataGridView1.Rows[2*i + 4].Cells[9].Value = Points[i].x.ToString("0.0000");
                        dataGridView1.Rows[2*i + 4].Cells[10].Value = Points[i].y.ToString("0.0000");
                    }
               
                    dataGridView1.Rows[2 * (Points.Count() - 1) + 3].Cells[4].Value = Points[Points.Count() - 1].Fdegree + " " + Points[Points.Count() - 1].Fminute + " " + Points[Points.Count() - 1].Fsecond + " ";
                    dataGridView1.Rows[2 * (Points.Count() - 1) + 3].Cells[6].Value = "(" + Points[(Points.Count() - 1)].DeltaX + "," + Points[(Points.Count() - 1)].DeltaY + ")";
                    dataGridView1.Rows[2 * (Points.Count() - 1) + 3].Cells[7].Value = "(" + Points[(Points.Count() - 1)].Xgai + "," + Points[(Points.Count() - 1)].Ygai + ")";
                    dataGridView1.Rows[2 * (Points.Count() - 1) + 3].Cells[8].Value = "(" + Points[(Points.Count() - 1)].DeltaXgai + "," + Points[(Points.Count() - 1)].DeltaYgai + ")";
                    dataGridView1.Rows[2 * (Points.Count() - 1) + 4].Cells[9].Value = Points[(Points.Count() - 1)].x.ToString("0.0000");
                    dataGridView1.Rows[2 * (Points.Count() - 1) + 4].Cells[10].Value = Points[(Points.Count() - 1)].y.ToString("0.0000");
                    dataGridView1.Rows[2 * (Points.Count() - 1) + 4].Cells[2].Value = Points[Points.Count() - 1].AngleGai;
                    dataGridView1.Rows[2 * (Points.Count() - 1) + 4].Cells[3].Value = Points[Points.Count() - 1].Gdegree + " " + Points[Points.Count() - 1].Gminute + " " + Points[Points.Count() - 1].Gsecond + " ";

                    for (int i = 0; i < Points.Count()-1; i++)
                    {
                        dataGridView1.Rows[2 * i + 5].Cells[4].Value = Points[i].Fdegree + " " + Points[i].Fminute + " " + Points[i].Fsecond + " ";
                    }

                  //  dataGridView1.Rows[2].Cells[2].Value = PointsA[1].AngleGai;
                    //    dataGridView1.Rows[2].Cells[3].Value = PointsA[1].Gdegree + " " + PointsA[1].Gminute + " " + PointsA[1].Gsecond + " ";
                        dataGridView1.Rows[3].Cells[4].Value = PointsA[1].Fdegree + " " + PointsA[1].Fminute + " " + PointsA[1].Fsecond + " ";
                        dataGridView1.Rows[1].Cells[4].Value = PointsA[0].Fdegree + " " + PointsA[0].Fminute + " " + PointsA[0].Fsecond + " ";
                    break;
                default:
                    MessageBox.Show("请选择正确的测量类型!");
                    break;
            }

        }

        private void 导入TXTToolStripMenuItem_Click(object sender, EventArgs e)//导入数据
        {
            //点击导入自动清空数据
            int count = dataGridView1.RowCount;
            if (count > 0)
            {
                for (int i = 0; i < count; i++)
                {
                    dataGridView1.Rows.Clear();
                }
            }
            Points.Clear();
            PointsA.Clear();
            richTextBox1.Text = "";
            string Datatype = comboBox2.Text;          
            if (comboBox2.Text == "")
            {
                MessageBox.Show("请选择测量模式!");
            }
            else
            {
                string[] temp;
                int b = 0;//导入数据时记录行数,用于提示存在格式错误的数据行数
                //打开选择文件对话框
                OpenFileDialog openFileDialog1 = new OpenFileDialog();  //动态初始化
                //打开txt文件
                openFileDialog1.Filter = "(*.txt)|*.*";
                openFileDialog1.FileName = "";
                if (openFileDialog1.ShowDialog() == DialogResult.OK)
                {
                    /*  //使用StreamReader类来读取文件
                      FileStream fs = new FileStream(openFileDialog1.FileName, FileMode.Open, FileAccess.Read);
                      //FileStream 类,为文件提供 Stream(数据流),既支持同步读写操作,也支持异步读写操作。
                      //FileMode.open:指定操作系统应打开现有文件
                      // FileAccess.Read:对文件进行读取
                      StreamReader sr = new StreamReader(fs, Encoding.Default);
                      //StreamReader 类用于从流中读取字符串。                
                      // 从数据流中读取每一行,直到文件的最后一行*/
                    //导入指定行
                    string[] textlines = File.ReadAllLines(openFileDialog1.FileName);

                    if (textlines.Length > 1)//判断数据是否为空
                    {
                        switch (Datatype)
                        {
                            case "闭合导线(一点一方向)":
                                try
                                {
                                    double DU;//DMS角度
                                    Point A = new Point();//已知点数据
                                    temp = textlines[0].Split(',');//已知点数据
                                    A.dianhao = temp[0];
                                    DU = Convert.ToDouble(temp[1]);
                                    A.Fdegree = Convert.ToInt32(Math.Floor( DU));//度
                                    A.Fminute = Convert.ToInt32(Math.Floor((DU-A.Fdegree)*100.0));//分
                                    A.Fsecond =Math.Round( (DU * 100.0 - A.Fminute - A.Fdegree * 100) * 100,2);//秒
                                    A.x = Convert.ToDouble(temp[2]);
                                    A.y = Convert.ToDouble(temp[3]);
                                    A.FDdegree = A.Fdegree + A.Fminute / 60.0 + A.Fsecond / 3600.0;//十进制度数
                                    A.rad = (A.FDdegree / 180.0) * Math.PI;//弧度制度数
                                    PointsA.Add(A);
                                    b += 1;
                                    

                                    for (int i = 1; i < textlines.Length; i++)
                                    {
                                        temp = textlines[i].Split(',');
                                        Point p = new Point();
                                        p.dianhao = temp[0];
                                        DU = Convert.ToDouble(temp[1]);
                                        p.degree = Convert.ToInt32(Math.Floor(DU));
                                        p.minute = Convert.ToInt32(Math.Floor((DU - p.degree) * 100.0));
                                        p.second =Math.Round( (DU * 100.0 - p.minute - p.degree * 100.0) * 100.0,2);
                                        p.pingju = Convert.ToDouble(temp[2]);
                                        p.Ddegree = p.degree + p.minute / 60.0 + p.second / 3600.0;
                                        b += 1;
                                        Points.Add(p);
                                    }
                                    GridBuild1();
                                }
                                catch//导入时存在格式错误的数据,提示错误并清除已导入的数据
                                {
                                    MessageBox.Show("第" + b + "行数据格式存在错误,请检查数据!");
                                    int count2 = dataGridView1.RowCount;
                                    if (count2 > 0)
                                    {
                                        for (int i = 0; i < count2; i++)
                                        {
                                            dataGridView1.Rows.Clear();
                                        }
                                    }
                                }
                                break;
                            case "闭合导线(两个已知点)":
                                try
                                {
                                    double DU;//DMS度
                                    temp = textlines[0].Split(',');//已知点数据
                                    Point A = new Point();//已知点数据
                                    Point B = new Point();
                                    A.dianhao = temp[0];
                                    A.x = Convert.ToDouble(temp[1]);
                                    A.y = Convert.ToDouble(temp[2]);
                                    PointsA.Add(A);
                                    b += 1;//记录行数
                                
                                    
                                    temp = textlines[1].Split(',');//已知点数据                                    
                                    B.dianhao = temp[0];
                                    DU = Convert.ToDouble(temp[1]);
                                    B.degree = Convert.ToInt32(Math.Floor(DU));//度
                                    B.minute = Convert.ToInt32(Math.Floor((DU - B.degree) * 100.0));//分
                                    B.second = Math.Round((DU * 100.0 - B.minute - B.degree * 100) * 100, 2);//秒
                                    B.x = Convert.ToDouble(temp[2]);
                                    B.y = Convert.ToDouble(temp[3]);
                                    B.Ddegree = B.degree + B.minute / 60.0 + B.second / 3600.0;                                  
                                    PointsA.Add(B);
                                    b += 1;
                                   
                                    for (int i = 2; i < textlines.Length; i++)
                                    {
                                        temp = textlines[i].Split(',');
                                        Point p = new Point();
                                        p.dianhao = temp[0];
                                        DU = Convert.ToDouble(temp[1]);
                                        p.degree = Convert.ToInt32(Math.Floor(DU));
                                        p.minute = Convert.ToInt32(Math.Floor((DU - p.degree) * 100.0));
                                        p.second = Math.Round((DU * 100.0 - p.minute - p.degree * 100.0) * 100.0, 2);
                                        p.pingju = Convert.ToDouble(temp[2]);
                                        p.Ddegree = p.degree + p.minute / 60.0 + p.second / 3600.0;
                                        Points.Add(p);
                                        b += 1;
                                    }
                                   
                                }
                                catch//导入时存在格式错误的数据,提示错误并清除已导入的数据
                                {
                                    MessageBox.Show("第" + b + "行数据格式存在错误,请检查数据!");
                                    int count2 = dataGridView1.RowCount;
                                    if (count2 > 0)
                                    {
                                        for (int i = 0; i < count2; i++)
                                        {
                                            dataGridView1.Rows.Clear();
                                        }
                                    }
                                    return;
                                }
                                GridBuild1();
                                break;

                          

                            default:
                                MessageBox.Show("请选择正确的测量类型!");
                                break;

                        }



                    }
                    else
                    {
                        MessageBox.Show("缺少测量数据!");
                    }
                }
            }

        }
        public void GridBuild1()//显示数据
        {
            string Datatype = comboBox2.Text;
            switch (Datatype)
            {
                case "闭合导线(一点一方向)":
                    dataGridView1.Rows.Add(2);
                    dataGridView1.Rows[0].Cells[0].Value = PointsA[0].dianhao;
                    dataGridView1.Rows[1].Cells[4].Value = PointsA[0].Fdegree + " " + PointsA[0].Fminute + " " + PointsA[0].Fsecond + " ";
                    dataGridView1.Rows[0].Cells[9].Value = PointsA[0].x.ToString("0.0000");
                    dataGridView1.Rows[0].Cells[10].Value = PointsA[0].y.ToString("0.0000");
                    for (int i = 0; i < Points.Count(); i++)
                    {
                        dataGridView1.Rows.Add(2);
                        dataGridView1.Rows[2*i+2].Cells[0].Value = Points[i].dianhao;
                        dataGridView1.Rows[2*i+2].Cells[1].Value = Points[i].degree + " " + Points[i].minute + " " + Points[i].second + " ";
                        dataGridView1.Rows[2*i+1].Cells[5].Value = Points[i].pingju;
                    }
                    break;
                case "闭合导线(两个已知点)":
                    dataGridView1.Rows.Add(2);
                    dataGridView1.Rows[0].Cells[0].Value = PointsA[0].dianhao;
                    dataGridView1.Rows[0].Cells[9].Value = PointsA[0].x.ToString("0.0000");
                    dataGridView1.Rows[0].Cells[10].Value = PointsA[0].y.ToString("0.0000");
                    dataGridView1.Rows.Add(2);
                    dataGridView1.Rows[2].Cells[0].Value = PointsA[1].dianhao;
                    dataGridView1.Rows[2].Cells[1].Value = PointsA[1].degree + " " + PointsA[1].minute + " " + PointsA[1].second + " ";
                    dataGridView1.Rows[2].Cells[9].Value = PointsA[1].x.ToString("0.0000");
                        dataGridView1.Rows[ 2].Cells[10].Value = PointsA[1].y.ToString("0.0000");
                        dataGridView1.Rows[ 3].Cells[5].Value = Points[0].pingju;
                    for (int i =0; i < Points.Count(); i++)
                    {
                        dataGridView1.Rows.Add(2);
                        dataGridView1.Rows[2*i+4].Cells[0].Value = Points[i].dianhao;
                        dataGridView1.Rows[2*i+4].Cells[1].Value = Points[i].degree + " " + Points[i].minute + " " + Points[i].second + " ";
                      
                    }
                  //  dataGridView1.Rows[2 * (Points.Count() - 1) + 4].Cells[0].Value = Points[Points.Count() - 1].dianhao;
                    for (int i = 1; i < Points.Count(); i++)
                    {
                        dataGridView1.Rows[2 * i + 3].Cells[5].Value = Points[i].pingju;
                    }

                    break;

                default:
                    MessageBox.Show("数据写入表格失败");
                    break;

            }
        }

       

        private void button2_Click(object sender, EventArgs e)//画图
        {
            try
            {
                Bitmap bit2 = new Bitmap(pictureBox1.ClientRectangle.Width, pictureBox1.ClientRectangle.Height);
                bit2 = drawbitmap();
                Image img = Image.FromHbitmap(bit2.GetHbitmap());
                pictureBox1.Image = img;
                pictureBox1.Show();
            }
           catch
            {
               MessageBox.Show("请输入数据!");
            }
        }
        public Bitmap drawbitmap()//将水准路线图绘制到bitmap
        {
            Bitmap bit = new Bitmap(pictureBox1.ClientRectangle.Width, pictureBox1.ClientRectangle.Height);
            pictureBox1.DrawToBitmap(bit, pictureBox1.ClientRectangle);

            Graphics g2 = Graphics.FromImage(bit);//画布
            g2.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            g2.Clear(Color.White);
            //画坐标轴
            Pen p4 = new Pen(Color.Black, 4);//画笔
            p4.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;//恢复实线
            p4.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;//定义线尾的样式为箭头
            int x3, y3, x4, y4, x5, y5, x6, y6;
            x3 = 20;
            y3 = 20;
            x4 = Convert.ToInt16(pictureBox1.ClientRectangle.Width - 10);
            y4 = Convert.ToInt16(pictureBox1.ClientRectangle.Height - 10);
            x5 = 20;
            y5 = Convert.ToInt16(pictureBox1.ClientRectangle.Height - 10);
            x6 = 16;
            y6 = Convert.ToInt16(pictureBox1.ClientRectangle.Height - 10);
            g2.DrawLine(p4, x5, y5, x3, y3);
            g2.DrawLine(p4, x6, y6, x4, y4);

            Font myFont3 = new Font("宋体", 20, FontStyle.Bold);
            Brush bush3 = new SolidBrush(Color.Black);//填充的颜色
            int x7, y7, x8, y8;
            x7 = 30;
            y7 = 30;
            x8 = Convert.ToInt16(pictureBox1.ClientRectangle.Width - 35);
            y8 = Convert.ToInt16(pictureBox1.ClientRectangle.Height - 45);
            g2.DrawString("X", myFont3, bush3, x7, y7);
            g2.DrawString("Y", myFont3, bush3, x8, y8);


            double[] x = new double[Points.Count()+1];//储存所有点号和坐标
            double[] y = new double[Points.Count()+1];
            string[] dh = new string[Points.Count()+1];
            

           /* 闭合导线(一点一方向)
闭合导线(两个已知点)*/
            string s = comboBox2.Text;//记录导线类型
            switch (s)

            {
                case"闭合导线(一点一方向)":
                    for (int i = 0; i < Points.Count(); i++)
            {
                x[i] = Points[i].x;
                y[i] = Points[i].y;
                dh[i] = Points[i].dianhao;
            }
            x[Points.Count() ] = PointsA[0].x;
            y[Points.Count() ] = PointsA[0].y;
            dh[Points.Count()] = PointsA[0].dianhao;
                    
                    if(x.Min()<0)//如果坐标存在负值,则将坐标平移
                    {
                        for (int o = 0; o < Points.Count() + 1; o++)
                        {
                            x[o] +=Math.Abs( x.Min()) + 10.0;
                        }
            
                    }
                    if (y.Min() < 0)
                    {
                        for (int o = 0; o < Points.Count() + 1; o++)
                        {
                            y[o] +=Math.Abs( y.Min()) + 10.0;
                        }
                    }


 Pen p2 = new Pen(Color.Red, 10);//画笔
            p2.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;//恢复实线
            p2.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;//定义线尾的样式为箭头
            Pen p3 = new Pen(Color.Blue, 15);//画笔,用于画三角形
           
            double chang = pictureBox1.Size.Height;
            double kuan = pictureBox1.Size.Width;
            double bli;//biliyingz

            double dx = (kuan - 20) / (x.Max() - x.Min());
            double dy = (chang - 20) / (y.Max() - y.Min());

            double idx = (kuan - 20) / (x.Max() - x.Min());
            double idy = (chang - 20) / (y.Max() - y.Min());
            if (idx > idy)
            {
                bli = idy;
            }
            else
            {
                bli = idx;
            }

            int x1, y1, x2, y2;
            Font myFont = new Font("宋体", 10, FontStyle.Bold);
            Brush bush = new SolidBrush(Color.Black);//填充的颜色
            for (int i = 0; i < Points.Count(); i++)//画路线
            {
                
                    x1 = Convert.ToInt16(y[i] * bli - y.Min() * bli + 50);
                    y1 = Convert.ToInt16((kuan - x[i] * bli) - (kuan - x.Max() * bli) + 50);
                    x2 = Convert.ToInt16(y[i + 1] * bli - y.Min() * bli + 40);
                    y2 = Convert.ToInt16((kuan - x[i + 1] * bli) - (kuan - x.Max() * bli) + 50);
                    g2.DrawLine(p2, x1, y1, x2, y2);//画线   

            }
            x1 = Convert.ToInt16(y[Points.Count()] * bli - y.Min() * bli + 50);
            y1 = Convert.ToInt16((kuan - x[Points.Count()] * bli) - (kuan - x.Max() * bli) + 50);
            x2 = Convert.ToInt16(y[0] * bli - y.Min() * bli + 40);
            y2 = Convert.ToInt16((kuan - x[0] * bli) - (kuan - x.Max() * bli) + 50);
            g2.DrawLine(p2, x1, y1, x2, y2);//画线  

           
          
            //绘制已知点
            x1 = Convert.ToInt16(y[Points.Count()] * bli - y.Min() * bli + 50);
            y1 = Convert.ToInt16((kuan - x[Points.Count()] * bli) - (kuan - x.Max() * bli) + 50);
            PointF point1 = new PointF(x1 - 1, y1);
            PointF point2 = new PointF(x1 + 1, y1 + 1);
            PointF point3 = new PointF(x1 + 1, y1 - 1);
            PointF[] pol = { point1, point2, point3 };
            g2.DrawPolygon(p3, pol);
            g2.FillPolygon(new SolidBrush(Color.Blue), pol);
            Brush bush2 = new SolidBrush(Color.Green);//填充的颜色
            for (int o = 0; o < Points.Count() - 1; o++)//绘制未知点
            {
                x1 = Convert.ToInt16(y[o] * bli - y.Min() * bli + 50);
                y1 = Convert.ToInt16((kuan - x[o] * bli) - (kuan - x.Max() * bli) + 50);
                g2.FillEllipse(bush2, x1 - 10, y1 - 10, 15, 15);
                for (int i = 0; i < Points.Count(); i++)//标坐标
                {
                    x1 = Convert.ToInt16(y[i] * bli - y.Min() * bli + 50);
                    y1 = Convert.ToInt16((kuan - x[i] * bli) - (kuan - x.Max() * bli) + 50);
                    g2.DrawString(Points[i].dianhao + "(" + Convert.ToString(Points[i].x) + "," + Convert.ToString(Points[i].y) + ")", myFont, bush, x1 - 20, y1 - 30);

                }
            }
            break;
                case"闭合导线(两个已知点)":
                    for (int i = 0; i < Points.Count()-1; i++)
            {
                x[i] = Points[i].x;
                y[i] = Points[i].y;
                dh[i] = Points[i].dianhao;
            }
                     x[Points.Count()-1 ] = PointsA[0].x;
            y[Points.Count()-1 ] = PointsA[0].y;
            dh[Points.Count()-1] = PointsA[0].dianhao;

            x[Points.Count() ] = PointsA[1].x;
            y[Points.Count() ] = PointsA[1].y;
            dh[Points.Count()] = PointsA[1].dianhao;


                    if(x.Min()<0)//如果坐标存在负值,则将坐标平移
                    {
                        for (int o = 0; o < Points.Count() + 1; o++)
                        {
                            x[o] +=Math.Abs( x.Min()) + 10.0;
                        }
            
                    }
                    if (y.Min() < 0)
                    {
                        for (int o = 0; o < Points.Count() + 1; o++)
                        {
                            y[o] +=Math.Abs( y.Min()) + 10.0;
                        }
                    }




             p2 = new Pen(Color.Red, 10);//画笔
            p2.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;//恢复实线
            p2.EndCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;//定义线尾的样式为箭头
             p3 = new Pen(Color.Blue, 15);//画笔,用于画三角形
             chang = pictureBox1.Size.Height;
           kuan = pictureBox1.Size.Width;
           

           dx = (kuan - 20) / (x.Max() - x.Min());
         dy = (chang - 20) / (y.Max() - y.Min());

        idx = (kuan - 20) / (x.Max() - x.Min());
         idy = (chang - 20) / (y.Max() - y.Min());
            if (idx > idy)//判断长、宽两个比例那个更合适
            {
                bli = idy;
            }
            else
            {
                bli = idx;
            }

           
           myFont = new Font("宋体", 10, FontStyle.Bold);
          bush = new SolidBrush(Color.Black);//填充的颜色
            for (int i = 0; i < Points.Count()-2; i++)//画路线
            {
                
                    x1 = Convert.ToInt16(y[i] * bli - y.Min() * bli + 50);
                    y1 = Convert.ToInt16((kuan - x[i] * bli) - (kuan - x.Max() * bli) + 50);
                    x2 = Convert.ToInt16(y[i + 1] * bli - y.Min() * bli + 40);
                    y2 = Convert.ToInt16((kuan - x[i + 1] * bli) - (kuan - x.Max() * bli) + 50);
                    g2.DrawLine(p2, x1, y1, x2, y2);//画线   

            }
                      x1 = Convert.ToInt16(y[Points.Count()-2] * bli - y.Min() * bli + 50);
            y1 = Convert.ToInt16((kuan - x[Points.Count()-2] * bli) - (kuan - x.Max() * bli) + 50);
            x2 = Convert.ToInt16(y[Points.Count()] * bli - y.Min() * bli + 40);
            y2 = Convert.ToInt16((kuan - x[Points.Count()] * bli) - (kuan - x.Max() * bli) + 50);
            g2.DrawLine(p2, x1, y1, x2, y2);//画线  

            x1 = Convert.ToInt16(y[Points.Count()] * bli - y.Min() * bli + 50);
            y1 = Convert.ToInt16((kuan - x[Points.Count()] * bli) - (kuan - x.Max() * bli) + 50);
            x2 = Convert.ToInt16(y[0] * bli - y.Min() * bli + 40);
            y2 = Convert.ToInt16((kuan - x[0] * bli) - (kuan - x.Max() * bli) + 50);
            g2.DrawLine(p2, x1, y1, x2, y2);//画线  
           

                       x1 = Convert.ToInt16(y[Points.Count()-1] * bli - y.Min() * bli + 50);
            y1 = Convert.ToInt16((kuan - x[Points.Count()-1] * bli) - (kuan - x.Max() * bli) + 50);
            x2 = Convert.ToInt16(y[Points.Count()] * bli - y.Min() * bli + 40);
            y2 = Convert.ToInt16((kuan - x[Points.Count()] * bli) - (kuan - x.Max() * bli) + 50);
            g2.DrawLine(p2, x1, y1, x2, y2);//画线 
            

         
                     x1 = Convert.ToInt16(y[Points.Count()] * bli - y.Min() * bli + 50);
            y1 = Convert.ToInt16((kuan - x[Points.Count()] * bli) - (kuan - x.Max() * bli) + 50);
            g2.DrawString(PointsA[1].dianhao + "(" + Convert.ToString(PointsA[1].x) + "," + Convert.ToString(PointsA[1].y) + ")", myFont, bush, x1 - 20, y1 - 30);//标已知点点号
                     x1 = Convert.ToInt16(y[Points.Count()-1] * bli - y.Min() * bli + 50);
            y1 = Convert.ToInt16((kuan - x[Points.Count()-1] * bli) - (kuan - x.Max() * bli) + 50);
            g2.DrawString(PointsA[0].dianhao + "(" + Convert.ToString(PointsA[0].x) + "," + Convert.ToString(PointsA[0].y) + ")", myFont, bush, x1 - 20, y1 - 30);
            //绘制已知点
            x1 = Convert.ToInt16(y[Points.Count()] * bli - y.Min() * bli + 50);
            y1 = Convert.ToInt16((kuan - x[Points.Count()] * bli) - (kuan - x.Max() * bli) + 50);
            PointF point4 = new PointF(x1 - 1, y1);
            PointF point5 = new PointF(x1 + 1, y1 + 1);
            PointF point6 = new PointF(x1 + 1, y1 - 1);
            PointF[] pol2 = { point4, point5, point6 };
            g2.DrawPolygon(p3, pol2);
            g2.FillPolygon(new SolidBrush(Color.Blue), pol2);
             bush2 = new SolidBrush(Color.Green);//填充的颜色

                      x1 = Convert.ToInt16(y[Points.Count()-1] * bli - y.Min() * bli + 50);
            y1 = Convert.ToInt16((kuan - x[Points.Count()-1] * bli) - (kuan - x.Max() * bli) + 50);
            PointF point7 = new PointF(x1 - 1, y1);
            PointF point8 = new PointF(x1 + 1, y1 + 1);
            PointF point9 = new PointF(x1 + 1, y1 - 1);
            PointF[] pol3 = { point7, point8, point9 };
            g2.DrawPolygon(p3, pol3);
            g2.FillPolygon(new SolidBrush(Color.Blue), pol3);
        
          
             
             
             for (int o = 0; o < Points.Count() - 1; o++)//绘制未知点
            {
                x1 = Convert.ToInt16(y[o] * bli - y.Min() * bli + 50);
                y1 = Convert.ToInt16((kuan - x[o] * bli) - (kuan - x.Max() * bli) + 50);
                g2.FillEllipse(bush2, x1 - 10, y1 - 10, 15, 15);
            }
             for (int i = 0; i < Points.Count() - 1; i++)//标坐标
             {
                 x1 = Convert.ToInt16(y[i] * bli - y.Min() * bli + 50);
                 y1 = Convert.ToInt16((kuan - x[i] * bli) - (kuan - x.Max() * bli) + 50);
                 g2.DrawString(Points[i].dianhao + "(" + Convert.ToString(Points[i].x) + "," + Convert.ToString(Points[i].y) + ")", myFont, bush, x1 - 20, y1 - 30);

             }

            break;
                default:
            MessageBox.Show("绘制失败");
            break;

            }
            
            
        



            return bit;
        }

        private void button3_Click(object sender, EventArgs e)
        {
            try
            {
                SaveFileDialog save = new SaveFileDialog();
                save.FileName = "水准路线示意图";
                save.Filter = "(.jpg)|*.jpg";

                if (save.ShowDialog() == DialogResult.OK)
                {

                    Bitmap bit2 = new Bitmap(pictureBox1.ClientRectangle.Width, pictureBox1.ClientRectangle.Height);
                    bit2 = drawbitmap();
                    bit2.Save(save.FileName);

                }
            }
            catch
            {
                MessageBox.Show("请输入数据!");
            }
        }

    

        

        private void 使用说明ToolStripMenuItem_Click(object sender, EventArgs e)//打开使用说明
        {
            string str3 = System.Windows.Forms.Application.StartupPath;//获取debug目录
            string fileNameFullPath = str3 + @"\test1.pdf";//获取使用说明目录
            System.Diagnostics.Process.Start(fileNameFullPath);//使用系统默认应用打开文件
        }
        public bool DataGridviewShowToExcel(DataGridView dgv, bool isShowExcle)//导出到Excel
        {
            if (dgv.Rows.Count == 0)
                return false;
            //建立Excel对象
            Excel.Application excel = new Excel.Application();
            excel.Application.Workbooks.Add(true);
            excel.Visible = isShowExcle;
            //生成字段名称
            for (int i = 0; i < dgv.ColumnCount; i++)
            {
                excel.Cells[1, i + 1] = dgv.Columns[i].HeaderText.ToString();
            }
            //填充数据
            for (int i = 0; i < dgv.RowCount - 1; i++)
            {
                for (int j = 0; j < dgv.ColumnCount; j++)
                {
                    if (dgv[j, i].Value == null)
                    {
                        excel.Cells[i + 2, j + 1] = "";
                    }
                    else
                    {
                        excel.Cells[i + 2, j + 1] = dgv[j, i].Value.ToString();
                    }
                }
            }
            excel.Columns.AutoFit();//调整excle列宽自适应数据
            excel.Cells.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;//平差数水平居中  
            Excel.Range range = excel.Range["A" + (dgv.RowCount + 2), "K" + (dgv.RowCount + 12)];//指定表格后一片区域
            range.Merge();//将指定区域单元格合并
            range.Value = text;//在合并的单元格加上平差限差信息,text是string类型数据,存储限差信息
            range.HorizontalAlignment = Excel.XlHAlign.xlHAlignLeft;//限差信息左对齐
            return true;
        }

        private void 输出结果ToolStripMenuItem_Click(object sender, EventArgs e)//导出结果到excel
        {
            try
            {
                bool isShowExcle = true;
                DataGridviewShowToExcel(dataGridView1, isShowExcle);
            }
            catch
            {
                MessageBox.Show("操作失败,您的电脑可能没有安装Microsoft Excel。");
            }
        }

        private void 导出到TXTToolStripMenuItem_Click(object sender, EventArgs e)//输出结果到TXT
        {
            int i = 0;
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "文本文件(*.txt)|*.txt";
            if (dlg.ShowDialog() == DialogResult.OK)
            {
                string path = dlg.FileName;
                StreamWriter sw = new StreamWriter(path);
                switch (comboBox2.Text)
                {
                    case "闭合导线(一点一方向)":
                        sw.WriteLine(PointsA[0].dianhao + "," + PointsA[0].Fdegree + "," + PointsA[0].Fminute + "," + PointsA[0].Fsecond + "," + PointsA[0].x + "," + PointsA[0].y + "\r\n");
                        for (i = 0; i < Points.Count(); i++)
                        {
                            sw.WriteLine(Points[i].dianhao + "," + Points[i].Fdegree + "," + Points[i].Fminute + "," + Points[i].Fsecond + "," + Points[i].x + "," + Points[i].y + "\r\n");
                        }
                        break;
                    case "闭合导线(两个已知点)":
                        sw.WriteLine(PointsA[1].dianhao + "," + PointsA[1].x + "," + PointsA[1].y + "\r\n");
                        sw.WriteLine(PointsA[0].dianhao + "," + PointsA[0].Fdegree + "," + PointsA[0].Fminute + "," + PointsA[0].Fsecond + "," + PointsA[0].x + "," + PointsA[0].y + "\r\n");                 
                        for (i = 0; i < Points.Count(); i++)
                        {
                            sw.WriteLine(Points[i].dianhao + "," + Points[i].Fdegree + "," + Points[i].Fminute + "," + Points[i].Fsecond + "," + Points[i].x + "," + Points[i].y + "\r\n");
                        }
                        break;
                    default:
                        MessageBox.Show("导出失败");
                        return;
                }      
                sw.Close();
                MessageBox.Show("保存路径:" + dlg.FileName + "\r\n" + "保存成功!");
            }
            else
            {
                MessageBox.Show("保存失败!");
            }

        }


        }
       
    }

源程序、测试数据及实验报告下载

提取码:ii57

如果对你有帮助,就点一个赞吧~

  • 18
    点赞
  • 121
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

风风疯风

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

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

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

打赏作者

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

抵扣说明:

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

余额充值