diff --git a/README.md b/README.md
index a210c2e2..95259263 100644
--- a/README.md
+++ b/README.md
@@ -161,17 +161,18 @@ For more comprehensive installation instructions, please refer to [INSTALLATION.
24. [Server Config](#socketserver) facility with the ability to act as an NTRIP caster (mountpoint = `pygnssutils`) or generic socket server. To display the Server Configuration Dialog, click
, or go to Menu..Options..Server Configuration Dialog.
25. [GPX Track Viewer](#gpxviewer) facility with the ability to map GPX files containing track, route or waypoint data and show elevation and speed profiles and other metadata. To display the GPX Track viewer, go to Menu..Options..GPX Track Viewer.
-26. [Import Custom Map](#custommap) facility which allows the user to import geo-referenced images for use as background maps. To display the Import Custom Map dialog, go to Menu..Options..Import Custom Map.
-27. [Configuration Command Recorder](#recorder) facility which allows the user to record, save, load, import (*as a preset*) and replay UBX, NMEA or TTY configuration commands sent to a receiver. To display the Command Record Facility dialog, go to Menu..Options..Configuration Command Recorder.
-28. [SPARTN Client](#spartnconfig) facility with the ability to configure an IP or L-Band SPARTN Correction source and SPARTN-compatible GNSS receiver (e.g. ZED-F9P) and pass the incoming correction data to the GNSS receiver (*requires an Internet connection and access to a SPARTN location service*). To display the SPARTN Client Configuration Dialog, go to Menu..Options..SPARTN Configuration Dialog.
+26. [RINEX Conversion](#rinex) facility which supports conversion of previously-saved binary datalogs to RINEX observation and navigation format. To display the RINEX Conversion dialog, go to Menu..Options..RINEX Conversion.
+27. [Import Custom Map](#custommap) facility which allows the user to import geo-referenced images for use as background maps. To display the Import Custom Map dialog, go to Menu..Options..Import Custom Map.
+28. [Configuration Command Recorder](#recorder) facility which allows the user to record, save, load, import (*as a preset*) and replay UBX, NMEA or TTY configuration commands sent to a receiver. To display the Command Record Facility dialog, go to Menu..Options..Configuration Command Recorder.
+29. [SPARTN Client](#spartnconfig) facility with the ability to configure an IP or L-Band SPARTN Correction source and SPARTN-compatible GNSS receiver (e.g. ZED-F9P) and pass the incoming correction data to the GNSS receiver (*requires an Internet connection and access to a SPARTN location service*). To display the SPARTN Client Configuration Dialog, go to Menu..Options..SPARTN Configuration Dialog.
#### GUI refresh rate setting
-29. PyGPSClient processes all incoming GNSS data in 'real time' but, by default, the GUI is only refreshed every 0.5 seconds. The refresh rate can be manually configured via the `guiupdateinterval_f` setting in the json configuration file. **NB:** PyGPSClient may become unresponsive on slower platforms (e.g. Raspberry Pi) at high message rates if the GUI update interval is less than 0.1 seconds, though lower intervals (<= 0.1 secs) can be accommodated on more powerful platforms.
+30. PyGPSClient processes all incoming GNSS data in 'real time' but, by default, the GUI is only refreshed every 0.5 seconds. The refresh rate can be manually configured via the `guiupdateinterval_f` setting in the json configuration file. **NB:** PyGPSClient may become unresponsive on slower platforms (e.g. Raspberry Pi) at high message rates if the GUI update interval is less than 0.1 seconds, though lower intervals (<= 0.1 secs) can be accommodated on more powerful platforms.
#### Toplevel ('pop-up') dialog setting
-30. The behaviour of Toplevel ('pop-up') dialogs will depend on the screen resolution and 'transient' setting. If the width or height of a Toplevel dialog exceeds the screen resolution, the dialog will be displayed in a scrollable, resizeable window. Otherwise, the dialog is displayed as a fixed, non-resizeable panel.
+31. The behaviour of Toplevel ('pop-up') dialogs will depend on the screen resolution and 'transient' setting. If the width or height of a Toplevel dialog exceeds the screen resolution, the dialog will be displayed in a scrollable, resizeable window. Otherwise, the dialog is displayed as a fixed, non-resizeable panel.
- A boolean configuration setting `transient_dialog_b` governs whether Toplevel dialogs are 'transient' (i.e. always on top of main application dialog) or not. Changing this setting to `0` allows Toplevel dialogs to be minimised independently of the main application window, but be mindful that some dialogs may end up hidden behind others e.g. "Open file/folder" dialogs. **If a file open button appears unresponsive, check that the "Open file/folder" panel isn't already open but obscured**.
- If you're accessing the desktop via a VNC session (e.g. to a headless Raspberry Pi) it is recommended to keep the setting at the default `1`, as VNC may not recognise keystrokes on overlaid non-transient windows.
@@ -421,7 +422,7 @@ Click . See [pygnssutils release notes](https://github.com/semuconsulting/pygnssutils/releases/tag/v1.2.0) for details of current functionality and limitations**. The intention is to enhance functionality in future releases.
+**NB: RINEX conversion is currently an experimental facility based on the [pygnssutils pyrinexconv CLI utility](https://github.com/semuconsulting/pygnssutils#rinexconvert). See [pygnssutils release notes](https://github.com/semuconsulting/pygnssutils/releases/tag/v1.2.1) for details of current functionality and limitations**. The intention is to enhance functionality in future releases.

@@ -429,18 +430,18 @@ The RINEX Conversion Dialog supports the conversion of raw observation, navigati
**Pre-Requisites:**
-1. A previously-saved binary datalog containing raw observation, navigation and/or meteorology data e.g. UBX RXM-RAWX and RXM-SFRBX¹ messages or RTCM3 ephemerides (1019, 1020, 1042-1046) messages. A suitable datalog can be recorded using PyGPSClient's [binary datalogging](#datalog) facility. **NB**: The file should contain at least 15-30 minutes of continuous data.
+1. A previously-saved binary datalog containing raw observation, navigation and/or meteorology data e.g. UBX RXM-RAWX and RXM-SFRBX¹ messages or RTCM3 ephemerides (1019, 1020, 1041-1046) messages. A suitable datalog can be recorded using PyGPSClient's [binary datalogging](#datalog) facility. **NB**: The file should contain at least 15-30 minutes of continuous data.
- ¹ Only GPS LNAV data is supported in this experimental release, though the underlying pygnssutils classes are readily extensible.
+ ¹ Only GPS LNAV & CNAV data is supported in this experimental release, though the underlying pygnssutils classes are readily extensible.
**Instructions:**
1. Click the  to select the required binary datalog file.
-2. Select the required RINEX protocol version (*only 3.05 supported in this experimental release*).
+2. Select the required RINEX protocol version (3.05 or 4.02).
3. Select the required RINEX output file types - O observation, N navigation or M meteorology.
-4. Select the datasource for each RINEX output type e.g. R Receiver, N RTCM3 (NTRIP), etc.
+4. Select the datasource for each RINEX output type e.g. UBX (u-blox), RTCM3, NMEA 0183.
5. (Optional) Select the GNSS to be included e.g. GPS, GAL, BDS, etc.
-6. (Optional) Select the RINEX observation (frequency / signal) codes to be included e.g. 1C, 2L, etc.
+6. (Optional) Select the RINEX observation (frequency / signal) codes to be included e.g. 1C, 2L, 5I, etc.
7. (Optional) Expand the advanced panel  to enter details of the marker, antenna, receiver, observer and any user-defined comments.
8. Click  to process the file. A progress bar will be displayed and, when complete, the output file names (*.rnx) and record counts will be displayed at the foot of the dialog.
9. Processing can be cancelled by clicking .
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index 69934f10..73e9cd9f 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,5 +1,9 @@
# PyGPSClient Release Notes
+### RELEASE 1.6.8
+
+1. Updates to experimental RINEX conversion dialog for pygnssutils >=1.2.1. Provisional support for RINEX 4.02 and GPS CNAV added.
+
### RELEASE 1.6.7
ENHANCEMENTS:
diff --git a/images/rinex_dialog.png b/images/rinex_dialog.png
index 4f7df7fd..4b668433 100644
Binary files a/images/rinex_dialog.png and b/images/rinex_dialog.png differ
diff --git a/pyproject.toml b/pyproject.toml
index 82df662a..95b01984 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -52,7 +52,7 @@ classifiers = [
dependencies = [
"requests>=2.28.0",
"Pillow>=9.0.0",
- "pygnssutils>=1.2.0",
+ "pygnssutils>=1.2.1",
"pyunigps>=1.0.0",
"pynmeagps>=1.1.4",
]
diff --git a/src/pygpsclient/_version.py b/src/pygpsclient/_version.py
index f2e2790f..dd27ace7 100644
--- a/src/pygpsclient/_version.py
+++ b/src/pygpsclient/_version.py
@@ -8,4 +8,4 @@
:license: BSD 3-Clause
"""
-__version__ = "1.6.7"
+__version__ = "1.6.8"
diff --git a/src/pygpsclient/rinex_dialog.py b/src/pygpsclient/rinex_dialog.py
index 5ed9db97..d651061c 100644
--- a/src/pygpsclient/rinex_dialog.py
+++ b/src/pygpsclient/rinex_dialog.py
@@ -69,27 +69,33 @@
DLGTRINEX,
LBLRINEXANTENNA,
LBLRINEXCOMMENT,
+ LBLRINEXCOUNTRY,
+ LBLRINEXDOI,
LBLRINEXGNSSTYPES,
LBLRINEXINPUTFILE,
+ LBLRINEXLICENSE,
LBLRINEXMARKER,
LBLRINEXOBSERVER,
LBLRINEXOBSTYPES,
LBLRINEXOUTPUTS,
LBLRINEXRCVR,
LBLRINEXSTARTTIME,
+ LBLRINEXSTATION,
LBLRINEXTYPES,
LBLRINEXVER,
+ NA,
RINEXFILEINVALID,
RINEXFILEVALID,
RINEXFILEVALIDATING,
)
from pygpsclient.toplevel_dialog import ToplevelDialog
-RINEXVERSIONS = [
- "3.05",
-] # "4.02"]
+RINEXVERSIONS = ("3.05", "4.02")
RINEXTYPES = (OBS, NAV, MET)
-RINEXSOURCES = ("R Receiver", "S Stream", "N RTCM3", "U Unknown")
+NMEASOURCE = "NMEA 0183"
+RTCMSOURCE = "RTCM 3"
+UBXSOURCE = "UBX (u-blox)"
+RINEXSOURCES = {UBXSOURCE: "R", NMEASOURCE: "R", RTCMSOURCE: "N"}
RINEXMARKERTYPES = (
"GEODETIC",
"HUMAN",
@@ -134,6 +140,7 @@ def __init__(self, app, *args, **kwargs): # pylint: disable=unused-argument
self._navsource = StringVar()
self._metsource = StringVar()
self._rinexver = StringVar()
+ self._countrycode = StringVar()
self._rinexobs = IntVar()
self._rinexnav = IntVar()
self._rinexmet = IntVar()
@@ -161,6 +168,9 @@ def __init__(self, app, *args, **kwargs): # pylint: disable=unused-argument
self._outputlabels = {}
for rt in (OBS, NAV, MET):
self._outputlabels[rt] = StringVar()
+ self._doi = StringVar()
+ self._license = StringVar()
+ self._station = StringVar()
self._settings = {}
self._status = False
self._filecount = 0
@@ -238,8 +248,8 @@ def _body(self):
)
self._spn_obssource = Spinbox(
self._frm_basic,
- values=RINEXSOURCES,
- width=10,
+ values=list(RINEXSOURCES),
+ width=14,
wrap=True,
textvariable=self._obssource,
state=READONLY,
@@ -254,8 +264,8 @@ def _body(self):
)
self._spn_navsource = Spinbox(
self._frm_basic,
- values=RINEXSOURCES,
- width=10,
+ values=list(RINEXSOURCES),
+ width=14,
wrap=True,
textvariable=self._navsource,
state=READONLY,
@@ -270,8 +280,8 @@ def _body(self):
)
self._spn_metsource = Spinbox(
self._frm_basic,
- values=RINEXSOURCES,
- width=10,
+ values=list(RINEXSOURCES),
+ width=14,
wrap=True,
textvariable=self._metsource,
state=READONLY,
@@ -407,11 +417,43 @@ def _body(self):
self._lbl_observer = Label(self._frm_advanced, text=LBLRINEXOBSERVER, anchor=W)
self._ent_observer = Entry(
self._frm_advanced,
- width=60,
+ width=30,
textvariable=self._observer,
state=NORMAL,
relief="sunken",
)
+ self._lbl_country = Label(self._frm_advanced, text=LBLRINEXCOUNTRY, anchor=W)
+ self._ent_country = Entry(
+ self._frm_advanced,
+ width=5,
+ textvariable=self._countrycode,
+ state=NORMAL,
+ relief="sunken",
+ )
+ self._lbl_doi = Label(self._frm_advanced, text=LBLRINEXDOI, anchor=W)
+ self._ent_doi = Entry(
+ self._frm_advanced,
+ width=60,
+ textvariable=self._doi,
+ state=NORMAL,
+ relief="sunken",
+ )
+ self._lbl_license = Label(self._frm_advanced, text=LBLRINEXLICENSE, anchor=W)
+ self._ent_license = Entry(
+ self._frm_advanced,
+ width=60,
+ textvariable=self._license,
+ state=NORMAL,
+ relief="sunken",
+ )
+ self._lbl_station = Label(self._frm_advanced, text=LBLRINEXSTATION, anchor=W)
+ self._ent_station = Entry(
+ self._frm_advanced,
+ width=60,
+ textvariable=self._station,
+ state=NORMAL,
+ relief="sunken",
+ )
self._lbl_comments = Label(self._frm_advanced, text=LBLRINEXCOMMENT, anchor=W)
self._lbl_starttime = Label(
self._frm_advanced, text=LBLRINEXSTARTTIME, anchor=W
@@ -442,90 +484,107 @@ def _do_layout(self):
self._frm_body.grid(column=0, row=0, sticky=NSEW)
self._frm_basic.grid(column=0, row=0, sticky=NSEW)
- self._lbl_infile.grid(column=0, row=0, columnspan=6, padx=3, pady=3, sticky=W)
- self._btn_toggle.grid(column=6, row=0, padx=3, pady=3, rowspan=2, sticky=E)
- self._ent_infilepath.grid(
- column=0, row=1, columnspan=6, padx=3, pady=3, sticky=EW
- )
- self._btn_load.grid(column=0, row=2, padx=3, pady=3, sticky=W)
- self._btn_convert.grid(column=5, row=2, padx=3, pady=3, sticky=E)
- self._btn_cancel.grid(column=6, row=2, padx=3, pady=3, sticky=E)
+ self._lbl_infile.grid(column=0, row=0, columnspan=6, padx=3, sticky=W)
+ self._btn_toggle.grid(column=6, row=0, padx=3, rowspan=2, sticky=E)
+ self._ent_infilepath.grid(column=0, row=1, columnspan=6, padx=3, sticky=EW)
+ self._btn_load.grid(column=0, row=2, padx=3, sticky=W)
+ self._btn_convert.grid(column=5, row=2, padx=3, sticky=E)
+ self._btn_cancel.grid(column=6, row=2, padx=3, sticky=E)
ttk.Separator(self._frm_basic).grid(
- column=0, row=3, columnspan=7, padx=3, pady=3, sticky=EW
- )
- self._lbl_rinexver.grid(column=0, row=4, padx=3, columnspan=2, pady=3, sticky=W)
- self._spn_rinexver.grid(column=2, row=4, padx=3, columnspan=2, pady=3, sticky=W)
- self._lbl_outtypes.grid(column=0, row=5, columnspan=7, padx=3, pady=3, sticky=W)
- self._chk_rinexobs.grid(column=0, row=6, columnspan=2, padx=3, pady=3, sticky=W)
- self._chk_rinexnav.grid(column=2, row=6, columnspan=2, padx=3, pady=3, sticky=W)
- self._chk_rinexmet.grid(column=4, row=6, columnspan=2, padx=3, pady=3, sticky=W)
- self._spn_obssource.grid(
- column=0, row=7, padx=3, columnspan=2, pady=3, sticky=W
- )
- self._spn_navsource.grid(
- column=2, row=7, padx=3, columnspan=2, pady=3, sticky=W
- )
- self._spn_metsource.grid(
- column=4, row=7, padx=3, columnspan=2, pady=3, sticky=W
- )
- self._lbl_gnsstypes.grid(
- column=0, row=8, columnspan=7, padx=3, pady=3, sticky=W
- )
- self._chk_rxgps.grid(column=0, row=9, padx=3, pady=3, sticky=W)
- self._chk_rxsbas.grid(column=1, row=9, padx=3, pady=3, sticky=W)
- self._chk_rxgalileo.grid(column=2, row=9, padx=3, pady=3, sticky=W)
- self._chk_rxbeidou.grid(column=3, row=9, padx=3, pady=3, sticky=W)
- self._chk_rxqzss.grid(column=4, row=9, padx=3, pady=3, sticky=W)
- self._chk_rxglonass.grid(column=5, row=9, padx=3, pady=3, sticky=W)
- self._chk_rxnavic.grid(column=6, row=9, padx=3, pady=3, sticky=W)
- self._lbl_obstypes.grid(
- column=0, row=10, columnspan=7, padx=3, pady=3, sticky=W
- )
- self._ent_obstypes.grid(
- column=0, row=11, columnspan=7, padx=3, pady=3, sticky=EW
- )
- self._pgb_elapsed.grid(
- column=0, row=12, columnspan=7, padx=3, pady=3, sticky=EW
- )
+ column=0, row=3, columnspan=7, padx=3, sticky=EW
+ )
+ self._lbl_rinexver.grid(column=0, row=4, padx=3, columnspan=2, sticky=W)
+ self._spn_rinexver.grid(column=2, row=4, padx=3, columnspan=2, sticky=W)
+ self._lbl_country.grid(column=4, row=4, padx=3, sticky=W)
+ self._ent_country.grid(column=5, row=4, padx=3, sticky=W)
+ self._lbl_outtypes.grid(column=0, row=5, columnspan=7, padx=3, sticky=W)
+ self._chk_rinexobs.grid(column=0, row=6, columnspan=2, padx=3, sticky=W)
+ self._chk_rinexnav.grid(column=2, row=6, columnspan=2, padx=3, sticky=W)
+ self._chk_rinexmet.grid(column=4, row=6, columnspan=2, padx=3, sticky=W)
+ self._spn_obssource.grid(column=0, row=7, padx=3, columnspan=2, sticky=W)
+ self._spn_navsource.grid(column=2, row=7, padx=3, columnspan=2, sticky=W)
+ self._spn_metsource.grid(column=4, row=7, padx=3, columnspan=2, sticky=W)
+ self._lbl_gnsstypes.grid(column=0, row=8, columnspan=7, padx=3, sticky=W)
+ self._chk_rxgps.grid(column=0, row=9, padx=3, sticky=W)
+ self._chk_rxsbas.grid(column=1, row=9, padx=3, sticky=W)
+ self._chk_rxgalileo.grid(column=2, row=9, padx=3, sticky=W)
+ self._chk_rxbeidou.grid(column=3, row=9, padx=3, sticky=W)
+ self._chk_rxqzss.grid(column=4, row=9, padx=3, sticky=W)
+ self._chk_rxglonass.grid(column=5, row=9, padx=3, sticky=W)
+ self._chk_rxnavic.grid(column=6, row=9, padx=3, sticky=W)
+ self._lbl_obstypes.grid(column=0, row=10, columnspan=7, padx=3, sticky=W)
+ self._ent_obstypes.grid(column=0, row=11, columnspan=7, padx=3, sticky=EW)
+ self._pgb_elapsed.grid(column=0, row=12, columnspan=7, padx=3, sticky=EW)
ttk.Separator(self._frm_basic).grid(
- column=0, row=13, columnspan=7, padx=3, pady=3, sticky=EW
+ column=0, row=13, columnspan=7, padx=3, sticky=EW
)
self._lbl_outputs.grid(column=0, row=14, columnspan=7, padx=3, pady=1, sticky=W)
for i, lbl in enumerate(self._lbl_output_labels.values()):
lbl.grid(column=0, row=15 + i, columnspan=7, padx=3, pady=1, sticky=EW)
- self._lbl_marker.grid(column=0, row=0, columnspan=3, padx=3, pady=3, sticky=W)
- self._ent_markernum.grid(column=0, row=1, padx=3, pady=3, sticky=W)
- self._ent_markername.grid(column=1, row=1, padx=3, pady=3, sticky=W)
- self._spn_markertype.grid(column=2, row=1, padx=3, pady=3, sticky=W)
- self._lbl_antenna.grid(column=0, row=2, columnspan=3, padx=3, pady=3, sticky=W)
- self._ent_antennanum.grid(column=0, row=3, padx=3, pady=3, sticky=W)
- self._ent_antennatype.grid(column=1, row=3, padx=3, pady=3, sticky=W)
- self._lbl_receiver.grid(column=0, row=4, columnspan=3, padx=3, pady=3, sticky=W)
- self._ent_rcvrnum.grid(column=0, row=5, padx=3, pady=3, sticky=W)
- self._ent_rcvrtype.grid(column=1, row=5, padx=3, pady=3, sticky=W)
- self._ent_rcvrversion.grid(column=2, row=5, padx=3, pady=3, sticky=W)
- self._lbl_observer.grid(column=0, row=6, columnspan=3, padx=3, pady=3, sticky=W)
- self._ent_observer.grid(
- column=0, row=7, columnspan=3, padx=3, pady=3, sticky=EW
- )
- self._lbl_starttime.grid(
- column=0, row=8, columnspan=2, padx=3, pady=3, sticky=W
- )
- self._ent_starttime.grid(column=2, row=8, padx=3, pady=3, sticky=W)
- self._lbl_comments.grid(column=0, row=9, columnspan=3, padx=3, pady=3, sticky=W)
+ self._lbl_marker.grid(column=0, row=0, columnspan=3, padx=3, sticky=W)
+ self._ent_markernum.grid(column=0, row=1, padx=3, sticky=W)
+ self._ent_markername.grid(column=1, row=1, padx=3, sticky=W)
+ self._spn_markertype.grid(column=2, row=1, padx=3, sticky=W)
+ self._lbl_antenna.grid(column=0, row=2, columnspan=3, padx=3, sticky=W)
+ self._ent_antennanum.grid(column=0, row=3, padx=3, sticky=W)
+ self._ent_antennatype.grid(column=1, row=3, padx=3, sticky=W)
+ self._lbl_receiver.grid(column=0, row=4, columnspan=3, padx=3, sticky=W)
+ self._ent_rcvrnum.grid(column=0, row=5, padx=3, sticky=W)
+ self._ent_rcvrtype.grid(column=1, row=5, padx=3, sticky=W)
+ self._ent_rcvrversion.grid(column=2, row=5, padx=3, sticky=W)
+ self._lbl_observer.grid(column=0, row=6, columnspan=3, padx=3, sticky=W)
+ self._lbl_country.grid(column=2, row=6, columnspan=3, padx=3, sticky=W)
+ self._ent_observer.grid(column=0, row=7, columnspan=2, padx=3, sticky=EW)
+ self._ent_country.grid(column=2, row=7, padx=3, sticky=W)
+ self._lbl_starttime.grid(column=0, row=8, columnspan=2, padx=3, sticky=W)
+ self._ent_starttime.grid(column=2, row=8, padx=3, sticky=W)
+ self._lbl_comments.grid(column=0, row=9, columnspan=3, padx=3, sticky=W)
for i, ec in enumerate(self._entcomments):
- ec.grid(column=0, row=10 + i, columnspan=3, padx=3, pady=1, sticky=EW)
+ ec.grid(column=0, row=10 + i, columnspan=3, padx=3, sticky=EW)
for col in range(7): # make columns equal width
self._frm_basic.grid_columnconfigure(col, weight=1, uniform="col")
+ def _do_layout_rinex4(self, show: bool, startrow: int = 10 + USERCOMMENTS):
+ """
+ Position optional RINEX 4 widgets in frame.
+ """
+
+ if show:
+ self._lbl_doi.grid(
+ column=0, row=startrow + 1, columnspan=3, padx=3, sticky=W
+ )
+ self._ent_doi.grid(
+ column=0, row=startrow + 2, columnspan=3, padx=3, sticky=EW
+ )
+ self._lbl_license.grid(
+ column=0, row=startrow + 3, columnspan=3, padx=3, sticky=W
+ )
+ self._ent_license.grid(
+ column=0, row=startrow + 4, columnspan=3, padx=3, sticky=EW
+ )
+ self._lbl_station.grid(
+ column=0, row=startrow + 5, columnspan=3, padx=3, sticky=W
+ )
+ self._ent_station.grid(
+ column=0, row=startrow + 6, columnspan=3, padx=3, sticky=EW
+ )
+ else:
+ self._lbl_doi.grid_forget()
+ self._ent_doi.grid_forget()
+ self._lbl_license.grid_forget()
+ self._ent_license.grid_forget()
+ self._lbl_station.grid_forget()
+ self._ent_station.grid_forget()
+
def _attach_events(self):
"""
Set up event listeners.
"""
+ self._rinexver.trace_add(TRACEMODE_WRITE, self._on_update_rinexver)
for setting in (
self._rinexobs,
self._rinexnav,
@@ -542,7 +601,7 @@ def _attach_events(self):
def _reset(self):
"""
- Reset configuration widgets.
+ Reset dialog widgets.
"""
for chk in (
@@ -558,9 +617,23 @@ def _reset(self):
self._rxnavic,
):
chk.set(1)
+ self._obssource.set(UBXSOURCE)
+ self._navsource.set(UBXSOURCE)
+ self._metsource.set(NMEASOURCE)
+ rcvrname = self.__app.gnss_status.version_data.get("hwversion", NA)
+ self._rcvrname.set("" if rcvrname == NA else rcvrname)
+ rcvrversion = self.__app.gnss_status.version_data.get("fwversion", NA)
+ self._rcvrversion.set("" if rcvrversion == NA else rcvrversion)
self._starttime.set(datetime.now(timezone.utc).strftime("%Y%m%d%H%M%S%z"))
self.set_controls(self._status)
+ def _on_update_rinexver(self, var, index, mode): # pylint: disable=unused-argument
+ """
+ Update RINEX version.
+ """
+
+ self._do_layout_rinex4(self._rinexver.get() >= "4.00", 10 + USERCOMMENTS)
+
def _on_update_config(self, var, index, mode): # pylint: disable=unused-argument
"""
Update in-memory configuration if setting is changed.
@@ -755,16 +828,20 @@ def _do_conversion(self, **kwargs):
self._rcvrversion.get(),
]
observer = self._observer.get()
+ doi = self._doi.get()
+ license = self._license.get()
+ station = self._station.get()
comments = ["PyGPSClient RINEX Converter Dialog"]
+ country = self._countrycode.get()
for cvar in self._usercommentvar:
cval = cvar.get()
if cval != "":
comments.append(cval)
protfilter = NMEA_PROTOCOL | RTCM3_PROTOCOL | UBX_PROTOCOL
datasource = [
- self._obssource.get()[0:1],
- self._navsource.get()[0:1],
- self._metsource.get()[0:1],
+ RINEXSOURCES[self._obssource.get()],
+ RINEXSOURCES[self._navsource.get()],
+ RINEXSOURCES[self._metsource.get()],
]
rc = RinexConverter(
self.__app,
@@ -781,6 +858,10 @@ def _do_conversion(self, **kwargs):
observer=observer,
comments=comments,
protfilter=protfilter,
+ doi=doi,
+ license=license,
+ station=station,
+ country=country,
**kwargs,
)
self._stopevent.clear()
diff --git a/src/pygpsclient/strings.py b/src/pygpsclient/strings.py
index 7e96429d..b5363bfd 100644
--- a/src/pygpsclient/strings.py
+++ b/src/pygpsclient/strings.py
@@ -157,14 +157,18 @@
LBLPUBLICIP = "Public IP"
LBLRINEXANTENNA = "Antenna Number / Type:"
LBLRINEXCOMMENT = "User Comments:"
+LBLRINEXCOUNTRY = "Country Code:"
+LBLRINEXDOI = "Digital Object Identifier:"
LBLRINEXGNSSTYPES = "GNSS Constellations:"
LBLRINEXINPUTFILE = "GNSS Binary Data Log File:"
+LBLRINEXLICENSE = "License of Use:"
LBLRINEXMARKER = "Marker Number / Name / Type:"
LBLRINEXOBSERVER = "Observer / Agency:"
LBLRINEXOBSTYPES = "Observation Codes (comma-separated, blank for ALL):"
LBLRINEXOUTPUTS = "Output files and process counts{path}:"
LBLRINEXRCVR = "Receiver Number / Name / Version:"
-LBLRINEXSTARTTIME = "Approximate Start Time of RTCM3 Data:"
+LBLRINEXSTARTTIME = "Approximate Start Time of RTCM 3 Data:"
+LBLRINEXSTATION = "Station Metadata:"
LBLRINEXTYPES = "RINEX Output File Types and Data Sources:"
LBLRINEXVER = "RINEX Version:"
LBLSERVERCONFIG = "Server\nConfig"