Skip to content

✨ allow sending multiple anchors when building line items #170

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@
import com.mindee.geometry.BboxUtils;
import com.mindee.parsing.custom.ListField;
import com.mindee.parsing.custom.ListFieldValue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.math3.util.Precision;

Expand All @@ -19,38 +21,53 @@ public final class LineGenerator {
private LineGenerator() {
}

public static Collection<Line> prepareLines(
public static PreparedLines prepareLines(
Map<String, ListField> fields,
Anchor fieldAsAnchor
List<Anchor> anchors
) {
HashMap<Integer, Line> table = new HashMap<>();

ListField anchor = fields.get(fieldAsAnchor.getName());

if (anchor == null) {
throw new IllegalStateException("The field selected for the anchor was not found.");
Anchor bestAnchor = null;
Collection<Line> lines = null;
int lineCount = 0;
for (Anchor anchor : anchors) {
ListField anchorColumn = fields.get(anchor.getName());
if (anchorColumn == null) {
throw new IllegalStateException("The field selected for the anchor was not found.");
}
Collection<Line> currentLines = createLines(
anchorColumn.getValues(),
anchor.getTolerance()
);
if (currentLines.size() > lineCount) {
bestAnchor = anchor;
lines = currentLines;
lineCount = currentLines.size();
}
}

if (anchor.getValues().isEmpty()) {
throw new IllegalStateException("No lines have been detected.");
if (lines == null) {
throw new IllegalStateException("Could not determine which anchor to use.");
}
return new PreparedLines(
bestAnchor,
new ArrayList<>(lines)
);
}

private static Collection<Line> createLines(List<ListFieldValue> anchorValues, double tolerance) {
HashMap<Integer, Line> table = new HashMap<>();

// handle one value and the case of one line
int lineNumber = 1;
Line currentLine = new Line(lineNumber, fieldAsAnchor.getTolerance());
ListFieldValue currentValue = anchor.getValues().get(0);
Line currentLine = new Line(lineNumber, tolerance);
ListFieldValue currentValue = anchorValues.get(0);
currentLine.setBbox(currentValue.getPolygon().getAsBbox());

for (int i = 1; i < anchor.getValues().size(); i++) {

currentValue = anchor.getValues().get(i);
for (ListFieldValue anchorValue : anchorValues) {
currentValue = anchorValue;
Bbox currentFieldBbox = currentValue.getPolygon().getAsBbox();

if (
Precision.equals(
currentLine.getBbox().getMinY(),
currentFieldBbox.getMinY(),
fieldAsAnchor.getTolerance()
tolerance
)
) {
currentLine.setBbox(
Expand All @@ -60,13 +77,11 @@ public static Collection<Line> prepareLines(
// when it is a new line
table.put(lineNumber, currentLine);
lineNumber++;
currentLine = new Line(lineNumber, fieldAsAnchor.getTolerance());
currentLine = new Line(lineNumber, tolerance);
currentLine.setBbox(currentFieldBbox);
}
}

table.putIfAbsent(lineNumber, currentLine);

return table.values();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.mindee.parsing.custom.lineitems;

import com.mindee.geometry.MinMax;
import com.mindee.geometry.PolygonUtils;
import com.mindee.parsing.custom.ListField;
import com.mindee.parsing.custom.ListFieldValue;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
Expand All @@ -19,8 +19,25 @@ private LineItemsGenerator() {
}

/**
* WARNING: This feature is experimental!
* Results may not always work as intended.
* Generate line items.
* Use this method if you want to send a list of different possible anchor fields.
* Will use the tolerance settings from the best anchor.
*/
public static LineItems generate(
List<String> fieldNames,
Map<String, ListField> fields,
List<Anchor> anchors
) {
Map<String, ListField> fieldsToTransformIntoLines = fields.entrySet()
.stream()
.filter(field -> fieldNames.contains(field.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
return generate(fieldsToTransformIntoLines, anchors);
}

/**
* Generate line items.
* Use this method if you want to use a single anchor field.
*/
public static LineItems generate(
List<String> fieldNames,
Expand All @@ -31,20 +48,32 @@ public static LineItems generate(
.stream()
.filter(field -> fieldNames.contains(field.getKey()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
List<Anchor> anchors = new ArrayList<>(
Collections.singletonList(anchor)
);
return generate(fieldsToTransformIntoLines, anchors);
}

private static LineItems generate(
Map<String, ListField> fieldsToTransformIntoLines,
List<Anchor> anchors
) {
PreparedLines preparedLines = LineGenerator.prepareLines(
fieldsToTransformIntoLines,
anchors
);
List<Line> lines = populateLines(
fieldsToTransformIntoLines,
new ArrayList<>(LineGenerator.prepareLines(fieldsToTransformIntoLines, anchor)),
anchor.getTolerance()
preparedLines.getLines(),
preparedLines.getAnchor().getTolerance()
);

return new LineItems(lines);
}

private static List<Line> populateLines(
Map<String, ListField> fields,
List<Line> lines,
double heightLineTolerance
double tolerance
) {
List<Line> populatedLines = new ArrayList<>();

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

if (
Math.abs(minMaxY.getMax() - currentLine.getBbox().getMaxY()) <= heightLineTolerance
&& Math.abs(minMaxY.getMin() - currentLine.getBbox().getMinY()) <= heightLineTolerance
Math.abs(minMaxY.getMax() - currentLine.getBbox().getMaxY()) <= tolerance
&& Math.abs(minMaxY.getMin() - currentLine.getBbox().getMinY()) <= tolerance
) {
currentLine.addField(field.getKey(), listFieldValue);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package com.mindee.parsing.custom.lineitems;

import java.util.List;
import lombok.Getter;

/**
* An anchor and its initial lines.
*/
@Getter
public final class PreparedLines {
private final Anchor anchor;
private final List<Line> lines;

/**
* An anchor and its initial lines.
*/
public PreparedLines(Anchor anchor, List<Line> lines) {
this.anchor = anchor;
this.lines = lines;
}
}
Loading
Loading