起因是我的同学想在网上搜一份C++的导线平差代码,发现没有直接高效、可以用简单C++直接实现的代码,然后找到了一份古早代码,代码本身应该还是挺强大的,但是我没有细看,帮着调试了一波,将其升级到了现代版本,然后倒推了一下数据的组织格式,跑通后就扔给我同学了。在此开源给测绘牛马作为一个小小的参考。
都在同一份cpp里面(原始代码就这个样子,有裹脚布的嫌疑,但对小白友好),main函数在最后,可自己拆分。
#include
#include
#define MAX 100
#define PI 3.14159265358979312
#define rou (180.0*60*60/PI)
#include
#include
using namespace std;
int inverse(double C[][MAX], double B[][MAX], int n);
//define the function of inverseing;
//return 0 means mat can't be inversed or;
//return 1 means mat inversed correctly, and B is inversed mat;
void AXB(double A[][MAX], double B[][MAX], double C[][MAX], int m, int n, int k);
void AXB(double a, double A[][MAX], double aA[][MAX], int m, int n);
void AXB(double A[][MAX], double B[][1], double C[][1], int m, int n);
//define the time fuction of mats or mat and a number
void AT(double A[][MAX], double AH[][MAX], int m, int n);
void AT(double A[][1], double AH[][MAX], int m);
void AT(double A[][MAX], double AH[][1], int m);
//define the fuction to turn over a mat
void ATPA(double A[][MAX], double P[][MAX], double ATPA[][MAX], int m, int n);
void ATPL(double A[][MAX], double P[][MAX], double L[][1], double ATPL[][1], int m, int n);
double VPV(double V[][1], double P[][MAX], int m);
//define initial fuctions of doadj()
void matdis(double A[][MAX], int n, int m);
void matdis(double A[][1], int n);
//define two fuctions to output a mat to screen
struct adj;
void ksetadj(adj& a); //input data from keyboard
int fsetadj(adj& aa, char name[20]); //input data from a file
int doadj(adj& a); //adjusting a adj
int rubust(adj& a); //抗差估计
void adjdis(adj& aa); //output a adj results to screen
int foutadj(adj& aa, char name[20]); //outputdate to a file
//define adj and it related fuctions
//************************************************************************************************
void AXB(double A[][MAX], double B[][MAX], double C[][MAX], int m, int n, int k)
{
for (int i = 0; i < m; i++)
for (int j = 0; j < k; j++)
{
C[i][j] = 0;
for (int l = 0; l < n; l++)
C[i][j] += A[i][l] * B[l][j];
}
}
//************************************************************************************************
void AXB(double A[][MAX], double B[][1], double C[][1], int m, int n)
{
for (int i = 0; i < m; i++)
for (int j = 0; j < 1; j++)
{
C[i][j] = 0;
for (int l = 0; l < n; l++)
C[i][j] += A[i][l] * B[l][j];
}
}
//************************************************************************************************
void AXB(double a, double A[][MAX], double aA[][MAX], int m, int n) //void
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
aA[i][j] = a * A[i][j];
}
//************************************************************************************************
void AT(double A[][MAX], double AH[][MAX], int m, int n) // 矩阵转置
{
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
AH[j][i] = A[i][j];
}
//************************************************************************************************
void AT(double A[][1], double AH[][MAX], int m) // 列向量转置为行向量
{
for (int i = 0; i < m; i++)
AH[0][i] = A[i][0];
}
//************************************************************************************************
void AT(double A[][MAX], double AH[][1], int m) // 行向量转置为列向量
{
for (int i = 0; i < m; i++)
AH[i][0] = A[0][i];
}
//************************************************************************************************
void ATPA(double A[][MAX], double P[][MAX], double ATPA[][MAX], int m, int n)
{
double AH[MAX][MAX], ATP[MAX][MAX];
AT(A, AH, m, n);
AXB(AH, P, ATP, n, m, m);
AXB(ATP, A, ATPA, n, m, n);
}
//************************************************************************************************
double VPV(double V[][1], double P[][MAX], int m)
{
double VH[1][MAX], VTP[1][MAX];
for (int i = 0; i < m; i++)
VH[0][i] = V[i][0];
for (int i = 0; i < m; i++)
{
VTP[0][i] = 0;
for (int j = 0; j < m; j++)
VTP[0][i] += VH[0][j] * P[j][i];
}
double dd(0);
for (int i = 0; i < m; i++)
dd += VTP[0][i] * V[i][0];
return dd;
}
//************************************************************************************************
void ATPL(double A[][MAX], double P[][MAX], double L[][1], double ATPL[][1], int m, int n)
{
double AH[MAX][MAX], ATP[MAX][MAX];
AT(A, AH, m, n);
AXB(AH, P, ATP, n, m, m);
for (int i = 0; i < n; i++)
{
ATPL[i][0] = 0;
for (int j = 0; j < m; j++)
ATPL[i][0] += ATP[i][j] * L[j][0];
}
}
//************************************************************************************************
void matdis(double A[][MAX], int n, int m) // 显示矩阵
{//1.set B[][] I;
for (int i = 0; i < n; i++)
{
cout << " ";
for (int j = 0; j < m; j++)
cout << A[i][j] << " ";
cout << endl;
}
}
//************************************************************************************************
void matdis(double A[][1], int n) // 显示列向量
{//1.set B[][] I;
for (int i = 0; i < n; i++)
cout << " " << A[i][0] << endl;
}
//************************************************************************************************
int inverse(double C[][MAX], double B[][MAX], int n)
{//1.set B[][] I;
double A[MAX][MAX], e;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
A[i][j] = C[i][j];
if( i== j) B[i][j] = 1;
else B[i][j] = 0;
}
//2. inverse and judge the Matrix inversable
for (int i = 0; i < n; i++)
{
//对主元为零的处理
if (A[i][i] == 0)
for (int j = i + 1; j < n; j++)
{
if (A[j][i] != 0)
for (int k = 0; k < n; k++)
{
A[i][k] += A[j][k];
B[i][k] += B[j][k];
}
break;
}
if (fabs(A[i][i]) < 0.000000000000001)
{
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
B[i][j] = 0;
return 0;
}//MAT can't be inversed
// line processing
e = A[i][i];
for (int j = 0; j < n; j++)
{
A[i][j] = A[i][j] / e;
B[i][j] = B[i][j] / e;
}
// row processing
for (int j = 0; j < n; j++)
{
e = A[j][i];
for (int k = 0; k < n; k++)
if (i != j)
{
A[j][k] += -1 * e * A[i][k];
B[j][k] += -1 * e * B[i][k];
}
}
}
return 1;
}
//************************************************************************************************
double setf(double a, int t)
{
double b = fabs(a);
for (int i = 0; i < t; i++)
b *= 10;
if (b - floor(b) > 0.5) b = floor(b) + 1;
else b = floor(b);
for (int i = 0; i < t; i++)
b /= 10;
if (a < 0) b = -b;
return b;
}
//************************************************************************************************
struct adj {
// adjustment model :
// V=AX-L P
// A[m][n], P[m][m], L[m][1]
char name[40]; // V=AX-L P
int m; // the number of observations
int n; // the number of unknown data
double A[MAX][MAX]; // paremater mat of unknown data
double P[MAX][MAX]; // observation weight mat
double l[MAX][1]; // fix data mat
double X[MAX][1]; // unknown data mat
double QXX[MAX][MAX];// coherance date mat
double m0; // unit weight error
double V[MAX][1];
int flag; // flag=1 means adjustment successfully
};
//************************************************************************************************
void ksetadj(adj& a) //keyboard and screen input
{
cout << " input the object name: ";
cin >> a.name; cout << endl;
cout << " input observation number: ";
cin >> a.m; cout << endl;
cout << " input unknown data number: ";
cin >> a.n; cout << endl;
cout << " input data of mat A[" << a.m << "][" << a.n << "]" << endl;
for (int i = 0; i < a.m; i++)
for (int j = 0; j < a.n; j++)
cin >> a.A[i][j];
cout << " input data of mat P[" << a.m << "][" << a.m << "]" << endl;
for( int i= 0; i < a.m; i++)
for (int j = 0; j < a.m; j++)
cin >> a.P[i][j];
cout << " input data of mat L[" << a.m << "][1]" << endl;
for( int i= 0; i < a.m; i++)
cin >> a.l[i][0];
}
//************************************************************************************************
int fsetadj(adj& aa, const char* name) //keyboard and screen input
{
ifstream in(name);
if (!in) return 0;
// 输入平差项目名
in >> aa.name;
// input observation number:
in >> aa.m;
// input unknown data number:
in >> aa.n;
// input data of mat A[m][n]:
for (int i = 0; i < aa.m; i++)
for (int j = 0; j < aa.n; j++)
in >> aa.A[i][j];
// input data of mat P[m][m]:
for( int i= 0; i < aa.m; i++)
for (int j = 0; j < aa.m; j++)
in >> aa.P[i][j];
// input data of mat L[m][1]:
for( int i= 0; i < aa.m; i++)
in >> aa.l[i][0];
in.close();
return 1;
}
//*******************************************************************************************
int doadj(adj& a) // 普通最小二乘平差
{
double APA[MAX][MAX];
ATPA(a.A, a.P, APA, a.m, a.n);
int flag = inverse(APA, a.QXX, a.n);
if (flag != 1)
{
a.flag = 0;
return 0;
}
double AX[MAX][1];
ATPL(a.A, a.P, a.l, AX, a.m, a.n);
AXB(a.QXX, AX, a.X, a.n, a.n);
AXB(a.A, a.X, AX, a.m, a.n);
for (int i = 0; i < a.m; i++)
a.V[i][0] = AX[i][0] - a.l[i][0];
double cc = VPV(a.V, a.P, a.m);
a.m0 = sqrt(cc / (a.m - a.n));
a.flag = 1;
return 1;
}
//*******************************************************************************************
int doadj(adj& a, int known, int r) // 极大权法最小二乘平差,known--控制点已知数据个数;
{ // r-固定数据个数+测站数(平面网)
double APA[MAX][MAX];
ATPA(a.A, a.P, APA, a.m, a.n);
double add(0);
for (int i = 0; i < a.n; i++)
if (add <= APA[i][i]) add = APA[i][i];
add *= 1000;
for( int i= 0; i < known; i++) // 对已知点方法程系数阵的处理:
APA[i][i] += add; // 控制点点号对应矩阵主元加平均权的10000倍
int flag = inverse(APA, a.QXX, a.n);
if (flag != 1) // 不可求逆的判断及处理
{
a.flag = 0; return 0;
}
double AX[MAX][1]; // 极大权平差过程
ATPL(a.A, a.P, a.l, AX, a.m, a.n);
AXB(a.QXX, AX, a.X, a.n, a.n);
AXB(a.A, a.X, AX, a.m, a.n);
for( int i= 0; i < a.m; i++)
a.V[i][0] = AX[i][0] - a.l[i][0];
double cc = VPV(a.V, a.P, a.m); // VTPV计算
a.m0 = sqrt(cc / (a.m - a.n + known - r)); // 单位权中误差计算,必要观测数为(a.n-knownp)
a.flag = 1; // 平差完毕
return 1;
}
//*******************************************************************************************
void adjdis(adj& aa)
{
cout << " 平差项目名 :" << aa.name << endl << endl;
cout << " 误差方程阵:" << endl;
matdis(aa.A, aa.m, aa.n);
cout << endl << endl << " 观测值权矩阵:" << endl;
matdis(aa.P, aa.m, aa.m);
cout << endl << endl << " 常数项:" << endl;
matdis(aa.l, aa.m);
cout << endl << endl;
cout << endl << endl << " 未知数解:" << endl;
matdis(aa.X, aa.n);
cout << endl << endl << " 未知数协因数阵:" << endl;
matdis(aa.QXX, aa.n, aa.n);
cout << endl << endl << " 改正数:" << endl;
matdis(aa.V, aa.m);
cout << endl << endl << " 单位权中误差:+-" << aa.m0 << endl;
}
//************************************************************************************************
int foutadj(adj& aa, char* name)
{
ofstream on(name);
if (!on) return 0;
// 输出平差项目名
on << aa.name << endl << endl;
// output observation number:
on << aa.m << endl;
// output unknown data number:
on << aa.n << endl << endl;
//out unknown data results
for (int i = 0; i < aa.n; i++)
on << aa.X[i][0] << endl;
on << endl;
// 未知数协因数阵:"<
for (int i = 0; i < aa.n; i++)
{
for (int j = 0; j < aa.n; j++)
on << aa.QXX[i][j] << " ";
on << endl;
}
on << endl;
//output 改正数:;
for (int i = 0; i < aa.m; i++)
on << aa.V[i][0] << endl;
on << endl;
on << aa.m0 << endl;
on.close();
return 1;
}
//************************************************************************************************
int rubust(adj& a) // 定义抗差估计
{
// 1.最小二成平差
if (!doadj(a)) return 0;
double* xold, * xnew, small(0), P[MAX], n0(0);
xold = new double[a.n];
int num(0);
xnew = new double[a.n];
for (int i = 0; i < a.m; i++)
P[i] = a.P[i][i];
do {
small = 0;
for (int i = 0; i < a.n; i++) *(xold + i) = a.X[i][0];
// 2.等权处理
for( int i= 0; i < a.m; i++)
{
if (fabs(a.V[i][0]) > 2.5 * a.m0) { a.P[i][i] = 0; n0++; }
else if (fabs(a.V[i][0]) < 1.8 * a.m0 * sqrt(1 / a.P[i][i]));
else a.P[i][i] = a.P[i][i] / 1.8 / a.m0;
}
cout << "a.m0=" << a.m0 << endl;
matdis(a.P, a.m, a.m);
doadj(a);
for (int i = 0; i < a.n; i++)
{
*(xnew + i) = a.X[i][0] - *(xold + i);
if (small < fabs(*(xnew + i))) small = fabs(*(xnew + i));
}
num++;
} while (small > 0.0000000001);
if (n0) a.m0 *= sqrt((a.m - a.n) / (a.m - a.n - n0));
delete[] xold;
delete[] xnew;
return 1;
}
//************************************************************************************************
void matout(double A[][1], int n, ofstream &out) // 向文件输出矩阵
{
for (int i = 0; i < n; i++)
out << " " << A[i][0] << endl;
}
//************************************************************************************************
void matout(double A[][MAX], int n, int m, ofstream &out) // 向文件输出矩阵
{//1.set B[][] I;
for (int i = 0; i < n; i++)
{
out << " ";
for (int j = 0; j < m; j++)
out << A[i][j] << " ";
out << endl;
}
}
//**********************************************************************************
//**************** 高程网平差程序 ****************************************
struct Hpnt { // 高程点结构
char name[20];
double H;
double H0;
double mH;
int fixed; // known=1;else =0;
int i; // point number
};
struct line { // 水准线路结构
Hpnt* startp;
Hpnt* endp;
double length;
double h;
int style; // 水准测量=1;三角高程=2
};
struct Hnet { // 高程网结构
char netname[40]; // 网名
int allpnum; // 总点数
int fixpnum; // 控制点个数
int obnum; // 观测值个数
double m0; // 验前单位权中误差
Hpnt Pt[MAX]; // 高程点数组
line L[MAX]; // 水准线路数组
adj aa; // 平差结构
};
//************************************************************************************************
int finHnet(Hnet& a, char* fname) // 文件输入高程网函数
{
ifstream in(fname); // 建立文件流,并与输入文件名建立关联
if (!in) { cout << fname << " error: file does not exist! " << endl; return 0; }
// 文件现实性判断
char name[20];
in >> a.netname;
cout << a.netname << endl;
in >> a.obnum;
cout << a.obnum<< endl;
in >> a.allpnum;
cout << a.allpnum << endl;
in >> a.fixpnum;
cout << a.fixpnum << endl;
in >> a.m0;
cout << a.m0 << endl;
int n(a.fixpnum); // n为已输入名字的点的个数
// 输入控制点信息
for (int i = 0; i < a.fixpnum; i++)
{
in >> a.Pt[i].name >> a.Pt[i].H;
a.Pt[i].fixed = 1; // 控制点标记
a.Pt[i].H0 = a.Pt[i].H;
a.Pt[i].mH = 0;
a.Pt[i].i = i; // 控制点编号,从0到a.fixpnum-1
}
for( int i= a.fixpnum; i < a.allpnum; i++) // 输入未知点相关信息(名字在后面输入)
{
a.Pt[i].fixed = 0; // 未知点标记
a.Pt[i].H = 0; a.Pt[i].H0 = -PI;
a.Pt[i].mH = 0;
*(a.Pt[i].name) = 0;
a.Pt[i].i = i; // 为未知点编号,从a.fixpnum到a.allpnum-1
}
// 输入观测值
for( int i= 0; i < a.obnum; i++)
{
int t = 0; // 点名比较标志
in >> name; // 输入起点名
for (int k = 0; k < n; k++)
if (_strnicmp(name, a.Pt[k].name, 20) == 0)
{
a.L[i].startp = &(a.Pt[k]); // 找到同名点,起点指针指向该点
t++; // 找到标志
}
if (t == 0) {
strcpy_s(a.Pt[n].name, name);
a.L[i].startp = &(a.Pt[n]); // 找不到同名点,该名输给新点
n++;
}
in >> name; t = 0; // 输入终点名,操作过程同上
for (int k = 0; k < n; k++)
if (_strnicmp(name, a.Pt[k].name, 20) == 0)
{
a.L[i].endp = &(a.Pt[k]);
t++;
}
if (t == 0) {
strcpy_s(a.Pt[n].name, name);
a.L[i].endp = &(a.Pt[n]);
n++;
}
in >> a.L[i].h; // 输入线路高差
in >> a.L[i].length; // 输入线路长度
}
if (n != a.allpnum) {
cout << fname << " error: file provide not correct point number ! " << endl;
return 0;
}
// 文件正确性判断
in.close(); // 关闭输入流及关联文件
// 向屏幕输出原始平差文件
cout << " 平差文件 " << fname << " 数据输入结果:" << endl;
cout << " " << a.netname << " " << a.obnum << " " << a.allpnum << " "
<< a.fixpnum << " " << a.m0 << endl << endl;
for( int i= 0; i < a.fixpnum; i++) // 控制点数据
cout << " " << a.Pt[i].name << " " << a.Pt[i].H << endl;
cout << endl;
for( int i= 0; i < a.obnum; i++) // 水准线路数据
cout << " " << a.L[i].startp->name << " " << a.L[i].endp->name << " " << a.L[i].h
<< " " << a.L[i].length << endl;
//*********************** 平差数据准备 ***************************
// 近似高程计算
do {
n = 0; // 近似高程标志,=1表示仍有点近似高程未知
for( int i= 0; i < a.obnum; i++)
if (a.L[i].startp->H0 == -PI || a.L[i].endp->H0 == -PI) { n = 1; break; }
for( int i= 0; i < a.obnum; i++) // 由水准线路计算近似高程
{
if (a.L[i].startp->H0 != -PI && a.L[i].endp->H0 == -PI)
a.L[i].endp->H0 = a.L[i].startp->H0 + a.L[i].h;
if (a.L[i].startp->H0 == -PI && a.L[i].endp->H0 != -PI)
a.L[i].startp->H0 = a.L[i].endp->H0 - a.L[i].h;
}
} while (n == 1);
// 极大权法平差数据
a.aa.m = a.obnum; // 观测值个数
a.aa.n = a.allpnum; // 未知点个数(极大权处理,含控制点)
// 观测值权阵计算
for( int i= 0; i < a.aa.m; i++)
for (int j = 0; j < a.aa.m; j++)
if (i != j) a.aa.P[i][j] = 0;
else a.aa.P[i][j] = 1 / a.L[i].length;
cout << endl << endl << " 平差数据准备,请稍等...... " << endl << endl;
cout << " 观测值权阵计算结果 :" << endl; matdis(a.aa.P, a.obnum, a.obnum);
cout << endl;
// 误差方程系数阵计算
for( int i= 0; i < a.aa.m; i++) // 根据水准线路号及起、终点号确定
for (int j = 0; j < a.aa.n; j++)
a.aa.A[i][j] = 0;
for( int i= 0; i < a.aa.m; i++)
{
a.aa.A[i][a.L[i].endp->i] = 1;
a.aa.A[i][a.L[i].startp->i] = -1;
}
cout << " " << " 误差方程系数阵计算结果: " << endl;
matdis(a.aa.A, a.aa.m, a.aa.n);
cout << endl;
// 误差方程常数项计算
double AX0;
for( int i= 0; i < a.aa.m; i++) // V=AX-L
{ // L=h-AX0
AX0 = 0;
for (int j = 0; j < a.aa.n; j++)
AX0 += a.aa.A[i][j] * a.Pt[j].H0;
a.aa.l[i][0] = a.L[i].h - AX0;
}
cout << endl;
cout << " " << " 误差方程常数项计算结果 :" << endl;
matdis(a.aa.l, a.aa.m);
cout << endl;
// 平差数据保存在date.txt文件中
ofstream out("date.txt");
out << a.netname << endl;
out << a.obnum << endl;
out << a.allpnum << endl;
matout(a.aa.A, a.aa.m, a.aa.n, out);
out << endl;
matout(a.aa.P, a.aa.m, a.aa.m, out);
out << endl;
matout(a.aa.l, a.aa.m, out);
out.close();
return 1;
}
//************************************************************************************************
int Hnetadj(Hnet& a, char* outfile) // 高程网平差函数
{
fsetadj(a.aa, "date.txt");
cout << endl << " 正在平差计算,请稍等...... " << endl << endl;
doadj(a.aa, a.fixpnum, 0); // 极大权法最小二乘平差:
for (int i = 0; i < a.allpnum; i++) // 未知点高程及精度计算
{
a.Pt[i].H = a.Pt[i].H0 + a.aa.X[i][0];
a.Pt[i].mH = a.aa.m0 * sqrt(a.aa.QXX[i][i]);
}
// 结果屏幕输出:
cout << endl << " " << " 验后单位权中误差:+-" << a.aa.m0 << endl << endl << " 未知数改正数dX: " << endl;
matdis(a.aa.X, a.aa.n);
cout << endl << " " << " 观测值改正数V:" << endl;
matdis(a.aa.V, a.aa.m);
cout << endl << " " << " 未知点高程及精度 :" << endl;
for( int i= a.fixpnum; i < a.allpnum; i++)
cout << " " << a.Pt[i].name << "高程=" << a.Pt[i].H << " +-" << a.Pt[i].mH << endl;
cout << endl;
// 平差结果文件保存
ofstream out(outfile);
if (!out) cout << "can not open save file!" << endl;
out << " 高程网" << a.netname << "平差计算 " << endl << endl;
out << "1. 原始数据: " << endl << endl;
out << " " << a.netname << " " << a.obnum << " " << a.allpnum << " " << a.fixpnum << " " << a.m0 << endl;
for( int i= 0; i < a.fixpnum; i++)
out << " " << a.Pt[i].name << " " << a.Pt[i].H << endl;
out << endl;
for( int i= 0; i < a.obnum; i++)
out << " " << a.L[i].startp->name << " " << a.L[i].endp->name << " " << a.L[i].h
<< " " << a.L[i].length << endl;
out << endl;
out << "2. 平差数据:" << endl << endl;
out << " 2.1 误差方程系数阵: " << endl;
matout(a.aa.A, a.aa.m, a.aa.n, out);
out << endl << endl;
out << " 2.2 误差方程权阵: " << endl;
matout(a.aa.P, a.aa.m, a.aa.m, out);
out << endl << endl;
out << " 2.3 未知点近似高程: " << endl;
for( int i= a.fixpnum; i < a.allpnum; i++)
{
out << " ";
out << a.Pt[i].name << " " << a.Pt[i].H0 << " ";
out << endl;
}
out << endl << endl;
out << " 2.4 误差方程常数项: " << endl;
matout(a.aa.l, a.aa.m, out);
out << endl;
out << "3. 平差结果 " << endl << endl;
out << " 3.1 观测值改正数V: " << endl;
matout(a.aa.V, a.aa.m, out);
out << endl << endl;
out << " 3.2 单位权中误差m0:+-" << a.aa.m0 << endl;
out << endl << endl;
out << " 3.3 未知数改正数dH:" << endl;
for( int i= a.fixpnum; i < a.allpnum; i++)
{
out << " ";
out << a.aa.X[i][0] << " ";
out << endl;
}
out << endl << endl;
out << " 3.4 未知点高程及精度: " << endl;
for( int i= a.fixpnum; i < a.allpnum; i++)
{
out << " ";
out << a.Pt[i].name << " " << a.Pt[i].H << " +-" << a.Pt[i].mH;
out << endl;
}
out << endl << endl;
out << " 3.5 未知参数协方差阵: " << endl;
for( int i= a.fixpnum; i < a.allpnum; i++)
{
out << " ";
for (int j = a.fixpnum; j < a.allpnum; j++)
out << a.aa.m0 * a.aa.m0 * a.aa.QXX[i][j] << " ";
out << endl;
}
out.close();
return 1;
}
int Hdoadj(Hnet& a, char* infilename, char* outfilename)
{
if (finHnet(a, infilename)) {
Hnetadj(a, outfilename);
return 1;
}
else return 0;
}
// ***********************************************************************************************
// *********************************** 平面网平差******** ****************************************
double d_h(double angle) //角度化弧度
{
double a, b;
angle = modf(angle, &a);
angle = modf(angle * 100.0, &b);
return (a + b / 60.0 + angle / 36.0) * (PI + 3.0E-16) / 180.0;
}
// ***********************************************************************************************
double h_d(double angle) //弧度化角度
{
double a, b, c;
angle = modf(angle * 180.0 / (PI - 3.0E-16), &a);
angle = modf(angle * 60.0, &b);
angle = modf(angle * 60.0, &c);
return a + b * 0.01 + c * 0.0001 + angle * 0.0001;
}
// ************************************平面网平差计算*********************************************
// ************************************平面网点结构定义*******************************************
struct XYP {
char name[20]; // 点名
double X; // x坐标值
double Y; // y坐标值
double X0; // x坐标近似值
double Y0; // y坐标近似值
double mX; // x坐标中误差
double mY; // y坐标中误差
double mp; // 点位中误差
double E; // 误差椭圆长半轴
double F; // 误差椭圆短半轴
double T; // 误差椭圆长半轴方向
int fixed; // 是否控制点(控制点为1;未知点为0)
int i; // 点号(0-->allpnum-1)
};
//*****************************对点的"=="的重载***************************************************
int operator ==(XYP& a, XYP& b)
{
if (_strnicmp(b.name, a.name, 20))
return 1;
else return 0;
}
//***********************************平面网观测值结构*********************************************
struct obser {
XYP* startp; // 观测值起点指针
XYP* endp; // 观测值终点指针
double dist; // 距离观测值
double dist0; // 近似距离
double angle; // 方向观测值
double A; // 观测值方位角
double A0; // 近似方位角
double m0; // 观测值平差值精度
int i; // 测站的观测值序号
int sti; // 测站序号
int style; // 角度测量=1;距离测量=2;固定方位角=3;固定边长=4
};
//******************************平面网测站结构****************************************************
struct stat1 {
XYP* stp;
int obnum; // 测站观测值总数
int disnum; // 测站距离观测值个数
int aglnum; // 测站方向观测值个数
int i; // 测站序号
};
//********************************平面网结构******************************************************
struct XYnet {
char netname[40]; // 网名
int allpnum; // 总点数
int fixpnum; // 控制点个数
int statnum; // 测站数
int obnum; // 观测值总数
int fixdisn; // 固定边长个数
int fixafn; // 固定方位角个数
int anglenum; // 方向观测值总数
int distnum; // 距离观测值总数
double mangle; // 验前方向观测值误差
double msa; // 距离误差加常数
double msb; // 距离误差乘常数
stat1 st[MAX]; // 定义平面网测站结构
XYP Pt[MAX]; // 平面网点结构
obser L[MAX]; // 平面网观测值结构
adj aa; // 平面网平差结构
};
//************************* 坐标反算距离**********************************************************
double dist(XYP& a, XYP& b)
{
if (a.X != -PI && b.X != -PI)
return sqrt((b.X - a.X) * (b.X - a.X) + (b.Y - a.Y) * (b.Y - a.Y));
if (a.X0 != -PI && b.X0 != -PI)
return sqrt((b.X0 - a.X0) * (b.X0 - a.X0) + (b.Y0 - a.Y0) * (b.Y0 - a.Y0));
return -PI;
}
//************************* 坐标反算方位角********************************************************
double afa(XYP& a, XYP& b)
{
if (a.X != -PI && b.X != -PI)
{
double d = dist(a, b);
double t = acos((b.X - a.X) / d);
if (b.Y - a.Y < 0.0) t = 2.0 * PI - t;
return t;
}
if (a.X0 != -PI && b.X0 != -PI)
{
double d = dist(a, b);
double t = acos((b.X0 - a.X0) / d);
if (b.Y0 - a.Y0 < 0.0) t = 2.0 * PI - t;
return t;
}
return -PI;
}
//**********************************两方向交会近似坐标计算****************************************
int XY0ang(obser& a1, obser& a2) // 两方向交会近似坐标计算
{
if (a1.A0 == -PI || a2.A0 == -PI || a1.A0 == a2.A0) return 0;
if (d_h(a1.A0) == d_h(a2.A0) + PI || d_h(a1.A0) == d_h(a2.A0) - PI) return 0;
if (a1.dist != -PI || a1.dist0 != -PI || a2.dist != -PI || a2.dist0 != -PI) return 0;
double k, B[MAX][MAX], A[MAX][MAX], L[MAX][1], X[MAX][1];
if (a1.startp == a2.startp && a1.startp->X0 == -PI && a1.endp->X0 != -PI && a2.endp->X0 != -PI)
{
k = tan(d_h(a1.A0));
A[0][0] = k; A[0][1] = -1;
L[0][0] = k * a1.endp->X0 - a1.endp->Y0;
k = tan(d_h(a2.A0));
A[1][0] = k; A[1][1] = -1;
L[1][0] = k * a2.endp->X0 - a2.endp->Y0;
inverse(A, B, 2);
AXB(B, L, X, 2, 2);
a1.startp->X0 = X[0][0];
a1.startp->Y0 = X[1][0];
// cout<<"XY0ang****1 "<
return 1;
}
/*
if(a1.endp==a2.endp && a1.startp->X0!=-PI && a2.startp->X0!=-PI && a1.endp->X0==-PI)
{
k=tan(d_h(a1.A0));
A[0][0]=-k;A[0][1]=1;
L[0][0]=-(k*a1.startp->X0-a1.startp->Y0);
k=tan(d_h(a2.A0));
A[1][0]=-k;A[1][1]=1;
L[1][0]=-(k*a2.startp->X0-a2.startp->Y0);
inverse(A,B,2);
// cout<<"XY0ang****3 "<X0=X[0][0];
a1.endp->Y0=X[1][0];
return 1;
}
if(a1.startp==a2.endp && a1.startp->X0==-PI && a1.endp->X0!=-PI && a2.startp->X0!=-PI)
{
k=tan(d_h(a1.A0));
A[0][0]=k;A[0][1]=-1;
L[0][0]=k*a1.endp->X0-a1.endp->Y0;
k=tan(d_h(a2.A0));
A[1][0]=-k;A[1][1]=1;
L[1][0]=-(k*a2.startp->X0-a2.startp->Y0);
inverse(A,B,2);
AXB(B,L,X,2,2);
a1.startp->X0=X[0][0];
a1.startp->Y0=X[1][0];
// cout<<"XY0ang****3 "<X0==-PI && a1.startp->X0!=-PI && a2.endp->X0!=-PI)
{
k=tan(d_h(a1.A0));
A[0][0]=-k;A[0][1]=1;
L[0][0]=-(k*a1.startp->X0-a1.startp->Y0);
k=tan(d_h(a2.A0));
A[1][0]=k;A[1][1]=-1;
L[1][0]=k*a2.endp->X0-a2.endp->Y0;
inverse(A,B,2);
AXB(B,L,X,2,2);
a1.endp->X0=X[0][0];
a1.endp->Y0=X[1][0];
// cout<<"XY0ang****4 "<
return 0;
}
//**********************************三边交会法计算近似坐标****************************************
int XY0dist(obser& a, obser& b, obser& c) // 三边交会法计算近似坐标
{
if (a.dist0 == -PI || b.dist0 == -PI || c.dist0 == -PI) return 0;
if (a.startp != b.startp || a.startp != c.startp || b.startp != c.startp) return 0;
if (a.endp == b.endp || a.endp == c.endp || b.endp == c.endp) return 0;
if (a.endp->X0 == -PI || b.endp->X0 == -PI || c.endp->X0 == -PI || a.startp->X0 != -PI) return 0;
double a1 = afa(*(a.endp), *(b.endp)) - afa(*(a.endp), *(c.endp));
if (fabs(a1) < 0.2 * PI || fabs(fabs(a1) - PI) < 0.2) return 0;
double B[MAX][MAX], A[MAX][MAX], L[MAX][1], X[MAX][1];
A[0][0] = a.endp->X0 - b.endp->X0; A[0][1] = a.endp->Y0 - b.endp->Y0;
L[0][0] = (-a.dist0 * a.dist0 + b.dist0 * b.dist0 + a.endp->X0 * a.endp->X0
- b.endp->X0 * b.endp->X0 + a.endp->Y0 * a.endp->Y0 - b.endp->Y0 * b.endp->Y0) / 2.0;
A[1][0] = a.endp->X0 - c.endp->X0; A[1][1] = a.endp->Y0 - c.endp->Y0;
L[1][0] = (-a.dist0 * a.dist0 + c.dist0 * c.dist0 + a.endp->X0 * a.endp->X0
- c.endp->X0 * c.endp->X0 + a.endp->Y0 * a.endp->Y0 - c.endp->Y0 * c.endp->Y0) / 2.0;
inverse(A, B, 2);
AXB(B, L, X, 2, 2);
a.startp->X0 = X[0][0];
a.startp->Y0 = X[1][0];
// cout<<"XY0dist****1 "<
return 1;
}
//***********************************坐标正算法近似坐标计算***************************************
// 坐标正算
int zheng(obser& a)
{
if (a.startp->X0 == -PI && a.endp->X0 == -PI || a.startp->X0 != -PI && a.endp->X0 != -PI
|| a.dist0 == -PI || a.A0 == -PI)
return 0;
if (a.startp->X0 != -PI && a.endp->X0 == -PI)
{
a.endp->X0 = a.startp->X0 + cos(d_h(a.A0)) * a.dist0; // 要求方位角为弧度制
a.endp->Y0 = a.startp->Y0 + sin(d_h(a.A0)) * a.dist0;
return 1;
}
if (a.startp->X0 == -PI && a.endp->X0 != -PI)
{
a.startp->X0 = a.endp->X0 - cos(d_h(a.A0)) * a.dist0; // 要求方位角为弧度制
a.startp->Y0 = a.endp->Y0 - sin(d_h(a.A0)) * a.dist0;
return 1;
}
return 0;
}
//*********************************角度后方交会法计算近似坐标*************************************
//角度后方交会法计算近似坐标
int houj(obser& a, obser& b, obser& c)
{
if (a.startp != b.startp || a.startp != c.startp || b.startp != c.startp) return 0;
if (a.endp->X0 == -PI || b.endp->X0 == -PI || c.endp->X0 == -PI) return 0;
if (a.angle == -PI || b.angle == -PI || c.angle == -PI) return 0;
if (a.A0 != -PI || b.A0 != -PI || c.A0 != -PI || a.startp->X0 != -PI) return 0;
// add code here...
obser L1, L2, L0;
int i = 0;
if (i < a.i) { i = a.i; L2 = a; } if (i < b.i) { i = b.i; L2 = b; } if (i < c.i) { i = c.i; L2 = c; }
i = 1000000;
if (i > a.i) { i = a.i; L0 = a; } if (i > b.i) { i = b.i; L0 = b; } if (i > c.i) { i = c.i; L0 = c; }
if ((a.i == L0.i || a.i == L2.i) && (b.i == L0.i || b.i == L2.i)) L1 = c;
if ((a.i == L0.i || a.i == L2.i) && (c.i == L0.i || c.i == L2.i)) L1 = b;
if ((b.i == L0.i || b.i == L2.i) && (c.i == L0.i || c.i == L2.i)) L1 = a;
double A, B, C, af, bt, B1, B2;
B = afa(*(L1.endp), *(L0.endp)) - afa(*(L1.endp), *(L2.endp)); //弧度
A = afa(*(L0.endp), *(L2.endp)) - afa(*(L0.endp), *(L1.endp)); //弧度
C = afa(*(L2.endp), *(L1.endp)) - afa(*(L2.endp), *(L0.endp)); //弧度
B = fabs(B); if (B > PI) B = 2 * PI - B;
A = fabs(A); if (A > PI) A = 2 * PI - A;
C = fabs(C); if (C > PI) C = 2 * PI - C;
af = d_h(L1.angle) - d_h(L0.angle); //弧度
if (af > PI) af = 2 * PI - af;
bt = d_h(L2.angle) - d_h(L1.angle); //弧度
if (bt > PI) bt = 2 * PI - bt;
B1 = atan((1 / tan(A) - 1 / tan(bt)) / (1 - 1 / tan(A) / tan(af) - 1 / tan(B) * (1 / tan(af) + 1 / tan(bt))));
if (B1 < 0)B1 += PI;
B2 = atan((1 / tan(C) - 1 / tan(af)) / (1 - 1 / tan(C) / tan(bt) - 1 / tan(B) * (1 / tan(af) + 1 / tan(bt))));
if (B2 < 0)B2 += PI;
// cout<
L1.A0 = h_d(afa(*(L1.endp), *(L0.endp)) - B1 + PI);
if (L1.A0 > 360) L1.A0 = h_d(d_h(L1.A0) - 2 * PI);
double dd = d_h(L1.angle) - d_h(L1.A0);
L0.A0 = h_d(d_h(L0.angle) - dd);
L2.A0 = h_d(d_h(L2.angle) - dd);
XY0ang(L0, L1);
// cout<X0<<" "<Y0<
return 1;
}
//**************************键盘输入未知点近似坐标************************************************
void kinXY0(XYnet& a) // 键盘输入未知点近似坐标
{
for (int i = a.fixpnum; i < a.allpnum; i++)
{
cout << a.Pt[i].name << " x0= "; cin >> a.Pt[i].X0; cout << endl;
cout << a.Pt[i].name << " y0= "; cin >> a.Pt[i].Y0; cout << endl;
}
}
//****************************文件输入未知点近似坐标**********************************************
int finXY0(XYnet& a, char* XY0filename) // 文件输入未知点近似坐标
{
// add code here
return 1;
}
//****************************************逐测站近似方位角推算************************************
void statangc(XYnet& a)
{
int n1 = 0;
int n = a.obnum + a.fixafn + a.fixdisn;
for (int i = 0; i < a.statnum; i++) // 逐测站
{
for (int j = n1; j < n1 + a.st[i].aglnum; j++) // 测站首观测值的序号
{
if (a.L[j].A0 != -PI)
{
double df = d_h(a.L[j].angle) - d_h(a.L[j].A0);
for (int k = j - a.L[j].i; k < j - a.L[j].i + a.st[a.L[j].sti].aglnum; k++)
if (a.L[k].A0 == -PI)
{
if (d_h(a.L[k].angle) - df >= 0) a.L[k].A0 = h_d(d_h(a.L[k].angle) - df);
if (d_h(a.L[k].angle) - df >= 2 * PI) a.L[k].A0 = h_d(d_h(a.L[k].angle) - df - 2 * PI);
if (d_h(a.L[k].angle) - df < 0) a.L[k].A0 = h_d(d_h(a.L[k].angle) - df + 2.0 * PI);
for (int k1 = 0; k1 < n; k1++) // 已知近似方位角的传递
{
if (a.L[k1].A0 == -PI && a.L[k1].startp == a.L[k].endp
&& a.L[k1].endp == a.L[k].startp)
if (d_h(a.L[k].A0) - PI >= 0) a.L[k1].A0 = h_d(d_h(a.L[k].A0) - PI);
else a.L[k1].A0 = h_d(d_h(a.L[k].A0) + PI);
if (a.L[k1].A0 == -PI && a.L[k1].startp == a.L[k].startp
&& a.L[k1].endp == a.L[k].endp)
a.L[k1].A0 = a.L[k].A0;
}
break;
}
}
}
n1 += a.st[i].disnum + a.st[i].aglnum; // 下一个测站
}
}
//****************************************???三角形结构*******************************************
struct Triangle
{
XYP p1;
XYP p2;
XYP p3;
double p1ang;
double p2ang;
double p3ang;
double d12;
double d13;
double d23;
double adajian180;
};
//************************无定向导线计算未知点的近似坐标******************************************
int Udxdsetx0y0(XYnet& a) // 用于三角网控制点不相邻且无方向观测情况
{
// add code here
int obi, flag;
for (int i = 0; i < a.obnum; i++)
if (a.L[i].startp->fixed == 1 && a.L[i].endp->fixed || a.L[i].A0 != -PI) return 0;
// 1号以上控制点近似坐标归零
for( int i= 1; i < a.fixpnum; i++)
a.Pt[i].X0 = a.Pt[i].Y0 = -PI;
// 起始边确定
for( int i= 0; i < a.obnum; i++)
if (a.L[i].startp->i == 0 && a.L[i].endp->fixed == 0
|| a.L[i].startp->fixed == 0 && a.L[i].endp->i == 0) {
obi = i; break;
}
// 假设方位角与边长
if (a.L[obi].A0 == -PI)a.L[obi].A0 = 0;
if (a.L[obi].dist0 == -PI)a.L[obi].dist0 = 1;
XYP end;
zheng(a.L[obi]);
// 假设方位角计算
do {
flag = 0;
statangc(a);
for (int i = 0; i < a.obnum; i++)
if (a.L[i].A0 == -PI) { flag = 1; break; }
} while (flag == 1);
// 假设近似坐标计算
flag = 0;
do {
for (int i = 0; i < a.obnum - 1; i++)
for (int j = i + 1; j < a.obnum; j++)
XY0ang(a.L[i], a.L[j]);
flag++;
} while (flag < a.obnum);
end.X0 = a.Pt[1].X0; end.Y0 = a.Pt[1].Y0;
end.X = end.Y = -PI;
// 计算改正后起始坐标方位角与长度
a.L[obi].dist0 *= dist(a.Pt[0], a.Pt[1]) / dist(a.Pt[0], end);
double ddf = afa(a.Pt[0], a.Pt[1]) - afa(a.Pt[0], end);
if (ddf < 0) ddf += 2 * PI;
a.L[obi].A0 += h_d(ddf);
// 各点近似坐标归零
for( int i= 1; i < a.allpnum; i++)
if (i < a.fixpnum) { a.Pt[i].X0 = a.Pt[i].X; a.Pt[i].Y0 = a.Pt[i].Y; }
else a.Pt[i].X0 = a.Pt[i].Y0 = -PI;
// 近似方位角归零
for( int i= 0; i < a.obnum + a.fixafn + a.fixdisn; i++)
if (i != obi)a.L[i].A0 = -PI;
zheng(a.L[obi]); // 坐标正算
// 计算改正后近似方位角
do {
flag = 0;
statangc(a);
for (int i = 0; i < a.obnum; i++)
if (a.L[i].A0 == -PI) { flag = 1; break; }
} while (flag == 1);
// 计算改正后各点的近似坐标
do {
flag = 0;
for (int i = 0; i < a.obnum - 1; i++)
for (int j = i + 1; j < a.obnum; j++)
XY0ang(a.L[i], a.L[j]);
for( int i= 0; i < a.allpnum; i++)
if (a.Pt[i].X0 == -PI)
{
flag = 1; break;
}
} while (flag == 1);
// for(i=0;i
// cout<
// <
return 1;
}
//************************计算控制网未知点的近似坐标**********************************************
int setx0y0(XYnet& a)
{
int n = a.obnum + a.fixdisn + a.fixafn;
// 1.计算近似坐标、近似边长确定的方位角与边长
int t(0);
do {
for (int i = 0; i < n; i++)
{
if (a.L[i].startp->X0 != -PI && a.L[i].endp->X0 != -PI && a.L[i].A0 == -PI)
{
//1.1 近似坐标确定的边的方位角
a.L[i].A0 = h_d(afa(*(a.L[i].startp), *(a.L[i].endp)));
for (int k = 0; k < n; k++)
{
if (a.L[i].startp == a.L[k].endp && a.L[i].endp == a.L[k].startp && a.L[k].A0 == -PI)
{
if (d_h(a.L[i].A0) - PI >= 0)
a.L[k].A0 = h_d(d_h(a.L[i].A0) - PI);
else a.L[k].A0 = h_d(d_h(a.L[i].A0) + PI);
}
if (a.L[i].startp == a.L[k].startp && a.L[i].endp == a.L[k].endp && a.L[k].A0 == -PI)
a.L[k].A0 = a.L[i].A0;
}
}
//1.2 边长观测值计算的近似边长
if (a.L[i].style == 2 || a.L[i].style == 4)
for (int k = 0; k < n; k++)
if (a.L[i].startp == a.L[k].endp && a.L[i].endp == a.L[k].startp && a.L[k].dist0 == -PI
|| a.L[i].startp == a.L[k].startp && a.L[i].endp == a.L[k].endp && a.L[k].dist0 == -PI)
a.L[k].dist0 = a.L[i].dist0;
//1.3 由已知近似方位角推算未知近似方位角
if (a.L[i].A0 != -PI)
for (int k = 0; k < n; k++)
{
if (a.L[i].startp == a.L[k].endp && a.L[i].endp == a.L[k].startp && a.L[k].A0 == -PI)
{
if (d_h(a.L[i].A0) - PI >= 0)
a.L[k].A0 = h_d(d_h(a.L[i].A0) - PI);
else a.L[k].A0 = h_d(d_h(a.L[i].A0) + PI);
}
if (a.L[i].startp == a.L[k].startp && a.L[i].endp == a.L[k].endp && a.L[k].A0 == -PI)
a.L[k].A0 = a.L[i].A0;
}
}
// 2. 以测站计算观测值近似方位角
statangc(a);
// 3.近似坐标计算
// 3.1 两方位角交会法
for( int i= 0; i < n - 1; i++)
for (int j = i + 1; j < n; j++)
XY0ang(a.L[i], a.L[j]);
// 3.2 坐标正算法
for( int i= 0; i < a.obnum + a.fixafn + a.fixdisn; i++)
zheng(a.L[i]);
// 3.3 角度后方交会法
for( int i= 0; i < a.obnum - 2; i++)
for (int j = i + 1; j < a.obnum - 1; j++)
for (int k = j + 1; k < a.obnum; k++)
houj(a.L[i], a.L[j], a.L[k]);
// 3.4边长后方交会法
for( int i= 0; i < a.obnum + a.fixafn + a.fixdisn - 2; i++)
for (int j = i + 1; j < a.obnum + a.fixafn + a.fixdisn - 1; j++)
for (int k = j + 1; k < a.obnum + a.fixafn + a.fixdisn; k++)
XY0dist(a.L[i], a.L[j], a.L[k]);
// 3.5 无定向导线
Udxdsetx0y0(a);
// 4. 迭代条件的判断
t = 0;
for( int i= 0; i < a.allpnum; i++)
{
// cout<
if (a.Pt[i].X0 == -PI || a.Pt[i].Y0 == -PI)
t = 1;
}
} while (t == 1);
cout << "---------------------------------------------------------------------------" << endl;
cout << " 未知点近似坐标 " << endl;
cout << "---------------------------------------------------------------------------" << endl;
for (int ii = a.fixpnum; ii < a.allpnum; ii++)
cout << " " << a.Pt[ii].name << " " << setf(a.Pt[ii].X0, 3) << " " << setf(a.Pt[ii].Y0, 3) << endl;
cout << "---------------------------------------------------------------------------" << endl;
return 1;
}
//********************************设置平面网平差的A,P,L*******************************************
int setXYadj(XYnet& a)
{
// 1 确定平差网基本信息
a.aa.m = a.obnum + a.fixafn + a.fixdisn;
a.aa.n = 2 * a.allpnum + a.statnum;
// 2 确定观测值的权镇P
for (int i = 0; i < a.aa.m; i++)
{
for (int j = 0; j < a.aa.m; j++)
a.aa.P[i][j] = 0;
if (a.L[i].style == 1) // 设置角度观测值的权
{
a.aa.P[i][i] = 1;
}
if (a.L[i].style == 2) // 设置距离观测值的权
{
double mlml = a.msa + a.msb / 1000000 * a.L[i].dist;
mlml *= mlml;
a.aa.P[i][i] = a.mangle / rou * a.mangle / rou / mlml;
}
if (a.L[i].style == 3 || a.L[i].style == 4)// 设置固定距离与方位角观测值的权
a.aa.P[i][i] = 1000000;
}
// matdis(a.aa.P,a.aa.m,a.aa.m);
// 3 确定误差方程系数阵A
for( int i= 0; i < a.aa.m; i++)
{
double s = dist(*(a.L[i].startp), *(a.L[i].endp));
// cout<
double ss = s * s;
double dy = a.L[i].endp->Y0 - a.L[i].startp->Y0;
double dx = a.L[i].endp->X0 - a.L[i].startp->X0;
double aki = dy / ss; double bki = -1 * dx / ss;
for (int j = 0; j < a.aa.n; j++)
{
a.aa.A[i][j] = 0;
if (a.L[i].style == 1) // 方向观测值误差方程系数
{
a.aa.A[i][2 * a.allpnum + a.L[i].sti] = -1; // 测站定向角未知数系数
a.aa.A[i][2 * (a.L[i].startp->i)] = aki;
a.aa.A[i][2 * (a.L[i].startp->i) + 1] = bki;
a.aa.A[i][2 * (a.L[i].endp->i)] = -aki;
a.aa.A[i][2 * (a.L[i].endp->i) + 1] = -bki;
}
if (a.L[i].style == 2 || a.L[i].style == 4) // 边长观测值、固定边长误差方程系数
{
a.aa.A[i][2 * (a.L[i].startp->i)] = bki * s;
a.aa.A[i][2 * (a.L[i].startp->i) + 1] = -aki * s;
a.aa.A[i][2 * (a.L[i].endp->i)] = -bki * s;
a.aa.A[i][2 * (a.L[i].endp->i) + 1] = aki * s;
}
if (a.L[i].style == 3) // 固定方位角误差方程系数
{
a.aa.A[i][2 * a.L[i].startp->i] = aki;
a.aa.A[i][2 * a.L[i].startp->i + 1] = bki;
a.aa.A[i][2 * a.L[i].endp->i] = -aki;
a.aa.A[i][2 * a.L[i].endp->i + 1] = -bki;
}
}
}
// matdis(a.aa.A,a.aa.m,a.aa.n);
// 4 确定误差方程常数项L
for( int i= 0; i < a.aa.m; i++)
{
a.L[i].A0 = h_d(afa(*(a.L[i].startp), *(a.L[i].endp)));
a.L[i].dist0 = dist(*(a.L[i].startp), *(a.L[i].endp));
if (a.L[i].style == 3)
{
a.aa.l[i][0] = d_h(a.L[i].A - a.L[i].A0);
}
if (a.L[i].style == 2 || a.L[i].style == 4)
{
a.aa.l[i][0] = a.L[i].dist - a.L[i].dist0;
}
}
//方向观测值误差方程常数项
int n = 0;
for (int j = 0; j < a.statnum; j++)
{
for (int i = n; i < n + a.st[j].aglnum; i++)
{
double scd = d_h(a.L[i].A0) - d_h(a.L[n].A0);
if (scd < 0) scd += 2 * PI;
a.aa.l[i][0] = d_h(a.L[i].angle) - scd;
}
n += a.st[j].aglnum + a.st[j].disnum;
}
//matdis(a.aa.l,a.aa.m);
return 1;
}
//********************************控制网平差计算**************************************************
int doXYadj(XYnet& a)
{
// 6 平差计算
int r0 = a.fixafn + a.fixdisn;
if (!doadj(a.aa, 2 * a.fixpnum, r0))return 0; // 其中第二项为控制点数与测站数之和
cout << "---------------------------------------------------------------------------" << endl;
cout << " 未知数改正数 " << endl;
cout << "---------------------------------------------------------------------------" << endl;
matdis(a.aa.X, a.aa.n);
cout << "---------------------------------------------------------------------------" << endl;
cout << " 验后单位权中误差:" << a.aa.m0 * 206264.8 << " 秒 " << endl;
cout << "---------------------------------------------------------------------------" << endl;
cout << " 平差后未知点坐标: " << endl << endl;
cout << "---------------------------------------------------------------------------" << endl;
for (int i = a.fixpnum; i < a.allpnum; i++)
{
a.Pt[i].X = a.Pt[i].X0 + a.aa.X[2 * i][0];
a.Pt[i].Y = a.Pt[i].Y0 + a.aa.X[2 * i + 1][0];
a.Pt[i].X0 += a.aa.X[2 * i][0];
a.Pt[i].Y0 += a.aa.X[2 * i + 1][0];
cout.precision(11); cout.width(10);
cout << " " << a.Pt[i].name << " " << setf(a.Pt[i].X, 4) << " " << setf(a.Pt[i].Y, 4) << endl;
}
cout << "---------------------------------------------------------------------------" << endl;
cout << " 未知点坐标的协方差阵:" << endl << endl;
cout << "---------------------------------------------------------------------------" << endl;
for( int i= 2 * a.fixpnum; i < 2 * a.allpnum; i++)
{
cout << " ";
for (int j = 2 * a.fixpnum; j < 2 * a.allpnum; j++)
{
cout << a.aa.m0 * a.aa.m0 * a.aa.QXX[i][j] << " ";
}cout << endl;
}
cout << "---------------------------------------------------------------------------" << endl;
cout << " 观测值改正数:" << endl << endl;
cout << "---------------------------------------------------------------------------" << endl;
matdis(a.aa.V, a.aa.m);
cout << "---------------------------------------------------------------------------" << endl;
//7 点位中误差与误差椭圆元素计算
for( int i= a.fixpnum; i < a.allpnum; i++)
{
// 坐标中误差计算
a.Pt[i].mX = a.aa.m0 * sqrt(a.aa.QXX[2 * i][2 * i]);
a.Pt[i].mY = a.aa.m0 * sqrt(a.aa.QXX[2 * i + 1][2 * i + 1]);
// 误差椭圆参数计算
double K = sqrt((a.aa.QXX[2 * i][2 * i] - a.aa.QXX[2 * i + 1][2 * i + 1])
* (a.aa.QXX[2 * i][2 * i] - a.aa.QXX[2 * i + 1][2 * i + 1])
+ 4 * a.aa.QXX[2 * i][2 * i + 1] * a.aa.QXX[2 * i][2 * i + 1]);
a.Pt[i].mp = sqrt(a.Pt[i].mX * a.Pt[i].mX + a.Pt[i].mY * a.Pt[i].mY);
a.Pt[i].E = sqrt(1 / 2.0 * a.aa.m0 * a.aa.m0 * (a.aa.QXX[2 * i][2 * i] + a.aa.QXX[2 * i + 1][2 * i + 1] + K));
a.Pt[i].F = sqrt(1 / 2.0 * a.aa.m0 * a.aa.m0 * (a.aa.QXX[2 * i][2 * i] + a.aa.QXX[2 * i + 1][2 * i + 1] - K));
double F2 = atan2(2 * a.aa.QXX[2 * i][2 * i + 1], a.aa.QXX[2 * i][2 * i] - a.aa.QXX[2 * i + 1][2 * i + 1]);
if (F2 <= 0) F2 += 2 * PI; F2 /= 2.0;
if (a.aa.QXX[2 * i][2 * i + 1] > 0 && F2 > PI / 2.0 && F2 < PI
|| a.aa.QXX[2 * i][2 * i + 1]>0 && F2 > PI * 3 / 2.0 && F2 < 2 * PI)
F2 += PI / 2.0;
if (a.aa.QXX[2 * i][2 * i + 1] < 0 && F2 < PI / 2.0 && F2>0
|| a.aa.QXX[2 * i][2 * i + 1]<0 && F2>PI && F2 < PI * 3 / 2.0)
F2 += PI / 2.0;
if (F2 >= 2 * PI) F2 -= 2 * PI;
a.Pt[i].T = h_d(F2);
}
return 1;
}
//*******************************平面网的文件输入*************************************************
int finXYnet(XYnet& a,const char* fname) // 文件输入平面网函数
{
ifstream in(fname); // 建立文件流,并与输入文件名建立关联
if (!in) { cout << fname << " error: file does not exist! " << endl; return 0; }
// 文件现实性判断
// 1 输入网的基本信息
char name[20];
in >> a.netname;
in >> a.allpnum;
in >> a.fixpnum;
in >> a.statnum;
// in>>a.obnum;
a.obnum = 0;
in >> a.fixdisn;
in >> a.fixafn;
in >> a.mangle;
in >> a.msa;
in >> a.msb;
int n(a.fixpnum); // n为已输入名字的点的个数
// 2输入控制点信息
for (int i = 0; i < a.fixpnum; i++)
{
in >> a.Pt[i].name >> a.Pt[i].X >> a.Pt[i].Y;
a.Pt[i].fixed = 1; // 控制点标记
a.Pt[i].X0 = a.Pt[i].X;
a.Pt[i].Y0 = a.Pt[i].Y;
a.Pt[i].mX = a.Pt[i].mY = 0;
a.Pt[i].i = i; // 控制点编号,从0到a.fixpnum-1
}
// 3 输入未知点相关信息(名字在后面输入)
for( int i= a.fixpnum; i < a.allpnum; i++)
{
a.Pt[i].fixed = 0; // 未知点标记
a.Pt[i].X = a.Pt[i].Y = -PI;
a.Pt[i].X0 = a.Pt[i].Y0 = -PI;
a.Pt[i].mX = a.Pt[i].mY = 0;
*(a.Pt[i].name) = 0;
a.Pt[i].i = i; // 为未知点编号,从a.fixpnum到a.allpnum-1
}
a.anglenum = 0;
a.distnum = 0;
// 4 输入测站及观测值
int obsnum(0);
for( int i= 0; i < a.statnum; i++)
{
// 4-1 输入测站信息
int t = 0; // 点名比较标志
in >> name; // 输入测站名
for (int k = 0; k < n; k++)
if (_strnicmp(name, a.Pt[k].name, 20) == 0)
{
a.st[i].stp = &(a.Pt[k]); // 找到同名点,起点指针指向该点
t++; // 找到标志
}
if (t == 0) {
strcpy_s(a.Pt[n].name, name);
a.st[i].stp = &(a.Pt[n]); // 找不到同名点,该名输给新点
n++;
}
in >> a.st[i].obnum;
a.st[i].aglnum = 0; // 测站角度观测个数
a.st[i].disnum = 0; // 测站距离观测个数
a.st[i].i = i;
// 4-2 输入本站观测值
for (int j = obsnum; j < obsnum + a.st[i].obnum; j++)
{
in >> name; t = 0; // 输入照准点名,操作过程同上
a.L[j].startp = a.st[i].stp;
for (int k = 0; k < n; k++)
if (_strnicmp(name, a.Pt[k].name, 20) == 0)
{
a.L[j].endp = &(a.Pt[k]);
t++;
}
if (t == 0)
{
strcpy_s(a.Pt[n].name, name);
a.L[j].endp = &(a.Pt[n]);
n++;
}
in >> a.L[j].style;
a.L[j].A = a.L[j].A0 = -PI;
if (a.L[j].style == 1)
{
a.anglenum++;
a.st[i].aglnum++;
in >> a.L[j].angle; // 输入方向观测值
a.L[j].dist0 = -PI;
a.L[j].dist = -PI;
}
if (a.L[j].style == 2)
{
a.distnum++;
a.st[i].disnum++;
in >> a.L[j].dist; // 输入距离观测值
a.L[j].dist0 = a.L[j].dist;
a.L[j].angle = -PI;
}
a.L[j].i = j - obsnum;
a.L[j].sti = i;
}
obsnum += a.st[i].aglnum + a.st[i].disnum;
a.obnum += a.st[i].aglnum + a.st[i].disnum;
}
// 文件正确性判断
// 5 固定边长输入
for( int i= obsnum; i < obsnum + a.fixdisn; i++)
{
in >> name; int t = 0;
for (int k = 0; k < n; k++)
if (_strnicmp(name, a.Pt[k].name, 20) == 0)
{
a.L[i].startp = &(a.Pt[k]);
t++;
}
if (t == 0)
{
strcpy_s(a.Pt[n].name, name);
a.L[i].startp = &(a.Pt[n]);
n++;
}
in >> name; t = 0;
for (int k = 0; k < n; k++)
if (_strnicmp(name, a.Pt[k].name, 20) == 0)
{
a.L[i].endp = &(a.Pt[k]);
t++;
}
if (t == 0)
{
strcpy_s(a.Pt[n].name, name);
a.L[i].endp = &(a.Pt[n]);
n++;
}
in >> a.L[i].dist;
a.L[i].dist0 = a.L[i].dist; //输入距离值
a.L[i].A = a.L[i].A0 = -PI;
a.L[i].style = 4;
a.L[i].angle = -PI;
a.L[i].i = i - obsnum;
}
obsnum += a.fixdisn;
// 5 固定方位角输入
for( int i= obsnum; i < obsnum + a.fixafn; i++)
{
in >> name; int t = 0;
for (int k = 0; k < n; k++)
if (_strnicmp(name, a.Pt[k].name, 20) == 0)
{
a.L[i].startp = &(a.Pt[k]);
t++;
}
if (t == 0)
{
strcpy_s(a.Pt[n].name, name);
a.L[i].startp = &(a.Pt[n]);
n++;
}
in >> name; t = 0;
for (int k = 0; k < n; k++)
if (_strnicmp(name, a.Pt[k].name, 20) == 0)
{
a.L[i].endp = &(a.Pt[k]);
t++;
}
if (t == 0)
{
strcpy_s(a.Pt[n].name, name);
a.L[i].endp = &(a.Pt[n]);
n++;
}
in >> a.L[i].A; a.L[i].A0 = a.L[i].A;
a.L[i].style = 3;
a.L[i].dist = -PI;
a.L[i].dist0 = -PI;
a.L[i].i = i - obsnum;
a.L[i].angle = -PI;
}
obsnum += a.fixafn;
if (n != a.allpnum) {
cout << fname << " error: file provide not correct point number ! " << endl;
return 0;
}
in.close();
return 1; // 关闭输入流及关联文件
}
//***************************平面网数据屏幕输出***************************************************
void XYnetdis(XYnet& aa)
{
cout << "\n基本信息:\n";
cout << "k控制网名称:\t"<<aa.netname << "\n总点数:\t" << aa.allpnum << "\n控制点点数:\t" << aa.fixpnum << "\n测站数:\t" << aa.statnum << "\n观测值总数:\t"
<< aa.obnum << "\n固定边长个数:\t" << aa.fixdisn << "\n固定角度个数:\t" << aa.fixafn << endl;
cout << "\n验前方向观测值误差:\t" << aa.mangle << "\n距离误差加常数:\t" << aa.msa << "\n距离误差乘常数:\t" << aa.msb << endl << endl;
cout << "控制点信息:\n";
for (int i = 0; i < aa.fixpnum; i++)
cout << aa.Pt[i].name << " " << aa.Pt[i].X << " " << aa.Pt[i].Y << endl;
cout << endl;
cout << "测站信息:\n";
int n(0);
for (int j = 0; j < aa.statnum; j++)
{
cout << "第" << j+1 << "个测站:\n";
cout << aa.st[j].stp->name << " " << aa.st[j].aglnum << " " << aa.st[j].disnum << endl;
for( int i= n; i < n + aa.st[j].aglnum + aa.st[j].disnum; i++)
{
cout << " " << aa.L[i].i << " " << aa.L[i].endp->name << " " << aa.L[i].style;
if (aa.L[i].style == 1) cout << " " << aa.L[i].angle << endl;
if (aa.L[i].style == 2) cout << " " << aa.L[i].dist << endl;
}cout << endl;
n += aa.st[j].aglnum + aa.st[j].disnum;
}
for( int i= aa.obnum; i < aa.obnum + aa.fixdisn + aa.fixafn; i++)
{
cout << aa.L[i].startp->name << " " << aa.L[i].endp->name << " " << aa.L[i].style << " ";
if (aa.L[i].style == 4)cout << aa.L[i].dist << endl;
if (aa.L[i].style == 3)cout << aa.L[i].A << endl;
}cout << endl;
}
//*****************************平面网的边结构****************************************************
struct range {
XYP st; // 起点
XYP ed; // 终点
double A; // 计算方位角
double MA; // 方位角中误差
double S; // 计算边长
double MS; // 边长中误差
double sMS; // 边长相对精度
double E; // 相对误差极大值
double F; // 相对误差极小值
double T; // 相对误差极大值方位角
};
//*******************************平面控制网平差结果文件输出函数***********************************
//平面控制网平差结果文件输出函数
int XYfileout(XYnet& aa,const char* outfile)
{
ofstream ou(outfile);
ou.width(5);
ou.right;
ou.precision(11);
// 1网的基本信息输出
ou << endl << " 平面控制网" << aa.netname << "平差计算结果 " << endl << endl;
ou << "-----------------------------------------------------------------------" << endl;
ou << " 控制网输入数据 " << endl;
ou << "-----------------------------------------------------------------------" << endl;
ou << " 网 名: " << aa.netname << " 总点数: " << aa.allpnum << " 控制点数: "
<< aa.fixpnum << " 测站数: " << aa.statnum << " 观测值总数: " << aa.obnum << endl
<< " 固定边长数: " << aa.fixdisn << " 固定方位角数: " << aa.fixafn;
ou << endl << " 角度测量中误差: " << aa.mangle << "s 距离误差加常数: " << aa.msa
<< "m 距离误差乘常数: " << aa.msb << "ppm" << endl << endl;
ou << "-----------------------------------------------------------------------" << endl;
ou << " 控制点名 X Y " << endl;
ou << "-----------------------------------------------------------------------" << endl;
for (int i = 0; i < aa.fixpnum; i++)
{
ou << " "; ou.width(5); ou << aa.Pt[i].name; ou << " "; ou.width(13);
ou << aa.Pt[i].X; ou << " "; ou.width(13); ou << aa.Pt[i].Y << endl;
}ou << endl;
ou << "-----------------------------------------------------------------------" << endl;
ou << " 测站名 方向观测数 边长观测数 照准点 观测类型 观测值 " << endl;
ou << "-----------------------------------------------------------------------" << endl;
int n(0);
for (int j = 0; j < aa.statnum; j++)
{
ou.width(6); ou << aa.st[j].stp->name; ou.width(12); ou << aa.st[j].aglnum;
ou.width(12); ou << aa.st[j].disnum << endl;
for( int i= n; i < n + aa.st[j].aglnum + aa.st[j].disnum; i++)
{
ou << " " << " "; ou.width(12); ou << aa.L[i].endp->name << " ";
if (aa.L[i].style == 1)ou << "方向" << " " << aa.L[i].angle << endl;
if (aa.L[i].style == 2)ou << "边长" << " " << aa.L[i].dist << endl;
}ou << " " << endl;
n += aa.st[j].aglnum + aa.st[j].disnum;
}
if (aa.fixafn + aa.fixdisn > 0) {
ou << "-----------------------------------------------------------------------" << endl;
ou << " 固定方位角与边长数据 " << endl;
ou << "-----------------------------------------------------------------------" << endl;
ou << " 起点名 终点名 数据类型 数 据 " << endl;
ou << "-----------------------------------------------------------------------" << endl;
for( int i= aa.obnum; i < aa.obnum + aa.fixdisn + aa.fixafn; i++)
{
ou << " "; ou.width(6); ou << aa.L[i].startp->name << " ";
ou.width(6); ou << aa.L[i].endp->name; ou.width(12);
if (aa.L[i].style == 4) { ou << "边 长"; ou.width(16); ou << aa.L[i].dist << endl; }
if (aa.L[i].style == 3) { ou << "方位角"; ou.width(16); ou << aa.L[i].A0 << endl; }
}
ou << "-----------------------------------------------------------------------" << endl;
}
ou << endl;
// 2输出网的近似坐标计算结果
ou << "-----------------------------------------------------------------------" << endl;
ou << " 控制网近似坐标计算结果 " << endl;
ou << "-----------------------------------------------------------------------" << endl;
ou << " Name X(m) Y(m)" << endl;
ou << "-----------------------------------------------------------------------" << endl;
for (int i = 0; i < aa.allpnum; i++)
{
ou << " "; ou.width(6); ou << aa.Pt[i].name << " "; ou.width(12);
ou.precision(10); ou << setf(aa.Pt[i].X0, 3) << " "; ou.width(12);
ou.precision(10); ou << setf(aa.Pt[i].Y0, 3) << endl;
}
ou << "-----------------------------------------------------------------------" << endl;
double A[MAX][MAX], AQAT[MAX][MAX];
// 3输出观测值的平差结果
ou << "--------------------------------------------------------------------------------" << endl;
if (aa.anglenum > 0) {
ou << " 方向观测值平差结果" << endl;
ou << "--------------------------------------------------------------------------------" << endl;
ou << " FROM TO TYPE VALUE(dms) M(sec) V(sec) RESULT(dms) Ri" << endl;
ou << "--------------------------------------------------------------------------------" << endl;
for( int i= 0; i < aa.obnum; i++)
for (int j = 0; j < 2 * aa.allpnum + aa.statnum; j++)
AT(aa.aa.A, A, aa.obnum, 2 * aa.allpnum + aa.statnum);
ATPA(A, aa.aa.QXX, AQAT, 2 * aa.allpnum + aa.statnum, aa.obnum);
// cout<<"now,output QLL:"<
// matdis(AQAT,aa.obnum,aa.obnum);
for (int i = 0; i < aa.obnum; i++)
if (aa.L[i].style == 1)
{
ou.width(9); ou << aa.L[i].startp->name;
ou.width(8); ou << aa.L[i].endp->name;
ou.width(6); ou << " 方向";
ou.width(16);
ou << aa.L[i].angle;
ou.width(8);
ou << setf(aa.aa.m0 * sqrt(AQAT[i][i]) * rou, 2);
ou.width(9);
ou << setf(aa.aa.V[i][0] * rou, 2);
ou << " ";
ou.width(12);
ou << setf(h_d(d_h(aa.L[i].angle) + aa.aa.V[i][0]), 5);
// ou<
ou << endl;
}
ou << "--------------------------------------------------------------------------------" << endl;
}
if (aa.distnum > 0) {
ou << "--------------------------------------------------------------------------------" << endl;
ou << " 边长观测值平差结果" << endl;
ou << "--------------------------------------------------------------------------------" << endl;
ou << " FROM TO TYPE VALUE(m) M(cm) V(cm) RESULT(m) " << endl;
ou << "--------------------------------------------------------------------------------" << endl;
for( int i= 0; i < aa.obnum; i++)
if (aa.L[i].style == 2)
{
ou.width(9); ou << aa.L[i].startp->name;
ou.width(8); ou << aa.L[i].endp->name;
ou.width(6); ou << "边长";
ou.width(16);
ou << aa.L[i].dist;
ou.width(8);
ou << setf(aa.aa.m0 * sqrt(AQAT[i][i]) * 100, 2);
ou.width(9);
ou << setf(aa.aa.V[i][0] * 100, 2);
ou << " ";
ou.width(11);
ou << setf(aa.L[i].dist + aa.aa.V[i][0], 4);
ou << endl;
}
ou << "--------------------------------------------------------------------------------" << endl;
}
// 4输出坐标计算结果与精度
ou << "-----------------------------------------------------------------------------------------" << endl;
ou << " 平差坐标及其精度" << endl;
ou << "-----------------------------------------------------------------------------------------" << endl;
ou << " Name X(m) Y(m) MX(cm) MY(cm) MP(cm) E(cm) F(cm) T(d.ms) " << endl;
ou << "-----------------------------------------------------------------------------------------" << endl;
for( int i= 0; i < aa.fixpnum; i++)
{
ou.right;
ou.width(8); ou << aa.Pt[i].name; ou.precision(11); ou.width(17);
ou << setf(aa.Pt[i].X, 4); ou.precision(11); ou.width(16); ou << setf(aa.Pt[i].Y, 4) << endl;
}
double Mx(0), My(0), Mp(0);
for( int i= aa.fixpnum; i < aa.allpnum; i++)
{
ou.right;
ou.width(8); ou << aa.Pt[i].name; ou.precision(11);
ou.width(17); ou << setf(aa.Pt[i].X, 4); ou.precision(11);
ou.width(16); ou << setf(aa.Pt[i].Y, 4);
ou.precision(4); ou.width(8); ou << aa.Pt[i].mX * 100;
ou.precision(4); ou.width(7); ou << aa.Pt[i].mY * 100;
ou.precision(4); ou.width(7); ou << aa.Pt[i].mp * 100;
ou.precision(4); ou.width(7); ou << aa.Pt[i].E * 100;
ou.precision(4); ou.width(7); ou << aa.Pt[i].F * 100;
ou << " ";
ou.precision(9); ou.width(11); ou << setf(aa.Pt[i].T, 5);
ou << endl;
Mx += aa.Pt[i].mX * 100 / (aa.allpnum - aa.fixpnum);
My += aa.Pt[i].mY * 100 / (aa.allpnum - aa.fixpnum);
Mp += aa.Pt[i].mp * 100 / (aa.allpnum - aa.fixpnum);
}
ou.precision(4);
ou << "-----------------------------------------------------------------------------------------" << endl;
ou << " Mx均值: "; ou.width(5); ou << Mx;
ou << " My均值: "; ou.width(5); ou << My;
ou << " Mp均值: "; ou.width(5); ou << Mp << endl;
ou << "-----------------------------------------------------------------------------------------" << endl << endl;
// 5最弱点及精度
ou << " 最弱点及其精度" << endl;
ou << "-----------------------------------------------------------------------------------------" << endl;
ou << " Name X(m) Y(m) MX(cm) MY(cm) MP(cm) E(cm) F(cm) T(dms) " << endl;
double a(0);
for( int i= aa.fixpnum; i < aa.allpnum; i++)
if (a <= aa.Pt[i].mp) { a = aa.Pt[i].mp; n = i; }
ou.right;
ou.width(8); ou << aa.Pt[n].name; ou.precision(11); ou.width(17);
ou << setf(aa.Pt[n].X, 4); ou.precision(11); ou.width(16); ou << setf(aa.Pt[n].Y, 4);
ou.precision(4); ou.width(8); ou << aa.Pt[n].mX * 100;
ou.precision(4); ou.width(7); ou << aa.Pt[n].mY * 100;
ou.precision(4); ou.width(7); ou << aa.Pt[n].mp * 100;
ou.precision(4); ou.width(7); ou << aa.Pt[n].E * 100;
ou.precision(4); ou.width(7); ou << aa.Pt[n].F * 100;
ou << " ";
ou.precision(9); ou.width(10); ou << setf(aa.Pt[n].T, 5);
ou << endl;
ou << "-----------------------------------------------------------------------------------------" << endl;
// 6 网点间边长、方位角及其相对精度
ou << " 网点间边长、方位角及其相对精度" << endl;
ou << "--------------------------------------------------------------------------------------------------" << endl;
ou << " FROM TO A(dms) MA(sec) S(m) MS(cm) S/MS E(cm) F(cm) T(dms) " << endl;
ou << "--------------------------------------------------------------------------------------------------" << endl;
range L[MAX];
int Li(0);
for( int i= aa.fixpnum; i < aa.allpnum; i++)
for (int j = 0; j < aa.allpnum; j++)
{
if( i== j || aa.Pt[j].fixed == 0 && j < i) continue;
for (int k = 0; k < aa.obnum + aa.fixdisn + aa.fixafn; k++)
if (*(aa.L[k].startp) == aa.Pt[i] && *(aa.L[k].endp) == aa.Pt[j] ||
*(aa.L[k].startp) == aa.Pt[j] && *(aa.L[k].endp) == aa.Pt[i])
{
L[Li].st = aa.Pt[i]; L[Li].ed = aa.Pt[j];
Li++;
break;
}
}
for( int i= 0; i < Li; i++)
{
for (int k = 0; k < 4; k++)
for (int j = 0; j < 2 * aa.allpnum + aa.statnum; j++)
{
A[k][j] = 0;
}
double s = dist(L[i].ed, L[i].st);
double ss = s * s;
double dy = L[i].ed.Y - L[i].st.Y;
double dx = L[i].ed.X - L[i].st.X;
double aki = dy / ss; double bki = -1 * dx / ss;
A[0][2 * (L[i].st.i)] = bki * s; A[0][2 * (L[i].st.i) + 1] = -aki * s;
A[0][2 * (L[i].ed.i) + 1] = aki * s; A[0][2 * (L[i].ed.i)] = -bki * s;
A[1][2 * (L[i].st.i)] = aki; A[1][2 * (L[i].st.i) + 1] = bki;
A[1][2 * (L[i].ed.i)] = -aki; A[1][2 * (L[i].ed.i) + 1] = -bki;
A[2][2 * (L[i].st.i)] = -1; A[2][2 * (L[i].ed.i)] = 1;
A[3][2 * (L[i].st.i) + 1] = -1; A[3][2 * (L[i].ed.i) + 1] = 1;
double AH[MAX][MAX];
AT(A, AH, 4, 2 * aa.allpnum + aa.statnum);
ATPA(AH, aa.aa.QXX, AQAT, 2 * aa.allpnum + aa.statnum, 4);
// matdis(AQAT,4,4);
L[i].S = dist(L[i].st, L[i].ed);
L[i].A = h_d(afa(L[i].st, L[i].ed));
L[i].MS = aa.aa.m0 * sqrt(AQAT[0][0]);
L[i].MA = aa.aa.m0 * sqrt(AQAT[1][1]) * rou;
double K = sqrt((AQAT[2][2] - AQAT[3][3]) * (AQAT[2][2] - AQAT[3][3]) + 4 * AQAT[2][3] * AQAT[2][3]);
//a.Pt[i].mp=sqrt(a.Pt[i].mX*a.Pt[i].mX+a.Pt[i].mY*a.Pt[i].mY);
L[i].E = sqrt(1 / 2.0 * aa.aa.m0 * aa.aa.m0 * (AQAT[2][2] + AQAT[3][3] + K));
L[i].F = sqrt(1 / 2.0 * aa.aa.m0 * aa.aa.m0 * (AQAT[2][2] + AQAT[3][3] - K));
double F2 = atan2(2 * AQAT[2][3], AQAT[2][2] - AQAT[3][3]);
if (F2 <= 0) F2 += 2 * PI; F2 /= 2.0;
if (AQAT[2][3] > 0 && F2 > PI / 2.0 && F2 < PI || AQAT[2][3]>0 && F2 > PI * 3 / 2.0 && F2 < 2 * PI)
F2 += PI / 2.0;
if (AQAT[2][3] < 0 && F2 < PI / 2.0 && F2>0 || AQAT[2][3]<0 && F2>PI && F2 < PI * 3 / 2.0)
F2 += PI / 2.0;
if (F2 >= 2 * PI) F2 -= 2 * PI;
L[i].T = h_d(F2);
ou.width(6); ou << L[i].st.name; ou.width(9); ou << L[i].ed.name;
ou.width(13); ou << setf(h_d(afa(L[i].st, L[i].ed)), 5); ou.width(9);
ou << setf(L[i].MA, 2); ou.width(13); ou << setf(dist(L[i].st, L[i].ed), 4);
ou.width(8); ou << setf(L[i].MS * 100, 2);
ou.width(11);
if (L[i].S / L[i].MS > 10E+9) ou << "无穷大";
else ou << setf(L[i].S / L[i].MS, 0);
ou.width(8); ou << setf(L[i].E * 100, 2); ou.width(8); ou << setf(L[i].F * 100, 2);
ou.width(12); ou << setf(L[i].T, 4);
ou << endl;
}
ou << "--------------------------------------------------------------------------------------------------" << endl;
// 7输出最弱边信息
ou << " 最弱边及其精度" << endl;
ou << "--------------------------------------------------------------------------------------------------" << endl;
ou << " FROM TO A(dms) MA(sec) S(m) MS(cm) S/MS E(cm) F(cm) T(dms) " << endl;
a = 0;
for( int i= 0; i < Li; i++)
if (a < L[i].MS / L[i].S) { a = L[i].MS / L[i].S; n = i; }
ou.width(6); ou << L[n].st.name; ou.width(9); ou << L[n].ed.name;
ou.width(13); ou << setf(h_d(afa(L[n].st, L[n].ed)), 5); ou.width(9);
ou << setf(L[n].MA, 3); ou.width(13); ou << setf(dist(L[n].st, L[n].ed), 4);
ou.width(8); ou << setf(L[n].MS * 100, 2);
ou.width(11); ou << setf(L[n].S / L[n].MS, 0); ou.width(8);
ou << setf(L[n].E * 100, 3); ou.width(8); ou << setf(L[n].F * 100, 3);
ou.width(12); ou << setf(L[n].T, 5);
ou << endl;
ou << "--------------------------------------------------------------------------------------------------" << endl << endl;
// 7输出单位权中误差与多于观测信息
ou << " 单位权中误差与多于观测信息" << endl;
ou << "----------------------------------------------------------------------------------------------" << endl;
ou << " 先验单位权中误差: " << aa.mangle << endl;
ou << " 后验单位权中误差: " << setf(aa.aa.m0 * rou, 2) << endl;
ou << " 多余观测值总数: " << aa.obnum - 2 * (aa.allpnum - aa.fixpnum) << endl;
ou << " 平均多余观测值数: " << setf((double)aa.obnum / 2 / (aa.allpnum - aa.fixpnum) - 1, 2) << endl;
ou << "-----------------------------------------------------------------------------------------------------" << endl;
// 控制网总体信息
ou << "-----------------------------------------------------------------------------------------------------" << endl;
ou << endl;
ou << " " << aa.netname << "控制网总体信息" << endl;
ou << endl;
ou << " 已知点数: " << aa.fixpnum << " 未知点数: "
<< aa.allpnum - aa.fixpnum << endl;
ou << " 方向角数: " << aa.fixafn << " 固定边数: "
<< aa.fixdisn << endl;
ou << " 方向观测值数: " << aa.anglenum << " 边长观测值数: "
<< aa.distnum << endl;
ou << "-----------------------------------------------------------------------------------------------------" << endl;
ou.close();
return 1;
}
//***********************************************************************************************
//*******************平面三角网平差主程序模块****************************************************
int XYadj(XYnet& aa,const char* infile,const char* outfile)
{
if (finXYnet(aa, infile)) { // 文件输入控制网数据
XYnetdis(aa); // 网的基本信息屏幕输出
setx0y0(aa); // 未知点近似坐标的计算
int i(0);
double xold[MAX];
double dx[MAX], a;
do { // 近似坐标要求的平差迭代计算
a = 0;
setXYadj(aa);
if (!doXYadj(aa)) return 0;
for (int i = 0; i < aa.allpnum * 2; i++)
{
dx[i] = aa.aa.X[i][0] - xold[i];
xold[i] = aa.aa.X[i][0];
if (a < fabs(dx[i])) a = fabs(dx[i]);
}
} while (a > 0.00001); // 迭代的两次坐标差标准
for( int i= 0; i < aa.obnum; i++)
{
if (aa.L[i].style == 1) cout << "Vang==" << aa.aa.V[i][0] * rou << endl;
else cout << "Vdis==" << aa.aa.V[i][0] << endl;
}
XYfileout(aa, outfile);
}
else return 0;
return 1;
}
//****************************** main() ************************************************
void main()
{
cout.precision(16);
cout.width(12);
XYnet aa;
//finXYnet(aa,"pingmian1.txt");
// XYnetdis(aa);
//setx0y0(aa);
//setXYadj(aa);
//doXYadj(aa);
XYadj(aa, "data_bd-4.txt", "result_bd.txt");
}
//基本信息
平面控制网名字
总点数
控制点个数
测站数
固定边长个数
固定方位角个数
验前方向观测值误差
距离误差加常数
距离误差乘常数
//控制点信息
控制点点名1 X坐标 Y坐标
控制点点名2 X坐标 Y坐标
......
//测站信息
测站名1 观测值总数
照准点名1
观测值属性(角度测量=1;距离测量=2;固定方位角=3;固定边长=4 )
观测值(角度或距离)
照准点名2
观测值属性(角度测量=1;距离测量=2;固定方位角=3;固定边长=4 )
观测值(角度或距离)
测站名2
观测值总数
照准点名3
观测值属性(角度测量=1;距离测量=2;固定方位角=3;固定边长=4 )
观测值(角度或距离)
照准点名4
观测值属性(角度测量=1;距离测量=2;固定方位角=3;固定边长=4 )
观测值(角度或距离)
......
//固定边长信息
边名1 距离
边名2 距离
......
//固定方位角信息
角名1 角度
角名2 角度
......
导线网数据示例。
SHUJV
6
4
5
0
0
2.5
0
15
A 3143.237 5260.334
B 4609.361 5025.696
C 4157.197 8853.254
D 3822.911 9795.726
A 3
B 1 0.0
P1 1 44.05448
P1 2 2185.070
B 3
P1 1 0.0
A 1 93.10431
P1 2 1522.853
P1 4
A 1 0.0
B 1 42.43272
P2 1 244.32184
P2 2 1500.017
P2 3
P1 1 0.0
C 1 201.57340
C 2 1009.021
C 2
P2 1 0.0
D 1 168.01452
以上导线网的文件输出结果,这个输出还是做的相当美观的哈。
平面控制网SHUJV平差计算结果
-----------------------------------------------------------------------
控制网输入数据
-----------------------------------------------------------------------
网 名: SHUJV 总点数: 6 控制点数: 4 测站数: 5 观测值总数: 15
固定边长数: 0 固定方位角数: 0
角度测量中误差: 2.5s 距离误差加常数: 0m 距离误差乘常数: 15ppm
-----------------------------------------------------------------------
控制点名 X Y
-----------------------------------------------------------------------
A 3143.237 5260.334
B 4609.361 5025.696
C 4157.197 8853.254
D 3822.911 9795.726
-----------------------------------------------------------------------
测站名 方向观测数 边长观测数 照准点 观测类型 观测值
-----------------------------------------------------------------------
A 2 1
B 方向 0
P1 方向 44.05448
P1 边长 2185.07
B 2 1
P1 方向 0
A 方向 93.10431
P1 边长 1522.853
P1 3 1
A 方向 0
B 方向 42.43272
P2 方向 244.32184
P2 边长 1500.017
P2 2 1
P1 方向 0
C 方向 201.5734
C 边长 1009.021
C 2 0
P2 方向 0
D 方向 168.01452
-----------------------------------------------------------------------
控制网近似坐标计算结果
-----------------------------------------------------------------------
Name X(m) Y(m)
-----------------------------------------------------------------------
A 3143.237 5260.334
B 4609.361 5025.696
C 4157.197 8853.254
D 3822.911 9795.726
P1 4933.052 6513.721
P2 4684.411 7992.944
-----------------------------------------------------------------------
--------------------------------------------------------------------------------
方向观测值平差结果
--------------------------------------------------------------------------------
FROM TO TYPE VALUE(dms) M(sec) V(sec) RESULT(dms) Ri
--------------------------------------------------------------------------------
A B 方向 0 2.41 0.31 3e-05
A P1 方向 44.05448 2.41 -0.31 44.05445
B P1 方向 0 2.49 -2.28 -0.00023
B A 方向 93.10431 2.49 2.28 93.10454
P1 A 方向 0 2.02 -0.35 -3e-05
P1 B 方向 42.43272 2.43 0.61 42.43278
P1 P2 方向 244.32184 2.7 -0.26 244.32181
P2 P1 方向 0 2.88 0.47 5e-05
P2 C 方向 201.5734 2.88 -0.47 201.57335
C P2 方向 0 2.62 1.56 0.00016
C D 方向 168.01452 2.62 -1.56 168.01436
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
边长观测值平差结果
--------------------------------------------------------------------------------
FROM TO TYPE VALUE(m) M(cm) V(cm) RESULT(m)
--------------------------------------------------------------------------------
A P1 边长 2185.07 1.76 -2.61 2185.0439
B P1 边长 1522.853 1.96 -2.87 1522.8243
P1 P2 边长 1500.017 2.05 -4.25 1499.9745
P2 C 边长 1009.021 1.73 -1.74 1009.0036
--------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
平差坐标及其精度
-----------------------------------------------------------------------------------------
Name X(m) Y(m) MX(cm) MY(cm) MP(cm) E(cm) F(cm) T(d.ms)
-----------------------------------------------------------------------------------------
A 3143.237 5260.334
B 4609.361 5025.696
C 4157.197 8853.254
D 3822.911 9795.726
P1 4933.0521 6513.7209 1.578 1.954 2.512 1.96 1.571 82.48199
P2 4684.4114 7992.9441 1.396 1.659 2.168 1.734 1.302 116.03522
-----------------------------------------------------------------------------------------
Mx均值: 1.487 My均值: 1.807 Mp均值: 2.34
-----------------------------------------------------------------------------------------
最弱点及其精度
-----------------------------------------------------------------------------------------
Name X(m) Y(m) MX(cm) MY(cm) MP(cm) E(cm) F(cm) T(dms)
P1 4933.0521 6513.7209 1.578 1.954 2.512 1.96 1.571 82.48199
-----------------------------------------------------------------------------------------
网点间边长、方位角及其相对精度
--------------------------------------------------------------------------------------------------
FROM TO A(dms) MA(sec) S(m) MS(cm) S/MS E(cm) F(cm) T(dms)
--------------------------------------------------------------------------------------------------
P1 A 215.00112 1.69 2185.0439 1.76 124360 1.96 1.57 82.482
P1 B 257.43394 2.13 1522.8243 1.96 77819 1.96 1.57 82.482
P1 C 108.20491 1.38 2464.8258 1.89 130177 1.96 1.57 82.482
P1 D 108.41173 0.98 3464.6747 1.89 183147 1.96 1.57 82.482
P1 P2 99.32297 1.92 1499.9745 2.05 73076 2.05 1.4 96.5535
P2 A 240.34382 1.06 3137.2562 1.45 215664 1.73 1.3 116.0352
P2 B 268.33041 0.98 2968.197 1.65 179764 1.73 1.3 116.0352
P2 C 121.30027 2.67 1009.0036 1.73 58311 1.73 1.3 116.0352
P2 D 115.32307 1.34 1998.0504 1.73 115244 1.73 1.3 116.0352
--------------------------------------------------------------------------------------------------
最弱边及其精度
--------------------------------------------------------------------------------------------------
FROM TO A(dms) MA(sec) S(m) MS(cm) S/MS E(cm) F(cm) T(dms)
P2 C 121.30027 2.671 1009.0036 1.73 58311 1.734 1.302 116.03522
--------------------------------------------------------------------------------------------------
单位权中误差与多于观测信息
----------------------------------------------------------------------------------------------
先验单位权中误差: 2.5
后验单位权中误差: 3.19
多余观测值总数: 11
平均多余观测值数: 2.75
-----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------
SHUJV控制网总体信息
已知点数: 4 未知点数: 2
方向角数: 0 固定边数: 0
方向观测值数: 11 边长观测值数: 4
-----------------------------------------------------------------------------------------------------