测绘程序设计
一、实习目的
通过了六周的课程设计,在我们学习完测绘程序设计基础、测量学、测量平差的基础等课程上,通过课程的设计、制定详细的程序设计计划,编码等环节,进一步巩固了我们在这两年多的时间里所学习的知识,做到学以致用,并培养我们对于测绘的综合应用能力,使我们真正地学会自主学习,学会自主处理解决问题的能力。
作为一个测绘工作者,测量过程中免不了要做一些平差的计算,如果遇到测量值较多的平差,则使计算简直成了一种煎熬。随着电子计算机的出现,数学计算变得简单了很多,同时也使测量平差作业模式发生了翻天覆地的变化,把平差计算者从繁重的、枯燥乏味的数字计算中彻底解放了出来。学会平差程序设计,可以帮助我们更加灵活的使用计算机来帮助我们做平差处理以及其他的测量计算。
二、实习内容
1、角度弧度的相互转化程序;要求屏幕输入角度值或弧度值,将其转化为弧
度值或角度值,实现互换。键盘输入正、负角度,及弧度(弧度没有正负之分),计算实例,检验程序正确与否。
2、文件输入输出;
3、矩阵的加减乘;
4、条件平差、间接平差的计算;要求首先运用c++语言或c 语言编写程序,首先实现矩阵的加、减、乘、转置的基本运算,以及矩阵求逆运算,然后在文本中读写相关变量数据,根据条件平差和间接平差的基本公式,求出改正数、中误差及高程平差值,并输出到文本中。具体算例中,条件平差与间接平差的文件书写不同,需分别写在不同的文件中,分别读取。
5、水准网的平差计算。要求设计平差类,根据水准网平差计算内容及步骤定义平差类成员变量及成员函数,所需数据全部从文件中读取,全部数据存于同一个文件中,并以文本格式保存,文件格式的设计就是规定数据文件中包含的内容、各类
数据的先后以及各种数据的书写格式。数据存储方案设计,将磁盘中的数据读到内存中,按照不同的类别有序地放在变量或数组中,然后进行平差计算,最后将计算结果写到磁盘文件中。
三、实习过程
(一)实习1
1.老师讲解角度、弧度之间互相转化的计算方法以及注意事项,特别提及角度或弧度为负数的情况。
平差程序经常要处理角度值,按照测量上的习惯,角度值一般以度分秒的格式书写,从文件读取的角度值和写至文件中的角度值都是度分秒格式,但度分秒格式的角度值进行角度的格式换算。
(1)思路:
第一步:角度值的格式为度" °" 分" ′" 秒" ″,度值和秒值均保留两位整数,不足两位时补0,例如角度值。弧度值的格式为数字形式,例如弧度值;
第二步:角度转化为弧度时,首先分别输入度、分、秒值,然后根据数学转化公式,角度值=度值+分值/60+秒值/3600,弧度=(角度值⨯Ω)180°;弧度转化为角度时,先根据数学公式,角度值=(弧度⨯180°)/Ω, 然后将度值的小数位乘60转化为分值,再将分值的小数位乘60转化为秒值。
(二)实习2
1.老师讲解了文件输入、输出时调用fstream 类的方法,并且提到了类的对象访问公有函数的方法,如:fstream.Myfile; Myfile.open(“data.txt ”); 其中打开txt 类型的文件的方法尤其重要,
在流中,定义了一些处理数据的基本操作,如读取数据,写入数据等,程序员是对流进行所有操作的,而不用关心流的另一头数据的真正流向。流不但可以处理文件,还可以处理动态内存、网络数据等多种数据形式。如果你对流的操作非常熟练,在程序中利用流的方便性,写起程序会大大提高效率的。
鉴于文件输入输出的许多优点,并且使用文件的输入可以方便我们输入测量的数据,提高计算的速度。
(1)思路:
在fstream 类中,有一个成员函数open(),就是用来打开文件的,其原型是: Fstream MyFile;
MyFile.open(“data.txt ”);
(三)实习3
1. 老师讲解矩阵加减乘法的计算方法,并且强调输出时要是矩阵的形式。
(1)加法程序思路:
设置两个相加的矩阵A 、B 和结果矩阵C ,均为一维矩阵,用for 循环来控制将要进行计算的第i 个数字,并将第i 个数字相加后所得的数字放到C 矩阵的第i 个位置。
(2)减法程序思路:
类似于加法,设置两个相减的矩阵A 、B 和结果矩阵C ,均为一维矩阵,用for 循环来控制将要进行计算的第i 个数字,并将第i 个数字相减后所得的数字放到C 矩阵的第i 个位置。
(3)矩阵的乘法思路:
设置两个相减的矩阵A 、B 和结果矩阵C ,均为一维矩阵,使用3个for 循环, 第一步:i 来控制前一个矩阵的第i 行,j 来控制后一个矩阵的第j 列,t 来控制前矩阵的第i 行第t 个数字,后矩阵的第j 列的第t 个数字,将这两个数字相乘的值放到sum 中;
第二步:将t 依次加一,进行计算累计到sum 中,最后放到C 的第i 行j 列; 第三步:当t 运行到超过后,j 加一,i 不变,j 改为j+1,将得到的sum 放到C 的第i 行j+1列,重复一二三步;
第四步:当j 运行到超过后,i+1,重复一二三四步,直到i 超出。
(4)矩阵转置思路:
(四)实习4
间接平差
近年来,测量编程人员运用间接平差原理对导线网,高程网等进行平差,来进
行点位的精度分析,间接平差法是通过选定t 个与观测值有一定关系的独立未知量 作为参数,将每一个观测值都分别表达成这t 个参数的函数,建立函数模型,然后进行求解,从而求得各观测值的平差值。当已知点较多时,如处理大型的导线网或工程网数据时,间接平差比较实用。
与间接平差相比,条件平差不需要增选任何参数,只需要列立相应的条件方程式,在处理已知点较少如中小型的控制网,网型条件比较特殊的网型,例如单一符合导线时,需要列出的条件方程式比较少,使平差计算简单易行。这时,条件平差的优势就体现出来了。因此,运用条件平差进行平差的可视化语言设计,也具有一定的使用价值。
在此,我们仅讨论间接平差。
间接平差是测量平差方法的几个中要模型之一,在现阶段学习的平差原理中,间接平差的条件方程式比较容易列立,尤其是在比较复杂的控制网中,运用的比较广泛,因此,间接平差是在测量工作的内业计算中经常用到的平差模型。
如果只对几何模型中的必要元素进行观测,而没有多余的观测,则在观测值之间不可能产生任何函数关系,也不存在平差问题。只是在有了多余的观测的情况下,才会产生平差问题,
在测量工作中及其他科学工程领域,应用最早也是最广泛的就是“最小二乘法”:Φ=ΔT P Δ=min
在满足最小二乘准则下求得的真误差称为Δ估值,用Δ~表示, 测量工作中习惯用V 代替Δ,因此,最小二乘法表达式:Φ=VT PV=min
由于最小二乘法的准则,可求得真误差估值,也就是求得观测值的估值,其计算公式为L~=L+V
式中V 称为观测值的改正数,L~称为观测值L 的估值,或平差值。
平差原理:
N BB =BPB , W=BPl , x=NBB *W, V=Bx-l, L~=L+V;
按照上述的计算方法,挨个算式进行计算,即可算出L~;
单位中误差:
σ=√(V PV/n-t)
输入的B,P,L 矩阵
输出的高差平差值及测量精度 T T T -1
(五)实习5
水准网是为了确定地面点的高程而布设的控制网,网中的观测值是高程控制点之间的高差。
为了确定各未知点的高程,仅有观测高差是不够的,还必须有若干已知点,已知点的高程值是已知点,在平差中起到基准控制作用。由于存在观测误差,当水准网中有多余观测值之间就会存在矛盾全例如出现水准环闭合差、附合路线闭合差等,水准网平差的目的是消除矛盾,求得各高程点高程的最可靠值班,并对观测值和平差值和平差值进行精度评定。
下述程序的平差设计为函数调用,函数是double *Adjust(int nn,int tt,double *B,double *P,double *L )。该函数中调用了一个头文件include"Array.h" ,这个文件中含有进行矩阵计算的所有计算方法包括加、减、乘、矩阵的逆、乘以一个常数。
该水准网的程序设计计算步骤①从文件读取已知高程和观测数据②未知点近似高程计算③组成法方程式④法方程系数阵求逆⑤高程平差值计算⑥残差V 及单位权中误差的计算⑦最后成果计算和输出。
水准网最小二乘法平差时,王忠至少应有一个高程已知点。所谓已知点,是指点的高程值为已知,并且在平差中保持不变的点。亦即已知点的高程是作为常数值参加平差的,只有未知点的高程才是误差方程和法方程中的未知数。在平差程序中,若有些点有未知数,有些点没有未知数,未知数的个数少于总点数,点号与未知数的编号之间就会缺乏简单明确的对应关系,这给数据存储和编程带来一点的不便。相反,假如不区分已知点还是未知点,将每个点的高程都设成未知数,未知数的编号与高程点的编号就是一一对应的,这种规律性有利于编程,我们在程序中正是这样做的,但是这样做已知点就失去了控制作用,而且法方程系数矩阵还是奇异矩阵,所以必须对法方程次数矩阵进行处理才能使法方程有解且与最小二乘解相同。
在近似高程的计算中, 按照测量平差的习惯, 一班要引入参数近似值, 将误差方程的未知参数编程位置参数的改正数. 水准网中的参数近似值即高程近似值, 原始数据文件中已经有已知点的高程值, 只有未知点的高程近似值才需要程序计算,
思路;
第一步, 设置位置点标志. 个点的高程值用dispersion 数组保存, 近似高程计算之前, 现将dispersion 数组中未知点的高程值赋值为12000, 由于正常的高程值不可能大于12000, 根据高程数组中的值是否大于12000可判断某点是否是需要计算近似高程, 当某点的近似高程计算出来之后,数组中12000就会被实际的值所取代,指导高程数组中的所有的高程值均小于12000,近似高程计算便告知结束。
第二部,计算高程,近似高程计算的基本思路是,遍历观测值,找到每个观测值起始点号、终点号,在根据点号从dispersion 数组中获得每一段高差起始点的高程值和终点的高程值,当高差的一端是高程已知点,另一端是高程未知点时,就由已知点高程和观测高差传算出未知点的高程值,并将计算结果赋值给高程数组,如果高差两端同为已知点或者同为已知点,就跳到下一次循环,继续查找下一个观测值。
在遍历观测值时,排在前面的观测值总是最先用于高程近似值的计算,当观测值的排序不同时,近似高程计算用到的观测值不同,计算结果也不同,所以近似高程的计算结果不是唯一的。有时一次遍历观测值可能还有部分点的高程值任然未能计算出来,还要再次遍历观测值,直至全部点均计算出高程值为止。
精度的估计与平差结果的输出由函数dispersion 完成。该函数将平差结果以类似表格的格式写至结果文件。输出内容包括高程点名、高程平差值及其中误差,高差端点 、高差平差值、高差改正数、高差平差值的中误差等。
计算平差值的中误差需要知道高程平差值的权逆阵QX和单位权中误差μ,对于
不同的平差值方法,Q X 和μ具有不同的计算公式。
水准网平差
此题的难点是如何将文本中观测值读到程序中,并形成B 、P 、L 矩阵,但B 是最不容易得到的矩阵。
定义start[]和end[]两个字符数组,将每次观测的起点保存到start[i]里,终点保存到end[i]里,将这两点的高差保存到distance[i]中,将A 点作为基准点,通过ASK Ⅱ码来确定其它的点,另定义一个a[]矩阵,用来存放水准网中的点是否为已知点,若为已知点则a[m]=-1(m 为点的序号,A 为0、B 为1„„)若是未知点a[m]=0、1„„这样以此类推。先定义一个B 矩阵,行为观测的观测数,列为已知点的个数,(例如下图,共有四个已知点,五个观测值,) 并将B 初始化为0;当
a[end[i]-'A'] !=-1可知观测终点未知,这时就将这个字母所对应的那一列的其中一个0改为1,a[start[i]-'A']!=-1,这时就将这个字母对应的那一列的其中的一个0改为-1;这样就可以算出B 矩阵;而P 矩阵是很容易写的,先定义一个P 矩阵有n 行n 列,n=已知点+未知点的个数,计算两点之间的距离的倒数,作为权,记到P 矩阵中的主对角线上。L 矩阵可以通过观测值直接得到,按顺序保存到L[]中即可。
编程流程图:
四、实习总结
该课程的学习让我对间接平差有了更深刻的理解,知道了间接平差中列误差方程的原理,同时对编程中指针和数组的使用更加熟练。同时,也让我们知道C++在平差计算中的应用方式。
简介平差法相对于条件平差法更适合于电脑进行程序设计,编程简便、直观,易于观测数据的组织和输入,便于结构化程序的设计,精度评定项目齐全,且该法具有较强的适用范围,利用间接平差原理的方法来设计程序,可以达到理想的效果,而且针对遇到的新问题可简洁、快速的设计出适合的程序。
该水准网的平差程序设计的优点:适用于各种网型的水准网,对水准网的条件限制不高;程序的使用较为人性化,可实现交互式操作,简单易懂;程序直接从文件中读取输入数据,数据可以用TXT 文本编辑器实现编好,从而简化输入的步骤,并且适合批量的处理数据;程序设计了一个模块,这样,在水准网的平差的过程中,相应的代码会简洁方便他人的使用,并且合理选择矩阵的运算算法,可以保证最终的结果精确度。
缺点:水准网的平差过程中,需要大量的矩阵计算;文件的读取方式无法通过程序的界面输入,必须按照规定的格式在TXT 文本中实现读取;在进行列立误差方程时候,会出现将通过于两点之间的多条水准路线合并为一条进行计算的缺点;程序采用的是列主元高斯消去法去直接求解改正数,虽然便于计算,但是无法求解每个未知点的高程的协因数,也就无法进一步计算点位平差值中误差。
关于程序的改正展望:在程序中加入逆矩阵,在平差计算中,得到各高程协因数,求得各点高程平差值的中误差;弃用原误差检验方式,尽量探索使用数字探测法检验粗差,使得数据精度提高;在现有的水准网平差中,无法在计算完成后对函数模型进行检验其正确性,争取使用假设检验方式完成函数模型正确性的判定;水准网平差程序默认以一公里观测中误差为单位中误差,在进一步的修正中希望能实现由用户确定单位权中误差。
通过这次学习,我知道了测绘学科与计算机编程是紧密联系的,这是一门与时俱进的学科。它在生产实践中不断遇到新的要求,于是测绘也在不断地挑战中前进发展,就编程而言,编程的目的,算法的实现,我们现在编程,代码的书写,例如文件的读入,输出等等这些都是易于完成的,但是在最关键的部分,算法上我们就欠缺了很多,而这点在完成编程相应步骤的时候是至关重要的;数据结构安排,如何排列数据的格式这些都是我们在编程之前必须规划好的,
建议使用MATLAB 软件进行编程,这样可以在前人的基础上进行程序设计,可以节约很多时间,因为本课程的课时较短,而整个课时中用在矩阵计算上的时间比较多。如果用MATLAB ,可以直接进行平差的程序计算,同时我们也可以了解一个新的软件,方便以后的工作。