diff --git a/README.md b/README.md index 7ad125e..02fa670 100644 --- a/README.md +++ b/README.md @@ -217,7 +217,12 @@ const result = iterClip({ band: [2, 2], // 3rd band (blue), where band index starts at zero row: [55, 74], // from the 56th to the 75th row (counting from the top) column: [60, 62] // from the 61st to the 63rd column (counting from the left) - } + }, + + // optional + // order to return point values + // in left-to-right major order + order: ["band", "row", "column"] }); ``` result is an iterator object diff --git a/src/xdim.js b/src/xdim.js index 5ced4bd..b219d53 100644 --- a/src/xdim.js +++ b/src/xdim.js @@ -162,10 +162,10 @@ function prepareUpdate({ useLayoutCache = true, data, layout, sizes = {} }) { }; } -function iterClip({ data, layout, rect = {}, sizes = {}, useLayoutCache = true }) { +function iterClip({ data, layout, order, rect = {}, sizes = {}, useLayoutCache = true }) { if (!data) throw new Error("[xdim] must specify data"); if (!layout) throw new Error("[xdim] must specify layout"); - const points = iterPoints({ sizes, rect }); + const points = iterPoints({ order, sizes, rect }); return wrapNextFunction(function next() { const { value: point, done } = points.next(); if (done) { @@ -437,9 +437,9 @@ function iterRange({ start = 0, end = 100 }) { } // iterate over all the points, saving memory vs array -function iterPoints({ sizes, rect = {} }) { +function iterPoints({ order, sizes, rect = {} }) { // names sorted by shortest dimension to longest dimension - const names = Object.keys(sizes).sort((a, b) => sizes[a] - sizes[b]); + const names = Array.isArray(order) ? order : Object.keys(sizes).sort((a, b) => sizes[a] - sizes[b]); const iters = new Array(names.length); const current = {}; diff --git a/tests/test.iter-clip.js b/tests/test.iter-clip.js index 93118ad..3279081 100644 --- a/tests/test.iter-clip.js +++ b/tests/test.iter-clip.js @@ -3,18 +3,18 @@ const { iterClip } = require("../src/xdim"); const range = ct => new Array(ct).fill(0).map((_, i) => i); -test("iter clip with rect", ({ eq }) => { - // band row column - const pixelDepth = 4; - const height = 768; - const width = 1024; - const data = range(pixelDepth).map(band => { - return range(height).map(row => { - return range(width).map(column => { - return { b: band, r: row, c: column }; - }); +const pixelDepth = 4; +const height = 768; +const width = 1024; +const data = range(pixelDepth).map(band => { + return range(height).map(row => { + return range(width).map(column => { + return { b: band, r: row, c: column }; }); }); +}); + +test("iter clip with rect", ({ eq }) => { const iter = iterClip({ data, layout: "[band][row][column]", sizes: { band: 4, row: 768, column: 1024 }, rect: { band: [1, 3] } }); eq(iter.next().value, { b: 1, r: 0, c: 0 }); eq(iter.next().value, { b: 1, r: 0, c: 1 }); @@ -26,3 +26,15 @@ test("iter clip with rect", ({ eq }) => { for (last of iter); eq(last, { b: 3, r: 767, c: 1023 }); }); + +test("iter clip with rect and order", ({ eq }) => { + const iter = iterClip({ + data, + layout: "[band][row][column]", + order: ["row", "column", "band"], + sizes: { band: 4, row: 768, column: 1024 }, + rect: { band: [1, 3] } + }); + eq(iter.next().value, { b: 1, r: 0, c: 0 }); + eq(iter.next().value, { b: 2, r: 0, c: 0 }); +}); diff --git a/tests/test.iter-points.js b/tests/test.iter-points.js index d9504b4..204b3da 100644 --- a/tests/test.iter-points.js +++ b/tests/test.iter-points.js @@ -26,3 +26,15 @@ test("iter points with rect", ({ eq }) => { for (last of iter); eq(last, { band: 3, row: 767, column: 1023 }); }); + +test("iter points with order", ({ eq }) => { + const iter = iterPoints({ order: ["band", "row", "column"], sizes: { band: 4, row: 101, column: 50 } }); + eq(iter.next().value, { band: 0, row: 0, column: 0 }); + eq(iter.next().value, { band: 0, row: 0, column: 1 }); +}); + +test("iter points with rect and order", ({ eq }) => { + const iter = iterPoints({ order: ["row", "column", "band"], sizes: { band: 4, row: 101, column: 50 }, rect: { band: [1, 3] } }); + eq(iter.next().value, { row: 0, column: 0, band: 1 }); + eq(iter.next().value, { row: 0, column: 0, band: 2 }); +});