闭合水准网平差

c++水准网间接平差法平差

环境:vs2017+qt+eigen-3.3.8矩阵库

P1点为已知点,高程100米

文件数据格式

7,4,100.00
1,5,20.344,4
1,2,10.286,4.7
5,2,-10.069,3.1
2,3,-4.954,3.5
3,5,15.020,3.2
3,4,1.227,4.4
4,5,13.801,3.8

ui界面

代码

头文件

#pragma once

#include <QtWidgets/QWidget>
#include "ui_leveling_network.h"

class leveling_network : public QWidget
{
    Q_OBJECT

public:
    leveling_network(QWidget *parent = nullptr);
	int compute();
    ~leveling_network();

private:
    Ui::leveling_networkClass ui;
};

mian文件

#include "leveling_network.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    leveling_network w;
    w.show();
    return a.exec();
}

计算文件leveling_network.cpp

#include "leveling_network.h"
#include<qpushbutton.h>
#include<qmessagebox.h>
#include <QTextEdit>  
#include <QStringList>  
#include<qdebug.h>
#include<cmath>
#include<Eigen/Dense>
#include<stdio.h>
#include<iostream>
#include <QFileDialog>   //文件对话框
#include <fstream>
#define PI acos(-1)

using namespace std;

struct datas//侧段数据结构体
{
	int b;//后视点站号
	int f;//前视点站号
	double hd;//高度差=前视点高程-后视点高程
	double ds;//距离
};

