程序设计讲义第二篇 2.docx
- 文档编号:16425599
- 上传时间:2023-07-13
- 格式:DOCX
- 页数:29
- 大小:50.62KB
程序设计讲义第二篇 2.docx
《程序设计讲义第二篇 2.docx》由会员分享,可在线阅读,更多相关《程序设计讲义第二篇 2.docx(29页珍藏版)》请在冰点文库上搜索。
程序设计讲义第二篇2
测量程序设计讲义第二篇
一、控制网的数据结构
1、平差程序的数据结构
测量观测数据之间存在固定的关系,例如方向值、观测边都只有与测站点、照准点联系起来才有意义,所以确定了关系的观测值就是“控制网”的数据结构。
平差程序处理对象是各类控制网的观测值,由于观测值总是与不同的网型相联系,所以必须通过适当的编排,使观测值之间的联系能被计算机识别,这项工作可以称为网型数据化。
尽管对于观测结束的控制网而言,观测之间的关系是确定的,但是不同的平差程序,反映这些关系的方法不相同,所以说控制网的已知数据、观测数据、以及描述它们之间联系的组织编排可称为“测量平差程序”的数据结构。
2、测量平差程序的数据结构在平差程序设计中的作用
对于一个复杂的通用平差程序设计,首要的问题就是确定数据结构。
程序设实用性、可靠性都很大程度上取决于数据结构是否合理。
数据结构也直接决定着算法,数据结构一变,程序就随之改变,所以数据结构设计是一个非常重要的问题,甚至有人提出;算法+数据结构=程序。
3、平差程序的数据结构应满足的条件
(1)、充分条件:
应包含足够的数据,即:
必要的起算数据,大于必要观测数的独立观测值,这一点主要通过合理的布网和观测来解决,与程序设计关系不大。
(2)、必要条件:
数据结构只含构网必须的数据,无冗余数据。
注意这里所谓冗余数据是指描述网型的关系数据冗余,而不是多余观测数。
(3)、满足充分必要条件与否与程序的关系:
不满足充分条件,控制网中的待定元素将不能全部算出,从而程序不能成功运行;若不满足必要条件,可能程序能成功运行,解算正确,但是由于多而复杂的数据录入,使程序的方便性、可读性受到影响,用户会感到使用不便、难于维护,影响程序的质量。
二、导线网平差程序的数据结构
用户对平差程序的数据结构的要求是:
对控制点名无特殊要求,数据编排形式简单,没有严格的顺序要求,容易记住。
武汉大学测绘学院“科傻”平差软件,观测数据文件格式为:
方向中误差,测距固定误差,测距比例误差
已知点名,X坐标,Y坐标
。
。
。
测站点
照准点,标识符,观测值
。
。
。
它的数据格式特点很好地满足了上述要求,数据录入形式简单、输入量小,仅仅需要直接录入已知点坐标、测站名、照准点名、观测值即可、平差计算所需的已知点数、待定点数、方向观测值数、边长观测值数等信息均通过判读获取,程序运行后,用户不再需要通过人机交付方式输入信息,使用非常方便。
三、示例程序的采用的算法
1、控制点按录入顺序分配计算号:
数据结构中点名本身按实际点名录入,但计算机处理这样的点名是不方便的,所以程序中每个点都有一个计算号。
点名与点号一一对应,计算机处理数据时用点号,输出时使用点名。
程序中使用数组元素dm(i)保存点名,dm(i)中值按计算机录入的先后顺序存入,以数组元素的序号i作为控制点的计算编号,所以其计算号的顺序也是按读入的先后,由小到大地分配。
由于点名在数据中分别出现在测站和照准点中,其中测站中只会出现一次,而照准点中可能会出现多次,所以采用的做法是,当读到测站时,将其点名计入dm()数组,数据读完后,再搜索没有设过站的控制点(没有连接角的已知点、支站),将其点名补入dm()数组。
2、观测值与其照准点的存储
程序中在处理近似坐标计算、组误差方程等过程中都需要依次调用所有的观测值,采用的是首先按测站循环,然后在测站上,再进行按方向或边长循环的算法。
若将每一测站的观测值分别以不同的数组储存,则数组众多,调用非常不便,所以采用方法是全部方向观测值都存入数组l(),边长观测值存入数组s()的方法。
为了能识别某一测站上i有哪些观测值,设立数组nl(i)、ns(i)存入i测站上的最大方向值号、最大边长号。
数据结构中单列一个测站的观测值,该测站所观测的照准点和观测值位于同一行,所以读到方向观测值就将其赋给了l(j),同时将其照准点名赋给lb(j),读到边长观测值赋给s(j),照准点赋给sb(j)。
由于观测值与其照准点名在数组中的序号相同,所以查找非常方便。
同时,在初始化nl(i)=nl(i-1),ns(i)=ns(i-1)基础上,每读到一个方向值,nl(i)=n(i)+1,读到一个边长观测值,则ns(i)=ns(i)+1。
当i测站的观测数据读完后,数组nl(i)、ns(i)中保存的就是i测站上的最大方向值号、最大边长号。
有了数组nl(i)、ns(i),才能查出i测站的最小方向值号和最大方向值号,以及最大边长号和最小边长号。
3、近似坐标推算
导线网中已知点位置和个数都各不相同,但概括的说就两种情况,或者已知点相邻并且通视;或者不相邻,所以简便并适应两种情况的算法是:
假定任一点坐标和这一点所观测的某一方向的坐标方位角,按测站、方向做二重循环,依次推算其余点的假定坐标,一般而言,在几个循环内即可推算出全部控制点的假定坐标(包括已知点),然后利用一对已知点的坐标和假定坐标所包含的坐标转换信息,对全部假定坐标进行平移、旋转变换,得到近似坐标。
4、组误差方程、法方程
在测站循环的基础上,进行一测站上的方向循环、边长循环,分别依次调用所有的观测值,计算误差方程系数及常数,并立即将其对法方程系数阵元数、常数项元素的贡献充填进法方程系数及常数数组元素。
采用这样的算法,只需要一个1维数组b(),临时保存误差方程系数元素,当所有的观测值处理完毕,法方程就组成了。
5、法方程的组成及解算
法方程系数阵元素储存采用上三角一维数组存储,目的是节省备存空间,法方程的解算是采用高斯约化法。
四、导线网平差程序设计
DimfsoAsNewFileSystemObject,tsAsTextStream,FlAsFile,fnameAsString'定义用于各个过程的模块级变量
Dimxo()AsDouble,yo()AsDouble,ym()AsString,ydsAsInteger
DimmaAsSingle,msAsSingle,mkAsSingle,zdsAsInteger,m(20)AsInteger
Privatel()AsDouble,s()AsDouble,dm()AsString
Privatenl()AsInteger,ns()AsInteger,lb()AsString,sb()AsString,cdsAsInteger
Privatex()AsDouble,y()AsDouble,NX()AsDouble,UX()AsDouble,llAsDouble
Constpi=3.141592654
PrivateSubForm_load()'启动程序时初始化
Fil
(2).Enabled=False'"保存"菜单不可用
Fil(3).Enabled=False'"另存"菜单不可用
Text1.Visible=False'文本框不可见
MMControl1.Visible=False'播放控件不可视
MMControl1.DeviceType="sequencer"'指定音乐文件类型是MIDI型
MMControl1.FileName="c:
\windows\media\贝多芬第五交响乐.rmi"'等号右边部分是文件名及地址
MMControl1.Command="open"'打开背景音乐文件
MMControl1.Command="play"'播放
EndSub
PrivateSubForm_Resize()'设置窗体变化时,文本框对应变化功能
WithText1'以下属性值前可省略对象名
.Left=0'窗体外框左边缘与屏幕显示区左边缘距离为0
.Top=Picture1.Height'窗体外框上边缘与屏幕显示区上边缘距离为图片框高度值.
.Height=Form1.Height-Picture1.Height'文本框的高度为窗体高度减图片框高度
.Width=Form1.Width'文本框宽度等于窗体宽度
EndWith
EndSub
PrivateSubFil_Click(IndexAsInteger)'文件菜单点击事件
SelectCaseIndex
Case0'新建文件,调入写字板程序建立新文本文件
Form1.Caption="建立新数据文件"
xx=Shell("notepad.exe",vbNormalFocus)'参数设定最大化方式并有焦点,变量xx用来
'接受调用成功后返回的任务标识码,是语法所要求的。
Case1'打开一个已有文件,显示在文本框中
CommonDialog1.ShowOpen'打开公共对话框中的"open"对话框
fname=CommonDialog1.FileName'将用户在"open"对话框中选中的文件名(字符串)赋给变量fname
Iffname<>""Then'若无此判断当对话框中按取消钮时、下面语句将出错
SetFl=fso.GetFile(fname)'对文件设值句柄。
IfFl.Size<10Then'避免打开空文件时出错
MsgBox"文件"&fname&"是空文件"
Else
Setts=fso.OpenTextFile(fname)'打开文件同时设句柄
B=ts.ReadAll'读取文本文件全部内容
Text1.Text=B'将读取的字符,显示在文本框text1中
Text1.Visible=True'使文本框中内容可见
Form1.Caption=fname'更换窗体标题
EndIf
EndIf
Fil
(2).Enabled=True'使菜单"保存"可用
Fil(3).Enabled=True'使菜单"另存"可用
Case2'存文件
IfText1.Visible=TrueThen'表明有文件打开
Setts=fso.CreateTextFile(fname,True)'设True参数则允许覆盖,fname-模块级变量。
ts.WriteText1.Text'写文件
Text1.Visible=False'使文本框内容不可视
Fil
(2).Enabled=False
Fil(3).Enabled=False
ts.Close'不关闭,再次选择打开这个文件时会出错
EndIf
Case3'另存文件
IfText1.Visible=TrueThen
CommonDialog1.Flags=2'设置对话框flags属性为2,当已有同名文件时询问是否覆盖。
CommonDialog1.ShowSave'打开公共对话框中的"SaveAs"对话框
fname=CommonDialog1.FileName'选择不覆盖同名文件时,返回"另存"对话框。
Iffname<>""Then
Setts=fso.CreateTextFile(fname,True)'True参数指出同名文件可被覆盖
ts.WriteText1.Text'将显示在文本框1中的文本以文件名fname保存
ts.Close
EndIf
EndIf
Case4'结束程序运行
Text1.Text=""'清除文本框显示
End'结束整个程序运行
EndSelect'SelectCaseIndex语句结尾
EndSub'菜单点击事件结尾
PrivateSubedi_Click(IndexAsInteger)'编辑菜单点击事件
SelectCaseIndex
Case0'剪切
Clipboard.SetTextText1.SelText'.selText是Text1的一个属性值,内容是用户选中的文本,只能用于代码。
Text1.SelText=""'将纯文本内容放入剪贴板的语法为:
Clipboard.SetTextdate。
参数date可是任何能转换为字符型的变量、常量、属性或表达式
Case1'复制
Clipboard.SetTextText1.SelText'将Text1.SelText的值放入剪贴板
Case2'粘贴
Text1.SelText=Clipboard.GetText()'用剪贴板中的值对Text1.SelText赋值,SelText属性设置\返回包含当前选定文本的字符串。
Case3'删除
Text1.SelText=""
EndSelect
EndSub
PrivateSubEdit_Click()'设置编辑菜单的状态,Text1的selLength属性为0表明没有字符被选中
Edi(0).Enabled=IIf(Text1.SelLength=0,False,True)'条件成立执行前一项,否则执行一项。
Edi
(1).Enabled=IIf(Text1.SelLength=0,False,True)
Edi
(2).Enabled=IIf(Text1.SelLength=0,False,True)
Edi(3).Enabled=IIf(Text1.SelLength=0,False,True)
EndSub
PrivateSubForm_MouseDown(ButtonAsInteger,shiftAsInteger,xAsSingle,yAsSingle)'在窗体上单击鼠标右键事件
IfButton=2Then'Button参数指出按下哪一个鼠标键,1-左,2-右。
括号内部分是鼠标事件固定参数设置。
Form1.PopupMenuFiles
EndIf
EndSub
PrivateSubtext1_MouseDown(ButtonAsInteger,shiftAsInteger,xAsSingle,yAsSingle)'在文本框上单击鼠标右键事件
IfButton=2Then
Form1.PopupMenuEdit,4
EndIf
EndSub
PrivateSubCommand1_Click(IndexAsInteger)'设置快捷按钮点击与菜单点击的对应关系
n=Index'工具条上共六个按钮,Index属性0-5分别是:
新建、打开、保存、剪切、复制、粘贴
Ifn<3Then
Fil_Click(n)'由于已有对应语句,可用此简化表示方法,文件主菜单名Files,五个子菜单名均为Fil
Else'Index属性0-4,分别对应新建、打开、保存、另存、关闭
edi_Click(n-3)'编辑主菜单Edit,四个之菜单名均为Edi,Index属性0-3分别对应剪切、复制、粘贴、删除
EndIf
EndSub
PrivateSubadj_Click(IndexAsInteger)'平差菜单下点击子菜单事件
Dimtr(10)AsString'定义过程级变量
Dimnb()AsDouble,nc()AsDouble
DimiAsInteger,jAsInteger,kAsInteger,hAsInteger
SelectCaseIndex
Case0'读入观测值文件
Text1.Visible=False
CommonDialog1.ShowOpen
fname=CommonDialog1.FileName'将用户在"打开"对话框中选择的文件名对变量fname赋值
Iffname<>""Then'若无此判断当对话框中选择取消时、下面赋值语句将出错
Setts=fso.OpenTextFile(fname)'将fname作为文本文件打开,并设置句柄
EndIf
j=0:
k=0:
nl(j)=0:
ns(j)=0:
p=0:
h=0
'j是测站数累计变量,k是已知点累计变量,l(j)、ns(j)分别是方向值、边长累积计数
DoWhilets.AtEndOfLine<>True'前测型循环,进入循环的条件是没有读到文件结束尾
B=ts.ReadLine'读一行,置入b
B=Trim(B):
i=1:
'删除B可能有的前导和尾随空格,i是工作变量,
m(i)=InStr(B,",")'查行中第一个逗号的左数位置,并保存在整形数组变量m(i)中
Ifm
(1)<>0then‘字符串中有逗号
tr
(1)=Mid(B,1,m
(1)-1)'提取指定位置开始的指定数目字符。
m
(2)=InStr(m
(1)+1,B,",")'从上一个找到的逗号位置起,查找下一个逗号的位置
tr
(2)=Mid(B,m
(1)+1,m
(2)-m
(1)-1)
tr(3)=Right(B,Len(B)-m
(2))‘处理一行中最后一个逗号后的字符串
ifp=0Thenma=tr
(1):
ms=tr
(2):
mk=tr(3):
p=1'读到的是第一行,提取观测方向,边先验精度值,修改识别符p的值,
使该句以后不能再执行。
Ifp=1Thenk=k+1:
ReDimPreserveym(k):
ReDimPreservexo(k):
ReDimPreserveyo(k):
ym(k)=tr
(1):
xo(k)=Val(tr
(2)):
yo(k)=Val(tr(3))‘‘读到的是已知点坐标,存入相应的变量
Ifp=2then
tr
(2)=LCase(tr
(2))
Iftr
(2)="l"Then
nl(j)=nl(j)+1:
ReDimPreservelb(nl(j)):
ReDimPreservel(nl(j)):
lb(nl(j))=tr
(1):
l(nl(j))=Val(tr(3))
'累计测站方向数、提取照准点、方向值
else
ns(j)=ns(j)+1:
ReDimPreservesb(ns(j)):
ReDimPreserves(ns(j)):
sb(ns(j))=tr
(1):
s(ns(j))=Val(tr(3))
‘提取边观测数、提取照准点、观测边
Endif
Endif
Else
j=j+1:
ReDimPreservedm(j):
ReDimPreservenl(j):
ReDimPreservens(j):
dm(j)=B:
nl(j)=nl(j-1):
ns(j)=ns(j-1):
p=2
Endif‘`m
(1)=0,表明读到测站了,以后遇到有逗号的行,只能是观测值了。
所以将识别符p赋值2,目的是使得提取已知点信息的语句不再执行,并对该测站最大方向号,最大边长号数组变量nl(j)、ns(j)赋值累计起始值
ts.Close
cds=j:
yds=k'用模块级变量cds、yds保存测站点总数、已知点总数
d=cds'd是测站数
Fori=1Tonl(cds)'依次访问所有的方向值
p=0'设识别变量
Forj=1Tod'依次访问所有测站
Ifdm(j)=lb(i)Thenp=1'查看目标点是否设过测站,是则对识别变量p赋值1。
Nextj
Ifp=0Thend=d+1:
ReDimPreservedm(d):
ReDimPreservens(d):
dm(d)=lb(i)
'如p=0,表明目标点未设过测站,将该点点名加入点名数组
Nexti
zds=d'将总点数存入模块级变量zds
MsgBox"数据已成功读入",0+64+0,"数据输入"
Case1'解算近似坐标
ReDimx(zds),y(zds)'重新定义坐标数组
x
(1)=10000:
y
(1)=10000'为推算近似坐标,对第一个点赋假设坐标值
k=1
Fori=1Toyds
Iflb
(1)=ym(i)Thenk=k+1
Nexti
ss=sid(1,k)'调出第一点到未知点方向的边长,参数是测站点序号,照准方向号
h=seqn(lb(k))'查k方向照准点的计算序号
x(h)=x
(1)+ss*Cos(0):
y(h)=y
(1)+ss*Sin(0)'计算第一点上第k方向值的目标点假设坐标
Fori=1Tonl(cds)'遍访所有方向值,将其由角度值转换为弧度值.
Ifl(i)>0.001Thenl(i)=radian(l(i))'零方向值不参加转换
Nexti
n=0
Do
n=n+1'n是循环计数变量,控制循环次数,避免假定坐标计算不出时,进入死循环。
Fori=1Tocds'按测站循环
Ifx(i)>1Then'在该测站假设坐标已计算出的前提下,求照准点假设坐标
p1=0
Forj=nl(i-1)+1Tonl(i)'遍访i测站上所有方向值
h=seqn(lb(j))'查目标点对应的序号
Ifx(h)>1Then'目标点坐标已解出
t=azimuth(x(i),y(i),x(h),y(h)):
p1=j'反算方位角并记下方向号
ExitFor'退出For-Next循环
EndIf
Nextj
Forj=nl(i-1)+1Tonl(i)'再次遍访i测站上的所有方向值
h=seqn(lb(j))'查目标点对应的序号
Ifx(h)<1Then'该照准方向点坐标未求出
tt=t+l(j)-l(p1)'计算j方向的方位角
ss=sid(i,j)'根据测站号、方向号去查找边长
Ifss=0Thenss=side(i,h)
x(h)=x(i)+ss*Cos(tt):
y(h)=y(i)+ss*Sin(tt)'计算假设坐标
EndIf
Nextj
EndIf
Nexti
p=0
Fork=1Tozds
Ifx(k)<1Thenp=1'查看是否还有没解算出坐标的点,有则对p赋值,使进入循环再次搜索计算
Nextk
LoopUntilp=0Orn
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 程序设计讲义第二篇 程序设计 讲义 第二