ascii-grid
Advanced tools
Comparing version 0.1.2 to 0.2.0
{ | ||
"name": "ascii-grid", | ||
"version": "0.1.2", | ||
"version": "0.2.0", | ||
"description": "Identify and Read an ARC/INFO ASCII Grid", | ||
"main": "src", | ||
"scripts": { | ||
"format": "npx prettier --write test.js src/*.js", | ||
"test": "npx ava" | ||
"format": "prettier --arrow-parens=avoid --trailing-comma=none --write test.js src/*.js", | ||
"test": "ava --timeout=2m --verbose" | ||
}, | ||
@@ -32,4 +32,12 @@ "repository": { | ||
"devDependencies": { | ||
"toab": "^1.0.1" | ||
"ava": "^3.14.0", | ||
"fast-max": "0.0.0", | ||
"fast-min": "0.0.0", | ||
"prettier": "^2.2.1", | ||
"toab": "^1.0.2" | ||
}, | ||
"dependencies": { | ||
"get-byte": "0.0.0", | ||
"to-typed-array": "0.0.1" | ||
} | ||
} |
@@ -1,4 +0,2 @@ | ||
:warning: Work in Progress. This library is under active development and is not ready for production yet. | ||
# ascii-grid | ||
# ascii-grid: beta | ||
Identify and Read an ARC/INFO ASCII Grid | ||
@@ -8,2 +6,3 @@ | ||
## identify ascii grid files | ||
isAsciiGrid identifies ASCII GRID files in the following formats: ArrayBuffer, Buffer, DataView, Promise, String, and Uint8Array | ||
```javascript | ||
@@ -30,3 +29,5 @@ const isAsciiGrid = require("ascii-grid/is-ascii-grid"); | ||
cellsize: 0.0008333333333, | ||
nodata_value: -9999 | ||
nodata_value: -9999, | ||
last_metadata_line: 5, | ||
last_metadata_byte: 95 | ||
} | ||
@@ -37,2 +38,7 @@ */ | ||
## Reading Pixel Values | ||
Coming Soon! | ||
```javascript | ||
const parseAsciiGridData = require("ascii-grid/parse-ascii-grid-data"); | ||
const result = await parseAsciiGridData({ data: buffer, debug: true }); | ||
// result is a two-dimensional array of rows with pixel values | ||
``` |
@@ -1,9 +0,10 @@ | ||
module.exports = (input, options = {}) => { | ||
const debug = options.debug || false; | ||
const max_read_length = options.max_read_length || 500; | ||
const getByte = require("get-byte"); | ||
if (typeof Buffer !== "undefined" && Buffer.isBuffer(input)) { | ||
if (input.toString) { | ||
input = input.toString("utf8", 0, max_read_length); | ||
if (debug) console.log("converted input to a string"); | ||
module.exports = async ({ data, debug = false, max_read_length = 500 }) => { | ||
if (data instanceof Promise) data = await data; | ||
if (typeof Buffer !== "undefined" && Buffer.isBuffer(data)) { | ||
if (data.toString) { | ||
data = data.toString("utf8", 0, max_read_length); | ||
if (debug) console.log("converted data to a string"); | ||
} else { | ||
@@ -14,28 +15,28 @@ return false; | ||
if (debug) console.log("input is:", input); | ||
if (debug) console.log("[ascii-grid/is-ascii-grid] data is:", data); | ||
if (input instanceof ArrayBuffer) input = new DataView(input); | ||
if (data instanceof ArrayBuffer) data = new DataView(data); | ||
if (input instanceof DataView) { | ||
if (data instanceof DataView) { | ||
let decoded = ""; | ||
const length = Math.min(max_read_length, input.byteLength); | ||
const length = Math.min(max_read_length, data.byteLength); | ||
for (let i = 0; i < length; i++) { | ||
decoded += String.fromCharCode(input.getUint8(i)); | ||
decoded += String.fromCharCode(data.getUint8(i)); | ||
} | ||
input = decoded; | ||
data = decoded; | ||
} | ||
if (input instanceof Uint8Array) { | ||
if (data instanceof Uint8Array) { | ||
let decoded = ""; | ||
for (let i = 0; i < Math.min(max_read_length, input.length); i++) { | ||
decoded += String.fromCharCode(input[i]); | ||
for (let i = 0; i < Math.min(max_read_length, data.length); i++) { | ||
decoded += String.fromCharCode(data[i]); | ||
} | ||
input = decoded; | ||
data = decoded; | ||
} | ||
if (typeof input === "string") { | ||
if (debug) console.log("input is a string"); | ||
if (typeof data === "string") { | ||
if (debug) console.log("data is a string"); | ||
return ( | ||
Boolean(input.match(/.asc(.gz|.tar|.tar.gz|.tgz|.zip)?$/i)) || | ||
(input.includes("ncols") && input.includes("nrows")) | ||
Boolean(data.match(/.asc(.gz|.tar|.tar.gz|.tgz|.zip)?$/i)) || | ||
(data.includes("ncols") && data.includes("nrows")) | ||
); | ||
@@ -42,0 +43,0 @@ } else { |
@@ -1,43 +0,40 @@ | ||
const NEWLINE_CHARCODE = "\n".charCodeAt(0); | ||
const getByte = require("get-byte"); | ||
module.exports = (input, options = {}) => { | ||
const debug = options.debug || false; | ||
const max_read_length = options.max_read_length || 500; | ||
module.exports = async ({ data, debug = false, max_read_length = 500 }) => { | ||
const result = {}; | ||
if (typeof Buffer !== "undefined" && Buffer.isBuffer(input)) { | ||
let i = 0; | ||
// parse metadata | ||
let line = null; | ||
let i = 0; | ||
const read_length = Math.min(input.length, max_read_length); | ||
for (i = 0; i < read_length; i++) { | ||
const char = String.fromCharCode(input[i]); | ||
if (char === "\n") { | ||
const [param, value] = line.split(" "); | ||
result[param] = Number.parseFloat(value); | ||
line = null; | ||
} else if (line === null) { | ||
if ( | ||
["-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(char) | ||
) { | ||
break; | ||
} else { | ||
line = char; | ||
} | ||
let line_count = 0; | ||
// parse metadata | ||
let line = null; | ||
const read_length = Math.min(data.length, max_read_length); | ||
for (i = 0; i < read_length; i++) { | ||
const byte = getByte(data, i); | ||
const char = String.fromCharCode(byte); | ||
if (char === "\n") { | ||
const [param, value] = line.split(" "); | ||
result[param] = Number.parseFloat(value); | ||
line = null; | ||
line_count++; | ||
} else if (line === null) { | ||
if ( | ||
["-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(char) | ||
) { | ||
break; | ||
} else { | ||
line += char; | ||
line = char; | ||
} | ||
} else { | ||
line += char; | ||
} | ||
} | ||
if (input instanceof ArrayBuffer) input = new DataView(input); | ||
// add line that marks where metadata ends | ||
result.last_metadata_line = line_count - 1; | ||
result.last_metadata_byte = i - 1; | ||
if (input instanceof DataView) { | ||
const decoded = ""; | ||
input = decoded; | ||
} | ||
if (debug) console.log("result:", result); | ||
return result; | ||
}; |
42
test.js
const { readFileSync } = require("fs"); | ||
const test = require("ava"); | ||
const toab = require("toab"); | ||
const fastMin = require("fast-min"); | ||
const fastMax = require("fast-max"); | ||
const isAsciiGrid = require("./src/is-ascii-grid"); | ||
const parseAsciiGridMetaData = require("./src/parse-ascii-grid-meta"); | ||
const parseAsciiGridData = require("./src/parse-ascii-grid-data"); | ||
test("identifying ascii grid file extensions", async (t) => { | ||
t.true(isAsciiGrid("michigan_lld.asc")); | ||
t.true(isAsciiGrid("michigan_lld.asc.tar")); | ||
t.true(isAsciiGrid("michigan_lld.asc.tar.gz")); | ||
t.true(isAsciiGrid("michigan_lld.asc.zip")); | ||
t.false(isAsciiGrid("michigan_lld.asc.json")); | ||
test("identifying ascii grid file extensions", async t => { | ||
t.true(await isAsciiGrid({ data: "michigan_lld.asc" })); | ||
t.true(await isAsciiGrid({ data: "michigan_lld.asc.tar" })); | ||
t.true(await isAsciiGrid({ data: "michigan_lld.asc.tar.gz" })); | ||
t.true(await isAsciiGrid({ data: "michigan_lld.asc.zip" })); | ||
t.false(await isAsciiGrid({ data: "michigan_lld.asc.json" })); | ||
}); | ||
test("identifying ascii grid file from buffers", async (t) => { | ||
test("identifying ascii grid file from buffers", async t => { | ||
const buffer = readFileSync("./test_data/michigan_lld/michigan_lld.asc"); | ||
const bufferIsAsciiGrid = isAsciiGrid(buffer, { debug: false }); | ||
const bufferIsAsciiGrid = await isAsciiGrid({ data: buffer, debug: false }); | ||
t.true(bufferIsAsciiGrid); | ||
t.true(isAsciiGrid(Uint8Array.from(buffer))); | ||
t.true(isAsciiGrid(toab(buffer))); | ||
t.true(await isAsciiGrid({ data: Uint8Array.from(buffer) })); | ||
t.true(await isAsciiGrid({ data: await toab(buffer) })); | ||
}); | ||
test("reading ascii metadata", async (t) => { | ||
test("reading ascii metadata", async t => { | ||
const buffer = readFileSync("./test_data/michigan_lld/michigan_lld.asc"); | ||
const meta = parseAsciiGridMetaData(buffer, { debug: false }); | ||
const meta = await parseAsciiGridMetaData({ data: buffer, debug: false }); | ||
@@ -35,2 +38,17 @@ // check metadata | ||
t.is(meta.nodata_value, -9999); | ||
t.is(meta.last_metadata_line, 5); | ||
t.is(meta.last_metadata_byte, 95); | ||
}); | ||
test("reading ascii values", async t => { | ||
const buffer = readFileSync("./test_data/michigan_lld/michigan_lld.asc"); | ||
const result = await parseAsciiGridData({ data: buffer, debug: true }); | ||
const lastRow = result.values[result.values.length - 1]; | ||
t.is(fastMin(lastRow, { debug: false }), -0.102997); | ||
t.is(fastMax(lastRow, { debug: false }), 165.940948); | ||
t.is(result.values.length, 5365); | ||
t.deepEqual(Array.from(new Set(result.values[0])).sort(), [-9999, 9999]); | ||
t.true(result.values.every(ln => ln.length === 4201)); | ||
t.deepEqual(new Set(result.values[result.values.length - 1]).size, 3615); | ||
}); |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
15673
178
41
2
5
1
+ Addedget-byte@0.0.0
+ Addedto-typed-array@0.0.1
+ Added@extra-number/significant-digits@2.0.27(transitive)
+ Addedchoose-typed-array@0.0.1(transitive)
+ Addedget-byte@0.0.0(transitive)
+ Addedto-typed-array@0.0.1(transitive)