测绘程序设计基础 实验7 CSU

实验7 常用测量程序设计

(工具:VS2010)

一、 实验目的

• 巩固类的创建与使用
• 掌握数组参数的传递
• 掌握常用测绘程序设计的被巧

二、实验内容与要求

设计一个无定向导线简易计算的程序,
要求自己定义文件格式,把下图中数据编写至文件中,然后通过读取文件
的形式获取所有数据,计算结果也写入结果文件中
在这里插入图片描述
无定向导线基本步骤:
在这里插入图片描述

三、设计与实现:

3.1 设计思路:

在这里插入图片描述

3.2 界面设计及属性:

在这里插入图片描述

3.3主要代码:

3.3.1文件:<Angle.h>  
#pragma once
enum AngleStyle
{
	DEG,
	DMS,
	RAD
};
class Angle
{
public:
	Angle(double value=0,AngleStyle style=DMS);
	~Angle(void);
	private:
		double dValue;//角度值
		AngleStyle  nCurStyle;//当前角度值类型
private:
	//设置常成员函数的作用:1.类成员不会被改变
	//2.可以被常类变量调用
	double Deg(double dDms) const;
	double Dms(double dDeg) const;
	
public:
	//获取指定的类型获取角度值,
    //由于返回的是dValue的引用,所以该值大小可以改变,即可以进行赋值
	double& operator() (AngleStyle style);

	//重载,获取指定的类型获取角度值,该值不可改变,const CAngle类型变量调用
	double operator() (AngleStyle style) const;
	//重载运算符+/-
    friend Angle operator + (const Angle& m1,const Angle& m2);
	friend Angle operator - (const Angle& m1,const Angle& m2);
};


3.3.2文件:< Angle.cpp>  
#include "StdAfx.h"
#include "Angle.h"
#include "math.h"
const double EPSILON=1.0E-12;
const double PI=4.0*atan(1.0);

//重载构造函数,有缺省值
Angle::Angle(double value,AngleStyle style)
{
	dValue=value;
	nCurStyle=style;
}

Angle::~Angle(void)
{
}
//重载()函数
double& Angle::operator() (AngleStyle style) //指定的类型获取角度值
{
	//double dAngleValue;
    if(style==DMS)
	{
		if(nCurStyle==DEG)
		{
            dValue=Dms(dValue);
		}
		else if(nCurStyle==RAD)
		{
			dValue=Dms(dValue*180.0/PI);
		}
		nCurStyle=DMS;
        		
	}
	else if(style==DEG)
	{
	    if(nCurStyle==DMS)
		{
            dValue=Deg(dValue);
		}
		else if(nCurStyle==RAD)
		{
			dValue=dValue*180.0/PI;
		}
       nCurStyle=DEG;
	}
	else
	{
       if(nCurStyle==DMS)
		{
            dValue=Deg(dValue)*PI/180;
		}
		else if(nCurStyle==DEG)
		{
			dValue=dValue*PI/180;
		}
        nCurStyle=RAD;
	}
	return dValue;
}
//重载()函数,该函数是常函数,只能被常CAngle对象使用
double Angle::operator() (AngleStyle style) const //指定的类型获取角度值
{
	double dAngleValue;
    if(style==DMS)
	{
		if(nCurStyle==DEG)
		{
            dAngleValue=Dms(dValue);
		}
		else if(nCurStyle==RAD)
		{
			dAngleValue=Dms(dValue*180.0/PI);
		}
		else
		{
			dAngleValue=dValue;
		}
        		
	}
	else if(style==DEG)
	{
	    if(nCurStyle==DMS)
		{
            dAngleValue=Deg(dValue);
		}
		else if(nCurStyle==RAD)
		{
			dAngleValue=dValue*180.0/PI;
		}
       else
		{
			dAngleValue=dValue;
		}
	}
	else
	{
       if(nCurStyle==DMS)
		{
            dAngleValue=Deg(dValue)*PI/180;
		}
		else if(nCurStyle==DEG)
		{
			dAngleValue=dValue*PI/180;
		}
        else
		{
			dAngleValue=dValue;
		}
	}
	return dAngleValue;
}


