Archived
668 lines
28 KiB
Python
668 lines
28 KiB
Python
# @ File : Func_callback.py
|
|
#
|
|
# Copyright (c) 2024 KenanZhu. All Right Reserved.
|
|
#
|
|
# @ Author : KenanZhu
|
|
# @ Time : 2024/11/04
|
|
# @ Brief : Interactive control callback function class.
|
|
# #
|
|
# @ IDE : PyCharm 2024.2.1 (Community Edition)
|
|
#
|
|
# ----------------------------------------------------------------------------------------
|
|
|
|
### Std
|
|
import math
|
|
import threading
|
|
|
|
import numpy as np
|
|
import ctypes as ct
|
|
import tkinter as tk
|
|
import cartopy.crs as ccrs
|
|
|
|
from tkinter import filedialog
|
|
from tkinter import colorchooser
|
|
|
|
class CALLBACK:
|
|
def __init__(self, cfg, cfg_get):
|
|
# init
|
|
# -------------------------------------------------------------------------------
|
|
self.cfg = cfg
|
|
self.cfg_get = cfg_get
|
|
|
|
self.system = {1:'G',2:'C',3:'E',4:'R',5:'S'}
|
|
self.ioncormode = {'OFF':'0', 'Ion-Free LC':'1', 'Broadcast':'2'}
|
|
self.trocormode = {'OFF':'0', 'Hopfield':'1', 'Saastamoinen':'2'}
|
|
|
|
self.colorvalue = [
|
|
self.cfg_get['Options_Draw']['e_color'],
|
|
self.cfg_get['Options_Draw']['n_color'],
|
|
self.cfg_get['Options_Draw']['u_color'],
|
|
self.cfg_get['Options_Draw']['sat_amount_color']
|
|
]
|
|
self.linewidth = [
|
|
self.cfg_get['Options_Draw']['e_line'],
|
|
self.cfg_get['Options_Draw']['n_line'],
|
|
self.cfg_get['Options_Draw']['u_line']
|
|
]
|
|
|
|
self.obsvar = ('',)
|
|
self.navvar = ('',)
|
|
self.outvar = ('',)
|
|
|
|
self.outdir = dict(self.cfg_get.items('Output_Path'))
|
|
self.obspath = dict(self.cfg_get.items('Input_Obs_Path'))
|
|
self.navpath = dict(self.cfg_get.items('Input_Nav_Path'))
|
|
|
|
for i in self.obspath:
|
|
if self.obspath.get(i):
|
|
self.obsvar += (self.obspath.get(i),)
|
|
|
|
for i in self.navpath:
|
|
if self.navpath.get(i):
|
|
self.navvar += (self.navpath.get(i),)
|
|
|
|
for i in self.outdir:
|
|
if self.outdir.get(i):
|
|
self.outvar += (self.outdir.get(i),)
|
|
### Const value
|
|
global blank
|
|
blank = ' '
|
|
|
|
@staticmethod
|
|
def Move_center(hwnd, win_x, win_y):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: Move_Ccenter
|
|
# Brief : Move the window to the center of screen.
|
|
# Param : hwnd : instance handle of window
|
|
# win_x: the x size of window
|
|
# win_y: the y size of window
|
|
# Return: none
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
position_x = int((hwnd.winfo_screenwidth() - win_x) / 2)
|
|
position_y = int((hwnd.winfo_screenheight() - win_y) / 2)
|
|
hwnd.geometry(f'{win_x}x{win_y}+{position_x}+{position_y}')
|
|
|
|
def Calcuconfirm(self, cionbox, ctrobox, canglebox, systemv,
|
|
trackprn, trackint):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: Calcuconfirm
|
|
# Brief : Callback function of confirm button of options window
|
|
# Param : cionbox : iono combobox handle
|
|
# ctrobox : trop combobox handle
|
|
# canglabox: elev angle of sat combobox handle
|
|
# systemv : sat system button handle
|
|
# Return: none
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
|
|
self.cfg_get.set('Options_Calc', 'Iono_model', self.ioncormode.get(cionbox.get()))
|
|
self.cfg_get.set('Options_Calc', 'Trop_model', self.trocormode.get(ctrobox.get()))
|
|
self.cfg_get.set('Options_Calc', 'Elev_angle', canglebox.get())
|
|
self.cfg_get.set('Options_Calc', 'Sat_system', str(systemv.get()))
|
|
self.cfg_get.set('Options_Draw', 'Track of prn', trackprn.get())
|
|
self.cfg_get.set('Options_Draw', 'Track sample rate', trackint.get())
|
|
|
|
self.cfg.save_config()
|
|
|
|
def Colorchoose(self, hwndparent, i, colorlab, mode):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: Colorchoose
|
|
# Brief : Color choose card of options callback function.
|
|
# Param : hwndparent : instance handle of options window
|
|
# i : 0==e & 1==n & 2==u & 3==satn
|
|
# colorlab : color label handle
|
|
# mode : 0==undo & 1==select & 2==save change
|
|
# Return: none
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
match mode:
|
|
case 0:
|
|
if not i==3:
|
|
self.colorvalue = [
|
|
self.cfg_get['Options_Draw']['e_color'],
|
|
self.cfg_get['Options_Draw']['n_color'],
|
|
self.cfg_get['Options_Draw']['u_color'],
|
|
self.colorvalue[3]
|
|
]
|
|
colorlab.config(bg=self.colorvalue[i])
|
|
else:
|
|
self.colorvalue = [
|
|
self.colorvalue[0],
|
|
self.colorvalue[1],
|
|
self.colorvalue[2],
|
|
self.cfg_get['Options_Draw']['sat_amount_color']
|
|
]
|
|
colorlab.config(bg=self.colorvalue[i])
|
|
case 1:
|
|
colorvalue = tk.colorchooser.askcolor(parent=hwndparent)
|
|
if colorvalue[1]:
|
|
self.colorvalue[i] = str(colorvalue[1])
|
|
colorlab.config(bg=self.colorvalue[i])
|
|
case 2:
|
|
self.cfg_get.set('Options_Draw', 'E_Color', str(self.colorvalue[0]))
|
|
self.cfg_get.set('Options_Draw', 'N_Color', str(self.colorvalue[1]))
|
|
self.cfg_get.set('Options_Draw', 'U_Color', str(self.colorvalue[2]))
|
|
self.cfg_get.set('Options_Draw', 'Sat_Amount_Color', str(self.colorvalue[3]))
|
|
self.cfg.save_config()
|
|
|
|
def Linewchoose(self, entry0, entry1, entry2, mode):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: Linewchoose
|
|
# Brief : Line width selection of plot.
|
|
# Param : entry0 : spinbox handle
|
|
# entry1 : spinbox handle
|
|
# entry2 : spinbox handle
|
|
# mode : 0==undo & 1==confirm
|
|
# Return: none
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
match mode:
|
|
case 0:
|
|
entry0.set(self.cfg_get['Options_Draw']['e_line'])
|
|
entry1.set(self.cfg_get['Options_Draw']['n_line'])
|
|
entry2.set(self.cfg_get['Options_Draw']['u_line'])
|
|
case 1:
|
|
self.cfg_get.set('Options_Draw', 'E_Line', str(entry0.get()))
|
|
self.cfg_get.set('Options_Draw', 'N_Line', str(entry1.get()))
|
|
self.cfg_get.set('Options_Draw', 'U_Line', str(entry2.get()))
|
|
self.cfg.save_config()
|
|
|
|
@staticmethod
|
|
def Dir_or_name_get(path, mode):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: Dir_or_name_get
|
|
# Brief : Get the filedir or filename form path
|
|
# Param : path : file path
|
|
# mode : 0==get file name & 1==get file dir
|
|
# Return: mode==0 return filename,mode==1 return file dir
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
global nameend, filename, filedir
|
|
match mode:
|
|
case 0:
|
|
path_len = len(path)
|
|
while path_len > 0:
|
|
sig = path[path_len - 1:path_len]
|
|
if sig == '.':
|
|
nameend = path_len
|
|
if sig == '\\' or sig == '/':
|
|
filename = path[path_len:nameend]
|
|
return filename
|
|
path_len -= 1
|
|
|
|
|
|
case 1:
|
|
path_len = len(path)
|
|
while path_len > 0:
|
|
sig = path[path_len - 1:path_len]
|
|
if sig == '\\' or sig == '/':
|
|
filedir = path[:path_len]
|
|
return filedir
|
|
path_len -= 1
|
|
|
|
def GetObsFilePath(self, hwndparent, ObsFileSelectBox):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: GetObsFilePath
|
|
# Brief : Get obs file path of RINEX.
|
|
# Param : hwndparent : instance handle of RINEX processor window
|
|
# ObsFileSelectBox : string value of path combobox
|
|
# Return: none
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
path = filedialog.askopenfilename(
|
|
parent=hwndparent,
|
|
title='RINEX OBS File',
|
|
filetypes=[('RINEX OBS File(*.o*.*.*obs.*.*d)', '*.*o;*.*obs;*.*d'),
|
|
('All Files', '*.*')]
|
|
)
|
|
if path and path not in ObsFileSelectBox['value']:
|
|
ObsFileSelectBox['value'] += (path,)
|
|
ObsFileSelectBox.current(len(ObsFileSelectBox['value']) - 1)
|
|
self.obsvar += (path,)
|
|
self.cfg_get.set('Input_Obs_Path', '%s'
|
|
% str(len(ObsFileSelectBox['value']) - 1),
|
|
path)
|
|
self.cfg.save_config()
|
|
|
|
def GetNavFilePath(self, hwndparent, NavFileSelectBox):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: GetNavFilePath
|
|
# Brief : Get nav file path of RINEX.
|
|
# Param : hwndparent : instance handle of RINEX processor window
|
|
# NavFileSelectBox : string value of path combobox
|
|
# Return: none
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
path = filedialog.askopenfilename(
|
|
parent=hwndparent,
|
|
title='RINEX NAV File',
|
|
filetypes=[('RINEX NAV File(*.*nav.*.hnav.*.gnav.*.qnav.*.*n.*.*g.*.*h.*.*q.*.*p)',
|
|
'*.*nav;*.hnav;*.gnav;*.qnav;*.*n;*.*g;*.*h;*.*q;*.*p'),
|
|
('All Files', '*.*')]
|
|
)
|
|
if path and path not in NavFileSelectBox['value']:
|
|
NavFileSelectBox['value'] += (path,)
|
|
NavFileSelectBox.current(len(NavFileSelectBox['value']) - 1)
|
|
self.navvar += (path,)
|
|
self.cfg_get.set('Input_Nav_Path', '%s'
|
|
% str(len(NavFileSelectBox['value']) - 1),
|
|
path)
|
|
self.cfg.save_config()
|
|
|
|
def AskDirectory(self, hwndparent, AskDirectorySelectBox):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: AskDirectory
|
|
# Brief : Get the output file diectory.
|
|
# Param : hwndparent : instance handle of RINEX processor window
|
|
# AskDirectorySelectBox : instance handle of dir combox
|
|
# Return: none
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
path = filedialog.askdirectory(parent=hwndparent)
|
|
if path and path not in AskDirectorySelectBox['value']:
|
|
AskDirectorySelectBox['value'] += (path + '/*.sp',)
|
|
AskDirectorySelectBox.current(len(AskDirectorySelectBox['value']) - 1)
|
|
self.outvar += (path + '/*.sp',)
|
|
self.cfg_get.set('Output_Path', '%s'
|
|
% str(len(AskDirectorySelectBox['value']) - 1),
|
|
path + '/*.sp')
|
|
self.cfg.save_config()
|
|
|
|
@staticmethod
|
|
def AskOrNotCheck(AskOrNotCheckVar,
|
|
AskDirectorySelectBox,
|
|
AskDirectorySelectButton):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: AskOrNotCheck
|
|
# Brief : Check the file diectory.
|
|
# Param : AskOrNotCheckVar : button int value
|
|
# AskDirectorySelectBox : instance handle of dir combobox
|
|
# AskDirectorySelectButton : instance handle dir select button
|
|
# Return: none
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
if AskOrNotCheckVar.get() == 0:
|
|
AskDirectorySelectBox.config(state=tk.DISABLED)
|
|
AskDirectorySelectButton.config(state=tk.DISABLED)
|
|
else:
|
|
AskDirectorySelectBox.config(state=tk.NORMAL)
|
|
AskDirectorySelectButton.config(state=tk.NORMAL)
|
|
|
|
def ExecuteFile(self,
|
|
ExecuteState,
|
|
ObsSelectBoxVar,
|
|
NavSelectBoxVar,
|
|
AskOrNotCheckVar,
|
|
DirectorySelectBoxVar):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: ExecuteFile
|
|
# Brief : Execute RINEX file into .ksln.
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
exten = "ksln"
|
|
statemsg = ""
|
|
state3 = ["","",""]
|
|
if not ObsSelectBoxVar.get():
|
|
state3[0] = " obs file."
|
|
if not NavSelectBoxVar.get():
|
|
state3[1] = " nav file."
|
|
if not DirectorySelectBoxVar.get():
|
|
if AskOrNotCheckVar.get():
|
|
state3[2] = " solution directory."
|
|
for state in state3:
|
|
statemsg += state
|
|
if statemsg:
|
|
ExecuteState.config(text='No file: %s !'%statemsg)
|
|
return 0
|
|
|
|
obspath = ObsSelectBoxVar.get()
|
|
navpath = NavSelectBoxVar.get()
|
|
directory = obspath
|
|
if AskOrNotCheckVar.get():
|
|
directory = DirectorySelectBoxVar.get()
|
|
|
|
|
|
directory = self.Dir_or_name_get(directory, 1)
|
|
syssign = self.system.get(int(self.cfg_get['Options_Calc']['sat_system']))
|
|
if int(self.cfg_get['Options_Draw']['Enable of track'])==1:
|
|
exten="ssln"
|
|
resname = syssign + '-' + self.Dir_or_name_get(obspath,0) + exten
|
|
respath = (directory + resname)
|
|
|
|
ExecuteState.config(text='Processing...... file : %s' %resname)
|
|
|
|
dll = ct.cdll.LoadLibrary('./brdm2pos.dll')
|
|
dll.brdm2pos.restype = ct.c_double
|
|
match dll.brdm2pos(
|
|
navpath.encode(),
|
|
obspath.encode(),
|
|
respath.encode(),
|
|
int(self.cfg_get['Options_Calc']['Sat_system']),
|
|
int(self.cfg_get['Options_Calc']['Elev_angle']),
|
|
int(self.cfg_get['Options_Calc']['Iono_Model']),
|
|
int(self.cfg_get['Options_Calc']['Trop_Model']),
|
|
int(self.cfg_get['Options_Draw']['Enable of track'])
|
|
):
|
|
case 0.0:
|
|
ExecuteState.config(text='Generated successfully ! file : %s' %resname)
|
|
case -1.0:
|
|
ExecuteState.config(text='Error ! cant open nav file')
|
|
case -2.0:
|
|
ExecuteState.config(text='Error ! cant open obs file')
|
|
case -3.0:
|
|
ExecuteState.config(text='Error ! unsupported nav file')
|
|
case -4.0:
|
|
ExecuteState.config(text='Error ! no nav data')
|
|
case -5.0:
|
|
ExecuteState.config(text='Error ! unsupported obs file')
|
|
case -6.0:
|
|
ExecuteState.config(text='Error ! no obs data')
|
|
ct.windll.kernel32.FreeLibrary('./brdm2pos.dll')
|
|
|
|
def _ExecuteFile(self,ExecuteState,
|
|
ObsSelectBoxVar,
|
|
NavSelectBoxVar,
|
|
AskOrNotCheckVar,
|
|
DirectorySelectBoxVar):
|
|
T = threading.Thread(target=lambda: self.ExecuteFile(ExecuteState,
|
|
ObsSelectBoxVar,
|
|
NavSelectBoxVar,
|
|
AskOrNotCheckVar,
|
|
DirectorySelectBoxVar))
|
|
T.start()
|
|
|
|
def OpenkslnFile(self,
|
|
explot,nxplot,uxplot,satnplot,visbplot,
|
|
canvas0,canvas1,plotstate):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method: OpenkslnFile
|
|
# Brief : Plot by open ksln as pos solution.
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
system = self.system.get(int(self.cfg_get['Options_Calc']['sat_system']))
|
|
|
|
path = filedialog.askopenfilename(title='Open as Pos Solution',
|
|
filetypes=[('Solution File(*.ksln)', '*.ksln'),
|
|
('All Files', '*.*')])
|
|
if not path: return
|
|
if not path.find('.ksln'):
|
|
plotstate.config(text='Error : Unsupported format !')
|
|
return
|
|
with open(path,'r')as f:
|
|
while 1:
|
|
line = f.readline()
|
|
if not line: return
|
|
if line.find('APPROX POSITION XYZ')>=0:
|
|
apx = float(line[22:35])
|
|
apy = float(line[35:48])
|
|
apz = float(line[48:61])
|
|
elif line.find('APPROX POSITION BLH')>=0:
|
|
apb = float(line[22:35])
|
|
apl = float(line[35:48])
|
|
aph = float(line[48:61])
|
|
S = np.array([
|
|
[-math.sin(apl) , math.cos(apl) , 0],
|
|
[-math.sin(apb)*math.cos(apl),-math.sin(apb)*math.sin(apl),math.cos(apb)],
|
|
[ math.cos(apb)*math.cos(apl), math.cos(apb)*math.sin(apl),math.sin(apb)]
|
|
])
|
|
elif line.find('INTERVAL')>=0:
|
|
ive = float(line[22:27])
|
|
elif line.find('<END OF HEADER')>=0:
|
|
plotstate.config(text="Reading...")
|
|
break
|
|
satnum = 0
|
|
ENU = np.empty((3,0))
|
|
EPO = np.empty((1,0))
|
|
NUM = np.empty((1,0))
|
|
while 1:
|
|
line = f.readline()
|
|
if not line: return
|
|
if line[0:1]=='>':
|
|
satnum = 0
|
|
EPO = np.hstack((EPO,[[float(line[1:6])]]))
|
|
plotstate.config(text='Reading...%5d/%5d Mode: Single solving'
|
|
%(int(line[1:6]), int(86400/ive)))
|
|
|
|
elif line[0:1]==system:
|
|
if not line.find('END')==-1: pass
|
|
elif not line.find('Rec')==-1: pass
|
|
else:
|
|
satnum += 1
|
|
|
|
elif line.find('Rec:')>=0:
|
|
if line.find('insufficient')>=0:
|
|
ds = np.array([
|
|
[0],
|
|
[0],
|
|
[0]
|
|
])
|
|
else:
|
|
ds = np.array([
|
|
[float(line[ 4:13])],
|
|
[float(line[14:23])],
|
|
[float(line[24:33])]
|
|
])
|
|
ENU = np.hstack((ENU,S@ds))
|
|
NUM = np.hstack((NUM,[[satnum]]))
|
|
if line.find('END')>=0:
|
|
# plot on the e
|
|
# -------------------------------------------------------------------
|
|
explot.clear()
|
|
nxplot.clear()
|
|
uxplot.clear()
|
|
# plot on n
|
|
# -------------------------------------------------------------------
|
|
explot.plot(
|
|
EPO[0, :],
|
|
ENU[0, :],
|
|
marker='.',
|
|
linestyle=':',
|
|
ms=self.cfg_get['Options_Draw']['e_line'],
|
|
color=self.cfg_get['Options_Draw']['e_color'],
|
|
linewidth=self.cfg_get['Options_Draw']['e_line'],
|
|
)
|
|
explot.set_title(' E-W(m)', x=0.02, y=0, fontsize=8)
|
|
explot.grid(True, linestyle='--', alpha=0.7)
|
|
# plot on u
|
|
# -------------------------------------------------------------------
|
|
nxplot.plot(
|
|
EPO[0, :],
|
|
ENU[1, :],
|
|
marker='.',
|
|
linestyle=':',
|
|
ms=self.cfg_get['Options_Draw']['n_line'],
|
|
color=self.cfg_get['Options_Draw']['n_color'],
|
|
linewidth=self.cfg_get['Options_Draw']['n_line'],
|
|
)
|
|
nxplot.set_title(' N-S(m)', x=0.02, y=0, fontsize=8)
|
|
nxplot.grid(True, linestyle='--', alpha=0.7)
|
|
# plot on u
|
|
# -------------------------------------------------------------------
|
|
uxplot.plot(
|
|
EPO[0, :],
|
|
ENU[2, :],
|
|
marker='.',
|
|
linestyle=':',
|
|
ms=self.cfg_get['Options_Draw']['u_line'],
|
|
color=self.cfg_get['Options_Draw']['u_color'],
|
|
linewidth=self.cfg_get['Options_Draw']['u_line'],
|
|
)
|
|
uxplot.set_title(' U-D(m)', x=0.02, y=0, fontsize=8)
|
|
uxplot.grid(True, linestyle='--', alpha=0.7)
|
|
canvas0.draw()
|
|
|
|
satnplot.clear()
|
|
satnplot.plot(
|
|
EPO[0, :],
|
|
NUM[0, :],
|
|
ms=5,
|
|
marker='|',
|
|
linewidth=0,
|
|
linestyle=None,
|
|
color=self.cfg_get['Options_Draw']['sat_amount_color'],
|
|
)
|
|
satnplot.set_title('Valid Satellite Numbers', loc='left', fontsize=8)
|
|
satnplot.set_xlabel('Epochs')
|
|
satnplot.grid(True, linestyle='--', alpha=0.7)
|
|
canvas1.draw()
|
|
|
|
f.close()
|
|
|
|
plotstate.config(text="Plot form: %s" % path)
|
|
break
|
|
|
|
def _OpenkslnFile(self,
|
|
explot, nxplot, uxplot, satnplot, visbplot,
|
|
canvas0, canvas1, plotstate):
|
|
T = threading.Thread(
|
|
target=lambda :self.OpenkslnFile(
|
|
explot,nxplot,uxplot,satnplot,visbplot,
|
|
canvas0,canvas1,plotstate)
|
|
)
|
|
T.start()
|
|
|
|
def Plot2polar(self, sattrack, plotstate, canvas2):
|
|
# -------------------------------------------------------------------------------
|
|
# >
|
|
# Method:
|
|
# Brief :
|
|
# Author: @KenanZhu All Right Reserved.
|
|
# -------------------------------------------------------------------------------
|
|
if self.cfg_get['Options_Draw']['Enable of track']=='0':
|
|
plotstate.config(text="Track plot is not avaliable now, Please enable it.")
|
|
return
|
|
satprn = int(self.cfg_get['Options_Draw']['Track of prn'])
|
|
anirat = int(self.cfg_get['Options_Draw']['Track sample rate'])
|
|
system = self.system.get(int(self.cfg_get['Options_Calc']['sat_system']))
|
|
|
|
path = filedialog.askopenfilename(title='Open as Sat Solution',
|
|
filetypes=[('Solution File(*.ssln)', '*.ssln'),
|
|
('All Files', '*.*')])
|
|
if not path: return
|
|
if not path.find('.ssln')>=0:
|
|
plotstate.config(text="Error : Unsupported format !")
|
|
return
|
|
with open(path,'r') as f:
|
|
while 1:
|
|
line = f.readline()
|
|
if not line: return
|
|
if line.find('APPROX POSITION BLH')>=0:
|
|
sattrack.clear()
|
|
apb = math.degrees( float(line[22:35]) )
|
|
apl = math.degrees( float(line[35:48]) )
|
|
plotstate.config(text="Plotting...")
|
|
sattrack.scatter(
|
|
apl,
|
|
apb,
|
|
color='r',
|
|
s=35,
|
|
transform=ccrs.PlateCarree()
|
|
)
|
|
sattrack.text(
|
|
apl,
|
|
apb,
|
|
blank*4+marker,
|
|
color='k',
|
|
fontsize=10,
|
|
fontweight='bold',
|
|
transform=ccrs.PlateCarree()
|
|
)
|
|
canvas2.draw()
|
|
elif line.find('GENERATE SOURCE')>=0:
|
|
marker = line[22:26]
|
|
elif line.find('TIME OF FIRST OBS')>=0:
|
|
yea = int(line[22:26])
|
|
mon = int(line[27:29])
|
|
day = int(line[30:32])
|
|
hou = int(line[33:35])
|
|
min = int(line[36:38])
|
|
sec = float(line[39:46])
|
|
elif line.find('INTERVAL')>=0:
|
|
ive = float(line[22:27])
|
|
elif line.find('<END OF HEADER')>=0:
|
|
sattrack.coastlines(resolution='110m')
|
|
sattrack.gridlines(draw_labels=True, dms=True, x_inline=False, y_inline=False)
|
|
sattrack.set_title('Ground Track of %s%02d (GPST: %04d/%02d/%02d/%02d/%02d/%7.04f)'
|
|
%(system,satprn,yea,mon,day,hou,min,sec),
|
|
loc='left',fontsize=14,weight='bold')
|
|
break
|
|
while 1:
|
|
line = f.readline()
|
|
if not line: break
|
|
if line.find('END')>=0: break
|
|
if not str(line[ 0: 1])==system: continue
|
|
if not int(line[ 1: 3])==satprn: continue
|
|
if not int(line[41:46])%anirat==0: continue
|
|
plotstate.config(text="Reading...%5d/%5d Mode: Sat track plot"
|
|
% (int(line[41:46]), int(86400 / ive)))
|
|
# Judge twice
|
|
if not int(line[ 1: 3])==satprn:break
|
|
b = math.degrees( float(line[ 4:13]) )
|
|
l = math.degrees( float(line[14:23]) )
|
|
sattrack.scatter(
|
|
l,
|
|
b,
|
|
color='b',
|
|
s=2,
|
|
transform=ccrs.PlateCarree()
|
|
)
|
|
canvas2.draw()
|
|
|
|
text = sattrack.text(
|
|
l,
|
|
b,
|
|
4*blank+system+'%02d'%satprn,
|
|
color='k',
|
|
fontsize=10,
|
|
fontweight='bold',
|
|
transform=ccrs.PlateCarree()
|
|
)
|
|
point = sattrack.scatter(
|
|
l,
|
|
b,
|
|
color='b',
|
|
s=10,
|
|
transform=ccrs.PlateCarree()
|
|
)
|
|
canvas2.draw()
|
|
text.remove()
|
|
point.remove()
|
|
plotstate.config(text="Done ! Track plot form: sys=%s sat=%2d interval=%2d"
|
|
% (system, satprn, anirat))
|
|
return
|
|
|
|
def _Plot2polar(self, sattrack, plotstate, canvas2):
|
|
T = threading.Thread(
|
|
target=lambda :self.Plot2polar(sattrack, plotstate, canvas2)
|
|
)
|
|
T.start()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|