Read and write NodeNetCDF files
npm install nodenetcdfA Node.js native addon for reading and writing NodeNetCDF files, providing a comprehensive interface to the NetCDF-4 C library.
IMPORTANT NOTE: this project does not follow conventional open source standards we will accept PR's but we will not be actively changeing code unless something breaks
This package provides Node.js bindings to the NetCDF-4 library, allowing you to read and write NodeNetCDF files directly from JavaScript. NetCDF (Network Common Data Form) is a set of software libraries and machine-independent data formats that support the creation, access, and sharing of array-oriented scientific data.
- Read and write NetCDF-4 files
- Full support for groups, variables, dimensions, and attributes
- Support for all NetCDF-4 data types
- Chunk mode and compression options
- Fill values and endianness control
- Strided slice operations for efficient data access
- Cross-platform support (Windows, Linux, macOS)
- Node.js >= 22.0.0
- C++ compiler with C++20 support
- CMake (for building dependencies)
``bash`
npm install nodenetcdf
The installation process will:
1. Set up vcpkg package manager
2. Verify build dependencies
3. Build the native addon using node-gyp
4. Copy required shared libraries
Windows:
- Requires Visual Studio 2022 (v143 toolset)
- Build uses vcpkg to manage NetCDF and HDF5 dependencies
Linux:
- Requires gcc with C++20 support
- Dependencies are statically linked via vcpkg
macOS:
- Requires Xcode command line tools
- Minimum deployment target: macOS 10.15
`javascript
const nodenetcdf = require('nodenetcdf');
// Open an existing file for reading
const file = new nodenetcdf.File('path/to/file.nc', 'r');
// Create a new file
const newFile = new nodenetcdf.File('path/to/new-file.nc', 'w', 'nodenetcdf');
// Available modes:
// 'r' - read-only
// 'w' - write (create new file)
// 'c' - create (fail if exists)
// 'a' - append (read/write existing file)
// Available formats:
// 'nodenetcdf' - NetCDF-4 format
// 'classic' - NetCDF classic format
// '64bit' - 64-bit offset format
`
`javascript
// Access the root group
const root = file.root;
// Get group properties
console.log(root.name); // Group name
console.log(root.fullname); // Full path
console.log(root.id); // NetCDF ID
// Create a subgroup
const dataGroup = root.addSubgroup('data');
// Access subgroups
const subgroups = root.subgroups;
console.log(subgroups); // Object with subgroup names as keys
`
`javascript
// Add dimensions
const timeDim = root.addDimension('time', 0); // Unlimited dimension
const latDim = root.addDimension('lat', 180); // Fixed dimension
const lonDim = root.addDimension('lon', 360);
// Access dimension properties
console.log(timeDim.name); // 'time'
console.log(timeDim.length); // Current length
console.log(timeDim.id); // NetCDF ID
// Get all dimensions
const dimensions = root.dimensions;
const unlimitedDims = root.unlimited; // Array of unlimited dimensions
`
`javascript
// Create a variable
const tempVar = root.addVariable('temperature', 'float', ['time', 'lat', 'lon']);
// Supported data types:
// 'byte', 'char', 'short', 'int', 'float', 'double',
// 'ubyte', 'ushort', 'uint', 'int64', 'uint64'
// Write data
tempVar.write([1.5, 2.3, 3.7, ...]);
// Write a slice
tempVar.writeSlice([0, 0, 0], [1, 180, 360], data);
// Write with stride
tempVar.writeStridedSlice([0, 0, 0], [1, 1, 1], [10, 180, 360], data);
// Read data
const data = tempVar.read();
// Read a slice
const slice = tempVar.readSlice([0, 0, 0], [1, 180, 360]);
// Read with stride
const stridedData = tempVar.readStridedSlice([0, 0, 0], [2, 2, 2], [10, 180, 360]);
// Variable properties
console.log(tempVar.name); // Variable name
console.log(tempVar.type); // Data type
console.log(tempVar.dimensions); // Array of dimension names
console.log(tempVar.id); // NetCDF ID
`
`javascript
// Set endianness
tempVar.endianness = 'little'; // or 'big', 'native'
// Set checksum mode
tempVar.checksummode = 'fletcher32'; // or 'none'
// Set chunking
tempVar.chunkmode = 'chunked'; // or 'contiguous'
tempVar.chunksizes = [1, 180, 360];
// Set fill mode and value
tempVar.fillmode = true;
tempVar.fillvalue = -999.9;
// Set compression
tempVar.compression_shuffle = true;
tempVar.compression_deflate = true;
tempVar.compression_level = 6; // 0-9
`
`javascript
// Add attributes to variables
tempVar.addAttribute('units', 'Kelvin');
tempVar.addAttribute('long_name', 'Air Temperature');
tempVar.addAttribute('valid_range', [200.0, 350.0]);
// Add global attributes (to groups)
root.addAttribute('title', 'Climate Data');
root.addAttribute('institution', 'Research Center');
root.addAttribute('created', new Date().toISOString());
// Read attributes
const attrs = tempVar.attributes;
console.log(attrs.units.value); // 'Kelvin'
// Modify attribute value
attrs.units.value = 'Celsius';
// Delete an attribute
attrs.units.delete();
`
`javascript
// Sync changes to disk
file.sync();
// Close the file
file.close();
`
- new File(path, mode, format) - Open or create a NetCDF filefile.root
- - Access the root groupfile.close()
- - Close the filefile.sync()
- - Sync changes to disk
Properties:
- group.id - NetCDF group IDgroup.name
- - Group namegroup.fullname
- - Full path of the groupgroup.dimensions
- - Object containing dimensionsgroup.unlimited
- - Array of unlimited dimensionsgroup.variables
- - Object containing variablesgroup.attributes
- - Object containing attributesgroup.subgroups
- - Object containing subgroups
Methods:
- group.addDimension(name, length) - Add a dimensiongroup.addVariable(name, type, dimensions)
- - Add a variablegroup.addAttribute(name, value)
- - Add an attributegroup.addSubgroup(name)
- - Add a subgroup
Properties:
- dimension.id - NetCDF dimension IDdimension.name
- - Dimension namedimension.length
- - Current length of the dimension
Properties:
- variable.id - NetCDF variable IDvariable.name
- - Variable namevariable.type
- - Data typevariable.dimensions
- - Array of dimension namesvariable.attributes
- - Object containing attributesvariable.endianness
- - Byte order ('little', 'big', 'native')variable.checksummode
- - Checksum mode ('none', 'fletcher32')variable.chunkmode
- - Chunking mode ('contiguous', 'chunked')variable.chunksizes
- - Array of chunk sizesvariable.fillmode
- - Whether fill values are enabledvariable.fillvalue
- - Fill valuevariable.compression_shuffle
- - Shuffle filter enabledvariable.compression_deflate
- - Deflate compression enabledvariable.compression_level
- - Compression level (0-9)
Methods:
- variable.read() - Read all datavariable.readSlice(start, count)
- - Read a slicevariable.readStridedSlice(start, stride, count)
- - Read with stridevariable.write(data)
- - Write datavariable.writeSlice(start, count, data)
- - Write a slicevariable.writeStridedSlice(start, stride, count, data)
- - Write with stridevariable.addAttribute(name, value)
- - Add an attribute
Properties:
- attribute.name - Attribute nameattribute.value
- - Attribute value
Methods:
- attribute.delete() - Delete the attribute
`bash`
npm test
`bash`
npm install
The build process uses:
- node-gyp for compiling the native addonvcpkg` for managing C++ dependencies (NetCDF, HDF5, zlib, curl)
-
This is a fork and modernization of the original netcdf4 project.
- Andrea Parodi
- Sven Willner
- Luke Shore
ISC License
Copyright (c) 2015, Sven Willner
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
MIT License
Copyright (c) Luke Shore
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.