一、前言
这次的高斯正反算程序是使用的Python编写的。
环境信息是:Win10、PyCharm 2021.3.1、PySide6 6.3.1、Python 3.9.9,基于QT Designer设置图形界面。
具体的设置CSDN上都有,我也是看了其他人的教程设置的,最需要注意的就是版本了,因为不同版本有些包就运行不了,还可能遇到其他奇怪的错误。可以自行搜索一下。
二、代码界面展示
这个使用的QT Designer设计的,包用的是PySide6 6.3.1,控件包括:按钮,下拉列表框,文本框,
标签 。
三、代码运算结果展示
- 数据结果采用国家统一坐标(横坐标上加上500000m,在坐标前面冠以带号)。
- 内置了4种椭球参数(CGCS200,WGS84,西安80,克拉索夫斯基椭球体)。
- 可以计算三度带和六度带。
- 计算后的结果直接显示在文本框里面
3.1 数据相互转换验证
相互转换结果是一致的(其实公式就是根据我C#高斯正反算改编的,结果肯定是一样的)
3.2 数据结果正确性验证
3.2.1 高斯正算
因为运算公式都是一样的,所以数据结果的正确性就按照C#的来,还是展示一下吧。同样椭球参数选择西安80。
3.2.2 高斯反算
Python我保留的是3位,C#保留的两位
四、源代码
from PySide6.QtWidgets import QApplication, QMessageBox
from PySide6.QtUiTools import QUiLoader
import sys
import math
def AngleConversion(Angle): # 角度转换
degrees = (180 / math.pi) * Angle
d = int(degrees)
f = int((degrees - d) * 60)
m = round(((degrees - d) * 60 - f) * 60, 3)
if m == 60:
m = 0
f = f + 1
if f == 60:
f = 0
d = d + 1
return d, f, m
class Stats:
def __init__(self):
self.ui = QUiLoader().load('ui.ui')
# 窗体添加图标
self.ui.pushButton.clicked.connect(self.LB2XY)
self.ui.pushButton_2.clicked.connect(self.XY2LB)
def EllipsoidParameter(self): # 选择椭球参数
global a, e1, e2
if self.ui.comboBox.currentText() == 'CGCS2000':
a = 6378137
b = 6356752.3141403558
e1 = (a * a - b * b) / (a * a)
e2 = (a * a - b * b) / (b * b)
elif self.ui.comboBox.currentText() == 'WGS84':
a = 6378137
b = 6356752.3142451795
e1 = (a * a - b * b) / (a * a)
e2 = (a * a - b * b) / (b * b)
elif self.ui.comboBox.currentText() == '1980国家大地坐标系':
a = 6378140
b = 6356755.288157528
e1 = (a * a - b * b) / (a * a)
e2 = (a * a - b * b) / (b * b)
elif self.ui.comboBox.currentText() == '克拉索夫斯基椭球体':
a = 6378245
b = 6356863.0187730473
e1 = (a * a - b * b) / (a * a)
e2 = (a * a - b * b) / (b * b)
# m0 - m8的值
m0 = a * (1 - e1)
m2 = 1.5 * m0 * e1
m4 = 1.25 * m2 * e1
m6 = (7.0 / 6) * m4 * e1
m8 = (9.0 / 8) * m6 * e1
# a0 - a8的值
a0 = m0 + m2 / 2.0 + (3.0 / 8) * m4 + (5.0 / 16) * m6 + (35.0 / 128) * m8
a2 = (1.0 / 2) * (m2 + m4) + (15.0 / 32) * m6 + (7.0 / 16) * m8
a4 = (1.0 / 8) * m4 + (3.0 / 16) * m6 + (7.0 / 32) * m8
a6 = (1.0 / 32) * m6 + (1.0 / 16) * m8
a8 = (1.0 / 128) * m8
return a, e1, e2, a0, a2, a4, a6, a8
def NumberedSelectionBL2XY(self, L): # 大地转高斯带号选择
global N1, L0
if self.ui.comboBox_2.currentText() == '三度带':
N1 = int((L + 1.5) / 3)
L0 = 3 * N1
elif self.ui.comboBox_2.currentText() == '六度带':
N1 = int(L / 6) + 1
L0 = 6 * N1 - 3
return N1, L0
def LB2XY(self):
list1 = self.EllipsoidParameter()
Ld = self.ui.textEdit.toPlainText()
Lf = self.ui.textEdit_2.toPlainText()
Lm = self.ui.textEdit_3.toPlainText()
L = float(Ld) + float(Lf) / 60 + float(Lm) / 3600
Bd = self.ui.textEdit_4.toPlainText()
Bf = self.ui.textEdit_5.toPlainText()
Bm = self.ui.textEdit_6.toPlainText()
B = float(Bd) + float(Bf) / 60 + float(Bm) / 3600
list2 = self.NumberedSelectionBL2XY(L)
# 求椭球面上某点到赤道的子午线弧长,精度至0.001m
radB = (math.pi / 180) * B # 将纬度转换为弧度
delta1 = list1[3] * radB
delta2 = (list1[4] / 2) * math.sin(2 * radB)
delta3 = (list1[5] / 4) * math.sin(4 * radB)
delta4 = (list1[6] / 6) * math.sin(6 * radB)
delta5 = (list1[7] / 8) * math.sin(8 * radB)
X = round(delta1 - delta2 + delta3 - delta4 + delta5, 9)
N = list1[0] / math.sqrt(1 - list1[1] * math.sin(radB) * math.sin(radB))
t = math.tan(radB)
yita = math.sqrt(list1[2]) * math.cos(radB) # η
roum = 180 * 60 * 60 / math.pi # ρm
l = ((L - list2[1]) * 3600) / roum
x = round(float(X) + (N / 2) * t * math.cos(radB) * math.cos(radB) * l * l + (N / 24) * t * (5 - t * t + 9 * yita * yita + 4 * math.pow(yita, 4)) * math.pow(math.cos(radB), 4) * math.pow(l,4) + (N / 720) * t * (61 - 58 * t * t + math.pow(t, 4)) * math.pow(l, 6) * (math.pow(math.cos(radB), 6)), 4)
y = round(N * math.cos(radB) * l + (N / 6.0) * (1 - t * t + yita * yita) * math.pow(math.cos(radB), 3) * math.pow(l,3) + ( N / 120.0) * ( 5 - 18 * t * t + math.pow(t, 4) + 14 * yita * yita - 58 * yita * yita * t * t) * math.pow(math.cos(radB), 5) * math.pow(l, 5) + 500000 + list2[0] * math.pow(10, 6), 4)
self.ui.textEdit_7.setText(str(x))
self.ui.textEdit_8.setText(str(y))
QMessageBox.about(self.ui, '提示', '高斯正算转换完成')
def NumberedSelectionXY2BL(self, aa): # 高斯转大地带号选择
global L1
if self.ui.comboBox_2.currentText() == '三度带':
L1 = 3 * aa
elif self.ui.comboBox_2.currentText() == '六度带':
L1 = 6 * aa - 3
return L1
def XY2LB(self):
global i
list1 = self.EllipsoidParameter()
x = self.ui.textEdit_7.toPlainText()
y1 = self.ui.textEdit_8.toPlainText()
y = float(y1) - int(float(y1) / math.pow(10, 6)) * math.pow(10, 6) - 500000
aa = int((float(y1) / math.pow(10, 6)))
Bf1 = [0] * 20
F = [0] * 20
Bf1[0] = float(x) / list1[3] # 底点纬度
F[0] = (-list1[4] / 2.0) * math.sin(2 * Bf1[0]) + list1[5] / 4.0 * math.sin(4 * Bf1[0]) - list1[
6] / 6.0 * math.sin(6 * Bf1[0])
Bf1[1] = (float(x) - F[0]) / list1[3]
deltad = Bf1[1] - Bf1[0]
for i in range(10):
F[i] = (-list1[4] / 2.0) * math.sin(2 * Bf1[i]) + list1[5] / 4.0 * math.sin(4 * Bf1[i]) - list1[
6] / 6.0 * math.sin(6 * Bf1[i])
Bf1[i + 1] = (float(x) - F[i]) / list1[3]
deltad = Bf1[i + 1] - Bf1[i]
if deltad < math.pow(10, -10):
i += 1
break
tf = math.tan(Bf1[i])
yitaf = list1[2] * math.cos(Bf1[i]) * math.cos(Bf1[i]) # yitaf
Mf = list1[0] * (1 - list1[1]) / math.pow(1 - list1[1] * math.sin(Bf1[i]) * math.sin(Bf1[i]), 1.5)
Nf = list1[0] / math.sqrt(1 - list1[1] * math.sin(Bf1[i]) * math.sin(Bf1[i]))
L1 = self.NumberedSelectionXY2BL(aa)
L = (math.pi / 180) * L1 + y / (Nf * math.cos(Bf1[i])) - (1 + 2 * tf * tf + yitaf) * math.pow(y, 3) / (
6 * math.pow(Nf, 3) * math.cos(Bf1[i])) + (
5 + 28 * tf * tf + 24 * math.pow(tf, 4) + 6 * yitaf + 8 * yitaf * math.pow(tf, 4)) * math.pow(y,
5) / (
120 * math.pow(Nf, 5) * math.cos(Bf1[i]))
list2 = AngleConversion(L)
B = Bf1[i] - (tf * y * y) / (2 * Mf * Nf) + tf * (5 + 3 * tf * tf + yitaf - 9 * yitaf * tf * tf) * math.pow(y,
4) / (
24 * Mf * math.pow(Nf, 3)) + tf * (61 + 90 * tf * tf + 45 * math.pow(tf, 4)) * math.pow(y,
6) / (
720 * Mf * math.pow(Nf, 5))
list3 = AngleConversion(B)
self.ui.textEdit.setText(str(list2[0]))
self.ui.textEdit_2.setText(str(list2[1]))
self.ui.textEdit_3.setText(str(list2[2]))
self.ui.textEdit_4.setText(str(list3[0]))
self.ui.textEdit_5.setText(str(list3[1]))
self.ui.textEdit_6.setText(str(list3[2]))
QMessageBox.about(self.ui, '提示', '高斯反算转换完成')
app = QApplication(sys.argv)
stats = Stats()
stats.ui.show()
sys.exit(app.exec())
五、结语
Python源码就看看计算部分吧,如果想要改窗体还要自己设置QT Designer,Python这个源码改一改可以直接写一个输出结果的程序。而且Python打包的程序都比较大。
我的其他文章:
- 利用C#编写一个高斯正反算程序:https://blog.csdn.net/Zj1638/article/details/125380593
- 利用C#编写一个附和闭合导线简易平差程序:https://blog.csdn.net/Zj1638/article/details/125639541
- 利用C#编写一个水准测量近似平差程序:https://blog.csdn.net/Zj1638/article/details/119303957
- 利用C#编写一个GPS高程拟合(二次曲面拟合模型)程序:https://blog.csdn.net/Zj1638/article/details/125752243
相关下载链接:
- 利用C#编写一个水准测量近似平差程序下载链接:https://download.csdn.net/download/Zj1638/16732130
- 利用C#编写一个附和闭合导线简易平差程序下载链接:https://download.csdn.net/download/Zj1638/85928040
- 利用C#编写一个高斯正反算程序下载链接:https://download.csdn.net/download/Zj1638/85711234
- 利用Python编写一个高斯正反算程序下载链接:https://download.csdn.net/download/Zj1638/86059069
- 利用C#编写一个GPS高程拟合(二次曲面拟合模型)程序下载链接:https://download.csdn.net/download/Zj1638/85916113
需要的可以支持一下。如果有什么不懂的,可以私信,我看到了会回答的。