RED-6009: Document Tree Structure

* removed unnecessary final keywords
This commit is contained in:
Kilian Schuettler 2023-05-30 17:33:53 +02:00
parent 32df4ca867
commit 040097bc52
6 changed files with 44 additions and 35 deletions

View File

@ -152,7 +152,7 @@ public class DocumentGraphMapper {
} }
private static AtomicTextBlock getAtomicTextBlock(Context context, SemanticNode parent, Long atomicTextBlockId) { private AtomicTextBlock getAtomicTextBlock(Context context, SemanticNode parent, Long atomicTextBlockId) {
return AtomicTextBlock.fromAtomicTextBlockData(context.atomicTextBlockData.get(Math.toIntExact(atomicTextBlockId)), return AtomicTextBlock.fromAtomicTextBlockData(context.atomicTextBlockData.get(Math.toIntExact(atomicTextBlockId)),
context.atomicPositionBlockData.get(Math.toIntExact(atomicTextBlockId)), context.atomicPositionBlockData.get(Math.toIntExact(atomicTextBlockId)),

View File

@ -13,21 +13,27 @@ import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.no
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.Table; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.Table;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.TableCell; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.TableCell;
import lombok.AccessLevel;
import lombok.experimental.FieldDefaults;
import lombok.experimental.UtilityClass;
@UtilityClass
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
public class PropertiesMapper { public class PropertiesMapper {
private static final String imageType = "imageType"; String imageType = "imageType";
private static final String transparency = "transparency"; private final String transparency = "transparency";
private static final String position = "position"; private final String position = "position";
private static final String id = "id"; String id = "id";
private static final String row = "row"; String row = "row";
private static final String col = "col"; String col = "col";
private static final String header = "header"; String header = "header";
private static final String bBox = "bBox"; String bBox = "bBox";
private static final String numberOfRows = "numberOfRows"; String numberOfRows = "numberOfRows";
private static final String numberOfCols = "numberOfCols"; String numberOfCols = "numberOfCols";
public static Map<String, String> buildImageProperties(Image image) { public Map<String, String> buildImageProperties(Image image) {
Map<String, String> properties = new HashMap<>(); Map<String, String> properties = new HashMap<>();
properties.put(imageType, image.getImageType().toString()); properties.put(imageType, image.getImageType().toString());
@ -38,13 +44,13 @@ public class PropertiesMapper {
} }
private static String toString(Rectangle2D rectangle2D) { private String toString(Rectangle2D rectangle2D) {
return format("%f,%f,%f,%f", rectangle2D.getX(), rectangle2D.getY(), rectangle2D.getWidth(), rectangle2D.getHeight()); return format("%f,%f,%f,%f", rectangle2D.getX(), rectangle2D.getY(), rectangle2D.getWidth(), rectangle2D.getHeight());
} }
public static Map<String, String> buildTableCellProperties(TableCell tableCell) { public Map<String, String> buildTableCellProperties(TableCell tableCell) {
Map<String, String> properties = new HashMap<>(); Map<String, String> properties = new HashMap<>();
properties.put(row, String.valueOf(tableCell.getRow())); properties.put(row, String.valueOf(tableCell.getRow()));
@ -61,7 +67,7 @@ public class PropertiesMapper {
} }
public static Map<String, String> buildTableProperties(Table table) { public Map<String, String> buildTableProperties(Table table) {
Map<String, String> properties = new HashMap<>(); Map<String, String> properties = new HashMap<>();
properties.put(numberOfRows, String.valueOf(table.getNumberOfRows())); properties.put(numberOfRows, String.valueOf(table.getNumberOfRows()));
@ -70,7 +76,7 @@ public class PropertiesMapper {
} }
public static void parseImageProperties(Map<String, String> properties, Image.ImageBuilder builder) { public void parseImageProperties(Map<String, String> properties, Image.ImageBuilder builder) {
builder.imageType(ImageType.fromString(properties.get(imageType))); builder.imageType(ImageType.fromString(properties.get(imageType)));
builder.transparent(Boolean.parseBoolean(properties.get(transparency))); builder.transparent(Boolean.parseBoolean(properties.get(transparency)));
@ -79,7 +85,7 @@ public class PropertiesMapper {
} }
public static void parseTableCellProperties(Map<String, String> properties, TableCell.TableCellBuilder builder) { public void parseTableCellProperties(Map<String, String> properties, TableCell.TableCellBuilder builder) {
builder.row(Integer.parseInt(properties.get(row))); builder.row(Integer.parseInt(properties.get(row)));
builder.col(Integer.parseInt(properties.get(col))); builder.col(Integer.parseInt(properties.get(col)));
@ -88,14 +94,14 @@ public class PropertiesMapper {
} }
public static void parseTableProperties(Map<String, String> properties, Table.TableBuilder builder) { public void parseTableProperties(Map<String, String> properties, Table.TableBuilder builder) {
builder.numberOfRows(Integer.parseInt(properties.get(numberOfRows))); builder.numberOfRows(Integer.parseInt(properties.get(numberOfRows)));
builder.numberOfCols(Integer.parseInt(properties.get(numberOfCols))); builder.numberOfCols(Integer.parseInt(properties.get(numberOfCols)));
} }
private static Rectangle2D parseRectangle2D(String bBox) { private Rectangle2D parseRectangle2D(String bBox) {
List<Float> floats = Arrays.stream(bBox.split(",")).map(Float::parseFloat).toList(); List<Float> floats = Arrays.stream(bBox.split(",")).map(Float::parseFloat).toList();
return new Rectangle2D.Float(floats.get(0), floats.get(1), floats.get(2), floats.get(3)); return new Rectangle2D.Float(floats.get(0), floats.get(1), floats.get(2), floats.get(3));

View File

@ -196,7 +196,7 @@ public class DocumentGraphFactory {
@Builder @Builder
@AllArgsConstructor @AllArgsConstructor
@FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE)
public static final class Context { public final class Context {
DocumentTree documentTree; DocumentTree documentTree;
Map<Page, Integer> pages; Map<Page, Integer> pages;

View File

@ -10,18 +10,21 @@ import com.iqser.red.service.redaction.v1.server.layoutparsing.classification.mo
import com.iqser.red.service.redaction.v1.server.layoutparsing.classification.model.text.TextDirection; import com.iqser.red.service.redaction.v1.server.layoutparsing.classification.model.text.TextDirection;
import com.iqser.red.service.redaction.v1.server.layoutparsing.classification.model.text.TextPositionSequence; import com.iqser.red.service.redaction.v1.server.layoutparsing.classification.model.text.TextPositionSequence;
import lombok.experimental.UtilityClass;
@UtilityClass
public class SearchTextWithTextPositionFactory { public class SearchTextWithTextPositionFactory {
public static final int HEIGHT_PADDING = 2; public final int HEIGHT_PADDING = 2;
// when checking for a hyphen linebreak, we need to check after a linebreak if the last hyphen was less than three symbols away. // when checking for a hyphen linebreak, we need to check after a linebreak if the last hyphen was less than three symbols away.
// We detect a linebreak as either a "\n" character or if two adjacent symbol's position differ in y-coordinates by at least one character height. // We detect a linebreak as either a "\n" character or if two adjacent symbol's position differ in y-coordinates by at least one character height.
// If there is a hyphen linebreak, the hyphen will be 1 position in front of a "\n" or 2 positions in front of the character which has a lower y-coordinate // If there is a hyphen linebreak, the hyphen will be 1 position in front of a "\n" or 2 positions in front of the character which has a lower y-coordinate
// This is why, we need to initialize this to < -2, otherwise, if the very first symbol is a \n we would detect a hyphen linebreak that isn't there. // This is why, we need to initialize this to < -2, otherwise, if the very first symbol is a \n we would detect a hyphen linebreak that isn't there.
// Also, Integer.MIN_VALUE is a bad idea due to potential overflow during arithmetic operations. This is why the default should be -3. // Also, Integer.MIN_VALUE is a bad idea due to potential overflow during arithmetic operations. This is why the default should be -3.
public static final int MAX_HYPHEN_LINEBREAK_DISTANCE = 3; public final int MAX_HYPHEN_LINEBREAK_DISTANCE = 3;
public static SearchTextWithTextPositionDto buildSearchTextToTextPositionModel(List<TextPositionSequence> sequences) { public SearchTextWithTextPositionDto buildSearchTextToTextPositionModel(List<TextPositionSequence> sequences) {
if (sequences.isEmpty() || sequences.stream().allMatch(sequence -> sequence.getTextPositions().isEmpty())) { if (sequences.isEmpty() || sequences.stream().allMatch(sequence -> sequence.getTextPositions().isEmpty())) {
return SearchTextWithTextPositionDto.empty(); return SearchTextWithTextPositionDto.empty();
@ -72,7 +75,7 @@ public class SearchTextWithTextPositionFactory {
} }
private static void appendCurrentTextPosition(Context context, RedTextPosition currentTextPosition) { private void appendCurrentTextPosition(Context context, RedTextPosition currentTextPosition) {
context.stringBuilder.append(currentTextPosition.getUnicode()); context.stringBuilder.append(currentTextPosition.getUnicode());
@ -84,7 +87,7 @@ public class SearchTextWithTextPositionFactory {
} }
private static void removeHyphenLinebreaks(Context context) { private void removeHyphenLinebreaks(Context context) {
if (lastHyphenDirectlyBeforeLineBreak(context)) { if (lastHyphenDirectlyBeforeLineBreak(context)) {
context.stringBuilder.delete(context.lastHyphenIdx, context.stringBuilder.length()); context.stringBuilder.delete(context.lastHyphenIdx, context.stringBuilder.length());
@ -95,19 +98,19 @@ public class SearchTextWithTextPositionFactory {
} }
private static boolean lastHyphenDirectlyBeforeLineBreak(Context context) { private boolean lastHyphenDirectlyBeforeLineBreak(Context context) {
return context.stringIdx - context.lastHyphenIdx < MAX_HYPHEN_LINEBREAK_DISTANCE; return context.stringIdx - context.lastHyphenIdx < MAX_HYPHEN_LINEBREAK_DISTANCE;
} }
private static boolean isLineBreak(RedTextPosition currentTextPosition, RedTextPosition previousTextPosition) { private boolean isLineBreak(RedTextPosition currentTextPosition, RedTextPosition previousTextPosition) {
return Objects.equals(currentTextPosition.getUnicode(), "\n") || isDeltaYLargerThanTextHeight(currentTextPosition, previousTextPosition); return Objects.equals(currentTextPosition.getUnicode(), "\n") || isDeltaYLargerThanTextHeight(currentTextPosition, previousTextPosition);
} }
private static boolean isDeltaYLargerThanTextHeight(RedTextPosition currentPosition, RedTextPosition previousPosition) { private boolean isDeltaYLargerThanTextHeight(RedTextPosition currentPosition, RedTextPosition previousPosition) {
if (previousPosition == null) { if (previousPosition == null) {
return false; return false;
@ -118,13 +121,13 @@ public class SearchTextWithTextPositionFactory {
} }
private static boolean isRepeatedWhitespace(String currentUnicode, String previousUnicode) { private boolean isRepeatedWhitespace(String currentUnicode, String previousUnicode) {
return Objects.equals(previousUnicode, " ") && Objects.equals(currentUnicode, " "); return Objects.equals(previousUnicode, " ") && Objects.equals(currentUnicode, " ");
} }
private static boolean isHyphen(String unicodeCharacter) { private boolean isHyphen(String unicodeCharacter) {
return Objects.equals(unicodeCharacter, "-") || // return Objects.equals(unicodeCharacter, "-") || //
Objects.equals(unicodeCharacter, "~") || // Objects.equals(unicodeCharacter, "~") || //
@ -140,7 +143,7 @@ public class SearchTextWithTextPositionFactory {
} }
private static Rectangle2D mapRedTextPositionToInitialUserSpace(RedTextPosition textPosition, TextPositionSequence sequence) { private Rectangle2D mapRedTextPositionToInitialUserSpace(RedTextPosition textPosition, TextPositionSequence sequence) {
float textHeight = sequence.getTextHeight() + HEIGHT_PADDING; float textHeight = sequence.getTextHeight() + HEIGHT_PADDING;
Rectangle2D rectangle2D = new Rectangle2D.Double(textPosition.getXDirAdj(), Rectangle2D rectangle2D = new Rectangle2D.Double(textPosition.getXDirAdj(),
@ -166,7 +169,7 @@ public class SearchTextWithTextPositionFactory {
} }
private static class Context { private class Context {
List<Integer> stringIdxToPositionIdx = new LinkedList<>(); List<Integer> stringIdxToPositionIdx = new LinkedList<>();
List<Integer> lineBreaksStringIdx = new LinkedList<>(); List<Integer> lineBreaksStringIdx = new LinkedList<>();

View File

@ -48,7 +48,7 @@ public class SectionNodeFactory {
} }
private static List<Integer> getTreeId(GenericSemanticNode parentNode, DocumentGraphFactory.Context context, Section section) { private List<Integer> getTreeId(GenericSemanticNode parentNode, DocumentGraphFactory.Context context, Section section) {
if (parentNode == null) { if (parentNode == null) {
return context.getDocumentTree().createNewMainEntryAndReturnId(section); return context.getDocumentTree().createNewMainEntryAndReturnId(section);

View File

@ -24,7 +24,7 @@ import lombok.experimental.UtilityClass;
@UtilityClass @UtilityClass
public class TableNodeFactory { public class TableNodeFactory {
public static final double TABLE_CELL_MERGE_CONTENTS_SIZE_THRESHOLD = 0.05; public final double TABLE_CELL_MERGE_CONTENTS_SIZE_THRESHOLD = 0.05;
public void addTable(GenericSemanticNode parentNode, List<TablePageBlock> tablesToMerge, DocumentGraphFactory.Context context) { public void addTable(GenericSemanticNode parentNode, List<TablePageBlock> tablesToMerge, DocumentGraphFactory.Context context) {
@ -56,7 +56,7 @@ public class TableNodeFactory {
} }
private static void setPageNumberInTextBlocksWithPageNumberSetTo0(TablePageBlock table, Cell cell) { private void setPageNumberInTextBlocksWithPageNumberSetTo0(TablePageBlock table, Cell cell) {
cell.getTextBlocks().stream()// cell.getTextBlocks().stream()//
.filter(tb -> tb.getPage() == 0)// .filter(tb -> tb.getPage() == 0)//