//私有成员,度分秒向十进制度转换
double Angle::Deg(double dDms) const
{
	int iDeg,iMin;
	double dSec;

	iDeg = int(dDms + EPSILON);//度//加一个很小的数,以防止取整时的出错
	iMin = int((dDms - iDeg) * 100+ EPSILON);//分
	dSec = ((dDms - iDeg) * 100 - iMin) * 100 ;//秒

	return iDeg + (double)iMin / 60 + dSec / 3600;
}

//私有成员,十进制度向度分秒转换
double Angle::Dms(double dDeg) const
{
	int iDeg,iMin;
	double dSec;
	double dTmp;

	iDeg = int(dDeg + EPSILON);//整数部分度
	dTmp = (dDeg - iDeg) * 60;//小数部分转换成分
	iMin = int(dTmp+ EPSILON);//取分的整数部分
	dSec = (dTmp - iMin) * 60;//截取秒

	return iDeg + (double)iMin / 100 + dSec / 10000;
}

//友元重载+函数
Angle operator + (const Angle& m1,const Angle& m2)
{
       Angle addAngle(0,RAD);
	   addAngle(RAD)=m1(RAD)+m2(RAD);
	   return addAngle;
}
//友元重载-函数
Angle operator - (const Angle& m1,const Angle& m2)
{
       Angle subAngle(0,RAD);
	   subAngle(RAD)=m1(RAD)-m2(RAD);
	   return subAngle;
}

3.3.3文件:<CData.h>  
/***************************************************************************
*  文件名:<Data.h>                                                         *
*                                                                          *
*  描述:用来储存数据    使用了角度辅助类:Angle                            *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月5日        创建              ***                      *
*                                                                          *
*  外部过程:                                                              *
*                                                                          *
/**************************************************************************/

#pragma once
#include"Angle.h"
class CData
{
public:
	CData(void);
	~CData(void);
	//未修正------------------------------------------未修正
	Angle p;//储存角度
          double s;//边长
	Angle _a;//储存方位角
	double _dx;//储存坐标X增量
	double _dy;//储存坐标Y增量
	double _X;//储存未修正原始X
	double _Y;//储存未修正原始Y

	//修正------------------------------------------修正
	Angle a;//储存改正后方位角
	double X;//储存修正后X
	double Y;//储存修正后Y
	//------------------------------------------数据仅仅储存至开头元素 即P[0]中
	Angle Sum_a;//总方位角
	Angle _Sum_a;//假定总方位角
	Angle alfa;// 总方位角-假定总方位角

	double S;//总长度
	double _S;//观测值总长度
	double k;//  总长度/观测值总长度
	int iSum;
};


3.3.4文件:<CData.cpp>  
#include "StdAfx.h"
#include "Data.h"


CData::CData(void)
{
}


CData::~CData(void)
{
}

3.3.5文件:<CSupport.h>  
/***************************************************************************
*  文件名:<CSupport.h>                                                     *
*                                                                          *
*  描述:操纵主要函数     使用了类CData                                     *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月5日        创建              ***                        *
*                                                                          *
*  外部过程:                                                              *
*                                                                          *
/**************************************************************************/
#pragma once
#include"Data.h"
#include <locale.h>
#include"math.h"
class CSupport
{
public:
	CSupport(void);
	~CSupport(void);
	void main();//主要函数
CString * SplitString(CString str, char split, int& iSubStrs);//字符串分割函数
private:
	double Process_Rad(double dx1,double dy1,double dx2,double dy2);//角度转换
	double length(double x1,double y1,double x2,double y2);//求距离
	void read();//读取函数
	void Pocess();//过程函数
	void Out();//输出函数
private:
	CData *P;
};

3.3.6文件:<CSupport.cpp>  
#include "StdAfx.h"
#include "Support.h"
#define PI 4.0*atan(1.0)

CSupport::CSupport(void)
{
}


CSupport::~CSupport(void)
{
	delete [] P;
}


