1
0
Fork 0
mirror of https://github.com/sbrl/terrain50-cli.git synced 2024-11-26 07:33:00 +00:00

Add new analyse-frequencies subcommand

This commit is contained in:
Starbeamrainbowlabs 2020-09-28 17:55:03 +01:00
parent 0ffbfc42bd
commit 460e2bc1aa
Signed by: sbrl
GPG key ID: 1BE5172E637709C2
6 changed files with 129 additions and 4 deletions

View file

@ -13,9 +13,15 @@ npm install --save terrain50-cli
----- -----
## v1.5
- Update dependencies
- Add new `analyse-frequencies` subcommand
## v1.4.1 ## v1.4.1
- `validate` subcommand in `stream` mode: Write aggregated stats when validation is complete - `validate` subcommand in `stream` mode: Write aggregated stats when validation is complete
## v1.4 ## v1.4
- [BREAKING] Add new `--use-regex` flag to `validate` subcommand (only takes effect in stream mode: `--mode stream`) - [BREAKING] Add new `--use-regex` flag to `validate` subcommand (only takes effect in stream mode: `--mode stream`)

6
package-lock.json generated
View file

@ -338,9 +338,9 @@
} }
}, },
"terrain50": { "terrain50": {
"version": "1.8.0", "version": "1.8.1",
"resolved": "https://registry.npmjs.org/terrain50/-/terrain50-1.8.0.tgz", "resolved": "https://registry.npmjs.org/terrain50/-/terrain50-1.8.1.tgz",
"integrity": "sha512-G6wJw0ysZMet0KCqOZr9Cr0OWTjXn00BpZy0SVMfgIE/GiDTeFbCt2EeHANBwKwc93ItLxGua4nWI+5v42jHmw==", "integrity": "sha512-bPAOCOcDHgHoLf2Y7uvk09kDZBRKSkIjBNH5kLzufjzaimxaWVJiALegO9RYw5sHRlU+nzbPZ/0trdJjSs/CRQ==",
"requires": { "requires": {
"nexline": "^1.2.1", "nexline": "^1.2.1",
"nnng": "^1.0.0" "nnng": "^1.0.0"

View file

@ -37,7 +37,7 @@
"chroma-js": "^2.1.0", "chroma-js": "^2.1.0",
"image-encode": "^1.3.0", "image-encode": "^1.3.0",
"nexline": "^1.2.1", "nexline": "^1.2.1",
"terrain50": "^1.8.0" "terrain50": "^1.8.1"
}, },
"bin": { "bin": {
"terrain50": "./src/index.mjs" "terrain50": "./src/index.mjs"

View file

@ -0,0 +1,50 @@
"use strict";
/**
* Writes data to a stream, automatically waiting for the drain event if asked.
* See also write_safe.
* @param {stream.Writable} stream_out The writable stream to write to.
* @param {string|Buffer|Uint8Array} data The data to write.
* @return {Promise} A promise that resolves when writing is complete.
* @private
*/
function write_safe(stream_out, data) {
return new Promise(function (resolve, reject) {
// Handle errors
let handler_error = (error) => {
stream_out.off("error", handler_error);
reject(error);
};
stream_out.on("error", handler_error);
if(typeof data == "string" ? stream_out.write(data, "utf-8") : stream_out.write(data)) {
// We're good to go
stream_out.off("error", handler_error);
resolve();
}
else {
// We need to wait for the drain event before continuing
stream_out.once("drain", () => {
stream_out.off("error", handler_error);
resolve();
});
}
});
}
/**
* Waits for the given stream to end and finish writing data.
* NOTE: This function is not tested and guaranteed yet. (ref #10 the HydroIndexWriter bug)
* @param {stream.Writable} stream The stream to end.
* @param {Buffer|string} [chunk=undefined] Optional. A chunk to write when calling .end().
* @return {Promise} A Promise that resolves when writing is complete.
* @private
*/
function end_safe(stream, chunk = undefined) {
return new Promise((resolve, _reject) => {
if(typeof chunk == "undefined") stream.end(resolve);
else stream.end(chunk, resolve);
});
}
export { write_safe, end_safe };

View file

@ -0,0 +1,50 @@
"use strict";
import fs from 'fs';
import Terrain50 from 'terrain50';
import a from '../../Helpers/Ansi.mjs';
import l from '../../Helpers/Log.mjs';
import { percentage } from '../../Helpers/MathsHelpers.mjs';
import { write_safe, end_safe } from '../../Helpers/StreamHelpers.mjs';
export default async function(settings) {
// 1: Parse settings
let stream_in = process.stdin;
if(settings.cli.input !== "-") {
l.log(`Reading from ${a.hicol}${settings.cli.input}${a.reset}`);
stream_in = fs.createReadStream(settings.cli.input);
}
else
l.log(`Reading from stdin`);
let stream_out = process.stdout;
if(settings.cli.output !== "-") {
l.log(`Writing to ${a.hicol}${settings.cli.output}${a.reset}`);
stream_out = fs.createWriteStream(settings.cli.output);
}
else
l.log(`Writing to stdout`);
// ------------------------------------------------------------------------
let result_map = await Terrain50.AnalyseFrequencies(
Terrain50.ParseStream(stream_in),
settings.cli.ignore_nodata
);
let result_arr = [];
for(const [ key, value ] of result_map) {
result_arr.push([ key, value ]);
}
result_arr.sort((a, b) => a[0] - b[0]);
for(const [ key, value ] of result_arr) {
await write_safe(stream_out, `${key} ${value}\n`);
}
await end_safe(stream_out);
stream_in.destroy();
}

View file

@ -0,0 +1,19 @@
description = "Count the frequencies of data values. Data values are rounded down before counting."
[[arguments]]
name = "input"
description = "The input file to analyse (default: stdin)"
default_value = "-"
type = "string"
[[arguments]]
name = "output"
description = "The output file to write the results to as tab-separated-values (default: stdout)"
default_value = "-"
type = "string"
[[arguments]]
name = "ignore-nodata"
description = "Ignore NODATA values when analysing."
default_value = false
type = "boolean"