水准网平差VB代码.docx
《水准网平差VB代码.docx》由会员分享,可在线阅读,更多相关《水准网平差VB代码.docx(34页珍藏版)》请在冰点文库上搜索。
水准网平差VB代码
(误差理论与测量平差础)
课程设计报告
系(部):
土木工程系
实习单位:
山东交通学院
班级:
测绘084
学生姓名:
田忠星学号080712420
带队教师:
夏小裕﹑周宝兴
时间:
10年12月13日到10年12月19日
山东交通学院
目录:
1.摘要P3
2.概述P3
3.水准网间接平差程序设计思路P3—P4
4.平差程序流程图P4—P6
5.程序源代码及说明P7—P23
6.计算结果P23—P26
7.总结P26—P27
一:
摘要
在测量工作中,为了能及时发现错误和提高测量成果的精度,常作多余观测,这就产生了平差问题。
在一个平差问题中,当所选的独立参数
的个数等于必要观测数t时,可将每个观测值表达成这t个参数的函数,组成观测方程,这种以观测方程为函数模型的平差方法,就是间接平差。
二:
概述:
该课程设计的主要目是对水准网进行间接平差,在输入数据后依次计算高程近似值﹑误差方程和平差计算。
三:
水准网间接平差程序设计思路
1.根据平差问题的性质,选择t个独立量(既未知点的高程)作为参数
2.将每一个观测量的平差值(既观测的高程差值)分别表达成
3.由误差方程系数B和自由项组成法方程,法方程个数等于参数的个数t;
4.解算法方程,求出参数
计算参数(高程)的平差值
=X0+
;
5.由误差方程计算V,求出观测量(高差)平差值
6.评定精度
单位权中误差
平差值函数的中误差
四:
平差程序流程图
1.已知数据的输入
需要输入的数据包括水准网中已知点数﹑未知点数以及这些点的点号,已知高程和高差观测值﹑距离观测值。
程序采用文件方式进行输入,约定文件输入的格式如下:
第一行:
已知点数﹑未知点数﹑观测值个数
第二行:
点号(已知点在前,未知点在后)
第三行:
已知高程(顺序与上一行的点号对应)
第四行:
高差观测值,按“起点点号,终点点号。
高差观测值,距离观测值”的顺序输入。
本节中使用的算例的数据格式如下
2,3,7
1,2,3,4,5
5.016,6.016
1,3,1.359,1.1
1,4,2.009,1.7
2,3,0.363,2.3
2,4,1.012,2.7
3,4,0.657,2.4
3,5,0.238,1.4
5,2,-0.595,2.6
2.平差计算过程
(1)近似高程的计算。
用一个数组来存储高程近似值,已知点的高程放在这个数组的开头,然后按照点号输入顺序依次搜索涉及该店的高差观测值,看该高差涉及的另一点是否已知,若未知,则检查下一个高差观测值,若已知,则可以计算出当前未知点的高差近似值,并放入高程近似值数组,依次类推,直到所有未知点的高程近似值都被求出为止。
(2)列立观测值的误差方程。
根据各观测值的起止点信息及高差﹑距离值和误差方程的系数矩阵﹑权矩阵和常数项的各个元素赋值。
(3)平差计算。
通过间接平差通用过程进行平差计算,该过程将系数矩阵数组A﹑权矩阵数组P和常数向量数组L以参数的方式传入,通过计算,把平差结果存放在解向量数组X中,以参数的形式传出。
3.计算结果的输出
计算的中间结果和最后结果都实时在文本框中显示,最后还可以把文本框中的内容保存在文本文件中。
4.界面设计
根据以上分析,本程序采用菜单组织程序,用文本框显示数据的输入﹑计算和输出情况。
由于涉及到打开和保存文件的操作,所以还需要一个通用对话框。
(1)菜单设计。
本程序的菜单结构如表所示。
标题
名称
快捷键
文件(&File)
mnuFile
—
…打开数据
mnuOpen
—
…保存结果
mnuSave
—
…—
aa
—
…退出
mnuExit
Ctrl+E
计算(&Calc)
mnuCalc
—
…近似高程
mnuHeight
—
…误差方程
mnuEqu
—
…平差计算
mnuAdj
—
(2)窗体﹑文本框和通用对话框。
在主窗体上绘制1个文本框控件和一个通用对话框控件,并按照下图设置属性(文本框的Name属性改为txtShow)
对象
属性
值
Text1
Text
Text1
MultiLine
True
Form1
Caption
水准网间接平差
CommonDialog1
Name
CDg1
Text1设计好属性后,调整控件和窗体的大小和位置,以方便美观为好。
五:
程序源代码及说明
程序中涉及的公共变量及其说明如下:
DimstrFileNameAsString
Dimnn%,un%,tn%,hn%'已知点个数,未知点个数,总点数,观测值个数
DimPname()AsString'点名数组
DimHknown()AsDouble'已知高程数组,存放已知点高程和高程近似值
Dimbe%(),en%()'观测值的起点和终点编号数组,存储的是点序号
Dimh#(),s#()'高差观测值数组和距离观测值数组
DimA#(),X#(),P#(),L#()'间接平差的系数阵、解向量、权阵和常数向量
1.数据输入
单击“文件→打开文件”命令,弹出打开对话框,待用户选取了文件以后,程序开始读取已知数据,具体代码如下
PrivateSubmnuOpen_Click()
DimiAsInteger'循环变量
DimstrT1AsString,strT2AsString
CDg1.Filter="文本文件(*.txt)|*.txt|所有文件(*.*)|*.*"
CDg1.ShowOpen'打开对话框
strFileName=CDg1.FileName'获得选中的文件名和路径
OpenstrFileNameForInputAs#1'打开文件
Input#1,nn,un,hn'读入已知点个数,未知点个数,观测值个数
tn=nn+un
ReDimPname(1Totn),Hknown(1Totn)
ReDimh(1Tohn),s(1Tohn),be(1Tohn),en(1Tohn)
Fori=1Totn'读入点名
Input#1,Pname(i)
Nexti
Fori=1Tonn'读入已知高程
Input#1,Hknown(i)
Nexti
Fori=1Tohn'读入各观测值
Input#1,strT1,strT2,h(i),s(i)
be(i)=Order(strT1):
en(i)=Order(strT2)'给起终点数组排序
Nexti
'显示读入的数据
txtShow.Text=txtShow.Text&"读入的水准网数据:
"&vbCrLf
txtShow.Text=txtShow.Text&"已知点"&nn&"个,未知点"&un&"个,观测值"&hn&"个。
"&vbCrLf
txtShow.Text=txtShow.Text&"网中涉及的点名有:
"
Fori=1Totn
txtShow.Text=txtShow.Text&Pname(i)&","
Nexti
txtShow.Text=txtShow.Text&vbCrLf
txtShow.Text=txtShow.Text&"已知点高程为:
"&vbCrLf
Fori=1Tonn
txtShow.Text=txtShow.Text&Pname(i)&"的高程为:
"&Hknown(i)&vbCrLf
Nexti
txtShow.Text=txtShow.Text&"各观测值分别为:
"&vbCrLf
txtShow.Text=txtShow.Text&"起点"&""&"终点"&""&"高差观测值"&"距离观测值"&vbCrLf
Fori=1Tohn
txtShow.Text=txtShow.Text&Pname(be(i))&""&Pname(en(i))&""&Format(h(i),"0.000")&""&Format(s(i),"0.000")&vbCrLf
Nexti
Close#1'不要忘记关闭文件
EndSub
其中Order()函数是根据点号(字符串)获得一个点的序号(数值)的自定义函数,之所以要进行这样的排序,是因为在输入和输出时需使用字符串类型的点号,而在程序计算时。
数组的下标元素需要整数型的点号。
该函数定义如下:
'点名-序号转换函数
PublicFunctionOrder(strAsString)AsInteger
Dimi%
Fori=1Totn
Ifstr=Pname(i)Then
Order=i
ExitFor
EndIf
Nexti
EndFunction
2.高程近似值的计算
输入数据后,点击“计算→近似高程”,程序根据已知数据计算未知点的高程近似值,并将计算的中间结果显示在文本框中,代码如下:
'计算近似高程
PrivateSubmnuHeight_Click()
Dimi%,j%
Fori=1Toun
Forj=1Tohn
Ifbe(j)=nn+iAnden(j)Hknown(nn+i)=Hknown(en(j))-h(j)
ExitFor
EndIf
Ifen(j)=nn+iAndbe(j)Hknown(nn+i)=Hknown(be(j))+h(j)
ExitFor
EndIf
Nextj
Nexti
'显示近似高程计算结果
txtShow.Text=txtShow.Text&"近似高程计算结果:
"&vbCrLf
Fori=1Toun
txtShow.Text=txtShow.Text&Pname(i+nn)&":
"&Format(Hknown(i+nn),"0.000")&vbCrLf
Nexti
EndSub
3.列立误差方程
点击“计算→误差方程”命令,程序根据输入的数据给误差方程的系数矩阵﹑权矩阵和常数向量赋值,并将其结果显示在文本框中,代码如下:
'列立误差方程:
给A、P、L赋值
PrivateSubmnuEqu_Click()
Dimi%,j%
ReDimA(1Tohn,1Toun),L(1Tohn),P(1Tohn,1Tohn)
'对每个观测值列误差方程
Fori=1Tohn
Ifen(i)>nnThenA(i,en(i)-nn)=1'若终点未知,则给终点对应的系数矩阵元素赋值
Ifbe(i)>nnThenA(i,be(i)-nn)=-1'若起点未知,则给起点对应的系数矩阵元素赋值
L(i)=-(Hknown(en(i))-Hknown(be(i))-h(i))'根据起终点计算常数项
P(i,i)=1/s(i)'以距离的倒数为权
Nexti
'显示误差方程
txtShow.Text=txtShow.Text&"列立的误差方程:
"&vbCrLf
Fori=1Tohn
Forj=1Toun
txtShow.Text=txtShow.Text&A(i,j)&""
Nextj
txtShow.Text=txtShow.Text&""&Format(L(i),"0.0000")&vbCrLf
Nexti
txtShow.Text=txtShow.Text&"权矩阵:
"&vbCrLf
Fori=1Tohn
Forj=1Tohn
txtShow.Text=txtShow.Text&P(i,j)&""
Nextj
txtShow.Text=txtShow.Text&vbCrLf
Nexti
EndSub
4.计算高程平差值和高程中误差和高差中误差
点击“计算→平差计算”命令,程序调用间接平差通用过程求解误差方程,并求出高程平差值﹑高程中误差和高差中误差,显示在文本框中,代码如下:
'平差计算
PrivateSubmnuAdj_Click()
Dimi%,j%,VtP#(),VtPV#(),z#,AtP#(),AtPA#(),r(),Naan#(),b()
Dimo()AsDouble
ReDimX(1Toun)
ReDimo(1Toun,1To1)
ReDims(1Tohn,1To1)
ReDimAX(1Tohn,1To1)
ReDimV(1Tohn,1To1)
ReDimVtP(1To1,1Tohn)
ReDimVtPV(1To1,1To1)
ReDimAtP(1Toun,1Tohn)
ReDimAtPA(1Toun,1Toun)
ReDimbAt(1Toun,1Tohn)
ReDimAbAt(1Tohn,1Tohn)
ReDimr(1Toun,1Toun)
ReDimb(1Toun,1Toun)
InAdjustA,P,L,X'调用间接平差的通用过程求解
'计算并显示高程平差结果
txtShow.Text=txtShow.Text&"平差计算结果:
"&vbCrLf
txtShow.Text=txtShow.Text&"点号初始高程(m)高程改正数(m)平差后高程(m)"&vbCrLf
Fori=1Toun
txtShow.Text=txtShow.Text&Pname(nn+i)&""&Format(Hknown(nn+i),"0.0000")
Hknown(nn+i)=Hknown(nn+i)+X(i)
txtShow.Text=txtShow.Text&""&Format(X(i),"0.0000")&""&Format(Hknown(nn+i),"0.0000")&vbCrLf
Nexti
txtShow.Text=txtShow.Text&vbCrLf
'计算改正数V
Fori=1Toun
Forj=1To1
o(i,j)=X(i)
Nextj
Nexti
Matrix_MultyAX,A,o
Fori=1Toun
Forj=1To1
s(i,j)=L(i)*1000
Nextj
Nexti
MatrixMinusAX,s,V
Fori=1Tohn
Forj=1To1
V(i,j)=AX(i,j)*1000-s(i,j)
Nextj
Nexti
'计算并显示单位权中误差
MatrixTransV,Vt
txtShow.Text=txtShow.Text&vbCrLf
Matrix_MultyVtP,Vt,P
txtShow.Text=txtShow.Text&vbCrLf
Matrix_MultyVtPV,VtP,V
Fori=1To1
Forj=1To1
z=VtPV(i,j)
Nextj
Nexti
σ0=Sqr(z/(hn-nn))
txtShow.Text=txtShow.Text&"单位权中误差:
(mm)"&vbCrLf
txtShow.Text=txtShow.Text&Format(σ0,"0.0000")
txtShow.Text=txtShow.Text&vbCrLf
'计算未知点的高程中误差
MatrixTransA,At
Matrix_MultyAtP,At,P
Matrix_MultyAtPA,AtP,A
Fori=1Toun
Forj=1Toun
r(i,j)=AtPA(i,j)
Nextj
Nexti
Calljzqn(r(),b())
txtShow.Text=txtShow.Text&"点号高程中误差:
(mm)"&vbCrLf
Fori=1Toun
z=b(i,i)
zz=σ0*Sqr(z)
txtShow.Text=txtShow.Text&Pname(nn+i)&""
txtShow.Text=txtShow.Text&""&Format(zz,"0.0000")&vbCrLf
Nexti
'计算高差平差值的中误差
MatrixTransA,At
Matrix_MultybAt,b,At
Matrix_MultyAbAt,A,bAt
txtShow.Text=txtShow.Text&"起点"&""&"终点"&""&"高差平差值的中误差(mm)"&vbCrLf
Fori=1Tohn
y=AbAt(i,i)
yy=σ0*Sqr(y)
txtShow.Text=txtShow.Text&Pname(be(i))&""&Pname(en(i))&""&Format(yy,"0.0000")&vbCrLf
Nexti
EndSub
在此程序中用到了过程jzqn()代码如下:
PublicSubjzqn(Qa(),na())
DimA()
n=UBound(Qa,1)
ReDimna(n,n)
ReDimA(n,2*n)
Fori=1Ton
Forj=1Ton
A(i,j)=Qa(i,j)
Nextj
Nexti
Fori=1Ton
Forj=n+1To2*n
Ifj-i=nThen
A(i,j)=1
Else
A(i,j)=0
EndIf
Nextj
Nexti
Fori=1Ton
IfA(i,i)=0Then
ForQ=iTon
IfA(Q,i)<>0Then
ForW=iTo2*n
zj=A(i,W)
A(i,W)=A(Q,W)
A(Q,W)=zj
NextW
ExitFor
EndIf
NextQ
IfQ>nThenMsgBox"此矩阵不可逆":
ExitSub
EndIf
ForK=2*nToiStep-1
A(i,K)=A(i,K)/A(i,i)
NextK
Forj=i+1Ton
IfA(j,i)<>0Then
ForK=2*nToiStep-1
A(j,K)=A(j,K)/A(j,i)-A(i,K)
NextK
EndIf
Nextj
Nexti
Fori=nTo1Step-1
IfA(i,i)=0Then
ForQ=i-1To1Step-1
IfA(Q,i)<>0Then
ForW=iTo2*n
zj=A(i,W)
A(i,W)=A(Q,W)
A(Q,W)=zj
NextW
ExitFor
EndIf
NextQ
EndIf
ForK=2*nToiStep-1
A(i,K)=A(i,K)/A(i,i)
NextK
Forj=i-1To1Step-1
IfA(j,i)<>0Then
xxx=A(j,i)
ForK=2*nTo1Step-1
A(j,K)=A(j,K)/xxx-A(i,K)
NextK
EndIf
Nextj
Nexti
Fori=1Ton
Forj=1Ton
na(i,j)=A(i,j+n)
Nextj
Nexti
EndSub
5.保存﹑退出
点击“文件→保存结果”命令,将文本框中的内容保存在指定的文件中,代码如下:
'保存计算结果
PrivateSubmnuSave_Click()
CDg1.Filter="文本文件(*.txt)|*.txt|所有文件(*.*)|*.*"
CDg1.ShowSave
strFileName=CDg1.FileName
OpenstrFileNameForOutputAs#1
Print#1,txtShow.Text
Close#1
EndSub
点击“文件→退出”命令,退出程序。
代码如下:
PrivateSubmnuExit_Click()
End
EndSub
6.此程序用到的通用过程mdlAdjust()代码如下:
'矩阵转置的通用过程
PublicSubMatrixTrans(A,c)
Dimi%,j%
DimR1%,C1%
OnErrorResumeNext
C1=UBound(A,2)-LBound(A,2)+1
IfErrThen
MsgBox"输入的矩阵维数不对!
"
ExitSub
EndIf
R1=UBound(A,1)-LBound(A,1)+