diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/classification/service/BlockificationService.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/classification/service/BlockificationService.java index ddca2792..d1416a5b 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/classification/service/BlockificationService.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/classification/service/BlockificationService.java @@ -3,6 +3,7 @@ package com.iqser.red.service.redaction.v1.server.classification.service; import static java.util.stream.Collectors.toSet; import java.awt.geom.Line2D; +import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Comparator; import java.util.Iterator; @@ -33,7 +34,7 @@ public class BlockificationService { public Page blockify(List textPositions, List horizontalRulingLines, - List verticalRulingLines, PDRectangle cropbox) { + List verticalRulingLines, int rotation, PDRectangle cropbox) { // sortRotatedSequences(textPositions); @@ -53,14 +54,14 @@ public class BlockificationService { boolean xIsBeforeFirstX = prev != null && word.getX1() < minX; boolean newLineAfterSplit = prev != null && word.getY1() != prev.getY1() && wasSplitted && splitX1 != word.getX1(); boolean splittedByRuling = - isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), verticalRulingLines,cropbox.getHeight()) || - isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), horizontalRulingLines,cropbox.getHeight()) + isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), verticalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight()) || + isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), horizontalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight()) - || isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), horizontalRulingLines,cropbox.getHeight()) - || isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), verticalRulingLines,cropbox.getHeight()); + || isSplittedByRuling(maxX, minY, word.getX1(), word.getY1(), horizontalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight()) + || isSplittedByRuling(minX, minY, word.getX1(), word.getY2(), verticalRulingLines, word.getDir().getDegrees(), cropbox.getWidth(), cropbox.getHeight()); boolean splitByDir = prev != null && !prev.getDir().equals(word.getDir()); - if (prev != null && (lineSeparation || startFromTop || xIsBeforeFirstX || splitByX || splitByDir || startFromTop)) { + if (prev != null && (lineSeparation || startFromTop || xIsBeforeFirstX || splitByX || splitByDir || startFromTop || splittedByRuling)) { Orientation prevOrientation = null; if (!chunkBlockList1.isEmpty()) { @@ -112,55 +113,55 @@ public class BlockificationService { chunkBlockList1.add(cb1); } -// Iterator itty = chunkBlockList1.iterator(); -// -// TextBlock previousLeft = null; -// TextBlock previousRight = null; -// while (itty.hasNext()) { -// TextBlock block = (TextBlock) itty.next(); -// -// if (previousLeft != null && block.getOrientation().equals(Orientation.LEFT)) { -// if (previousLeft.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousLeft -// .getMinY()) { -// previousLeft.add(block); -// itty.remove(); -// continue; -// } -// } -// -// if (previousRight != null && block.getOrientation().equals(Orientation.RIGHT)) { -// if (previousRight.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousRight -// .getMinY()) { -// previousRight.add(block); -// itty.remove(); -// continue; -// } -// } -// -// if (block.getOrientation().equals(Orientation.LEFT)) { -// previousLeft = block; -// } else if (block.getOrientation().equals(Orientation.RIGHT)) { -// previousRight = block; -// } -// } -// -// itty = chunkBlockList1.iterator(); -// TextBlock previous = null; -// while (itty.hasNext()) { -// TextBlock block = (TextBlock) itty.next(); -// -// if (previous != null && previous.getOrientation().equals(Orientation.LEFT) && block.getOrientation() -// .equals(Orientation.LEFT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY()) || previous != null && previous -// .getOrientation() -// .equals(Orientation.LEFT) && block.getOrientation() -// .equals(Orientation.RIGHT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY())) { -// previous.add(block); -// itty.remove(); -// continue; -// } -// -// previous = block; -// } + Iterator itty = chunkBlockList1.iterator(); + + TextBlock previousLeft = null; + TextBlock previousRight = null; + while (itty.hasNext()) { + TextBlock block = (TextBlock) itty.next(); + + if (previousLeft != null && block.getOrientation().equals(Orientation.LEFT)) { + if (previousLeft.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousLeft + .getMinY()) { + previousLeft.add(block); + itty.remove(); + continue; + } + } + + if (previousRight != null && block.getOrientation().equals(Orientation.RIGHT)) { + if (previousRight.getMinY() > block.getMinY() && block.getMaxY() + block.getMostPopularWordHeight() > previousRight + .getMinY()) { + previousRight.add(block); + itty.remove(); + continue; + } + } + + if (block.getOrientation().equals(Orientation.LEFT)) { + previousLeft = block; + } else if (block.getOrientation().equals(Orientation.RIGHT)) { + previousRight = block; + } + } + + itty = chunkBlockList1.iterator(); + TextBlock previous = null; + while (itty.hasNext()) { + TextBlock block = (TextBlock) itty.next(); + + if (previous != null && previous.getOrientation().equals(Orientation.LEFT) && block.getOrientation() + .equals(Orientation.LEFT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY()) || previous != null && previous + .getOrientation() + .equals(Orientation.LEFT) && block.getOrientation() + .equals(Orientation.RIGHT) && equalsWithThreshold(block.getMaxY(), previous.getMaxY())) { + previous.add(block); + itty.remove(); + continue; + } + + previous = block; + } return new Page(chunkBlockList1); } @@ -221,10 +222,10 @@ public class BlockificationService { private boolean isSplittedByRuling(float previousX2, float previousY1, float currentX1, float currentY1, - List rulingLines, float pageHeight) { + List rulingLines, float rotation, float pageWidth, float pageHeight) { for (Ruling ruling : rulingLines) { - var line = new Line2D.Float(pageHeight -ruling.y1 , ruling.x1, pageHeight -ruling.y2, ruling.x2); + var line = convertToJavaCoord(ruling, rotation, pageWidth, pageHeight); if (line.intersectsLine(previousX2, previousY1, currentX1, currentY1)) { return true; } @@ -233,6 +234,74 @@ public class BlockificationService { } + private Line2D.Float convertToJavaCoord(Ruling ruling, float rotation, float pageWidth, float pageHeight){ + + + return new Line2D.Float(convertPoint(ruling.x1, ruling.y1, rotation, pageWidth, pageHeight), convertPoint(ruling.x2, ruling.y2, rotation, pageWidth, pageHeight)); + + + } + + private Point2D convertPoint(float x, float y, float rotation, float pageWidth, float pageHeight){ + var xAdj = getXRot(x,y,rotation, pageWidth, pageHeight); + var yAdj = 0f; + if (rotation == 0 || rotation == 180) + { + yAdj = pageHeight - getYLowerLeftRot(x,y,rotation, pageWidth, pageHeight); + } + else + { + yAdj = pageWidth - getYLowerLeftRot(x,y,rotation, pageWidth, pageHeight); + } + return new Point2D.Float(xAdj, yAdj); + } + + private float getXRot(float x, float y, float rotation, float pageWidth, float pageHeight) + { + if (rotation == 0) + { + return x; + } + else if (rotation == 90) + { + return y; + } + else if (rotation == 180) + { + return pageWidth - x; + } + else if (rotation == 270) + { + return pageHeight - y; + } + return 0; + } + + + private float getYLowerLeftRot(float x, float y, float rotation, float pageWidth, float pageHeight) + { + if (rotation == 0) + { + return y; + } + else if (rotation == 90) + { + return pageWidth - x; + } + else if (rotation == 180) + { + return pageHeight - y; + } + else if (rotation == 270) + { + return x; + } + return 0; + } + + + + public Rectangle calculateBodyTextFrame(List pages, FloatFrequencyCounter documentFontSizeCounter, boolean landscape) { diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/segmentation/PdfSegmentationService.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/segmentation/PdfSegmentationService.java index 1790834a..0640e7cc 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/segmentation/PdfSegmentationService.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/segmentation/PdfSegmentationService.java @@ -106,7 +106,7 @@ public class PdfSegmentationService { PDRectangle cropbox = pdPage.getCropBox(); CleanRulings cleanRulings = rulingCleaningService.getCleanRulings(pdfTableCells.get(pageNumber), stripper.getRulings(), stripper.getMinCharWidth(), stripper.getMaxCharHeight()); - Page page = blockificationService.blockify(stripper.getTextPositionSequences(), cleanRulings.getHorizontal(), cleanRulings.getVertical(), cropbox); + Page page = blockificationService.blockify(stripper.getTextPositionSequences(), cleanRulings.getHorizontal(), cleanRulings.getVertical(), rotation, cropbox); float cropboxArea = cropbox.getHeight() * cropbox.getWidth(); diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/tableextraction/model/AbstractTextContainer.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/tableextraction/model/AbstractTextContainer.java index c1bf285e..4dc3f7ef 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/tableextraction/model/AbstractTextContainer.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/tableextraction/model/AbstractTextContainer.java @@ -4,6 +4,7 @@ import com.dslplatform.json.JsonAttribute; import com.fasterxml.jackson.annotation.JsonIgnore; import com.iqser.red.service.redaction.v1.model.Rectangle; import com.iqser.red.service.redaction.v1.server.classification.model.Orientation; +import com.iqser.red.service.redaction.v1.server.classification.model.TextBlock; import lombok.AllArgsConstructor; import lombok.Data; @@ -30,35 +31,31 @@ public abstract class AbstractTextContainer { @JsonIgnore private Orientation orientation = Orientation.NONE; - public abstract String getText(); - public boolean contains(AbstractTextContainer other) { + public boolean containsBlock(TextBlock other) { + return this.minX <= other.getX1() && this.maxX >= other.getX2() && this.minY >= other.getY1() && this.maxY <= other.getY2(); + } + + public boolean contains(AbstractTextContainer other) { return this.minX <= other.minX && this.maxX >= other.maxX && this.minY >= other.minY && this.maxY <= other.maxY; } - public boolean contains(Rectangle other) { - - return page == other.getPage() && this.minX <= other.getTopLeft().getX() && this.maxX >= other.getTopLeft().getX() + other.getWidth() && this.minY <= other.getTopLeft() - .getY() && this.maxY >= other.getTopLeft().getY() + other.getHeight(); + return page == other.getPage() && this.minX <= other.getTopLeft().getX() && this.maxX >= other.getTopLeft().getX() + other.getWidth() && this.minY <= other.getTopLeft().getY() && this.maxY >= other.getTopLeft().getY() + other.getHeight(); } - @JsonIgnore @JsonAttribute(ignore = true) public float getHeight() { - return maxY - minY; } - @JsonIgnore @JsonAttribute(ignore = true) public float getWidth() { - return maxX - minX; } diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/tableextraction/service/TableExtractionService.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/tableextraction/service/TableExtractionService.java index 9fdc2fb6..3d22f2db 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/tableextraction/service/TableExtractionService.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/tableextraction/service/TableExtractionService.java @@ -94,7 +94,7 @@ public class TableExtractionService { Iterator itty = page.getTextBlocks().iterator(); while (itty.hasNext()) { AbstractTextContainer textBlock = itty.next(); - if (table.contains(textBlock) && position == -1) { + if (textBlock instanceof TextBlock ? table.containsBlock((TextBlock) textBlock) : table.contains(textBlock) && position == -1) { position = page.getTextBlocks().indexOf(textBlock); } } diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/visualization/service/PdfVisualisationService.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/visualization/service/PdfVisualisationService.java index 4067ed24..778aaf41 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/visualization/service/PdfVisualisationService.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/visualization/service/PdfVisualisationService.java @@ -97,41 +97,41 @@ public class PdfVisualisationService { contentStream.addRect(textBlock.getX1(), textBlock.getY1(), textBlock.getX2() - textBlock.getX1(), textBlock.getY2() - textBlock.getY1()); contentStream.stroke(); - if (textBlock.getClassification() != null) { - contentStream.beginText(); - - contentStream.setFont(PDType1Font.TIMES_ROMAN, 6f); - - contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2() + 2); - contentStream.showText(textBlock.getClassification() + textBlock.getOrientation() + "-->" + textBlock.getSequences().get(0).getDir()); - - contentStream.endText(); - - - contentStream.setNonStrokingColor(Color.BLUE); - contentStream.setFont(PDType1Font.TIMES_ROMAN, 2f); - - - - contentStream.beginText(); - contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY1()); - contentStream.showText("MinX,MinY(" + textBlock.getX1() + "," + textBlock.getY1() + ")"); - contentStream.endText(); - contentStream.beginText(); - contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY1()); - contentStream.showText("MaxX,MinY(" + textBlock.getX2() + "," + textBlock.getY1() + ")"); - contentStream.endText(); - contentStream.beginText(); - contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2()); - contentStream.showText("MinX,MaxY(" + textBlock.getX1() + "," + textBlock.getY2() + ")"); - contentStream.endText(); - contentStream.beginText(); - contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY2()); - contentStream.showText("MaxX,MaxY(" + textBlock.getX2() + "," + textBlock.getY2() + ")"); - - - contentStream.endText(); - } +// if (textBlock.getClassification() != null) { +// contentStream.beginText(); +// +// contentStream.setFont(PDType1Font.TIMES_ROMAN, 6f); +// +// contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2() + 2); +// contentStream.showText(textBlock.getClassification() + textBlock.getOrientation() + "-->" + textBlock.getSequences().get(0).getDir()); +// +// contentStream.endText(); +// +// +// contentStream.setNonStrokingColor(Color.BLUE); +// contentStream.setFont(PDType1Font.TIMES_ROMAN, 2f); +// +// +// +// contentStream.beginText(); +// contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY1()); +// contentStream.showText("MinX,MinY(" + textBlock.getX1() + "," + textBlock.getY1() + ")"); +// contentStream.endText(); +// contentStream.beginText(); +// contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY1()); +// contentStream.showText("MaxX,MinY(" + textBlock.getX2() + "," + textBlock.getY1() + ")"); +// contentStream.endText(); +// contentStream.beginText(); +// contentStream.newLineAtOffset(textBlock.getX1(), textBlock.getY2()); +// contentStream.showText("MinX,MaxY(" + textBlock.getX1() + "," + textBlock.getY2() + ")"); +// contentStream.endText(); +// contentStream.beginText(); +// contentStream.newLineAtOffset(textBlock.getX2(), textBlock.getY2()); +// contentStream.showText("MaxX,MaxY(" + textBlock.getX2() + "," + textBlock.getY2() + ")"); +// +// +// contentStream.endText(); +// } } diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RedactionIntegrationTest.java b/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RedactionIntegrationTest.java index fc93b818..9396f82a 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RedactionIntegrationTest.java +++ b/redaction-service-v1/redaction-service-server-v1/src/test/java/com/iqser/red/service/redaction/v1/server/RedactionIntegrationTest.java @@ -1098,7 +1098,7 @@ public class RedactionIntegrationTest { System.out.println("classificationTest"); - AnalyzeRequest request = prepareStorage("files/new/VV-511309_OCR.pdf"); + AnalyzeRequest request = prepareStorage("files/Metolachlor/S-Metolachlor_RAR_01_Volume_1_2018-09-06.pdf"); RedactionRequest redactionRequest = RedactionRequest.builder() .dossierId(request.getDossierId()) diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/new/S100.pdf b/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/new/S100.pdf new file mode 100644 index 00000000..c35ccae3 Binary files /dev/null and b/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/new/S100.pdf differ diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/new/S2.pdf b/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/new/S2.pdf new file mode 100644 index 00000000..b2fefd5a Binary files /dev/null and b/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/new/S2.pdf differ