New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ascii-grid

Package Overview
Dependencies
Maintainers
1
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ascii-grid - npm Package Compare versions

Comparing version 0.2.0 to 1.0.1

src/index.js

19

package.json
{
"name": "ascii-grid",
"version": "0.2.0",
"version": "1.0.1",
"description": "Identify and Read an ARC/INFO ASCII Grid",
"main": "src",
"main": "src/index.js",
"files": [
"src/index.js",
"src/is-ascii-grid.js",
"src/parse-ascii-grid-data.js",
"src/parse-ascii-grid-meta.js"
],
"scripts": {
"format": "prettier --arrow-parens=avoid --trailing-comma=none --write test.js src/*.js",
"test": "ava --timeout=2m --verbose"
"format": "prettier --arrow-parens=avoid --print-width=160 --trailing-comma=none --write test.js src/*.js",
"test": "node test.js"
},

@@ -32,5 +38,5 @@ "repository": {

"devDependencies": {
"ava": "^3.14.0",
"fast-max": "0.0.0",
"fast-min": "0.0.0",
"flug": "^1.1.0",
"prettier": "^2.2.1",

@@ -40,5 +46,4 @@ "toab": "^1.0.2"

"dependencies": {
"get-byte": "0.0.0",
"to-typed-array": "0.0.1"
"get-byte": "0.0.0"
}
}
# ascii-grid: beta
Identify and Read an ARC/INFO ASCII Grid
> Identify and Read an ARC/INFO ASCII Grid
# motivation
I do a lot of client-side geoprocessing (see [geoblaze](http://github.com/geotiff/geoblaze)) and wanted to add support for .asc files.
When I encountered large .asc files, I quickly ran out of memory because I was trying to load the whole file into memory.
This package was created to make it easy to read specific areas of an ASCII Grid in a memory-safe way and prevent my laptop from overheating.
# usage

@@ -11,3 +16,3 @@ ## identify ascii grid files

const buffer = readFileSync('./test_data/michigan_lld/michigan_lld.asc');
isAsciiGrid(buffer, { debug: false });
isAsciiGrid({ data: buffer, debug: false });
// true

@@ -21,3 +26,3 @@ ```

const buffer = readFileSync('./test_data/michigan_lld/michigan_lld.asc');
const metadata = parseAsciiGridMeta(buffer, { debug: false });
const metadata = parseAsciiGridMeta({ data: buffer, debug: false });
/*

@@ -42,3 +47,50 @@ {

const result = await parseAsciiGridData({ data: buffer, debug: true });
// result is a two-dimensional array of rows with pixel values
/*
result is an object with a values array that holds
two-dimensional array of rows with pixel values
{
values:
[
[55.874908, 57.874924, 58.874939, ...], // first row
[62.875015, 63.875031, 62.875046, ...],
[62.875122, 64.875137, 63.875168, ...],
.
.
.
[52.875671, 50.875702, 51.875717, ...], // last row
]
}
*/
```
## Reading Pixel Values within Bounding Box
You can specify a bounding box to read from by specifying the zero-based index
values of the first and last row, and first and last column for each row
```javascript
const parseAsciiGridData = require("ascii-grid/parse-ascii-grid-data");
const result = await parseAsciiGridData({
data: buffer,
debug: true,
start_column: 2, // start reading from the third column
end_column: 10, // read through the eleventh column
start_row: 1, // skip the first row
end_row: undefined // read through the end
});
/*
result's values array is the size of the bbox.
each row has a length of end_column - start_column + 1
{
values:
[
[62.875046, ...], // first row starting with index of start_row
[63.875168, ...],
.
.
.
[51.875717, ...], // last row
]
}
*/
```

@@ -38,6 +38,3 @@ const getByte = require("get-byte");

if (debug) console.log("data is a string");
return (
Boolean(data.match(/.asc(.gz|.tar|.tar.gz|.tgz|.zip)?$/i)) ||
(data.includes("ncols") && data.includes("nrows"))
);
return Boolean(data.match(/.asc(.gz|.tar|.tar.gz|.tgz|.zip)?$/i)) || (data.includes("ncols") && data.includes("nrows"));
} else {

@@ -44,0 +41,0 @@ return false;

@@ -9,12 +9,22 @@ const getByte = require("get-byte");

const NINE_CHARCODE = "9".charCodeAt(0);
// const NULL_CHARACTER = "\u0000".charCodeAt(0);
const DOT_CHARCODE = ".".charCodeAt(0);
const NULL_CHARCODE = 0;
module.exports = async ({
/*
Notes: .asc files can end with a newline, null byte, or number
*/
module.exports = ({
assume_clean = true,
debug = false,
debug_level = 0,
data,
max_read_length = Infinity,
start_of_data_byte,
start_column = 0,
end_column, // index of last column (using zero-based index)
start_row = 0,
end_row, // index of last row (using zero-based index)
meta
}) => {
if (debug_level >= 1) console.time("[asci-grid] parse-ascii-grid-data took");
const result = {};

@@ -26,23 +36,60 @@ const table = [];

const read_length = Math.min(data.length, max_read_length);
if (debug) console.log("[ascii-grid/get-values] read_length:", read_length);
if (debug_level >= 1) console.log("[ascii-grid/parse-ascii-grid-data] read_length:", read_length);
let i =
start_of_data_byte ||
(meta && meta.last_metadata_byte + 1) ||
(await parseAsciiGridMetaData({ data })).last_metadata_byte + 1;
if (!meta) meta = parseAsciiGridMetaData({ data });
if (debug_level >= 1) console.log("[ascii-grid/parse-ascii-grid-data] meta:", meta);
if (debug) console.log("[ascii-grid/get-values] i:", i);
if (!end_row) end_row = meta.nrows - 1;
if (debug_level >= 1) console.log("[ascii-grid/parse-ascii-grid-data] end_row:", end_row);
while (i < read_length - 1) {
i++;
const byte = getByte(data, i);
if (!end_column) end_column = meta.ncols - 1;
if (debug_level >= 1) console.log("[ascii-grid/parse-ascii-grid-data] end_column:", end_column);
if (byte === NEWLINE_CHARCODE) {
if (num !== "") row.push(parseFloat(num));
let i = start_of_data_byte !== undefined ? start_of_data_byte : meta.last_metadata_byte + 1;
if (debug_level >= 1) console.log("[ascii-grid/parse-ascii-grid-data] i:", i);
// index of current row
let r = 0;
// index of current column
let c = 0;
// previous character
let prev;
while (i <= read_length) {
// add phantom null byte to end, because of the processing algo
const byte = i === read_length ? NULL_CHARCODE : getByte(data, i);
if (debug_level >= 2) console.log("[ascii-grid/parse-ascii-grid-data] i, byte:", [i, String.fromCharCode(byte)]);
if (byte === SPACE_CHARCODE || byte === NEWLINE_CHARCODE || byte === NULL_CHARCODE) {
if (prev === SPACE_CHARCODE || prev === NEWLINE_CHARCODE || prev === NULL_CHARCODE) {
// don't do anything because have reached weird edge case
// where file has two white space characters in a row
// for example, a new line + space before the start of the next row's data
prev = byte;
i++;
continue;
}
if (num !== "" && c >= start_column && c <= end_column) {
row.push(parseFloat(num));
} else {
if (debug_level >= 2) console.log("[ascii-grid/parse-ascii-grid-data] skipping value at [", r, "][", c, "]");
}
num = "";
table.push(row);
row = [];
} else if (byte === SPACE_CHARCODE) {
if (num !== "") row.push(parseFloat(num));
num = "";
// reached end of the row
if (c == meta.ncols - 1) {
if (r >= start_row && r <= end_row) {
table.push(row);
}
r++;
c = 0;
row = [];
} else {
c++;
}
} else if (

@@ -53,24 +100,20 @@ assume_clean ||

byte === NINE_CHARCODE ||
byte === DOT_CHARCODE ||
(byte > ZERO_CHARCODE && byte < NINE_CHARCODE)
) {
num += String.fromCharCode(byte);
} else if (debug_level >= 2) {
console.error("[ascii-grid/parse-ascii-grid-data]: unknown byte", [byte]);
}
}
// special case is the last byte because sometimes it's a null-byte (0)
const lastByte = getByte(data, read_length - 1);
if (debug) console.log("[ascii-grid/get-values] lastByte:", [lastByte]);
if (lastByte >= ZERO_CHARCODE && lastByte <= NINE_CHARCODE) {
num += String.fromCharCode(lastByte);
prev = byte;
i++;
}
if (num !== "") row.push(num) && table.push(row);
result.end_of_data_byte = i;
result.values = table;
if (debug) console.log("[ascii-grid/get-values] finishing");
if (debug_level >= 1) console.log("[ascii-grid/parse-ascii-grid-data] finishing");
if (debug_level >= 1) console.timeEnd("[asci-grid] parse-ascii-grid-data took");
return result;
};
const getByte = require("get-byte");
module.exports = async ({ data, debug = false, max_read_length = 500 }) => {
module.exports = ({ data, debug = false, max_read_length = 500 }) => {
const result = {};

@@ -22,5 +22,3 @@

} else if (line === null) {
if (
["-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(char)
) {
if (["-", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"].includes(char)) {
break;

@@ -27,0 +25,0 @@ } else {

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc