rinex2bin
is a small command line utility to serialize your RINEX (Receiver Indepent EXchange) files
into BINEX (Binary EXchange). The tool can either
-
serialize into a BINEX (so called "bin") file, which may serve as a very compact option to distribute your GNSS/Geo data
-
stream directly to a writable I/O interface. Allowing to broadcast your GNSS/Geo data in real-time.
This tool is based on the GeoRust/RINEX parser.
rinex2bin
works well with Navigation RINEX. Observation RINEX is work in progress.
You can download the latest version from the release portal
You can directly install the tool from Cargo with internet access:
cargo install rinex2bin
Download the version you are interested in:
git clone https://github.com/rtk-rs/rinex2bin
And build it using cargo:
cargo build --all-features -r
rinex2bin
uses the standardized Rust logger to notify of potential local issues
during streaming. To activate the logs,
simply define the RUST_LOG
environment variable, you have many sensivity levels:
- info
- error
- debug
- trace
rinex2bin
always requires an input RINEX that needs to be readable.
Any supported format may apply, refer to the list of supported formats.
By default, the tool will serialize into a standardized binary ("bin") file. The file name is guessed from the actual RINEX content.
rinex2bin amel0010.21g
The BINEX stream will always start with the following key elements
- a BINEX Monument GEO comment announcing the start of a new stream, including the name of this software package & revision
- a BINEX Monument GEO comment describing the software name & revision of the underlying BINEX streamer
- Announcement of the serialized RINEX Header to follow, by means of a BINEX Monument GEO comment
- Any Comments found in your RINEX is serialized by means of a BINEX Monument GEO comment
- Any geodetic information, including Approximate coordinates of your geodetic marker, is encoded by means of Moument Geo frames
- The end of the serialized header section is announced by a new Monument GEO comment announcing the start of the file body
- The stream to follow is RINEX type dependent
RUST_LOG rinex2bin amel0010.21g
[2025-02-22T13:21:01Z DEBUG rinex2bin] Streaming started!
[2025-02-22T13:44:53Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: MonumentGeo(MonumentGeoRecord { epoch: 2020-12-31T23:45:00 UTC, meta: RNX2BIN, comments: ["rtk-rs/rinex2bin v0.0.1 from V2 Glonass NAVIGATION DATA", "Stream starting!"], frames: [GeoStringFrame { fid: SoftwareName, string: "geo-rust v0.17.0-beta" }] }) }
[2025-02-22T13:21:01Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: MonumentGeo(MonumentGeoRecord { epoch: 2020-12-31T23:45:00 UTC, meta: RNX2BIN, comments: [], frames: [GeoStringFrame { fid: SoftwareName, string: "geo-rust v0.17.0-beta" }] }) }
[2025-02-22T13:21:01Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: MonumentGeo(MonumentGeoRecord { epoch: 2020-12-31T23:45:00 UTC, meta: RNX2BIN, comments: ["RINEX Header comments following!"], frames: [GeoStringFrame { fid: SoftwareName, string: "geo-rust v0.17.0-beta" }] }) }
[2025-02-22T13:21:01Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: MonumentGeo(MonumentGeoRecord { epoch: 2020-12-31T23:45:00 UTC, meta: RNX2BIN, comments: ["Linux 2.4.21-27.ELsmp|Opteron|gcc|Linux 64|=+", "GN-RINEX 1.3 Geo++ GmbH 31-DEC-20 23:59", "gfzrnx-1.13-7761 FILE MERGE 20210101 010301 UTC"], frames: [GeoStringFrame { fid: SoftwareName, string: "geo-rust v0.17.0-beta" }] }) }
[2025-02-22T13:21:01Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: MonumentGeo(MonumentGeoRecord { epoch: 2020-12-31T23:45:00 UTC, meta: RNX2BIN, comments: ["RINEX Record starting!"], frames: [GeoStringFrame { fid: SoftwareName, string: "geo-rust v0.17.0-beta" }] }) }
[2025-02-22T13:21:01Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: EphemerisFrame(GLO(GLOEphemeris { slot: 0, day: 0, tod_s: 0, clock_offset_s: -4.20100986958e-5, clock_rel_freq_bias: 0.0, t_k_sec: 0, x_km: 18170.6850586, vel_x_km: 0.818475723267, acc_x_km: 2.79396772385e-9, y_km: 18170.6850586, vel_y_km: 0.75625038147, acc_y_km: 9.31322574615e-10, z_km: 18170.6850586, vel_z_km: -3.34566307068, acc_z_km: -2.79396772385e-9, sv_health: 0, freq_channel: 0, age_op_days: 0, leap_s: 0, tau_gps_s: 0.0, l1_l2_gd: 0.0 })) }
[2025-02-22T13:21:01Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: EphemerisFrame(GLO(GLOEphemeris { slot: 0, day: 0, tod_s: 0, clock_offset_s: 0.000461053103209, clock_rel_freq_bias: 1.81898940355e-12, t_k_sec: 0, x_km: -8955.04199219, vel_x_km: 1.43687725067, acc_x_km: -4.65661287308e-9, y_km: -8955.04199219, vel_y_km: 1.5303068161, acc_y_km: -9.31322574615e-10, z_km: -8955.04199219, vel_z_km: 2.66476726532, acc_z_km: 9.31322574615e-10, sv_health: 0, freq_channel: 0, age_op_days: 0, leap_s: 0, tau_gps_s: 0.0, l1_l2_gd: 0.0 })) }
[2025-02-22T13:21:01Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: EphemerisFrame(GLO(GLOEphemeris { slot: 0, day: 0, tod_s: 0, clock_offset_s: 2.83820554614e-5, clock_rel_freq_bias: 0.0, t_k_sec: 0, x_km: 15025.2294922, vel_x_km: 1.75297737122, acc_x_km: 9.31322574615e-10, y_km: 15025.2294922, vel_y_km: -0.947224617004, acc_y_km: -9.31322574615e-10, z_km: 15025.2294922, vel_z_km: -2.76998615265, acc_z_km: -2.79396772385e-9, sv_health: 0, freq_channel: 0, age_op_days: 0, leap_s: 0, tau_gps_s: 0.0, l1_l2_gd: 0.0 })) }
[...]
The input RINEX can be Gzip compressed, but its name needs to be terminated by .gz
RUST_LOG=trace rinex2bin GEOP092I.24o.gz
[2025-02-22T13:54:02Z DEBUG rinex2bin] Streaming started!
[2025-02-22T13:54:02Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: MonumentGeo(MonumentGeoRecord { epoch: 2024-04-01T08:30:58.442760200 UTC, meta: RNX2BIN, comments: ["rtk-rs/rinex2bin v0.0.1 from V3 MIXED OBS DATA", "Stream starting!"], frames: [GeoStringFrame { fid: SoftwareName, string: "geo-rust v0.17.0-beta" }] }) }
[2025-02-22T13:54:02Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: MonumentGeo(MonumentGeoRecord { epoch: 2024-04-01T08:30:58.442760200 UTC, meta: RNX2BIN, comments: [], frames: [GeoStringFrame { fid: SoftwareName, string: "geo-rust v0.17.0-beta" }, GeoStringFrame { fid: AgencyName, string: "Geo++" }, GeoStringFrame { fid: ObserverName, string: "Geo++" }, GeoStringFrame { fid: ReceiverType, string: "Xiaomi" }, GeoStringFrame { fid: ReceiverNumber, string: "unknown" }, GeoStringFrame { fid: ReceiverFirmwareVersion, string: "M2007J17G" }] }) }
[2025-02-22T13:54:02Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: MonumentGeo(MonumentGeoRecord { epoch: 2024-04-01T08:30:58.442760200 UTC, meta: RNX2BIN, comments: ["RINEX Header comments following!"], frames: [GeoStringFrame { fid: SoftwareName, string: "geo-rust v0.17.0-beta" }] }) }
[2025-02-22T13:54:02Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: MonumentGeo(MonumentGeoRecord { epoch: 2024-04-01T08:30:58.442760200 UTC, meta: RNX2BIN, comments: ["************************************************************", "This file was generated by the Geo++ RINEX Logger App", "for Android devices (Version 2.1.6). If you encounter", "any issues, please send an email to [email protected]", "Filtering Mode: BEST", "************************************************************"], frames: [GeoStringFrame { fid: SoftwareName, string: "geo-rust v0.17.0-beta" }] }) }
[2025-02-22T13:54:02Z DEBUG rinex2bin] Streaming: Message { meta: Meta { reversed: false, enhanced_crc: false, big_endian: true }, record: MonumentGeo(MonumentGeoRecord { epoch: 2024-04-01T08:30:58.442760200 UTC, meta: RNX2BIN, comments: ["RINEX Record starting!"], frames: [GeoStringFrame { fid: SoftwareName, string: "geo-rust v0.17.0-beta" }] }) }
When serializing RINEX3 in default mode, the output BIN file is automatically guessed from content to be streamed.
By default, RINEX3 prefers long and precise filenames:
RUST_LOG=trace rinex2bin ESBC00DNK_R_20201770000_01D_MN.rnx.gz
ESBC00DNK_R_20201771950_01D_MN.rnx.bin as been collected
If you prefer to generate a shorter (V2) file name, simply use -s
:
RUST_LOG=trace rinex2bin -s GEOP092I.24o.gz
[...]
[...]
ESBC1770.20N.bin has been collected
By default, the BIN file name is auto-guessed from the actual RINEX content.
You may specify a custom name with -o
instead:
RUST_LOG=trace rinex2bin GEOP092I.24o.gz -o GEOP092I.24o.bin
[...]
[...]
GEOP092I.24o.bin has been generated
The output filename is absolute:
RUST_LOG=trace rinex2bin GEOP092I.24o.gz -o /tmp/GEOP092I.24o.bin
[...]
[...]
/tmp/GEOP092I.24o.bin has been generated
In both cases, the tool allows gzip compression of the BINEX stream, for ultimate storage efficiency.
When working with the auto-guesser (default option) specify you want to Gzip compress
the auto-named BIN file with --gzip
:
RUST_LOG=trace rinex2bin GEOP092I.24o.gz --gzip
[...]
[...]
GEOP092I.24o.bin.gz has been compressed
If your output file name terminates with .gz
:
RUST_LOG=trace rinex2bin GEOP092I.24o.gz -o /tmp/GEOP092I.24o.bin.gz
[...]
[...]
/tmp/GEOP092I.24o.bin.gz has been compressed
When streaming to an I/O, you need to add the --gzip
flag to the streaming mode:
RUST_LOG=trace rinex2bin GEOP092I.24o.gz -s /dev/ttyUSB0 --gzip
[...]
This application is part of the RTK-rs framework which is delivered under the Mozilla V2 Public license.