//
//Author			: walk.ly  
//Time			: 2009-05-08
//Version		: 1.0.0
//Description	: 水准测量平差习题 	
//

#ifndef __LEVEL_SURV_
#define __LEVEL_SURV_

#ifdef _VS_WALK
#include "wkClassDefine.h"
#endif

#include "单进双不进.cpp"


int dec=3;	//有效小数位

array ptNames;	//高程点点名
array pws;		//权=测站数
array obs;		//观测值
array vs;		//改正数
array Hs;		//高程值

double bgnH;	//起点高程值
double endH;	//终点高程值

double f, fa;	//闭合差和容差

bool CalHClose()
{
	f=Sum(obs)-(endH-bgnH);

	//容许误差
	fa=0.012*sqrt(Sum(pws));
	if (abs(f)>fa)
	{
		string msg;
		msg.format("闭合差=%lf, 容许误差=%lf\n误差超限!", f, fa);
		message(msg);
		return false;
	}
	return true;
}

bool AdjError()
{
	double powerSm=Sum(pws);
	for (int i=0; i<pws.getSize(); i++)
	{
		double p=pws[i];
		double v=-f*p/powerSm;
		vs.add(round5(v, dec));//（凑整到dec位）
	}

	//*** 处理凑整误差
	double fr=(Sum(vs)+f);
	AdjRoundError(pws, vs, fr, dec);

	//验证改正数
	double sumV=Sum(vs);
	if (abs(f+sumV)>1e-6)
	{
		string msg;
		msg.format("闭合差=%lf, 改正数和=%lf\n二者应绝对值相等!", f, fa);
		message(msg);
		return false;
	}
	return true;
}

bool CalH()
{
	Hs.add(bgnH);
	for (int i=0; i<vs.getSize(); i++)
	{
		double h=Hs[i], o=obs[i], v=vs[i];
		Hs.add(h+o+v);
	}

	//验证终点高程
	double H=Hs[i];
	if (abs(H-endH)>1e-6)
	{
		string msg;
		msg.format("终点%s: 计算H=%lf, 已知H=%lf\n二者值不相等!", ptNames[i], H, endH);
		message(msg);
		return false;
	}
	return true;
}

void Output()
{
	string fileName="c:\\levelRes.txt";
	wkFile fp;
	fp.open(fileName, "wt");

	string msg;
	msg="|=====================================================|\n"; fp.puts(msg);
	msg="|  点名  | 测站数 | 观测值 | 改正数 |  高差  |  高程  |\n"; fp.puts(msg);
	msg="|--------|--------|--------|--------|--------|--------|\n"; fp.puts(msg);
	int n=Hs.getSize();
	for (int i=0; i<n; i++)
	{
		string m="--------";
		msg.format("|%6s  |%s|%s|%s|%s|%8.3lf|\n", ptNames[i], m, m, m, m, Hs[i]);
		fp.puts(msg);
		if (i<n-1)
		{
			double o=obs[i], v=vs[i];
			msg.format("|%s|%6d  |%7.3lf |%7.0lf |%7.3lf |%s|\n",
						m, pws[i], o, v*1000.0, o+v, m);
		}else
		{
			msg="|--------|--------|--------|--------|--------|--------|\n"; fp.puts(msg);
			msg.format("|  合计  |%6.0lf  |%7.3lf |%7.0lf |%7.3lf |        |\n",
						Sum(pws), Sum(obs), Sum(vs)*1000.0, Sum(obs)+Sum(vs));
		}
		fp.puts(msg);
	}
	msg=       "|-----------------------------------------------------|\n"; fp.puts(msg);
	msg.format("|     闭合差 f  =%6.0lf mm                            |\n", f*1000.0); fp.puts(msg);
	msg.format("| 容许闭合差 f容=%6.0lf mm                            |\n", fa*1000.0); fp.puts(msg);
	msg=       "|            f<f容，观测成果满足规范要求，可以平差    |\n"; fp.puts(msg);
	msg=       "| 注：测段改正数 = -(测段站数 * 闭合差 / 总站数)      |\n"; fp.puts(msg);
	msg=       "|=====================================================|\n"; fp.puts(msg);
	fp.close();

	//使用记事本显示结果
	wkView view;
	view.shell("notepad "+fileName);
}

//【平差】
void Adjustment()
{
	//计算闭合差
	if (!CalHClose())
		return;

	//计算改正数
	if (!AdjError())
		return;

	//计算高程
	if (!CalH())
		return;

	//输出结果
	Output();
}

#endif //__LEVEL_SURV_