/***************************************************************************
*  名字:CString * CSupport::SplitString(CString str, char split, int& iSubStrs)*
*                                                                          *
*  描述:字符串分割函数2                                                   *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月5日       引用该函数          ***                      *
*  参数: 1.CString str                                                    *
*         2.char split                                                     *
*         3.int& iSubStrs                                                  *
*  返回值:返回指针   指针带有动态数组的内容                               *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
CString * CSupport::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;
}


/***************************************************************************
*  名字:double Process_Rad(double dx1,double dy1,double dx2,double dy2)   *
*                                                                          *
*  描述:4个坐标值--》弧度式方位角                                         *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年3月8日       创建该函数          ***                       *
*      2019年5月5日       引用该函数          ***                       *
*                                                                          *
*  参数: 1.double dx1                                                     *
*         2.double dy1                                                     *
*		 3.double dx2                                                      * 
*		 4.double dy2                                                      * 
*                                                                          *
*  返回值:double类型数据   转换后的rad型方位角                            *
*                                                                          *
*  注:该函数在输入两坐标值相同时,会有一对话框弹出,且此时返回值为0       *
/**************************************************************************/
double CSupport::Process_Rad(double dx1,double dy1,double dx2,double dy2)
{
	double dx=dx2-dx1;
	double dy=dy2-dy1;
	double dRad;
	if(dy>0){
		if(dx<0){
			dRad=atan(dy/dx)+PI;//第二象限
		}
		else if(dx>0){
			dRad=atan(dy/dx);//第一象限
		}
		else{
			dRad=PI/2;//位于Y轴正方向
		}
	}
	else if(dy<0){
		if(dx<0){
			dRad=atan(dy/dx)+PI;//第三象限
		}
		else if(dx>0){
			dRad=atan(dy/dx)+2*PI;//第四象限
		}
		else{
			dRad=PI*3/2;//位于Y轴负方向
		}
	}
	else{
		if(dx>0){
			dRad=0;//位于X正半轴
		}
		else if(dx<0){
			dRad=PI;//位于X负半轴
		}
		else{
			AfxMessageBox(_T("您不能输入相同的坐标。"));//(x1,y1)==(x2,y2)的情况  
			return 0;
		}
	}
	return dRad;
}


