Compare commits
4 Commits
515a00119d
...
60ea19f2c4
Author | SHA1 | Date |
---|---|---|
|
60ea19f2c4 | |
|
c79c471415 | |
|
e0d64e4cbe | |
|
9e1d873ca5 |
|
@ -1 +1,4 @@
|
|||
/target
|
||||
|
||||
input
|
||||
rv.png
|
||||
|
|
|
@ -0,0 +1,428 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.23.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder-lite"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951"
|
||||
dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cmake"
|
||||
version = "0.1.54"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fdeflate"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c"
|
||||
dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"libredox",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.25.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db35664ce6b9810857a38a906215e75a9c879f0696556a39f59c62829710251a"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder-lite",
|
||||
"num-traits",
|
||||
"png",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libsqlite3-sys"
|
||||
version = "0.32.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fbb8270bb4060bd76c6e96f20c52d80620f1d82a3470885694e41e0f81ef6fe7"
|
||||
dependencies = [
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "link-cplusplus"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a6f6da007f968f9def0d65a05b187e2960183de70c160204ecfccf0ee330212"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "82151a2fc869e011c153adc57cf2789ccb8d9906ce52c0b39a6b5697749d7526"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"crc32fast",
|
||||
"fdeflate",
|
||||
"flate2",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.95"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proj"
|
||||
version = "0.30.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58e0c01de214d7ea50ee6519969be9efdc6f0dc5ce6c64fbd4f054ea26d43ca4"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"num-traits",
|
||||
"proj-sys",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proj-sys"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a208129995443a4c475464c33308274be1578993b0ad266c9139188ed0dc7e91"
|
||||
dependencies = [
|
||||
"cmake",
|
||||
"flate2",
|
||||
"libsqlite3-sys",
|
||||
"link-cplusplus",
|
||||
"pkg-config",
|
||||
"tar",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
|
||||
dependencies = [
|
||||
"bitflags 2.9.1",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "simd-adler32"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.101"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tar"
|
||||
version = "0.4.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a"
|
||||
dependencies = [
|
||||
"filetime",
|
||||
"libc",
|
||||
"xattr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "wetter"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"image",
|
||||
"proj",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "xattr"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rustix",
|
||||
]
|
|
@ -4,3 +4,5 @@ version = "0.1.0"
|
|||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
image = { version = "0.25.6", default-features = false, features = ["png"] }
|
||||
proj = { version = "0.30.0", default-features = false }
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
mod parser;
|
||||
mod rv;
|
||||
|
||||
pub use rv::Rv;
|
|
@ -0,0 +1,92 @@
|
|||
use std::io::{Error as IoError, Read, Seek};
|
||||
use std::num::ParseIntError;
|
||||
use std::slice;
|
||||
use std::str::{self, FromStr, Utf8Error};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub enum ParseError {
|
||||
IoError(IoError),
|
||||
ParseIntError(ParseIntError),
|
||||
Unexpected(String, &'static str),
|
||||
Utf8Error(Utf8Error),
|
||||
}
|
||||
|
||||
pub struct Parser<R: Read + Seek> {
|
||||
r: R,
|
||||
}
|
||||
|
||||
impl<R: Read + Seek> Parser<R> {
|
||||
pub fn new(r: R) -> Self {
|
||||
Self { r }
|
||||
}
|
||||
|
||||
pub fn take(&mut self, length: usize) -> Result<String, ParseError> {
|
||||
let mut buf = vec![0; length];
|
||||
|
||||
self.r
|
||||
.read_exact(&mut buf)
|
||||
.map_err(|err| ParseError::IoError(err))?;
|
||||
|
||||
Ok(String::from_utf8(buf).map_err(|err| ParseError::Utf8Error(err.utf8_error()))?)
|
||||
}
|
||||
|
||||
pub fn peek(&mut self, pos: i64, length: usize) -> Result<String, ParseError> {
|
||||
if pos != 0 {
|
||||
self.r
|
||||
.seek_relative(pos)
|
||||
.map_err(|err| ParseError::IoError(err))?;
|
||||
}
|
||||
|
||||
let string = self.take(length)?;
|
||||
|
||||
self.r
|
||||
.seek_relative(-(length as i64) - pos)
|
||||
.map_err(|err| ParseError::IoError(err))?;
|
||||
|
||||
Ok(string)
|
||||
}
|
||||
|
||||
pub fn expect(&mut self, expected: &'static str) -> Result<(), ParseError> {
|
||||
let actual = self.take(expected.len())?;
|
||||
|
||||
if actual == expected {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(ParseError::Unexpected(actual, expected))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_int<I, const N: usize>(&mut self) -> Result<I, ParseError>
|
||||
where
|
||||
I: FromStr<Err = ParseIntError>,
|
||||
{
|
||||
let mut buf = [0u8; N];
|
||||
|
||||
self.r
|
||||
.read_exact(&mut buf)
|
||||
.map_err(|err| ParseError::IoError(err))?;
|
||||
|
||||
I::from_str(
|
||||
str::from_utf8(&buf)
|
||||
.map_err(|err| ParseError::Utf8Error(err))?
|
||||
.trim_ascii_start(),
|
||||
)
|
||||
.map_err(|err| ParseError::ParseIntError(err))
|
||||
}
|
||||
|
||||
pub fn consume<T, const N: usize>(mut self) -> Result<Vec<T>, ParseError>
|
||||
where
|
||||
T: Clone + Default,
|
||||
{
|
||||
let mut data = vec![T::default(); N];
|
||||
|
||||
let buf =
|
||||
unsafe { slice::from_raw_parts_mut(data.as_mut_ptr() as *mut _, N * size_of::<T>()) };
|
||||
self.r
|
||||
.read_exact(buf)
|
||||
.map_err(|err| ParseError::IoError(err))?;
|
||||
|
||||
Ok(data)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,132 @@
|
|||
#[cfg(not(target_endian = "little"))]
|
||||
compile_error!("Only little-endian architectures are supported.");
|
||||
|
||||
use crate::data::parser::{ParseError, Parser};
|
||||
|
||||
use std::io::{Read, Seek};
|
||||
|
||||
const DATA_LEN: usize = 1100 * 1200;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct VersionMismatch {
|
||||
pub actual: u8,
|
||||
pub expected: u8,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct Datetime {
|
||||
pub year: u16,
|
||||
pub month: u8,
|
||||
pub day: u8,
|
||||
pub hour: u8,
|
||||
pub minute: u8,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Rv {
|
||||
timestamp: Datetime,
|
||||
version: u8,
|
||||
precision: i8,
|
||||
forecast: u16,
|
||||
data: Vec<u16>,
|
||||
}
|
||||
|
||||
impl Rv {
|
||||
pub fn parse<R: Read + Seek>(r: R) -> Result<Self, ParseError> {
|
||||
let mut parser = Parser::new(r);
|
||||
|
||||
parser.expect("RV")?;
|
||||
|
||||
let day = parser.parse_int::<_, 2>()?;
|
||||
let hour = parser.parse_int::<_, 2>()?;
|
||||
let minute = parser.parse_int::<_, 2>()?;
|
||||
|
||||
let _wmo = parser.parse_int::<u32, 5>()?;
|
||||
|
||||
let month = parser.parse_int::<_, 2>()?;
|
||||
let year = 2000 + parser.parse_int::<u16, 2>()?;
|
||||
|
||||
parser.expect("BY")?;
|
||||
|
||||
let _len = if parser.peek(7, 2)? == "VS" {
|
||||
parser.parse_int::<usize, 7>()?
|
||||
} else {
|
||||
parser.parse_int::<usize, 10>()?
|
||||
};
|
||||
|
||||
parser.expect("VS")?;
|
||||
|
||||
let version = parser.parse_int::<_, 2>()?;
|
||||
|
||||
parser.expect("SW ")?;
|
||||
|
||||
let _sw_version = parser.take(8)?;
|
||||
|
||||
parser.expect("PR E")?;
|
||||
|
||||
let precision = parser.parse_int::<_, 3>()?;
|
||||
|
||||
parser.expect("INT")?;
|
||||
|
||||
let _interval = parser.parse_int::<u16, 4>()?;
|
||||
|
||||
parser.expect("GP")?;
|
||||
|
||||
let _resolution = parser.take(9)?;
|
||||
|
||||
parser.expect("VV ")?;
|
||||
|
||||
let forecast = parser.parse_int::<_, 3>()?;
|
||||
|
||||
parser.expect("MF ")?;
|
||||
|
||||
let _flags = parser.parse_int::<u32, 8>()?;
|
||||
|
||||
parser.expect("MS")?;
|
||||
|
||||
let text_len = parser.parse_int::<_, 3>()?;
|
||||
|
||||
let _text = parser.take(text_len)?;
|
||||
|
||||
parser.expect("\x03")?;
|
||||
|
||||
let data = parser.consume::<_, DATA_LEN>()?;
|
||||
|
||||
Ok(Self {
|
||||
timestamp: Datetime {
|
||||
year,
|
||||
month,
|
||||
day,
|
||||
hour,
|
||||
minute,
|
||||
},
|
||||
version,
|
||||
precision,
|
||||
forecast,
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn expect_version(&self, version: u8) -> Result<(), VersionMismatch> {
|
||||
if self.version == version {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(VersionMismatch {
|
||||
actual: self.version,
|
||||
expected: version,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scale(&self) -> f64 {
|
||||
10_f64.powi(self.precision as i32)
|
||||
}
|
||||
|
||||
pub fn instant(&self) -> (Datetime, u16) {
|
||||
(self.timestamp, self.forecast)
|
||||
}
|
||||
|
||||
pub fn data(&self) -> &[u16] {
|
||||
&self.data[..]
|
||||
}
|
||||
}
|
64
src/main.rs
64
src/main.rs
|
@ -1,3 +1,63 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
mod data;
|
||||
|
||||
use data::Rv;
|
||||
|
||||
use image::imageops;
|
||||
use image::RgbaImage;
|
||||
|
||||
use proj::Proj;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io::BufReader;
|
||||
|
||||
const PROJ_WGS84_DE1200: &'static str = "+proj=stere +lat_0=90 +lat_ts=60 +lon_0=10 +a=6378137 +b=6356752.3142451802 +no_defs +x_0=543196.83521776402 +y_0=3622588.8619310018";
|
||||
|
||||
#[repr(u32)]
|
||||
enum Intensity {
|
||||
None = 0xffffff00,
|
||||
Light = 0x80d0d080,
|
||||
Moderate = 0x50a0e080,
|
||||
Heavy = 0x1030f080,
|
||||
Unknown = 0xd0d0d080,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let rv = Rv::parse(BufReader::new(File::open("input").unwrap())).unwrap();
|
||||
rv.expect_version(5).unwrap();
|
||||
|
||||
let mut data = Vec::with_capacity(1100 * 1200 * 4);
|
||||
|
||||
for v in rv.data() {
|
||||
let intensity = if *v == 0x29c4 {
|
||||
Intensity::Unknown
|
||||
} else {
|
||||
let mm_per_h = *v as f64 * rv.scale() * 12.0; // 12 * 5 min intervals per hour
|
||||
if mm_per_h < 0.1 {
|
||||
Intensity::None
|
||||
} else if mm_per_h < 5.0 {
|
||||
Intensity::Light
|
||||
} else if mm_per_h < 15.0 {
|
||||
Intensity::Moderate
|
||||
} else {
|
||||
Intensity::Heavy
|
||||
}
|
||||
};
|
||||
|
||||
data.extend_from_slice(&(intensity as u32).to_be_bytes());
|
||||
}
|
||||
|
||||
let mut img = RgbaImage::from_raw(1100, 1200, data).unwrap();
|
||||
imageops::flip_vertical_in_place(&mut img);
|
||||
img.save("rv.png").unwrap();
|
||||
|
||||
let wgs84_to_de1200 = Proj::new(PROJ_WGS84_DE1200).unwrap();
|
||||
println!(
|
||||
"{:#?}",
|
||||
wgs84_to_de1200
|
||||
.project(
|
||||
(1.463301510_f64.to_radians(), 55.86208711_f64.to_radians()),
|
||||
false
|
||||
)
|
||||
.unwrap()
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue