观测文件、星历文件合、修改、重采样等功能大家通常都会用gfzrnx,一但文件比较多,使用起来就稍微有点麻烦
这里分享一个py写的小脚本,大家可以根据自己的需求修改
第一步首先将gfzrnx.exe windos版和gfzrnxtool.py放到一个文件夹下
程序会自动找到exe文件,如果没有找到可以指定路径
第二步选择需要的功能
以文件合并为例 程序会自动找到文件夹下以o结尾的观测文件,合并星历同理 找到以n l c q结尾的文件进行合并
import os
import subprocess
from datetime import datetime, timedelta
from PyQt5 import QtCore, QtGui, QtWidgets
# Helper function to retrieve all files ending in "o"
def get_o_files(directory):
return [f for f in os.listdir(directory) if f.endswith('o')]
# Helper function to retrieve all files ending in "n" or "g" "l" or "c"
def get_nav_files(directory):
return [f for f in os.listdir(directory) if f.endswith('n') or f.endswith('g') or f.endswith('c') or f.endswith('l')]
# Command to split file
def run_gfzrnx(input_file, start_time_str, duration, directory):
input_path = os.path.join(directory, input_file)
output_file = "split_" + input_file
output_path = os.path.join(directory, output_file)
command = f'gfzrnx -finp "{input_path}" -epo_beg {start_time_str} -d {duration} -kv > "{output_path}"'
return command
# Command to convert file version
def run_version_conversion(input_file, version, directory):
input_path = os.path.join(directory, input_file)
output_file = "convert_" + input_file
output_path = os.path.join(directory, output_file)
command = f'gfzrnx -finp "{input_path}" -vo {version} > "{output_path}"'
return command
# Command to merge files
def run_file_merge(files, directory):
input_files = ' '.join([f'"{os.path.join(directory, f)}"' for f in files])
output_file = "merge_" + files[0]
output_path = os.path.join(directory, output_file)
command = f'gfzrnx -finp {input_files} -kv > "{output_path}"'
return command
# Command to merge ephemeris files
def run_ephemeris_merge(files, directory):
input_files = ' '.join([f'"{os.path.join(directory, f)}"' for f in files])
output_file = "merged_ephemeris.nav"
output_path = os.path.join(directory, output_file)
command = f'gfzrnx -finp {input_files} -kv > "{output_path}"'
return command
# Command to exclude satellite by PRNs
def run_satellite_edit(input_file, prns, directory):
input_path = os.path.join(directory, input_file)
output_file = "edit_" + input_file
output_path = os.path.join(directory, output_file)
command = f'gfzrnx -finp "{input_path}" -no_prn {prns} -kv > "{output_path}"'
return command
# Command to resample file
def run_file_smp(input_file, smp_str, directory):
input_path = os.path.join(directory, input_file)
output_file = "smp_" + smp_str + "_" + input_file
output_path = os.path.join(directory, output_file)
command = f'gfzrnx -finp "{input_path}" -smp {smp_str} -kv > "{output_path}"'
return command
# Convert GPS time to UTC
def gps_to_utc(year, week, seconds):
gps_epoch = datetime(1980, 1, 6)
total_seconds = week * 7 * 24 * 3600 + seconds
utc_time = gps_epoch + timedelta(seconds=total_seconds)
return utc_time
# Custom dialog to input time in components
class TimeInputDialog(QtWidgets.QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.initUI()
def initUI(self):
layout = QtWidgets.QFormLayout()
# Adding inputs for each component of time
self.year_input = QtWidgets.QSpinBox()
self.year_input.setRange(1980, 2100)
self.year_input.setValue(datetime.now().year)
layout.addRow("年:", self.year_input)
self.month_input = QtWidgets.QSpinBox()
self.month_input.setRange(1, 12)
self.month_input.setValue(datetime.now().month)
layout.addRow("月:", self.month_input)
self.day_input = QtWidgets.QSpinBox()
self.day_input.setRange(1, 31)
self.day_input.setValue(datetime.now().day)
layout.addRow("日:", self.day_input)
self.hour_input = QtWidgets.QSpinBox()
self.hour_input.setRange(0, 23)
layout.addRow("小时:", self.hour_input)
self.minute_input = QtWidgets.QSpinBox()
self.minute_input.setRange(0, 59)
layout.addRow("分钟:", self.minute_input)
self.second_input = QtWidgets.QSpinBox()
self.second_input.setRange(0, 59)
layout.addRow("秒:", self.second_input)
# Adding dialog buttons
button_box = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel)
button_box.accepted.connect(self.accept)
button_box.rejected.connect(self.reject)
layout.addRow(button_box)
self.setLayout(layout)
self.setWindowTitle("输入起始时间")
def get_time(self):
year = self.year_input.value()
month = self.month_input.value()
day = self.day_input.value()
hour = self.hour_input.value()
minute = self.minute_input.value()
second = self.second_input.value()
start_time = datetime(year, month, day, hour, minute, second)
return start_time.strftime('%Y-%m-%d_%H:%M:%S')
# Main GFZRNX Tool GUI
class GFZRNXTool(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.find_gfzrnx_exe() # Automatically find gfzrnx.exe on startup
def initUI(self):
layout = QtWidgets.QVBoxLayout()
self.label = QtWidgets.QLabel("请选择功能:")
layout.addWidget(self.label)
# Adding feature buttons
self.button1 = QtWidgets.QPushButton("文件切割")
self.button1.clicked.connect(self.file_split)
layout.addWidget(self.button1)
self.button2 = QtWidgets.QPushButton("文件版本转换")
self.button2.clicked.connect(self.file_version_conversion)
layout.addWidget(self.button2)
self.button3 = QtWidgets.QPushButton("文件合并")
self.button3.clicked.connect(self.file_merge)
layout.addWidget(self.button3)
self.button4 = QtWidgets.QPushButton("删除卫星")
self.button4.clicked.connect(self.satellite_edit)
layout.addWidget(self.button4)
self.button5 = QtWidgets.QPushButton("文件重采样")
self.button5.clicked.connect(self.file_smp)
layout.addWidget(self.button5)
self.button6 = QtWidgets.QPushButton("星历合并")
self.button6.clicked.connect(self.ephemeris_merge)
layout.addWidget(self.button6)
# Command output display
self.command_label = QtWidgets.QLabel("生成的命令:")
layout.addWidget(self.command_label)
self.command_text = QtWidgets.QTextEdit()
self.command_text.setReadOnly(True)
layout.addWidget(self.command_text)
self.setLayout(layout)
self.setWindowTitle('GFZRNX 工具')
self.setGeometry(800, 800, 800, 500)
# Automatically search for gfzrnx.exe
def find_gfzrnx_exe(self):
current_dir = os.path.dirname(os.path.abspath(__file__))
gfzrnx_path = None
# Check current and parent directories for gfzrnx.exe
if 'gfzrnx.exe' in os.listdir(current_dir):
gfzrnx_path = os.path.join(current_dir, 'gfzrnx.exe')
else:
parent_dir = os.path.abspath(os.path.join(current_dir, '..'))
if 'gfzrnx.exe' in os.listdir(parent_dir):
gfzrnx_path = os.path.join(parent_dir, 'gfzrnx.exe')
# If not found, prompt user to select gfzrnx.exe
if gfzrnx_path:
self.gfzrnx_exe_path = gfzrnx_path
self.gfzrnx_directory = os.path.dirname(gfzrnx_path)
QtWidgets.QMessageBox.information(self, "信息", f"找到 gfzrnx.exe: {self.gfzrnx_exe_path}")
else:
QtWidgets.QMessageBox.critical(self, "错误", "无法找到 gfzrnx.exe,请手动选择路径")
self.select_gfzrnx_exe()
# Manual selection of gfzrnx.exe if not automatically found
def select_gfzrnx_exe(self):
file, _ = QtWidgets.QFileDialog.getOpenFileName(self, "选择 gfzrnx.exe 文件", "", "Executable Files (gfzrnx.exe)")
if file:
self.gfzrnx_exe_path = file
self.gfzrnx_directory = os.path.dirname(file)
QtWidgets.QMessageBox.information(self, "信息", f"找到 gfzrnx.exe: {self.gfzrnx_exe_path}")
else:
self.gfzrnx_exe_path = None
self.gfzrnx_directory = None
# Select observation file
def select_obs_file(self):
options = QtWidgets.QFileDialog.Options()
file, _ = QtWidgets.QFileDialog.getOpenFileName(self, "选择观测文件", "", "All Files (*);;Observation Files (*.o)", options=options)
if file:
self.obs_file = file
self.obs_directory = os.path.dirname(file)
else:
self.obs_file = None
# Select observation directory
def select_obs_directory(self):
directory = QtWidgets.QFileDialog.getExistingDirectory(self, "选择观测文件所在文件夹")
if directory:
self.obs_directory = directory
else:
self.obs_directory = None
# File split functionality
def file_split(self):
self.select_obs_file()
if not hasattr(self, 'obs_file') or self.obs_file is None:
return
time_dialog = TimeInputDialog(self)
if time_dialog.exec_() == QtWidgets.QDialog.Accepted:
start_time_str = time_dialog.get_time()
duration, ok2 = QtWidgets.QInputDialog.getInt(self, "输入", "请输入持续时间 (秒):", 3600, 1, 86400)
if not ok2:
return
command = run_gfzrnx(os.path.basename(self.obs_file), start_time_str, duration, self.obs_directory)
self.command_text.setText(command)
self.execute_command(command)
# File version conversion functionality
def file_version_conversion(self):
self.select_obs_file()
if not hasattr(self, 'obs_file') or self.obs_file is None:
return
version, ok = QtWidgets.QInputDialog.getText(self, "输入", "请输入目标版本(2, 3 或 4):")
if not ok or version not in ['2', '3', '4']:
QtWidgets.QMessageBox.critical(self, "错误", "无效的版本号")
return
command = run_version_conversion(os.path.basename(self.obs_file), version, self.obs_directory)
self.command_text.setText(command)
self.execute_command(command)
# File merge functionality
def file_merge(self):
self.select_obs_directory()
if not hasattr(self, 'obs_directory') or self.obs_directory is None:
return
o_files = get_o_files(self.obs_directory)
if not o_files:
QtWidgets.QMessageBox.information(self, "信息", "没有找到以 o 结尾的文件")
return
command = run_file_merge(o_files, self.obs_directory)
self.command_text.setText(command)
self.execute_command(command)
# Satellite exclusion functionality
def satellite_edit(self):
self.select_obs_file()
if not hasattr(self, 'obs_file') or self.obs_file is None:
return
prns, ok = QtWidgets.QInputDialog.getText(self, "输入", "请输入PRN列表 (如 G01,G02):")
if not ok:
return
command = run_satellite_edit(os.path.basename(self.obs_file), prns, self.obs_directory)
self.command_text.setText(command)
self.execute_command(command)
# File resampling functionality
def file_smp(self):
self.select_obs_file()
if not hasattr(self, 'obs_file') or self.obs_file is None:
return
smp_str, ok = QtWidgets.QInputDialog.getText(self, "输入", "请输入重采样率 (秒):")
if not ok:
return
command = run_file_smp(os.path.basename(self.obs_file), smp_str, self.obs_directory)
self.command_text.setText(command)
self.execute_command(command)
# Ephemeris merge functionality
def ephemeris_merge(self):
self.select_obs_directory()
if not hasattr(self, 'obs_directory') or self.obs_directory is None:
return
nav_files = get_nav_files(self.obs_directory)
if not nav_files:
QtWidgets.QMessageBox.information(self, "信息", "没有找到以 n 、 g 、c 、l结尾的星历文件")
return
command = run_ephemeris_merge(nav_files, self.obs_directory)
self.command_text.setText(command)
self.execute_command(command)
# Helper function to execute the command and handle output
def execute_command(self, command):
try:
result = subprocess.run(command, shell=True, check=True, cwd=self.gfzrnx_directory, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdout_output = result.stdout.decode('utf-8', errors='ignore')
stderr_output = result.stderr.decode('utf-8', errors='ignore')
QtWidgets.QMessageBox.information(self, "信息", f"处理完成\nstdout: {stdout_output}\nstderr: {stderr_output}")
except subprocess.CalledProcessError as e:
try:
stderr_output = e.stderr.decode("utf-8")
except UnicodeDecodeError:
stderr_output = e.stderr.decode("gbk", errors='ignore')
QtWidgets.QMessageBox.critical(self, "错误", f"执行命令时出错\nstderr: {stderr_output}")
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
ex = GFZRNXTool()
ex.show()
sys.exit(app.exec_())
脚本下载