测绘程序设计 水准网实验 CSU
水准网实验 CSU一、实验目的二、实验内容三、设计与实现3.1 实验基本思路3.2 类的设计3.2.1 设计思路3.2.2 头文件(代码展示)3.2.3 cpp文件(代码展示)3.3 界面设计3.4 “计算”按钮对应的映射函数3.5 结果展示四、心得总结一、实验目的掌握面向对象编程基本思想掌握 VC++.net 中创建类掌握建立和使用对象掌握运算符号重载理解类的继承和多态性二、实验内容要求:设计一
水准网实验 CSU
一、实验目的
- 掌握面向对象编程基本思想
- 掌握 VC++.net 中创建类
- 掌握建立和使用对象
- 掌握运算符号重载
- 理解类的继承和多态性
二、实验内容
要求:设计一个水准网类,注意水准的基本属性。功能上要求:(1)能够通过
界面上的文本框按照以下格式输入数据;(2)能够计算未知点近似高程。
算例:
三、设计与实现
3.1 实验基本思路
1、设计一个水准网的类,类的(私有)成员包括已知点数,已知点,未知点数,未知点,高程差数和高程差,类能够实现的功能包括(重载)构造函数,析构函数,拷贝构造函数,为成员赋值,返回成员,计算未知点高程的近似值。
2、界面设计:设置两个编辑框,一个负责输入数据,另外一个负责输出数据(未知点的高程)。设置两个按钮,一个为“计算”,负责提取输入框中的数据,并输出结果,另一个按钮为“取消”,负责将两个编辑框清空。
3、本实验要利用类做到代码与界面分离,即不能直接利用界面输入的数据进行计算,要利用类进行计算。输入输出数据。
3.2 类的设计
3.2.1 设计思路
1、类的私有成员的设计思路:已知点和未知点都采用点位结构体数组来表示,用new函数动态存储,点位结构体的成员包含点号、高程值和高程是否已计算出的标志(bool型变量,为后来未知点高程计算函数的编写提供便利)。高程差采用高程差结构体数组来表示,同样采用new函数来动态存储,高程差结构体的成员包括起点、终点(均为点位结构体的指针变量)、高程差和路线长度。
#pragma once
//点位结构体
struct Point
{
CString name;//点号
double dHigh;//高程值
bool state;//高程值是否已计算出的状态
};
//高程差结构体
struct DiffH
{
Point* Start;//起点
Point* End;//终点
double dDiffH;//高程差
double dLen;//路线长度
};
class LevNet
{
private:
int GivPoiCount;//已知点数
Point* GivPoi;//动态存储已知点数组
int ObsPoiCount;//未知点数
Point* ObsPoi;//动态存储未知点数组
int DiffHCount;//高程差数
DiffH* ObsDiffH;//动态存储高程差数组
public:
LevNet(void);//构造函数
LevNet(int GivPoiCount_, Point* GivPoi_, int ObsPoiCount_, Point* ObsPoi_, int DiffHCount_, DiffH* ObsDiffH_);//重载构造函数
~LevNet(void);//析构函数
LevNet(LevNet &A);//拷贝构造函数
void SetGivPoi(int GivPoiCount_, Point* GivPoi_);//为已知点赋值
void SetObsPoi(int ObsPoiCount_, Point* ObsPoi_);//为未知点赋值
void SetDiffH(int DiffHCount_, DiffH* ObsDiffH_);//为高程差赋值
Point* GetGivPoi(void);//返回已知点
Point GetGivPoi_i(int i);//返回第i个已知点
Point* GetObsPoi(void);//返回未知点
Point GetObsPoi_i(int i);//返回第i个未知点
DiffH* GetDiffH(void);//返回高程差
DiffH GetDiffH_i(int i);//返回第i个高程差
bool CalH(Point* ObsPoi);//遍历高程差,并计算所求未知点的高程,能计算出返回真,计算不出返回假
void CalOBsPOi(void);//求未知点高程
void InOutData(CString& strData, CString& strResult);//从界面输入并输出数据
};
3.2.3 cpp文件(代码展示)
下面展示类的cpp文件的代码(部分)
#include "pch.h"
#include "LevNet.h"
#include "Cppplus.h"
//构造函数
LevNet::LevNet(void){}
//重载构造函数
LevNet::LevNet(int GivPoiCount_, Point* GivPoi_, int ObsPoiCount_, Point* ObsPoi_, int DiffHCount_, DiffH* ObsDiffH_)
{
//初始化已知点
GivPoiCount = GivPoiCount_;
GivPoi = new Point[GivPoiCount];
for (int i = 0; i < GivPoiCount; i++)
{
GivPoi[i] = GivPoi_[i];
}
//初始化未知点
ObsPoiCount = ObsPoiCount_;
ObsPoi = new Point[ObsPoiCount];
for (int i = 0; i < ObsPoiCount; i++)
{
ObsPoi[i] = ObsPoi_[i];
}
//初始化高程差
DiffHCount = DiffHCount_;
ObsDiffH = new DiffH[DiffHCount];
for (int i = 0; i < DiffHCount; i++)
{
ObsDiffH[i] = ObsDiffH_[i];
}
}
//析构函数
LevNet::~LevNet(void)
{
if (GivPoi)
{
delete[] GivPoi;
GivPoi = NULL;
}
if (ObsPoi)
{
delete[] ObsPoi;
ObsPoi = NULL;
}
if (ObsDiffH)
{
delete[] ObsDiffH;
ObsDiffH = NULL;
}
}
//拷贝构造函数
LevNet::LevNet(LevNet& A)
{
//拷贝已知点
GivPoiCount = A.GivPoiCount;
GivPoi = new Point[GivPoiCount];
for (int i = 0; i < GivPoiCount; i++)
{
GivPoi[i] = A.GivPoi[i];
}
//拷贝未知点
ObsPoiCount = A.ObsPoiCount;
ObsPoi = new Point[ObsPoiCount];
for (int i = 0; i < ObsPoiCount; i++)
{
ObsPoi[i] = A.ObsPoi[i];
}
//拷贝高程差
DiffHCount = A.DiffHCount;
ObsDiffH = new DiffH[DiffHCount];
for (int i = 0; i < DiffHCount; i++)
{
ObsDiffH[i] = A.ObsDiffH[i];
}
}
//为已知点赋值
void LevNet::SetGivPoi(int GivPoiCount_, Point* GivPoi_)
{
GivPoiCount = GivPoiCount_;
GivPoi = new Point[GivPoiCount];
for (int i = 0; i < GivPoiCount; i++)
{
GivPoi[i] = GivPoi_[i];
}
}
//为未知点赋值
void LevNet::SetObsPoi(int ObsPoiCount_, Point* ObsPoi_)
{
ObsPoiCount = ObsPoiCount_;
ObsPoi = new Point[ObsPoiCount];
for (int i = 0; i < ObsPoiCount; i++)
{
ObsPoi[i] = ObsPoi_[i];
}
}
//为高程差赋值
void LevNet::SetDiffH(int DiffHCount_, DiffH* ObsDiffH_)
{
DiffHCount = DiffHCount_;
ObsDiffH = new DiffH[DiffHCount];
for (int i = 0; i < DiffHCount; i++)
{
ObsDiffH[i] = ObsDiffH_[i];
}
}
//返回已知点
Point* LevNet::GetGivPoi(void)
{
return GivPoi;
}
//返回第i个已知点
Point LevNet::GetGivPoi_i(int i)
{
return GivPoi[i - 1];
}
//返回未知点
Point* LevNet::GetObsPoi(void)
{
return ObsPoi;
}
//返回第i个未知点
Point LevNet::GetObsPoi_i(int i)
{
return ObsPoi[i - 1];
}
//返回高程差
DiffH* LevNet::GetDiffH(void)
{
return ObsDiffH;
}
//返回第i个高程差
DiffH LevNet::GetDiffH_i(int i)
{
return ObsDiffH[i - 1];
}
//遍历高程差,并计算所求未知点的高程,能计算出返回真,计算不出返回假
bool LevNet::CalH(Point* ObsPoi)
{
int i;
for (i = 0; i < DiffHCount; i++)
{
if (strCompare(ObsDiffH[i].Start->name, ObsPoi->name) && ObsDiffH[i].End->state == TRUE)//如果所求点是高程差的起点并且终点的高程已求出
{
ObsPoi->dHigh = ObsDiffH[i].End->dHigh - ObsDiffH[i].dDiffH;
ObsPoi->state = TRUE;
return TRUE;
}
else if (ObsDiffH[i].Start->state == TRUE && strCompare(ObsDiffH[i].End->name, ObsPoi->name))//如果所求点是高程差的终点并且起点的高程已求出
{
ObsPoi->dHigh = ObsDiffH[i].Start->dHigh + ObsDiffH[i].dDiffH;
ObsPoi->state = TRUE;
return TRUE;
}
}
if (i == DiffHCount)//如果所求点的高程无法求出
{
return FALSE;
}
}
//求未知点高程
void LevNet::CalOBsPOi(void)
{
int go;//所有未知点的高程是否全部求出的标志
do
{
go = 1;
for (int i = 0; i < ObsPoiCount; i++)
{
if (ObsPoi[i].state == FALSE)//如果所求点的高程没有求出
{
if (!CalH(&ObsPoi[i]))
{
go = 0;
}//如果所求点的高程值没有求出的话,标记未知点的高程没有全部求出
}
}
} while (go == 0);
}
//从界面输入并输出数据
void LevNet::InOutData(CString& strData, CString& strResult)
{
strData.Trim();//去掉数据中的开头和结尾的换行符
int iLine;
//分行并存入字符串数组
CStringArray aStrLine;
iLine = SplitStringArray(strData, 13, aStrLine);//13 ‘\r’
int n;
CStringArray aStrTmp;
//获得已知点
n = SplitStringArray(aStrLine[0], ',', aStrTmp);
int GivPoiCount_ = _ttoi(aStrTmp[0]);
Point* GivPoi_ = new Point[GivPoiCount_];
for (int i = 1; i <= GivPoiCount_; i++)
{
n = SplitStringArray(aStrLine[i], ',', aStrTmp);
GivPoi_[i - 1].name = aStrTmp[0];
GivPoi_[i - 1].dHigh = _tstof(aStrTmp[1]);
GivPoi_[i - 1].state = TRUE;
}
//获得未知点
n = SplitStringArray(aStrLine[long(GivPoiCount_ + 1)], ',', aStrTmp);
int ObsPoiCount_ = _ttoi(aStrTmp[0]);
Point* ObsPoi_ = new Point[ObsPoiCount_];
n = SplitStringArray(aStrLine[long(GivPoiCount_ + 2)], ',', aStrTmp);
for (int i = 0; i < ObsPoiCount_; i++)
{
ObsPoi_[i].name = aStrTmp[i];
ObsPoi_[i].state = FALSE;
}
//获得高程差
n = SplitStringArray(aStrLine[long(GivPoiCount_ + 3)], ',', aStrTmp);
int DiffHCount_ = _ttoi(aStrTmp[0]);
DiffH* ObsDiffH_ = new DiffH[DiffHCount_];
for (int i = GivPoiCount_ + 4; i < DiffHCount_ + GivPoiCount_ + 4; i++)
{
n = SplitStringArray(aStrLine[i], ',', aStrTmp);
//遍历已知点,寻找和高程差中起点或终点相同的点
for (int t = 0; t < GivPoiCount_; t++)
{
if (strCompare(GivPoi_[t].name, aStrTmp[0]))
{
ObsDiffH_[i - GivPoiCount_ - 4].Start = &GivPoi_[t];
}
if (strCompare(GivPoi_[t].name, aStrTmp[1]))
{
ObsDiffH_[i - GivPoiCount_ - 4].End = &GivPoi_[t];
}
}
//遍历未知点,寻找和高程差中起点或终点相同的点
for (int k = 0; k < ObsPoiCount_; k++)
{
if (strCompare(ObsPoi_[k].name, aStrTmp[0]))
{
ObsDiffH_[i - GivPoiCount_ - 4].Start = &ObsPoi_[k];
}
if (strCompare(ObsPoi_[k].name, aStrTmp[1]))
{
ObsDiffH_[i - GivPoiCount_ - 4].End = &ObsPoi_[k];
}
}
//获得高程差和路线长度
ObsDiffH_[i - GivPoiCount_ - 4].dDiffH = _tstof(aStrTmp[2]);
ObsDiffH_[i - GivPoiCount_ - 4].dLen = _tstof(aStrTmp[3]);
}
//调用赋值函数把得到的已知点、未知点和高程差存入LevNet类中
SetGivPoi(GivPoiCount_, GivPoi_);
SetObsPoi(ObsPoiCount_, ObsPoi_);
SetDiffH(DiffHCount_, ObsDiffH_);
//调用未知点高程求解函数
CalOBsPOi();
//调用未知点返回函数
Point* p = GetObsPoi();
for (int i = 0; i < ObsPoiCount_; i++)
{
ObsPoi_[i] = p[i];
}
//格式化输出
strResult.Format(_T("%s\r\n"),
_T("未知点高程:"));
CString strOutput;
for (int i = 0; i < ObsPoiCount_; i++)
{
strOutput.Format(_T("%s%.3f\r\n"),
_T(":"), ObsPoi_[i].dHigh);
strResult = strResult + ObsPoi_[i].name + strOutput;
}
//释放空间
if (GivPoi_)
{
delete[] GivPoi_;
GivPoi_ = NULL;
}
if (ObsPoi_)
{
delete[] ObsPoi_;
ObsPoi_ = NULL;
}
if (ObsDiffH_)
{
delete[] ObsDiffH_;
ObsDiffH_ = NULL;
}
}
3.3 界面设计
1、界面设计思路:两个编辑框均添加CString变量,输入框的变量名为strData,输出框的变量名为strResult。
2、界面设计展示:
3.4 “计算”按钮对应的映射函数
1、设计思路:首先利用建立的水准网类类型声明一个变量LNEet。然后利用分割函数把输入的数据分行存入一个CStringArray数组中。接着再次利用分割函数获得已知点的数据、未知点的数据和高程差的数据。然后把获得的数据存入类LNet中。接着调用类的未知点高程计算函数计算出未知点的高程。然后利用未知点返回函数得到已计算出高程的未知点。接着格式化输出。最后释放空间。
2、下面展示“计算”按钮对应的映射函数的代码(部分)
//“计算”按钮的映射函数
void CCHtest6Dlg::OnBnClickedCal()
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(true);
LevNet LNet;
LNet.InOutData(strData, strResult);
UpdateData(false);
}
3.5 其他代码
下面展示本实验中所用到的其他函数的代码(部分):
// 分割字符串,得到字符串数组(CStringArray )
int SplitStringArray(CString str, char split, CStringArray& aStr)
{
int startIdx = 0;
int idx = str.Find(split, startIdx);
aStr.RemoveAll();//先清空
while (-1 != idx)
{
CString sTmp = str.Mid(startIdx, idx - startIdx);
aStr.Add(sTmp);
startIdx = idx + 1;
idx = str.Find(split, startIdx);
}
CString sTmp = str.Right(str.GetLength() - startIdx);
if (!sTmp.IsEmpty())
aStr.Add(sTmp);
return aStr.GetSize();
}
//比较两个字符串是否相等,相等返回真,不相等返回假
bool strCompare(CString a, CString b)
{
a.Remove('\r');
b.Remove('\r');
a.Remove('\n');
b.Remove('\n');
a.Remove(' ');
b.Remove(' ');
if (!a.Compare(b))
{
return TRUE;
}
else
return FALSE;
}
3.6 结果展示
四、心得总结
本实验对类的设计以及指针的运用的要求比较高,程序稍复杂,对逻辑思维的要求也较高。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)