From edec2031421cc6e4490accf89629bc8c7cbb8d8b Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Sun, 27 Jun 2021 14:48:15 -0700 Subject: [PATCH 01/22] initial ts declaration file with build step --- package.json | 5 +++-- src/georaster.d.ts | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 src/georaster.d.ts diff --git a/package.json b/package.json index c1bbc34..0c4ce84 100644 --- a/package.json +++ b/package.json @@ -16,10 +16,11 @@ "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", "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", diff --git a/src/georaster.d.ts b/src/georaster.d.ts new file mode 100644 index 0000000..e96df06 --- /dev/null +++ b/src/georaster.d.ts @@ -0,0 +1,40 @@ +export interface Georaster { + /** raster values. first dimension is raster band, remainder is 2D array of cell values */ + values: number[][][]; + /** 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: unknown; + /** left boundary, in units of projection*/ + xmin: number; + /** right boundary, in units of projection */ + xmax: number; + /** top boundary (image y-axis is inverse of cartesian), in units of projection */ + ymin: number; + /** bottom boundary (image y-axis is inverse of cartesian), 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[] +} + +/** Subset of Georaster properties */ +export type GeorasterMetadata = Pick + +export function parseGeoraster(data: object | string | Buffer | ArrayBuffer | number[][][], + metadata: GeorasterMetadata, + debug: boolean +): Promise From f13c83d6ab34b4a8c34b0b30fd42cb35f8510613 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Sun, 27 Jun 2021 14:59:06 -0700 Subject: [PATCH 02/22] add types to package.json --- package.json | 1 + src/georaster.d.ts | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0c4ce84..9deae18 100644 --- a/package.json +++ b/package.json @@ -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/*", diff --git a/src/georaster.d.ts b/src/georaster.d.ts index e96df06..2aa4be9 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -31,7 +31,6 @@ export interface Georaster { ranges: number[] } -/** Subset of Georaster properties */ export type GeorasterMetadata = Pick export function parseGeoraster(data: object | string | Buffer | ArrayBuffer | number[][][], From 6b8a86ea9cc6c3ca4091695d356f88b9db524df3 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Sun, 27 Jun 2021 15:10:35 -0700 Subject: [PATCH 03/22] add module declaration --- src/georaster.d.ts | 77 ++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 37 deletions(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 2aa4be9..0d7b815 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -1,39 +1,42 @@ -export interface Georaster { - /** raster values. first dimension is raster band, remainder is 2D array of cell values */ - values: number[][][]; - /** 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: unknown; - /** left boundary, in units of projection*/ - xmin: number; - /** right boundary, in units of projection */ - xmax: number; - /** top boundary (image y-axis is inverse of cartesian), in units of projection */ - ymin: number; - /** bottom boundary (image y-axis is inverse of cartesian), 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[] -} +declare module georaster { -export type GeorasterMetadata = Pick + export interface Georaster { + /** raster values. first dimension is raster band, remainder is 2D array of cell values */ + values: number[][][]; + /** 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: unknown; + /** left boundary, in units of projection*/ + xmin: number; + /** right boundary, in units of projection */ + xmax: number; + /** top boundary (image y-axis is inverse of cartesian), in units of projection */ + ymin: number; + /** bottom boundary (image y-axis is inverse of cartesian), 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[] + } -export function parseGeoraster(data: object | string | Buffer | ArrayBuffer | number[][][], - metadata: GeorasterMetadata, - debug: boolean -): Promise + export type GeorasterMetadata = Pick + + export function parseGeoraster(data: object | string | Buffer | ArrayBuffer | number[][][], + metadata: GeorasterMetadata, + debug: boolean + ): Promise +} \ No newline at end of file From cc934a63cd7f85e3d49d088af556c7b1cfb3f9cb Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Sun, 27 Jun 2021 15:55:56 -0700 Subject: [PATCH 04/22] add comments, drop declaration --- src/georaster.d.ts | 83 ++++++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 40 deletions(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 0d7b815..6466f51 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -1,42 +1,45 @@ -declare module georaster { +export interface Georaster { + /** raster values. first dimension is raster band, remainder is 2D array of cell values */ + values: number[][][]; + /** 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: unknown; + /** left boundary, in units of projection*/ + xmin: number; + /** right boundary, in units of projection */ + xmax: number; + /** top boundary (image y-axis is inverse of cartesian), in units of projection */ + ymin: number; + /** bottom boundary (image y-axis is inverse of cartesian), 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[] +} - export interface Georaster { - /** raster values. first dimension is raster band, remainder is 2D array of cell values */ - values: number[][][]; - /** 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: unknown; - /** left boundary, in units of projection*/ - xmin: number; - /** right boundary, in units of projection */ - xmax: number; - /** top boundary (image y-axis is inverse of cartesian), in units of projection */ - ymin: number; - /** bottom boundary (image y-axis is inverse of cartesian), 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[] - } +export type GeorasterMetadata = Pick - export type GeorasterMetadata = Pick - - export function parseGeoraster(data: object | string | Buffer | ArrayBuffer | number[][][], - metadata: GeorasterMetadata, - debug: boolean - ): Promise -} \ No newline at end of file +/** + * Creates a Georaster by parsing in-memory data arrays and accompanying metadata. The first data dimension is raster band. + * The second and third dimension are the 2D grid of cell values. + */ +export function parseGeoraster(data: object | string | Buffer | ArrayBuffer | number[][][], + /** the raster metadata */ + metadata: GeorasterMetadata, + /** whether or not to print debug statements */ + debug: boolean +): Promise \ No newline at end of file From de2c00b4ad206c28ac1483f8a06f88f521a23da3 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Sun, 27 Jun 2021 16:20:26 -0700 Subject: [PATCH 05/22] newline --- src/georaster.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 6466f51..d962bc1 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -42,4 +42,4 @@ export function parseGeoraster(data: object | string | Buffer | ArrayBuffer | nu metadata: GeorasterMetadata, /** whether or not to print debug statements */ debug: boolean -): Promise \ No newline at end of file +): Promise From 10a3048973aa5e3e9dd6eca5af64f7a1a091d269 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Sun, 27 Jun 2021 16:40:55 -0700 Subject: [PATCH 06/22] restructure with default export and namespace for additional type exports --- src/georaster.d.ts | 97 ++++++++++++++++++++++++++-------------------- 1 file changed, 54 insertions(+), 43 deletions(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index d962bc1..4927c59 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -1,45 +1,56 @@ -export interface Georaster { - /** raster values. first dimension is raster band, remainder is 2D array of cell values */ - values: number[][][]; - /** 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: unknown; - /** left boundary, in units of projection*/ - xmin: number; - /** right boundary, in units of projection */ - xmax: number; - /** top boundary (image y-axis is inverse of cartesian), in units of projection */ - ymin: number; - /** bottom boundary (image y-axis is inverse of cartesian), 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[] -} +// Matches index.js default export of this method +declare function parseGeoraster( + data: object | string | Buffer | ArrayBuffer | number[][][], + /** the raster metadata */ + metadata: georaster.GeorasterMetadata, + /** whether or not to print debug statements */ + debug?: boolean +): Promise; + +export = parseGeoraster; -export type GeorasterMetadata = Pick +// A namespace is needed to define additional type exports in addition to the default above +declare namespace georaster { + export interface Georaster { + /** raster values. first dimension is raster band, remainder is 2D array of cell values */ + values: number[][][]; + /** 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: unknown; + /** left boundary, in units of projection*/ + xmin: number; + /** right boundary, in units of projection */ + xmax: number; + /** top boundary (image y-axis is inverse of cartesian), in units of projection */ + ymin: number; + /** bottom boundary (image y-axis is inverse of cartesian), 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[]; + } -/** - * Creates a Georaster by parsing in-memory data arrays and accompanying metadata. The first data dimension is raster band. - * The second and third dimension are the 2D grid of cell values. - */ -export function parseGeoraster(data: object | string | Buffer | ArrayBuffer | number[][][], - /** the raster metadata */ - metadata: GeorasterMetadata, - /** whether or not to print debug statements */ - debug: boolean -): Promise + export type GeorasterMetadata = Pick< + Georaster, + | "noDataValue" + | "projection" + | "xmin" + | "ymax" + | "pixelWidth" + | "pixelHeight" + >; +} From e73e9e50bf704a572903a3bea848922c56ec5c1e Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Sun, 27 Jun 2021 17:16:40 -0700 Subject: [PATCH 07/22] solve default export + additional --- src/georaster.d.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 4927c59..70c2e0d 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -1,16 +1,17 @@ -// Matches index.js default export of this method +// Matches default CJS export in index.js declare function parseGeoraster( data: object | string | Buffer | ArrayBuffer | number[][][], /** the raster metadata */ - metadata: georaster.GeorasterMetadata, + metadata: parseGeoraster.GeorasterMetadata, /** whether or not to print debug statements */ debug?: boolean -): Promise; +): Promise; export = parseGeoraster; -// A namespace is needed to define additional type exports in addition to the default above -declare namespace georaster { +// 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 { export interface Georaster { /** raster values. first dimension is raster band, remainder is 2D array of cell values */ values: number[][][]; From bc7ab31c0c3fb4e94d7c96b275eff248f6a97a26 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Sun, 27 Jun 2021 17:21:50 -0700 Subject: [PATCH 08/22] nit --- src/georaster.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 70c2e0d..71edc37 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -1,4 +1,3 @@ -// Matches default CJS export in index.js declare function parseGeoraster( data: object | string | Buffer | ArrayBuffer | number[][][], /** the raster metadata */ @@ -7,6 +6,7 @@ declare function parseGeoraster( debug?: boolean ): Promise; +// 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 From 2dc58c488e6c166d6a166ef67307f73be453d4ac Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Mon, 28 Jun 2021 11:57:02 -0700 Subject: [PATCH 09/22] projection is always a number --- src/georaster.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 71edc37..0e24b42 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -24,7 +24,7 @@ declare namespace parseGeoraster { /** raster width in pixels */ pixelWidth: number; /** Projection identifier */ - projection: unknown; + projection: number; /** left boundary, in units of projection*/ xmin: number; /** right boundary, in units of projection */ From 7290f62725f583be282109a403afd6475935eee3 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Thu, 1 Jul 2021 14:40:59 -0700 Subject: [PATCH 10/22] Fix y ordering. Add getValues and toCanvas --- src/georaster.d.ts | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 0e24b42..4353eee 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -12,6 +12,16 @@ 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 { + export interface ValuesOptions { + left: number + top: number + right: number + bottom: number + width: number + height: number + resampleMethod: 'nearest' | 'bilinear' + } + export interface Georaster { /** raster values. first dimension is raster band, remainder is 2D array of cell values */ values: number[][][]; @@ -29,9 +39,9 @@ declare namespace parseGeoraster { xmin: number; /** right boundary, in units of projection */ xmax: number; - /** top boundary (image y-axis is inverse of cartesian), in units of projection */ + /** bottom boundary, in units of projection */ ymin: number; - /** bottom boundary (image y-axis is inverse of cartesian), in units of projection */ + /** top boundary, in units of projection */ ymax: number; /** cell value representing "no data" in raster */ noDataValue: number; @@ -43,6 +53,10 @@ declare namespace parseGeoraster { 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 without reading entire raster into memory. Useful for COGs */ + getValues: (options: ValuesOptions) => number[][][]; + /** experimental! returns a canvas picture of the data. */ + toCanvas: (options: { height?: number; width?: number }) => ImageData } export type GeorasterMetadata = Pick< From 855dc13065bf0d5f6272e5c798df14479fcb14ae Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Thu, 1 Jul 2021 14:43:03 -0700 Subject: [PATCH 11/22] make getValues optionally available --- src/georaster.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 4353eee..40c25f1 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -54,7 +54,7 @@ declare namespace parseGeoraster { /** 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 without reading entire raster into memory. Useful for COGs */ - getValues: (options: ValuesOptions) => number[][][]; + getValues?: (options: ValuesOptions) => number[][][]; /** experimental! returns a canvas picture of the data. */ toCanvas: (options: { height?: number; width?: number }) => ImageData } From d87ce6d7487014b4bd7c99cec7fdf0d8165c83bb Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Tue, 13 Jul 2021 07:59:21 -0700 Subject: [PATCH 12/22] corrections --- src/georaster.d.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 40c25f1..ad9fefb 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -1,7 +1,7 @@ declare function parseGeoraster( data: object | string | Buffer | ArrayBuffer | number[][][], /** the raster metadata */ - metadata: parseGeoraster.GeorasterMetadata, + metadata?: parseGeoraster.GeorasterMetadata, /** whether or not to print debug statements */ debug?: boolean ): Promise; @@ -19,7 +19,7 @@ declare namespace parseGeoraster { bottom: number width: number height: number - resampleMethod: 'nearest' | 'bilinear' + resampleMethod?: 'nearest' | 'bilinear' } export interface Georaster { @@ -54,7 +54,7 @@ declare namespace parseGeoraster { /** 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 without reading entire raster into memory. Useful for COGs */ - getValues?: (options: ValuesOptions) => number[][][]; + getValues?: (options: ValuesOptions) => Promise; /** experimental! returns a canvas picture of the data. */ toCanvas: (options: { height?: number; width?: number }) => ImageData } From f29b0eb7a624144e3b89669ae7699f7e25ce9179 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Tue, 13 Jul 2021 08:33:01 -0700 Subject: [PATCH 13/22] loosen resampleMethod type to reduce friction with use --- src/georaster.d.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index ad9fefb..786a95d 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -13,13 +13,19 @@ export = parseGeoraster; // https://stackoverflow.com/a/51238234/4159809 declare namespace parseGeoraster { export interface ValuesOptions { + /** pixels from the left of the image to skip before start clipping */ left: number + /** how many pixels from the top of the image to skip before start clipping */ top: number + /** how many pixels from the right of the image to skip before start clipping */ right: number + /** how many pixels from the bottom of the image to skip before start clipping */ bottom: number + /** width in pixels to make the resulting image */ width: number + /** height in pixels to make the resulting image */ height: number - resampleMethod?: 'nearest' | 'bilinear' + resampleMethod?: string } export interface Georaster { From 5dbd050db5a36a661c61a17bda6a57f23a61683f Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Tue, 13 Jul 2021 15:45:35 -0700 Subject: [PATCH 14/22] improve jsdoc --- src/georaster.d.ts | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 786a95d..18f4ae8 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -12,19 +12,21 @@ 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 { - export interface ValuesOptions { - /** pixels from the left of the image to skip before start clipping */ + /** 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 - /** how many pixels from the top of the image to skip before start clipping */ + /** top of the image window in pixel coordinates */ top: number - /** how many pixels from the right of the image to skip before start clipping */ + /** right of the image window in pixel coordinates. Should be greater than left */ right: number - /** how many pixels from the bottom of the image to skip before start clipping */ + /** bottom of the image window in pixel coordinates. Should be greater than top */ bottom: number - /** width in pixels to make the resulting image */ + /** 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 image */ + /** 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 } @@ -59,8 +61,12 @@ declare namespace parseGeoraster { 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 without reading entire raster into memory. Useful for COGs */ - getValues?: (options: ValuesOptions) => Promise; + /** 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; /** experimental! returns a canvas picture of the data. */ toCanvas: (options: { height?: number; width?: number }) => ImageData } From 873b67fe1feb47ab44115beecd17a71a5477bb94 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Mon, 19 Jul 2021 13:07:27 -0700 Subject: [PATCH 15/22] Switch from number to TypedArray --- src/georaster.d.ts | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/src/georaster.d.ts b/src/georaster.d.ts index 18f4ae8..c767dac 100644 --- a/src/georaster.d.ts +++ b/src/georaster.d.ts @@ -1,6 +1,19 @@ +/** 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( - data: object | string | Buffer | ArrayBuffer | number[][][], - /** the raster metadata */ + /** 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 @@ -31,8 +44,8 @@ declare namespace parseGeoraster { } export interface Georaster { - /** raster values. first dimension is raster band, remainder is 2D array of cell values */ - values: number[][][]; + /** 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 */ @@ -66,7 +79,7 @@ declare namespace parseGeoraster { * 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; + getValues?: (options: WindowOptions) => Promise; /** experimental! returns a canvas picture of the data. */ toCanvas: (options: { height?: number; width?: number }) => ImageData } From c87f633210f572c3fc26bcb1dd897d69d42db00c Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Mon, 19 Jul 2021 14:42:08 -0700 Subject: [PATCH 16/22] add TS type testing --- package.json | 2 ++ test/test.ts | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 test/test.ts diff --git a/package.json b/package.json index 9deae18..1b9861c 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "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 && npm run build:types", "build:prod": "npm run build:prod:node && npm run build:prod:web", @@ -69,6 +70,7 @@ "mocha": "^6.2.0", "null-loader": "^4.0.1", "threads-plugin": "^1.3.1", + "typescript": "^4.3.5", "webpack": "^4.12.0", "webpack-bundle-analyzer": "^3.6.0", "webpack-cli": "^3.0.8" diff --git a/test/test.ts b/test/test.ts new file mode 100644 index 0000000..d2df61e --- /dev/null +++ b/test/test.ts @@ -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); + } +}); \ No newline at end of file From f39e59904d7213492679981efdf4f7e7b756629d Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Tue, 20 Jul 2021 08:35:07 -0700 Subject: [PATCH 17/22] change declaration file name to fix test import --- package.json | 4 ++-- src/{georaster.d.ts => index.d.ts} | 0 test/test.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/{georaster.d.ts => index.d.ts} (100%) diff --git a/package.json b/package.json index 1b9861c..283a4b2 100644 --- a/package.json +++ b/package.json @@ -5,7 +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", + "types": "dist/index.d.ts", "scripts": { "analyze": "ANALYZE_GEORASTER_BUNDLE=true npm run build", "clean": "rm -f ./dist/*", @@ -22,7 +22,7 @@ "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:types": "cp src/georaster.d.ts dist/georaster.d.ts" + "build:types": "cp src/index.d.ts dist/index.d.ts" }, "repository": { "type": "git", diff --git a/src/georaster.d.ts b/src/index.d.ts similarity index 100% rename from src/georaster.d.ts rename to src/index.d.ts diff --git a/test/test.ts b/test/test.ts index d2df61e..612da28 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1,7 +1,7 @@ // 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 parseGeoraster from "../src"; // Import from outside to utilize dist and types pointer in package.json import { countIn2D } from "../src/utils"; // Floating point number values From c2607962bb6705f6d1fa2de0bca85fbf22fc3b53 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Tue, 20 Jul 2021 08:37:08 -0700 Subject: [PATCH 18/22] clean up comments --- test/test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test.ts b/test/test.ts index 612da28..2c0718b 100644 --- a/test/test.ts +++ b/test/test.ts @@ -1,7 +1,7 @@ -// Tests use of Typescript types, requires build to already be done into dist +// Tests use of Typescript types import { assert } from "console"; -import parseGeoraster from "../src"; // Import from outside to utilize dist and types pointer in package.json +import parseGeoraster from "../src"; import { countIn2D } from "../src/utils"; // Floating point number values From 27f0d7923861bf53506f0f8b37b3325109ebc69f Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Tue, 20 Jul 2021 08:48:54 -0700 Subject: [PATCH 19/22] change built type dec file to match library name, index is used internally --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 283a4b2..2574ef1 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "main": "dist/georaster.bundle.min.js", "browser": "./dist/georaster.browser.bundle.min.js", "unpkg": "./dist/georaster.browser.bundle.min.js", - "types": "dist/index.d.ts", + "types": "dist/georaster.d.ts", "scripts": { "analyze": "ANALYZE_GEORASTER_BUNDLE=true npm run build", "clean": "rm -f ./dist/*", @@ -22,7 +22,7 @@ "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:types": "cp src/index.d.ts dist/index.d.ts" + "build:types": "cp src/index.d.ts dist/georaster.d.ts" }, "repository": { "type": "git", From e97757d8dab1a90778c2689173cc85b7580e2585 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Tue, 20 Jul 2021 13:26:53 -0700 Subject: [PATCH 20/22] switch back to top-level import, use esm default export style --- src/index.d.ts | 2 +- test/{test.ts => types.ts} | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) rename test/{test.ts => types.ts} (78%) diff --git a/src/index.d.ts b/src/index.d.ts index c767dac..6699f75 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -20,7 +20,7 @@ declare function parseGeoraster( ): Promise; // Match default CJS export in index.js -export = parseGeoraster; +export default parseGeoraster; // A namespace with the same name as the default export is needed to define additional type exports // https://stackoverflow.com/a/51238234/4159809 diff --git a/test/test.ts b/test/types.ts similarity index 78% rename from test/test.ts rename to test/types.ts index 2c0718b..5592d5b 100644 --- a/test/test.ts +++ b/test/types.ts @@ -1,7 +1,12 @@ -// Tests use of Typescript types +/* + * Tests Typescript declaration file. Compile and run this with the 'test-types' command + * Imports georaster from top-level package, just as downstream Typescript consumer of this library would. + * This way the 'main' JS build distribution and 'types' property in package.json are imported and not the underlying source. + * Assumes top-level folder containing repo is named 'georaster' and build script has been run + */ import { assert } from "console"; -import parseGeoraster from "../src"; +import parseGeoraster from "../../georaster"; import { countIn2D } from "../src/utils"; // Floating point number values @@ -66,6 +71,7 @@ parseGeoraster(raster_url).then(georaster => { width: 10, height: 10 }; + if (!georaster.getValues) throw new Error('georaster configured without URL') georaster.getValues(options).then(values => { const numBands = values.length; const numRows = values[0].length; From 5c85e686f82a8be0e18e7967f149f51b87b317ef Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Tue, 20 Jul 2021 13:29:59 -0700 Subject: [PATCH 21/22] switch ts test to internal import --- test/types.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/test/types.ts b/test/types.ts index 5592d5b..f799c79 100644 --- a/test/types.ts +++ b/test/types.ts @@ -1,12 +1,8 @@ -/* - * Tests Typescript declaration file. Compile and run this with the 'test-types' command - * Imports georaster from top-level package, just as downstream Typescript consumer of this library would. - * This way the 'main' JS build distribution and 'types' property in package.json are imported and not the underlying source. - * Assumes top-level folder containing repo is named 'georaster' and build script has been run - */ +// Internal test of Typescript types. Imports from src not dist. +// downstream TS users of geotiff should simply import the geotiff library and will get types along with the dist build import { assert } from "console"; -import parseGeoraster from "../../georaster"; +import parseGeoraster from "../src"; import { countIn2D } from "../src/utils"; // Floating point number values From 64d7c64c138026685dc53951ea5753a4388a0d78 Mon Sep 17 00:00:00 2001 From: Tim Welch Date: Wed, 21 Jul 2021 08:11:57 -0700 Subject: [PATCH 22/22] no npx --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 2574ef1..3d6c4dd 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "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", + "test-types": "tsc test/types.ts --noEmit", "dev": "webpack --mode development --target node && webpack --mode development --target web", "build": "npm run build:prod && npm run build:types", "build:prod": "npm run build:prod:node && npm run build:prod:web", @@ -46,7 +46,7 @@ "dependencies": { "cross-fetch": "^3.0.4", "georaster-to-canvas": "0.2.0", - "geotiff": "1.0.0-beta.13", + "geotiff": "file://../geotiff", "geotiff-palette": "0.0.0", "threads": "^1.4.0", "tiny-worker": "^2.3.0",