diff --git a/KNZ_Convert.py b/KNZ_Convert.py index 6a7fe50..1bc6636 100644 --- a/KNZ_Convert.py +++ b/KNZ_Convert.py @@ -27,9 +27,9 @@ I_Box_Counter=0 O_Box_Counter=0 # I_Format_Rnx_List=0 -I_RINEX_BoxList=['2.10','2.11','3.03','3.04','3.05'] +I_RINEX_BoxList=['2','3'] O_Format_Rnx_List=0 -O_RINEX_BoxList=['2.10','2.11','3.03','3.04','3.05'] +O_RINEX_BoxList=['2.10','2.11','2.12','3.00','3.01','3.02','3.03','3.04','3.05'] # --------------------------------------------------------------------------------------- def instanceOPT(parenthwnd, func): OPTIONS(parenthwnd, func) @@ -164,6 +164,9 @@ class CALLBACK: ErrorMsg='' OutDirec='' out_path='' + Pro_style.configure( + 'text.Horizontal.TProgressbar', + text='Converting...') Exec_Progress.config(value=0) if Convertcards.index('current')==0: if not File_I_BoxVar.get(): ErrorMsg+=' path' @@ -181,7 +184,10 @@ class CALLBACK: Pro_style.configure('text.Horizontal.TProgressbar', text=ErrorMsg) return ### - resqueue = queue.Queue() + resqueue=queue.Queue() + Pro_style.configure( + 'text.Horizontal.TProgressbar', + text='Converting...') for in_path in InPath: if OutDirec: out_path=OutDirec+'COV-'+self.Dir_or_name_get(in_path,0) @@ -203,7 +209,7 @@ class CALLBACK: #Exec_Progress.config(value=0) Pro_style.configure( 'text.Horizontal.TProgressbar', - text='Complete ! %d successful, %d fails'%(State_O, len(InPath)-State_O)) + text='Complete ! %d successful. %d fails.'%(State_O, len(InPath)-State_O)) def _Convert( self, @@ -283,13 +289,13 @@ class MAINGUI: def initGUI(self): # ------------------------------------------------------------------------------- # > - # Method: - # Brief : + # Method: initGUI + # Brief : init of main gui # Author: @KenanZhu All Right Reserved. # ------------------------------------------------------------------------------- self.hwnd.title("KNZ_Convert") self.hwnd.resizable(0, 0) - self.func.Move_center(self.hwnd, 400, 230) + self.func.Move_center(self.hwnd, 400, 243) ### icon_ico = (b'AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAADjsAAA47AAAAAAAAAAAAAAAAAAAAAAAAAAAA' b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' @@ -364,16 +370,16 @@ class MAINGUI: def initCONVERT(self): # ------------------------------------------------------------------------------- # > - # Method: - # Brief : + # Method: initCONVERT + # Brief : init of convert gui # Author: @KenanZhu All Right Reserved. # ------------------------------------------------------------------------------- self.Convertcards=tk.ttk.Notebook(self.hwnd) - # + # Single convert # ------------------------------------------------------------------------------- self.SingleConv() self.Convertcards.add(self.SingleFrame, text='Single Convert') - # + # Batch convert # ------------------------------------------------------------------------------- self.BatchConv() self.Convertcards.add(self.BatchFrame, text='Batch Convert') @@ -382,8 +388,8 @@ class MAINGUI: def SingleConv(self): # ------------------------------------------------------------------------------- # > - # Method: - # Brief : + # Method: SingleConv + # Brief : Contrls of single convert # Author: @KenanZhu All Right Reserved. # ------------------------------------------------------------------------------- self.SingleFrame=ttk.Frame(self.hwnd) @@ -414,8 +420,8 @@ class MAINGUI: def BatchConv(self): # ------------------------------------------------------------------------------- # > - # Method: - # Brief : + # Method: BatchConv + # Brief : Contrls of batch convert # Author: @KenanZhu All Right Reserved. # ------------------------------------------------------------------------------- self.BatchFrame=ttk.Frame(self.hwnd) @@ -460,16 +466,16 @@ class MAINGUI: Files_I_ShowFrame, xscrollcommand=ScrollbarX.set, yscrollcommand=ScrollbarY.set, - height=4, wrap='none') - Files_I_ShowText.pack(side=tk.LEFT, fill=tk.X, anchor='w', padx='1px', pady='1px') + height=4, wrap='none', font=('Segoe UI',9)) + Files_I_ShowText.pack(side=tk.LEFT, fill=tk.BOTH, anchor='w', padx='1px', pady='1px') ScrollbarX.config(command=Files_I_ShowText.xview) ScrollbarY.config(command=Files_I_ShowText.yview) def initExecCtrl(self): # ------------------------------------------------------------------------------- # > - # Method: - # Brief : + # Method: initExecCtrl + # Brief : init of contrls # Author: @KenanZhu All Right Reserved. # ------------------------------------------------------------------------------- self.ExecFrame=ttk.Frame(self.hwnd) @@ -484,8 +490,8 @@ class MAINGUI: def ConvOut(self): # ------------------------------------------------------------------------------- # > - # Method: - # Brief : + # Method: ConvOut + # Brief : Contrls of output # Author: @KenanZhu All Right Reserved. # ------------------------------------------------------------------------------- ### @@ -529,8 +535,8 @@ class MAINGUI: def ExecCtrl(self): # ------------------------------------------------------------------------------- # > - # Method: - # Brief : + # Method: ExecCtrl + # Brief : Contrls of exe # Author: @KenanZhu All Right Reserved. # ------------------------------------------------------------------------------- CtrlButtonFrame=ttk.Frame(self.ExecFrame) @@ -577,7 +583,11 @@ class MAINGUI: ('Horizontal.Progressbar.label',{'sticky': ''}) ] ) - self.Pro_style.configure('text.Horizontal.TProgressbar', text='No task.') + self.Pro_style.configure( + 'text.Horizontal.TProgressbar', + text='No task.', + foreground='#000000', + font=('Segoe UI',9)) self.Exec_Progress=ttk.Progressbar( StateFrame, value=0, @@ -604,11 +614,18 @@ class OPTIONS: self.initGUI() def initGUI(self): + # ------------------------------------------------------------------------------- + # > + # Method: initGUI + # Brief : init of main gui + # Author: @KenanZhu All Right Reserved. + # ------------------------------------------------------------------------------- self.opthwnd=tk.Toplevel(self.parenthwnd) self.opthwnd.title("Options") self.opthwnd.resizable(0, 0) self.func.Move_center(self.opthwnd, 310, 110) + ### Set icon icon_ico=(b'AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOrq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6' @@ -629,98 +646,113 @@ class OPTIONS: icon_ico=ImageTk.PhotoImage(data=icon_ico) self.opthwnd.tk.call('wm', 'iconphoto', self.opthwnd._w, icon_ico) + ### Mian frame self.MainFrame=ttk.Frame(self.opthwnd) self.MainFrame.pack() + ### init self.initOPTIONS() self.initEXECTRL() def initOPTIONS(self): + # ------------------------------------------------------------------------------- + # > + # Method: initOPTIONS + # Brief : Init options of format choose + # Author: @KenanZhu All Right Reserved. + # ------------------------------------------------------------------------------- self.OptFrame=ttk.Frame(self.MainFrame) self.OptFrame.pack(side=tk.TOP, fill=tk.BOTH) - # # ------------------------------------------------------------------------------- - I_FormatFrame = tk.LabelFrame( + # Origin format frame + # ------------------------------------------------------------------------------- + I_FormatFrame=tk.LabelFrame( self.OptFrame, text='Origin Format') I_FormatFrame.pack(side=tk.LEFT, expand=tk.YES, padx='2px') + Rnx_I_Frame=ttk.Frame(I_FormatFrame) Rnx_I_Frame.pack(side=tk.TOP, fill=tk.X, pady='2px', padx='2px') - - I_RINEX = ttk.Label( + I_RINEX=ttk.Label( Rnx_I_Frame, text='RINEX:', style='I_RINEX.TLabel') I_RINEX.pack(side=tk.LEFT) - - - self.I_RINEX_Box = ttk.Combobox( + self.I_RINEX_Box=ttk.Combobox( Rnx_I_Frame, width=10, values=I_RINEX_BoxList) self.I_RINEX_Box.set(I_RINEX_BoxList[I_Format_Rnx_List]) + self.I_RINEX_Box['state']='readonly' self.I_RINEX_Box.pack(side=tk.RIGHT) + Rtc_I_Frame=ttk.Frame(I_FormatFrame) Rtc_I_Frame.pack(side=tk.TOP, fill=tk.X, pady='2px', padx='2px') - - I_RTCM = ttk.Label( + I_RTCM=ttk.Label( Rtc_I_Frame, text='RTCM :', style='I_RTCM.TLabel') I_RTCM.pack(side=tk.LEFT) - - I_RTCM_BoxList = ['2.xx', '3.xx', '4.xx'] - I_RTCM_Box = ttk.Combobox( + I_RTCM_BoxList=['2', '3', '4'] + I_RTCM_Box=ttk.Combobox( Rtc_I_Frame, width=10, state=tk.DISABLED, values=I_RTCM_BoxList) I_RTCM_Box.set(I_RTCM_BoxList[0]) + #I_RTCM_Box['state']='readonly' I_RTCM_Box.pack(side=tk.RIGHT) - # + # ------------------------------------------------------------------------------- + # Target format frame # ------------------------------------------------------------------------------- O_FormatFrame = tk.LabelFrame( self.OptFrame, text='Target Format') O_FormatFrame.pack(side=tk.RIGHT, expand=tk.YES, padx='2px') + Rnx_O_Frame=ttk.Frame(O_FormatFrame) Rnx_O_Frame.pack(side=tk.TOP, fill=tk.X, pady='2px', padx='2px') - O_RINEX=ttk.Label( Rnx_O_Frame, text='RINEX:', style='I_RINEX.TLabel') O_RINEX.pack(side=tk.LEFT) - self.O_RINEX_Box=ttk.Combobox( Rnx_O_Frame, width=10, - values=I_RINEX_BoxList) + values=O_RINEX_BoxList) self.O_RINEX_Box.set(O_RINEX_BoxList[O_Format_Rnx_List]) + self.O_RINEX_Box['state']='readonly' self.O_RINEX_Box.pack(side=tk.RIGHT) + Rtc_O_Frame=ttk.Frame(O_FormatFrame) Rtc_O_Frame.pack(side=tk.TOP, fill=tk.X, pady='2px', padx='2px') - O_RTCM=ttk.Label( Rtc_O_Frame, text='RTCM :', style='I_RTCM.TLabel') O_RTCM.pack(side=tk.LEFT) - - O_RTCM_BoxList=['2.xx', '3.xx', '4.xx'] + O_RTCM_BoxList=['2', '3', '4'] O_RTCM_Box=ttk.Combobox( Rtc_O_Frame, width=10, state=tk.DISABLED, values=O_RTCM_BoxList) O_RTCM_Box.set(I_RTCM_BoxList[0]) + #O_RTCM_Box['state']='readonly' O_RTCM_Box.pack(side=tk.RIGHT) def initEXECTRL(self): + # ------------------------------------------------------------------------------- + # > + # Method: initEXECTRL + # Brief : Init the gui of contrl frame + # Author: @KenanZhu All Right Reserved. + # ------------------------------------------------------------------------------- self.ExeFrame=ttk.Frame(self.MainFrame) self.ExeFrame.pack(side=tk.TOP, fill=tk.X, pady='2px', padx='2px') @@ -740,6 +772,12 @@ class OPTIONS: Confirm_Button.pack(side=tk.RIGHT) def Get_IO_Format(self): + # ------------------------------------------------------------------------------- + # > + # Method: Get_IO_Format + # Brief : Get the origin & target file format + # Author: @KenanZhu All Right Reserved. + # ------------------------------------------------------------------------------- global I_Format_Rnx_List, O_Format_Rnx_List I_Format_Rnx_List=I_RINEX_BoxList.index(self.I_RINEX_Box.get()) O_Format_Rnx_List=O_RINEX_BoxList.index(self.O_RINEX_Box.get()) diff --git a/Readme.md b/Readme.md index 71de8c0..b799774 100644 --- a/Readme.md +++ b/Readme.md @@ -21,10 +21,13 @@ do not modify the information. ![image](Convert_chart.png) ### About Project ### -At present, the RINEX2.xx format conversion has been fully supported, +2024/11/14: At present, the RINEX2.xx format conversion has been fully supported, the format output error of the previous version has been modified, and the conversion from 2.xx to 3.xx is currently supported. +2024/11/15: Correct the output format, omit the empty observation and change the +rule of match. + ### Update plan ### 1. 2.xx and 3.xx versions are fully supported, and support mutual conversion. 2. Gradually introduce the conversion support for RTCM files. diff --git a/ReadmeCN.md b/ReadmeCN.md index 2b2e6ee..d658211 100644 --- a/ReadmeCN.md +++ b/ReadmeCN.md @@ -17,7 +17,8 @@ ![image](Convert_chart.png) ### 关于项目 ### -目前已经对RINEX2.xx格式转换进行了全面支持,修改了上一版本的格式输出错误,目前支持2.xx转换为3.xx。 +2024/11/14: 目前已经对RINEX2.xx格式转换进行了全面支持,修改了上一版本的格式输出错误,目前支持2.xx转换为3.xx。 +2024/11/15: 更正了输出格式,忽略空余信号并更改匹配规则 ### 更新计划 ### 1. 2.xx版本与3.xx版本全面支持,支持相互转换。 diff --git a/rnx_convert.py b/rnx_convert.py index 55264e1..87f0e79 100644 --- a/rnx_convert.py +++ b/rnx_convert.py @@ -14,8 +14,15 @@ import time import math import threading +emp='' bnk=' ' + +# Get local time of converting ----------------------- # def conv_time(): + # generate convert timestamp + covpro='KNZ_Convert ver1.2.5' + covtmp='COV-PGM / DATE' + # Get the locate time and transform to RINEX format y=time.localtime().tm_year m=time.localtime().tm_mon @@ -23,113 +30,518 @@ def conv_time(): h=time.localtime().tm_hour min=time.localtime().tm_min sec=time.localtime().tm_sec - localtime=str(y)+str(m)+str(d)+bnk+"%02d"%h+"%02d"%min+"%02d"%sec+bnk+"LLC"+bnk - outline=('KNZ_Convert ver1.2.1'+20*bnk+ - '%s'%localtime+ - 'COV-PGM / DATE\n') + localtime=('%04d'%y + + '%02d'%m + + '%02d'%d +bnk+ + '%02d'%h + + '%02d'%min+ + '%02d'%sec+bnk+ + 'LLC' +bnk) + + outline=(covpro + + 20*bnk + + localtime+ + covtmp + + '\n') + return outline -# ======================================================================================= -# Convert observ type of RINEX 2.xx to others -# ======================================================================================= -def obsfmt_conv(obstype): - match obstype[1:2]: - case '1': - if obstype[0:1]=='P': - obstype='C1P' - else: - obstype+='C' - case '2': - if obstype[0:1]=='P': - obstype='C2P' - else: - obstype+='C' - case '3': pass - case '4': pass - case '5': obstype+='I' - case '6': obstype+='C' - case '7': obstype+='I' - case '8': obstype+='I' - return obstype -# ======================================================================================= -# Convert Format -# ======================================================================================= -def datefmt_conv(inline): - hou = inline[49:51] - min = inline[52:54] - sec = inline[55:57] + + + +# Convert Format ------------------------------ # +def datefmt2_conv(inline): + hou=inline[49:51] + min=inline[52:54] + sec=inline[55:57] return (inline[0:49] + hou + min + sec + bnk + "UTC" + bnk + "PGM / RUN BY / DATE\n") -# ======================================================================================= -# Convert observ msg of RINEX 2.xx to others -# ======================================================================================= -def obstype_conv(inline, in_f): + + + +# Convert Format ------------------------------ # +def datefmt3_conv(inline): + hou=inline[49:51] + min=inline[51:53] + sec=inline[53:55] + return (inline[0:49] + + hou + ':' + + min + ':' + + sec + ':' + + 'UTCPGM / RUN BY / DATE\n') + + + +# Convert observ type of RINEX 2.xx to Uni-Format --------------- # +def obsfmt2_conv(obstypes, sys): + + counter =0 + obstypex=[] + obsbomit='' + + match sys: + case 'G': + for obs in obstypes: + counter+=1 + if obs[1:2]=='1': + if obs[0:1]=='P': obs='C1W' + else: obs+='C' + elif obs[1:2]=='2': + if obs[0:1]=='P': obs='C2W' + else: obs+='C' + elif obs[1:2]=='5': obs+='I' + else: + obsbomit+=('%02d'%counter) + continue + obstypex.append(obs) + case 'E': + for obs in obstypes: + counter+=1 + if obs[1:2]=='1': + if obs[0:1]=='P': + obsbomit+=('%02d'%counter) + continue + else: obs+='C' + elif obs[1:2]=='5': obs+='I' + elif obs[1:2]=='6': obs+='C' + elif obs[1:2]=='7': obs+='I' + elif obs[1:2]=='8': obs+='I' + else: + obsbomit+=('%02d'%counter) + continue + obstypex.append(obs) + case 'R': + for obs in obstypes: + counter+=1 + if obs[1:2]=='1': + if obs[0:1]=='P': obs='C1P' + else: obs+='C' + elif obs[1:2]=='2': + if obs[0:1]=='P': obs='C2P' + else: obs+='C' + else: + obsbomit+=('%02d'%counter) + continue + obstypex.append(obs) + case 'S': + for obs in obstypes: + counter+=1 + if obs[1:2]=='1': + if obs[0:1]=='P': + obsbomit+=('%02d'%counter) + continue + else: obs+='C' + elif obs[1:2]=='5': obs+='I' + else: + obsbomit+=('%02d'%counter) + continue + obstypex.append(obs) + + obstypex.append(obsbomit) + + return obstypex + + + +# Convert observ msg of RINEX 2.xx to Uni-Format ---------------- # +def obstype2_conv(inline, in_f, omilist): + # uni-format message label + obsobs='SYS / # / OBS TYPES' + outlines=[] obstypes=[] - system=['G', 'R', 'E', 'S'] + obstypex=[] + system=['G', 'E', 'R', 'S'] obsnum=int(inline[0:6]) - + omilist.append(obsnum) for i in range(math.ceil(obsnum/9)): obstypes.extend(inline[6:60].split()) if i+1==math.ceil(obsnum/9): break inline = in_f.readline() - for i in range(len(obstypes)): - obstypes[i]=obsfmt_conv(obstypes[i]) - for sys in system: - outline=sys+3*bnk+'%2d'%len(obstypes) + bnk - for i in range(len(obstypes)): - outline+=obstypes[i] + bnk - if (i+1)%13==0: - outlines.append( - outline+bnk+'SYS / # / OBS TYPES\n') - outline = 7*bnk - elif (i+1)==obsnum: - outlines.append( - outline + ( (13-len(obstypes))%13*4 + 1)*bnk + 'SYS / # / OBS TYPES\n') + obstypex=obsfmt2_conv(obstypes, sys) + omilist.append(obstypex[-1]) + # S___2D_ + num =len(obstypex)-1 + outline=sys+3*bnk+'%2d'%num+bnk + + for i in range(num): + outline+=obstypex[i]+bnk + if (i+1)==num: + bnx=((13-num%13)*4+1)*bnk + outlines.append(outline+bnx+obsobs+'\n') + outline=0*bnk + elif (i+1)%13==0: + outlines.append(outline+bnk+obsobs+'\n') + outline=7*bnk return outlines -# ======================================================================================= -# Convert obs of RINEX 2.xx to others -# ======================================================================================= -def rnx2uni_head_bxx(in_path, out_path, oriver, desver): + + + +# Convert obstpe msg of RINEX 2.xx to Uni-Format --------------- # +def obstpe2_conv(inline, outlines, desver): + oriver=inline[ 5: 9] + # generate convert stamp + obscov='COV-OBSERVATION DATA' + covpro='COV-RINEX VER / TYPE' + + outlines.append( 5*bnk+ + oriver+ + '->' + + desver+ + 1*bnk+ + obscov+ + 24*bnk+ + covpro+ + '\n') + outlines.append(conv_time()) + outlines.append( + inline.replace('%s'%re.search(r'[1-9]\d*.\d*|0\.\d*[1-9]\d*', inline).group(), desver)) + return + + + +# Convert head_data of RINEX 2.xx to Uni-format -------------- # +def rnx2_head2uni(in_f, desver, outlines, omilist): + # rinex message label + obscom='COMMENT' + obstpe='RINEX VERSION / TYPE' + obsl12='WAVELENGTH FACT L1/2' + obspro='PGM / RUN BY / DATE' + obsobs='# / TYPES OF OBSERV' + obsend='END OF HEADER' + + # get input head file & convert + while True: + inline=in_f.readline() + # file is aleady checked so no need to judge again + if not inline: pass + if inline.find(obscom)>=0: outlines.append(inline) + elif inline.find(obspro)>=0: outlines.append(datefmt2_conv(inline)) + elif inline.find(obsobs)>=0: outlines.extend(obstype2_conv(inline, in_f, omilist)) + elif inline.find(obstpe)>=0: obstpe2_conv(inline, outlines, desver) + elif inline.find(obsl12)>=0: continue + elif inline.find(obsend)>=0: break + else : outlines.append(inline) + + # get the end message after break + outlines.append(60*bnk+obsend+'\n') + + return 1 + + + +# Convert obs of RINEX 2.xx to Uni-Format ------------------- # +def rnx2_data2uni(in_f, outlines, omilist, obsnum): + sPRN=[] + scounter=0 + outline=emp + + # return false when file end + inline=in_f.readline() + if not inline : return False + + # get epoch message & flag state + year = int(inline[0 :3]) + month = int(inline[0+3 :3+3]) + day = int(inline[0+3+3 :3+3+3]) + hour = int(inline[0+3+3+3 :3+3+3+3]) + minute= int(inline[0+3+3+3+3 :3+3+3+3+3]) + second=float(inline[0+3+3+3+3+3 :3+3+3+3+3+11]) + e_flag= int(inline[0+3+3+3+3+3+11 :3+3+3+3+3+11+3]) + satnum= int(inline[0+3+3+3+3+3+11+3:3+3+3+3+3+11+3+3]) + if not e_flag==0: return True + + # time to Uni-Format + outlines.append( + "> %4d %02d %02d %02d %02d %10.7f %2d %2d\n" \ + % (year + 2000, month, day, hour, minute, second, e_flag, satnum)) + + # get list of sPRN + for i in range(math.ceil(satnum/12)): + if not i==0 : inline =in_f.readline() + if i+1< math.ceil(satnum/12): scounter=12 + if i+1==math.ceil(satnum/12): scounter=satnum-i*12 + for j in range(scounter): + sPRN.append(inline[32+3*j:32+3*(j+1)].replace(bnk,'0')) + + # convert epoch data to Uni-Format + for i in range(satnum): + oulist=[] + outline=emp + + # get omit list + match sPRN[i][0:1]: + case 'G': omitlis=omilist[0] + case 'E': omitlis=omilist[1] + case 'R': omitlis=omilist[2] + case 'S': omitlis=omilist[3] + + # observ amount lower than 5. no need to enter + if obsnum <= 5: + outline=in_f.readline() + outline=inline.replace('\n',emp).replace('\r',emp) + + # elif, need to enter + elif obsnum > 5: + for j in range(math.ceil(obsnum/5)): + inline=in_f.readline() + outline+=inline.replace('\n',emp).replace('\r',emp) + if len(outline)%16==15: outline+=bnk + if len(outline)%16==14: outline+=2*bnk + outline+=(5 - int(len(outline)/16))*16*bnk + + # omit the empty observ by '' + # outline be divide into parts + for j in range(obsnum): + oulist.append(outline[16*j:16*j+16]) + for j in range(len(omitlis)): + oulist[omitlis[j]-1]=emp + + # remerge into outline + outline=emp.join(oulist) + + outlines.append(sPRN[i]+outline+"\n") + return True + + + +# Convert Uni-format to RINEX 3.xx --------------------- # +def uni2rnx3_data(outlines, out_path): + out_f = open(out_path, 'a') + out_f.writelines(outlines) + out_f.close() + return + + + +# Get observ type need be omitted --------------------- # +def getomit(omilist): + for i in range(len(omilist)): + sysomit=[] + omitlis=omilist[0] + omitnum=len(omitlis)/2 + for j in range(int(omitnum)): + sysomit.append(int(omitlis[j*2+0:j*2+2])) + omilist.append(sysomit) + omilist.pop(0) + return + + + +# Convert data of RINEX 2.xx to Des-format ----------------- # +def rnx2des(in_path, out_path, oriver, desver): + headread=False + outlines=[] + omilist=[] + # convert rinex 2.xx(header) to Uni-format + in_f=open(in_path, 'r') + match rnx2_head2uni(in_f, desver, outlines, omilist): + case 1: headread=True + case 0: headread=False + + uni2rnx3_data(outlines, out_path) + outlines=[] + + if headread: + # get each observ type and omit the empty + obsnum=omilist[0] + omilist.pop(0) + getomit(omilist) + + while rnx2_data2uni(in_f, outlines, omilist, obsnum): + match desver[0:1]: + case '2': return 0 + case '3': uni2rnx3_data(outlines, out_path) + outlines=[] + return 1 + + + +# Reject data of invaild input ----------------------- # +def rnx_reject(in_path, out_path, oriver): + # rinex message label + obstpe='RINEX VERSION / TYPE' + obsmsg='OBSERVATION DATA' + obsend='END OF HEADER' + + # reject cause cant input file + try: + with open(in_path, 'r'): pass + except FileNotFoundError: return 0 + + # reject wrong format or version + in_f=open(in_path, 'r') + while True: + inline=in_f.readline() + if not inline: return 0 + if inline.find(obstpe)>=0: + if not inline.find(obsmsg)>=0: return 0 + if not inline[ 5: 6]==oriver : return 0 + elif inline.find(obsend)>=0: break + + # reject cause cant output file + try: + with open(out_path, 'w'): pass + except PermissionError: return 0 + + return 1 + + + +# --------------------------------------------------------------------------------------- +# CONVERT FUNCTION +# +# Brief :Determine the file format and assign handlers +# Return : +# queue msg==0: fail. +# queue msg==1: ok. +# --------------------------------------------------------------------------------------- +def Convert_Un(in_path, out_path, oriver, desver, resqueue): + file_state=False + + match rnx_reject(in_path, out_path, oriver): + case 1: file_state=True + case 0: file_state=False + + if file_state: + match oriver: + case '2': rnx2des(in_path, out_path, oriver, desver) + case '3': resqueue.put(0) + else : resqueue.put(0) + + resqueue.put(1) + return + +# Multi-threading task --------------------------- # +def _Convert_Un(in_path, out_path, oriver, desver, resqueue): + T=threading.Thread( + target=lambda :Convert_Un(in_path, out_path, oriver, desver, resqueue) + ) + T.start() + T.join() + return resqueue.get() + + + + + + + +# --------------------------------------------------------------- # +# The functions below are not be useable. on progress............ # +# +# +# --------------------------------------------------------------- # + +# Convert observ type of RINEX 3.xx to Uni-Format --------------- # +def obsfmt_conv_cxx(obstypes): + outlines=[] + outline='%6d'%len(obstypes) + + for i in range(len(obstypes)): + outline+='%6s'%obstypes[i] + if (i+1)==len(obstypes): + outlines.append(outline + (9 - (i+1)%9)*6*bnk + '# / TYPES OF OBSERV\n') + outline='' + elif (i+1)%9==0: + outlines.append(outline + '# / TYPES OF OBSERV\n') + outline=6*bnk + return outlines +# Convert observ msg of RINEX 3.xx to Uni-Format ---------------- # +def obstype_conv_cxx(obstypes, inline, in_f): + while True: + if inline[0:1]=='G': flag=True + elif inline[0:1]=='E': flag=True + elif inline[0:1]=='R': flag=True + elif inline[0:1]=='S': flag=True + else: flag=False + + if flag: + obsnum=int(inline[2:6]) + for i in range(math.ceil(obsnum/13)): + for obs in inline[6:60].split(): + if obs[1:2]=='3': continue + if obs[1:2]=='4': continue + if obs[2:3]=='P': obs='P'+obs[1:2] + else: obs=obs[0:2] + if obs and obs not in obstypes: + obstypes.append(obs) + + if i+1==math.ceil(obsnum/13): + break + inline=in_f.readline() + return +# Convert head_data of RINEX 3.xx to Uni-format -------------- # +def rnx3_head2uni(in_path, out_path, desver): try: with open(in_path, 'r'): pass except FileNotFoundError: return -12 + obstypes=[] outlines=[] + in_put=False + output=False in_f=open(in_path, 'r') while True: inline=in_f.readline() - if not inline: return 0 - if inline.find('COMMENT')>=0: + if not inline: + return 0 + + if in_put and not output: + if not inline.find('SYS / # / OBS TYPES')>=0: + output=True + + if in_put and output: + outlines.extend(obsfmt_conv_cxx(obstypes)) + in_put=False + output=False + + if inline.find('COMMENT')>=0: outlines.append(inline) + elif inline.find('RINEX VERSION / TYPE')>=0: if not inline.find('OBSERVATION DATA')>=0: return -10 - if not float(inline[5: 9])<3: return -10 + if not float(inline[5: 9])>=3: + return -10 + # Output convert message outlines.append( - 5*bnk+'%s->%s'%(str(oriver),str(desver))+ - 1*bnk+'COV-OBSERVATION DATA'+ + 5*bnk+'%s->%s'%(str(inline[5: 9]),str(desver))+ + 1*bnk+'COV-OBSERVATION DATA'+ 24*bnk+'COV-RINEX VER / TYPE\n') outlines.append(conv_time()) outlines.append(inline.replace( '%s'%re.search(r'[1-9]\d*.\d*|0\.\d*[1-9]\d*', inline).group(), desver)) + elif inline.find('PGM / RUN BY / DATE')>=0: - outlines.append(datefmt_conv(inline)) - elif inline.find('# / TYPES OF OBSERV')>=0: - outlines.extend(obstype_conv(inline, in_f)) - elif inline.find("WAVELENGTH FACT L1/2")>=0: pass + outlines.append(datefmt3_conv(inline)) + + elif inline.find('SYS / # / OBS TYPES')>=0: + in_put=True + obstype_conv_cxx(obstypes, inline, in_f) + + elif inline.find('SYS / PHASE SHIFT')>=0: + continue + + elif inline.find('GLONASS COD/PHS/BIS')>=0: + continue + + elif inline.find('GLONASS SLOT / FRQ #')>=0: + continue + elif inline.find("END OF HEADER")>=0: outlines.append(inline) break + else: outlines.append(inline) try: @@ -140,116 +552,4 @@ def rnx2uni_head_bxx(in_path, out_path, oriver, desver): out_f=open(out_path, 'a') out_f.writelines(outlines) out_f.close() - - return 1 -# ======================================================================================= -# Convert head_data of RINEX 3.xx to Uni-format -# ======================================================================================= -def data2uni_bxx(inline, obsnum, in_f): - sPRN=[] - outlines=[] - count_er=0 - - year = int(inline[0 :3]) - month = int(inline[0+3 :3+3]) - day = int(inline[0+3+3 :3+3+3]) - hour = int(inline[0+3+3+3 :3+3+3+3]) - minute= int(inline[0+3+3+3+3 :3+3+3+3+3]) - second=float(inline[0+3+3+3+3+3 :3+3+3+3+3+11]) - e_flag= int(inline[0+3+3+3+3+3+11 :3+3+3+3+3+11+3]) - satnum= int(inline[0+3+3+3+3+3+11+3:3+3+3+3+3+11+3+3]) - - outlines.append( - "> %4d %02d %02d %02d %02d %10.7f %2d %2d\n" \ - % (year + 2000, month, day, hour, minute, second, e_flag, satnum)) - - for i in range(math.ceil(satnum/12)): - if not i==0: inline = in_f.readline() - if i+1 5: - for j in range(math.ceil(obsnum/5)): - inline=in_f.readline() - outline+=inline.replace("\n","").replace("\r","") - if len(outline)%16==15: outline+=bnk - if len(outline)%16==14: outline+=2*bnk - outline+=(5 - int(len(outline)/16))*16*bnk - outlines.append(sPRN[i] + outline + "\n") - - return outlines -# ======================================================================================= -# Convert Uni-format to RINEX 3.xx -# ======================================================================================= -def uni2data_cxx(outlines, out_path): - out_f = open(out_path, 'a') - out_f.writelines(outlines) - out_f.close() -# ======================================================================================= -# Convert data of RINEX 3.xx to Uni-format -# ======================================================================================= -def rnx2uni_data_bxx(in_path, out_path, desver): - obsnum=0 - obsget=False - - in_f=open(in_path, 'r') - while True: - inline = in_f.readline() - if not inline: break - elif inline.find('# / TYPES OF OBSERV')>=0: - if not obsget: - obsget=True - obsnum=int(inline[0:6]) - else: continue - elif inline.find("END OF HEADER")>=0: break - - while True: - inline = in_f.readline() - if not inline: break - elif inline[0:5]==5*bnk: continue - elif inline.find("COMMENT")>=0: continue - else: - outlines=data2uni_bxx(inline, obsnum, in_f) - uni2data_cxx(outlines, out_path) - return 1 -# ======================================================================================= -# -# -# -# -# ======================================================================================= -def Convert_Un(in_path, out_path, oriver, desver, resqueue): - origin=0 - match oriver: - case '2.10': origin=2 - case '2.11': origin=2 - case '3.03': origin=3 - case '3.04': origin=3 - case '3.05': origin=3 - - if origin==2: - match rnx2uni_head_bxx(in_path, out_path, oriver, desver): - case 1: rnx2uni_data_bxx(in_path, out_path, desver) - case 0: return resqueue.put(0) - case-10: return resqueue.put(0) - case-11: return resqueue.put(0) - case-12: return resqueue.put(0) - elif origin==3: resqueue.put(0) - - resqueue.put(1) -# ======================================================================================= -def _Convert_Un(in_path, out_path, oriver, desver, resqueue): - T=threading.Thread( - target=lambda :Convert_Un(in_path, out_path, oriver, desver, resqueue) - ) - T.start() - - T.join() - return resqueue.get() \ No newline at end of file + return 1 \ No newline at end of file