-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathdecode_layer.rs
54 lines (44 loc) · 1.85 KB
/
decode_layer.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
use std::{env, error::Error, fs::File, io::BufReader, path::Path};
fn main() -> Result<(), Box<dyn Error>> {
// This example shows how to decode values inside a layer in a GRIB2 message.
// The example also shows how to obtain the latitude-longitude locations of grid
// points, which are usually used in conjunction with the grid point values.
// Take the first argument as an input file path and the second argument as a
// layer index.
let mut args = env::args().skip(1);
if let (Some(file_path), Some(index), Some(subindex)) = (args.next(), args.next(), args.next())
{
let index: (usize, usize) = (index.parse()?, subindex.parse()?);
decode_layer(file_path, index)
} else {
panic!("Usage: decode_layer <path> <index>");
}
}
fn decode_layer<P>(path: P, message_index: (usize, usize)) -> Result<(), Box<dyn Error>>
where
P: AsRef<Path>,
{
// Open the input file in a normal way.
let f = File::open(path)?;
let f = BufReader::new(f);
// Read with the reader.
let grib2 = grib::from_reader(f)?;
// Find the target submessage.
let (_index, submessage) = grib2
.iter()
.find(|(index, _)| *index == message_index)
.ok_or("no such index")?;
// Obtain latitude-longitude locations as an iterator.
let latlons = submessage.latlons()?;
// Prepare a decoder.
let decoder = grib::Grib2SubmessageDecoder::from(submessage)?;
// Actually dispatch a decoding process and get an iterator of decoded values.
// There are various methods available for compressing GRIB2 data, but some are
// not yet supported by this library and may return errors.
let values = decoder.dispatch()?;
// Iterate over decoded values along with locations.
for ((lat, lon), value) in latlons.zip(values) {
println!("{lat} {lon} {value}");
}
Ok(())
}