leveling_network::leveling_network(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
	//读取文件计算并输出按钮的槽函数
	connect(ui.pushButton, &QPushButton::clicked, this, [=] {
		compute();
	});
	//退出功能
	connect(ui.pushButton_3, &QPushButton::clicked, this, &QWidget::close);
	
}
//
//计算函数
int leveling_network::compute()
{
	int n, i, j, t;//往测和返侧数
	datas ss[100];//声明数据结构体
	double h1;//起始点高程
	
	// 文件对话框
		QString in_path = QFileDialog::getOpenFileName(this, "OPEN", "../", "TXT(*.txt)");//设置文件路径 文件格式
		if (in_path.isEmpty() == false) {//路径正确
			//创建文件对象 并且关联起来
			QFile file(in_path);
			bool isok = file.open(QIODevice::ReadOnly);//利用只读模式打开文件
			if (isok) {//打开成功
				QString text = file.readLine();//读取第一行
				text.replace("\n", "\0");//将换行符剔除
				QStringList list = text.split(',');
				n = list[0].toInt();//观测值个数
				t = list[1].toInt();//未知点高程个数
				h1 = list[2].toDouble();//已知点高程

				i = 0;
				//行循环读取 file.readLine()
				while (file.atEnd() == false) {
					QString text = file.readLine();//换行符号也是读取的
					text.replace("\n", "\0");//将换行符剔除
					QStringList list1 = text.split(',');//结构体数组赋值
					ss[i].b = list1[0].toInt();
					ss[i].f = list1[1].toInt();
					ss[i].hd = list1[2].toDouble();
					ss[i].ds = list1[3].toDouble();
					i++;
				}
				file.close();
				if (i != n) { QMessageBox::critical(this, "warning", "data error"); file.close(); return 0; }
			}
			else {
				QMessageBox::critical(this, "warning", "Failed to open observation data file, exiting function"); file.close(); return 0;
			}
		}else {
				QMessageBox::critical(this, "warning", "The observation data file path is empty"); return 0;
			}
		
		double H[100] ;//点高程近似值(包括第一个已知点)
		H[0] = h1;
		j = 0;
		for (i = 1; i <=t; i++) {
			for (j = 0; i < n; j++) {
				if (H[ss[j].b-1] != NULL && ss[j].f == i + 1)
				{
					H[i] = H[ss[j].b-1] + ss[j].hd;
					break;
				}
				else if (ss[j].b == i + 1 && H[ss[j].f-1] != NULL) {
					H[i] = H[ss[j].f-1] - ss[j].hd;
					break;
				}
			}
		}

		//定义矩阵
		Eigen::MatrixXd l = Eigen::MatrixXd::Zero( n , 1);//常数向量
		Eigen::MatrixXd L = Eigen::MatrixXd::Zero(n , 1);//观测值近似阵
		Eigen::MatrixXd B = Eigen::MatrixXd::Zero(n , t);//系数阵
		Eigen::MatrixXd P = Eigen::MatrixXd::Zero(n, n);//权阵
		Eigen::MatrixXd X = Eigen::MatrixXd::Zero(t, 1);//参数近似值矩阵
		//第一点为已知点,参数矩阵第一个值从第二个高程点开始
		for (i = 0; i < t; i++) X(i, 0)= H[i + 1];参数近似值矩阵赋值
		//B矩阵赋值
		for (i = 0; i < n; i++) {
			if (ss[i].b == 1) {
				L(i, 0) = X(ss[i].f - 2, 0) - h1;
				B(i, ss[i].f - 2) = 1;
			}
			else if (ss[i].f == 1) {
				L(i, 0) =h1- X(ss[i].b - 2, 0) ;
				B(i, ss[i].b - 2) = -1;
			}
			else {
				L(i, 0) = X(ss[i].f - 2, 0) - X(ss[i].b - 2, 0);
				B(i, ss[i].b - 2) = -1;
				B(i, ss[i].f - 2) = 1;
			}
			P(i, i) = 1 / ss[i].ds;//权阵赋值
			l(i, 0) = ss[i].hd - L(i, 0);//l向量赋值
		}
		//矩阵解算
		Eigen::MatrixXd NBB(t,  t);
		Eigen::MatrixXd x(t,1);
		Eigen::MatrixXd v( n , 1);
		Eigen::MatrixXd L_( n, 1);
		NBB = B.transpose()*P*B;
		x = NBB.inverse()*B.transpose()*P*l;
		v = B * x - l;


		Eigen::MatrixXd zh(1, 1);//从一行一列矩阵提取单位权中误差所需数字
		zh = v.transpose()*P*v;
		double jm = zh(0, 0);
		double o = sqrt(jm/(n-t));//单位权中误差
		//创建文件并输出
		QString filePath = QFileDialog::getSaveFileName(this, "Save As", "E:/output2", tr("TXT(*.txt)"));
		string path = filePath.toStdString();//将qstring转换为string
		ofstream out_file(path);
		if (out_file.is_open()) {
			out_file << "单位权中误差为(单位米):" << std::endl;
			out_file << to_string(o) << std::endl;
			out_file << "--------------------------------------------------------------------" << std::endl;
			out_file << "观测值近似值矩阵为(单位米):" << std::endl;
			out_file << L << std::endl;
			out_file << "--------------------------------------------------------------------" << std::endl;
			out_file << "参数近似值矩阵为(单位米):" << std::endl;
			out_file << X << std::endl;
			out_file << "--------------------------------------------------------------------" << std::endl;
			out_file << "B矩阵为:" << std::endl;
			out_file << B << std::endl;
			out_file << "--------------------------------------------------------------------" << std::endl;
			out_file << "x参数改正数矩阵为:单位为米:" << std::endl;
			out_file << x << std::endl;
			out_file << "--------------------------------------------------------------------" << std::endl;
			out_file << "v观测值改正数矩阵为(单位米):" << std::endl;
			out_file << v << std::endl;
			out_file << "--------------------------------------------------------------------" << std::endl;
			L_ = v + L;
			out_file << "改正后的观测阵矩阵为(单位米):" << std::endl;
			out_file << L_ << std::endl;
			out_file << "--------------------------------------------------------------------" << std::endl;
			X = X + x;
			out_file << "改正后的参数矩阵为(单位米):" << std::endl;
			out_file << X << std::endl;
			out_file << "--------------------------------------------------------------------" << std::endl;

		}
		else {
			QMessageBox::critical(this, "warning", "The outfile is not opened!"); return 0;
		};
		out_file.close();
		return 0;

}

leveling_network::~leveling_network()
{}

输出文件(部分)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值