Compare commits

..
85 Commits
Author SHA1 Message Date
KenanZhu fb86442c9b none 2025-04-19 12:38:13 +08:00
KenanZhu 5350c8fa61 Remove all license, you are free to use 2025-04-19 12:33:28 +08:00
KenanZhu 5cebf53014 Modify readme 2025-04-19 12:23:06 +08:00
Kenan Zhu 8934efd425 Update READMECN.md 2025-02-02 21:15:25 +08:00
Kenan Zhu 5f5f8114e4 Update README.md 2025-02-02 21:14:04 +08:00
KenanZhu111 9e5b6d9ea3 Merge branch 'master' of https://github.com/KenanZhu111/KNZ_GeoTrackLab
# Conflicts:
#	README.md
2024-11-08 16:46:40 +08:00
KenanZhu111 fc181301c7 fix some bugs 2024-11-08 16:39:42 +08:00
Kenan Zhu 635b1da9ca Update README.md 2024-11-05 20:07:22 +08:00
KenanZhu111 80e29d68c7 see on update notes 2024-11-05 20:05:36 +08:00
KenanZhu111 93f218a113 none 2024-11-04 21:02:19 +08:00
KenanZhu111 8059c482e3 See update notes: 2024-11-04 20:56:45 +08:00
KenanZhu111 a3fb64a657 Update: 2024/11/03:
1.  KNZ_GeoTrackLab: Fix some bug, Modify some UI logic.
2.  KNZ_GeoTrackLab: Remove 3D plot function.
3.  KNZ_GeoTrackLab: Merge some functions and concentrated.
4.  KNZ_GeoTrackLab: New added:
                                Sat track projection ui(not ok on function).
2024-11-03 22:38:54 +08:00
KenanZhu111 d4db845cb3 Modify:
Restruct ui code
2024-11-01 23:11:53 +08:00
KenanZhu111 b28dd3e28d See update notes 2024-10-31 14:20:09 +08:00
KenanZhu111 8d22576a73 Update: 2024/10/28
1. KNZ_GeoTrackLab: Fix some bug.
2. KNZ_GeoTrackLab: Optimize code structure.
2024-10-28 19:27:59 +08:00
KenanZhu111 f895b31a8e Update: 2024/10/28
1.  KNZ_GeoTrackLab: Fix some bug.
2.  KNZ_GeoTrackLab: Optimize code structure.
2024-10-28 14:37:23 +08:00
Kenan Zhu ccd8d27d1c Update dllmain.cpp 2024-10-27 10:45:45 +08:00
Kenan Zhu 012f9c905e Update READMECN.md 2024-10-27 10:10:57 +08:00
Kenan Zhu db25335d2f Update pch.h 2024-10-27 00:22:25 +08:00
Kenan Zhu d942ae6845 Update Mainui.py 2024-10-27 00:20:07 +08:00
Kenan Zhu a3aa011b71 Update dllmain.cpp 2024-10-27 00:19:27 +08:00
Kenan Zhu b7c79f89a7 Update READMECN.md 2024-10-26 21:11:26 +08:00
Kenan Zhu f465bf1104 Update README.md 2024-10-26 21:08:32 +08:00
Kenan Zhu f27fc3d4ac Update README.md 2024-10-26 21:07:58 +08:00
Kenan Zhu 2f43dbc6c7 Update issue templates 2024-10-26 17:08:24 +08:00
Kenan Zhu e0d5b1db2d Create LICENSE 2024-10-26 17:05:34 +08:00
Kenan Zhu f5cde43dd6 Update README.md 2024-10-26 11:12:21 +08:00
Kenan Zhu 683786e2cf Update READMECN.md 2024-10-26 11:11:38 +08:00
Kenan Zhu d485ef0c02 Update and rename ReadmeCN.md to READMECN.md 2024-10-26 11:10:10 +08:00
Kenan Zhu 5b47228553 Update README.md 2024-10-26 11:09:02 +08:00
Kenan Zhu adcc7fad77 ReadmeCN.md 2024-10-26 11:08:18 +08:00
Kenan Zhu 12f72e6fee Update README.md 2024-10-26 11:00:44 +08:00
KenanZhu111 c02ae7f8d7 Merge branch 'master' of https://github.com/KenanZhu111/KNZ_Satnav 2024-10-26 10:20:42 +08:00
KenanZhu111 68f31ded24 BIG UPDATE:
1. Full gui
2. Integrated KNZ_Calculate and KNZ_Plot
3. Realized GPS, BeiDou, Galileo, GLONASS satellite position calculation,
4. New module added: 3D satellite orbit display
2024-10-26 10:14:53 +08:00
Kenan Zhu 26dabdfa3e Update README.md 2024-10-15 16:12:02 +08:00
Kenan Zhu cffc520d98 Update README.md 2024-10-15 16:09:55 +08:00
Kenan Zhu 8ef5b360c1 Update README.md 2024-10-15 16:09:00 +08:00
Kenan Zhu 7cb70f96c6 Update README.md 2024-10-14 23:52:20 +08:00
Kenan Zhu a4253f7e14 Update README.md 2024-10-14 22:06:53 +08:00
Kenan Zhu 94ecd5a94d Update README.md 2024-10-14 22:05:37 +08:00
Kenan Zhu 36deeb4408 Update README.md 2024-10-14 21:37:56 +08:00
KenanZhu111 aba6c009ab SUPPORT:
1. be able to calculate the sat pos of BDS & Galileo
2. be able to Single postiting by GPS & Galileo
2024-10-14 21:24:01 +08:00
KenanZhu111 f29614d834 Update:
1.KNZ_Calculate: modified some mistake and
optimize the use experience.
2.KNZ_Plot: more selective options and more united
style of GUI
2024-10-09 11:15:22 +08:00
KenanZhu111 c6d0e5bb48 Rename the Project:
1.Update KNZ_Plot
2.Update mpre GUI parts
2024-10-08 21:03:30 +08:00
KenanZhu111 d5a7fd37ce Main Update:
Realize the file view function
Realize the color select
Optimized operation experience
2024-10-06 16:11:02 +08:00
KenanZhu111 90d0aa850e Merge branch 'master' of https://github.com/KenanZhu111/SPP_-pseudorange-positioning 2024-10-06 11:39:44 +08:00
KenanZhu111 3908c51c9f Update:
modify the GUI experience
2024-10-06 11:38:58 +08:00
Kenan Zhu 70ea281da7 Update README.md 2024-10-05 22:14:17 +08:00
Kenan Zhu 2175285dfc Update README.md 2024-10-05 18:59:57 +08:00
Kenan Zhu 31dffa789b Update README.md 2024-10-05 18:52:50 +08:00
KenanZhu111 f9951695c8 plot module 2024-10-05 18:24:55 +08:00
KenanZhu111 b013a7fa02 HUGE UPDATES:
1. Realize the full gui program
2. Complete the plot function
2024-10-05 18:20:41 +08:00
KenanZhu111 37473233c2 UPDATE MANY NWE FUNCTIONS
Origin project is based on visual studio solution,
so, when you load all the files in your editor,
it can be cause errors. So, modify is a good choice
2024-10-01 22:06:38 +08:00
KenanZhu111 0f1a59c2aa Merge branch 'master' of https://github.com/KenanZhu111/SPP_-pseudorange-positioning 2024-09-28 18:47:29 +08:00
KenanZhu111 3ffe92bb31 Implement GUI by WIN32 API 2024-09-28 18:42:35 +08:00
Kenan Zhu c33a8c9d15 Update public.h 2024-09-26 18:54:24 +08:00
Kenan Zhu fa4b53a915 Update cal_mod.h 2024-09-26 18:53:23 +08:00
KenanZhu111 6dbb8aa67d none 2024-09-26 18:48:45 +08:00
KenanZhu111 cba65f6a85 modified some unuseful definition 2024-09-26 18:47:08 +08:00
KenanZhu111 dbecbe95cb Modify 2024-09-23 10:44:47 +08:00
KenanZhu111 1d5ab4cb1c Merge branch 'master' of https://github.com/KenanZhu111/SPP_-pseudorange-positioning 2024-09-23 10:00:05 +08:00
KenanZhu111 b8a6cf4e6e modified the crash 2024-09-23 09:59:40 +08:00
Kenan Zhu f6bbe8ebb0 Update main.c 2024-09-22 18:30:50 +08:00
Kenan Zhu d0fb56ee6d Update terminal.h 2024-09-22 18:30:11 +08:00
KenanZhu111 54547f9d3e WORING IN RESULT THE PROBLEM OF POINTER 2024-09-22 17:34:14 +08:00
KenanZhu111 1784076340 Correct some crash 2024-09-22 11:51:33 +08:00
KenanZhu111 a1c6c68166 Merge branch 'master' of https://github.com/KenanZhu111/SPP_-pseudorange-positioning 2024-09-22 11:16:51 +08:00
KenanZhu111 eca309d24a None 2024-09-22 11:16:40 +08:00
KenanZhu111 3852cdbc1b None 2024-09-22 11:14:17 +08:00
Kenan Zhu 9ed4ac9bd9 Update README.md 2024-09-22 00:42:45 +08:00
KenanZhu111 5ccca138b6 Modify UI 2024-09-22 00:23:15 +08:00
KenanZhu111 38b7dd9da3 Modify some mistakes 2024-09-21 21:29:03 +08:00
KenanZhu111 428e8508ff Merge branch 'master' of https://github.com/KenanZhu111/SPP_-pseudorange-positioning 2024-09-21 16:08:45 +08:00
KenanZhu111 2ca57dcb64 Major update: Improve the function and operation logic of software input and output 2024-09-21 16:07:58 +08:00
Kenan Zhu 8125aefcfc Update README.md 2024-09-21 12:33:05 +08:00
KenanZhu111 c44c1df50f Adding and modify many useful function
in their header file:
-blh2enu.h
-xyz2blh.h
-rahcal.h
-deg2dms.h
-degRrad.h
2024-09-21 11:38:30 +08:00
KenanZhu111 22cc906c00 Modify comments and output 2024-09-21 09:56:19 +08:00
KenanZhu111 e6e8ac6e9a Modify some file struct 2024-09-21 08:21:42 +08:00
KenanZhu111 1573f0a95a Fixed some mistake 2024-09-20 22:08:55 +08:00
KenanZhu111 d8d577dc7c Merge branch 'master' of https://github.com/KenanZhu111/SPP_-pseudorange-positioning 2024-09-20 21:47:22 +08:00
KenanZhu111 7093286114 Modify some function define 2024-09-20 21:45:16 +08:00
Kenan Zhu 53dfe80aab Update README.md 2024-09-20 14:51:59 +08:00
Kenan Zhu acf9d8e3f9 Update README.md 2024-09-20 14:40:42 +08:00
Kenan Zhu 9c28843b9a README.md 2024-09-20 14:28:51 +08:00
KenanZhu111 68362e984a SPP 2024-09-20 13:34:44 +08:00
26 changed files with 5188 additions and 1721 deletions

No files matched your search

