c++qt窗口程序下的空间直角坐标系、大地坐标系和子午面直角坐标系的相互转换
公式算法前往:
地球坐标系的各坐标系的转换算法_进击中的小龙的博客-优快云博客
项目头文件convert.h(窗口类定义)
#pragma once
#include <QtWidgets/QWidget>
#include "ui_convert.h"
namespace Ui {
class Form;
class convert;
}
class convert : public QWidget
{
Q_OBJECT
public:
convert(QWidget *parent = nullptr);
~convert();
private slots:
void compute();
private:
Ui::convert ui;
};
主函数main.cpp
#include "convert.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
convert w;
w.show();
return a.exec();
}
Ui设计
窗口类构造函数,及自定义计算函数compute()的实现均在convert.cpp中
//---------convert.cpp----------
#include "convert.h"
#include"ui_convert.h"
#include<qpushbutton.h>
#include<qmessagebox.h>
#include<qdebug.h>
#include<cmath>
#define PI acos(-1)
convert::convert(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
//计算函数调用compute函数,此处使用qt4版本的信号和槽函数,qt5可以兼容
connect(ui.pushButton,SIGNAL(clicked()), this, SLOT(compute()));
//清空功能
connect(ui.pushButton_2, &QPushButton::clicked, this, [=]() {
ui.lineEdit->clear();
ui.lineEdit_2->clear();
ui.lineEdit_3->clear();
ui.lineEdit_4->clear();
ui.lineEdit_5->clear();
ui.lineEdit_6->clear();
ui.lineEdit_7->clear();
ui.lineEdit_8->clear();
ui.lineEdit_9->clear();
ui.lineEdit_10->clear();
ui.lineEdit_11->clear();
ui.lineEdit_12->clear();
ui.lineEdit_13->clear();
ui.lineEdit_14->clear();
ui.lineEdit_15->clear();
});
//退出功能
connect(ui.pushButton_3, &QPushButton::clicked, this, &QWidget::close);
}
convert::~convert()
{}
void convert::compute()
{
double L, B, H, X, Y, Z, x, y;
double a = 6378137;//椭圆长半轴
double b = 6356752.3141;//椭圆短半轴
double e_2 = 0.00669438002290;//椭圆第一偏心率e^2
double e_dot_2 = 0.00673949677548;//椭圆第二偏心率e'^2
double c = a * a / b;
double k = 1 + e_dot_2;
int pp = 0;
if (ui.radioButton->isChecked())
{
a = 6378245;//椭圆长半轴
b = 6356863.0187730473;//椭圆短半轴
e_2 = 0.006693421622966;//椭圆第一偏心率e^2
e_dot_2 = 0.006738525414683;//椭圆第二偏心率e'^2
pp = 1;
}
else if (ui.radioButton_2->isChecked())//
{
a = 6378140;//椭圆长半轴
b = 6356755.2881575287;//椭圆短半轴
e_2 = 0.006694384999588;//椭圆第一偏心率e^2
e_dot_2 = 0.006739501819473;//椭圆第二偏心率e'^2
pp = 1;
}
else if (ui.radioButton_3->isChecked())//
{
a = 6378137;//椭圆长半轴
b = 6356752.3142;//椭圆短半轴
e_2 = 0.00669437999013;//椭圆第一偏心率e^2
e_dot_2 = 0.00673949674227;//椭圆第二偏心率e'^2
pp = 1;
}
else if (ui.radioButton_4->isChecked())//
{
a = 6378137;//椭圆长半轴
b = 6356752.3141;//椭圆短半轴
e_2 = 0.00669438002290;//椭圆第一偏心率e^2
e_dot_2 = 0.00673949677548;//椭圆第二偏心率e'^2
pp = 1;
}
else if (pp == 0)
{
QMessageBox::critical(this, "warning", "Please select an ellipsoid");
}
if (!ui.lineEdit->text().isEmpty()&& !ui.lineEdit_2->text().isEmpty()&& !ui.lineEdit_3->text().isEmpty()&&
!ui.lineEdit_4->text().isEmpty() && !ui.lineEdit_5->text().isEmpty() && !ui.lineEdit_6->text().isEmpty()
&& !ui.lineEdit_7->text().isEmpty() )//已知大地坐标系
{
L = (ui.lineEdit->text().toDouble() + ui.lineEdit_4->text().toDouble() / 60 + ui.lineEdit_6->text().toDouble() / 3600) / 180 * PI;
B = (ui.lineEdit_2->text().toDouble() + ui.lineEdit_5->text().toDouble() / 60 + ui.lineEdit_7->text().toDouble() / 3600) / 180 * PI;
H = ui.lineEdit_3->text().toDouble();
double W = sqrt(1 - e_2 * sin(B) * sin(B));
double V = sqrt(1 + e_dot_2 * cos(B ) *cos(B ));
double N = a / W;
//计算空间直角坐标系
X = (N + H)*cos(B ) * cos(L );
Y = (N + H) * cos(B) * sin(L );
Z = (N*(1 - e_2) + H)*sin(B);
ui.lineEdit_13->setText(QString::number(X,'f',4));
ui.lineEdit_14->setText(QString::number(Y, 'f', 4));
ui.lineEdit_15->setText(QString::number(Z, 'f', 4));
//计算子午面直角坐标系
x = X / cos(L);
y = Z;
//打印经度
ui.lineEdit_8->setText(ui.lineEdit->text());
ui.lineEdit_9->setText(ui.lineEdit_4->text());
ui.lineEdit_10->setText(ui.lineEdit_6->text());
//
ui.lineEdit_11->setText(QString::number(x, 'f', 4));
ui.lineEdit_12->setText(QString::number(y, 'f', 4));
}
else if (!ui.lineEdit_8->text().isEmpty() && !ui.lineEdit_9->text().isEmpty() && !ui.lineEdit_10->text().isEmpty() &&
!ui.lineEdit_11->text().isEmpty() && !ui.lineEdit_12->text().isEmpty() )//已知子午面直角坐标系
{
L = (ui.lineEdit_8->text().toDouble() + ui.lineEdit_9->text().toDouble() / 60 + ui.lineEdit_10->text().toDouble() / 3600) / 180 * PI;
x = ui.lineEdit_11->text().toDouble();
y = ui.lineEdit_12->text().toDouble();
//计算空间直角坐标系
X = x * cos(L );
Y = x * sin(L );
Z = y;
ui.lineEdit_13->setText(QString::number(X, 'f', 4));
ui.lineEdit_14->setText(QString::number(Y, 'f', 4));
ui.lineEdit_15->setText(QString::number(Z, 'f', 4));
//计算大地坐标系
double tan0 = Z /sqrt(X *X + Y * Y);
double P = c * e_2 / sqrt(X * X + Y * Y);
double tanB = tan0, cha;//循环迭代
do
{
cha = tanB;
tanB = tan0 + P * cha / sqrt(k + cha * cha);
} while (abs(cha - tanB) > pow(10, -10));
B =atan(tanB);
double W = sqrt(1 - e_2 * sin(B) * sin(B));
double V = sqrt(1 + e_dot_2 * cos(B) * cos(B));
double N = a / W;
H = sqrt(X * X + Y * Y) / cos(B) - N;
//打印经度
L = L * 180 / PI;
ui.lineEdit->setText(QString::number((int)(L)));
ui.lineEdit_4->setText(QString::number((int)((L - (int)(L)) * 60)));
ui.lineEdit_6->setText(QString::number(((L - (int)(L)) * 60 - (int)((L - (int)(L)) * 60)) * 60));
//打印纬度
ui.lineEdit_2->setText(QString::number((int)(B)));
ui.lineEdit_5->setText(QString::number((int)((B - (int)(B)) * 60)));
ui.lineEdit_7->setText(QString::number(((B- (int)(B)) * 60 - (int)((B - (int)(B)) * 60)) * 60));
//
ui.lineEdit_3->setText(QString::number(H,'f',4));
}
else if (!ui.lineEdit_13->text().isEmpty() && !ui.lineEdit_14->text().isEmpty() && !ui.lineEdit_15->text().isEmpty())//已知空间直角坐标系
{
X = ui.lineEdit_13->text().toDouble();;
Y = ui.lineEdit_14->text().toDouble();;
Z = ui.lineEdit_15->text().toDouble();;
//计算大地坐标系
L = atan(Y / X);
double tan0 = Z /sqrt(X * X + Y * Y);
double P = c * e_2 / sqrt(X * X + Y * Y);
double tanB = tan0, cha;//循环迭代
do
{
cha = tanB;
tanB = tan0 + P * cha / sqrt(k + cha * cha);
} while (abs(cha - tanB) > pow(10, -10));
B = atan(tanB);
double W = sqrt(1 - e_2 *sin(B) * sin(B));
double V = sqrt(1 + e_dot_2 *cos(B) * cos(B));
double N = a / W;
H = sqrt(X * X + Y * Y) /cos(B) - N;
//打印经度
ui.lineEdit->setText(QString::number((int)(L*180/PI)));
ui.lineEdit_4->setText(QString::number((int)((L * 180 / PI - (int)(L * 180 / PI)) * 60)));
ui.lineEdit_6->setText(QString::number(((L * 180 / PI - (int)(L * 180 / PI)) * 60 - floor((L * 180 / PI - (int)(L * 180 / PI)) * 60)) * 60));
//打印纬度
B = B * 180 / PI;
ui.lineEdit_2->setText(QString::number((int)(B)));
ui.lineEdit_5->setText(QString::number((int)((B - (int)(B)) * 60)));
ui.lineEdit_7->setText(QString::number(((B - (int)(B)) * 60 - (int)((B - (int)(B)) * 60)) * 60));
//
ui.lineEdit_3->setText(QString::number(H,'f',4));
//计算子午面直角坐标系
x = X / cos(L);
y = Z;
L = L * 180 / PI;
// 打印经度
ui.lineEdit_8->setText(QString::number((int)(L)));
ui.lineEdit_9->setText(QString::number((int)((L - (int)(L)) * 60)));
ui.lineEdit_10->setText(QString::number(((L - (int)(L)) * 60 - (int)((L - (int)(L)) * 60)) * 60));
//
ui.lineEdit_11->setText(QString::number(x, 'f', 4));
ui.lineEdit_12->setText(QString::number(y, 'f', 4));
}