Skip to content

Commit 7ae7901

Browse files
authored
✨ allow sending multiple anchors when building line items (#170)
1 parent 0fc5b1f commit 7ae7901

File tree

5 files changed

+255
-74
lines changed

5 files changed

+255
-74
lines changed

src/main/java/com/mindee/parsing/custom/lineitems/LineGenerator.java

Lines changed: 37 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
import com.mindee.geometry.BboxUtils;
55
import com.mindee.parsing.custom.ListField;
66
import com.mindee.parsing.custom.ListFieldValue;
7+
import java.util.ArrayList;
78
import java.util.Arrays;
89
import java.util.Collection;
910
import java.util.HashMap;
11+
import java.util.List;
1012
import java.util.Map;
1113
import org.apache.commons.math3.util.Precision;
1214

@@ -19,38 +21,53 @@ public final class LineGenerator {
1921
private LineGenerator() {
2022
}
2123

22-
public static Collection<Line> prepareLines(
24+
public static PreparedLines prepareLines(
2325
Map<String, ListField> fields,
24-
Anchor fieldAsAnchor
26+
List<Anchor> anchors
2527
) {
26-
HashMap<Integer, Line> table = new HashMap<>();
27-
28-
ListField anchor = fields.get(fieldAsAnchor.getName());
29-
30-
if (anchor == null) {
31-
throw new IllegalStateException("The field selected for the anchor was not found.");
28+
Anchor bestAnchor = null;
29+
Collection<Line> lines = null;
30+
int lineCount = 0;
31+
for (Anchor anchor : anchors) {
32+
ListField anchorColumn = fields.get(anchor.getName());
33+
if (anchorColumn == null) {
34+
throw new IllegalStateException("The field selected for the anchor was not found.");
35+
}
36+
Collection<Line> currentLines = createLines(
37+
anchorColumn.getValues(),
38+
anchor.getTolerance()
39+
);
40+
if (currentLines.size() > lineCount) {
41+
bestAnchor = anchor;
42+
lines = currentLines;
43+
lineCount = currentLines.size();
44+
}
3245
}
33-
34-
if (anchor.getValues().isEmpty()) {
35-
throw new IllegalStateException("No lines have been detected.");
46+
if (lines == null) {
47+
throw new IllegalStateException("Could not determine which anchor to use.");
3648
}
49+
return new PreparedLines(
50+
bestAnchor,
51+
new ArrayList<>(lines)
52+
);
53+
}
54+
55+
private static Collection<Line> createLines(List<ListFieldValue> anchorValues, double tolerance) {
56+
HashMap<Integer, Line> table = new HashMap<>();
3757

3858
// handle one value and the case of one line
3959
int lineNumber = 1;
40-
Line currentLine = new Line(lineNumber, fieldAsAnchor.getTolerance());
41-
ListFieldValue currentValue = anchor.getValues().get(0);
60+
Line currentLine = new Line(lineNumber, tolerance);
61+
ListFieldValue currentValue = anchorValues.get(0);
4262
currentLine.setBbox(currentValue.getPolygon().getAsBbox());
43-
44-
for (int i = 1; i < anchor.getValues().size(); i++) {
45-
46-
currentValue = anchor.getValues().get(i);
63+
for (ListFieldValue anchorValue : anchorValues) {
64+
currentValue = anchorValue;
4765
Bbox currentFieldBbox = currentValue.getPolygon().getAsBbox();
48-
4966
if (
5067
Precision.equals(
5168
currentLine.getBbox().getMinY(),
5269
currentFieldBbox.getMinY(),
53-
fieldAsAnchor.getTolerance()
70+
tolerance
5471
)
5572
) {
5673
currentLine.setBbox(
@@ -60,13 +77,11 @@ public static Collection<Line> prepareLines(
6077
// when it is a new line
6178
table.put(lineNumber, currentLine);
6279
lineNumber++;
63-
currentLine = new Line(lineNumber, fieldAsAnchor.getTolerance());
80+
currentLine = new Line(lineNumber, tolerance);
6481
currentLine.setBbox(currentFieldBbox);
6582
}
6683
}
67-
6884
table.putIfAbsent(lineNumber, currentLine);
69-
7085
return table.values();
7186
}
7287

src/main/java/com/mindee/parsing/custom/lineitems/LineItemsGenerator.java

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package com.mindee.parsing.custom.lineitems;
22

33
import com.mindee.geometry.MinMax;
4-
import com.mindee.geometry.PolygonUtils;
54
import com.mindee.parsing.custom.ListField;
65
import com.mindee.parsing.custom.ListFieldValue;
76
import java.util.ArrayList;
7+
import java.util.Collections;
88
import java.util.List;
99
import java.util.Map;
1010
import java.util.stream.Collectors;
@@ -19,8 +19,25 @@ private LineItemsGenerator() {
1919
}
2020

2121
/**
22-
* WARNING: This feature is experimental!
23-
* Results may not always work as intended.
22+
* Generate line items.
23+
* Use this method if you want to send a list of different possible anchor fields.
24+
* Will use the tolerance settings from the best anchor.
25+
*/
26+
public static LineItems generate(
27+
List<String> fieldNames,
28+
Map<String, ListField> fields,
29+
List<Anchor> anchors
30+
) {
31+
Map<String, ListField> fieldsToTransformIntoLines = fields.entrySet()
32+
.stream()
33+
.filter(field -> fieldNames.contains(field.getKey()))
34+
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
35+
return generate(fieldsToTransformIntoLines, anchors);
36+
}
37+
38+
/**
39+
* Generate line items.
40+
* Use this method if you want to use a single anchor field.
2441
*/
2542
public static LineItems generate(
2643
List<String> fieldNames,
@@ -31,20 +48,32 @@ public static LineItems generate(
3148
.stream()
3249
.filter(field -> fieldNames.contains(field.getKey()))
3350
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
51+
List<Anchor> anchors = new ArrayList<>(
52+
Collections.singletonList(anchor)
53+
);
54+
return generate(fieldsToTransformIntoLines, anchors);
55+
}
3456

57+
private static LineItems generate(
58+
Map<String, ListField> fieldsToTransformIntoLines,
59+
List<Anchor> anchors
60+
) {
61+
PreparedLines preparedLines = LineGenerator.prepareLines(
62+
fieldsToTransformIntoLines,
63+
anchors
64+
);
3565
List<Line> lines = populateLines(
3666
fieldsToTransformIntoLines,
37-
new ArrayList<>(LineGenerator.prepareLines(fieldsToTransformIntoLines, anchor)),
38-
anchor.getTolerance()
67+
preparedLines.getLines(),
68+
preparedLines.getAnchor().getTolerance()
3969
);
40-
4170
return new LineItems(lines);
4271
}
4372

4473
private static List<Line> populateLines(
4574
Map<String, ListField> fields,
4675
List<Line> lines,
47-
double heightLineTolerance
76+
double tolerance
4877
) {
4978
List<Line> populatedLines = new ArrayList<>();
5079

@@ -54,8 +83,8 @@ private static List<Line> populateLines(
5483
MinMax minMaxY = listFieldValue.getPolygon().getMinMaxY();
5584

5685
if (
57-
Math.abs(minMaxY.getMax() - currentLine.getBbox().getMaxY()) <= heightLineTolerance
58-
&& Math.abs(minMaxY.getMin() - currentLine.getBbox().getMinY()) <= heightLineTolerance
86+
Math.abs(minMaxY.getMax() - currentLine.getBbox().getMaxY()) <= tolerance
87+
&& Math.abs(minMaxY.getMin() - currentLine.getBbox().getMinY()) <= tolerance
5988
) {
6089
currentLine.addField(field.getKey(), listFieldValue);
6190
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.mindee.parsing.custom.lineitems;
2+
3+
import java.util.List;
4+
import lombok.Getter;
5+
6+
/**
7+
* An anchor and its initial lines.
8+
*/
9+
@Getter
10+
public final class PreparedLines {
11+
private final Anchor anchor;
12+
private final List<Line> lines;
13+
14+
/**
15+
* An anchor and its initial lines.
16+
*/
17+
public PreparedLines(Anchor anchor, List<Line> lines) {
18+
this.anchor = anchor;
19+
this.lines = lines;
20+
}
21+
}

0 commit comments

Comments
 (0)