Press n or j to go to the next uncovered block, b, p or k for the previous block.
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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | 18x 18x 18x 18x 18x 18x | 'use strict'; const { IOBuffer } = require('iobuffer'); const utils = require('./utils'); const data = require('./data'); const readHeader = require('./header'); const toString = require('./toString'); /** * Reads a NetCDF v3.x file * https://www.unidata.ucar.edu/software/netcdf/docs/file_format_specifications.html * @param {ArrayBuffer} data - ArrayBuffer or any Typed Array (including Node.js' Buffer from v4) with the data * @constructor */ class NetCDFReader { constructor(data) { const buffer = new IOBuffer(data); buffer.setBigEndian(); // Validate that it's a NetCDF file utils.notNetcdf(buffer.readChars(3) !== 'CDF', 'should start with CDF'); // Check the NetCDF format const version = buffer.readByte(); utils.notNetcdf(version > 2, 'unknown version'); // Read the header this.header = readHeader(buffer, version); this.buffer = buffer; } /** * @return {string} - Version for the NetCDF format */ get version() { if (this.header.version === 1) { return 'classic format'; } else { return '64-bit offset format'; } } /** * @return {object} - Metadata for the record dimension * * `length`: Number of elements in the record dimension * * `id`: Id number in the list of dimensions for the record dimension * * `name`: String with the name of the record dimension * * `recordStep`: Number with the record variables step size */ get recordDimension() { return this.header.recordDimension; } /** * @return {Array<object>} - List of dimensions with: * * `name`: String with the name of the dimension * * `size`: Number with the size of the dimension */ get dimensions() { return this.header.dimensions; } /** * @return {Array<object>} - List of global attributes with: * * `name`: String with the name of the attribute * * `type`: String with the type of the attribute * * `value`: A number or string with the value of the attribute */ get globalAttributes() { return this.header.globalAttributes; } /** * Returns the value of an attribute * @param {string} attributeName * @return {string} Value of the attributeName or null */ getAttribute(attributeName) { const attribute = this.globalAttributes.find( (val) => val.name === attributeName ); I if (attribute) return attribute.value; return null; } /** * Returns the value of a variable as a string * @param {string} variableName * @return {string} Value of the variable as a string or null */ getDataVariableAsString(variableName) { const variable = this.getDataVariable(variableName); I if (variable) return variable.join(''); return null; } /** * @return {Array<object>} - List of variables with: * * `name`: String with the name of the variable * * `dimensions`: Array with the dimension IDs of the variable * * `attributes`: Array with the attributes of the variable * * `type`: String with the type of the variable * * `size`: Number with the size of the variable * * `offset`: Number with the offset where of the variable begins * * `record`: True if is a record variable, false otherwise */ get variables() { return this.header.variables; } toString() { return toString.call(this); } /** * Retrieves the data for a given variable * @param {string|object} variableName - Name of the variable to search or variable object * @return {Array} - List with the variable values */ getDataVariable(variableName) { let variable; if (typeof variableName === 'string') { // search the variable variable = this.header.variables.find(function (val) { return val.name === variableName; }); } else { variable = variableName; } // throws if variable not found utils.notNetcdf( variable === undefined, `variable not found: ${variableName}` ); // go to the offset position this.buffer.seek(variable.offset); if (variable.record) { // record variable case return data.record(this.buffer, variable, this.header.recordDimension); } else { // non-record variable case return data.nonRecord(this.buffer, variable); } } /** * Check if a dataVariable exists * @param {string} variableName - Name of the variable to find * @return {boolean} */ dataVariableExists(variableName) { const variable = this.header.variables.find(function (val) { return val.name === variableName; }); return variable !== undefined; } /** * Check if an attribute exists * @param {string} attributeName - Name of the attribute to find * @return {boolean} */ attributeExists(attributeName) { const attribute = this.globalAttributes.find( (val) => val.name === attributeName ); return attribute !== undefined; } } module.exports = NetCDFReader; |