Skip to content

mmomtchev/ndarray-gdal

Folders and files

NameName
Last commit message
Last commit date

Latest commit

aeaeacc · Dec 3, 2024

History

78 Commits
Nov 25, 2024
May 30, 2021
May 3, 2024
Jun 15, 2021
May 28, 2021
Jun 15, 2021
May 29, 2021
Nov 30, 2023
May 27, 2021
Sep 25, 2022
Nov 30, 2023
Nov 30, 2023
Dec 3, 2024
May 29, 2021
Sep 25, 2022

Repository files navigation

ndarray-gdal

License npm version Node.js CI codecov

Plugin for gdal-async allowing zero-copy I/O from and to scijs/ndarray and @stdlib/ndarray.

This module requires at least gdal-async@3.3.0.

Installation

For scijs/ndarray:

npm install --save gdal-async ndarray ndarray-gdal

For @stdlib/ndarray:

npm install --save gdal-async @stdlib/ndarray ndarray-gdal

(beware, @stdlib/ndarray causes npm@6 to hang, you need at least npm@7)

Usage

const gdal = require('gdal-async');
const ndarray = require('ndarray');
require('ndarray-gdal');

const ds = gdal.open('test/sample.tif');
const band = ds.bands.get(1);

// Creating a new ndarray
const nd1 = band.pixels.readArray({ width: ds.rasterSize.x, height: ds.rasterSize.y });

// Reading into existing ndarray with a non-default stride
const nd2 = ndarray(new Uint8Array(ds.rasterSize.x * ds.rasterSize.y),
                    [ ds.rasterSize.y, ds.rasterSize.x ], [ ds.rasterSize.x, -1 ]);
// read the whole raster band fitting it in the array, resampling if needed
band.pixels.readArray({ data: nd2 });

// Writing from an ndarray (size can be deduced from the array)
band.pixels.writeArray({ data: nd2 });

I/O from and to all strides is supported without copying/rotation, but positive/positive row-major stride will be the fastest as this is usually the ordering that matches the file format. Interleaving is provided by the GDAL C++ implementation which uses SIMD instructions on CPUs that support it.

⚠️ The default coordinate order in GDAL is (x, y), while ndarray uses (y, x)

Multi-dimensional arrays

When used with GDAL >= 3.1, ndarray-gdal supports the new Multidimensional Raster Data Model.

const gdal_array = gdal.open('gfs.t00z.alnsf.nc', 'mr').root.arrays.get('alnsf');
// Into existing ndarray keeping its stride
const nd1 = ndarray(new Float32Array(array.length), 
                    gdal_array.dimensions.map((dim) => dim.size));
gdal_array.readArray({ data: nd });
// Into a new ndarray
const nd2 = gdal_array.readArray();
// Async
const nd3 = await gdal_array.readArrayAsync();

Multidimensional arrays are currently read-only.

TypeScript

TypeScript is supported via a module augmentation definition file.

npm install --save-dev @types/ndarray @stdlib/types
import * as gdal from 'gdal-async';
import ndarray from 'ndarray';
import 'ndarray-gdal';

const ds: gdal.Dataset = gdal.open('test/sample.tif');
const nd: ndarray.NdArray = ds.bands.get(1).pixels.readArray({
                width: ds.rasterSize.x, 
                height: ds.rasterSize.y });

Asynchronous I/O

Same rules for asynchronous I/O as gdal-async apply, you should refer to its documentation.

const nd = await gdal.openAsync('test/sample.tif')
            .then((ds) => ds.bands.getAsync(1))
            .then((band) => band.pixels.readArrayAsync())
            .catch((e) => console.error(`bad things happened ${e}`));

Copyright

Copyright © 2021 Momtchil Momtchev, @mmomtchev

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.