+38
View File
@@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.
+20
View File
@@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.
+10
View File
@@ -0,0 +1,10 @@
{
"files.associations": {
"unistd.h": "c",
"select_epo.h": "c",
"xyz2blh.h": "c",
"deg2dms.h": "c",
"blh2enu.h": "c",
"terminal.h": "c"
}
}
+33
View File
@@ -0,0 +1,33 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: gcc.exe 生成活动文件",
"command": "C:\\Users\\34716\\mingw64\\bin\\gcc.exe",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe",
"-leasyx",
"-lmingw32",
"-lSDL2main",
"-lSDL2",
"-mwindows"
],
"options": {
"cwd": "C:\\Users\\34716\\mingw64\\bin"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "调试器生成的任务。"
}
],
"version": "2.0.0"
}
+137
View File
@@ -0,0 +1,137 @@
[ENGLISH](READMEEN.md)
> [!WARNING]
> 你正在浏览已经被遗弃的仓库 !
> 我们将不再对该项目进行更新。
# **主要功能介绍**
支持RINEX版本:
* [RINEX 2.xx 观测值文件 ](https://github.com/KenanZhu111/KNZ_Convert)(通过KNZ_Convert支持)
* RINEX 3.xx 观测值文件和广播星历
* RINEX 4.xx 观测值文件
支持GNSS:
* GPS:卫星位置解算&接收机定位
* Galileo:卫星位置解算&接收机定位
* GLONASS:卫星位置解算(OINP)
* 北斗/Compass:卫星位置解算(OINP)
支持定位方式
* 伪距定位
* (OINP)
# 主要介绍
## 程序介绍
### 关于KNZ_GeoTrackLab
* 2024年10月24日新增,由KNZ_Calculate与KNZ_Plot合并而成,改进运算逻辑,优化界面显示。
* 阅读帮助文档了解更多
### 关于 KNZ_Calculate(停止)(与 KNZ_Plot 合并)
* 自 2024 年 10 月 24 日起,KNZ_Calculate 已与 KNZ_Plot 合并为 KNZ_GeoTrackLab。[ADIN 2024/10/26]
### 关于 KNZ_Plot(停止)(与 KNZ_Calculate 合并)
* 自 2024 年 10 月 24 日起,KNZ_Calculate 已与 KNZ_Plot 合并为 KNZ_GeoTrackLab。[ADIN 2024/10/26]
### 关于 PyGMT(停止)
* 自 2024 年 10 月 5 日起,PyGMT 项目将不再考虑。[ADIN 2024/10/5]
### 关于 Matlab(停止)
* 自 2024 年 10 月 5 日起,Matlab 项目将不再考虑。[ADIN 2024/10/5]
## 项目更新
更新:2024/11/08:
1. KNZ_GeoTrackLab: 修复一些bug。
更新:2024/11/05:
1. KNZ_GeoTrackLab: 修复一些bug, 优化UI逻辑。
2. KNZ_GeoTrackLab: 为View文本编辑器增添保存修改功能。
3. KNZ_GeoTrackLab: 卫星轨迹投影图更改为墨卡托投影,
并实现动画显示,卫星号选择,绘
制采样频率选择。
更新: 2024/10/31:
1. KNZ_GeoTrackLab: 修复一些bug, 优化UI逻辑。
2. KNZ_GeoTrackLab: 移除3D绘图功能。
2. KNZ_GeoTrackLab: 合并功能并专一化。
3. KNZ_GeoTrackLab: 新增:
卫星轨迹投影图。
更新: 2024/10/31:
1. KNZ_GeoTrackLab: 修复一些bug, 优化UI逻辑.
2. KNZ_GeoTrackLab: 优化代码结构.
3. KNZ_GeoTrackLab: 新增:
截止高度角选项。
更新:2024/10/28
1. KNZ_GeoTrackLab:修复一些bug。
2. KNZ_GeoTrackLab:优化代码结构。
重命名项目并更新:2024/10/26
1. 首次发布 KNZ_GeoTrackLab。
2. KNZ_Calculate:与 KNZ_Plot 合并。
3. KNZ_Plot:与 KNZ_Calculate 合并。
4. KNZ_GeoTrackLab:支持 GPS、北斗、伽利略和 GLONASS。
更新:2024/10/14
1. KNZ_Calculate:支持 GPS、BDS 和伽利略。
2. KNZ_Plot:支持 GPS 和伽利略。
更新:2024/10/09
1. KNZ_Calculate:修改一些崩溃。
2. KNZ_Calculate:优化使用体验。
3. KNZ_Plot:修改 UI。
重命名项目并更新:2024/10/08
1. 首次发布 KNZ_Plot、KNZ_Calculate。
2. KNZ_Plot:修改 UI。
3. KNZ_Calculate:修改 UI。
更新:2024/10/06
1. SPP_Plot:修复一些bug。
2. SPP_Plot:优化使用体验。
3. SPP_Calculate:优化代码结构。
4. SPP_Calculate:修改UI。
更新:2024/10/05
1. 首次发布SPP_Plot
2. SPP_Calculate:修改UI。
更新:2024/09/28
1. 首次发布SPP_Calculate。
2. 优化代码结构。
更新:2024/09/26
1. 修复一些bug。
2. 优化使用体验。
更新:2024/09/23
1. 修复一些bug。
2. 修改一些崩溃。
更新:2024/09/22
1. 修复一些bug。
2. 修改UI。
更新:2024/09/21
1. 修复一些bug。
2. 优化使用体验。
更新:2024/09/20
1. 首次发布。
## 项目公告
* 编写代码时,借助了已有的开源代码成果,并不同程度的参考,在此一一标注并表示感谢:
| *https://blog.csdn.net/why1472587?type=blog*
| *https://zhuanlan.zhihu.com/p/416072448*
| *https://www.pygmt.org/latest/index.html*
| *https://blog.csdn.net/FrankXCR/article/details/135438701*
### 文档标签说明
* [ADIN TIME]: 新增于“TIME”(如 [ADIN 2024/9/22]: 新增于 2024/9/22)。
* (OINP):正在进行中的更改,或急需改进的部分。
* (STOP):不再更新维护或考虑实现功能。
> [!NOTE]
> 你可以对该代码核心功能和界面部分进行二次开发
> 无需额外授权。我们对此不保留任何权利。
+123 -62
View File
@@ -1,75 +1,136 @@
[English](READMEEN.md) | [中文](README.md) [中文](README.md)
### USING METHOD > [!WARNING]
Open the English version"KNZ_Convert_en_us_ver_1.2.5.exe", Click the "Single Convert", and > You are browse a aborted repositories !
select the path of origin file. Click the button on the right of "Convert" button to choose > We will no longer update this project.
the origin format and target format. The converted file will generate in the same diectory
of origin file, if not select the path of output file. Click the "Batch Convert", same
as the operate of "Single Convert", it is to be noticed that the major version of files must
be same or the file of different version will fail to convert. The file name format of
converted is like: COV-{$originfilename}.{$originfileextensions}
### BRIEF # **MAIN FUNCTION INTRODUCTION**
This software is developed by Python, mainly to complish the convert of different format
of RINEX observation data. At present, the convert between RINEX 2.xx and RINEX 3.xx is
already be basiclly supported.
Supported file format: Support version of RINEX:
* [RINEX of Observation of version 2.xx.](https://github.com/KenanZhu111/KNZ_Convert)(Support by KNZ_Convert)
* RINEX of Observation & Navigation of version 3.xx.
* RINEX of Observation of version 4.xx.
Support system of GNSS:
* GPS: Satellite position solving & Receiver station orientation
* Galileo : Satellite position solving & Receiver station orientation
* GLONASS : Satellite position solving(OINP)
* BeiDou / Compass : Satellite position solving(OINP)
| FILE TYPE | MAJOR VERSION |2.10|2.11|2.12|3.00|3.01|3.02|3.03|3.04|3.20|3.30|4.00|4.01| Support method of orientation
|-----------|---------------|----|----|----|----|----|----|----|----|----|----|----|----| * Pseudorange positioning
| RINEX OBS | 2.xx | √ | √ | √ | √ | √ | √ | √ | √ | —— | —— | x | x | * (OINP)
| | 3.xx | √ | √ | √ | √ | √ | √ | √ | √ | —— | —— | x | x |
| | 4.xx | x | x | x | x | x | x | x | x | —— | —— | x | x |
| RINEX NAV | 2.xx | x | x | x | x | x | x | x | x | —— | —— | x | x |
| | 3.xx | x | x | x | x | x | x | x | x | —— | —— | x | x |
| | 4.xx | x | x | x | x | x | x | x | x | —— | —— | x | x |
| RTCM | 2.xx | —— | —— | —— | —— | —— | —— | —— | —— | x | x | —— | —— |
| | 3.xx | —— | —— | —— | —— | —— | —— | —— | —— | x | x | —— | —— |
# MAIN INTRO
## Program intro
### About KNZ_GeoTrackLab
* Added on October 24, 2024, merged from KNZ_Calculate and KNZ_Plot, improved operation logic, optimized interface display.
* Read more on help.doc
### About KNZ_Calculate(STOP)(Merge with KNZ_Plot )
* As of October 24, 2024, KNZ_Calculate has been merged with KNZ_Plot to form KNZ_GeoTrackLab.[ADIN 2024/10/26]
### About KNZ_Plot(STOP)(Merge with KNZ_Calculate )
* As of October 5, 2024, KNZ_Calculate has been merged with KNZ_Plot to form KNZ_GeoTrackLab.[ADIN 2024/10/26]
### About PyGMT(STOP)
* As of October 5, 2024, PyGMT plot project will no longer be considered.[ADIN 2024/10/5]
### About Matlab(STOP)
* As of October 5, 2024, Matlab project will no longer be considered.[ADIN 2024/10/5]
## Project Update
Update: 2024/11/08:
1. KNZ_GeoTrackLab: Fix some bug。
The double-character observation type of RINEX 2.xx will be matched by the list Update: 2024/11/05:
below: 1. KNZ_GeoTrackLab: Fix some bug, Optimize UI logic。
2. KNZ_GeoTrackLab: New added function of save and change
file for View.
3. KNZ_GeoTrackLab: Sat track projection plot changed as
Mecator projection and relize the display
by dynamic, sat prn selection, selection of
sample rate/inteval of plot.
|SYSTEM |FREQ.BAND |FREQUENCY |2.xx CODE | > |3.xx CODE | Update: 2024/11/03:
|--------|-----------|-----------|-----------------|-----|-------------------| 1. KNZ_GeoTrackLab: Fix some bug, Modify some UI logic.
|GPS |L1 |1575.42 |[C, L, D, S] 1,P1| > |[C, L, D, S] 1C,C1W| 2. KNZ_GeoTrackLab: Remove 3D plot function.
| |L2 |1227.60 |[C, L, D, S] 2,P2| > |[C, L, D, S] 2C,C2W| 3. KNZ_GeoTrackLab: Merge some functions and concentrated.
| |L5 |1176.45 |[C, L, D, S] 5 | > |[C, L, D, S] 5I | 4. KNZ_GeoTrackLab: New added:
|GLONASS |G1 |1602+K*9/16|[C, L, D, S] 1,P1| > |[C, L, D, S] 1C,C1P| Sat track projection ui.
| |G2 |1246+K*7/16|[C, L, D, S] 2,P2| > |[C, L, D, S] 2C,C2P|
|Galileo |E2-L1-E1 |1575.42 |[C, L, D, S] 1 | > |[C, L, D, S] 1C |
| |E5a |1176.45 |[C, L, D, S] 5 | > |[C, L, D, S] 5I |
| |E5b |1207.140 |[C, L, D, S] 7 | > |[C, L, D, S] 7I |
| |E5a+b |1191.795 |[C, L, D, S] 8 | > |[C, L, D, S] 8I |
| |E6 |1278.75 |[C, L, D, S] 6 | > |[C, L, D, S] 6C |
|SBAS |L1 |1575.42 |[C, L, D, S] 1 | > |[C, L, D, S] 1C |
| |L2 |1176.45 |[C, L, D, S] 5 | > |[C, L, D, S] 5I |
Because of the observation type of RINEX 3.xx is not completely compatible with the type of Update: 2024/10/31:
RINEX 2.xx. So, it will be omitted for the observation of same type from the same frequency. 1. KNZ_GeoTrackLab: Fix some bug, Modify some UI logic.
In general, based on the rule: "Convert the first, omit the next." to compatible with the 2. KNZ_GeoTrackLab: Optimize code structure.
RINEX 2.xx. At the same time, since this conversion is an irreversible processing method, 3. KNZ_GeoTrackLab: New added:
the converted observation file data can only be used as a reference when performing this Elevation angle option.
conversion, cannot replace the original version format.
Update: 2024/10/28
1. KNZ_GeoTrackLab: Fix some bug.
2. KNZ_GeoTrackLab: Optimize code structure.
Tip: if need to use RINEX file of strict format, you are supposed to be not use this software. Rename the Project & Update: 2024/10/26
1. First release KNZ_GeoTrackLab.
2. KNZ_Calculate: Merged with KNZ_Plot.
3. KNZ_Plot: Merged with KNZ_Calculate.
4. KNZ_GeoTrackLab: Support GPS & BeiDou & Galileo & GLONASS.
### UPDATE STAMP Update: 2024/10/14
2024/11/14: Currently, full support for RINEX 2.xx format conversion has been implemented, and 1. KNZ_Calculate: Support GPS & BDS & Galileo.
the format output errors of the previous version have been corrected. Currently, 2. KNZ_Plot: Support GPS & Galileo.
support for converting RINEX 2.xx to RINEX 3.xx is available.
2024/11/15: Corrected output format, ignored RINEX 2.xx free signals and changed matching rules.
2024/11/17: Supports conversion between RINEX2.xx format and RINEX3.xx format, and also supports Update: 2024/10/09
conversion between the same major versions. 1. KNZ_Calculate: Modify some crash.
2. KNZ_Calculate: Optimize use experience.
3. KNZ_Plot: Modify UI..
2024/11/18: Correct crash when input RINEX file with comment in the middle of data; Enhance the Rename the Project & Update: 2024/10/08
speed of converting. 1. First release KNZ_Plot ,KNZ_Calculate.
2. KNZ_Plot: Modify UI.
3. KNZ_Calculate: Modify UI.
### UPDATE PLAN Update: 2024/10/06
1. ~~Short-term goals:Supports conversion of RINEX2.xx and RINEX3.xx observation files.~~ √ 1. SPP_Plot: Fix some bug.
2. Middle-term goals:Supports conversion of RINEX2.xx and RINEX3.xx broadcast ephemeris files. 2. SPP_Plot: Optimize use experience.
3. Middle-term goals:Gradually introduce support for conversion of RTCM format files. 3. SPP_Calculate: Optimize code structure.
4. Long-term goals:Receiver raw data conversion. 4. SPP_Calculate: Modify UI.
Update: 2024/10/05
1. First release SPP_Plot
2. SPP_Calculate: Modify UI.
Update: 2024/09/28
1. First release SPP_Calculate.
2. Optimize code structure.
Update: 2024/09/26
1. Fix some bug.
2. Optimize use experience.
Update: 2024/09/23
1. Fix some bug.
2. Modify some crash.
Update: 2024/09/22
1. Fix some bug.
2. Modify UI.
Update: 2024/09/21
1. Fix some bug.
2. Optimize use experience.
Update: 2024/09/20
1. First release.
## Project notice
* When writing the code, with the help of the existing open source code results, and different degrees of reference, here one by one mark and express thanks:
| *https://blog.csdn.net/why1472587?type=blog*
| *https://zhuanlan.zhihu.com/p/416072448*
| *https://www.pygmt.org/latest/index.html*
| *https://blog.csdn.net/FrankXCR/article/details/135438701*
### Document label specification
* [ADIN TIME]: new added in "TIME"(e.g. [ADIN 2024/9/22]: new added in 2024/9/22).
* (OINP): Operation in progress, or in urgent need of improvement.
* (STOP): No longer update maintenance or consider implementing features.
[!NOTE]
> You are free to modify the core functionality and interface of this code.
> No additional permissions are required. We waive all rights to these modifications.
-65
View File
@@ -1,65 +0,0 @@
[English](READMEEN.md) | [中文](README.md)
### 使用方法
打开中文版本“KNZ_Convert_zh_cn_ver_1.2.5.exe”,点击单文件处理,选择原始文件路径。点击转换右侧按钮
选择原始格式和目标格式。如果未指定输出文件路径,转换后的文件将生成在原始文件的同一目录下。点击批文件
处理,与单文件转换相同操作下,需要注意要保证输入文件的主要版本相同。否则会转换失败。转换后的文件命名
格式为:COV-{原文件名}.{原文件后缀名}
### 软件简介
本软件是基于Python开发,主要实现转换不同版本格式的RINEX观测值文件。目前已经实现RINEX 2.xx格式与
RINEX 3.xx格式基本的相互转换。
文件格式转换支持列表:
| FILE TYPE | MAJOR VERSION |2.10|2.11|2.12|3.00|3.01|3.02|3.03|3.04|3.20|3.30|4.00|4.01|
|-----------|---------------|----|----|----|----|----|----|----|----|----|----|----|----|
| RINEX OBS | 2.xx | √ | √ | √ | √ | √ | √ | √ | √ | —— | —— | x | x |
| | 3.xx | √ | √ | √ | √ | √ | √ | √ | √ | —— | —— | x | x |
| | 4.xx | x | x | x | x | x | x | x | x | —— | —— | x | x |
| RINEX NAV | 2.xx | x | x | x | x | x | x | x | x | —— | —— | x | x |
| | 3.xx | x | x | x | x | x | x | x | x | —— | —— | x | x |
| | 4.xx | x | x | x | x | x | x | x | x | —— | —— | x | x |
| RTCM | 2.xx | —— | —— | —— | —— | —— | —— | —— | —— | x | x | —— | —— |
| | 3.xx | —— | —— | —— | —— | —— | —— | —— | —— | x | x | —— | —— |
对于RINEX 2.xx版本的两字符观测值类型将按照如下表格进行匹配:
|SYSTEM |FREQ.BAND |FREQUENCY |2.xx CODE | > |3.xx CODE |
|--------|-----------|-----------|-----------------|-----|-------------------|
|GPS |L1 |1575.42 |[C, L, D, S] 1,P1| > |[C, L, D, S] 1C,C1W|
| |L2 |1227.60 |[C, L, D, S] 2,P2| > |[C, L, D, S] 2C,C2W|
| |L5 |1176.45 |[C, L, D, S] 5 | > |[C, L, D, S] 5I |
|GLONASS |G1 |1602+K*9/16|[C, L, D, S] 1,P1| > |[C, L, D, S] 1C,C1P|
| |G2 |1246+K*7/16|[C, L, D, S] 2,P2| > |[C, L, D, S] 2C,C2P|
|Galileo |E2-L1-E1 |1575.42 |[C, L, D, S] 1 | > |[C, L, D, S] 1C |
| |E5a |1176.45 |[C, L, D, S] 5 | > |[C, L, D, S] 5I |
| |E5b |1207.140 |[C, L, D, S] 7 | > |[C, L, D, S] 7I |
| |E5a+b |1191.795 |[C, L, D, S] 8 | > |[C, L, D, S] 8I |
| |E6 |1278.75 |[C, L, D, S] 6 | > |[C, L, D, S] 6C |
|SBAS |L1 |1575.42 |[C, L, D, S] 1 | > |[C, L, D, S] 1C |
| |L2 |1176.45 |[C, L, D, S] 5 | > |[C, L, D, S] 5I |
由于RINEX 3.xx版本的观测值类型无法完全兼容RINEX 2.xx版本,所以对于RINEX 3.xx同一频段的同类型观测值
转换时会进行缺省处理。一般按照原观测值文件头文件中观测值 “先列出先转换,后列出先省略”的方式进行兼容。
同时由于该转换是不可逆的处理方式,因此进行该转换时转换后的观测值文件数据只能作为参考使用,无法替代原生
的版本格式。
注:如需使用严格的RINEX格式文件,请勿使用本软件。
### 更新简记
2024/11/14: 目前已经对RINEX 2.xx格式转换进行了全面支持,修改了上一版本的格式输出错误,目前支持RINEX 2.xx转换为RINEX 3.xx。
2024/11/15: 更正了输出格式,忽略RINEX 2.xx空余信号并更改匹配规则
2024/11/17: 支持RINEX2.xx格式和RINEX3.xx格式的相互转换,同时支持同一主要版本之间的转换。
2024/11/18: 修复了在转换数据中标有注释的RINEX文件时崩溃的错误;提高了文件转换速度。
### 更新计划
1. ~~近期目标:支持转换RINEX2.xx版本与RINEX3.xx版本观测值文件。~~ √
2. 中期目标:支持转换RINEX2.xx版本与RINEX3.xx版本广播星历文件。
3. 中期目标:逐步引入对RTCM格式文件的转换支持。
4. 远期目标:接收机原始数据转换。
+106
View File
@@ -0,0 +1,106 @@
# @ File : Config_file.py
#
# Copyright (c) 2024 KenanZhu. All Right Reserved.
#
# @ Author : KenanZhu
# @ Time : 2024/11/04
# @ Brief : Initialize the configuration file.
# #
# @ IDE : PyCharm 2024.2.1 (Community Edition)
#
# ----------------------------------------------------------------------------------------
from configparser import ConfigParser
class Configinit:
def __init__(self, config_filepath):
# init
# -------------------------------------------------------------------------------
self.config = ConfigParser()
self.config_filepath = config_filepath### Config file path
def load_config(self):
# -------------------------------------------------------------------------------
# >
# Method: load_config
# Brief : Load config file, if not exist, regenerate the config.
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
try:
with open(self.config_filepath, 'r'):
pass
except FileNotFoundError:
self.create_config()
def get_config(self):
# -------------------------------------------------------------------------------
# >
# Method: get_config
# Brief : Capture config instance handle.
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.config.read(self.config_filepath)
return self.config
def create_config(self):
# -------------------------------------------------------------------------------
# >
# Method: create_config
# Brief : Generate the initial config file.
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
### Config for software info
self.config.add_section('INFO')
self.config.set('INFO', 'Version','1.5.5.0')
self.config.add_section('Options_Calc')
### Config for calculate param
self.config.set('Options_Calc', 'Iono_model', '0')
self.config.set('Options_Calc', 'Trop_model', '0')
self.config.set('Options_Calc', 'Elev_angle', '0')
self.config.set('Options_Calc', 'Sat_system', '0')
### Config for plot param
self.config.add_section('Options_Draw')
self.config.set('Options_Draw', 'E_Color', '#0080FF')
self.config.set('Options_Draw', 'N_Color', '#0080FF')
self.config.set('Options_Draw', 'U_Color', '#0080FF')
self.config.set('Options_Draw', 'E_Line', '0.80')
self.config.set('Options_Draw', 'N_Line', '0.80')
self.config.set('Options_Draw', 'U_Line', '0.80')
self.config.set('Options_Draw', 'Sat_Amount_Color', '#0080FF')
self.config.set('Options_Draw', 'Enable of track', '0')
self.config.set('Options_Draw', 'Track of prn', '01')
self.config.set('Options_Draw', 'Track sample rate','10')
### Config for input path
self.config.add_section('Input_Obs_Path')
self.config.set('Input_Obs_Path', '0', '')
self.config.add_section('Input_Nav_Path')
self.config.set('Input_Nav_Path', '0', '')
### Config for output path
self.config.add_section('Output_Path')
self.config.set('Output_Path','0','')
with open(self.config_filepath, 'w') as configfile:
self.config.write(configfile)
return
def save_config(self):
# -------------------------------------------------------------------------------
# >
# Method: save_config
# Brief : Save changes of config file.
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
with open(self.config_filepath, 'w') as configfile:
self.config.write(configfile)
+667
View File
@@ -0,0 +1,667 @@
# @ 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()
+41
View File
@@ -0,0 +1,41 @@
# @ File : UI_about.py
#
# Copyright (c) 2024 KenanZhu. All Right Reserved.
#
# @ Author : KenanZhu
# @ Time : 2024/11/04
# @ Brief : Help info window class.
# #
# @ IDE : PyCharm 2024.2.1 (Community Edition)
#
# ----------------------------------------------------------------------------------------
### Std
import tkinter as tk
class ABODUI:
def __init__(self, hwndparent, cfg_get, func):
# init
# -------------------------------------------------------------------------------
self.func = func
self.cfg_get = cfg_get
self.hwndparent = hwndparent
self.initGUI()
def initGUI(self):
abo = tk.Toplevel(self.hwndparent)
abo.title("About")
abo.attributes('-toolwindow', 2)
self.func.Move_center(abo, 200, 100)
abo.minsize(200, 100)
abo.maxsize(200, 100)
About = tk.Label(abo,
text="\nKNZ_GeoTrackLab %s"
"\n"
"\nCopyright (c) 2024 by KenanZhu"
"\nAll Right Reserved."
% self.cfg_get['INFO']['Version']
)
About.pack(side=tk.TOP, expand=tk.YES)
+512
View File
@@ -0,0 +1,512 @@
# @ File : UI_main.py
#
# Copyright (c) 2024 KenanZhu. All Right Reserved.
#
# @ Author : KenanZhu
# @ Time : 2024/11/04
# @ Brief : Main window class.
# #
# @ IDE : PyCharm 2024.2.1 (Community Edition)
#
# ----------------------------------------------------------------------------------------
### Self
import Ui_view as vie
import Ui_about as abo
import Ui_options as opt
import Ui_processor as pro
import Config_file as config
import Func_callback as func
### Std
import threading
from tkinter import ttk
from PIL import ImageTk
from base64 import b64decode
from matplotlib.backends.backend_tkagg import (
FigureCanvasTkAgg, NavigationToolbar2Tk)
import tkinter as tk
import tkinter.font as tkfont
import cartopy.crs as ccrs
import cartopy.io.shapereader as shp
import matplotlib as mpl
mpl.use('TkAgg')
import matplotlib.pyplot as plt
def instanceOPT(hwndparent, cfg_get_, func_):
opt.OPTGUI(hwndparent, cfg_get_, func_)
def instancePRO(hwndparent, cfg_get_, func_):
pro.EXECUDUI(hwndparent, cfg_get_, func_)
def instanceVIE(hwndparent, func_):
vie.VIEWGUI(hwndparent, func_)
def instanceABO(hwndparemt, cfg_get_, func_):
abo.ABODUI(hwndparemt, cfg_get_, func_)
def _instanceOPT(hwndparemt, cfg_get_, func_):
T = threading.Thread(target=lambda :instanceOPT(hwndparemt, cfg_get_, func_))
T.start()
def _instancePRO(hwndparemt, cfg_get_, func_):
T = threading.Thread(target=lambda :instancePRO(hwndparemt, cfg_get_, func_))
T.start()
def _instanceVIE(hwndparemt, func_):
T = threading.Thread(target=lambda :instanceVIE(hwndparemt, func_))
T.start()
def _instanceABO(hwndparemt, cfg_get_, func_):
T = threading.Thread(target=lambda :instanceABO(hwndparemt, cfg_get_, func_))
T.start()
# noinspection PyUnusedLocal,PyProtectedMember
class MAINGUI:
def __init__(self, hwnd_, func_):
# init
# -------------------------------------------------------------------------------
self.func = func_
self.hwnd = hwnd_
self.ux = None
self.nx = None
self.ex = None
self.satn = None
self.satvisb = None
self.sattrack = None
self.canvas1 = None
self.canvas0 = None
self.canvas2 = None
self.Drawcards = None
self.Figurefrm_Sky = None
self.Figurefrm_Vis = None
self.Figurefrm_ENU = None
self.lastx = None
self.lasty = None
self.press = None
self.plotstate = None
self.initGUI()
def initGUI(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
### Set size
self.hwnd.title(
"KNZ_GeoTrackLab %s"
%cfg_get['INFO']['Version']
)
self.func.Move_center(hwnd,1200,700)
self.hwnd.minsize(1200, 700)
### Set icon
icon_ico = (b'AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADExMS4xMTGQMDAwKgAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxMTE0MjIy7jMzM/8zMzPrMDAwLwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAvLy8QMTExSAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAMTExNDIyMu4zMzP/MzMz/zMzM/8zMzPrMDAwLwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALy8vEDIyMsoyMjLKAAAAAAAAAAAAAAAAAAAAADExMTQyMjLuMzMz/zIy'
b'MvsxMTGaMjIy/TMzM/8zMzPrMTExLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAyMjJRMjIy3TExMbgyMjLKMzMz/zIyMtkAAAAAMDAwOioqKgYAAAAAMTExszMzM/8yMjL7MDAwWQAAAAAxMTFhMjIy/TMz'
b'M/8zMzPrMTExLgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADIyMt0zMzP/MzMz/zMz'
b'M/8zMzP/MTExrjExMU0yMjL4MTExsyoqKgYqKioMMjIyvzAwMFkAAAAAAAAAAAAAAAAxMTFhMjIy/TMzM/8zMzPrMTExLgAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMTExuDMzM/8zMzP/MzMz/zMzM/8xMTGaMjIy+DMz'
b'M/8zMzP/MTExsyoqKgYAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAxMTFhMjIy/jMzM/8yMjLfAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAC8vLxAyMjLKMzMz/zMzM/8zMzP/MzMz9TIyMvkzMzP/MzMz/zMzM/8zMzP/MTExsyoq'
b'KgYAAAAAAAAAAAAAAAAAAAAAAAAAADExMY8zMzP/MzMz/zMzM8gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAvLy8QMjIyyjMzM/8zMzP/MzMz/zMzM/UyMjL+MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MTExsyoqKgYAAAAAAAAAAAAA'
b'AAAxMTGPMzMz/zMzM/8yMjLTMDAwFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADExMUgyMjLKMjIy2DEx'
b'Ma4xMTGaMjIy+TMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MTExsyoqKgYAAAAAMTExbDMzM/8zMzP/MjIy0zAw'
b'MBUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMTExTTIyMvgzMzP/MzMz/zMz'
b'M/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MTExsyoqKgYqKioMMzMzwzIyMtMwMDAVAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDoyMjL4MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMz'
b'M/8zMzP/MzMz/zMzM/8zMzP/MTExsyoqKgYqKioMMDAwFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAKioqBjIyMrIzMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMz'
b'M/8zMzP/MTExsyoqKgYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAKioqBjIyMrIzMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjIyfgAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMTExNDExMbMqKioMKioqBjIy'
b'MrIzMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8xMTGUAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDUyMjLvMzMz/zIyMsAAAAABKioqBjIyMrIzMzP/MzMz/zMz'
b'M/8zMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8zMzP/MjIy3i0tLRwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAwMDA1MjIy7zMzM/8yMjL7MDAwWQAAAAAAAAAAKioqBjIyMrIzMzP/MzMz/zMzM/8zMzP/MzMz/zMz'
b'M/8zMzP/MzMz/zIyMt4zMzMeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwLzIy'
b'Mu8zMzP/MjIy+zAwMFkAAAAAAAAAAAAAAAAAAAAAKioqBjIyMrIzMzP/MzMz/zMzM/8zMzP/MzMz/zMzM/8yMjLeMzMzHgAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAxMTGQMzMz/zMzM/8zMzObAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAKioqBjIyMrIzMzP/MzMz/zMzM/8zMzP/MjIy3jMzMx4AAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADExMSkzMzPrMzMz/zIyMv0xMTFiAAAAAAAAAAAAAAAAAAAAADEx'
b'MWwqKioMKioqBjIyMrIzMzP/MzMz/zIyMt4zMzMeAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAADExMS4zMzPrMzMz/zIyMv0xMTFiAAAAAAAAAAAxMTGQMzMz/zMzM8MqKioMKioqBjIy'
b'Mn4xMTGULy8vGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAADExMS4zMzPrMzMz/zIyMv0xMTFiMTExkDMzM/8zMzP/MjIy0zAwMBUAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADEx'
b'MS4zMzPrMzMz/zIyMv4zMzP/MzMz/zIyMtMwMDAVAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADExMS4zMzPrMzMz/zMz'
b'M/8yMjLTMDAwFQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADExMS4yMjLfMTExxzAwMBUAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////////////////////'
b'/////////////////x////4P//58B//8eAP/4EhB/+AA4P/gAfD/wAHw/4AA4P+AAEH/8AAD/+AAB//gAA//8AAP/8AAD/+A'
b'AA//BgAf/g8AP/4fgH/+DwD//wYB//+AH///wD///+B////w//8=')
icon_ico = b64decode(icon_ico)
icon_ico = ImageTk.PhotoImage(data=icon_ico)
self.hwnd.tk.call('wm', 'iconphoto', self.hwnd._w, icon_ico)
### Set front
default_font = tkfont.nametofont("TkDefaultFont")
default_font.configure(family="Segoe UI", size=9)
### Top tool
self.initTOPMENU()
### Plot area
self.initPLOT()
### State bar
self.initSTATE_BAR()
### Quit event & mainloop start
self.hwnd.protocol("WM_DELETE_WINDOW", self.hwnd.quit)
self.hwnd.mainloop()
def initTOPMENU(self):
# -------------------------------------------------------------------------------
# Class :
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
topmenu = tk.Menu(self.hwnd)
### File
filemenu = tk.Menu(topmenu, tearoff=False)
### File > Open...
openmenu = tk.Menu(filemenu, tearoff=False)
### File > Open... > Open Pos Solution
openmenu.add_command(
label="Open Pos Solution",
accelerator='Ctrl+S',
command=lambda :self.func._OpenkslnFile(
self.ex,self.nx,self.ux,self.satn,self.satvisb,
self.canvas0,self.canvas1,self.plotstate)
)
### File > Open... > Open Sat Solution
openmenu.add_command(
label="Open Sat Solution",
accelerator='Ctrl+S',
command=lambda :self.func._Plot2polar(
self.sattrack,self.plotstate,self.canvas2)
)
### File > Open... > Open RINEX
openmenu.add_command(
label="Open RINEX",
command=lambda :instancePRO(hwnd, cfg_get, self.func),
accelerator='Ctrl+P'
)
filemenu.add_cascade(label="Open...", menu=openmenu)
### File > Clesr
filemenu.add_command(
label="Clear",
command=self.Clear_canvas
)
### File > View
filemenu.add_command(
label="View",
command=lambda :instanceVIE(self.hwnd, self.func)
)
### File > Exit
filemenu.add_command(
label="Exit",
command=self.hwnd.quit,
accelerator='Ctrl+E'
)
topmenu.add_cascade(label="File", menu=filemenu)
### Options
optmenu = tk.Menu(topmenu, tearoff=False)
### Options > Options...
optmenu.add_command(
label="Options...",
command=lambda :instanceOPT(self.hwnd,cfg_get,self.func)
)
topmenu.add_cascade(
label="Options",
menu=optmenu
)
### Help
helpmenu = tk.Menu(topmenu, tearoff=False)
### Help > About
helpmenu.add_command(
label="About",
command=lambda :instanceABO(self.hwnd, cfg_get, self.func)
)
topmenu.add_cascade(label="Help", menu=helpmenu)
self.hwnd.config(menu=topmenu)
def initPLOT(self):
# -------------------------------------------------------------------------------
# >
# Method: initPLOT
# Brief : Initializes the drawing area of the main ui
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.Drawcards = ttk.Notebook(self.hwnd)
# E-N-U Plot area
# -------------------------------------------------------------------------------
self.PLOT_ENU()
self.Drawcards.add(self.Figurefrm_ENU, text='ENU-Draw')
# Valid Satellite Amout area
# -------------------------------------------------------------------------------
self.PLOT_VIS()
self.Drawcards.add(self.Figurefrm_Vis, text='Sat Number')
# Sky Track Plot area
# -------------------------------------------------------------------------------
self.PLOT_SKY()
self.Drawcards.add(self.Figurefrm_Sky, text='Sat Track')
self.Drawcards.pack(fill=tk.BOTH, expand=True, padx='2px', pady='0px')
def PLOT_ENU(self):
# -------------------------------------------------------------------------------
# >
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.Figurefrm_ENU = tk.Frame(self.hwnd)
self.Figurefrm_ENU.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=tk.YES)
plt.rc('font', family='Segoe UI')
plt.rcParams['xtick.direction'] = 'in'
plt.rcParams['ytick.direction'] = 'in'
fig, (self.ex, self.nx, self.ux) = plt.subplots(
3,
1,
figsize=(10, 0),
sharex=True
)
for spine in ['right', 'left']:
self.ex.spines[spine].set_visible(False)
self.ex.set_facecolor('#f5f5f5')
for spine in ['right', 'left']:
self.nx.spines[spine].set_visible(False)
self.nx.set_facecolor('#f5f5f5')
for spine in ['right', 'left']:
self.ux.spines[spine].set_visible(False)
self.ux.set_facecolor('#f5f5f5')
fig.subplots_adjust(
left=0,
bottom=0.040,
right=1,
top=1,
hspace=0.0
)
self.canvas0 = FigureCanvasTkAgg(fig, self.Figurefrm_ENU)
self.canvas0.draw()
self.canvas0.get_tk_widget().pack( side=tk.BOTTOM, fill=tk.BOTH, expand=tk.YES)
toolbar0 = NavigationToolbar2Tk(self.canvas0, self.Figurefrm_ENU, pack_toolbar=False)
toolbar0.update()
toolbar0.pack(side=tk.LEFT)
### Call back event
self.canvas0.mpl_connect("button_press_event",self.On_press)
self.canvas0.mpl_connect("button_release_event",self.On_release)
self.canvas0.mpl_connect("motion_notify_event",self.On_move)
self.canvas0.mpl_connect('scroll_event',self.On_scaleing)
def PLOT_VIS(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.Figurefrm_Vis = tk.Frame(self.hwnd)
self.Figurefrm_Vis.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=tk.YES)
plt.rc('font', family='Segoe UI')
plt.rcParams['xtick.direction'] = 'in'
plt.rcParams['ytick.direction'] = 'in'
fig, (self.satn, self.satvisb) = plt.subplots(
2,
1,
figsize=(10, 0),
sharex=True
)
fig.subplots_adjust(
left=0,
bottom=0.045,
right=1,
top=0.95,
hspace=0.0
)
for spine in ['right', 'left']:
self.satn.spines[spine].set_visible(False)
self.satn.set_facecolor('#f5f5f5')
for spine in ['right', 'left']:
self.satvisb.spines[spine].set_visible(False)
self.satvisb.set_facecolor('#f5f5f5')
self.canvas1 = FigureCanvasTkAgg(fig, self.Figurefrm_Vis)
self.canvas1.draw()
self.canvas1.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=tk.YES)
toolbar1 = NavigationToolbar2Tk(self.canvas1, self.Figurefrm_Vis, pack_toolbar=False)
toolbar1.update()
toolbar1.pack(side=tk.LEFT)
def PLOT_SKY(self):
# -------------------------------------------------------------------------------
# >
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.Figurefrm_Sky = tk.Frame(self.hwnd)
self.Figurefrm_Sky.pack(side=tk.BOTTOM, fill=tk.BOTH, expand=tk.YES)
plt.rc('font', family='Segoe UI')
fig = plt.figure()
self.sattrack = fig.add_subplot(
projection=ccrs.Mercator()
)
self.sattrack.coastlines(resolution='110m')
self.sattrack.gridlines()
fig.subplots_adjust(
left=0,
bottom=0.045,
right=1,
top=0.90
)
for spine in ['right', 'left']:
self.sattrack.spines[spine].set_visible(False)
self.sattrack.set_facecolor('#f5f5f5')
self.canvas2 = FigureCanvasTkAgg(fig, self.Figurefrm_Sky)
self.canvas2.draw()
self.canvas2.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=tk.YES)
toolbar2 = NavigationToolbar2Tk(self.canvas2, self.Figurefrm_Sky, pack_toolbar=False)
toolbar2.update()
toolbar2.pack(side=tk.TOP, anchor='w')
def initSTATE_BAR(self):
stateframe = tk.Frame(self.hwnd)
stateframe.pack(side=tk.BOTTOM, fill=tk.X)
self.plotstate = ttk.Label(stateframe, text="None")
self.plotstate.pack(side=tk.LEFT, anchor='w')
def On_press(self, event):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
if event.inaxes:
if event.button == 1:
self.press = True
self.lastx = event.xdata
self.lasty = event.ydata
def On_move(self, event):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
axtemp = event.inaxes
if axtemp:
if self.press:
x = event.xdata - self.lastx
y = event.ydata - self.lasty
x_min, x_max = axtemp.get_xlim()
y_min, y_max = axtemp.get_ylim()
x_min = x_min - x
x_max = x_max - x
y_min = y_min - y
y_max = y_max - y
axtemp.set_xlim(x_min, x_max)
axtemp.set_ylim(y_min, y_max)
self.canvas0.draw()
def On_release(self, event):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
if self.press:
self.press = False
def On_scaleing(self, event):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
axtemp = event.inaxes
y_min, y_max = axtemp.get_ylim()
scaley = (y_max - y_min) / 10
if event.button == 'up':
axtemp.set(ylim=(y_min + scaley, y_max - scaley))
elif event.button == 'down':
axtemp.set(ylim=(y_min - scaley, y_max + scaley))
self.canvas0.draw_idle()
def Clear_canvas(self):
# -------------------------------------------------------------------------------
# >
# Method: Clear_canvas
# Brief : clear the canvas
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.ex.clear()
self.nx.clear()
self.ux.clear()
self.satn.clear()
self.satvisb.clear()
self.sattrack.clear()
self.canvas0.draw()
self.canvas1.draw()
self.canvas2.draw()
self.plotstate.config(text="None")
self.hwnd.update()
if __name__ == "__main__":
### LOad Config
cfg = config.Configinit('config.ini')
cfg.load_config()
cfg_get = cfg.get_config()
### Call Back Process
func = func.CALLBACK(cfg, cfg_get)
### Main Window
hwnd = tk.Tk()
mainui = MAINGUI(hwnd, func)
+582
View File
@@ -0,0 +1,582 @@
# @ File : UI_options.py
#
# Copyright (c) 2024 KenanZhu. All Right Reserved.
#
# @ Author : KenanZhu
# @ Time : 2024/11/04
# @ Brief : Plot options window class.
# #
# @ IDE : PyCharm 2024.2.1 (Community Edition)
#
# ----------------------------------------------------------------------------------------
### Std
from PIL import ImageTk
from tkinter import ttk
from base64 import b64decode
import tkinter as tk
# noinspection PyProtectedMember
class OPTGUI:
def __init__(
self,
hwndparent,
cfg_get,
func
):
# init
# -------------------------------------------------------------------------------
self.func = func
self.cfg_get = cfg_get
self.hwndparent = hwndparent
self.PlotFrame = None
self.CalcuFrame = None
self.systemv = None
self.ctrobox = None
self.cionbox = None
self.opthwnd = None
self.canglebox = None
self.angleentry = None
self.enable = tk.IntVar()
self.trackprn = tk.StringVar()
self.trackint = tk.StringVar()
self.enable.set(int(self.cfg_get['Options_Draw']['Enable of track']))
self.trackprn.set(self.cfg_get['Options_Draw']['Track of prn'])
self.trackint.set(self.cfg_get['Options_Draw']['Track sample rate'])
self.ulinewidth = None
self.nlinewidth = None
self.elinewidth = None
self.initGUI()
def initGUI(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
### Set size
self.opthwnd = tk.Toplevel(self.hwndparent)
self.opthwnd.title("Options")
self.opthwnd.resizable(0,0)
self.func.Move_center(self.opthwnd,320,280)
self.opthwnd.minsize(320,280)
self.opthwnd.maxsize(320,280)
### Set icon
icon_ico = (b'AAABAAEAICAAAAAAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAADjsAAA47AAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'ABAAAAAwAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAACQAAABIAAAASAAAACQAAAAAAAAACAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAABwAAAJAAAADqAAAA7gAAAO4AAADqAAAAk'
b'QAAAAcAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAACQAAAA/wAAAPw'
b'AAAD/AAAA/wAAAPwAAAD/AAAAkAAAAAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAADAAAAAQAAAAEAAAAAA'
b'AAACwAAAOMAAAD/AAAA/AAAAP4AAAD+AAAA/AAAAP8AAADjAAAACgAAAAAAAAABAAAAAQAAAAMA'
b'AAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAABAAAAAAA'
b'AAAAAAAABAAAABQAAAAAAAAATAAAA7QAAAP8AAAD+AAAA/wAAAP8AAAD+AAAA/wAAAO0AAAATAA'
b'AAAAAAAAUAAAABAAAAAAAAAAAAAAABAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AABAAAAAAAAABEAAABTAAAAUQAAAA8AAAAAAAAAAAAAAEQAAAD/AAAA/gAAAP8AAAD/AAAA/wAA'
b'AP8AAAD+AAAA/wAAAEQAAAAAAAAAAAAAAA8AAABRAAAAUwAAABEAAAAAAAAAAQAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAgAAAAAAAAAwAAAA5QAAAP8AAAD/AAAA4QAAAHYAAAB2AAAA6QAAAP8AAA'
b'D+AAAA/wAAAP8AAAD/AAAA/wAAAP4AAAD/AAAA6QAAAHYAAAB1AAAA4QAAAP8AAAD/AAAA5QAAA'
b'DAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAMoAAAD/AAAA+gAAAPwAAAD/AAAA'
b'/wAAAP8AAAD+AAAA/wAAAP8AAAD/AAAA/gAAAP4AAAD/AAAA/wAAAP8AAAD+AAAA/wAAAP8AAAD'
b'/AAAA/AAAAPoAAAD/AAAAywAAAAMAAAAAAAAAAQAAAAAAAAAAAAAAAwAAAAAAAABrAAAA/wAAAP'
b'oAAAD/AAAA/wAAAP0AAAD7AAAA+wAAAP4AAAD/AAAA/AAAAP0AAAD/AAAA/wAAAP0AAAD8AAAA/'
b'wAAAP4AAAD7AAAA+wAAAP0AAAD/AAAA/wAAAPoAAAD/AAAAawAAAAAAAAADAAAAAAAAAAEAAAAA'
b'AAAAAwAAANUAAAD/AAAA/QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAD/AAAA/wAAAPI'
b'AAADyAAAA/wAAAP8AAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/QAAAP8AAADVAAAAAw'
b'AAAAAAAAABAAAAAQAAAAAAAAATAAAA7AAAAP8AAAD+AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9A'
b'AAA/wAAAK8AAAA8AAAAFQAAABUAAAA8AAAArgAAAP8AAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8A'
b'AAD+AAAA/wAAAOwAAAATAAAAAAAAAAEAAAAAAAAAAQAAAAAAAADBAAAA/wAAAPoAAAD/AAAA/wA'
b'AAP8AAAD/AAAA/QAAAP8AAAB3AAAAAAAAAAIAAAAAAAAAAAAAAAIAAAAAAAAAdwAAAP8AAAD9AA'
b'AA/wAAAP8AAAD/AAAA/wAAAPoAAAD/AAAAwQAAAAAAAAABAAAAAAAAAAAAAAACAAAAAAAAADEAA'
b'ADmAAAA/wAAAP0AAAD/AAAA/wAAAPwAAAD/AAAAqwAAAAAAAAAEAAAAAwAAAAEAAAABAAAABAAA'
b'AAQAAAAAAAAArAAAAP8AAAD8AAAA/wAAAP8AAAD9AAAA/wAAAOYAAAAwAAAAAAAAAAIAAAAAAAA'
b'AAAAAAAAAAAABAAAAAAAAAA0AAACuAAAA/wAAAP0AAAD/AAAA/QAAAP8AAABCAAAAAAAAAAMAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAwAAAAAAAABCAAAA/wAAAP0AAAD/AAAA/QAAAP8AAACvAAAADQAAA'
b'AAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAACAAAAD4AAAA/wAAAP0AAAD/AAAA'
b'8gAAABgAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAABgAAADyAAAA/wAAAP0AAAD'
b'/AAAA+AAAACAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAIAAAAP'
b'gAAAD/AAAA/QAAAP8AAADyAAAAGAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAG'
b'AAAAPIAAAD/AAAA/QAAAP8AAAD4AAAAIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB'
b'AAAAAAAAAA0AAACuAAAA/wAAAP0AAAD/AAAA/QAAAP8AAABCAAAAAAAAAAMAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAwAAAAAAAABCAAAA/wAAAP0AAAD/AAAA/QAAAP8AAACuAAAADQAAAAAAAAABAAAAAA'
b'AAAAAAAAAAAAAAAgAAAAAAAAAxAAAA5gAAAP8AAAD9AAAA/wAAAP8AAAD8AAAA/wAAAKsAAAAAA'
b'AAABAAAAAMAAAABAAAAAQAAAAMAAAAEAAAAAAAAAKsAAAD/AAAA/AAAAP8AAAD/AAAA/QAAAP8A'
b'AADmAAAAMAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAMEAAAD/AAAA+gAAAP8AAAD/AAAA/wA'
b'AAP8AAAD9AAAA/wAAAHcAAAAAAAAAAgAAAAAAAAAAAAAAAgAAAAAAAAB3AAAA/wAAAP0AAAD/AA'
b'AA/wAAAP8AAAD/AAAA+gAAAP8AAADBAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAATAAAA7AAAAP8AA'
b'AD+AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAA/wAAAK4AAAA8AAAAFQAAABUAAAA8AAAArgAA'
b'AP8AAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD+AAAA/wAAAOwAAAATAAAAAAAAAAEAAAABAAA'
b'AAAAAAAMAAADWAAAA/wAAAP0AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD9AAAA/wAAAP8AAA'
b'DyAAAA8gAAAP8AAAD/AAAA/QAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAD/AAAA1QAAA'
b'AMAAAAAAAAAAQAAAAAAAAADAAAAAAAAAGsAAAD/AAAA+gAAAP8AAAD/AAAA/QAAAPsAAAD7AAAA'
b'/gAAAP8AAAD8AAAA/QAAAP8AAAD/AAAA/QAAAPwAAAD/AAAA/gAAAPsAAAD7AAAA/QAAAP8AAAD'
b'/AAAA+gAAAP8AAABrAAAAAAAAAAMAAAAAAAAAAAAAAAEAAAAAAAAAAwAAAMsAAAD/AAAA+gAAAP'
b'wAAAD/AAAA/wAAAP8AAAD+AAAA/wAAAP8AAAD/AAAA/gAAAP4AAAD/AAAA/wAAAP8AAAD+AAAA/'
b'wAAAP8AAAD/AAAA/AAAAPoAAAD/AAAAywAAAAMAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAIAAAAA'
b'AAAAMQAAAOYAAAD/AAAA/wAAAOEAAAB2AAAAdgAAAOkAAAD/AAAA/gAAAP8AAAD/AAAA/wAAAP8'
b'AAAD+AAAA/wAAAOkAAAB2AAAAdgAAAOEAAAD/AAAA/wAAAOYAAAAxAAAAAAAAAAIAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEQAAAFQAAABRAAAADwAAAAAAAAAAAAAARAAAAP8AAAD+A'
b'AAA/wAAAP8AAAD/AAAA/wAAAP4AAAD/AAAARAAAAAAAAAAAAAAADwAAAFEAAABUAAAAEQAAAAAA'
b'AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAABAAAAAAAAAAAAAAABAAAABQA'
b'AAAAAAAATAAAA7QAAAP8AAAD+AAAA/wAAAP8AAAD+AAAA/wAAAO0AAAATAAAAAAAAAAUAAAABAA'
b'AAAAAAAAAAAAABAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAA'
b'AAEAAAABAAAAAEAAAABAAAAAAAAAAsAAADjAAAA/wAAAPwAAAD+AAAA/gAAAPwAAAD/AAAA4wAA'
b'AAoAAAAAAAAAAQAAAAEAAAAEAAAABAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAAJAAAAD/AAAA/AAAAP8AAA'
b'D/AAAA/AAAAP8AAACQAAAAAAAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAA'
b'BwAAAJAAAADqAAAA7gAAAO4AAADqAAAAkQAAAAcAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAkAAAASAAAAEgAAAAoAAAAAAAAAAgAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAM'
b'AAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/9GL//'
b'+kJf//kAn//5AJ/+ggBBfTIATLqCAEFZAAAAkgAAAEIAAABEAAAAJAAAACIAQgBKAIEAVQClAKq'
b'AmQFagJkBVQClAKoAgQBSAEIARAAAACQAAAAiAAAAQgAAAEkAAACaggBBXTIATL6CAEF/+QCf//'
b'kAn//6Ql///Ri/8=')
icon_ico = b64decode(icon_ico)
icon_ico = ImageTk.PhotoImage(data=icon_ico)
self.opthwnd.tk.call('wm', 'iconphoto', self.opthwnd._w, icon_ico)
### Main window
self.initOPTION()
self.initCONFIRM()
def initOPTION(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
Optionscards = tk.ttk.Notebook(self.opthwnd)
# Calcu options card
# -------------------------------------------------------------------------------
self.initCARDCALCU()
Optionscards.add(self.CalcuFrame, text='Calc options')
# Plot options card
# -------------------------------------------------------------------------------
self.initCARDDRAW()
Optionscards.add(self.PlotFrame, text='Draw options')
Optionscards.pack(fill=tk.BOTH, expand=True, padx='2px', pady='0px')
def initCARDCALCU(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.CalcuFrame = tk.Frame(self.opthwnd)
# Iono option frame
# -------------------------------------------------------------------------------
self.IONOOPT()
# Trop option frame
# -------------------------------------------------------------------------------
self.TROPOPT()
# Elev option frame
# -------------------------------------------------------------------------------
self.HANGOPT()
# Sat track opt frame
# -------------------------------------------------------------------------------
self.TRACK()
# Syst option frame
# -------------------------------------------------------------------------------
self.SYSOPT()
def IONOOPT(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
# ION correction frame#
IonoFrame = ttk.Frame(self.CalcuFrame)
IonoFrame.pack(side=tk.TOP, expand=tk.YES, padx='1px', pady='2px', fill=tk.X)
ioncor = ttk.Label(IonoFrame, text='Ionosphere Correction')
ioncor.pack(side=tk.LEFT, anchor='w', padx='1px')
self.cionbox = ttk.Combobox(IonoFrame, width=15, height=4)
self.cionbox['state'] = 'readonly'
self.cionbox['value'] = ('OFF', 'Ion-Free LC', 'Broadcast')
self.cionbox.current(self.cfg_get['Options_Calc']['iono_model'])
self.cionbox.pack(side=tk.RIGHT, anchor='e')
def TROPOPT(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
# TRO correction frame#
TropFrame = ttk.Frame(self.CalcuFrame)
TropFrame.pack( side=tk.TOP, expand=tk.YES, padx='1px', pady='2px', fill=tk.X)
ioncor = ttk.Label(TropFrame, text='Troposphere Correction')
ioncor.pack(side=tk.LEFT, anchor='w', padx='1px')
self.ctrobox = ttk.Combobox(TropFrame, width=15, height=4)
self.ctrobox['state'] = 'readonly'
self.ctrobox['value'] = ('OFF', 'Hopfield', 'Saastamoinen')
self.ctrobox.current(self.cfg_get['Options_Calc']['trop_model'])
self.ctrobox.pack(side=tk.RIGHT, anchor='e')
def HANGOPT(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
# Angle of elevation frame
SatElevFrame = ttk.Frame(self.CalcuFrame)
SatElevFrame.pack(side=tk.TOP, expand=tk.YES, padx='1px', pady='2px', fill=tk.X)
h_angle = ttk.Label(SatElevFrame, text='Satellite Elevation(°) / #')
h_angle.pack(side=tk.LEFT, anchor='w', padx='1px')
self.angleentry = ttk.Entry(SatElevFrame, width=8)
self.angleentry.pack(side=tk.RIGHT, anchor='w')
self.canglebox = ttk.Combobox(SatElevFrame, width=6, height=10)
self.canglebox['state'] = 'readonly'
self.canglebox['value'] = (
'00', '05', '10', '15',
'20', '25', '30', '35',
'40', '45', '50', '55',)
pos = int(self.cfg_get['Options_Calc']['elev_angle'])/5
self.canglebox.current(int(pos))
self.canglebox.pack(side=tk.RIGHT,anchor='e')
def TRACK(self):
# -------------------------------------------------------------------------------
# >
# Method: TRACK
# Brief : Plot satellite track by dynamic
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
SattrackFrm = ttk.LabelFrame(self.CalcuFrame, text='Satellite Track', labelanchor='nw')
SattrackFrm.pack(side=tk.TOP, expand=tk.YES, padx='0px', pady='2px', fill=tk.BOTH)
Sattrack = ttk.Frame(SattrackFrm)
Sattrack.pack(side=tk.TOP, expand=tk.YES, padx='0px', pady='0px',fill=tk.X)
SatenableBut = ttk.Checkbutton(
Sattrack,
text='Enable : (s)PRN / Plot Interval',
variable=self.enable,
onvalue=1,
offvalue=0,
command=lambda :self.func.AskOrNotCheck(
self.enable,
RateEntry,
SattprnEntry
)
)
SatenableBut.pack(side=tk.LEFT, anchor='w')
# Interval of track plot
# -------------------------------------------------------------------------------
RateEntry = ttk.Entry(
Sattrack,
width=8,
state=tk.DISABLED,
textvariable=self.trackint,
)
RateEntry.pack(side=tk.RIGHT, anchor='e')
# SPRN of satellite ploted
# -------------------------------------------------------------------------------
SattprnEntry = ttk.Entry(
Sattrack,
width=8,
state=tk.DISABLED,
textvariable=self.trackprn
)
SattprnEntry.pack(side=tk.RIGHT, anchor='e')
if self.enable.get():
RateEntry.config(state=tk.NORMAL)
SattprnEntry.config(state=tk.NORMAL)
def SYSOPT(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
# GNSS Options
SystemFrame = ttk.LabelFrame(self.CalcuFrame, text='Satellite system', labelanchor='nw')
SystemFrame.pack(side=tk.TOP, expand=tk.YES, padx='1px', pady='2px', fill=tk.X)
satsys = [("GPS", 1), ("GLO", 4), ("BeiDou", 2), ("Galileo", 3), ("SBAS", 5)]
self.systemv = tk.IntVar()
for sys, num in satsys:
radio_button = ttk.Radiobutton(SystemFrame, text=sys, variable=self.systemv, value=num)
radio_button.pack(side=tk.LEFT, padx='3px', anchor='w')
self.systemv.set(self.cfg_get['Options_Calc']['sat_system'])
def initCARDDRAW(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.PlotFrame = tk.Frame(self.opthwnd)
self.initDRAWCOLOR()
self.initDRAWLINE()
def initDRAWLINE(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
# Line's weight options#
LineoptFrame = ttk.LabelFrame(self.PlotFrame, text='Draw configs', labelanchor='nw')
LineoptFrame.pack(side=tk.RIGHT, expand=tk.YES, padx='1px', pady='1px', fill=tk.Y)
EFrame = tk.Frame(LineoptFrame)
EFrame.pack(side=tk.TOP, expand=tk.YES, padx='5px', pady='2px')
elinewopt = tk.Label(
EFrame,
text='Eline:',
width=5,
height=1
)
elinewopt.pack(side=tk.LEFT, expand=tk.YES, padx='1px', pady='0px')
self.elinewidth = ttk.Spinbox(
EFrame,
from_=0,
to=10,
increment=0.01,
width=10
)
self.elinewidth.set(self.cfg_get['Options_Draw']['e_line'])
self.elinewidth.pack(side=tk.LEFT, expand=tk.YES, padx='1px', pady='0px')
NFrame = tk.Frame(LineoptFrame)
NFrame.pack(side=tk.TOP, expand=tk.YES, padx='5px', pady='2px')
nlinewopt = tk.Label(
NFrame,
text='Nline:',
width=5,
height=1
)
nlinewopt.pack(side=tk.LEFT, expand=tk.YES, padx='1px', pady='0px')
self.nlinewidth = ttk.Spinbox(
NFrame,
from_=0,
to=10,
increment=0.01,
width=10
)
self.nlinewidth.set(self.cfg_get['Options_Draw']['n_line'])
self.nlinewidth.pack(side=tk.LEFT, expand=tk.YES, padx='1px', pady='0px')
UFrame = tk.Frame(LineoptFrame)
UFrame.pack(side=tk.TOP, expand=tk.YES, padx='5px', pady='2px')
ulinewopt = tk.Label(
UFrame,
text='Uline:',
width=5,
height=1
)
ulinewopt.pack(side=tk.LEFT, expand=tk.YES, padx='1px', pady='0px')
self.ulinewidth = ttk.Spinbox(
UFrame,
from_=0,
to=10,
increment=0.01,
width=10
)
self.ulinewidth.set(self.cfg_get['Options_Draw']['u_line'])
self.ulinewidth.pack(side=tk.LEFT, expand=tk.YES, padx='1px', pady='0px')
LineCon = tk.Frame(LineoptFrame)
LineCon.pack(side=tk.TOP, expand=tk.YES, padx='5px', pady='2px')
linewre = ttk.Button(
LineCon,
text='Undo',
width=10,
command=lambda :self.func.Linewchoose(
self.elinewidth,
self.nlinewidth,
self.ulinewidth,
0
)
)
linewre.pack(side=tk.LEFT, expand=tk.YES, padx='1px')
def initDRAWCOLOR(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
# Satnum plot options#
SatvisFrame = ttk.LabelFrame(self.PlotFrame, text='SatN configs', labelanchor='nw')
SatvisFrame.pack(side=tk.BOTTOM, expand=tk.YES, padx='1px', pady='1px', fill=tk.BOTH)
SatnFrame = tk.Frame(SatvisFrame)
SatnFrame.pack(side=tk.LEFT, expand=tk.YES, padx='5px', pady='2px')
satncollab = tk.Label(
SatnFrame,
width=5,
height=1,
bg=self.cfg_get['Options_Draw']['sat_amount_color'])
satncollab.pack(side=tk.RIGHT, expand=tk.YES, padx='5px', pady='0px')
satncolopt = ttk.Button(
SatnFrame,
text='Satn Color',
width=10,
command=lambda :self.func.Colorchoose(self.opthwnd, 3, satncollab, 1)
)
satncolopt.pack(side=tk.RIGHT, expand=tk.YES, padx='5px', pady='0px')
SatviCon = tk.Frame(SatvisFrame)
SatviCon.pack(side=tk.RIGHT, expand=tk.YES, padx='5px', pady='0px')
satviopt = ttk.Button(
SatviCon,
text='Undo',
width=10,
command=lambda :self.func.Colorchoose(self.opthwnd, 3, satncollab, 0)
)
satviopt .pack(side=tk.LEFT, expand=tk.YES, padx='1px')
# Line's colors options#
LinecolorFrame = ttk.LabelFrame(self.PlotFrame, text='ENU colors', labelanchor='nw')
LinecolorFrame.pack(side=tk.LEFT, expand=tk.YES, padx='1px', pady='1px', fill=tk.Y)
EFrame = tk.Frame(LinecolorFrame)
EFrame.pack(side=tk.TOP, expand=tk.YES, padx='5px', pady='2px')
ecollab = tk.Label(
EFrame,
width=5,
height=1,
bg=self.cfg_get['Options_Draw']['e_color'])
ecollab.pack(side=tk.RIGHT, expand=tk.YES, padx='5px', pady='0px')
ecolopt = ttk.Button(
EFrame,
text='E Color',
width=10,
command=lambda :self.func.Colorchoose(self.opthwnd, 0, ecollab, 1)
)
ecolopt.pack(side=tk.RIGHT, expand=tk.YES, padx='5px', pady='0px')
NFrame = tk.Frame(LinecolorFrame)
NFrame.pack(side=tk.TOP, expand=tk.YES, padx='5px', pady='2px')
ncollab = tk.Label(
NFrame,
width=5,
height=1,
bg=self.cfg_get['Options_Draw']['n_color']
)
ncollab.pack(side=tk.RIGHT, expand=tk.YES, padx='5px', pady='0px')
ncolopt = ttk.Button(
NFrame,
text='N Color',
width=10,
command=lambda :self.func.Colorchoose(self.opthwnd, 1, ncollab, 1)
)
ncolopt.pack(side=tk.RIGHT, expand=tk.YES, padx='5px', pady='0px')
UFrame = tk.Frame(LinecolorFrame)
UFrame.pack(side=tk.TOP, expand=tk.YES, padx='5px', pady='2px')
ucollab = tk.Label(
UFrame,
width=5,
height=1,
bg=self.cfg_get['Options_Draw']['u_color']
)
ucollab.pack(side=tk.RIGHT, expand=tk.YES, padx='5px', pady='0px')
ucolopt = ttk.Button(
UFrame,
text='U Color',
width=10,
command=lambda :self.func.Colorchoose(self.opthwnd, 2, ucollab, 1)
)
ucolopt.pack(side=tk.RIGHT, expand=tk.YES, padx='5px', pady='0px')
ColorCon = tk.Frame(LinecolorFrame)
ColorCon.pack(side=tk.TOP, expand=tk.YES, padx='5px', pady='2px')
colorcon = ttk.Button(
ColorCon,
text='Undo',
width=10,
command=lambda :[
self.func.Colorchoose(self.opthwnd, 0, ecollab, 0),
self.func.Colorchoose(self.opthwnd, 1, ncollab, 0),
self.func.Colorchoose(self.opthwnd, 2, ucollab, 0),
]
)
colorcon.pack(side=tk.LEFT, expand=tk.YES, padx='5px', pady='0px')
def initCONFIRM(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
ConfirmFrame = ttk.Frame(self.opthwnd)
ConfirmFrame.pack(side=tk.TOP, expand=tk.YES, padx='1px', pady='0px', fill=tk.Y)
TotalCancel = ttk.Button(
ConfirmFrame,
text='Cancel',
width=10,
command=lambda :[
self.opthwnd.destroy()
]
)
TotalCancel.pack(side=tk.RIGHT, padx='1px', anchor='e')
TotalCon = ttk.Button(
ConfirmFrame,
text='Confirm',
width=10,
command=lambda :[
self.func.Colorchoose(
self.opthwnd,
0, None, 2
),
self.func.Linewchoose(
self.elinewidth,
self.nlinewidth,
self.ulinewidth,
1
),
self.func.Calcuconfirm(
self.cionbox,
self.ctrobox,
self.canglebox,
self.systemv,
self.trackprn,
self.trackint
),
self.cfg_get.set('Options_Draw',
'Enable of track',
'%d' % self.enable.get()),
self.opthwnd.destroy()
]
)
TotalCon.pack(side=tk.RIGHT, padx='1px', anchor='e')
+245
View File
@@ -0,0 +1,245 @@
# @ File : UI_processor.py
#
# Copyright (c) 2024 KenanZhu. All Right Reserved.
#
# @ Author : KenanZhu
# @ Time : 2024/11/04
# @ Brief : RINEX file processor window class.
# #
# @ IDE : PyCharm 2024.2.1 (Community Edition)
#
# ----------------------------------------------------------------------------------------
### Std
from tkinter import ttk
from PIL import ImageTk
from base64 import b64decode
import tkinter as tk
# noinspection PyProtectedMember
class EXECUDUI:
def __init__(self, hwndparent, cfg_get, func):
# init
# -------------------------------------------------------------------------------
self.func = func
self.cfg_get = cfg_get
self.hwndparent = hwndparent
self.exehwnd = None
self.ObsSelectBoxVar = tk.StringVar()
self.NavSelectBoxVar = tk.StringVar()
self.AskOrNotCheckButtonVar = tk.IntVar()
self.DirectorySelectBoxVar = tk.StringVar()
self.initGUI()
def initGUI(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.exehwnd = tk.Toplevel(self.hwndparent)
self.exehwnd.title("RINEX Processor")
self.exehwnd.resizable(0,0)
self.func.Move_center(self.exehwnd,550,180)
self.exehwnd.minsize(550,180)
self.exehwnd.maxsize(550,180)
### Set icon
icon_ico = (b'AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAADjsAAA47AAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMAAAAEAAAAAQ'
b'AAAAAAAAAAAAAAAQAAAAQAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'QAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAADAAAAAAAAAAAAAAABAAAADQAAAA0AAAABAAAA'
b'AAAAAAAAAAADAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAABAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAAAAAAzAAAAlgAAANQAAADwAAAA8AAAANQAAACWAAAAMwAAAAAAAAADAA'
b'AAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAgAAAARAAAAEAAAABAAAAAPAAAAAQAAAAAAAAAAA'
b'AAAAQAAAAAAAAAIAAAAlwAAAP4AAAD/AAAA/wAAAPcAAAD3AAAA/wAAAP8AAAD+AAAAlwAAAAgAAAAAAAAAAQAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAgAAAAAAAABRAAAA5gAAAPIAAADwAAAA9gAAAOIAAAAQAAAAAAAAAAIAAAAAAAAACAAAALsAAAD'
b'/AAAA8gAAAIsAAAAyAAAAFAAAABQAAAAyAAAAiwAAAPIAAAD/AAAAuwAAAAgAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAA'
b'AAAAAABgAAANwAAAD/AAAA8QAAAPEAAAD2AAAA4gAAABAAAAAAAAAABAAAAAAAAACWAAAA/wAAAN0AAAAuAAAAAAAAAAIAA'
b'AAAAAAAAAAAAAIAAAAAAAAALgAAAN0AAAD/AAAAlgAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAARAAAA8AAAAPEA'
b'AAAfAAAADAAAABIAAAAPAAAAAQAAAAIAAAAAAAAANgAAAP8AAAD2AAAAMwAAAAAAAAAHAAAAAgAAAAAAAAAFAAAABAAAAAY'
b'AAAAAAAAAMwAAAPYAAAD/AAAANgAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAABAAAADxAAAA8gAAABAAAAAAAAAAAQAAAA'
b'AAAAAAAAAABAAAAAAAAACSAAAA/wAAAIoAAAAAAAAAAAAAABUAAACiAAAAJwAAAAAAAAADAAAAAwAAAAYAAAAAAAAAigAAA'
b'P8AAACSAAAAAAAAAAQAAAAAAAAAAAAAAAEAAAAAAAAAEAAAAPIAAADyAAAAEQAAAAAAAAACAAAAAQAAAAEAAAAAAAAAAAAA'
b'ANAAAAD/AAAANwAAAAAAAAAAAAAAEQAAAO8AAAD7AAAAfgAAAAgAAAAAAAAAAwAAAAAAAAA3AAAA/wAAANAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAQAAAAAAAAAQAAAA8gAAAPIAAAAQAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAOAAAA7QAAAPcAAAAWAAAAAA'
b'AAAAAAAAARAAAA6gAAAP8AAAD/AAAA5gAAAFYAAAAAAAAAAAAAABYAAAD3AAAA7QAAAA0AAAAAAAAAAQAAAAAAAAABAAAAA'
b'AAAABAAAADyAAAA8gAAABAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAA4AAADtAAAA9gAAABYAAAAAAAAAAAAAABEAAADqAAAA'
b'/wAAAP8AAADmAAAAVgAAAAAAAAAAAAAAFgAAAPcAAADtAAAADQAAAAAAAAABAAAAAAAAAAEAAAAAAAAAEAAAAPIAAADyAAA'
b'AEAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAANAAAAD/AAAANgAAAAAAAAAAAAAAEQAAAO8AAAD7AAAAfgAAAAgAAAAAAA'
b'AAAwAAAAAAAAA3AAAA/wAAANAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAQAAAA8gAAAPIAAAAQAAAAAAAAAAEAAAAAA'
b'AAAAAAAAAQAAAAAAAAAkgAAAP8AAACJAAAAAAAAAAAAAAAVAAAAogAAACcAAAAAAAAAAwAAAAMAAAAGAAAAAAAAAIoAAAD/'
b'AAAAkwAAAAAAAAAEAAAAAAAAAAAAAAABAAAAAAAAABAAAADyAAAA8gAAABAAAAAAAAAAAQAAAAAAAAAAAAAAAgAAAAAAAAA'
b'2AAAA/wAAAPUAAAAyAAAAAAAAAAcAAAACAAAAAAAAAAUAAAAEAAAABgAAAAAAAAAyAAAA9gAAAP8AAAA2AAAAAAAAAAIAAA'
b'AAAAAAAAAAAAEAAAAAAAAAEAAAAPIAAADyAAAAEAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAgAAAAAAAACWAAAA/wAAANwAA'
b'AAuAAAAAAAAAAIAAAAAAAAAAAAAAAIAAAAAAAAALgAAAN0AAAD/AAAAlgAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAQAAAAAA'
b'AAAQAAAA8gAAAPIAAAAQAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAgAAAC7AAAA/wAAAPEAAACKAAAAMgAAABQ'
b'AAAAUAAAAMgAAAIoAAADyAAAA/wAAALsAAAAIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAABAAAADyAAAA8gAAAB'
b'AAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAgAAACXAAAA/wAAAP8AAAD/AAAA9gAAAPcAAAD/AAAA/wAAA'
b'P8AAACXAAAACAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEAAAAPIAAADyAAAAEQAAAAAAAAACAAAAAQAA'
b'AAEAAAABAAAAAQAAAAEAAAACAAAAAwAAAAAAAAA0AAAAlgAAANUAAADwAAAA8AAAANUAAACXAAAANAAAAAAAAAADAAAAAgA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAQAAAA8gAAAPIAAAAQAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAkAAAAJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAABAAAAAAAAABAAAADyAAAA8wAAAB8AAAAMAAAAEQAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAA'
b'EwAAABQAAAAQAAAADAAAAAwAAAAQAAAAFAAAABMAAAAQAAAAEgAAABAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAA'
b'AEQAAAO4AAAD/AAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPMAAADzAA'
b'AA8wAAAPMAAADyAAAA8gAAAPEAAADyAAAA3QAAABAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAARAAAA7gAAAP8AAADyA'
b'AAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADy'
b'AAAA8gAAAP8AAADuAAAAEQAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAABAAAADyAAAA8wAAAB8AAAAMAAAAEQAAABAAAAA'
b'QAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEQAAAAwAAAAfAAAA8gAAAPEAAA'
b'AQAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAEAAAAPIAAADyAAAAEAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAABAAAADyAAAA8gAAABAAAAAAAAAAAQAAAAAA'
b'AAAAAAAAAQAAAAAAAAAQAAAA8QAAAPIAAAAQAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEAAAAPIAAADxAAAAEAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAB'
b'EAAADwAAAA8QAAAB8AAAAMAAAAEQAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAA'
b'BAAAAAQAAAAEQAAAAwAAAAfAAAA8QAAAPAAAAARAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAABgAAANwAAAD/AAAA8QAA'
b'APIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gA'
b'AAPEAAAD/AAAA3AAAAAYAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAIAAAAAAAAAUgAAAOYAAADyAAAA8gAAAPIAAADyAAAA8g'
b'AAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAOYAAABSAAAAA'
b'AAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAACAAAABEAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAA'
b'EAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAARAAAACAAAAAAAAAABAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAB'
b'AAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//2Mb+gSYZfS9IBLqBgABZAUAAmgFCEIoAhIhKFIhEShGMFGoVDAwqFQwMKhW'
b'MFGoUiERKFISIShZCEIoWQACaFoABWhAIBJoX+hf6AAAAWgAAAFoAAABaAAAAWhf/6FoX/+haAAAAWgAAAFkAAACagAABXS'
b'//9L6AAAF/////8=')
icon_ico = b64decode(icon_ico)
icon_ico = ImageTk.PhotoImage(data=icon_ico)
self.exehwnd.tk.call('wm', 'iconphoto', self.exehwnd._w, icon_ico)
self.initIO()
def initIO(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
MainFrame = tk.Frame(self.exehwnd)
MainFrame.pack()
InputFrame = ttk.Frame(MainFrame)
InputFrame.pack(side=tk.TOP, expand=tk.YES, padx='1px', pady='1px', fill=tk.X)
# Input Frame
# -------------------------------------------------------------------------------
### Observation file
ObsInFrame = ttk.LabelFrame(InputFrame, text='RINEX Obs File')
ObsInFrame.pack(side=tk.TOP, expand=tk.YES, padx='1px', pady='0px', fill=tk.X)
ObsFileSelectBox = ttk.Combobox(
ObsInFrame,
width=70,
height=4,
values=self.func.obsvar,
textvariable=self.ObsSelectBoxVar
)
ObsFileSelectBox.current(len(ObsFileSelectBox['value'])-1)
ObsFileSelectBox.pack(side=tk.LEFT, anchor='w', padx='0px', pady='0px')
ObsFileSelectButton = ttk.Button(
ObsInFrame,
text='...',
width=3,
command=lambda :self.func.GetObsFilePath(self.exehwnd, ObsFileSelectBox)
)
ObsFileSelectButton.pack(side=tk.RIGHT, anchor='e', padx='1px', pady='0px')
### Navigation file
NavInFrame = ttk.LabelFrame(InputFrame, text='RINEX Nav File')
NavInFrame.pack(side=tk.TOP, expand=tk.YES, padx='1px', pady='0px', fill=tk.X)
NavFileSelectBox = ttk.Combobox(
NavInFrame,
width=70,
height=4,
values=self.func.navvar,
textvariable=self.NavSelectBoxVar
)
NavFileSelectBox.current(len(NavFileSelectBox['value'])-1)
NavFileSelectBox.pack(side=tk.LEFT, anchor='w', padx='0px', pady='0px')
NavFileSelectButton = ttk.Button(
NavInFrame,
text='...',
width=3,
command=lambda :self.func.GetNavFilePath(self.exehwnd, NavFileSelectBox)
)
NavFileSelectButton.pack(side=tk.RIGHT, anchor='e', padx='1px', pady='0px')
# Output Frame
# -------------------------------------------------------------------------------
OutputFrame = ttk.Frame(MainFrame)
OutputFrame.pack(side=tk.BOTTOM, expand=tk.YES, padx='1px', pady='0px', fill=tk.X)
FileOutFrame = ttk.LabelFrame(OutputFrame, text='Output Directory')
FileOutFrame.pack(side=tk.TOP, expand=tk.YES, padx='1px', pady='0px', fill=tk.X)
## CheckButton Initialize
AskOrNotCheckButton = ttk.Checkbutton(
FileOutFrame,
text='Directory',
variable=self.AskOrNotCheckButtonVar,
onvalue=1,
offvalue=0,
command=lambda :self.func.AskOrNotCheck(
self.AskOrNotCheckButtonVar,
AskDirectorySelectBox,
AskDirectorySelectButton
)
)
AskOrNotCheckButton.pack(side=tk.LEFT, anchor='w', padx='0px', pady='0px')
AskDirectorySelectBox = ttk.Combobox(
FileOutFrame,
width=60,
height=4,
values=self.func.outvar,
state=tk.DISABLED,
textvariable=self.DirectorySelectBoxVar
)
AskDirectorySelectBox.current(len(AskDirectorySelectBox['value'])-1)
AskDirectorySelectBox.pack(side=tk.LEFT, anchor='w', padx='0px', pady='0px')
AskDirectorySelectButton = ttk.Button(
FileOutFrame,
text='...',
width=3,
state=tk.DISABLED,
command=lambda :self.func.AskDirectory(self.exehwnd, AskDirectorySelectBox)
)
AskDirectorySelectButton.pack(side=tk.RIGHT, anchor='e', padx='1px', pady='0px')
# Execute frame
# -------------------------------------------------------------------------------
ExeFrame = ttk.Frame(OutputFrame)
ExeFrame.pack(side=tk.TOP, expand=tk.YES, padx='1px', pady='0px', fill=tk.X)
ExitButton = ttk.Button(
ExeFrame,
text='Exit',
width=10,
command=self.exehwnd.destroy
)
ExitButton.pack(side=tk.LEFT, expand=tk.YES, padx='1px', pady='0px')
ExecuteButton = ttk.Button(
ExeFrame,
text='Execute',
width=10,
command=lambda :self.func._ExecuteFile(
ExecuteState,
self.ObsSelectBoxVar,
self.NavSelectBoxVar,
self.AskOrNotCheckButtonVar,
self.DirectorySelectBoxVar
)
)
ExecuteButton.pack(side=tk.LEFT, expand=tk.YES, padx='1px', pady='0px')
# State bar
# -------------------------------------------------------------------------------
StateFrame = ttk.Frame(OutputFrame)
StateFrame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='0px')
ExecuteState = ttk.Label(StateFrame, text="None")
ExecuteState.pack(side=tk.LEFT, anchor='nw')
+314
View File
@@ -0,0 +1,314 @@
# @ File : UI_view.py
#
# Copyright (c) 2024 KenanZhu. All Right Reserved.
#
# @ Author : KenanZhu
# @ Time : 2024/11/04
# @ Brief : File viewer window class.
# #
# @ IDE : PyCharm 2024.2.1 (Community Edition)
#
# ----------------------------------------------------------------------------------------
### Std
from PIL import ImageTk
from base64 import b64decode
from tkinter import filedialog
import tkinter as tk
# noinspection PyProtectedMember
class VIEWGUI:
def __init__(self, hwndparent, func):
# init
# -------------------------------------------------------------------------------
self.text = None
self.func = func
self.hwndparent = hwndparent
self.view = None
self.f_path=""
self.initGUI()
def initGUI(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.view = tk.Toplevel(self.hwndparent)
self.view.title("View")
self.func.Move_center(self.view, 1000, 600)
self.view.minsize(1000, 600)
icon_ico = (b'AAABAAEAMDAAAAEAIACoJQAAFgAAACgAAAAwAAAAYAAAAAEAIAAAAAAAACQAAPY6AQD2OgEAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAA'
b'ABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAEAAAAAQAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAACAAAAAgAAAAAAAAABAAAADQAAABIAAAARAAAAEQAAABEAAAARAAAAEQAAAB'
b'EAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAASAAAAD'
b'QAAAAEAAAAAAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAACQAAAHEAAADMAAAA6wAAAO8'
b'AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7g'
b'AAAO4AAADuAAAA7gAAAO4AAADvAAAA6wAAAMwAAAByAAAACQAAAAAAAAACAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAA'
b'AAAdAAAAzwAAAP8AAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wA'
b'AAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAD/AA'
b'AA0AAAAB0AAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAABAAAAAAAAAAgAAADMAAAA/wAAAPoAAAD6AAAA/gAAAP8AAAD/AAAA/wAA'
b'AP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAA'
b'A/wAAAP8AAAD/AAAA/gAAAPoAAAD6AAAA/wAAAMwAAAAIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAHIAAAD/AAAA+QAAA'
b'P8AAAD/AAAA9wAAAO0AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA'
b'7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADtAAAA9wAAAP8AAAD/AAAA+QAAAP8AAAB'
b'xAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAABAAAAAAAAAMcAAAD/AAAA+gAAAP8AAACtAAAAGQAAABEAAAASAAAAEQAAABEAAAARAAAAE'
b'QAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAAUAAAAFgAAABUAAAAR'
b'AAAAGQAAAK0AAAD/AAAA+gAAAP8AAADHAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAADQAAAOgAAAD/AAAA/wAAAPkAAAAjAAAAAA'
b'AAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAACMAAAD5AAAA/wAAAP8AAADnAAAADQAAAAAA'
b'AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgA'
b'AAO0AAAD/AAAA/wAAAO0AAAATAAAAAAAAAAIAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAA'
b'AAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAABQAAAAAAAAA/AAAAkwAAAE0AAAAAAAAAAAAAABQAA'
b'ADtAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAEAAAAAAAAAEQAAAO0AAAD/AAAA/wAAAO4AAAASAAAAAAAAAAEAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAQAAAAEAAAABAAAAAIAAAAFAAAAAAAAAFsAAA'
b'D/AAAA/gAAAP8AAABNAAAAAAAAABUAAADuAAAA/wAAAP8AAADtAAAAEQAAAAAAAAABAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA'
b'/wAAAO4AAAARAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAADAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAIAAAAAAAAAXAAAAP8AAAD9AAAA9QAAAP8AAACIAAAAAAAAABUAAADuAAAA/wAAAP'
b'8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAgAAAAIAAAAAAAAAKgAAAGcAAAB7AAAAaAAAAB0AAABaAAAA/wAAAP0AAAD8AAAA/QAAAP8'
b'AAAA/AAAAAAAAABQAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARA'
b'AAAAAAAAAEAAAAAAAAAAAAAAAAAAAACAAAAAAAAABYAAACrAAAA/gAAAP8AAAD+AAAA/wAAAPcA'
b'AAD4AAAA/gAAAP0AAAD9AAAA/wAAAFwAAAAAAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgA'
b'AAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAA'
b'AAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAGAAAANgAA'
b'AD/AAAA/QAAAPkAAAD2AAAA+QAAAP8AAAD9AAAA/gAAAP8AAAD/AAAAXAAAAAAAAAAFAAAAAAAA'
b'ABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAA'
b'AAAAAAAAAAAAIAAAAAAAAArAAAAP8AAAD5AAAA/QAAAP8AAAD/AAAA/wAAAP0AAAD+AAAA/wAAA'
b'P8AAABbAAAAAAAAAAUAAAABAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD'
b'/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAAAAAAAAgAAAAAAAAAwAAAA/gAAAP0AAAD+AAAA/wAAAM'
b'YAAACAAAAAygAAAP8AAAD9AAAA/wAAAPoAAAAmAAAAAAAAAAIAAAABAAAAAAAAABEAAADuAAAA/'
b'wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAAAAAAABAAAAAA'
b'AAABqAAAA/wAAAPkAAAD/AAAAxQAAAAMAAAAAAAAABgAAAMsAAAD/AAAA+QAAAP8AAABkAAAAAA'
b'AAAAQAAAABAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4A'
b'AAARAAAAAAAAAAEAAAAAAAAABAAAAAAAAAB/AAAA/wAAAPcAAAD/AAAAggAAAAAAAAASAAAAAAA'
b'AAIoAAAD/AAAA9wAAAP8AAAB4AAAAAAAAAAQAAAABAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAA'
b'AAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAA'
b'AAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAAAAAAABAAAAAAAAABrAAAA/wAA'
b'APkAAAD/AAAAwQAAAAAAAAAAAAAAAwAAAMcAAAD/AAAA+QAAAP8AAABkAAAAAAAAAAQAAAABAAA'
b'AAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAA'
b'AEAAAAAAAAAAgAAAAAAAAAyAAAA/wAAAP0AAAD+AAAA/wAAAMEAAAB4AAAAxAAAAP8AAAD+AAAA'
b'/gAAAPwAAAArAAAAAAAAAAIAAAABAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAA'
b'BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO'
b'0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAAAAAAAAAAAAAIAAAAAAAAAsAAAAP8AAAD5AAAA/'
b'QAAAP8AAAD/AAAA/wAAAP0AAAD5AAAA/wAAAKkAAAAAAAAAAgAAAAAAAAABAAAAAAAAABEAAADu'
b'AAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAAAAAAAAA'
b'AAAAEAAAAAAAAAHAAAAN0AAAD/AAAA/AAAAPgAAAD2AAAA+AAAAPwAAAD/AAAA2AAAABgAAAAAA'
b'AAAAQAAAAAAAAABAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wA'
b'AAO4AAAARAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAACAAAAAAAAABsAAAC0AAAA/wAAAP8AAAD+AA'
b'AA/wAAAP8AAACvAAAAGAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAABEAAADuAAAA/wAAAP8AA'
b'ADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAAAAAAAAQAAAAEAAAABAAA'
b'AAwAAAAIAAAAAAAAAMQAAAG8AAACEAAAAbgAAAC8AAAAAAAAAAgAAAAMAAAABAAAAAQAAAAAAAA'
b'ABAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAA'
b'AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAA'
b'AAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAE'
b'gAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAABAAAAEAAAABIAAAASAAAAEgAAABIAAAAS'
b'AAAAFAAAABYAAAAWAAAAFgAAABQAAAASAAAAEgAAABIAAAASAAAAEAAAAAEAAAABAAAAAAAAABE'
b'AAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAAAAAAQA'
b'AAA3QAAAPIAAADsAAAA7QAAAO0AAADtAAAA7QAAAO0AAADtAAAA7QAAAO0AAADtAAAA7QAAAOwA'
b'AADyAAAA3QAAABAAAAAAAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AA'
b'AA/wAAAO4AAAARAAAAAAAAAAAAAAASAAAA7QAAAP8AAAD+AAAA/wAAAP8AAAD/AAAA/wAAAP8AA'
b'AD/AAAA/wAAAP8AAAD/AAAA/wAAAP4AAAD/AAAA7QAAABIAAAAAAAAAAAAAABEAAADuAAAA/wAA'
b'AP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAAAAAASAAAA7QAAAP8AAA'
b'D+AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP4AAAD/AAAA7QAAA'
b'BIAAAAAAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAA'
b'RAAAAAAAAAAAAAAAQAAAA3QAAAPIAAADtAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7gAAAO'
b'4AAADuAAAA7gAAAO0AAADyAAAA3QAAABAAAAAAAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAE'
b'gAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAA'
b'AAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAABAAAAEAAAABIAAAARAAAAEQAAABE'
b'AAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAASAAAAEAAAAAEAAAABAAAAAA'
b'AAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AA'
b'AD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAABEAAADuAAA'
b'A/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAEAAAABAAAAEAAAA'
b'BIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAA'
b'EAAAAAEAAAABAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO'
b'4AAAARAAAAAAAAAAAAAAAQAAAA3QAAAPIAAADsAAAA7QAAAO0AAADtAAAA7QAAAO0AAADtAAAA7'
b'QAAAO0AAADtAAAA7QAAAOwAAADyAAAA3QAAABAAAAAAAAAAAAAAABEAAADuAAAA/wAAAP8AAADt'
b'AAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE'
b'AAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAAAAAASAAAA7QAAAP8AAAD+AAAA/w'
b'AAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP4AAAD/AAAA7QAAABIAAAAAA'
b'AAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/wAAAO4AAAARAAAAAAA'
b'AAAAAAAASAAAA7QAAAP8AAAD+AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AA'
b'AA/wAAAP4AAAD/AAAA7QAAABIAAAAAAAAAAAAAABEAAADuAAAA/wAAAP8AAADtAAAAEgAAAAAAA'
b'AABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAA'
b'AO0AAAD/AAAA/wAAAO4AAAARAAAAAAAAAAAAAAAQAAAA3QAAAPIAAADsAAAA7QAAAO0AAADtAAA'
b'A7QAAAO0AAADtAAAA7QAAAO0AAADtAAAA7QAAAOwAAADyAAAA3QAAABAAAAAAAAAAAAAAABEAAA'
b'DuAAAA/wAAAP8AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAEAAAAAAAAAEQAAAO0AAAD/AAAA/wAAAO4AAAASAAAAAAAAAAEAAAABAAAA'
b'EAAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAASAAAAEgAAABIAAAA'
b'SAAAAEAAAAAEAAAABAAAAAAAAABIAAADuAAAA/wAAAP8AAADtAAAAEQAAAAAAAAABAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEgAAAO0AAAD/AAAA/'
b'wAAAO0AAAATAAAAAAAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAACAAAAAAAAABMAAADtAAAA/wAAAP8'
b'AAADtAAAAEgAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAEAAAAAAAAADQAAAOgAAAD/AAAA/wAAAPkAAAAjAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAACAAAAAAAAACMAAAD5AAAA/wAAAP8AAADnAAAADQAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAMcAAAD/AAAA+gAAAP8AAACtAA'
b'AAGQAAABEAAAASAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAA'
b'AARAAAAEQAAABEAAAARAAAAEQAAABIAAAARAAAAGQAAAK0AAAD/AAAA+gAAAP8AAADHAAAAAAAA'
b'AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAA'
b'AAAAAAHIAAAD/AAAA+QAAAP8AAAD/AAAA9wAAAO0AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAA'
b'DuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADtAAAA9wAAA'
b'P8AAAD/AAAA+QAAAP8AAABxAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAgAAADMAAAA/wAAAPoAAAD6AAAA/gAAAP8AAAD'
b'/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP'
b'8AAAD/AAAA/wAAAP8AAAD/AAAA/gAAAPoAAAD5AAAA/wAAAMwAAAAIAAAAAAAAAAEAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAd'
b'AAAA0AAAAP8AAAD9AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8'
b'AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP8AAAD/AAAA/wAAAP0AAAD/AAAA0A'
b'AAAB0AAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAAACgAAAHIAAADNAAAA6wAAAO8AAADuAAAA7gAAAO4A'
b'AADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7gAAAO4AAADuAAAA7gA'
b'AAO4AAADvAAAA6wAAAM0AAAByAAAACgAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAgAAAAAAA'
b'AABAAAADQAAABIAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAARAAAAEQAA'
b'ABEAAAARAAAAEQAAABEAAAARAAAAEQAAABEAAAASAAAADQAAAAEAAAAAAAAAAgAAAAIAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAQAAAAQAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAEAAAAEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/Rf/'
b'/ov8AAP6QAAAJfwAA/UAAAAK/AAD+gAAAAX8AAPkAAAAAnwAA+QAAAACfAAD5AAAAAJ8AAPoF//'
b'+gXwAA+gQABGBfAAD6BegIIF8AAPoF0pAgXwAA+gWkACBfAAD6BVAAYF8AAPoFIACgXwAA+gUgA'
b'SBfAAD6BUABIF8AAPoFQIEgXwAA+gVBQSBfAAD6BUCBIF8AAPoFQAEgXwAA+gUgAiBfAAD6BSAC'
b'IF8AAPoFUAUgXwAA+gQEECBfAAD6Bf//oF8AAPoEAAAgXwAA+gYAAGBfAAD6BgAAYF8AAPoGAAB'
b'gXwAA+gYAAGBfAAD6BAAAIF8AAPoF//+gXwAA+gX//6BfAAD6BAAAIF8AAPoGAABgXwAA+gYAAG'
b'BfAAD6BgAAYF8AAPoGAABgXwAA+gQAACBfAAD6BF/6IF8AAPoF//+gXwAA+QAAAACfAAD5AAAAA'
b'J8AAPkAAAAAnwAA/oAAAAF/AAD9QAAAAr8AAP6QAAAJfwAA/0X//6L/AAA=')
icon_ico = b64decode(icon_ico)
icon_ico = ImageTk.PhotoImage(data=icon_ico)
self.view.tk.call('wm', 'iconphoto', self.view._w, icon_ico)
topmenu = tk.Menu(self.view)
### File
filemenu = tk.Menu(topmenu, tearoff=False)
### File > Oprn File
filemenu.add_command(
label="Open File",
command=self.View_windowshow,
accelerator='Ctrl+O'
)
filemenu.add_command(
label="Save File",
command=self.Save_file,
accelerator='Ctrl+S'
)
### File > Exit
filemenu.add_command(
label="Exit",
command=self.view.destroy,
accelerator='Ctrl+E'
)
topmenu.add_cascade(label="File", menu=filemenu)
self.view.config(menu=topmenu)
ybar = tk.Scrollbar(self.view)
ybar.pack(side=tk.RIGHT, fill=tk.Y)
xbar = tk.Scrollbar(self.view, orient=tk.HORIZONTAL)
xbar.pack(side=tk.BOTTOM, fill=tk.X)
self.text = tk.Text(
self.view,
xscrollcommand=xbar.set,
yscrollcommand=ybar.set,
height=500, width=1000,
undo=True,
autoseparators=False,
wrap='none'
)
self.text.pack(side=tk.TOP, fill=tk.BOTH)
ybar.config(command=self.text.yview)
xbar.config(command=self.text.xview)
def View_windowshow(self):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.f_path = filedialog.askopenfilename(parent=self.view)
if not self.f_path:
return 0
self.view.title('Viewing: %s' % self.f_path)
self.text.delete('1.0', 'end')
with open(self.f_path,'r',encoding='utf-8') as f:
fcon = f.read()
self.text.insert('insert', fcon)
self.text.config()
def Save_file(self):
filecontent = self.text.get('1.0', 'end')
if self.f_path:
with open(self.f_path,'w',encoding='utf-8') as f:
f.write(filecontent)
else:
if not filecontent=='\n':
fpath = filedialog.asksaveasfilename(
defaultextension='.txt',
parent=self.view,
title='Save As:',
filetypes=[
('Text File(*.txt)', '*.txt'),
('Solution File(*.ksln)', '*.ksln'),
('Solution File(*.ssln)', '*.ssln'),
('RINEX NAV File(*.*nav.*.hnav.*.gnav.*.qnav.*.*n.*.*g.*.*h.*.*q.*.*p)',
'*.*nav;*.hnav;*.gnav;*.qnav;*.*n;*.*g;*.*h;*.*q;*.*p'),
('RINEX OBS File(*.o*.*.*obs.*.*d)', '*.*o;*.*obs;*.*d'),
('All Files', '*.*')])
try:
with open(fpath,'w',encoding='utf-8') as f:
f.write(filecontent)
except FileNotFoundError:
self.view.title('Fail to save: %s' % fpath)
return
self.view.title('Viewing : %s' % fpath)
else:
return
Binary file not shown.
Binary file not shown.
-775
View File
@@ -1,775 +0,0 @@
# @ File : KNZ_Convert.py
#
# @ Brief : GUI main functions.
#
# Copyright (c) 2024 - 2024 KenanZhu. All Right Reserved.
#
# @ Author : KenanZhu
# @ Time stamp : [2024/11/13] First release.
# @ IDE : PyCharm
#
# ----------------------------------------------------------------------------------------
# ---SELPORT--- #
import rnx_convert as conv
# ---STDPORT--- #
import queue
import threading
import tkinter as tk
from tkinter import ttk
from PIL import ImageTk
from base64 import b64decode
from tkinter import filedialog
# ------------- #
# global const
InPaths = []
# io oath combox index
I_Box_Counter=0
O_Box_Counter=0
# io format list & index
I_Format_Rnx_List=0
I_RINEX_BoxList=['2','3']
O_Format_Rnx_List=0
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)
class CALLBACK:
@staticmethod
def Get_I_File(File_I_Box):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
global I_Box_Counter
path = filedialog.askopenfilename(
title='RINEX OBS File',
filetypes=[('RINEX OBS File(*.o*.*.*obs.*.*d)', '*.*o;*.*obs;*.*d'),
('All Files', '*.*')]
)
if path and path not in File_I_Box['value']:
File_I_Box['value'] += (path,)
I_Box_Counter += 1
File_I_Box.current(I_Box_Counter)
@staticmethod
def Get_I_Files(Files_I_ShowText):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
global InPaths
paths = filedialog.askopenfilenames(
title='RINEX OBS File',
filetypes=[('RINEX OBS File(*.o*.*.*obs.*.*d)', '*.*o;*.*obs;*.*d'),
('All Files', '*.*')]
)
for path in paths:
if path and path not in InPaths:
InPaths.append(path)
Files_I_ShowText.delete('1.0', 'end')
for path in InPaths:
Files_I_ShowText.insert('end', path + '\n')
@staticmethod
def Clear_I_Files(Files_I_ShowText):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
global InPaths
InPaths.clear()
Files_I_ShowText.delete('1.0', 'end')
@staticmethod
def Get_O_Dir(File_O_Box):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
global O_Box_Counter
path = filedialog.askdirectory()
if path and path not in File_O_Box['value']:
File_O_Box['value'] += (path + '/',)
O_Box_Counter += 1
File_O_Box.current(O_Box_Counter)
@staticmethod
def Enable_YN(File_O_ynVar, File_O_Box, File_O_Button):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
if File_O_ynVar.get() == 0:
File_O_Box.config(state=tk.DISABLED)
File_O_Button.config(state=tk.DISABLED)
else:
File_O_Box.config(state=tk.NORMAL)
File_O_Button.config(state=tk.NORMAL)
def Dir_or_name_get(self, 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 == '\\' or sig == '/':
filename = path[path_len:]
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 Convert(self,
Pro_style, File_O_ynVar, File_I_BoxVar, File_O_BoxVar, Convertcards, Exec_Progress):
# -------------------------------------------------------------------------------
# >
# Method:
# Brief :
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
global InPaths
Counter=0
State_O=0
InPath=[]
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'
else: InPath.append(File_I_BoxVar.get())
elif Convertcards.index('current')==1:
if not InPaths: ErrorMsg+=' path'
else: InPath=InPaths.copy()
if File_O_BoxVar.get(): OutDirec = File_O_BoxVar.get()
if not File_O_BoxVar.get():
if File_O_ynVar.get(): ErrorMsg+=' directory'
else : pass
if ErrorMsg:
ErrorMsg='Error : no'+ErrorMsg+' !'
Exec_Progress.config(value=0)
Pro_style.configure('text.Horizontal.TProgressbar', text=ErrorMsg)
return
#
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)
if not OutDirec:
out_path=(self.Dir_or_name_get(in_path,1)+'COV-'+
self.Dir_or_name_get(in_path,0))
State_O+=conv._Convert_Un(in_path,
out_path,
I_RINEX_BoxList[I_Format_Rnx_List],
O_RINEX_BoxList[O_Format_Rnx_List],
resqueue)
Counter+=1
Exec_Progress.config(value=int(Counter*100/len(InPath)))
Pro_style.configure(
'text.Horizontal.TProgressbar',
text='Converting...%d/%d'%(Counter, len(InPath)))
if State_O<=len(InPath):
#Exec_Progress.config(value=0)
Pro_style.configure(
'text.Horizontal.TProgressbar',
text='Complete ! %d successful. %d fails.'%(State_O, len(InPath)-State_O))
def _Convert(self,
Pro_style, File_O_ynVar, File_I_BoxVar, File_O_BoxVar, Convertcards, Exec_Progress):
T=threading.Thread(target=lambda :
self.Convert(Pro_style, File_O_ynVar, File_I_BoxVar, File_O_BoxVar, Convertcards, Exec_Progress))
T.start()
@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}')
# noinspection PyProtectedMember
class MAINGUI:
def __init__(self, hwnd, func):
# init
# -------------------------------------------------------------------------------
self.hwnd=hwnd
self.func=func
self.Pro_style=None
self.ExecFrame=None
self.BatchFrame=None
self.SingleFrame=None
self.Convertcards=None
self.Exec_Progress=None
self.File_O_ynVar=tk.IntVar()
self.File_I_BoxVar=tk.StringVar()
self.File_O_BoxVar=tk.StringVar()
self.iconoptions=(b'AAABAAEAEBAAAAEAIABoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOrq6v/q6ur/6urq/+rq6'
b'v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v+CgoL/dnZ2/1RUVP9UVFT/VFRU'
b'/1RUVP9UVFT/VFRU/1RUVP9UVFT/VFRU/1RUVP9UVFT/VFRU/3Z2dv+CgoL/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P'
b'/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/'
b'6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/4KCgv92dnb/VFRU/1RUVP9UVFT/VFRU/1RUVP9UVFT/VFRU/1RUVP9'
b'UVFT/VFRU/1RUVP9UVFT/dnZ2/4KCgv/Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8'
b'PDw//Dw8P/w8PD/8PDw//Dw8P/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6urqGAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAADq6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+r'
b'q6v/q6ur/goKC/3Z2dv9UVFT/VFRU/1RUVP9UVFT/VFRU/1RUVP9UVFT/VFRU/1RUVP9UVFT/VFRU/1RUVP92dnb/go'
b'KC/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw/8AA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//'
b'AAAAAAAAAAAAAAAAAAD//wAA//8AAAAAAAAAAAAAAAAAAP//AAD/fwAAAAAAAAAAAAAAAAAA//8AAA==')
self.iconoptions=b64decode(self.iconoptions)
self.iconoptions=ImageTk.PhotoImage(data=self.iconoptions)
self.initGUI()
def initGUI(self):
# -------------------------------------------------------------------------------
# >
# Method: initGUI
# Brief : init of main gui
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.hwnd.title("KNZ_Convert")
self.func.Move_center(self.hwnd, 400, 243)
self.hwnd.maxsize( 1000, 243)
self.hwnd.minsize( 400, 243)
#
icon_ico = (b'AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAADjsAAA47AAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAA'
b'AAAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAEgAAABAAAAAQAA'
b'AAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABIAAAAGAAAAAAAAAAAAAAAGAAAAEgAAABAAAAAQAAAAEAAAABAAAAAQAAA'
b'AEAAAABAAAAAQAAAAEAAAABIAAAAGAAAAAAAAAAAAAAAAAAAAAQAAALkAAAD3AAAA8AAAAPIAAADyAAAA8gAAAPIAAADyAAAA'
b'8gAAAPIAAADwAAAA9wAAALkAAAAAAAAAAAAAALkAAAD3AAAA8AAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADwAAAA9'
b'wAAALkAAAABAAAAAAAAAAAAAAARAAAA7wAAAP8AAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAAD/AAAA7w'
b'AAAA0AAAANAAAA7wAAAP8AAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAAD/AAAA7wAAABEAAAAAAAAAAAA'
b'AABAAAADxAAAA8gAAAB8AAAAMAAAAEQAAABAAAAAQAAAAEAAAABEAAAAMAAAAHwAAAPIAAADxAAAADAAAAAwAAADxAAAA8gAA'
b'AB8AAAAMAAAAEQAAABAAAAAQAAAAEAAAABEAAAAMAAAAHwAAAPIAAADxAAAAEAAAAAAAAAAAAAAAEAAAAPMAAADyAAAAEAAAA'
b'AAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAQAAAA8gAAAPMAAAAMAAAADAAAAPMAAADyAAAAEAAAAAAAAAABAAAAAAAAAA'
b'AAAAAAAAAAAQAAAAAAAAAQAAAA8gAAAPMAAAAQAAAAAAAAAAAAAAAQAAAA8wAAAPIAAAARAAAAAAAAAAIAAAABAAAAAQAAAAE'
b'AAAACAAAAAAAAABEAAADwAAAA8QAAAAsAAAALAAAA8QAAAPAAAAARAAAAAAAAAAIAAAACAAAAAgAAAAEAAAACAAAAAAAAABEA'
b'AADyAAAA8wAAABAAAAAAAAAAAAAAABAAAADzAAAA8gAAABAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEAAAAPIAA'
b'ADzAAAADAAAAAwAAADzAAAA8gAAABAAAAAAAAAAAgAAAAEAAAABAAAAAgAAAAEAAAAAAAAAEAAAAPIAAADzAAAAEAAAAAAAAA'
b'AAAAAAEAAAAPMAAADyAAAAEAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAgAAAAEAAAAAAAAAwwAAAMMAAAAAAAAAAAAAAMQAAAD'
b'DAAAAAAAAAAEAAAAAAAAABwAAAAcAAAAAAAAAAwAAAAAAAAAQAAAA8gAAAPMAAAAQAAAAAAAAAAAAAAAQAAAA8wAAAPIAAAAQ'
b'AAAAAAAAAAIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAEAAADEA'
b'AAA0AAAABYAAAAAAAAAAAAAABAAAADyAAAA8wAAABAAAAAAAAAAAAAAABAAAADzAAAA8gAAABAAAAAAAAAAAAAAAAUAAAARAA'
b'AAEAAAABAAAAAQAAAAEQAAAA8AAAAPAAAAEQAAABEAAAAPAAAADwAAABIAAAAPAAAAEwAAANMAAAD/AAAAzwAAABgAAAAAAAA'
b'AEgAAAPIAAADzAAAAEAAAAAAAAAAAAAAAEAAAAPMAAADyAAAAEQAAAAAAAAADAAAAwgAAAPsAAADwAAAA8gAAAPIAAADyAAAA'
b'8wAAAPMAAADyAAAA8gAAAPMAAADzAAAA8gAAAPMAAADvAAAA8gAAAPwAAAD/AAAAzAAAAAAAAAAPAAAA8wAAAPMAAAAQAAAAA'
b'AAAAAAAAAAQAAAA8wAAAPIAAAARAAAAAAAAAAMAAADCAAAA+wAAAPAAAADyAAAA8gAAAPIAAADzAAAA8wAAAPIAAADyAAAA8w'
b'AAAPMAAADyAAAA8wAAAO8AAADzAAAA/AAAAP8AAADMAAAAAAAAAA8AAADzAAAA8wAAABAAAAAAAAAAAAAAABAAAADzAAAA8gA'
b'AABAAAAAAAAAAAAAAAAUAAAARAAAAEAAAABAAAAAQAAAAEQAAAA8AAAAPAAAAEQAAABEAAAAPAAAADwAAABIAAAAPAAAAEwAA'
b'ANMAAAD/AAAAzwAAABgAAAAAAAAAEgAAAPIAAADzAAAAEAAAAAAAAAAAAAAAEAAAAPMAAADyAAAAEAAAAAAAAAACAAAAAQAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAABAAAAxAAAANAAAAAWAAAAAAAAAA'
b'AAAAAQAAAA8gAAAPMAAAAQAAAAAAAAAAAAAAAQAAAA8wAAAPIAAAAQAAAAAAAAAAEAAAABAAAAAQAAAAEAAAACAAAAAQAAAAA'
b'AAADDAAAAwwAAAAAAAAAAAAAAwwAAAMMAAAAAAAAAAQAAAAAAAAAHAAAABwAAAAAAAAADAAAAAAAAABAAAADyAAAA8wAAABAA'
b'AAAAAAAAAAAAABAAAADzAAAA8gAAABAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAEAAAAPIAAADzAAAADAAAAAwAA'
b'ADzAAAA8gAAABAAAAAAAAAAAgAAAAEAAAABAAAAAgAAAAEAAAAAAAAAEAAAAPIAAADzAAAAEAAAAAAAAAAAAAAAEAAAAPMAAA'
b'DyAAAAEQAAAAAAAAACAAAAAQAAAAEAAAABAAAAAgAAAAAAAAARAAAA8AAAAPEAAAALAAAACwAAAPEAAADwAAAAEQAAAAAAAAA'
b'CAAAAAgAAAAIAAAABAAAAAgAAAAAAAAARAAAA8gAAAPMAAAAQAAAAAAAAAAAAAAAQAAAA8wAAAPIAAAAQAAAAAAAAAAEAAAAA'
b'AAAAAAAAAAAAAAABAAAAAAAAABAAAADyAAAA8wAAAAwAAAAMAAAA8wAAAPIAAAAQAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABA'
b'AAAAAAAABAAAADyAAAA8wAAABAAAAAAAAAAAAAAABAAAADxAAAA8gAAAB8AAAAMAAAAEQAAABAAAAAQAAAAEAAAABEAAAAMAA'
b'AAHwAAAPIAAADxAAAADAAAAAwAAADxAAAA8gAAAB8AAAAMAAAAEQAAABAAAAAQAAAAEAAAABEAAAAMAAAAHwAAAPIAAADxAAA'
b'AEAAAAAAAAAAAAAAAEQAAAO8AAAD/AAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA/wAAAO8AAAANAAAA'
b'DQAAAO8AAAD/AAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA/wAAAO8AAAARAAAAAAAAAAAAAAABAAAAu'
b'gAAAPcAAADwAAAA8gAAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPAAAAD3AAAAuQAAAAAAAAAAAAAAugAAAPcAAADwAAAA8g'
b'AAAPIAAADyAAAA8gAAAPIAAADyAAAA8gAAAPAAAAD3AAAAugAAAAEAAAAAAAAAAAAAAAAAAAAGAAAAEgAAABAAAAAQAAAAEAA'
b'AABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABIAAAAGAAAAAAAAAAAAAAAGAAAAEgAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAA'
b'ABAAAAAQAAAAEAAAABIAAAAGAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'EAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAA'
b'AAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAA////////////////QAGAApf0L+lAAYACgAAAAYAAAAGAAAABhdALoYQQCCGF0AghhAmQIYSpmGGEAAAhhA'
b'AAIYQAACGEAAAhhKmYYYQJkCGF0AghhBAIIYXQC6GAAAABgAAAAYAAAAFAAYACl/Qv6UABgAL///////////////8=')
icon_ico = b64decode(icon_ico)
icon_ico = ImageTk.PhotoImage(data=icon_ico)
self.hwnd.tk.call('wm', 'iconphoto', self.hwnd._w, icon_ico)
#
self.initCONVERT()
#
self.initExecCtrl()
#
self.hwnd.protocol('WM_DELETE_WINDOW',self.hwnd.quit)
self.hwnd.mainloop()
def initCONVERT(self):
# -------------------------------------------------------------------------------
# >
# 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')
self.Convertcards.pack(side=tk.TOP, fill=tk.BOTH, expand=True, padx='0px', pady='0px')
def SingleConv(self):
# -------------------------------------------------------------------------------
# >
# Method: SingleConv
# Brief : Contrls of single convert
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.SingleFrame=ttk.Frame(self.hwnd)
# Initialize of input frame
File_I_Frame=tk.LabelFrame(
self.SingleFrame,
text='Object Observation of RINEX')
File_I_Frame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='0px')
# Initialize of input box
File_I_Box=ttk.Combobox(
File_I_Frame,
width=47,
height=4,
values=('',),
textvariable=self.File_I_BoxVar)
File_I_Box.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES, anchor='w', padx='1px', pady='1px')
# Initialize of input Button
File_I_Bbutton=ttk.Button(
File_I_Frame,
text='...',
width=3,
command=lambda :self.func.Get_I_File(File_I_Box))
File_I_Bbutton.pack(side=tk.RIGHT, anchor='e', padx='1px', pady='1px')
def BatchConv(self):
# -------------------------------------------------------------------------------
# >
# Method: BatchConv
# Brief : Contrls of batch convert
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.BatchFrame=ttk.Frame(self.hwnd)
#
Files_I_Frame=tk.LabelFrame(
self.BatchFrame,
text='Objects Observation of RINEX')
Files_I_Frame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='0px')
#
Files_I_CtrlFrame=ttk.Frame(Files_I_Frame)
Files_I_CtrlFrame.pack(side=tk.RIGHT, fill=tk.Y, anchor='e', padx='1px', pady='1px')
#
Files_I_CtrlInput=ttk.Button(
Files_I_CtrlFrame,
text='...',
width=3,
command=lambda :self.func.Get_I_Files(Files_I_ShowText))
Files_I_CtrlInput.pack(side=tk.TOP, anchor='e', padx='1px', pady='1px')
Files_I_CtrlClear=ttk.Button(
Files_I_CtrlFrame,
text='x',
width=3,
command=lambda :self.func.Clear_I_Files(Files_I_ShowText))
Files_I_CtrlClear.pack(side=tk.BOTTOM, anchor='e', padx='1px', pady='1px')
#
Files_I_ShowFrame=ttk.Frame(Files_I_Frame)
Files_I_ShowFrame.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES, anchor='e', padx='1px', pady='1px')
#
ScrollbarX=ttk.Scrollbar(Files_I_ShowFrame,orient=tk.HORIZONTAL)
ScrollbarX.pack(side=tk.BOTTOM, fill=tk.X)
ScrollbarY=ttk.Scrollbar(Files_I_ShowFrame)
ScrollbarY.pack(side=tk.RIGHT, fill=tk.Y)
#
Files_I_ShowText=tk.Text(
Files_I_ShowFrame,
xscrollcommand=ScrollbarX.set,
yscrollcommand=ScrollbarY.set,
height=4, wrap='none', font=('Segoe UI',9))
Files_I_ShowText.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES, anchor='w', padx='1px', pady='1px')
ScrollbarX.config(command=Files_I_ShowText.xview)
ScrollbarY.config(command=Files_I_ShowText.yview)
def initExecCtrl(self):
# -------------------------------------------------------------------------------
# >
# Method: initExecCtrl
# Brief : init of contrls
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
self.ExecFrame=ttk.Frame(self.hwnd)
self.ExecFrame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='0px')
#
# -------------------------------------------------------------------------------
self.ConvOut()
#
# -------------------------------------------------------------------------------
self.ExecCtrl()
def ConvOut(self):
# -------------------------------------------------------------------------------
# >
# Method: ConvOut
# Brief : Contrls of output
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
###
File_O_Frame=tk.LabelFrame(
self.ExecFrame,
text='Output directory')
File_O_Frame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='1px')
#
File_O_yn=ttk.Checkbutton(
File_O_Frame,
text='Directory',
variable=self.File_O_ynVar,
onvalue=1,
offvalue=0,
command=lambda :self.func.Enable_YN(
self.File_O_ynVar,
File_O_Box,
File_O_Button))
File_O_yn.pack(side=tk.LEFT, anchor='w', padx='1px', pady='0px')
#
File_O_Box=ttk.Combobox(
File_O_Frame,
width=36,
height=4,
values=('',),
state=tk.DISABLED,
textvariable=self.File_O_BoxVar)
File_O_Box.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES, anchor='w', padx='1px', pady='0px')
#
File_O_Button=ttk.Button(
File_O_Frame,
text='...',
width=3,
state=tk.DISABLED,
command=lambda :self.func.Get_O_Dir(File_O_Box))
File_O_Button.pack(side=tk.RIGHT, anchor='e', padx='1px', pady='0px')
def ExecCtrl(self):
# -------------------------------------------------------------------------------
# >
# Method: ExecCtrl
# Brief : Contrls of exe
# Author: @KenanZhu All Right Reserved.
# -------------------------------------------------------------------------------
CtrlButtonFrame=ttk.Frame(self.ExecFrame)
CtrlButtonFrame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='0px')
Conv_Option = ttk.Button(
CtrlButtonFrame,
image=self.iconoptions,
width=3,
command=lambda :instanceOPT(self.hwnd,self.func)
)
Conv_Option.pack(side=tk.RIGHT, padx='1px', pady='0px')
#
Conv_Button=ttk.Button(
CtrlButtonFrame,
text='Convert',
width=10,
command=lambda :self.func._Convert(
self.Pro_style,
self.File_O_ynVar,
self.File_I_BoxVar,
self.File_O_BoxVar,
self.Convertcards,
self.Exec_Progress))
Conv_Button.pack(side=tk.RIGHT, padx='1px', pady='0px')
#
Exit_button=ttk.Button(
CtrlButtonFrame,
text='Exit',
width=10,
command=self.hwnd.quit)
Exit_button.pack(side=tk.LEFT, padx='1px', pady='0px')
#
StateFrame=ttk.Frame(self.ExecFrame)
StateFrame.pack(side=tk.TOP, fill=tk.X, padx='1px', pady='4px')
self.Pro_style=ttk.Style(StateFrame)
self.Pro_style.layout(
'text.Horizontal.TProgressbar',
[
('Horizontal.Progressbar.trough',
{'children': [('Horizontal.Progressbar.pbar',{'side': 'left', 'sticky': 'ns'})],
'sticky': 'nswe'}
),
('Horizontal.Progressbar.label',{'sticky': ''})
]
)
self.Pro_style.configure(
'text.Horizontal.TProgressbar',
text='No task.',
foreground='#000000',
font=('Segoe UI',9))
self.Exec_Progress=ttk.Progressbar(
StateFrame,
value=0,
length=400,
maximum=100,
mode='determinate',
style='text.Horizontal.TProgressbar')
self.Exec_Progress.pack(side=tk.LEFT, fill=tk.X, expand=tk.YES)
class OPTIONS:
def __init__(self, parenthwnd, func):
# init
# -------------------------------------------------------------------------------
self.func=func
self.parenthwnd=parenthwnd
self.opthwnd=None
self.OptFrame=None
self.ExeFrame=None
self.MainFrame=None
self.I_RINEX_Box=None
self.O_RINEX_Box=None
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'
b'urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v+CgoL/dnZ2/1RUVP9UVFT/VFRU/1RUVP9UVFT/VFRU/1RUVP9UVFT/VFRU'
b'/1RUVP9UVFT/VFRU/3Z2dv+CgoL/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8P'
b'Dw//Dw8P/w8PD/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6urq/+rq6v/q6'
b'ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/4KCgv92dnb/VFRU/1RUVP9UVFT/'
b'VFRU/1RUVP9UVFT/VFRU/1RUVP9UVFT/VFRU/1RUVP9UVFT/dnZ2/4KCgv/Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8P'
b'D/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6urqGAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAADq6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q6ur/6urq/+rq6v/q'
b'6ur/goKC/3Z2dv9UVFT/VFRU/1RUVP9UVFT/VFRU/1RUVP9UVFT/VFRU/1RUVP9UVFT/VFRU/1RUVP92dnb/goKC/8PDw//Dw8P'
b'/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw//Dw8P/w8PD/8PDw/8AAAAAAAAAAAAAAAAAAAAAAA'
b'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAP//AAAAAAAAAAAAAAAAAAD//wAA//8AA'
b'AAAAAAAAAAAAAAAAP//AAD/fwAAAAAAAAAAAAAAAAAA//8AAA==')
icon_ico=b64decode(icon_ico)
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)
# -------------------------------------------------------------------------------
# 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(
Rnx_I_Frame,
text='RINEX:',
style='I_RINEX.TLabel')
I_RINEX.pack(side=tk.LEFT)
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(
Rtc_I_Frame,
text='RTCM :',
style='I_RTCM.TLabel')
I_RTCM.pack(side=tk.LEFT)
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=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', '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')
Cancel_Button = ttk.Button(
self.ExeFrame,
text='Cancel',
command=self.opthwnd.destroy)
Cancel_Button.pack(side=tk.LEFT)
Confirm_Button = ttk.Button(
self.ExeFrame,
text='Confirm',
command=lambda :[
self.Get_IO_Format(),
self.opthwnd.destroy()
])
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())
# Main program entry ---------------------------- #
if __name__ == "__main__":
root=tk.Tk()
call=CALLBACK()
initGUI=MAINGUI(root, call)
-801
View File
@@ -1,801 +0,0 @@
# @ File : rnx_convert.py
#
# @ Brief : RINEX Convert functions.
#
# Copyright (c) 2024 - 2024 KenanZhu. All Right Reserved.
#
# @ Author : KenanZhu
# @ Time stamp : [2024/11/13] First release.
# : [2024/11/14] Correct: convert of observation type of
# 'P1/P2' of GPS is correct into 'C1W/C2W'.
# : [2024/11/15] Fix bug: remove the empty observation of
# RINEX 2.xx format.
# : [2024/11/17] Add new: complish the funtions of convert
# form RINEX 3.xx to RINEX 2.xx and also support
# convert in major version of RINEX.
# : [2024/11/18] Fix bug: correct the bug when Convert RINEX file
# with comment in the middle of data will cause
# crash.
# Correct: correct the mistake in the functions
# below:
# 1. Correct function: getsys_rnx3()
# 2. Correct function: obstype3_conv()
# 3. Correct function: rnx2uni3_data()
# 4. Correct function: rnx2_data2uni()
# 5. Correct function: rnx3rnx2_data()
# Optimze: enhance the speed of converting.
#
#
# @ IDE/Editor : PyCharm / VisualStudio Code
#
# ----------------------------------------------------------------------------------------
# ---STDPORT--- #
import re
import time
import math
import threading
# ------------- #
emp=''
bnk=' '
# Get local time of converting ----------------------- #
def conv_time():
# generate convert timestamp
covpro='KNZ_Convert ver1.2.6'
covcom='COMMENT'
# Get the locate time and transform to Uni-format
y=time.localtime().tm_year
m=time.localtime().tm_mon
d=time.localtime().tm_mday
h=time.localtime().tm_hour
min=time.localtime().tm_min
sec=time.localtime().tm_sec
localtime=('%04d'%y +
'%02d'%m +
'%02d'%d +bnk+
'%02d'%h +
'%02d'%min+
'%02d'%sec+bnk+
'LLC' +bnk)
outline=(covpro +
20*bnk +
localtime+
covcom +
'\n')
return outline
# Convert data 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 data 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=emp
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=[]
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 sys in system:
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
if num%13==0: bnx=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
# Generate the convert stamp ------------------------ #
def conv_stamp(inline, outlines, desver):
oriver=inline[ 5: 9]
# generate convert stamp
obscov='COV-OBSERVATION DATA'
obscom='COMMENT'
outlines.append( 5*bnk+
oriver+
'->' +
desver+
1*bnk+
obscov+
24*bnk+
obscom+
'\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 RINEX 2.xx(header) 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: break
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: conv_stamp(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 RINEX 2.xx(data) 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
if not inline[28:29]=='0':
outlines.append(inline)
for i in range(int(inline[29:32])):
outlines.append(in_f.readline())
return True
# 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_f):
out_f.writelines(outlines)
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 RINEX 2.xx to Des-format --------------------- #
def rnx2des(in_path, out_path, oriver, desver):
headread=False
outlines=[]
omilist=[]
in_f=open(in_path, 'r')
out_f=open(out_path, 'a')
# convert RINEX 2.xx(header) to Uni-format
match rnx2_head2uni(in_f, desver, outlines, omilist):
case 1: headread=True
case 0: headread=False
if headread:
# convert Uni-foramt(header) to Des-format
match desver[0:1]:
case '2': addemp=uni2rnx2_data(4, outlines, out_f, True, None)
case '3': uni2rnx3_data(outlines, out_f)
outlines=[]
# get each observ type and omit the empty
obsnum=omilist[0]
omilist.pop(0)
getomit(omilist)
# convert RINEX 2.xx(data) to Uni-format
while rnx2_data2uni(in_f, outlines, omilist, obsnum):
# convert Uni-foramt(data) to Des-format
match desver[0:1]:
case '2': uni2rnx2_data(4, outlines, out_f, False, addemp)
case '3': uni2rnx3_data(outlines, out_f)
outlines=[]
elif not headread: return 0
in_f.close()
out_f.close()
return 1
# Get the position of new add observ type ----------------- #
def getaddemp(alltypes, sysstype):
addemp=[[],[],[],[]]
for i in range(len(sysstype)):
for j in range(len(sysstype[i])):
for k in range(len(alltypes)):
if sysstype[i][j]==alltypes[k]:
addemp[i].append(k)
return addemp
# Filter the same obs fmt in RINEX 2.xx ----------------- #
def obsfmt_filter(alltypes):
empemp=[]
spos=npos=0
empemp.append(len(alltypes))
while True:
npos+=1
if spos==empemp[0]: break
if npos==empemp[0]:
spos+=1
npos=spos
continue
if not alltypes[spos]: continue
if not alltypes[npos]: continue
if alltypes[spos]==alltypes[npos]:
alltypes[npos]=emp
empemp.append(npos)
# restruct the data
totnum=empemp[0]
empemp=sorted(empemp[1:])
empemp.insert(0,totnum)
empemp.clear()
# addemp.append(empemp)
# clear the empty
alltypes=[obs for obs in alltypes if obs!=emp]
return alltypes
# Sort by observ type --------------------------- #
def sort_observ(alltypes):
alltypex=[]
temtypes=[]
freindex=['1','2','3','4',
'5','6','7','8']
obsetype=['C','L','D','S']
for type in alltypes:
freidx=freindex.index(type[1:2])/ 1
if type=='P1C' or type=='P2C':
tyeidx=obsetype.index(type[2:3])/10
else:
tyeidx=obsetype.index(type[0:1])/10
alltypex.append(freidx+tyeidx)
sdx=ndx=0
while True:
if len(alltypex)==0:
break
if (ndx+1)==len(alltypex):
temtypes.append(alltypes[sdx])
alltypes.pop(sdx)
alltypex.pop(sdx)
sdx=ndx=0
continue
ndx+=1
if alltypex[ndx]<=alltypex[sdx]:
sdx=ndx
continue
return temtypes
# Convert observ type of RINEX 3.xx to Uni-Format --------------- #
def obsfmt3_conv(alltypes):
alltypex=[]
for type in alltypes:
if type[1:2]=='1':
if type=='C1W': type='P1'
elif type[1:2]=='2':
if type=='C2W': type='P2'
else: pass
alltypex.append(type[0:2])
return alltypex
# Convert observ msg of RINEX 3.xx to Uni-Format ---------------- #
def obstype3_conv(i, sysnum, outlines, outlinex):
alltypes=[]
obstypes=[]
sysstype=[[],[],[],[]]
# rinex message label
obsobs='# / TYPES OF OBSERV'
for j in range(sysnum):
obstypes=[]
# reject system not support in Uni-Format
match outlines[i][0:1]:
case 'G': obstypes.append(0)
case 'E': obstypes.append(1)
case 'R': obstypes.append(2)
case 'S': obstypes.append(3)
case 'C':
i+=math.ceil(int(outlines[i][1:6])/13)
continue
case 'I':
i+=math.ceil(int(outlines[i][1:6])/13)
continue
case 'J':
i+=math.ceil(int(outlines[i][1:6])/13)
continue
case _:
i+=1
continue
obsnum=int(outlines[i][1:6])
for k in range(math.ceil(obsnum/13)):
obstypes.extend(outlines[i][6:60].split())
if k+1==math.ceil(obsnum/13): break
i+=1
# check the differ observ type in glonass
if obstypes[0]==2:
try:
pos=obstypes.index('C1P')
obstypes[pos]='P1C'
except ValueError: pass
try:
pos=obstypes.index('C2P')
obstypes[pos]='P2C'
except ValueError: pass
sysstype[obstypes[0]]=obsfmt3_conv(obstypes[1:])
alltypes=list(set(obstypes[1:]+alltypes))
i+=1
# sort observ types
alltypes=sort_observ(alltypes)
# convert observ type into des-format
alltypes=obsfmt3_conv(alltypes)
# fliter the same observ type
alltypes=obsfmt_filter(alltypes)
# get new added pos
addemp=getaddemp(alltypes, sysstype)
num =len(alltypes)
outline=4*bnk+'%2d'%num
for j in range(num):
outline+=4*bnk+alltypes[j]
if (j+1)==num:
bnx=((9-num%9)*6)*bnk
if num%9==0: bnx=emp
outlinex.append(outline+bnx+obsobs+'\n')
outline=0*bnk
elif (j+1)%9==0:
bnx=0*bnk
outlinex.append(outline+bnx+obsobs+'\n')
outline=6*bnk
# get amout of observ tyeps
addemp.append(num)
return addemp
# Get the total amount of sat system -------------------- #
def getsys_rnx3(in_f):
# rinex message label
obsobs='SYS / # / OBS TYPES'
readst=False
syslis=[]
sysnum=0
while True:
inline=in_f.readline()
if not inline: break
if inline.find(obsobs)>=0:
readst=True
sys=inline[0:1]
if sys==bnk: continue
if sys not in syslis:
syslis.append(sys)
sysnum+=1
elif readst and inline.find(obsobs)<0: break
in_f.seek(0)
return sysnum
# Convert head_data of RINEX 3.xx to Uni-format -------------- #
def rnx3_head2uni(in_f, desver, outlines):
# rinex message label
# obscom='COMMENT'
obstpe='RINEX VERSION / TYPE'
# obspro='PGM / RUN BY / DATE'
# obsobs='SYS / # / OBS TYPES'
obsshi='SYS / PHASE SHIFT'
obsrsb='GLONASS COD/PHS/BIS'
obsrsl='GLONASS SLOT / FRQ #'
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: break
#if inline.find(obscom)>=0: outlines.append(inline)
#elif inline.find(obspro)>=0: outlines.append(inline)
#elif inline.find(obsobs)>=0: outlines.append(inline)
elif inline.find(obstpe)>=0: conv_stamp(inline, outlines, desver)
elif inline.find(obsshi)>=0: continue
elif inline.find(obsrsb)>=0: continue
elif inline.find(obsrsl)>=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 3.xx to Uni-format ------------------- #
def rnx2uni3_data(outlines, in_f):
inline=in_f.readline()
if not inline: return False
if not inline[0:1]=='>': return True
if not int(inline[30:32])==0: return True
outlines.append(inline)
satnum=int(inline[33:35])
for i in range(satnum):
outlines.append(in_f.readline())
return True
# Convert RINEX 3.xx(epoch msg) to RINEX 2.xx --------------- #
def rnx3rnx2_epo(outline, sPRN):
outlines=[]
datedat=outline.split()
# omit data when flag !=0
if not int(datedat[7])==0: return outlines
outline=(
'%3d%3d%3d%3d%3d%11.7f%3d%3d'
%(int(datedat[1])-2000,int(datedat[2]), int(datedat[3]),# |year |month |day
int(datedat[4]) ,int(datedat[5]),float(datedat[6]),# |hour |minute |second
int(datedat[7]) ,len(sPRN))) # |flag |satnum |
# convert to RINEX 2.xx
satnum=len(sPRN)
for i in range(satnum):
outline+=sPRN[i]
if (i+1)==len(sPRN):
outlines.append(outline+'\n')
elif (i+1)%12==0:
outlines.append(outline+'\n')
outline=32*bnk
return outlines
# Convert RINEX 3.xx(data of each sat) to RINEX 2.xx ------------ #
def rnx3rnx2_dat(addemp, obsnum, outline):
outlines=[]
num=range(len(addemp))
empdat=16*bnk
outlinx=[empdat for i in range(obsnum)]
for i,j in zip(num,addemp):
if not outlinx[j]==empdat: continue
if outline[i*16+3:i*16+16+3]:
outlinx[j]=outline[i*16+3:i*16+16+3]\
.replace('\n',2*bnk).replace('\r',2*bnk)
else: continue
outline=emp
for i in range(len(outlinx)):
outline+=outlinx[i]
for i in range(math.ceil(len(outline)/80)):
outlines.append(outline[i*80:i*80+80]+'\n')
return outlines
# Convert RINEX 3.xx to RINEX 2.xx --------------------- #
def rnx3rnx2_data(outlines, addemp):
sPRN=[]
datline=[]
outlinex=[]
# filter the sat system ecxcept:#
# ---GPS-Galileo-GLONASS-SBAS---#
for i in range(len(outlines)):
if outlines[i][0:1]=='G': pass
elif outlines[i][0:1]=='E': pass
elif outlines[i][0:1]=='R': pass
elif outlines[i][0:1]=='S': pass
else: continue
datline.append(i)
sPRN.append(outlines[i][0:3])
outlinex.extend(rnx3rnx2_epo(outlines[0], sPRN))
for i in datline:
if outlines[i][0:1]=='G': idx=0
elif outlines[i][0:1]=='E': idx=1
elif outlines[i][0:1]=='R': idx=2
elif outlines[i][0:1]=='S': idx=3
else: continue
outlinex.extend(rnx3rnx2_dat(addemp[idx], addemp[4], outlines[i]))
return outlinex
# Convert Uni-format to RINEX 2.xx --------------------- #
def uni2rnx2_data(sysnum, outlines, out_f, headordata, add_emp):
# rinex message label
obspro='PGM / RUN BY / DATE'
obsobs='SYS / # / OBS TYPES'
obsend='END OF HEADER'
outlinex=[]
obsread=False
# convert Uni-format to RINEX 2.xx(header)
if headordata:
for i in range(len(outlines)):
if outlines[i].find(obspro)>=0: outlinex.append(datefmt3_conv(outlines[i]))
elif outlines[i].find(obsobs)>=0:
if not obsread:
obsread=True
addemp=obstype3_conv(i, sysnum, outlines, outlinex)
else: continue
elif outlines[i].find(obsend)>=0: outlinex.append(outlines[i])
else:outlinex.append(outlines[i])
# convert Uni-format to RINEX 2.xx(data)
elif not headordata:
if not outlines: return 0
outlinex=rnx3rnx2_data(outlines, add_emp)
# output to destination file
out_f.writelines(outlinex)
if headordata: return addemp
elif not headordata: return 0
# Convert data of RINEX 3.xx to Des-format ----------------- #
def rnx3des(in_path, out_path, oriver, desver):
headread=False
outlines=[]
in_f=open(in_path, 'r')
out_f=open(out_path, 'a')
# get the amount of sat system
sysnum=getsys_rnx3(in_f)
# convert RINEX 3.xx(header) to Uni-format
match rnx3_head2uni(in_f, desver, outlines):
case 1: headread=True
case 0: headread=False
# convert Uni-foramt(header) to Des-format
if headread:
match desver[0:1]:
case '2': addemp=uni2rnx2_data(sysnum, outlines, out_f, True, None)
case '3': uni2rnx3_data(outlines, out_f)
outlines=[]
# convert RINEX 3.xx(data) to Uni-format
while rnx2uni3_data(outlines, in_f):
# convert Uni-foramt(data) to Des-format
match desver[0:1]:
case '2': uni2rnx2_data(sysnum, outlines, out_f, False, addemp)
case '3': uni2rnx3_data(outlines, out_f)
outlines=[]
elif not headread: return 0
in_f.close()
out_f.close()
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': rnx3des(in_path, out_path, oriver, desver)
else : return resqueue.put(0)
return resqueue.put(1)
# 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()
-18
View File
@@ -1,18 +0,0 @@
# @ File : rtcm_convert.py.py
#
# Copyright (c) 2024 - 2024 KenanZhu. All Right Reserved.
#
# @ Author : KenanZhu
# @ Time : 2024/11/16
# @ Brief :
# :
# @ IDE : PyCharm
#
# ----------------------------------------------------------------------------------------
# ---SELPORT--- #
# ---STDPORT--- #
# ------------- #
def Convert_Un():
return 0
+404
View File
@@ -0,0 +1,404 @@
#pragma once
#ifndef _BRDM2POS_H_
#define _BRDM2POS_H_
#include <iostream>
#include <math.h>
#include <time.h>
#endif // _BRDM2POS_H_
#define KNZ_GTL_VER "1.5.5.0"
/* CALCU CONST*/
#define C_V 299792458 /* Speed of light (m/s) */
#define GM 398600500000000 /* */
#define math_e 2.718281828459 /* Natural constant e */
#define PI 3.141592653589793 /* Ratio of circumference to diameter */
#define Earth_e 7.2921151467e-5 /* Rotational angular velocity of the earths (omega/s) */
#define C20 1.0826257e-3 /* */
#define DAYSEC 86400 /* The total second of a day */
/*WGS-84 CONST*/
#define a 6378137.0
#define e2 (0.0033528106647475*(2 - 0.0033528106647475))
/*PZ-90 CONST*/
#define TSTEP 30.0 /* RK-4 step */
/*GNSS OBSERV TYPE*/
#define FREQ1 1.57542E9 /* L1/E1/B1C frequency (Hz) */
#define FREQ2 1.22760E9 /* L2 frequency (Hz) */
#define FREQ5 1.17645E9 /* L5/E5a/B2a frequency (Hz) */
#define FREQ6 1.27875E9 /* E6/L6 frequency (Hz) */
#define FREQ7 1.20714E9 /* E5b frequency (Hz) */
#define FREQ8 1.191795E9 /* E5a+b frequency (Hz) */
#define FREQ9 2.492028E9 /* S frequency (Hz) */
#define FREQ1_GLO 1.60200E9 /* GLONASS G1 base frequency (Hz) */
#define DFRQ1_GLO 0.56250E6 /* GLONASS G1 bias frequency (Hz/n) */
#define FREQ2_GLO 1.24600E9 /* GLONASS G2 base frequency (Hz) */
#define DFRQ2_GLO 0.43750E6 /* GLONASS G2 bias frequency (Hz/n) */
#define FREQ3_GLO 1.202025E9 /* GLONASS G3 frequency (Hz) */
#define FREQ1a_GLO 1.600995E9 /* GLONASS G1a frequency (Hz) */
#define FREQ2a_GLO 1.248060E9 /* GLONASS G2a frequency (Hz) */
#define FREQ1_BDS 1.561098E9 /* BDS B1I frequency (Hz) */
#define FREQ2_BDS 1.20714E9 /* BDS B2I/B2b frequency (Hz) */
#define FREQ3_BDS 1.26852E9 /* BDS B3 frequency (Hz) */
//frequency 1
#define C1 100
#define C1A 100
#define C1B 101
#define C1C 102
#define C1D 103
#define C1L 104
#define C1M 105
#define C1P 106
#define C1S 107
#define C1X 108
#define C1Y 109
#define C1Z 110
//frequency 2
#define C2 200
#define C2C 200
#define C2D 201
#define C2I 202
#define C2L 203
#define C2M 204
#define C2P 205
#define C2Q 206
#define C2R
#define C2S 207
#define C2X 208
#define C2Y 209
#define C2Z 210
//frequency 3
#define C3 300
#define C3I 300
#define C3Q 301
#define C3X 302
//frequency 4
#define C4 400
#define C4A 400
#define C4B 401
#define C4X 402
//frequency 5
#define C5 500
#define C5I 500
#define C5Q 501
#define C5X 502
//frequency 6
#define C6 600
#define C6A 600
#define C6B 601
#define C6C 602
#define C6X 603
#define C6Z 604
//frequency 7
#define C7 700
#define C7I 700
#define C7Q 701
#define C7X 702
//frequency 8
#define C8 800
#define C8I 800
#define C8Q 801
#define C8X 802
/*GNSS CODE*/
#define GPS 01
#define BDS 02
#define GAL 03
#define GLO 04
#define SBAS 05
#define MAXTOE_GPS 7200.0
#define MAXTOE_BDS 21600.0
#define MAXTOE_GAL 14400.0
#define MAXTOE_GLO 1800.0
#define MAXTOE_SBS 360.0
#define TIMEGAP_GPS 7200.0
#define TIMEGAP_BDS 3600.0
#define TIMEGAP_GAL 600.0
#define TIMEGAP_GLO 1800.0
#define MAXRINEX 4096 /* Max length of line of rinex file */
#define MAXPATH 260 /* Max length of file path */
typedef struct pos_ts{//Satellite position
double X;
double Y;
double Z;
double deltat;
double delta_t;
double delta_clk;
}pos_ts;
typedef struct stations{//
double X;
double Y;
double Z;
double delta_TR;
}stations;
typedef struct rah{//
double R;
double A;
double H;
}rah;
typedef struct enu{//East/North/Up coordinate system
double E;
double N;
double U;
}enu;
typedef struct blh{//Longitude/Latitude/Altitude coordinate system
double B;
double L;
double H;
}blh;
typedef struct blhdms{//Longitude/Latitude/Altitude coordinate system
//With Degree/Minute/Second
double B;
int B_d;
int B_m;
int B_s;
double L;
int L_d;
int L_m;
int L_s;
double H;
}blhdms;
typedef struct nav_head{//Header data of file of nav
double ver; /* RINEX version */
char type[20]; /* RINEX file format */
double ION_GPSA[4]; /* Ionosphere correction parameters alpha GPS */
double ION_GPSB[4]; /* Ionosphere correction parameters belta GPS */
double ION_BDSA[4]; /* Ionosphere correction parameters alpha BeiDou */
double ION_BDSB[4]; /* Ionosphere correction parameters belta BeiDou */
double ION_QZSA[4]; /* Ionosphere correction parameters alpha QZSS */
double ION_QZSB[4]; /* Ionosphere correction parameters belta QZSS */
double ION_IRNA[4]; /* Ionosphere correction parameters alpha */
double ION_IRNB[4]; /* Ionosphere correction parameters belta */
double GPUT[4]; /* Time system correction of GPST */
double GLUT[4]; /* Time system correction of GLONASST */
double GAUT[4]; /* Time system correction of GALT */
double BDUT[4]; /* Time system correction of BDT */
double QZUT[4]; /* Time system correction of QZST */
double IRUT[4]; /* Time system correction of */
double SBUT[4]; /* Time system correction of SBAST */
int leap; /* Leap second */
}nav_head, * pnav_head;
typedef struct nav_body{//Body data of file of nav: GPS BeiDou Galileo GLONASS
/* GPS BeiDou Galileo GLONASS*/
int sPRN_GPS; int sPRN_BDS; int sPRN_GAL; int sPRN_GLO;/* System */
int TOC_Y;
int TOC_M;
int TOC_D;
int TOC_H;
int TOC_Min;
int TOC_Sec;
double sa0;
double sa1;
double sa2; double Dos;
double IODE; double AODE; double SatX;
double Crs; double SatXv;
double deltan; double SatXa;
double M0;
double Cuc; double SatY;
double e; double SatYv;
double Cus; double SatYa;
double sqrtA; int FreN;
double TOE; double SatZ;
double Cic; double SatZv;
double OMEGA; double SatZa;
double Cis; int AOO;
double i0;
double Crc;
double omega;
double deltaomega;
double IDOT;
double L2code; int Datasource;
double GPSweek; double BDTweek; double GALweek;
double L2Pflag;
double sACC;
double sHEA;
double TGD; double TGD1; double BGDa;
double IODC; double TGD2; double BGDb;
double TTN;
double fit; double AODC;
double spare1;
double spare2;
}nav_body, * pnav_body;
typedef struct obs_head{//Header data of file of obs
double ver;
char type[30];
char marker[10];
double apX;
double apY;
double apZ;
double apB;
double apL;
double apH;
double ANTH;
double ANTdeltaE;
double ANTdeltaN;
int obstypenum_gps; /* Observation amount of GPS */
int obstypenum_bds; /* Observation amount of BeiDou */
int obstypenum_gal; /* Observation amount of Galilro */
int obstypenum_glo; /* Observation amount of GLONASS */
int obscode_gps[40];/* Observation code of GPS */
int obscode_bds[40];/* Observation code of BeiDou */
int obscode_gal[40];/* Observation code of Galileo */
int obscode_glo[40];/* Observation code of GLONASS */
double interval; /* */
int f_y; /* Year of first observe */
int f_m; /* Month of first observe */
int f_d; /* Day of first observe */
int f_h; /* Hour of first observe */
int f_min; /* Minute of first observe */
double f_sec; /* Second of first observe */
int l_y; /* Year of last observe */
int l_m; /* Month of last observe */
int l_d; /* Day of last observe */
int l_h; /* Hour of last observe */
int l_min; /* Minute of last observe */
double l_sec; /* Second of last observe */
char tsys[5]; /* Time system of obs */
}obs_head, * pobs_head;
typedef struct obs_epoch{//Epoch data of file of obs
int y; /* Epoch year */
int m; /* Epoch month */
int d; /* Epoch day */
int h; /* Epoch hour */
int min; /* Epoch minute */
double sec; /* Epoch second */
int p_flag; /* Epoch flag */
int sat_num; /* The total number of obsable sat */
int gps_num; /* The total GPS satellite */
int bds_num; /* The total BeiDou satellite */
int gal_num; /* The total Galileo satellite */
int glo_num; /* The total GLONASS satellite */
int sPRN[84]; /* Total sprn of obs satellite */
int sPRN_GPS[32];/* Total sprn of GPS satellite in this epoch */
int sPRN_BDS[60];/* Total sprn of BeiDou satellite in this epoch */
int sPRN_GAL[30];/* Total sprn of Galileo satellite in this epoch */
int sPRN_GLO[24];/* Total sprn of GLONASS satellite in this epoch */
}obs_epoch, * pobs_epoch;
typedef struct obs_body{//Body data of file of obs
double obs_gps[30][26];/* GPS obs data */
double obs_bds[40][26];/* BeiDou obs data */
double obs_gal[30][26];/* Galileo obs data */
double obs_glo[30][26];/* GLONASS obs data */
}obs_body, * pobs_body;
typedef struct lsq_part {
double* l;
double* m;
double* n;
double* o;
double* B;
double* P;
double* L;
double* x;
}lsq_part;
typedef struct acct_obs {
double Per1[30];
double Per2[30];
double sclk[30];
int freq1;
int freq2;
acct_obs() = default;
}acct_obs;
//Contain in timesys.cpp
extern double jdutc2gpst(double JD_UTCSU);
extern double time2gpst(int y, int m, int d, double h, int min, double sec);
extern double utctime2jd(int y, int m, int d, double h, int min, double sec);
//Contain in martix.cpp
extern double* mat(int n, int m);
extern int* imat(int n, int m);
extern double* zeros(int n, int m);
extern double* eye(int n);
extern double dot(const double* va, const double* vb, int n);
extern double norm(const double* va, int n);
extern void cross3(const double* va, const double* vb, double* vc);
extern int normv3(const double* va, double* vb);
extern void matcpy(double* A, const double* B, int n, int m);
extern void matmul(const char* tr, int n, int k, int m, double alpha,
const double* A, const double* B, double beta, double* C);
extern int matinv(double* A, int n);
extern int solve(const char* tr, const double* A, const double* Y, int n,
int m, double* X);
extern stations designmat(pobs_head obs_h, acct_obs obs,
double* l, double* m, double* n, double* o,
double* B, double* P, double* L,
double X, double Y, double Z, int satnum, int ionopt, int tropopt,
int GNSS);
extern int lsq(const double* BtP, const double* L, const double* B, int n, int m, double* x,
double* Q);
extern void matprint(const double A[], int n, int m, int p, int q);
//Contain in coordtrans.cpp
extern double deg2rad(double deg);
extern double rad2deg(double rad);
extern rah rahcal(rah rah, double E, double N, double U);
extern enu blh2enu(enu enu, double stationB, double stationL,
double deltax, double deltay, double deltaz);
extern blh xyz2blh(blh blh, double X, double Y, double Z);
extern rah xyz2rah(pos_ts pos_t, pobs_head obs_h);
extern void pz90towgs84(double X, double Y, double Z);
//Contain in readrnx.cpp
extern int getsatnum(FILE*);
extern int get_epochnum(FILE*);
extern void freeobs_e(pobs_epoch, pobs_body);
extern int type2code(int, char buff[MAXRINEX]);
extern int code2type(int, int, int typearr[36]);
extern int select_epoch(double, int, pnav_body, int, int);
//Contain in readrnx.cpp/read
extern void read_n_h(FILE*, pnav_head);
extern void read_n_b(FILE*, pnav_body);
extern void read_o_h(FILE*, pobs_head);
extern void read_o_eb(FILE*, pobs_head, pobs_epoch, pobs_body);
//Contain in solutionout.cpp
extern FILE* headerout(pobs_head obs_h, int mode, char obs_path[MAXPATH], char nav_path[MAXPATH], char res_path[MAXPATH]);
extern void solution(FILE* res_file, pobs_head obs_h, double X, double Y, double Z);
extern void outdata(blh blh, FILE* res_file, int sPRN, int GNSS);
//Entry function
extern "C" _declspec(dllexport) double brdm2pos(
char nav_path[MAXPATH],
char obs_path[MAXPATH],
char res_path[MAXPATH],
int GNSS,
int Hangle,
int ionopt,
int tropopt,
int genmode);
+134
View File
@@ -0,0 +1,134 @@
#include "brdm2pos.h"
using namespace std;
/**
* Degree to radian.
*
* \param deg: Degree
* \return Radian
*/
double deg2rad(double deg)
{
double rad = (PI / 180) * deg;
return rad;
}
/**
* Radian to degree .
*
* \param rad: Radian
* \return Degree
*/
double rad2deg(double rad)
{
double deg = (180 / PI) * rad;
return deg;
}
/**
* Azimuth/Calculate.
*
* \param rah: Parameter transfer structure
* \param E: East
* \param N: North
* \param U: Up
* \return structure contain R, A, H members
*/
rah rahcal(rah rah,
double E, double N, double U)
{
rah.H = atan2(U, sqrt(E * E + N * N));
rah.A = atan2(E, U);
if (rah.A < 0)
rah.A += 2 * PI;
if (rah.A > 2 * PI)
rah.A -= 2 * PI;
rah.R = sqrt(E * E + N * N + U * U);
return rah;
}
/**
* Convert BLH coordinates to ENU coordinates.
*
* \param enu: Parameter transfer structure
* \param stationB: Latitude of receiver station
* \param stationL: Longitude of receiver station
* \param deltax: Deltax X-coordinate difference of satellite arrival center
* \param deltay: Deltax Y-coordinate difference of satellite arrival center
* \param deltaz: Deltax Z-coordinate difference of satellite arrival center
* \return
*/
enu blh2enu(enu enu,
double stationB, double stationL,
double deltax, double deltay, double deltaz)
{
double sinB = sin(stationB);
double cosB = cos(stationB);
double sinL = sin(stationL);
double cosL = cos(stationL);
enu.E = -sinL * (deltax) +cosL * (deltay);
enu.N = -sinB * cosL * (deltax)-sinB * sinL * (deltay)+cosB * (deltaz);
enu.U = cosB * cosL * (deltax)+cosB * sinL * (deltay)+sinB * (deltaz);
return enu;
}
/**
* Convert ECEF geostationary coordinates to BLH coordinates.
*
* \param blh: Parameter transfer structure
* \param X: X coordinates of ECEF
* \param Y; Y coordinates of ECEF
* \param Z: Z coordinates of ECEF
* \return type of structure contain B, L, H members
*/
blh xyz2blh(blh blh,
double X, double Y, double Z)
{
double B = 0.0, N = 0.0, H = 0.0, R0, R1, deltaH, deltaB;
R0 = sqrt(pow(X, 2) + pow(Y, 2));
R1 = sqrt(pow(X, 2) + pow(Y, 2) + pow(Z, 2));
blh.L = atan2(Y, X);
N = a;
H = R1 - a;
B = atan2(Z * (N + H), R0 * (N * (1 - e2) + H));
do{
deltaH = N;
deltaB = B;
N = a / sqrt(1 - e2 * pow(sin(B), 2));
H = R0 / cos(B) - N;
B = atan2(Z * (N + H), R0 * (N * (1 - e2) + H));
} while (fabs(deltaH - H) > 1.0e-3 && fabs(deltaB - B) > 1.0e-9);
blh.B = B;
blh.H = H;
return blh;
}
rah xyz2rah(pos_ts pos_t, pobs_head obs_h)
{
double
deltax,
deltay,
deltaz;
enu enu = { 0 };
rah rah = { 0 };
deltax = pos_t.X - obs_h->apX;
deltay = pos_t.Y - obs_h->apY;
deltaz = pos_t.Z - obs_h->apZ;
enu = blh2enu(enu, obs_h->apB, obs_h->apL,
deltax, deltay, deltaz);
//Satellite elevation Angle calculation
rah = rahcal(rah, enu.E, enu.N, enu.U);
return rah;
}
/**
* Convert from PZ-90 to WGS-84.
*
* \param X: Coordinate in PZ-90
*/
void pz90towgs84(double X, double Y, double Z)
{
while (X || Y || Z) {
X = -0.47 + (X * 1 + Y * 1.728e-6 + Z * -0.017e-6) * (1 + 22e-9);
Y = -0.51 + (X * 1.728e-6 + Y * 1 + Z * -0.076e-6) * (1 + 22e-9);
Z = -1.56 + (X * 0.0178e-6 + Y * -0.076e-6 + Z * 1) * (1 + 22e-9);//PZ90 Convert to WGS-84
break;
}return;
}
+231
View File
@@ -0,0 +1,231 @@
#include "brdm2pos.h"
/* new matrix ------------------------------------------------------------------
* allocate memory of matrix
* args : int n,m I number of rows and columns of matrix
* return : matrix pointer (if n<=0 or m<=0, return NULL)
*-----------------------------------------------------------------------------*/
double* mat(int n, int m)
{
double* p;
if (n <= 0 || m <= 0) return NULL;
if (!(p = (double*)malloc(sizeof(double) * n * m))) {
return NULL;
}
return p;
}
/* new integer matrix ----------------------------------------------------------
* allocate memory of integer matrix
* args : int n,m I number of rows and columns of matrix
* return : matrix pointer (if n<=0 or m<=0, return NULL)
*-----------------------------------------------------------------------------*/
int* imat(int n, int m)
{
int* p;
if (n <= 0 || m <= 0) return NULL;
if (!(p = (int*)malloc(sizeof(int) * n * m))) {
return NULL;
}
return p;
}
/* zero matrix -----------------------------------------------------------------
* generate new zero matrix
* args : int n,m I number of rows and columns of matrix
* return : matrix pointer (if n<=0 or m<=0, return NULL)
*-----------------------------------------------------------------------------*/
double* zeros(int n, int m)
{
double* p;
#if NOCALLOC
if ((p = mat(n, m))) for (n = n * m - 1; n >= 0; n--) p[n] = 0.0;
#else
if (n <= 0 || m <= 0) return NULL;
if (!(p = (double*)calloc(sizeof(double), n * m))) {
return NULL;
}
#endif
return p;
}
/* identity matrix -------------------------------------------------------------
* generate new identity matrix
* args : int n I number of rows and columns of matrix
* return : matrix pointer (if n<=0, return NULL)
*-----------------------------------------------------------------------------*/
double* eye(int n)
{
double* p;
int i;
if ((p = zeros(n, n))) for (i = 0; i < n; i++) p[i + i * n] = 1.0;
return p;
}
/* inner product ---------------------------------------------------------------
* inner product of vectors
* args : double *a,*b I vector a,b (n x 1)
* int n I size of vector a,b
* return : a'*b
*-----------------------------------------------------------------------------*/
double dot(const double* va, const double* vb, int n)
{
double c = 0.0;
while (--n >= 0) c += va[n] * vb[n];
return c;
}
/* euclid norm -----------------------------------------------------------------
* euclid norm of vector
* args : double *a I vector a (n x 1)
* int n I size of vector a
* return : || a ||
*-----------------------------------------------------------------------------*/
double norm(const double* va, int n)
{
return sqrt(dot(va, va, n));
}
/* outer product of 3d vectors -------------------------------------------------
* outer product of 3d vectors
* args : double *a,*b I vector a,b (3 x 1)
* double *c O outer product (a x b) (3 x 1)
* return : none
*-----------------------------------------------------------------------------*/
void cross3(const double* va, const double* vb, double* vc)
{
vc[0] = va[1] * vb[2] - va[2] * vb[1];
vc[1] = va[2] * vb[0] - va[0] * vb[2];
vc[2] = va[0] * vb[1] - va[1] * vb[0];
}
/* normalize 3d vector ---------------------------------------------------------
* normalize 3d vector
* args : double *a I vector a (3 x 1)
* double *b O normlized vector (3 x 1) || b || = 1
* return : status (1:ok,0:error)
*-----------------------------------------------------------------------------*/
int normv3(const double* va, double* vb)
{
double r;
if ((r = norm(va, 3)) <= 0.0) return 0;
vb[0] = va[0] / r;
vb[1] = va[1] / r;
vb[2] = va[2] / r;
return 1;
}
/* copy matrix -----------------------------------------------------------------
* copy matrix
* args : double *A O destination matrix A (n x m)
* double *B I source matrix B (n x m)
* int n,m I number of rows and columns of matrix
* return : none
*-----------------------------------------------------------------------------*/
void matcpy(double* A, const double* B, int n, int m)
{
memcpy(A, B, sizeof(double) * n * m);
}
/*multiply matrix*/
void matmul(const char* tr, int n, int k, int m, double alpha,
const double* A, const double* B, double beta, double* C)
{
double d;
int i, j, x, f = tr[0] == 'N' ? (tr[1] == 'N' ? 1 : 2) : (tr[1] == 'N' ? 3 : 4);
for (i = 0; i < n; i++) for (j = 0; j < k; j++) {
d = 0.0;
switch (f) {
case 1: for (x = 0; x < m; x++) d += A[i + x * n] * B[x + j * m]; break;
case 2: for (x = 0; x < m; x++) d += A[i + x * n] * B[j + x * k]; break;
case 3: for (x = 0; x < m; x++) d += A[x + i * m] * B[x + j * m]; break;
case 4: for (x = 0; x < m; x++) d += A[x + i * m] * B[j + x * k]; break;
}
if (beta == 0.0) C[i + j * n] = alpha * d; else C[i + j * n] = alpha * d + beta * C[i + j * n];
}
}
/*LU decomposition*/
static int ludcmp(double* A, int n, int* indx, double* d)
{
double big, s, tmp, * vv = mat(n, 1);
int i, imax = 0, j, k;
*d = 1.0;
for (i = 0; i < n; i++) {
big = 0.0; for (j = 0; j < n; j++) if ((tmp = fabs(A[i + j * n])) > big) big = tmp;
if (big > 0.0) vv[i] = 1.0 / big; else { free(vv); return -1; }
}
for (j = 0; j < n; j++) {
for (i = 0; i < j; i++) {
s = A[i + j * n]; for (k = 0; k < i; k++) s -= A[i + k * n] * A[k + j * n]; A[i + j * n] = s;
}
big = 0.0;
for (i = j; i < n; i++) {
s = A[i + j * n]; for (k = 0; k < j; k++) s -= A[i + k * n] * A[k + j * n]; A[i + j * n] = s;
if ((tmp = vv[i] * fabs(s)) >= big) { big = tmp; imax = i; }
}
if (j != imax) {
for (k = 0; k < n; k++) {
tmp = A[imax + k * n]; A[imax + k * n] = A[j + k * n]; A[j + k * n] = tmp;
}
*d = -(*d); vv[imax] = vv[j];
}
indx[j] = imax;
if (A[j + j * n] == 0.0) { free(vv); return -1; }
if (j != n - 1) {
tmp = 1.0 / A[j + j * n]; for (i = j + 1; i < n; i++) A[i + j * n] *= tmp;
}
}
free(vv);
return 0;
}
/*LU back-substitution*/
static void lubksb(const double* A, int n, const int* indx, double* b)
{
double s;
int i, ii = -1, ip, j;
for (i = 0; i < n; i++) {
ip = indx[i]; s = b[ip]; b[ip] = b[i];
if (ii >= 0) for (j = ii; j < i; j++) s -= A[i + j * n] * b[j]; else if (s) ii = i;
b[i] = s;
}
for (i = n - 1; i >= 0; i--) {
s = b[i]; for (j = i + 1; j < n; j++) s -= A[i + j * n] * b[j]; b[i] = s / A[i + i * n];
}
}
/*inverse of matrix*/
int matinv(double* A, int n)
{
double d, * B;
int i, j, * indx;
indx = imat(n, 1); B = mat(n, n); matcpy(B, A, n, n);
if (ludcmp(B, n, indx, &d)) { free(indx); free(B); return -1; }
for (j = 0; j < n; j++) {
for (i = 0; i < n; i++) A[i + j * n] = 0.0;
A[j + j * n] = 1.0;
lubksb(B, n, indx, A + j * n);
}
free(indx); free(B);
return 0;
}
/*solve linear equation*/
int solve(const char* tr, const double* A, const double* Y, int n,
int m, double* X)
{
double* B = mat(n, n);
int info;
matcpy(B, A, n, n);
if (!(info = matinv(B, n))) matmul(tr[0] == 'N' ? "NN" : "TN", n, m, n, 1.0, B, Y, 0.0, X);
free(B);
return info;
}
void matprint(const double A[], int n, int m, int p, int q)
{
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) printf(" %*.*f", p, q, A[i + j * n]);
printf("\n");
}
}
+773
View File
@@ -0,0 +1,773 @@
#include "brdm2pos.h"
using namespace std;
/**
* Find the nearest obs epoch with boardcast.
*
* \param SecofWeek: SecofWeek second of week of obs epoch time
* \param sPRN: sPRN the satellite PRN which need to match
* \param nav_b: Nav data file structure
* \param satnum: Total number of boardcast satellite
* \param syscode: GNSS code
* \return the absolute epoch number of the best epoch
* -1 ,no match satellite
*/
int select_epoch(double SecofWeek, int sPRN, pnav_body nav_b, int satnum, int syscode)
{
int best_epoch = -1;
double min;//Initialize the minimum value
double Min;
if (syscode == GPS){//GPS
min = MAXTOE_GPS;
for (int i = 0; i < satnum; i++){
if (sPRN == nav_b[i].sPRN_GPS && nav_b[i].sHEA == 0) {
Min = fabs(SecofWeek - nav_b[i].TOE);
if (Min <= min){
best_epoch = i;
min = Min;
}
}
}return best_epoch;
}
else if (syscode == BDS){//BeiDou
min = MAXTOE_BDS;
for (int i = 0; i < satnum; i++){
if (sPRN == nav_b[i].sPRN_BDS){
Min = fabs(SecofWeek - nav_b[i].TOE);
if (Min <= min){
best_epoch = i;
min = Min;
}
}
}return best_epoch;
}
else if (syscode == GAL){//Galileo
min = MAXTOE_GAL;
for (int i = 0; i < satnum; i++){
if (sPRN == nav_b[i].sPRN_GAL){
Min = fabs(SecofWeek - nav_b[i].TOE);
if (Min <= min){
best_epoch = i;
min = Min;
}
}
}return best_epoch;
}
else if (syscode == GLO){//GLONASS
min = MAXTOE_GLO;
for (int i = 0; i < satnum; i++){
if (sPRN == nav_b[i].sPRN_GLO){
Min = fabs(SecofWeek - nav_b[i].TOE);
if (Min <= min){
best_epoch = i;
min = Min;
}
}
}return best_epoch;
}return best_epoch;
}
/**
* Match the observation type(char*) with the code type(int).
*
* \param Lxcodeindex: Frequency X observation type(char*)
* \param code_original: The observation will matched
* \param freq: Observation frequency
* \return code type
*/
static int findtype(const char Lxcodeindex[60], char code_original[4], int freq)
{
int code_return = 0;
char code_contrast[4] = "/0";
for (int j = 0; j < (strlen(Lxcodeindex) / 3); j++) {
strncpy(code_contrast, Lxcodeindex + 0 + j * 3, 3);
if (strcmp(code_contrast, code_original) == 0) {
code_return = j + freq;
}
}return code_return;
}
/**
* Converts the observation type to the numeric code defined.
*
* \param i: Reads the number of incoming loops in the loop
* \param buff: Type of incoming observation
* \return
*/
int type2code(int i, char buff[MAXRINEX])
{
int code_return = 0;
char code_original[4] = "/0";
const char L1codeindex[] = "C1AC1BC1CC1DC1LC1MC1PC1SC1XC1YC1Z";//obs type of different frequency
const char L2codeindex[] = "C2CC2DC2IC2LC2MC2PC2QC2SC2XC2YC2Z";
const char L3codeindex[] = "C3IC3QC3X";
const char L4codeindex[] = "C5IC5QC5X";
const char L5codeindex[] = "C5IC5QC5X";
const char L6codeindex[] = "C6AC6BC6CC6XC6Z";
const char L7codeindex[] = "C7IC7QC7XC7DC7PC7Z";
const char L8codeindex[] = "C8IC8QC8X";
strncpy(code_original, buff + 7 + 4 * i, 3);
if (strstr(code_original, "1")) return findtype(L1codeindex, code_original, C1);
else if (strstr(code_original, "2")) return findtype(L2codeindex, code_original, C2);
else if (strstr(code_original, "3")) return findtype(L3codeindex, code_original, C3);
else if (strstr(code_original, "4")) return findtype(L4codeindex, code_original, C4);
else if (strstr(code_original, "5")) return findtype(L5codeindex, code_original, C5);
else if (strstr(code_original, "6")) return findtype(L6codeindex, code_original, C6);
else if (strstr(code_original, "7")) return findtype(L7codeindex, code_original, C7);
else if (strstr(code_original, "8")) return findtype(L8codeindex, code_original, C8);
else return 0;
}
/**
* Match the obs code and convert into type.
*
* \param type: Obs type that you want to match
* \param typenum: The total number of obs types
* \param typearr: Type codes store arrays
* \return the array position of the corresponding obs type code
*/
int code2type(int type, int typenum, int typearr[36])
{
int pos;
for (pos = 0; pos < typenum; pos++) {
if ((typearr[pos] - typearr[pos] % 100) == type) {
return pos;
}
}return pos;
}
/**
* Broad form of function code2type.
*
* \param exclude: The excluded type
* \param typenum: The total number of obs types
* \param typearr: Type codes store arrays
* \return the array position of the corresponding obs type code
*/
int code2type_broad(int exclude, int freq, int typenum, int typearr[36])
{
int pos;
for (pos = 0; pos < typenum; pos++) {
if (typearr[pos] == 0 ? (0) : ((typearr[pos] - typearr[pos] % 100) == exclude ? 0 : 1)) {
return pos;
}
}return pos;
}
/*Read the file of rnx*/
/**
* Convert the string to number.
*
* \param buff
* \param i: Position of begin to read
* \param n: The number of character will to capture
* \return number of string you captured
*
* @Author: T. TAKASU
*
* Function will return 0.0 as error code when three occasion are below:
* 1.Begining position < 0
* 2.The number of Byte of read < i
* 3.The Byte size of string < n
*/
static double strtonum(const char* buff, int i, int n)
{
double value = 0.0;char str[256] = { 0 };char* p = str;
if (i < 0 || (int)strlen(buff) < i || (int)sizeof(str) - 1 < n) {
return 0.0;
}
for (buff += i; *buff && --n >= 0; buff++) {
*p++ = ((*buff == 'D' || *buff == 'd') ? 'e' : *buff);
}
*p = '\0';
return sscanf(str, "%lf", &value) == 1 ? value : 0.0;
}
/*Free the memory of observation structure*/
void freeobs_e(pobs_epoch obs_e, pobs_body obs_b)
{
free(obs_e); free(obs_b);
}
/*Read the file of nav*/
/**
* Get the total amount of satellite boardcast data of nav file .
*
* \param fp_nav: The file pointer of nav file
* \return amount of satellite
*/
int getsatnum(FILE* fp_nav)
{
int satnum = 0;
char buff[MAXRINEX];
char satvar;
char* lable = buff + 60;
while (fgets(buff, MAXRINEX, fp_nav)) {
if (strstr(lable, "RINEX VERSION / TYPE")) {
if (strtonum(buff, 0, 9) < 3 || strtonum(buff, 0, 9) >= 4) return -1;
}
if (strstr(lable, "END OF HEADER")) {
while (fgets(buff, MAXRINEX, fp_nav)) {
strncpy(&satvar, buff + 0, 1);
if (satvar == 'G' || satvar == 'E' || satvar == 'R' || satvar == 'S' || satvar == 'C' || satvar == 'I' || satvar == 'J') {
satnum++;
}
else {
continue;
}
}
}
}return satnum;
}
/*Read the header data of file of nav*/
void read_n_h(FILE* fp_nav, pnav_head nav_h)
{
char buff[MAXRINEX] = { 0 };
char* lable = buff;
int i = 0;
int j = 0;
while (fgets(buff, MAXRINEX, fp_nav)) {
if (strstr(lable, "RINEX VERSION / TYPE")) {
nav_h->ver = strtonum(buff, 0, 9);
strncpy((nav_h->type), buff + 20, 15);
continue;}
else if (strstr(lable, "GPSA")) {
nav_h->ION_GPSA[0] = strtonum(buff, 6, 12);
nav_h->ION_GPSA[1] = strtonum(buff, 6 + 12, 12);
nav_h->ION_GPSA[2] = strtonum(buff, 6 + 12 + 12, 12);
nav_h->ION_GPSA[3] = strtonum(buff, 6 + 12 + 12 + 12, 12);
continue;}
else if (strstr(lable, "GPSB")) {
nav_h->ION_GPSB[0] = strtonum(buff, 6, 12);
nav_h->ION_GPSB[1] = strtonum(buff, 6 + 12, 12);
nav_h->ION_GPSB[2] = strtonum(buff, 6 + 12 + 12, 12);
nav_h->ION_GPSB[3] = strtonum(buff, 6 + 12 + 12 + 12, 12);
continue;}
else if (strstr(lable, "BDSA")) {
nav_h->ION_BDSA[0] = strtonum(buff, 6, 12);
nav_h->ION_BDSA[1] = strtonum(buff, 6 + 12, 12);
nav_h->ION_BDSA[2] = strtonum(buff, 6 + 12 + 12, 12);
nav_h->ION_BDSA[3] = strtonum(buff, 6 + 12 + 12 + 12, 12);
continue;}
else if (strstr(lable, "BDSB")) {
nav_h->ION_BDSB[0] = strtonum(buff, 6, 12);
nav_h->ION_BDSB[1] = strtonum(buff, 6 + 12, 12);
nav_h->ION_BDSB[2] = strtonum(buff, 6 + 12 + 12, 12);
nav_h->ION_BDSB[3] = strtonum(buff, 6 + 12 + 12 + 12, 12);
continue;}
else if (strstr(lable, "BDUT")) {
nav_h->BDUT[0] = strtonum(buff, 5, 17);
nav_h->BDUT[1] = strtonum(buff, 5 + 17, 16);
nav_h->BDUT[2] = strtonum(buff, 5 + 17 + 16, 7);
nav_h->BDUT[3] = strtonum(buff, 5 + 17 + 16 + 7, 5);
continue;}
else if (strstr(lable, "GPUT")) {
nav_h->GPUT[0] = strtonum(buff, 5, 17);
nav_h->GPUT[1] = strtonum(buff, 5 + 17, 16);
nav_h->GPUT[2] = strtonum(buff, 5 + 17 + 16, 7);
nav_h->GPUT[3] = strtonum(buff, 5 + 17 + 16 + 7, 5);
continue;}
else if (strstr(lable, "LEAP SECONDS")) {
nav_h->leap = (int)strtonum(buff, 4, 2);}
else if (strstr(lable, "END OF HEADER"))
break;
}
}
/*Read the body data of file of nav*/
void read_n_b(FILE* fp_nav, pnav_body nav_b)
{
int i_g = 0;
char buff[MAXRINEX] = { 0 };
char flag = { 0 };
while (fgets(buff, MAXRINEX, fp_nav)) {
int j_g = 0;
int j_c = 0;
int j_ga = 0;
int j_gl = 0;
strncpy(&flag, buff + 0, 1);
//GPS SATELLITE
if (flag == 'G') {
for (j_g = 0; j_g < 8; j_g++) {
switch (j_g) {
case 0:
nav_b[i_g].sPRN_BDS = -1;
nav_b[i_g].sPRN_GAL = -1;
nav_b[i_g].sPRN_GLO = -1;
nav_b[i_g].sPRN_GPS = (int)strtonum(buff, 1, 2);
nav_b[i_g].TOC_Y = (int)strtonum(buff, 4, 4);
nav_b[i_g].TOC_M = (int)strtonum(buff, 9, 2);
nav_b[i_g].TOC_D = (int)strtonum(buff, 12, 2);
nav_b[i_g].TOC_H = (int)strtonum(buff, 15, 2);
nav_b[i_g].TOC_Min = (int)strtonum(buff, 18, 2);
nav_b[i_g].TOC_Sec = strtonum(buff, 21, 2);
nav_b[i_g].sa0 = strtonum(buff, 23, 19);
nav_b[i_g].sa1 = strtonum(buff, 23 + 19, 19);
nav_b[i_g].sa2 = strtonum(buff, 23 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 1:
nav_b[i_g].IODE = strtonum(buff, 4, 19);
nav_b[i_g].Crs = strtonum(buff, 4 + 19, 19);
nav_b[i_g].deltan = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].M0 = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 2:
nav_b[i_g].Cuc = strtonum(buff, 4, 19);
nav_b[i_g].e = strtonum(buff, 4 + 19, 19);
nav_b[i_g].Cus = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].sqrtA = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 3:
nav_b[i_g].TOE = strtonum(buff, 4, 19);
nav_b[i_g].Cic = strtonum(buff, 4 + 19, 19);
nav_b[i_g].OMEGA = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].Cis = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 4:
nav_b[i_g].i0 = strtonum(buff, 4, 19);
nav_b[i_g].Crc = strtonum(buff, 4 + 19, 19);
nav_b[i_g].omega = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].deltaomega = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 5:
nav_b[i_g].IDOT = strtonum(buff, 4, 19);
nav_b[i_g].L2code = strtonum(buff, 4 + 19, 19);
nav_b[i_g].GPSweek = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].L2Pflag = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 6:
nav_b[i_g].sACC = strtonum(buff, 4, 19);
nav_b[i_g].sHEA = strtonum(buff, 4 + 19, 19);
nav_b[i_g].TGD = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].IODC = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 7:
nav_b[i_g].TTN = strtonum(buff, 4, 19);
nav_b[i_g].fit = strtonum(buff, 4 + 19, 19);
//nav_b[i_g].spare1 = strtonum(buff, 4 + 19 + 19, 19);
//nav_b[i_g].spare2 = strtonum(buff, 4 + 19 + 19 + 19, 19);
break;
}
}
i_g++;
continue;
}
//BDS SATELLITE
if (flag == 'C') {
for (j_c = 0; j_c < 8; j_c++) {
switch (j_c) {
case 0:
nav_b[i_g].sPRN_GPS = -1;
nav_b[i_g].sPRN_GAL = -1;
nav_b[i_g].sPRN_GLO = -1;
nav_b[i_g].sPRN_BDS = (int)strtonum(buff, 1, 2);
nav_b[i_g].TOC_Y = (int)strtonum(buff, 4, 4);
nav_b[i_g].TOC_M = (int)strtonum(buff, 9, 2);
nav_b[i_g].TOC_D = (int)strtonum(buff, 12, 2);
nav_b[i_g].TOC_H = (int)strtonum(buff, 15, 2);
nav_b[i_g].TOC_Min = (int)strtonum(buff, 18, 2);
nav_b[i_g].TOC_Sec = strtonum(buff, 21, 2);
nav_b[i_g].sa0 = strtonum(buff, 23, 19);
nav_b[i_g].sa1 = strtonum(buff, 23 + 19, 19);
nav_b[i_g].sa2 = strtonum(buff, 23 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 1:
nav_b[i_g].AODE = strtonum(buff, 4, 19);
nav_b[i_g].Crs = strtonum(buff, 4 + 19, 19);
nav_b[i_g].deltan = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].M0 = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 2:
nav_b[i_g].Cuc = strtonum(buff, 4, 19);
nav_b[i_g].e = strtonum(buff, 4 + 19, 19);
nav_b[i_g].Cus = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].sqrtA = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 3:
nav_b[i_g].TOE = strtonum(buff, 4, 19);
nav_b[i_g].Cic = strtonum(buff, 4 + 19, 19);
nav_b[i_g].OMEGA = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].Cis = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 4:
nav_b[i_g].i0 = strtonum(buff, 4, 19);
nav_b[i_g].Crc = strtonum(buff, 4 + 19, 19);
nav_b[i_g].omega = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].deltaomega = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 5:
nav_b[i_g].IDOT = strtonum(buff, 4, 19);
//nav_b[i_g].L2code = strtonum(buff, 4 + 19, 19);
nav_b[i_g].BDTweek = strtonum(buff, 4 + 19 + 19, 19);
//nav_b[i_g].L2Pflag = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 6:
nav_b[i_g].sACC = strtonum(buff, 4, 19);
nav_b[i_g].sHEA = strtonum(buff, 4 + 19, 19);
nav_b[i_g].TGD1 = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].TGD2 = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 7:
//nav_b[i_g].TTN = strtonum(buff, 4, 19);
nav_b[i_g].AODC = strtonum(buff, 4 + 19, 19);
//nav_b[i_g].spare1 = strtonum(buff, 4 + 19 + 19, 19);
//nav_b[i_g].spare2 = strtonum(buff, 4 + 19 + 19 + 19, 19);
break;
}
}
i_g++;
continue;
}
//GAL SATELLITE
if (flag == 'E') {
for (j_ga = 0; j_ga < 8; j_ga++) {
switch (j_ga) {
case 0:
nav_b[i_g].sPRN_BDS = -1;
nav_b[i_g].sPRN_GPS = -1;
nav_b[i_g].sPRN_GLO = -1;
nav_b[i_g].sPRN_GAL = (int)strtonum(buff, 1, 2);
nav_b[i_g].TOC_Y = (int)strtonum(buff, 4, 4);
nav_b[i_g].TOC_M = (int)strtonum(buff, 9, 2);
nav_b[i_g].TOC_D = (int)strtonum(buff, 12, 2);
nav_b[i_g].TOC_H = (int)strtonum(buff, 15, 2);
nav_b[i_g].TOC_Min = (int)strtonum(buff, 18, 2);
nav_b[i_g].TOC_Sec = strtonum(buff, 21, 2);
nav_b[i_g].sa0 = strtonum(buff, 23, 19);
nav_b[i_g].sa1 = strtonum(buff, 23 + 19, 19);
nav_b[i_g].sa2 = strtonum(buff, 23 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 1:
nav_b[i_g].IODE = strtonum(buff, 4, 19);
nav_b[i_g].Crs = strtonum(buff, 4 + 19, 19);
nav_b[i_g].deltan = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].M0 = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 2:
nav_b[i_g].Cuc = strtonum(buff, 4, 19);
nav_b[i_g].e = strtonum(buff, 4 + 19, 19);
nav_b[i_g].Cus = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].sqrtA = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 3:
nav_b[i_g].TOE = strtonum(buff, 4, 19);
nav_b[i_g].Cic = strtonum(buff, 4 + 19, 19);
nav_b[i_g].OMEGA = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].Cis = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 4:
nav_b[i_g].i0 = strtonum(buff, 4, 19);
nav_b[i_g].Crc = strtonum(buff, 4 + 19, 19);
nav_b[i_g].omega = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].deltaomega = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 5:
nav_b[i_g].IDOT = strtonum(buff, 4, 19);
//nav_b[i_g].L2code = strtonum(buff, 4 + 19, 19);
nav_b[i_g].GALweek = strtonum(buff, 4 + 19 + 19, 19);
//nav_b[i_g].L2Pflag = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 6:
nav_b[i_g].sACC = strtonum(buff, 4, 19);
nav_b[i_g].sHEA = strtonum(buff, 4 + 19, 19);
nav_b[i_g].BGDa = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].BGDb = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 7:
//nav_b[i_g].TTN = strtonum(buff, 4, 19);
//nav_b[i_g].fit = strtonum(buff, 4 + 19, 19);
//nav_b[i_g].spare1 = strtonum(buff, 4 + 19 + 19, 19);
//nav_b[i_g].spare2 = strtonum(buff, 4 + 19 + 19 + 19, 19);
break;
}
}
i_g++;
continue;
}
//GLO SATELLITE
if (flag == 'R') {
for (j_gl = 0; j_gl < 4; j_gl++) {
switch (j_gl) {
case 0:
nav_b[i_g].sPRN_BDS = -1;
nav_b[i_g].sPRN_GPS = -1;
nav_b[i_g].sPRN_GAL = -1;
nav_b[i_g].sPRN_GLO = (int)strtonum(buff, 1, 2);
nav_b[i_g].TOC_Y = (int)strtonum(buff, 4, 4);
nav_b[i_g].TOC_M = (int)strtonum(buff, 9, 2);
nav_b[i_g].TOC_D = (int)strtonum(buff, 12, 2);
nav_b[i_g].TOC_H = (int)strtonum(buff, 15, 2);
nav_b[i_g].TOC_Min = (int)strtonum(buff, 18, 2);
nav_b[i_g].TOC_Sec = strtonum(buff, 21, 2);
nav_b[i_g].sa0 = strtonum(buff, 23, 19);
nav_b[i_g].sa1 = strtonum(buff, 23 + 19, 19);
nav_b[i_g].Dos = strtonum(buff, 23 + 19 + 19, 19);
nav_b[i_g].TOE = jdutc2gpst(
utctime2jd(nav_b[i_g].TOC_Y, nav_b[i_g].TOC_M, nav_b[i_g].TOC_D,
nav_b[i_g].TOC_H, nav_b[i_g].TOC_Min, nav_b[i_g].TOC_Sec)
);
fgets(buff, MAXRINEX, fp_nav);
break;
case 1:
nav_b[i_g].SatX = strtonum(buff, 4, 19);
nav_b[i_g].SatXv = strtonum(buff, 4 + 19, 19);
nav_b[i_g].SatXa = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].sHEA = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 2:
nav_b[i_g].SatY = strtonum(buff, 4, 19);
nav_b[i_g].SatYv = strtonum(buff, 4 + 19, 19);
nav_b[i_g].SatYa = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].FreN = strtonum(buff, 4 + 19 + 19 + 19, 19);
fgets(buff, MAXRINEX, fp_nav);
break;
case 3:
nav_b[i_g].SatZ = strtonum(buff, 4, 19);
nav_b[i_g].SatZv = strtonum(buff, 4 + 19, 19);
nav_b[i_g].SatZa = strtonum(buff, 4 + 19 + 19, 19);
nav_b[i_g].AOO = strtonum(buff, 4 + 19 + 19 + 19, 19);
break;
}
}
i_g++;
continue;
}
}
}
/*Read the file of obs*/
/**
* Get the total amount of epoch of obs.
*
* \param fp_obs: The file pointer of obs
* \return amount of epoch
*/
int get_epochnum(FILE* fp_obs)
{
int n = 0;
char flag;
char buff[MAXRINEX];
char* lable = buff + 60;
while (fgets(buff, MAXRINEX, fp_obs)) {
if (strstr(lable, "RINEX VERSION / TYPE")) {
if (strtonum(buff, 0, 9) < 3) return -1;
}
if (strstr(lable, "END OF HEADER")) {
while (fgets(buff, MAXRINEX, fp_obs)) {
strncpy(&flag, buff + 0, 1);
if (flag == '>') {
n++;
}
}
}
}return n;
}
/*Read the header data of file of obs*/
void read_o_h(FILE* fp_obs, pobs_head obs_h)
{
char buff[MAXRINEX] = { 0 };
char flag = { 0 };
char* lable = buff + 60;
int i = 0;
int j = 0;
obs_h->interval = 30;
obs_h->f_y = obs_h->f_m = obs_h->f_d = obs_h->f_h = obs_h->f_min = obs_h->f_sec = 0;
obs_h->l_y = obs_h->l_m = obs_h->l_d = obs_h->l_h = obs_h->l_min = obs_h->l_sec = 0;
while (fgets(buff, MAXRINEX, fp_obs)) {
if (strstr(lable, "RINEX VERSION / TYPE")) {
obs_h->ver = strtonum(buff, 0, 9);
strncpy(obs_h->type, buff + 20, 30);
continue;
}
else if (strstr(lable, "MARKER NAME")) {
strncpy(obs_h->marker, buff + 0, 10);
continue;
}
else if (strstr(lable, "APPROX POSITION XYZ")) {
obs_h->apX = strtonum(buff, 0, 14);
obs_h->apY = strtonum(buff, 0 + 14, 14);
obs_h->apZ = strtonum(buff, 0 + 14 + 14, 14);
continue;
}
else if (strstr(lable, "ANTENNA: DELTA H/E/N")) {
obs_h->ANTH = strtonum(buff, 0, 14);
obs_h->ANTdeltaE = strtonum(buff, 14, 14);
obs_h->ANTdeltaN = strtonum(buff, 14 + 14, 14);
continue;
}
else if (strstr(lable, "SYS / # / OBS TYPES")) {
char flag = { 0 };
strncpy(&flag, buff + 0, 1);
if (flag == 'G') {
obs_h->obstypenum_gps = (int)strtonum(buff, 4, 2);
for (i = 0; i < obs_h->obstypenum_gps;) {
for (int j = 0; j < 13; i++, j++) {
if (i == obs_h->obstypenum_gps) break;
else obs_h->obscode_gps[i] = type2code(i, buff);
}i == obs_h->obstypenum_gps? 0 : fgets(buff, MAXRINEX, fp_obs);
}continue;
}
else if (flag == 'C') {
obs_h->obstypenum_bds = (int)strtonum(buff, 4, 2);
for (i = 0; i < obs_h->obstypenum_bds;) {
for (int j = 0; j < 13; i++, j++) {
if (i == obs_h->obstypenum_bds) break;
else obs_h->obscode_bds[i] = type2code(i, buff);
}i == obs_h->obstypenum_bds ? 0 : fgets(buff, MAXRINEX, fp_obs);
}continue;
}
else if (flag == 'E') {
obs_h->obstypenum_gal = (int)strtonum(buff, 4, 2);
for (i = 0; i < obs_h->obstypenum_gal;) {
for (int j = 0; j < 13; i++, j++) {
if (i == obs_h->obstypenum_gal) break;
else obs_h->obscode_gal[i] = type2code(i, buff);
}i == obs_h->obstypenum_gal ? 0 : fgets(buff, MAXRINEX, fp_obs);
}continue;
}
else if (flag == 'R') {
obs_h->obstypenum_glo = (int)strtonum(buff, 4, 2);
for (i = 0; i < obs_h->obstypenum_glo;) {
for (int j = 0; j < 13; i++, j++) {
if (i == obs_h->obstypenum_glo) break;
else obs_h->obscode_glo[i] = type2code(i, buff);
}i == obs_h->obstypenum_glo ? 0 : fgets(buff, MAXRINEX, fp_obs);
}continue;
}continue;
}
else if (strstr(lable, "INTERVAL")) {
obs_h->interval = strtonum(buff, 0, 10);
continue;
}
else if (strstr(lable, "TIME OF FIRST OBS")) {
obs_h->f_y = (int)strtonum(buff, 2, 4);
obs_h->f_m = (int)strtonum(buff, 2 + 6, 4);
obs_h->f_d = (int)strtonum(buff, 2 + 6 + 6, 4);
obs_h->f_h = (int)strtonum(buff, 2 + 6 + 6 + 6, 4);
obs_h->f_min = (int)strtonum(buff, 2 + 6 + 6 + 6 + 6, 4);
obs_h->f_sec = strtonum(buff, 2 + 6 + 6 + 6 + 6 + 6, 9);
strncpy(obs_h->tsys, buff + 6 + 6 + 6 + 6 + 6 + 18, 3);
continue;
}
else if (strstr(lable, "TIME OF LAST OBS")) {
obs_h->l_y = (int)strtonum(buff, 2, 4);
obs_h->l_m = (int)strtonum(buff, 2 + 6, 4);
obs_h->l_d = (int)strtonum(buff, 2 + 6 + 6, 4);
obs_h->l_h = (int)strtonum(buff, 2 + 6 + 6 + 6, 4);
obs_h->l_min = (int)strtonum(buff, 2 + 6 + 6 + 6 + 6, 4);
obs_h->l_sec = strtonum(buff, 2 + 6 + 6 + 6 + 6 + 6, 9);
continue;
}
else if (strstr(lable, "END OF HEADER")) {
break;
}
}
}
/*Read the body data of file of obs*/
void read_o_eb(FILE* fp_obs, pobs_head obs_h, pobs_epoch obs_e, pobs_body obs_b)
{
char buff[MAXRINEX] = { 0 };
char flag = { 0 };
while (fgets(buff, MAXRINEX, fp_obs)) {
strncpy(&flag, buff + 0, 1);
if (flag == '>') {
int j_g = 0; int k_g = 0;
int j_c = 0; int k_c = 0;
int j_ga = 0; int k_ga = 0;
int j_gl = 0; int k_gl = 0;
obs_e->gps_num = 0;
obs_e->bds_num = 0;
obs_e->gal_num = 0;
obs_e->glo_num = 0;
obs_e->y = (int)strtonum(buff, 2, 4);
obs_e->m = (int)strtonum(buff, 7, 2);
obs_e->d = (int)strtonum(buff, 10, 2);
obs_e->h = (int)strtonum(buff, 13, 2);
obs_e->min = (int)strtonum(buff, 16, 2);
obs_e->sec = strtonum(buff, 19, 10);
obs_e->p_flag = (int)strtonum(buff, 31, 1);
obs_e->sat_num = strtonum(buff, 33, 3);
strncpy(&flag, buff + 0, 1);
memset(obs_e->sPRN, 0, sizeof(obs_e->sPRN));
memset(obs_e->sPRN_GPS, 0, sizeof(obs_e->sPRN_GPS));
memset(obs_e->sPRN_BDS, 0, sizeof(obs_e->sPRN_BDS));
memset(obs_e->sPRN_GAL, 0, sizeof(obs_e->sPRN_GAL));
memset(obs_e->sPRN_GLO, 0, sizeof(obs_e->sPRN_GLO));
memset(obs_b->obs_gps, 0, sizeof(obs_b->obs_gps));
memset(obs_b->obs_bds, 0, sizeof(obs_b->obs_bds));
memset(obs_b->obs_gal, 0, sizeof(obs_b->obs_gal));
memset(obs_b->obs_glo, 0, sizeof(obs_b->obs_glo));
for (int i = 0; i < obs_e->sat_num; i++) {
if (flag == 'G') {
obs_e->sPRN[i] = strtonum(buff, 1, 2);
obs_e->sPRN_GPS[j_g] = obs_e->sPRN[i];
for (k_g = 0; k_g < obs_h->obstypenum_gps; k_g++) {
obs_b->obs_gps[j_g][k_g] = strtonum(buff, 3 + 16 * k_g, 14);
}
obs_e->gps_num++; j_g++;
fgets(buff, MAXRINEX, fp_obs);
strncpy(&flag, buff + 0, 1);
}
else if (flag == 'C') {
obs_e->sPRN[i] = strtonum(buff, 1, 2);
obs_e->sPRN_BDS[j_c] = obs_e->sPRN[i];
for (k_c = 0; k_c < obs_h->obstypenum_bds; k_c++) {
obs_b->obs_bds[j_c][k_c] = strtonum(buff, 3 + 16 * k_c, 14);
}
obs_e->bds_num++; j_c++;
fgets(buff, MAXRINEX, fp_obs);
strncpy(&flag, buff + 0, 1);
}
else if (flag == 'E') {
obs_e->sPRN[i] = strtonum(buff, 1, 2);
obs_e->sPRN_GAL[j_ga] = obs_e->sPRN[i];
for (k_ga = 0; k_ga < obs_h->obstypenum_gal; k_ga++) {
obs_b->obs_gal[j_ga][k_ga] = strtonum(buff, 3 + 16 * k_ga, 14);
}
obs_e->gal_num++; j_ga++;
fgets(buff, MAXRINEX, fp_obs);
strncpy(&flag, buff + 0, 1);
}
else if (flag == 'R') {
obs_e->sPRN[i] = strtonum(buff, 1, 2);
obs_e->sPRN_GLO[j_gl] = obs_e->sPRN[i];
for (k_gl = 0; k_gl < obs_h->obstypenum_glo; k_gl++) {
obs_b->obs_glo[j_gl][k_gl] = strtonum(buff, 3 + 16 * k_gl, 14);
}
obs_e->glo_num++; j_gl++;
fgets(buff, MAXRINEX, fp_obs);
strncpy(&flag, buff + 0, 1);
}
else {
fgets(buff, MAXRINEX, fp_obs);
strncpy(&flag, buff + 0, 1);
}
}
}break;
}
}
+515
View File
@@ -0,0 +1,515 @@
#include "brdm2pos.h"
using namespace std;
/*Obatain the intergral term of acceleraction of each component*/
void pz90deq(double X[6], double K[6], double acc[3])
{
double r = sqrt(pow(X[0], 2) + pow(X[1], 2) + pow(X[2], 2));
double coef0 = -GM / pow(r, 3);
double coef1 = 1.5 * C20 * (GM * pow(a, 2) / pow(r, 5));
K[0] = X[3]; K[1] = X[4]; K[2] = X[5];
K[3] =
coef0 * X[0] +
coef1 * (1 - 5 * pow((X[2] / r), 2)) * X[0] +
pow(Earth_e, 2) * X[0] +
2 * Earth_e * X[4] +
acc[0];
K[4] =
coef0 * X[1] +
coef1 * (1 - 5 * pow((X[2] / r), 2)) * X[1] +
pow(Earth_e, 2) * X[1] -
2 * Earth_e * X[3] +
acc[1];
K[5] =
coef0 * X[2] +
coef1 * (3 - 5 * pow((X[2] / r), 2)) * X[2] +
acc[2];
}
/*Construct the RK-4 method*/
void pz90pos(double tstep, double X[6], double acc[3])
{
double K1[6], K2[6], K3[6], K4[6], W[6];
pz90deq(X, K1, acc); for (int i = 0; i < 6; i++) W[i] = X[i] + K1[i] * tstep / 2.0;
pz90deq(W, K2, acc); for (int i = 0; i < 6; i++) W[i] = X[i] + K2[i] * tstep / 2.0;
pz90deq(W, K3, acc); for (int i = 0; i < 6; i++) W[i] = X[i] + K3[i] * tstep;
pz90deq(W, K4, acc);
for (int i = 0; i < 6; i++) X[i] += (K1[i] + 2.0 * K2[i] + 2.0 * K3[i] + K4[i]) * tstep / 6.0;
}
/*Calculate the satellite position of GLONASS on this epoch*/
pos_ts glo_pos(int best_epoch, double Weeksec,
pnav_body nav_b, pobs_head obs_h, pos_ts pos_t)
{
double X[6], acc[3]; double R = 0.0;
double tdist = Weeksec - pos_t.delta_t - nav_b[best_epoch].TOE, tstep = 0.0;
pos_t.delta_clk = nav_b[best_epoch].sa0 + nav_b[best_epoch].sa1 * tdist;
X[0] = nav_b[best_epoch].SatX * 1e3;
X[1] = nav_b[best_epoch].SatY * 1e3;
X[2] = nav_b[best_epoch].SatZ * 1e3;//Position
X[3] = nav_b[best_epoch].SatXv * 1e3;
X[4] = nav_b[best_epoch].SatYv * 1e3;
X[5] = nav_b[best_epoch].SatZv * 1e3;//Velocity
acc[0] = nav_b[best_epoch].SatXa * 1e3;
acc[1] = nav_b[best_epoch].SatYa * 1e3;
acc[2] = nav_b[best_epoch].SatZa * 1e3;//Acclerate
for (tstep = tdist < 0.0 ? -TSTEP : TSTEP; fabs(tdist) > 1.0e-9; tdist -= tstep) {
if (fabs(tdist) < TSTEP) tstep = tdist;
pz90pos(tstep, X, acc);
}
pz90towgs84(X[0], X[1], X[2]);
pos_t.X = X[0];
pos_t.Y = X[1];
pos_t.Z = X[2];
R = sqrt(pow(pos_t.X - obs_h->apX, 2) +
pow(pos_t.Y - obs_h->apY, 2) +
pow(pos_t.Z - obs_h->apZ, 2));
pos_t.deltat = pos_t.delta_t;
pos_t.delta_t = R / C_V - pos_t.delta_clk;
return pos_t;
}
/*Calculate the satellite position of other systems on this epoch*/
pos_ts sat_pos(int sPRN, int best_epoch, double Weeksec, int GNSS,
pnav_body nav_b, pobs_head obs_h, pos_ts pos_t)
{
double T_S = Weeksec - pos_t.delta_t;
double n_0 = sqrt(GM) / pow(nav_b[best_epoch].sqrtA, 3);
double n = n_0 + nav_b[best_epoch].deltan;
double tk;
if (GNSS == BDS) tk = T_S - nav_b[best_epoch].TOE - 14;//BDST = GPST + 14
else tk = T_S - nav_b[best_epoch].TOE;
if (tk > 32400)tk -= 604800;
else if (tk < -32400)tk += 604800;
double Ms = nav_b[best_epoch].M0 + n * tk;
double Es = Ms, E0;
do
{
E0 = Es;
Es = Ms + nav_b[best_epoch].e * sin(Es);
} while (fabs(Es - E0) > 1.0e-10);
double cosfs = (cos(Es) - nav_b[best_epoch].e) / (1 - nav_b[best_epoch].e * cos(Es));
double sinfs = (sqrt(1 - pow(nav_b[best_epoch].e, 2)) * sin(Es)) / (1 - nav_b[best_epoch].e * cos(Es));
double fs = atan2(sinfs, cosfs);
double u0 = fs + nav_b[best_epoch].omega;
double epsilon_u = nav_b[best_epoch].Cus * sin(2 * u0) + nav_b[best_epoch].Cuc * cos(2 * u0);
double epsilon_r = nav_b[best_epoch].Crs * sin(2 * u0) + nav_b[best_epoch].Crc * cos(2 * u0);
double epsilon_i = nav_b[best_epoch].Cis * sin(2 * u0) + nav_b[best_epoch].Cic * cos(2 * u0);
double u = u0 + epsilon_u;
double r = pow(nav_b[best_epoch].sqrtA, 2) * (1 - nav_b[best_epoch].e * cos(Es)) + epsilon_r;
double i = nav_b[best_epoch].i0 + epsilon_i + nav_b[best_epoch].IDOT * tk;
double x = r * cos(u);
double y = r * sin(u);
double l, X, Y, Z;
if (GNSS == BDS && (sPRN <= 5 || sPRN >= 59)) {//BDS GEO Satellites
l = nav_b[best_epoch].OMEGA + nav_b[best_epoch].deltaomega * tk - Earth_e * nav_b[best_epoch].TOE;
X = x * cos(l) - y * cos(i) * sin(l);
Y = x * sin(l) + y * cos(i) * cos(l);
Z = y * sin(i);
double f = deg2rad(-5);
double p = Earth_e * tk;
X = X * cos(p) + Y * sin(p) * cos(f) + Z * sin(p) * sin(f);
Y = X * -sin(p) + Y * cos(p) * cos(f) + Z * cos(p) * sin(f);
Z = Y * -sin(f) + Z * cos(f);
}
else {
l = nav_b[best_epoch].OMEGA + (nav_b[best_epoch].deltaomega - Earth_e) * tk - Earth_e * nav_b[best_epoch].TOE;
X = x * cos(l) - y * cos(i) * sin(l);
Y = x * sin(l) + y * cos(i) * cos(l);
Z = y * sin(i);
}
pos_t.X = cos(Earth_e * pos_t.delta_t) * X + sin(Earth_e * pos_t.delta_t) * Y;
pos_t.Y = -sin(Earth_e * pos_t.delta_t) * X + cos(Earth_e * pos_t.delta_t) * Y;
pos_t.Z = Z;//Correction of earth rotation
double TGD=0.0;
if (GNSS == GPS) TGD = nav_b[best_epoch].TGD;
else if (GNSS == GAL) TGD = nav_b[best_epoch].BGDa;
else if (GNSS == BDS) TGD = nav_b[best_epoch].TGD1;
//Recalculate the diatance of satellite-receiver
double R = sqrt(pow(pos_t.X - obs_h->apX, 2) +
pow(pos_t.Y - obs_h->apY, 2) +
pow(pos_t.Z - obs_h->apZ, 2));
//Get relativistic effect correction
double rela = 2 * sqrt(GM) * nav_b[best_epoch].e * nav_b[best_epoch].sqrtA * sin(Es) / pow(C_V, 2);
pos_t.delta_clk = nav_b[best_epoch].sa0 +
nav_b[best_epoch].sa1 * tk +
nav_b[best_epoch].sa2 * pow(tk, 2) -
rela + TGD;
pos_t.deltat = pos_t.delta_t;
pos_t.delta_t = R / C_V - pos_t.delta_clk;
return pos_t;
}
/**
* .
*
* \param obs_h: Observation header data
* \param obs_e: Observation epoch data
* \param obs_b: Observation data
* \param nav_b: Navigation data
* \param res_file: The file path of result file of satellite position
* \param GNSS: GNSS system code
* \param satnum: The total number of satellite of designated satellite system
* \return
*/
int sat_pos_cal(pobs_head obs_h, pobs_epoch obs_e, pobs_body obs_b,
pnav_body nav_b,
FILE* solu,
int GNSS, int satnum, int Hangle, int ionopt, int troopt)
{
int y, m, d, min, epochcount, sat_num = 0, sPRN = 0;
double h, sec, detat_toc, beginsec, endinsec, Weeksec, PERS = 0;
double apX, apY, apZ, ap_X, ap_Y, ap_Z;
stations sta = { 0 };rah in_rah = { 0 };
enu in_enu = { 0 };blh in_blh = { 0 };
lsq_part in_lsq = { 0 };pos_ts pos_t = { 0 };
acct_obs obs = { 0 };
//the beginning second of observation
beginsec = time2gpst(obs_h->f_y, obs_h->f_m, obs_h->f_d,
obs_h->f_h, obs_h->f_min, obs_h->f_sec);
//the ending second of observation
endinsec = time2gpst(obs_h->l_y, obs_h->l_m, obs_h->l_d,
obs_h->l_h, obs_h->l_min, obs_h->l_sec);
y = obs_e->y;m = obs_e->m;d = obs_e->d;
h = obs_e->h;min = obs_e->min;sec = obs_e->sec;
Weeksec = time2gpst(y, m, d, h, min, sec);
epochcount = round((Weeksec - beginsec) / obs_h->interval) + 1;
fprintf(solu, "\n>%05d lat/r lon/r alt/m", epochcount);
//Match the system and assign the satellite number
if (GNSS == GPS)sat_num = obs_e->gps_num;
else if (GNSS == GAL)sat_num = obs_e->gal_num;
else if (GNSS == BDS)sat_num = obs_e->bds_num;
else if (GNSS == GLO)sat_num = obs_e->glo_num;
in_lsq.l = mat(sat_num, 1);
in_lsq.m = mat(sat_num, 1);
in_lsq.n = mat(sat_num, 1);
in_lsq.o = mat(sat_num, 1); int k = 0;
for (int j = 0; j < sat_num; j++) {
//Match system and assign the sPRN
if (GNSS == GPS) {
sPRN = obs_e->sPRN_GPS[j];
PERS = obs_b->obs_gps[j][
code2type(C1, obs_h->obstypenum_gps, obs_h->obscode_gps)] / C_V;}
else if (GNSS == GAL) {
sPRN = obs_e->sPRN_GAL[j];
PERS = obs_b->obs_gal[j][
code2type(C1, obs_h->obstypenum_gal, obs_h->obscode_gal)] / C_V;}
else if (GNSS == BDS) {
sPRN = obs_e->sPRN_BDS[j];
PERS = obs_b->obs_bds[j][
code2type(C2, obs_h->obstypenum_bds, obs_h->obscode_bds)] / C_V;}
else if (GNSS == GLO) {
sPRN = obs_e->sPRN_GLO[j];
PERS = obs_b->obs_glo[j][
code2type(C1, obs_h->obstypenum_glo, obs_h->obscode_glo)] / C_V;}
//Match the nearest satellite of nav with this epoch
int best_epoch = select_epoch(Weeksec, sPRN, nav_b, satnum, GNSS);
if (best_epoch == -1) continue;//when the sPRN is not exist function will return -1
if (GNSS == BDS) detat_toc = Weeksec - nav_b[best_epoch].TOE - 14;//BDST = GPST + 14s
else detat_toc = Weeksec - nav_b[best_epoch].TOE;
//Iterative approximate propagation time
if (GNSS == GLO) {
//Get the approximately transit of signal
pos_t.delta_t = PERS - 0 +
nav_b[best_epoch].sa0 +
nav_b[best_epoch].sa1 * detat_toc;
pos_t.deltat = 0.0;
//Satellite position calculation
while (fabs(pos_t.delta_t - pos_t.deltat) > 1.0e-9) {
pos_t = glo_pos(best_epoch, Weeksec, nav_b, obs_h, pos_t);
}
}
//Exclude GLONASS
else {
//Get the approximately transit of signal
pos_t.delta_t = PERS - 0 +
nav_b[best_epoch].sa0 +
nav_b[best_epoch].sa1 * detat_toc +
nav_b[best_epoch].sa2 * pow(detat_toc, 2);
pos_t.deltat = 0.0;
//Satellite position calculation
while (fabs(pos_t.delta_t - pos_t.deltat) > 1.0e-9) {
pos_t = sat_pos(sPRN, best_epoch, Weeksec, GNSS, nav_b, obs_h, pos_t);
}
}
//Satellite blh & rah position calculation
in_rah = xyz2rah(pos_t, obs_h);
in_blh = xyz2blh(in_blh, pos_t.X, pos_t.Y, pos_t.Z);
if (in_blh.H < 0 || rad2deg(in_rah.H) < Hangle)continue;
else {
//Store the accept observation data
in_lsq.l[k] = pos_t.X, in_lsq.m[k] = pos_t.Y;
in_lsq.n[k] = pos_t.Z, in_lsq.o[k] = deg2rad(in_rah.H);
obs.sclk[k] = pos_t.delta_clk;
switch (GNSS) {
case GPS:
obs.Per1[k] = obs_b->obs_gps[j][code2type(C1, obs_h->obstypenum_gps, obs_h->obscode_gps)];
obs.Per2[k] = obs_b->obs_gps[j][code2type(C2, obs_h->obstypenum_gps, obs_h->obscode_gps)];
obs.freq1 = FREQ1; obs.freq2 = FREQ2; break;
case BDS:
obs.Per1[k] = obs_b->obs_bds[j][code2type(C2, obs_h->obstypenum_bds, obs_h->obscode_bds)];
obs.Per2[k] = obs_b->obs_bds[j][code2type(C7, obs_h->obstypenum_bds, obs_h->obscode_bds)];
obs.freq1 = FREQ1_BDS; obs.freq2 = FREQ2_BDS;
break;
case GAL:
obs.Per1[k] = obs_b->obs_gal[j][code2type(C1, obs_h->obstypenum_gal, obs_h->obscode_gal)];
obs.Per2[k] = obs_b->obs_gal[j][code2type(C6, obs_h->obstypenum_gal, obs_h->obscode_gal)];
obs.freq1 = FREQ1; obs.freq2 = FREQ6;
break;
case GLO:
obs.Per1[k] = obs_b->obs_glo[j][code2type(C1, obs_h->obstypenum_glo, obs_h->obscode_glo)];
obs.Per2[k] = obs_b->obs_glo[j][code2type(C2, obs_h->obstypenum_glo, obs_h->obscode_glo)];
obs.freq1 = FREQ1_GLO; obs.freq2 = FREQ2_GLO;
break;}
outdata(in_blh, solu, sPRN, GNSS); k++;
};
}
//Solve the position
if (k >= 4) {
in_lsq.x = mat(4, 1);
in_lsq.B = mat(k, 4);
in_lsq.L = mat(k, 1);
in_lsq.P = zeros(k, k);
apX = 0; ap_X = obs_h->apX;
apY = 0; ap_Y = obs_h->apY;
apZ = 0; ap_Z = obs_h->apZ;
int stop = 0;
while (fabs(ap_X - apX) > 1e-6) {
if (stop == 3) break;
apX = ap_X;
apY = ap_Y;
apZ = ap_Z;
sta = designmat(obs_h, obs,
in_lsq.l, in_lsq.m, in_lsq.n, in_lsq.o,
in_lsq.B, in_lsq.P, in_lsq.L,
ap_X, ap_Y, ap_Z, k,
ionopt, troopt, GNSS);
ap_X += sta.X;
ap_Y += sta.Y;
ap_Z += sta.Z;
stop++;
}solution(solu, obs_h, ap_X, ap_Y, ap_Z);
}
else {
fprintf(solu,"\nRec:insufficient quantity of sat, sat=%d",k);
}
free(in_lsq.l); free(in_lsq.m); free(in_lsq.n); free(in_lsq.o);
free(in_lsq.B); free(in_lsq.P); free(in_lsq.L);
return 1;
}
/**/
int sat_cal(pnav_body nav_b, pobs_head obs_h, FILE* solu,int satnum, int GNSS) {
int ii, i, sPRN=0;
double Min, min, Weeksec=0, Beginsec, STOP=0;
pos_ts pos = { 0 };
blh in_blh = { 0 };
Beginsec = time2gpst(
obs_h->f_y,
obs_h->f_m,
obs_h->f_d,
obs_h->f_h,
obs_h->f_min,
obs_h->f_sec
);
for (i = 0; i < satnum; i++) {
switch (GNSS){
case GPS:if (nav_b[i].sPRN_GPS == -1) { continue; }
Weeksec =
fabs(sPRN - nav_b[i].sPRN_GPS) > 0 ? Beginsec : Weeksec;
sPRN = nav_b[i].sPRN_GPS;
STOP = TIMEGAP_GPS/2;
break;
case BDS:if (nav_b[i].sPRN_BDS == -1) { continue; }
Weeksec =
fabs(sPRN - nav_b[i].sPRN_BDS) > 0 ? Beginsec : Weeksec;
sPRN = nav_b[i].sPRN_BDS;
STOP = TIMEGAP_BDS/2;
break;
case GAL:if (nav_b[i].sPRN_GAL == -1) { continue; }
Weeksec =
fabs(sPRN - nav_b[i].sPRN_GAL) > 0 ? Beginsec : Weeksec;
sPRN = nav_b[i].sPRN_GAL;
STOP = TIMEGAP_GAL/2;
break;
case GLO:if (nav_b[i].sPRN_GLO == -1) { continue; }
Weeksec =
fabs(sPRN - nav_b[i].sPRN_GLO) > 0 ? Beginsec : Weeksec;
sPRN = nav_b[i].sPRN_GLO;
STOP = TIMEGAP_GLO/2+18;
break;
}
for (Weeksec; fabs(Weeksec - nav_b[i].TOE) <= STOP; Weeksec += 30.0) {
if (Weeksec - Beginsec >= DAYSEC) break;
else if (Weeksec - Beginsec >= DAYSEC - STOP) STOP += STOP;
if (GNSS != GLO) pos = sat_pos(sPRN, i, Weeksec, GNSS, nav_b, obs_h, pos);
else if (GNSS == GLO) pos = glo_pos(i, Weeksec, nav_b, obs_h, pos);
in_blh = xyz2blh(in_blh, pos.X, pos.Y, pos.Z);
outdata(in_blh, solu, sPRN, GNSS);
fprintf(solu, ">>%05d", (int)(Weeksec - Beginsec) / 30 + 1);
}
}return 0;
}
/**
* The entrance of function.
*
* \param nav_path: The RINEX navigation file's path
* \param obs_path: The RINEX observation file's path
* \param res_path: The satellite position solution output path
* \param GNSS: GNSS code
* \param Hangle :
* \param ionopt :
* \param troopt :
* \param genmode:
* \return
* -1 ,Can not open the nav file
* -2 ,Can not open the obs file
* -3 ,Mismatch version or format of nav
* -4 ,No data of nav
* -5 ,Mismatch version or format of obs
* -6 ,No data of obs
* 0 ,Soulution generated completely
* >0 ,Some epoch cant be calculate
*/
double brdm2pos(
char nav_path[MAXPATH],
char obs_path[MAXPATH],
char res_path[MAXPATH],
int GNSS,
int Hangle,
int ionopt,
int tropopt,
int genmode
)
{
int satnum, epochnum, result = 0;
pos_ts pos_t = { 0 };
blh apblh = { 0 };
pnav_head nav_h = NULL;
pnav_body nav_b = NULL;
pobs_head obs_h = NULL;
pobs_body obs_b = NULL;
pobs_epoch obs_e = NULL;
FILE* fp_nav = fopen(nav_path, "r");
if (fp_nav == NULL) return -1;//cant read nav file
//Get the amount of satellite
satnum = getsatnum(fp_nav);
switch (satnum) {
case -1: return -3;//mismatch version or format
case 0: return -4;//no data
default: break;
}
rewind(fp_nav);
nav_h = (pnav_head)malloc(sizeof(nav_head));
nav_b = (pnav_body)malloc(sizeof(nav_body) * (satnum));
if (nav_h && nav_b) { read_n_h(fp_nav, nav_h); read_n_b(fp_nav, nav_b); }
fclose(fp_nav);
FILE* fp_obs = fopen(obs_path, "r");
if (fp_obs == NULL) return -2;//cant read obs file
//Get the amonut of obs epoch
epochnum = get_epochnum(fp_obs);
switch (epochnum) {
case -1: return -5;//mismatch version or format
case 0: return -6;//no data
default: break;
}
rewind(fp_obs); obs_h = (pobs_head)malloc(sizeof(obs_head));
if (obs_h) {
//Read the header of obs
read_o_h(fp_obs, obs_h);
//Convert the approximately position (ECEF -> LLA)
apblh = xyz2blh(apblh, obs_h->apX, obs_h->apY, obs_h->apZ);
obs_h->apB = apblh.B;
obs_h->apL = apblh.L;
obs_h->apH = apblh.H;
FILE* solu = headerout(obs_h, genmode, obs_path, nav_path, res_path);
if (genmode == 1) {
sat_cal(nav_b, obs_h, solu, satnum, GNSS);
fprintf(solu, "\nEND");
fclose(solu);
return 0;
}
//Begin to calculate
for (int i = 0; i < epochnum; i++) {
//Allocate memory for obs epoch and body data
obs_e = (pobs_epoch)malloc(sizeof(obs_epoch));
obs_b = (pobs_body)malloc(sizeof(obs_body));
//Read epoch data
read_o_eb(fp_obs, obs_h, obs_e, obs_b);
//Calculate the position of satellite
result += sat_pos_cal(obs_h, obs_e, obs_b, nav_b,
solu, GNSS, satnum, Hangle, ionopt,tropopt);
fprintf(solu, "\n");
//Free epoch data
freeobs_e(obs_e, obs_b);
}
//Output the signal of ending
fprintf(solu, "\nEND"); fclose(solu);
//free nav & obs memory of data
free(obs_h); free(nav_h); free(nav_b);
if (epochnum == result) return 0;
else return epochnum - result;
}
}
+217
View File
@@ -0,0 +1,217 @@
#include "brdm2pos.h"
using namespace std;
/*Tropshere correction with saastamoinen model*/
static double trosaastamoinen(pobs_head obs_h, double elev)
{
double P0, e0, T0, deltaSd, deltaSw, dtropd, dtropw, dtrop;
double B = obs_h->apB, L = obs_h->apL, H = obs_h->apH;
P0 = 1013.25 * pow((1 - 2.2557 * 10e-5 * H), 5.2568);
e0 = 11.69;
T0 = 15 - 6.5 * 10e-3 * H + 273.15;
deltaSd = 2.2768e-3 * P0 / (1 - 2.66e-3 * cos(2 * B) - 2.8e-4 * H * 1e3);
deltaSw = 2.2768e-3 * (1255 / T0 + 0.05) * e0;
// Dry
dtropd = deltaSd / sqrt(
sin(
deg2rad(
rad2deg(
pow(elev,2)
) + 6.25
)
)
);
// Wet
dtropw = deltaSw / sqrt(
sin(
deg2rad(
rad2deg(
pow(elev,2)
) + 6.25
)
)
);
dtrop = dtropw + dtropd;
return dtrop;
}
/*Tropshere correction with hopfiled model*/
static double trohopfield(pobs_head obs_h, double elev)
{
double P0, e0, T0, deltaSd, deltaSw, dtropd, dtropw, dtrop;
double B = obs_h->apB, L = obs_h->apL, H = obs_h->apH;
P0 = 1013.25 * pow((1 - 2.2557 * 10e-5 * H), 5.2568);
e0 = 11.69;
T0 = 15 - 6.5 * 10e-3 * H + 273.15;
deltaSd = 1.552e-5 * P0 * (40136 + 148.72 * (T0 - 273.16) - H) / T0;
deltaSw = 1.552e-5 * 4810 * e0 * (11000 - H) / pow(T0, 2);
// Dry delay component
dtropd = deltaSd / sqrt(
sin(
deg2rad(
rad2deg(
pow(deg2rad(elev), 2)
) + 6.25
)
)
);
// Wet delay component
dtropw = deltaSw / sqrt(
sin(
deg2rad(
rad2deg(
pow(deg2rad(elev), 2)
) + 6.25
)
)
);
dtrop = dtropw + dtropd;
return dtrop;
}
/*Iono correction by IF-IC*/
static double ionofree(acct_obs obs, pobs_head obs_h, int k, int GNSS)
{
double P1 = obs.Per1[k], P2 = obs.Per2[k],
freq1 = obs.freq1, freq2 = obs.freq2;
//IF-IC
if (P1 != 0.0 && P2 != 0.0) {
P1 = (pow(freq1, 2) * P1) / (pow(freq1, 2) - pow(freq2, 2))
- (pow(freq2, 2) * P2) / (pow(freq1, 2) - pow(freq2, 2));
return P1;
}
if (P1 == 0.0 || P2 == 0.0) {
if (P1 == 0.0 && P2 != 0.0) return P2;
if (P1 != 0.0 && P2 == 0.0) return P1;
return 0.0;
}
}
/*Rest correction of observation*/
static double restcorr(pobs_head obs_h, acct_obs obs, int ionopt, int tropopt,
int k, int GNSS, double elev) {
double P = 0.0, diono = 0.0, dtrop = 0.0;
switch (ionopt) {
case 0:P = obs.Per1[k]; break;
case 1:P = ionofree(obs, obs_h, k, GNSS); break;
case 2:break;
}
switch (tropopt) {
case 0:break;
case 1:dtrop = trohopfield(obs_h, elev); break;
case 2:dtrop = trosaastamoinen(obs_h, elev); break;
}
P = P - diono - dtrop;
return P;
}
/*(Weighted)Least square estimate*/
int lsq(const double* BtP, const double* L, const double* B, int n, int m, double* x,
double* Q)
{
double* BtPL;
int info;
if (m < n) return -1;
BtPL = mat(n, 1);
matmul("NN", n, 1, m, 1.0, BtP, L, 0.0, BtPL); /* =B'*P*L */
matmul("NN", n, n, m, 1.0, BtP, B, 0.0, Q); /* =B'*P*B */
if (!(info = matinv(Q, n)))
matmul("NN", n, 1, n, 1.0, Q, BtPL, 0.0, x); /* x=Q^-1*(B'*P*L) */
free(BtPL);
return info;
}
/*Construct into desgin matrix and solve the lsq*/
stations designmat(pobs_head obs_h, acct_obs obs,
double *l, double* m, double* n, double* o,
double* B, double* P, double* L,
double X, double Y, double Z,
int satnum, int ionopt, int tropopt, int GNSS)
{
stations sta;
double Q[16], dx[4], *BP, *PL;
BP = mat(satnum, 4);
PL = mat(satnum, 1);
double R;
for (int i = 0; i < satnum; i++) {
R = sqrt(
pow(l[i] - X, 2) +
pow(m[i] - Y, 2) +
pow(n[i] - Z, 2)
);
B[i + satnum * 0] = -(l[i] - X) / R;
B[i + satnum * 1] = -(m[i] - Y) / R;
B[i + satnum * 2] = -(n[i] - Z) / R;
B[i + satnum * 3] = 1;
P[i * (satnum) + i] = pow(sin(o[i]),2);
L[i] = restcorr(obs_h, obs, ionopt, tropopt, i, GNSS, o[i]) -
R + obs.sclk[i] * C_V;
}
matmul("TN", 4, satnum, satnum, 1.0, B, P, 0.0, BP);//B'*P
if (!lsq(BP, L, B, 4, satnum, dx, Q))
sta.X = dx[0]; sta.Y = dx[1]; sta.Z = dx[2]; sta.delta_TR = dx[3];
free(BP); free(PL);
return sta;
}
/*Output the header data of satllite position solution*/
FILE* headerout(pobs_head obs_h, int mode,
char obs_path[MAXPATH], char nav_path[MAXPATH], char res_path[MAXPATH])
{
time_t gen_time;
time(&gen_time);
FILE* result_file_clear = fopen(res_path, "w");
fclose(result_file_clear);
FILE* result_file = fopen(res_path, "a+");
fprintf(result_file, ">GENERATE PROGRAM : KNZ_GeoTrackLab ver%s\n", KNZ_GTL_VER);
fprintf(result_file, " GENERATE SOURCE : %.10s\n", obs_h->marker);
if (mode == 0); fprintf(result_file, " GENERATE TYPE : Position Resolve\n");
if (mode == 1); fprintf(result_file, " GENERATE TYPE : Satellite Position\n");
fprintf(result_file, " GENERATE TIME : %s", ctime(&gen_time));
fprintf(result_file, " OBS FILE PATH : %s\n", obs_path);
fprintf(result_file, " NAV FILE PATH : %s\n", nav_path);
fprintf(result_file, " APPROX POSITION XYZ: %13.04f%13.04f%13.04f\n"\
" APPROX POSITION BLH: %12.07f %12.07f %12.07f\n"
, obs_h->apX, obs_h->apY, obs_h->apZ
, obs_h->apB, obs_h->apL, obs_h->apH);
fprintf(result_file, " TIME OF FIRST OBS : %4d %02d %02d %02d %02d %07.4f\n"
, obs_h->f_y, obs_h->f_m, obs_h->f_d, obs_h->f_h, obs_h->f_min, obs_h->f_sec);
fprintf(result_file, " TIME OF LAST OBS : %4d %02d %02d %02d %02d %07.4f\n"
, obs_h->l_y, obs_h->l_m, obs_h->l_d, obs_h->l_h, obs_h->l_min, obs_h->l_sec);
fprintf(result_file, " INTERVAL : %5.02f\n",obs_h->interval);
fprintf(result_file, "<END OF HEADER\n");
return result_file;
}
/*Output the satellite solution data*/
void outdata(blh blh, FILE* res_file, int sPRN, int GNSS)
{
switch (GNSS) {
case GPS:
fprintf(res_file, "\nG%02d %9.06f %9.06f %15.05f"
, sPRN, blh.B, blh.L, blh.H);break;
case BDS:
fprintf(res_file, "\nC%02d %9.06f %9.06f %15.05f"
, sPRN, blh.B, blh.L, blh.H);break;
case GAL:
fprintf(res_file, "\nE%02d %9.06f %9.06f %15.05f"
, sPRN, blh.B, blh.L, blh.H);break;
case GLO:
fprintf(res_file, "\nR%02d %9.06f %9.06f %15.05f"
, sPRN, blh.B, blh.L, blh.H);break;
}
}
/*Output the satellite solution data*/
void solution(FILE* res_file,pobs_head obs_h, double X, double Y, double Z)
{
double deltax, deltay, deltaz;
deltax = X - obs_h->apX;
deltay = Y - obs_h->apY;
deltaz = Z - obs_h->apZ;
fprintf(res_file, "\nRec:%9.4f %9.4f %9.4f",
deltax, deltay, deltaz);
}
+86
View File
@@ -0,0 +1,86 @@
#include "brdm2pos.h"
using namespace std;
/**
* Convert Time format to GPS second of week.
*
* \param y: Year of
* \param m: Month of
* \param d: Day of
* \param h: Hour of
* \param min: Minute of
* \param sec: Second of
* \return GPS: Second of week
*/
double time2gpst(int y, int m, int d, double h, int min, double sec)
{
if (m > 2)
{
y = y;
m = m;
}
if (m <= 2)
{
y = y - 1;
m = m + 12;
}
h = h + min / 60.0 + sec / 3600.0;
double JD = (int)(365.25 * y) + (int)(30.6001 * (m + 1)) + d + h / 24.0 + 1720981.5;
double MJD = JD - 2400000.5;
int gpsweek = (int)((MJD - 44244) / 7);
double secofweek = (MJD - 44244.0 - gpsweek * 7.0) * 86400.0;
return secofweek;
}
/**
* Convert UTC(SU) time to GPS second of week.
*
* \param JD_UTCSU: JD of UTC(SU) time
* \return GPS: Second of week
*/
double jdutc2gpst(double JD_UTCSU)
{
double n;//Leap second
if (2451179.5000000 < JD_UTCSU && JD_UTCSU < 2453736.5000000) { n = 32.0; }
else if (2453736.5000000 < JD_UTCSU && JD_UTCSU < 2454832.5000000) { n = 33.0; }
else if (2454832.5000000 < JD_UTCSU && JD_UTCSU < 2455927.5000000) { n = 34.0; }
else if (2455927.5000000 < JD_UTCSU && JD_UTCSU < 2457023.5000000) { n = 35.0; }
else if (2457023.5000000 < JD_UTCSU && JD_UTCSU < 2457754.5000000) { n = 36.0; }
else if (2457754.5000000 < JD_UTCSU) { n = 37.0; }
JD_UTCSU += ((n * 1 - 19) / 3600.0) / 24.0;
double MJD = JD_UTCSU - 2400000.5;
int gpsweek = (int)((MJD - 44244) / 7);
double secofweek = (MJD - 44244.0 - gpsweek * 7.0) * 86400.0;
return secofweek;
}
/**
* Convert UTC time to JD format.
*
* \param y: Year of UTC time
* \param m: Month of UTC time
* \param d: Day of UTC time
* \param h: Hour of UTC time
* \param min: Minute of UTC time
* \param sec: Second of UTC time
* \return JD:
*/
double utctime2jd(int y, int m, int d, double h, int min, double sec)
{
if (m > 2)
{
y = y;
m = m;
}
if (m <= 2)
{
y = y - 1;
m = m + 12;
}
h = h + min / 60.0 + sec / 3600.0;
double JD = (int)(365.25 * y) + (int)(30.6001 * (m + 1)) + d + h / 24.0 + 1720981.5;
return JD;
}