Expand description
OxiGDAL NetCDF Driver - Pure Rust NetCDF-3 with Optional NetCDF-4 Support
This crate provides NetCDF file format support for OxiGDAL, following the COOLJAPAN Pure Rust policy.
§Pure Rust Policy Compliance
IMPORTANT: This driver provides the structure and API for Pure Rust NetCDF support, but the actual netcdf3 integration is currently incomplete due to breaking API changes in netcdf3 v0.6.0. The driver demonstrates:
- Complete Pure Rust data structures for NetCDF metadata (dimensions, variables, attributes)
- CF conventions support
- Feature-gated architecture for Pure Rust vs. C-binding implementations
Status: The reader/writer implementations need to be updated to use the new
Dataset/FileReader/FileWriter API from netcdf3 v0.6.0 (breaking change from v0.1.0).
For NetCDF-4 (HDF5-based) support, you can enable the netcdf4 feature,
which requires system libraries (libnetcdf, libhdf5) and is NOT Pure Rust.
§Feature Flags
netcdf3(default): Pure Rust NetCDF-3 support via netcdf3 cratenetcdf4: NetCDF-4/HDF5 support via C bindings (requires system libraries)cf_conventions: CF (Climate and Forecast) conventions supportasync: Async I/O supportcompression: Compression support (NetCDF-4 only)
§NetCDF Format Support
§NetCDF-3 (Pure Rust, Default)
Fully supported data types:
i8,i16,i32- Signed integersf32,f64- Floating point numberschar- Character data
Features:
- Fixed and unlimited dimensions
- Multi-dimensional arrays
- Variable and global attributes
- Coordinate variables
§NetCDF-4 (C Bindings, Feature-Gated)
Additional data types (requires netcdf4 feature):
u8,u16,u32,u64- Unsigned integersi64,u64- 64-bit integersstring- Variable-length strings
Additional features (requires netcdf4 feature):
- HDF5-based compression
- Groups and nested groups
- User-defined types
- Multiple unlimited dimensions
§Example - Reading NetCDF-3 File (Pure Rust)
use oxigdal_netcdf::NetCdfReader;
// Open a NetCDF-3 file
let reader = NetCdfReader::open("data.nc")?;
// Get metadata
println!("{}", reader.metadata().summary());
// List dimensions
for dim in reader.dimensions().iter() {
println!("Dimension: {} (size: {})", dim.name(), dim.len());
}
// List variables
for var in reader.variables().iter() {
println!("Variable: {} (type: {})", var.name(), var.data_type().name());
}
// Read variable data
let temperature = reader.read_f32("temperature")?;
println!("Temperature data: {:?}", temperature);§Example - Writing NetCDF-3 File (Pure Rust)
use oxigdal_netcdf::{NetCdfWriter, NetCdfVersion};
use oxigdal_netcdf::dimension::Dimension;
use oxigdal_netcdf::variable::{Variable, DataType};
use oxigdal_netcdf::attribute::{Attribute, AttributeValue};
// Create a new NetCDF-3 file
let mut writer = NetCdfWriter::create("output.nc", NetCdfVersion::Classic)?;
// Add dimensions
writer.add_dimension(Dimension::new_unlimited("time", 0)?)?;
writer.add_dimension(Dimension::new("lat", 180)?)?;
writer.add_dimension(Dimension::new("lon", 360)?)?;
// Add coordinate variables
writer.add_variable(Variable::new_coordinate("time", DataType::F64)?)?;
writer.add_variable(Variable::new_coordinate("lat", DataType::F32)?)?;
writer.add_variable(Variable::new_coordinate("lon", DataType::F32)?)?;
// Add data variable
let temp_var = Variable::new(
"temperature",
DataType::F32,
vec!["time".to_string(), "lat".to_string(), "lon".to_string()],
)?;
writer.add_variable(temp_var)?;
// Add variable attributes
writer.add_variable_attribute(
"temperature",
Attribute::new("units", AttributeValue::text("celsius"))?,
)?;
writer.add_variable_attribute(
"temperature",
Attribute::new("long_name", AttributeValue::text("Air Temperature"))?,
)?;
// Add global attributes
writer.add_global_attribute(
Attribute::new("Conventions", AttributeValue::text("CF-1.8"))?,
)?;
writer.add_global_attribute(
Attribute::new("title", AttributeValue::text("Temperature Data"))?,
)?;
// End define mode
writer.end_define_mode()?;
// Write data
let time_data = vec![0.0, 1.0, 2.0];
writer.write_f64("time", &time_data)?;
let lat_data: Vec<f32> = (0..180).map(|i| -90.0 + i as f32).collect();
writer.write_f32("lat", &lat_data)?;
let lon_data: Vec<f32> = (0..360).map(|i| -180.0 + i as f32).collect();
writer.write_f32("lon", &lon_data)?;
// Write temperature data
let temp_data = vec![20.0f32; 3 * 180 * 360];
writer.write_f32("temperature", &temp_data)?;
// Close file
writer.close()?;§CF Conventions Support
The driver recognizes and parses CF (Climate and Forecast) conventions metadata:
use oxigdal_netcdf::NetCdfReader;
let reader = NetCdfReader::open("cf_data.nc")?;
if let Some(cf) = reader.cf_metadata() {
if cf.is_cf_compliant() {
println!("CF Conventions: {}", cf.conventions.as_deref().unwrap_or(""));
println!("Title: {}", cf.title.as_deref().unwrap_or(""));
println!("Institution: {}", cf.institution.as_deref().unwrap_or(""));
}
}§Pure Rust Limitations
When using the default Pure Rust mode (NetCDF-3 only):
- No NetCDF-4/HDF5 format support
- No compression support
- No groups or user-defined types
- Only one unlimited dimension allowed
- Limited to NetCDF-3 data types
To use NetCDF-4 features, enable the netcdf4 feature (requires C dependencies):
[dependencies]
oxigdal-netcdf = { version = "0.1", features = ["netcdf4"] }Note: Enabling netcdf4 violates the COOLJAPAN Pure Rust policy and requires
system libraries (libnetcdf ≥ 4.0, libhdf5 ≥ 1.8).
§Performance Considerations
- Pure Rust NetCDF-3 reader/writer has comparable performance to C libraries
- For large datasets, consider using chunked reading/writing
- Unlimited dimensions may have performance implications
- CF metadata parsing is done on-demand
§References
Re-exports§
pub use attribute::Attribute;pub use attribute::AttributeValue;pub use attribute::Attributes;pub use dimension::Dimension;pub use dimension::DimensionSize;pub use dimension::Dimensions;pub use error::NetCdfError;pub use error::Result;pub use metadata::CfMetadata;pub use metadata::NetCdfMetadata;pub use metadata::NetCdfVersion;pub use netcdf4::ChunkInfo;pub use netcdf4::CompressionFilter;pub use netcdf4::Hdf5ByteOrder;pub use netcdf4::Hdf5DatatypeClass;pub use netcdf4::Hdf5MessageType;pub use netcdf4::Hdf5Superblock;pub use netcdf4::Hdf5SuperblockVersion;pub use netcdf4::Nc4Group;pub use netcdf4::Nc4Reader;pub use netcdf4::Nc4VariableInfo;pub use netcdf4::Nc4Writer;pub use reader::NetCdfReader;pub use variable::DataType;pub use variable::Variable;pub use variable::Variables;pub use writer::NetCdfWriter;
Modules§
- attribute
- NetCDF attribute types and utilities.
- dimension
- NetCDF dimension types and utilities.
- error
- Error types for NetCDF operations.
- metadata
- NetCDF file metadata structures.
- netcdf4
- Auto-generated module structure
- reader
- NetCDF file reader implementation.
- variable
- NetCDF variable types and utilities.
- writer
- NetCDF file writer implementation.
Constants§
Functions§
- has_
netcdf3 - Check if NetCDF-3 support is available.
- has_
netcdf4 - Check if NetCDF-4 support is available.
- info
- Get driver information.
- is_
pure_ rust - Pure Rust compliance status
- supported_
versions - Get supported format versions.