文档库 最新最全的文档下载
当前位置:文档库 › 测绘程序设计—实验八 水准网平差程序设计报告

测绘程序设计—实验八 水准网平差程序设计报告

测绘程序设计—实验八 水准网平差程序设计报告
测绘程序设计—实验八 水准网平差程序设计报告

《测绘程序设计(https://www.wendangku.net/doc/0d17226532.html,)》

上机实验报告

(Visual C++.Net)

班级:测绘0901班

学号:0405090204

姓名:代娅琴

2012年4月29日

实验八平差程序设计基础

一、实验目的

?巩固过程的定义与调用

?巩固类的创建与使用

?巩固间接平差模型及平差计算

?掌握平差程序设计的基本技巧与步骤

二、实验内容

水准网平差程序设计。设计一个水准网平差的程序,要求数据从文件中读取,计算部分与界面无关。

1.水准网间接平差模型:

2.计算示例:

近似高程计算:

3.水准网平差计算一般步骤

(1)读取观测数据和已知数据;

(2)计算未知点高程近似值;

(3)列高差观测值误差方程;

(4)根据水准路线长度计算高差观测值的权;

(5)组成法方程;

(6)解法方程,求得未知点高程改正数及平差后高程值;

(7)求高差观测值残差及平差后高差观测值;

(8)精度评定;

(9)输出平差结果。

4.水准网高程近似值计算算法

5.输入数据格式示例

实验代码:

#pragma once

class LevelControlPoint

{

public:

LevelControlPoint(void);

~LevelControlPoint(void);

public:

CString strName;//点名

CString strID;//点号

float H;

bool flag;//标记是否已经计算出近似高程值,若计算出则为,否则为};

class CDhObs

{

public:

CDhObs(void);

~CDhObs(void);

public:

LevelControlPoint* cpBackObj;//后视点

LevelControlPoint* cpFrontObj;//前视点

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(void)

{

}

#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_iUnknownPointCount;//未知点个数

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);//读入观测文件

CString* 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(void);//计算权矩阵

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

#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::~AdjustLevel(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(int 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[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));//根据已知点的数目,创建已知点数组;

int n=0;

for(int i=0;i

{

sf.ReadString(strLine);

CString *pstrData=SplitString(strLine,',',n);

m_pKnownPoint[i].strName=pstrData[0];

m_pKnownPoint[i].strID=pstrData[0];

m_pKnownPoint[i].H=_tstof(pstrData[1]);

m_pKnownPoint[i].flag=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

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(_ttoi(strLine));//按照观测值的大小,创建观测值数组

for(int i=0;i

sf.ReadString(strLine);

CString *pstrData=SplitString(strLine,',',n);

m_pDhObs[i].cpBackObj=SearchPointUsingID(pstrData[0]);//后视点

m_pDhObs[i].cpFrontObj=SearchPointUsingID(pstrData[1]);//前视点

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; //分割符的总数

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;

iNums++;

}

if (iNums == 0) //没有找到分割符

{

//子字符串数就是字符串本身

iSubStrs = 1;

return NULL;

}

//子字符串数组

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);

//右子串

strRight = strTemp.Mid(iPos + 1, strTemp.GetLength());

strTemp = strRight;

pStrSplit[i] = strLeft;

}

pStrSplit[iNums] = strTemp;

return pStrSplit;

}

//

LevelControlPoint* AdjustLevel::SearchKnownPointUsingID(CString ID) {

for(int i=0;i

{

if(m_pKnownPoint[i].strID==ID)

{return &m_pKnownPoint[i];}

}

return NULL;

}

//

LevelControlPoint* AdjustLevel::SearchUnknownPointUsingID(CString ID) {

for(int i=0;i

{

if(m_pUnknownPoint[i].strID==ID)

{return &m_pUnknownPoint[i];}

}

return NULL;

}

LevelControlPoint* AdjustLevel::SearchPointUsingID(CString ID)

{

LevelControlPoint* cp;

cp=SearchKnownPointUsingID(ID);

if(cp==NULL)

cp=SearchUnknownPointUsingID(ID);

return cp;

}

void AdjustLevel::ApproHeignt(void)//用于计算高程近似值的函数

{

for(int i=0;i

{

if(m_pUnknownPoint[i].flag!=1)

{

//先在未知点作为观测值的前视点的情况

for(int j=0;j

{//如果观测值的前视点是未知点且其后视点已经有高程值

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].HObsValue;

m_pUnknownPoint[i].flag=1;

break;

}

}

if(m_pUnknownPoint[i].flag!=1)//如果经过上一步骤未知点仍没有计算出近似值

{

for(int j=0;j

{//如果观测值的后视点是未知点且其前视点已经有高程值

if((m_pDhObs[j].cpBackObj->strID==m_pUnknownPoint[i].strID)

&& 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;

}

}

}

}

if(i==m_iUnknownPointCount-1)//如果已经计算到最后一个未知点

{

for(int a=0;a

{

if(m_pUnknownPoint[i].flag!=1)//只要有一个未知点的近似高程直没有计算

{ //则要重新进行上面的步骤直到所有的未知点的近似高程值都计算出

i=-1;

break;

}

}

}

}

}

CMatrix AdjustLevel::LevleWeight(void)

{

CMatrix p(m_iDhObsCount,m_iDhObsCount);

p.Unit();

double value;

for(int i=0;i

{

value=(1.0/m_pDhObs[i].Dist);

p(i,i)=value;

}

return p;

}

void AdjustLevel::FormErrorEquation(CMatrix &B, CMatrix &L)

{

B.SetSize(m_iDhObsCount,m_iUnknownPointCount);

L.SetSize(m_iDhObsCount,1);

for(int i=0;i

{

LevelControlPoint *tmpBack=NULL,*tmpFront=NULL;

tmpBack=SearchPointUsingID(m_pDhObs[i].cpBackObj->strID);

tmpFront=SearchPointUsingID(m_pDhObs[i].cpFrontObj->strID);

//找到与第i个观测值有关的未知点

tmpBack->strID;

for(int j=0;j

{

if(m_pUnknownPoint[j].strID==tmpBack->strID)//如果是后视点则前面的系数为-1

{ B(i,j)=-1;continue;

}

if(m_pUnknownPoint[j].strID==tmpFront->strID)//如果是前视点则前面的系数为

{

B(i,j)=1;

}

}

}

//建立L矩阵

CString tmp;

for(int i=0;i

{

//l=高差观测值-(后视近似值-前视近似值)

/*L(i,0)=m_pDhObs[i].ObsValue-(m_pDhObs[i].cpBackObj->H-m_pDhObs[i].cpFrontObj->H);*/ L(i,0)=m_pDhObs[i].HObsValue-(m_pDhObs[i].cpFrontObj->H - m_pDhObs[i].cpBackObj->H);

tmp.Format(_T("%.3f"),L(i,0));

L(i,0)=_tstof(tmp);

L(i,0)=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);

NBB=BT*P*B;

CMatrix NBBl=NBB.Inv();

x=NBBl*BT*P*l;

for(int i=0;i

{

m_pUnknownPoint[i].H+=x(i,0);//未知点高程值=近似值+改正数

}

}

void AdjustLevel::Accuracy_Assessment(double &r0,CMatrix &Qxx)//精度评定

{

CMatrix B,l,P,x;

P=LevleWeight(); //P为权矩阵

FormErrorEquation(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,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;

CMatrix x,Qxx;

FormErrorEquation(B,L);//组成误差方程,B为系数矩阵,l为常数项

EquationCompute(x);//计算法方程

Accuracy_Assessment(r0,Qxx);//精度评定

for(int i=0;i

{

Qx[i]=sqrt(Qxx(i,i))*r0;

}

}

#include"Matrix.h"

#include"locale.h"

#include"LevelControlPoint.h"

#include"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);

if (iPos == -1)

{

break;

}

strRight = strTemp.Mid(iPos + 1, str.GetLength());

strTemp = strRight;

iNums++;

}

if (iNums == 0) //没有找到分割符

{

//子字符串数就是字符串本身

iSubStrs = 1;

return NULL;

}

//子字符串数组

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);

//右子串

strRight = strTemp.Mid(iPos + 1, strTemp.GetLength());

strTemp = strRight;

pStrSplit[i] = strLeft;

}

pStrSplit[iNums] = strTemp;

return pStrSplit;

}

void CIndircLelveDlg::OnBnClickedOpendatafile()

{

// TODO: 在此添加控件通知处理程序代码

UpdateData(TRUE);

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, 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();

UpdateData(FALSE);

}

void CIndircLelveDlg::OnBnClickedSavedata()

{

// TODO: 在此添加控件通知处理程序代码

U pdateData(TRUE);

CFileDialog dlgFile(FALSE,_T("txt"),NULL,OFN_EXPLORER,

_T("(Level格式)|*.txt"));

if(dlgFile.DoModal()==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);

}

void CIndircLelveDlg::OnBnClickedComputelevel()

{

// TODO: 在此添加控件通知处理程序代码

UpdateData(TRUE);

setlocale(LC_ALL,"");

double *Qx=new double[LevelComput.m_iUnknownPointCount];

double r0;

https://www.wendangku.net/doc/0d17226532.html,pAdjust(r0,Qx);

LevleContent.Format(_T("平差后高程值:\r\n"));

CString Temp;

for(int i=0;i

{

相关文档