/***************************************************************************
*  名字:double length(double x1,double y1,double x2,double y2)            *
*                                                                          *
*  描述:由(x1,y1)和(x2,y2)计算两点之间距离 长度                         *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年3月20日       创建该函数          ***                    *
*      2019年5月5日        引用该函数          ***                    *
*  参数: 1.double x1                                                      *
*         2.double y1                                                      *
*         3.double x2                                                      *
*         4.double y2                                                      *
*  返回值:double类型数据 返回距离                                         *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
double CSupport::length(double x1,double y1,double x2,double y2)
{
	double tmp=((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
	return sqrt(tmp);
}

/***************************************************************************
*  名字:void CSupport::read()                                             *
*                                                                          *
*  描述:读取函数        调用函数SplitString 开辟动态数组P                *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月5日        创建该函数          ***                   *
*  参数: 1.                                                               *
*  返回值:无                                                              *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
void CSupport::read()
{
	CFileDialog dlgFile(TRUE,_T("txt"),NULL,
	OFN_ALLOWMULTISELECT|OFN_EXPLORER,
	//_T("(文本文件)|*.txt"));
	_T(""));
	if(dlgFile.DoModal()==IDCANCEL) return ;
	CString strName=dlgFile.GetPathName();//获取打开文件文件名(路径)
	setlocale(LC_ALL,"");
	CStdioFile sf;
	if(! sf.Open(strName,CFile::modeRead)) return ;
	CString strLine;
	CString strContent;//接受内容字符串
	strContent.Empty();
	BOOL bEOF =sf.ReadString (strLine);
	bEOF =sf.ReadString (strLine);//运行两次
	if(!bEOF)
	{
		AfxMessageBox(_T("数据有误,请检查数据文件!"));
		return ;
	}
	int iPointCount;
	iPointCount=_ttoi(strLine);//读取点数
	P=new CData [iPointCount+1];//创建动态数组
	P[0].iSum=iPointCount;
	int i1=0;
	int i2=0;
	int i3=0;
	int n=0;//为下文读取做铺垫
	int counter=0;
	
	while (counter<2*P[0].iSum+1)
	{
		bEOF=sf.ReadString(strLine);
		CString *pstrData =SplitString(strLine,',',n);
		//if(pstrData==NULL) continue;
		if(counter<P[0].iSum)
		{
			P[i1].s = _tstof(pstrData[2]);
			i1++;
		}
		else if(counter<(2*P[0].iSum-1))
		{
			P[i2].p=Angle(_tstof(strLine),DMS);
			i2++;
		}
		else
		{
			if(i3==0)
			{
			P[0].X = _tstof(pstrData[0]);
			P[0].Y = _tstof(pstrData[1]);
			}
			if(i3!=0)
			{
				i3=P[0].iSum;
				P[i3].X = _tstof(pstrData[0]);
				P[i3].Y = _tstof(pstrData[1]);
				
			}
			i3++;
		}
		counter++;
	}
	sf.Close();
	//AfxMessageBox(_T("成功读取数据!"));
}

/***************************************************************************
*  名字:void CSupport::Pocess()                                           *
*                                                                          *
*  描述:过程函数 调用函数length()、Process_Rad()函数  加工数组P中元素   *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月5日        创建该函数          ***                    *
*  参数:                                                                  *
*  返回值:无                                                              *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
void CSupport::Pocess()
{
	//----------------------------------------------------------------------未修正----------------------------------------------------------------------
	//计算方位角
	P[0]._a=Angle(87.0053,DMS);
	for(int i=1;i<P[0].iSum;i++)
	{                                                                                                                                                                                                                                                
		P[i]._a=Angle(P[i-1]._a(DEG)+P[i-1].p(DEG)-180,DEG);
	}
	//计算坐标增量
	for(int i=0;i<P[0].iSum;i++)
	{
		P[i]._dx=P[i].s*cos(P[i]._a(RAD));
		P[i]._dy=P[i].s*sin(P[i]._a(RAD));
	}
	//计算假定坐标
	P[0]._X=0;
	P[0]._Y=0;
	for(int i=1;i<P[0].iSum+1;i++)
	{
		P[i]._X=P[i-1]._X+P[i-1]._dx;
		P[i]._Y=P[i-1]._Y+P[i-1]._dy;
	}
	//---------------------------------------------------------------------修正过程----------------------------------------------------------------------
	//计算角度偏移状况
	
	P[0]._Sum_a=Angle(Process_Rad(P[0]._X,P[0]._Y,P[P[0].iSum]._X,P[P[0].iSum]._Y),RAD);
	P[0].Sum_a=Angle(Process_Rad(P[0].X,P[0].Y,P[P[0].iSum].X,P[P[0].iSum].Y),RAD);
	P[0].alfa=Angle(P[0].Sum_a(DEG)-P[0]._Sum_a(DEG),DEG);
	//长度缩放状况
	P[0]._S=length(P[0]._X,P[0]._Y,P[P[0].iSum]._X,P[P[0].iSum]._Y);
	P[0].S=length(P[0].X,P[0].Y,P[P[0].iSum].X,P[P[0].iSum].Y);
	P[0].k=P[0].S/P[0]._S;

	for(int i=0;i<P[0].iSum;i++)
	{
		P[i].a=Angle(P[i]._a(DMS)+P[0].alfa(DMS),DMS);
	}
	for(int i=0;i<P[0].iSum+1;i++)
	{
		P[i].X=P[0].X+P[0].k*(P[i]._X*cos(P[0].alfa(RAD))-P[i]._Y*sin(P[0].alfa(RAD)));
		P[i].Y=P[0].Y+P[0].k*(P[i]._X*sin(P[0].alfa(RAD))+P[i]._Y*cos(P[0].alfa(RAD)));
	}
}

/***************************************************************************
*  名字:void CSupport::Out()                                              *
*                                                                          *
*  描述:输出函数  将P中元素输出                                           *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月5日        创建该函数          ***                      *
*  参数:                                                                  *
*  返回值:无                                                              *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
void CSupport::Out()
{
	CStdioFile SF;
	CString Result;
	CString strOut;
	setlocale(LC_ALL,""); 
	if(!SF.Open(_T("Result.txt"), CFile::modeCreate|CFile::modeWrite)) return;

	Result.Format(_T("%s\r\n%s\r\n"),
			_T("----------------------------原始数据----------------------------"),
			_T("---------- 边长")
			);
	strOut+=Result;
	
	for(int i=0;i<P[0].iSum;i++)
	{
		Result.Format(_T("%.4f\r\n"),
		P[i].s
		);
		strOut+=Result;
	}

	Result.Format(_T("%s\r\n"),
			_T("---------- 角度")
			);
	strOut+=Result;
	
	for(int i=0;i<P[0].iSum-1;i++)
	{
		Result.Format(_T("%f\r\n"),
		P[i].p(DMS)
		);
		strOut+=Result;
	}

	Result.Format(_T("%s\r\n"),
			_T("---------- 假定方位角,坐标增量dx,dy")
			);
	strOut+=Result;

	for(int i=0;i<P[0].iSum;i++)
	{
		Result.Format(_T("%f,%f,%f\r\n"),
		P[i]._a(DMS),P[i]._dx,P[i]._dy
		);
		strOut+=Result;
	}

	Result.Format(_T("%s\r\n"),
			_T("---------- 假定坐标")
			);
	strOut+=Result;

	for(int i=0;i<P[0].iSum+1;i++)
	{
		Result.Format(_T("%f,%f\r\n"),
		P[i]._X,P[i]._Y
		);
		strOut+=Result;
	}

	Result.Format(_T("%s\r\n%s%f\r\n%s%f\r\n%s%f\r\n"),
		    _T("----------------------------修正过程----------------------------"),
		    _T("---------- 导线总假设方位角 "),P[0]._Sum_a(DMS),
			_T("---------- 导线总真方位角 "),P[0].Sum_a(DMS),
			_T("---------- 角度闭合差 "),P[0].alfa(DMS)
			);
	strOut+=Result;
	
   Result.Format(_T("%s%f\r\n%s%f\r\n%s%f\r\n"),
		    _T("----------  导线总长"),P[0].S,
			_T("---------- 观测值总长度"),P[0]._S,
			_T("---------- 闭合边长度比:导线总长/观测值总长度 "),P[0].k
			);
	strOut+=Result;
	Result.Format(_T("%s\r\n"),
			_T("---------- 修正后方位角")
			);
	strOut+=Result;

	for(int i=0;i<P[0].iSum;i++)
	{
		Result.Format(_T("%f\r\n"),
		P[i].a
		);
		strOut+=Result;
	}


	Result.Format(_T("%s\r\n"),
			_T("---------- 修正后坐标")
			);
	strOut+=Result;

	for(int i=0;i<P[0].iSum+1;i++)
	{
		Result.Format(_T("%f,%f\r\n"),
		P[i].X,P[i].Y
		);
		strOut+=Result;
	}
	SF.WriteString(strOut);
	SF.Close();
	AfxMessageBox(_T("成功!已输入至“Result.txt”中"));
}


/***************************************************************************
*  名字:void CSupport::main()                                             *
*                                                                          *
*  描述:main函数  调用函数read()、Pocess()、Out()函数                     *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月5日        创建该函数          ***                      *
*  参数:                                                                  *
*  返回值:无                                                              *
*                                                                          *
*  注:                                                                    *
/**************************************************************************/
void CSupport::main()
{
	CSupport temp;
	temp.read();
	temp.Pocess();
	temp.Out();
}


	
3.3.7文件: < RS_110_zhangruixiang_SY7Dlg.cpp >  (只摘取部分)
/***************************************************************************
*  文件名:<RS_110_zhangruixiang_SY7Dlg.cpp>                                *
*                                                                          *
*  描述:对话框                                                             *
*                                                                          *
*  历史:**日期**         **理由**            **签名**                     *
*      2019年5月5日        创建              ***                      *
*                                                                          *
*  外部过程:                                                              *
*                                                                          *
/**************************************************************************/



void CRS_110_zhangruixiang_SY7Dlg::OnBnClickedOk()
{
	// TODO: 在此添加控件通知处理程序代码
	//CDialogEx::OnOK();
	CSupport k;
	k.main();
}


3.4运行结果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.5设计技巧:

 创建多个类,层次分明。
 调用角度Angle类,省了较多力气
 使用指针动态开辟数组,较为方便
 使用文件操作输入与输出

代码虽多,不要贪杯~

  • 3
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值