文章目录
前言
导线测量是利用全站仪测量一系列点以及测站之间的距离以及转角,从而根据已知点坐标和方位角推算出未知测站点的平面坐标。如果你想详细了解附和导线近似平差计算,可以参考武汉大学李英冰老师编写的书籍-《测绘程序设计试题集》,有uu想要电子书的话可以私信我哦!
那我们话不多说,直接进入今天的正题,让我们看看如何通过c#窗体程序实现附合导线近似平差计算
一、数据说明
本程序采取TXT格式数据作为起算数据,数据第一行分别为:测角中误差,加常数,乘常数;第二行至第五行为已知点数据,分别为:点名,X坐标,Y坐标;第六行直到结束为测站数据,每一测站包含三行数据,格式如下:第一行为测站名,第二行为前视观测站名,前视观测类型,前视观测值;第二行为后视观测站名,后视观测类型,后视观测值。下图是部分数据截图,仅仅作为参考哦!
二、程序主要变量以及函数说明
2.1 主要变量说明
2.1.1 Form类变量说明
本程序已有如下三种数据结构:
class Point//已知点
{
public string name;//点名
public double X, Y;//坐标
}
class GCZ//观测值
{
public string GCD,type;//类型
public double value;//观测值
}
class CZ//测站
{
public Point P = new Point();//测站点
public List<Point> GCZs = new List<Point>();
}
根据如上三种数据结构,建立了Form类中不同的变量,下面以表格形式说明各主要变量的信息。
2.1.2 Drawing类变量说明
Drawing类中主要的全局变量均是用于确定画图基准以及比例尺,将实际距离转换成为屏幕距离。
2.2 主要函数说明
2.2.1 operation类
这个类是平差计算的核心类,涉及的函数很多,这里我只例举出一个核心的函数。
相信很多熟悉测绘工程的小伙伴都知道,如何计算坐标方位角在很多的测绘计算之中都是重中之重,传统的方法是这样的:
α = a r c tan ( y 2 − y 1 x 2 − x 1 ) = a r c tan ( Δ y Δ x ) \alpha =\mathrm{arc}\tan\left( \frac{y2-y1}{x2-x1} \right) =\mathrm{arc}\tan \left( \frac{\varDelta y}{\varDelta x} \right) α=arctan(x2−x1y2−y1)=arctan(ΔxΔy)
进而我们可以通过方位角以及两个点的相对位置分类讨论出真正的坐标方位角。而且,在本程序中创新了坐标方位角求解的方式,合理的利用了先验知识,大大减小了代码量。
public double CalAzimuth(double deltaY, double deltaX)
{
double Azimuth = 0;
if (deltaX > 0) Azimuth = Math.Atan(deltaY / deltaX);
else if (deltaX < 0) Azimuth = Math.PI + Math.Atan(deltaY / deltaX);
else if (deltaY > 0) Azimuth = Math.PI / 2;
else if (deltaY < 0) Azimuth = Math.PI * 1.5;
return Azimuth;
}
第二个核心函数便是在计算各个转点的坐标方位角,这里有个重点哦,我们需要判断一下转点是在前行方向的左角还是右角,遵循的原则是左加右减,之后需要根据导线终点和起点坐标计算出线路的真实拐点,与计算出的线路拐角对比,得到误差项,等权的对每个转角进行改正,消除真实值与观测值之间的矛盾。
if (Math.Abs(fj)*180/Math.PI*3600 <= 40 * Math.Sqrt(CZs.Count))//注意单位
{
double v = -fj / CZs.Count;
int j = 1;
foreach(CZ cz in CZs)
{
cz.ZJ = cz.gczs[1].value - cz.gczs[0].value + v;
if (cz.ZJ > Math.PI * 2)
{
cz.ZJ -= Math.PI * 2;
}
if (cz.ZJ < 0)
{
cz.ZJ += Math.PI * 2;
}
if (flag)
{
As[j] = cz.ZJ + As[j-1] - Math.PI;
while (As[j] < 0)
{
As[j] += Math.PI * 2;
}
while (As[j] > Math.PI * 2)
{
As[j] -= Math.PI * 2;
}
}//左角
else
{
As[j] = cz.ZJ - As[j-1] + Math.PI;
while (As[j] < 0)
{
As[j] += Math.PI * 2;
}
while (As[j] > Math.PI * 2)
{
As[j] -= Math.PI * 2;
}
}//右角
j++;
}
2.2.2 Drawing类
Drawing类共包含一个创建画布的函数,两个绘制已知点和测站点的函数,一个绘制坐标轴的函数,三个有关图像移动的函数以及三个有关图像放缩的函数,他们的输入输出信息如下:
#static public void Create(Rectangle rect, List<CZ> CZs, List<Point> Known_Ps)
//创建画布
1.输入画框信息,测站点信息,已知点信息,确定出实际点坐标中的最小值作为画图基准,并计算绘图比例尺。
static public void DrawKP(Graphics g, Rectangle rect, List<Point> Known_Ps)
//已知点以及连线,三角形
2.输入画布,画框信息,以及已知点信息,输出已知点图像(红色三角形表示)以及已知点之间的连线。
static public void DrawCZ(Graphics g, Rectangle rect, List<CZ> CZs)
//测站点以及连线,圆形
3.输入画布,画框信息,以及测站点信息,输出测站点图像(黑色圆形表示)以及测站点之间的连线。
static public void DrawAX(Graphics g, Rectangle rect)
//坐标轴以及图名
4.输入画布以及画框信息,输出坐标轴和图名。
static public void MouseDown(MouseEventArgs e)
//鼠标按下
static public void MouseUp(MouseEventArgs e)
//鼠标抬起
static public void MouseMove(MouseEventArgs e)
//鼠标移动
5.三个函数均和图像移动有关,输入鼠标点击事件,实现鼠标按下后拖动使图像移动,抬起结束图像移动的功能。
static public void MouseDelta(MouseEventArgs e)
//滚轮放缩
static public void FD(EventArgs e)
//点击放大
static public void SX(EventArgs e)
//点击缩小
6.三个函数均和图像放缩有关,第一个函数输入鼠标事件和后两个输入鼠标点击事件,实现图像随着滚轮滚动而放大缩小或随着鼠标点击工具栏中的放大、缩小按钮实现图像放大缩小功能。
3.界面展示
3.1.数据读取界面
3.2.计算报告界面
3.3.示意图界面
4.总结
这就是今天的全部内容啦,创作不易,喜欢的小伙伴给我点个赞或者加入自己的收藏夹哦!需要源代码的小伙伴可以在评论区私信我或者访问我的github链接: https://github.com/fly1234566/fly,有任何问题uu们可以在评价区@我,我会及时回复的!