Skip to content

Commit

Permalink
fix: classifier break count must >= features.length - 1 (#1022)
Browse files Browse the repository at this point in the history
* fix: break count must >= features.length - 1
  • Loading branch information
rgwozdz committed May 29, 2024
1 parent efe51ac commit cc30f71
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-avocados-guess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@koopjs/winnow": patch
---

- breakCount needs to >= features.length - 1
8 changes: 4 additions & 4 deletions packages/winnow/coverage-unit.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
16 changes: 12 additions & 4 deletions packages/winnow/src/calculate-class-breaks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,22 @@ const transformClassBreaksToRanges = require('./transform-class-breaks-to-ranges
const filterAndValidateClassificationFeatures = require('./filter-and-validate-classification-features'); // eslint-disable-line

function calculateClassBreaks(features, classification) {
if (!classification.method) throw new Error('must supply classification.method');
if (!classification.breakCount) throw new Error('must supply classification.breakCount');
if (!classification.method) {
throw new Error('must supply classification.method');
}

if (!classification.breakCount) {
throw new Error('must supply classification.breakCount');
}

const values = classification.normType
? normalizeClassificationValues(features, classification)
: getFieldValues(features, classification.field);
// limit break count to num values
if (classification.breakCount > values.length) classification.breakCount = values.length;

// limit break count to num values - 1; [1, 2, 3, 4, 5, 6] => [1-2, 2-3, 3-4, 4-5, 5-6]
if (classification.breakCount > values.length) {
classification.breakCount = values.length - 1;
}

// calculate break ranges [ [a-b], [b-c], ...] from input values
const classBreakArray = transformValuesToClassBreaksArray(values, classification);
Expand Down
98 changes: 98 additions & 0 deletions packages/winnow/src/calculate-class-breaks/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,31 @@ test('calculateClassBreaks: no breakCount', (t) => {
}
});

test('calculateClassBreaks: breakCount > values', (t) => {
t.plan(1);
const features = [
{ properties: { Trunk_Diameter: 13 } },
{ properties: { Trunk_Diameter: 7 } },
{ properties: { Trunk_Diameter: 17 } },
{ properties: { Trunk_Diameter: 25 } },
{ properties: { Trunk_Diameter: 3 } },
];
const classification = {
type: 'classes',
field: 'Trunk_Diameter',
method: 'equalInterval',
breakCount: 6,
};

const result = calculateClassBreaks(features, classification);
t.deepEquals(result, [
[3, 8.5],
[8.6, 14],
[15, 19.5],
[19.6, 25],
]);
});

test('calculateClassBreaks: no method', (t) => {
t.plan(1);
const features = [
Expand Down Expand Up @@ -171,6 +196,54 @@ test('calculateClassBreaks: quantile', (t) => {
]);
});

test('calculateClassBreaks: geomInterval not supported', (t) => {
t.plan(1);
const features = [
{ properties: { Trunk_Diameter: 13 } },
{ properties: { Trunk_Diameter: 7 } },
{ properties: { Trunk_Diameter: 17 } },
{ properties: { Trunk_Diameter: 25 } },
{ properties: { Trunk_Diameter: 3 } },
];
const classification = {
type: 'classes',
field: 'Trunk_Diameter',
method: 'geomInterval',
breakCount: 4,
};

try {
calculateClassBreaks(features, classification);
t.fail('should have thrown');
} catch (error) {
t.equals(error.message, 'Classification method not yet supported');
}
});

test('calculateClassBreaks: unknown method not supported', (t) => {
t.plan(1);
const features = [
{ properties: { Trunk_Diameter: 13 } },
{ properties: { Trunk_Diameter: 7 } },
{ properties: { Trunk_Diameter: 17 } },
{ properties: { Trunk_Diameter: 25 } },
{ properties: { Trunk_Diameter: 3 } },
];
const classification = {
type: 'classes',
field: 'Trunk_Diameter',
method: 'geomIntervalz',
breakCount: 4,
};

try {
calculateClassBreaks(features, classification);
t.fail('should have thrown');
} catch (error) {
t.equals(error.message, 'invalid classificationMethod: geomIntervalz');
}
});

test('calculateClassBreaks: normalize by field', (t) => {
t.plan(1);
const features = [
Expand Down Expand Up @@ -271,3 +344,28 @@ test('calculateClassBreaks: null values not used in breaks calculation', (t) =>
[17.666666666666664, 25],
]);
});

test('calculateClassBreaks: zero negative values', (t) => {
t.plan(1);
const features = [
{ properties: { Trunk_Diameter: 13 } },
{ properties: { Trunk_Diameter: -10 } },
{ properties: { Trunk_Diameter: 7 } },
{ properties: { Trunk_Diameter: 17 } },
{ properties: { Trunk_Diameter: 25 } },
{ properties: { Trunk_Diameter: 3 } },
];
const classification = {
type: 'classes',
field: 'Trunk_Diameter',
method: 'equalInterval',
breakCount: 3,
};

const result = calculateClassBreaks(features, classification);
t.deepEquals(result, [
[0, 8.333333333333334],
[8.333333333333336, 16.666666666666668],
[16.666666666666668, 25],
]);
});
25 changes: 4 additions & 21 deletions test/geoservice-generate-renderer.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ describe('Feature Server Output - /generateRenderer', () => {
classBreakInfos: [
{
classMinValue: 900,
classMaxValue: 900,
label: '900-900',
classMaxValue: 985,
label: '900-985',
description: '',
symbol: {
color: [0, 255, 0],
Expand All @@ -57,26 +57,9 @@ describe('Feature Server Output - /generateRenderer', () => {
},
},
{
classMinValue: 901,
classMaxValue: 1103,
label: '901-1103',
description: '',
symbol: {
color: [0, 255, 255],
outline: {
color: [190, 190, 190, 105],
width: 0.5,
type: 'esriSLS',
style: 'esriSLSSolid',
},
size: 7.5,
type: 'esriSMS',
style: 'esriSMSCircle',
},
},
{
classMinValue: 1104,
label: '1104-undefined',
classMinValue: 986,
label: '986-1103',
description: '',
symbol: {
color: [0, 0, 255],
Expand Down

0 comments on commit cc30f71

Please sign in to comment.