1、 《测绘程序设计(VC.net)》 上机试验汇报 (Visual C++.Net) 班 级: 测绘0901班 学 号: 姓 名: 代娅琴 4月29日 试验八 平差程序设计基础 一、 试验目标 • 巩固过程定义和调用 • 巩固类创建和使用 • 巩固间接平差模型及平差计算 • 掌握平差程序设计基础技巧和步骤 二、 试验内容 水准网平差程序设计。设计一个水准网平差程序,要求数据从文件中读取, 计算部分和界面无关。 1. 水准网间接平差模型: 2. 计算示例:
2、 近似高程计算: 3. 水准网平差计算通常步骤 (1)读取观察数据和已知数据; (2)计算未知点高程近似值; (3)列高差观察值误差方程; (4)依据水准路线长度计算高差观察值权; (5)组成法方程; (6)解法方程,求得未知点高程更正数及平差后高程值; (7)求高差观察值残差及平差后高差观察值; (8)精度评定; (9)输出平差结果。 4. 水准网高程近似值计算算法 5. 输入数据格式示例 试验代码: #pragma once class LevelControlPoint { public: LevelCont
3、rolPoint(void); ~LevelControlPoint(void); public: CString strName;//点名 CString strID;//点号 float H; bool flag;//标识是否已经计算出近似高程值,若计算出则为,不然为 }; class CDhObs { public: CDhObs(void); ~CDhObs(void); public: LevelControlPoint* cpBackObj;//后视点 LevelControlPoint* cpFrontObj;//前视点
4、double ObsValue;//高差值 double Dist;//测站距离 }; #include "StdAfx.h" #include "LevelControlPoint.h" LevelControlPoint::LevelControlPoint(void) { strName=_T(""); strID=_T(""); H=0; flag=0; } LevelControlPoint::~LevelControlPoint(void) { } CDhObs::CDhObs(void) { } CDhObs::~CDhObs(voi
5、d) { } #pragma once #include"LevelControlPoint.h" #include "Matrix.h" class AdjustLevel { public: AdjustLevel(void); ~AdjustLevel(void); public: LevelControlPoint* m_pKnownPoint;//已知点数组 int m_iKnownPointCount;//已知点个数 LevelControlPoint* m_pUnknownPoint;//未知点数组 int m_iUnknownPoi
6、ntCount;//未知点个数 CDhObs* m_pDhObs;//高差观察值数组 int m_iDhObsCount;//高差观察值个数 public: void SetKnownPointSize(int size);//创建大小为size已知点数组 void SetUnkonwnPointSize(int size);//创建大小为size未知点数组 void SetDhObsSize(int size);//创建大小为size观察值数组 bool LoadObsData(const CString& strFile);//读入观察文件 CStrin
7、g* SplitString(CString str, char split, int& iSubStrs); void ApproHeignt(void);//计算近似值 private: LevelControlPoint* SearchKnownPointUsingID(CString ID); LevelControlPoint* SearchUnknownPointUsingID(CString ID); LevelControlPoint* SearchPointUsingID(CString ID); CMatrix LevleWeight(vo
8、id);//计算权矩阵
public:
void FormErrorEquation(CMatrix &B, CMatrix &L);//组成误差方程
void EquationCompute(CMatrix &x);//计算法方程
void Accuracy_Assessment(double &r0,CMatrix &Qxx);//精度评定
void CompAdjust(double &r0,CMatrix Qx[]);
};
#include "StdAfx.h"
#include "AdjustLevel.h"
#include
9、 #include "LevelControlPoint.h" #include "math.h" AdjustLevel::AdjustLevel(void) { m_pKnownPoint=NULL;//已知点数组 m_iKnownPointCount=0;//已知点个数 m_pUnknownPoint=NULL;//未知点数组 m_iUnknownPointCount=0;//未知点个数 m_pDhObs=NULL;//高差观察值数组 m_iDhObsCount=0;//高差观察值个数 } AdjustLevel::~AdjustLev
10、el(void) { if(m_pKnownPoint!=NULL) { delete[] m_pKnownPoint; m_pKnownPoint=NULL; } if(m_pUnknownPoint!=NULL) { delete[] m_pUnknownPoint; m_pUnknownPoint=NULL; } if(m_pDhObs!=NULL) { delete[] m_pDhObs; m_pDhObs=NULL; } } void AdjustLevel::SetKnownPointSize(i
11、nt size) { m_pKnownPoint=new LevelControlPoint[size];//创建动态指针 m_iKnownPointCount=size; } void AdjustLevel::SetUnkonwnPointSize(int size) { m_pUnknownPoint=new LevelControlPoint[size]; m_iUnknownPointCount=size; } void AdjustLevel::SetDhObsSize(int size) { m_pDhObs=new CDhObs
12、[size]; m_iDhObsCount=size;//高差观察值个数 } bool AdjustLevel::LoadObsData(const CString& strFile) { CStdioFile sf; if(!sf.Open(strFile,CFile::modeRead)) return false;//创建并打开文件对象 CString strLine; bool bEOF=sf.ReadString(strLine);//读取第一行,即已知点数目 SetKnownPointSize(_ttoi(strLine));//依据已知点
13、数目,创建已知点数组;
int n=0;
for(int i=0;i 14、lag=1;//已知点不用平差,故将其flag设置为
delete[] pstrData;
pstrData=NULL;
}
sf.ReadString(strLine);//读取未知点个数
SetUnkonwnPointSize(_ttoi(strLine));//依据未知点个数创建未知点数组
sf.ReadString(strLine);//读取未知点点名
CString *pstrData=SplitString(strLine,',',n);
for(int i=0;i 15、
{
m_pUnknownPoint[i].strName=pstrData[i];
m_pUnknownPoint[i].strID=pstrData[i];
m_pUnknownPoint[i].H=0;//未知点高程值设置为
m_pUnknownPoint[i].flag=0;//还没有求得近似高程,故其flag设置为
}
if(pstrData!=NULL)
{
delete[] pstrData;
pstrData=NULL;
}
sf.ReadString(strLine);//读取观察值个数
SetDhObsSize 16、ttoi(strLine));//根据观察值大小,创建观察值数组
for(int i=0;i 17、 m_pDhObs[i].HObsValue=_tstof(pstrData[2]);//高差观察值
m_pDhObs[i].Dist=_tstof(pstrData[3]);//距离观察值
delete[] pstrData;
pstrData=NULL;
}
sf.Close();
return 1;
}
CString* AdjustLevel::SplitString(CString str, char split, int& iSubStrs)
{
int iPos = 0; //分割符位置
int iNums = 0; // 18、分割符总数
CString strTemp = str;
CString strRight;
//先计算子字符串数量
while (iPos != -1)
{
iPos = strTemp.Find(split);
if (iPos == -1)
{
break;
}
strRight = strTemp.Mid(iPos + 1, str.GetLength());
strTemp = strRight;
19、 iNums++;
}
if (iNums == 0) //没有找到分割符
{
//子字符串数就是字符串本身
iSubStrs = 1;
return NULL;
}
//子字符串数组
iSubStrs = iNums + 1; //子串数量= 分割符数量+ 1
CString* pStrSplit;
pStrSplit = new CString[iSubStrs];
strTemp = str;
CString strLef 20、t;
for (int i = 0; i < iNums; i++)
{
iPos = strTemp.Find(split);
//左子串
strLeft = strTemp.Left(iPos);
//右子串
strRight = strTemp.Mid(iPos + 1, strTemp.GetLength());
strTemp = strRight;
pStrSplit[i] = strLeft;
}
pStrSplit 21、[iNums] = strTemp;
return pStrSplit;
}
//
LevelControlPoint* AdjustLevel::SearchKnownPointUsingID(CString ID)
{
for(int i=0;i 22、nownPointUsingID(CString ID)
{
for(int i=0;i 23、f(cp==NULL)
cp=SearchUnknownPointUsingID(ID);
return cp;
}
void AdjustLevel::ApproHeignt(void)//用于计算高程近似值函数
{
for(int i=0;i 24、观察值前视点是未知点且其后视点已经有高程值
if((m_pDhObs[j].cpFrontObj->strID==m_pUnknownPoint[i].strID)
&& m_pDhObs[j].cpBackObj->flag==1 )
{ //前视点=后视点-高差
/*m_pUnknownPoint[i].H=m_pDhObs[i].cpBackObj->H - m_pDhObs[i].ObsValue;*/
m_pUnknownPoint[i].H=m_pDhObs[j].cpBackObj->H + m_pDhObs[j].HOb 25、sValue;
m_pUnknownPoint[i].flag=1;
break;
}
}
if(m_pUnknownPoint[i].flag!=1)//假如经过上一步骤未知点仍没有计算出近似值
{
for(int j=0;j 26、 && m_pDhObs[j].cpFrontObj->flag==1 )
{ //后视点=前视点+高差
m_pUnknownPoint[i].H=m_pDhObs[j].cpFrontObj->H-m_pDhObs[j].HObsValue;
/* m_pUnknownPoint[i].H=m_pDhObs[i].cpFrontObj->H+m_pDhObs[i].ObsValue;*/
m_pUnknownPoint[i].flag=1;
break;
}
27、}
}
}
if(i==m_iUnknownPointCount-1)//假如已经计算到最终一个未知点
{
for(int a=0;a 28、ustLevel::LevleWeight(void)
{
CMatrix p(m_iDhObsCount,m_iDhObsCount);
p.Unit();
double value;
for(int i=0;i 29、nt,m_iUnknownPointCount);
L.SetSize(m_iDhObsCount,1);
for(int i=0;i 30、 tmpBack->strID;
for(int j=0;j 31、t i=0;i 32、)=L(i,0)*1000;//将单位化为mm
}
}
void AdjustLevel::EquationCompute(CMatrix &x)//计算法方程
{
CMatrix P,B,l;
P=LevleWeight(); //P为权矩阵
FormErrorEquation(B,l);
ApproHeignt();
CMatrix BT(m_iUnknownPointCount,m_iDhObsCount);
BT=~B; //B转置矩阵
CMatrix NBB(m_iUnknownPointCount,m_iUnknownPointCount) 33、
NBB=BT*P*B;
CMatrix NBBl=NBB.Inv();
x=NBBl*BT*P*l;
for(int i=0;i 34、B,l);
EquationCompute(x);
CMatrix v(m_iDhObsCount,1);
v=B*x-l;
CMatrix vT(1,m_iDhObsCount);
vT=~v;
CMatrix r/*(1,l)*/;
r=vT*P*v;
r0=sqrt(r(0,0)/(m_iDhObsCount-m_iUnknownPointCount));//单位权中误差
Qxx.SetSize(m_iUnknownPointCount,m_iUnknownPointCount);
CMatrix BT(m_iUnknownPointCount, 35、m_iDhObsCount);
BT=~B;
CMatrix NBB(m_iUnknownPointCount,m_iUnknownPointCount);
NBB=BT*P*B;
Qxx=NBB.Inv();
}
void AdjustLevel::CompAdjust(double &r0,CMatrix Qx[])
{
ApproHeignt();//计算未知点近似高程值而且存入数组
CMatrix P(m_iDhObsCount,m_iDhObsCount);
P=LevleWeight();//p为权矩阵
CMatrix B,L;
CMa 36、trix x,Qxx;
FormErrorEquation(B,L);//组成误差方程,B为系数矩阵,l为常数项
EquationCompute(x);//计算法方程
Accuracy_Assessment(r0,Qxx);//精度评定
for(int i=0;i 37、ude "AdjustLevel.h"
AdjustLevel LevelComput;
CString* SplitString(CString str, char split, int& iSubStrs)
{
int iPos = 0; //分割符位置
int iNums = 0; //分割符总数
CString strTemp = str;
CString strRight;
//先计算子字符串数量
while (iPos != -1)
{
iPos = strTemp.Find(split);
38、 if (iPos == -1)
{
break;
}
strRight = strTemp.Mid(iPos + 1, str.GetLength());
strTemp = strRight;
iNums++;
}
if (iNums == 0) //没有找到分割符
{
//子字符串数就是字符串本身
iSubStrs = 1;
return NULL;
}
39、//子字符串数组
iSubStrs = iNums + 1; //子串数量= 分割符数量+ 1
CString* pStrSplit;
pStrSplit = new CString[iSubStrs];
strTemp = str;
CString strLeft;
for (int i = 0; i < iNums; i++)
{
iPos = strTemp.Find(split);
//左子串
strLeft = strTemp.Left(iPos);
40、 //右子串
strRight = strTemp.Mid(iPos + 1, strTemp.GetLength());
strTemp = strRight;
pStrSplit[i] = strLeft;
}
pStrSplit[iNums] = strTemp;
return pStrSplit;
}
void CIndircLelveDlg::OnBnClickedOpendatafile()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE 41、);
CFileDialog dlgFile(TRUE,_T("txt"),NULL,OFN_ALLOWMULTISELECT|OFN_EXPLORER,
_T("(文本文件)|*.txt"));//创建文件对话框
if(dlgFile.DoModal()==IDCANCEL) return;//假如选择取消按钮则返回
CString strFileName=dlgFile.GetPathName();//打开获取文件文件名
setlocale(LC_ALL,""); //设置语言环境
CStdioFile sf;
if(!sf.Open(strFileName, 42、 CFile::modeRead)) return;
InputContent.Empty();//清空字符串str_openContent中内容
CString strLine;
BOOL bEOF=sf.ReadString(strLine);//读取第一行数据
while(bEOF)//开始读取顶点数据
{
bEOF=sf.ReadString(strLine);
if(bEOF)
InputContent+=strLine+_T("\r\n");
}
sf.Close();
UpdateD 43、ata(FALSE);
}
void CIndircLelveDlg::OnBnClickedSavedata()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
CFileDialog dlgFile(FALSE,_T("txt"),NULL,OFN_EXPLORER,
_T("(Level格式)|*.txt"));
if(dlgFile.DoModal()==IDCANCEL) return;
CString strFileName=dlgFile.GetPathName();
setlocale(LC_AL 44、L,"");
CStdioFile sf;
if(!sf.Open(strFileName, CFile::modeCreate|CFile::modeWrite)) return;
sf.WriteString(LevleContent);
sf.Close();
UpdateData(FALSE);
}
void CIndircLelveDlg::OnBnClickedComputelevel()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
setlocale(LC_ALL,"");
dou 45、ble *Qx=new double[LevelComput.m_iUnknownPointCount];
double r0;
LevelComput.CompAdjust(r0,Qx);
LevleContent.Format(_T("平差后高程值:\r\n"));
CString Temp;
for(int i=0;i 46、strID,LevelComput.m_pUnknownPoint[i].H);
LevleContent+=Temp;
}
Temp.Format(_T("单位权中误差:%.1f mm\r\n"),r0*1000);
LevleContent+=Temp;
LevleContent+=_T("未知点高程中误差(mm):\r\n");
for(int i=0;i< LevelComput.m_iUnknownPointCount;i++)
{
Temp.Empty();
Temp.Format(_T("%s,%.1f\r\n"),LevelCompu 47、t.m_pUnknownPoint[i].strName,Qx[i]*1000);
LevleContent+=Temp;
}
UpdateData(false);
}
void CIndircLelveDlg::OnBnClickedSavelevleresult()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);
CFileDialog dlgFile(FALSE,_T("txt"),NULL,OFN_EXPLORER,
_T("(Level格式)|*.txt"));
if(dlgFile.DoModal()= 48、IDCANCEL) return;
CString strFileName=dlgFile.GetPathName();
setlocale(LC_ALL,"");
CStdioFile sf;
if(!sf.Open(strFileName, CFile::modeCreate|CFile::modeWrite)) return;
sf.WriteString(LevleContent);
sf.Close();
UpdateData(FALSE);
}
三、 试验结果
打开文件数据:
平差结果:
四、试验心得
这从试验是我们测绘 49、程序设计最终一次试验,即使这个学期我们做了好几次相关试验,不过我却发觉自己学东西也越来越模糊,感觉很多内容全部不了解。这次试验很大程度上我全部是根据《测绘程序设计》上面单导线简易计算来编,在加上后面相关水准网间接平差误差方程和法方程,和精度评定相关函数,来完成。而自己关键完成就是水准网数据读取,保留操作,因为这部分关键用知识是文件读取,因为前面做过,所以不是太难。不过这并不意味着这次试验很简单,最少在我心中这确实比较难,因为里面很多东西不是纯粹把代码写上去就能够完成,还要靠自己做对应代码对应,才能够真正得到想要结果。但学好编程并扎实为自己所用是需要更多学习和练习,我知道在掌握课堂知识同时,主动去寻求吸收相关知识,期望经过本门课程学习,掌握学习编程方法,使自己水平能够更深入,循序渐进掌握更多。即使这门课试验已经结束,不过我却深深地知道,我们专业对编程要求很高,而且必需含有很好编程能力,或许这些日子下来,我学到不是很多,不过我或多或少明白,编程是一个循序渐进过程,我想真能够在这方面有所突破,就更要花时间多花工夫。






