Skip to content

Commit 06fad24

Browse files
committed
✨ allow sending multiple anchors when building line items
1 parent 0fc5b1f commit 06fad24

File tree

5 files changed

+256
-86
lines changed

5 files changed

+256
-86
lines changed

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

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,9 @@
44
import com.mindee.geometry.BboxUtils;
55
import com.mindee.parsing.custom.ListField;
66
import com.mindee.parsing.custom.ListFieldValue;
7-
import java.util.Arrays;
8-
import java.util.Collection;
9-
import java.util.HashMap;
10-
import java.util.Map;
7+
8+
import java.util.*;
9+
1110
import org.apache.commons.math3.util.Precision;
1211

1312

@@ -19,54 +18,67 @@ public final class LineGenerator {
1918
private LineGenerator() {
2019
}
2120

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

3855
// handle one value and the case of one line
3956
int lineNumber = 1;
40-
Line currentLine = new Line(lineNumber, fieldAsAnchor.getTolerance());
41-
ListFieldValue currentValue = anchor.getValues().get(0);
57+
Line currentLine = new Line(lineNumber, tolerance);
58+
ListFieldValue currentValue = anchorValues.get(0);
4259
currentLine.setBbox(currentValue.getPolygon().getAsBbox());
43-
44-
for (int i = 1; i < anchor.getValues().size(); i++) {
45-
46-
currentValue = anchor.getValues().get(i);
60+
for (ListFieldValue anchorValue : anchorValues) {
61+
currentValue = anchorValue;
4762
Bbox currentFieldBbox = currentValue.getPolygon().getAsBbox();
48-
4963
if (
50-
Precision.equals(
51-
currentLine.getBbox().getMinY(),
52-
currentFieldBbox.getMinY(),
53-
fieldAsAnchor.getTolerance()
54-
)
64+
Precision.equals(
65+
currentLine.getBbox().getMinY(),
66+
currentFieldBbox.getMinY(),
67+
tolerance
68+
)
5569
) {
5670
currentLine.setBbox(
57-
BboxUtils.merge(Arrays.asList(currentLine.getBbox(), currentFieldBbox))
71+
BboxUtils.merge(Arrays.asList(currentLine.getBbox(), currentFieldBbox))
5872
);
5973
} else {
6074
// when it is a new line
6175
table.put(lineNumber, currentLine);
6276
lineNumber++;
63-
currentLine = new Line(lineNumber, fieldAsAnchor.getTolerance());
77+
currentLine = new Line(lineNumber, tolerance);
6478
currentLine.setBbox(currentFieldBbox);
6579
}
6680
}
67-
6881
table.putIfAbsent(lineNumber, currentLine);
69-
7082
return table.values();
7183
}
7284

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

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +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;
7-
import java.util.ArrayList;
8-
import java.util.List;
9-
import java.util.Map;
6+
7+
import java.util.*;
108
import java.util.stream.Collectors;
119

1210
/**
@@ -19,8 +17,25 @@ private LineItemsGenerator() {
1917
}
2018

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

55+
private static LineItems generate(
56+
Map<String, ListField> fieldsToTransformIntoLines,
57+
List<Anchor> anchors
58+
) {
59+
PreparedLines preparedLines = LineGenerator.prepareLines(
60+
fieldsToTransformIntoLines,
61+
anchors
62+
);
3563
List<Line> lines = populateLines(
3664
fieldsToTransformIntoLines,
37-
new ArrayList<>(LineGenerator.prepareLines(fieldsToTransformIntoLines, anchor)),
38-
anchor.getTolerance()
65+
preparedLines.getLines(),
66+
preparedLines.getAnchor().getTolerance()
3967
);
40-
4168
return new LineItems(lines);
4269
}
4370

4471
private static List<Line> populateLines(
4572
Map<String, ListField> fields,
4673
List<Line> lines,
47-
double heightLineTolerance
74+
double tolerance
4875
) {
4976
List<Line> populatedLines = new ArrayList<>();
5077

@@ -54,8 +81,8 @@ private static List<Line> populateLines(
5481
MinMax minMaxY = listFieldValue.getPolygon().getMinMaxY();
5582

5683
if (
57-
Math.abs(minMaxY.getMax() - currentLine.getBbox().getMaxY()) <= heightLineTolerance
58-
&& Math.abs(minMaxY.getMin() - currentLine.getBbox().getMinY()) <= heightLineTolerance
84+
Math.abs(minMaxY.getMax() - currentLine.getBbox().getMaxY()) <= tolerance
85+
&& Math.abs(minMaxY.getMin() - currentLine.getBbox().getMinY()) <= tolerance
5986
) {
6087
currentLine.addField(field.getKey(), listFieldValue);
6188
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.mindee.parsing.custom.lineitems;
2+
3+
import java.util.List;
4+
import lombok.Getter;
5+
6+
@Getter
7+
public final class PreparedLines {
8+
private final Anchor anchor;
9+
private final List<Line> lines;
10+
11+
public PreparedLines(Anchor anchor, List<Line> lines) {
12+
this.anchor = anchor;
13+
this.lines = lines;
14+
}
15+
}

0 commit comments

Comments
 (0)