Skip to content
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "dist/georaster.bundle.min.js",
"browser": "./dist/georaster.browser.bundle.min.js",
"unpkg": "./dist/georaster.browser.bundle.min.js",
"types": "dist/georaster.d.ts",
"scripts": {
"analyze": "ANALYZE_GEORASTER_BUNDLE=true npm run build",
"clean": "rm -f ./dist/*",
Expand All @@ -15,11 +16,13 @@
"test-all": "npm run test-dev && npm run test-prod",
"test-dev": "npm run dev && GEORASTER_TEST_BUNDLE_NAME='georaster.bundle.js' node ./node_modules/.bin/mocha --reporter spec",
"test-prod": "npm run build && GEORASTER_TEST_BUNDLE_NAME='georaster.bundle.min.js' node ./node_modules/.bin/mocha --reporter spec",
"test-types": "npx ts-node --compiler-options '{\"esModuleInterop\":true, \"module\":\"commonjs\"}' test/test.ts",
"dev": "webpack --mode development --target node && webpack --mode development --target web",
"build": "npm run build:prod",
"build": "npm run build:prod && npm run build:types",
"build:prod": "npm run build:prod:node && npm run build:prod:web",
"build:prod:node": "webpack --mode production --target node",
"build:prod:web": "webpack --mode production --target web"
"build:prod:web": "webpack --mode production --target web",
"build:types": "cp src/georaster.d.ts dist/georaster.d.ts"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -67,6 +70,7 @@
"mocha": "^6.2.0",
"null-loader": "^4.0.1",
"threads-plugin": "^1.3.1",
"typescript": "^4.3.5",
Comment thread
DanielJDufour marked this conversation as resolved.
"webpack": "^4.12.0",
"webpack-bundle-analyzer": "^3.6.0",
"webpack-cli": "^3.0.8"
Expand Down
96 changes: 96 additions & 0 deletions src/georaster.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
/** Typed array of data values, the basic building block of a georaster */
type TypedArray =
| number[]
| Uint8Array
| Int8Array
| Uint16Array
| Int16Array
| Uint32Array
| Int32Array
| Float32Array
| Float64Array;

declare function parseGeoraster(
/** raster pixel data, accepts variety of forms */
data: object | string | Buffer | ArrayBuffer | TypedArray[][],
/** raster metadata */
metadata?: parseGeoraster.GeorasterMetadata,
/** whether or not to print debug statements */
debug?: boolean
): Promise<parseGeoraster.Georaster>;

// Match default CJS export in index.js
export = parseGeoraster;

// A namespace with the same name as the default export is needed to define additional type exports
// https://stackoverflow.com/a/51238234/4159809
declare namespace parseGeoraster {
/** defines the new raster image to generate as a window in the source raster image. Resolution (cell size) is determined from this */
export interface WindowOptions {
/** left side of the image window in pixel coordinates */
left: number
/** top of the image window in pixel coordinates */
top: number
/** right of the image window in pixel coordinates. Should be greater than left */
right: number
/** bottom of the image window in pixel coordinates. Should be greater than top */
bottom: number
/** width in pixels to make the resulting raster. Will resample and/or use overview if not same as right - left */
width: number
/** height in pixels to make the resulting raster. Will resample and/or use overview if not same as bottom - top */
height: number
/** method to map src raster values to result raster. Supports 'nearest' neighbor, defaults to 'bilinear' */
resampleMethod?: string
}

export interface Georaster {
/** raster values for one or more bands. Represented as [band, column, row] */
values: TypedArray[][];
/** raster height in units of projection */
height: number;
/** raster width in units of projection */
width: number;
/** raster height in pixels */
pixelHeight: number;
/** raster width in pixels */
pixelWidth: number;
/** Projection identifier */
projection: number;
/** left boundary, in units of projection*/
xmin: number;
/** right boundary, in units of projection */
xmax: number;
/** bottom boundary, in units of projection */
ymin: number;
/** top boundary, in units of projection */
ymax: number;
/** cell value representing "no data" in raster */
noDataValue: number;
/** number of raster bands */
numberOfRasters: number;
/** Minimum cell value for each raster band. Indexed by band number */
mins: number[];
/** Maximum cell value for each raster band. Indexed by band number */
maxs: number[];
/** difference between max and min for each raster band. Indexed by band number */
ranges: number[];
/** if raster initialized with a URL, this method is available to fetch a
* specific subset or 'window' without reading the entire raster into memory.
* If the window options do not align exactly with the source image then a new
* one is generated using the resampleMethod. The best available overview will
* also be used if they are available. */
getValues?: (options: WindowOptions) => Promise<TypedArray[][]>;
/** experimental! returns a canvas picture of the data. */
toCanvas: (options: { height?: number; width?: number }) => ImageData
}

export type GeorasterMetadata = Pick<
Georaster,
| "noDataValue"
| "projection"
| "xmin"
| "ymax"
| "pixelWidth"
| "pixelHeight"
>;
}
81 changes: 81 additions & 0 deletions test/test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Tests use of Typescript types, requires build to already be done into dist

import { assert } from "console";
import parseGeoraster from "../../georaster"; // Import from outside to utilize dist and types pointer in package.json
import { countIn2D } from "../src/utils";

// Floating point number values

const values = [
[
[0, 1, 2],
[0, 0, 0],
[2, 1, 1]
]
];

const noDataValue = 3;
const projection = 4326;
const xmin = 10; // left
const ymax = 13; // top
const pixelWidth = 1;
const pixelHeight = 1;
const metadata = {
noDataValue,
projection,
xmin,
ymax,
pixelWidth,
pixelHeight,
};

parseGeoraster(values, metadata).then(georaster => {
const values = georaster.values
console.log('number raster values', values)
assert(values.length === 1) // single band
assert(values[0].length === 3)
values[0].forEach(row => assert(Array.isArray(row))) // Should be standard javascript Array type
assert(values[0][0][2] === 2)
});

//// Unsigned 8-bit integer values

const unsignedValues = values.map(band =>
band.map(row => new Uint8Array(row))
);

parseGeoraster(unsignedValues, metadata).then(georaster => {
const values = georaster.values
console.log('unsigned 8-bit int raster values', values)
assert(values.length === 1) // single band
assert(values[0].length === 3)
values[0].forEach(row => assert(typeof row === 'object')) // Typed arrays in Javascript are not of Array type
assert(values[0][0][2] === 2) // But they do behave like arrays for read access and return numbers
});

/// COG test

const raster_url = "https://landsat-pds.s3.amazonaws.com/c1/L8/024/030/LC08_L1TP_024030_20180723_20180731_01_T1/LC08_L1TP_024030_20180723_20180731_01_T1_B1.TIF";
parseGeoraster(raster_url).then(georaster => {
try {
const options = {
left: 0,
top: 0,
right: 4000,
bottom: 4000,
width: 10,
height: 10
};
georaster.getValues(options).then(values => {
const numBands = values.length;
const numRows = values[0].length;
const numColumns = values[0][0].length;

// checking histogram for first and only band
const histogram = countIn2D(values[0]);
assert(histogram[0] === 39)
});
} catch (error) {
console.error('error:', error);
}
});