RED-6009: Document Tree Structure

* changed redactionLog Rectangle mapping to match UI
This commit is contained in:
Kilian Schuettler 2023-04-27 12:28:50 +02:00
parent 2f9b023bb4
commit 3ce08a34a6
7 changed files with 99 additions and 87 deletions

View File

@ -1,6 +1,6 @@
package com.iqser.red.service.redaction.v1.server.layoutparsing.document.data.mapper; package com.iqser.red.service.redaction.v1.server.layoutparsing.document.data.mapper;
import static com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleTransformations.parseRectangle2D; import static com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleMapper.parseRectangle2D;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -9,7 +9,7 @@ import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.no
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.SectionNode; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.SectionNode;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.TableCellNode; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.TableCellNode;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.TableNode; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.TableNode;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleTransformations; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleMapper;
import com.iqser.red.service.redaction.v1.server.redaction.model.ImageType; import com.iqser.red.service.redaction.v1.server.redaction.model.ImageType;
public class PropertiesMapper { public class PropertiesMapper {
@ -19,7 +19,7 @@ public class PropertiesMapper {
Map<String, String> properties = new HashMap<>(); Map<String, String> properties = new HashMap<>();
properties.put("imageType", image.getImageType().toString()); properties.put("imageType", image.getImageType().toString());
properties.put("transparency", String.valueOf(image.isTransparent())); properties.put("transparency", String.valueOf(image.isTransparent()));
properties.put("position", RectangleTransformations.toString(image.getPosition())); properties.put("position", RectangleMapper.toString(image.getPosition()));
properties.put("id", image.getId()); properties.put("id", image.getId());
return properties; return properties;
} }
@ -35,7 +35,7 @@ public class PropertiesMapper {
if (tableCell.getPages().size() > 1 || tableCell.getBBox().keySet().size() > 1) { if (tableCell.getPages().size() > 1 || tableCell.getBBox().keySet().size() > 1) {
throw new IllegalArgumentException("TableCell can only occur on a single page!"); throw new IllegalArgumentException("TableCell can only occur on a single page!");
} }
String bBoxString = RectangleTransformations.toString(tableCell.getBBox().get(tableCell.getPages().stream().findFirst().get())); String bBoxString = RectangleMapper.toString(tableCell.getBBox().get(tableCell.getPages().stream().findFirst().get()));
properties.put("bBox", bBoxString); properties.put("bBox", bBoxString);
return properties; return properties;

View File

@ -32,7 +32,7 @@ import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.no
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.SectionNode; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.SectionNode;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.SemanticNode; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.SemanticNode;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.textblock.AtomicTextBlock; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.textblock.AtomicTextBlock;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleTransformations; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleMapper;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.TextPositionOperations; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.TextPositionOperations;
import com.iqser.red.service.redaction.v1.server.redaction.utils.IdBuilder; import com.iqser.red.service.redaction.v1.server.redaction.utils.IdBuilder;
@ -108,7 +108,7 @@ public class DocumentGraphFactory {
public void addImage(SectionNode sectionNode, ClassifiedImage image, Context context) { public void addImage(SectionNode sectionNode, ClassifiedImage image, Context context) {
Rectangle2D position = RectangleTransformations.toRectangle2D(image.getPosition()); Rectangle2D position = RectangleMapper.toRectangle2D(image.getPosition());
PageNode page = context.getPage(image.getPage()); PageNode page = context.getPage(image.getPage());
ImageNode imageNode = ImageNode.builder() ImageNode imageNode = ImageNode.builder()
.id(IdBuilder.buildId(Set.of(page), List.of(position))) .id(IdBuilder.buildId(Set.of(page), List.of(position)))

View File

@ -8,7 +8,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.annotations
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.entity.RedactionEntity; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.entity.RedactionEntity;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.entity.RedactionPosition; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.entity.RedactionPosition;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.SemanticNode; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.nodes.SemanticNode;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleTransformations; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -27,7 +27,7 @@ public class ManualRedactionApplicationService {
.findFirst() .findFirst()
.orElseThrow(() -> new NoSuchElementException("No redaction position with matching annotation id found!")); .orElseThrow(() -> new NoSuchElementException("No redaction position with matching annotation id found!"));
redactionPositionToBeResized.setRectanglePerLine(manualResizeRedaction.getPositions().stream().map(RectangleTransformations::toRectangle2D).toList()); redactionPositionToBeResized.setRectanglePerLine(manualResizeRedaction.getPositions().stream().map(RectangleMapper::toRectangle2D).toList());
int newStartOffset; int newStartOffset;
if (manualResizeRedaction.getValue().length() > entityToBeResized.getValue().length()) { if (manualResizeRedaction.getValue().length() > entityToBeResized.getValue().length()) {

View File

@ -0,0 +1,79 @@
package com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils;
import static java.lang.String.format;
import java.awt.geom.Rectangle2D;
import java.util.Arrays;
import java.util.List;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Point;
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Rectangle;
import com.iqser.red.service.redaction.v1.server.layoutparsing.classification.model.AbstractPageBlock;
import com.iqser.red.service.redaction.v1.server.redaction.model.RedRectangle2D;
public class RectangleMapper {
public static Rectangle2D toRectangle2D(AbstractPageBlock abstractPageBlock) {
return new Rectangle2D.Float(abstractPageBlock.getMinX(), abstractPageBlock.getMinY(), abstractPageBlock.getWidth(), abstractPageBlock.getHeight());
}
public static Rectangle2D toRectangle2D(RedRectangle2D redRectangle2D) {
return new Rectangle2D.Double(redRectangle2D.getX(), redRectangle2D.getY(), redRectangle2D.getWidth(), redRectangle2D.getHeight());
}
public static Rectangle2D toRectangle2D(Rectangle redactionLogRectangle) {
return new Rectangle2D.Double(redactionLogRectangle.getTopLeft().getX(),
redactionLogRectangle.getTopLeft().getY(),
redactionLogRectangle.getWidth(),
redactionLogRectangle.getHeight());
}
public static Rectangle2D toRectangle2D(PDRectangle rectangle) {
return new Rectangle2D.Double(rectangle.getLowerLeftX(), rectangle.getLowerLeftY(), rectangle.getWidth(), rectangle.getHeight());
}
public static Rectangle toRedactionLogRectangle(Rectangle2D rectangle2D, int pageNumber) {
return new Rectangle(new Point((float) rectangle2D.getMinX(), (float) rectangle2D.getMinY()), (float) rectangle2D.getWidth(), (float) rectangle2D.getHeight(), pageNumber);
}
public static com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle toAnnotationRectangle(Rectangle2D rectangle2D, int pageNumber) {
return new com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle((float) rectangle2D.getMaxX(),
(float) rectangle2D.getMaxY(),
(float) rectangle2D.getWidth(),
(float) rectangle2D.getHeight(),
pageNumber);
}
public static String toString(Rectangle2D rectangle2D) {
return format("%f,%f,%f,%f", rectangle2D.getX(), rectangle2D.getY(), rectangle2D.getWidth(), rectangle2D.getHeight());
}
public static Rectangle2D parseRectangle2D(String bBox) {
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));
}
public static Rectangle2D toRectangle2D(com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle rect) {
return new Rectangle2D.Double(rect.getTopLeftX() - rect.getWidth(), rect.getTopLeftY() - rect.getHeight(), rect.getWidth(), rect.getHeight());
}
}

View File

@ -1,10 +1,7 @@
package com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils; package com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils;
import static java.lang.String.format;
import java.awt.geom.Area; import java.awt.geom.Area;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
@ -15,11 +12,9 @@ import java.util.stream.Collector;
import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.apache.pdfbox.pdmodel.common.PDRectangle;
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Point;
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Rectangle; import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.Rectangle;
import com.iqser.red.service.redaction.v1.server.layoutparsing.classification.model.AbstractPageBlock; import com.iqser.red.service.redaction.v1.server.layoutparsing.classification.model.AbstractPageBlock;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.textblock.AtomicTextBlock; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.graph.textblock.AtomicTextBlock;
import com.iqser.red.service.redaction.v1.server.redaction.model.RedRectangle2D;
public class RectangleTransformations { public class RectangleTransformations {
@ -31,52 +26,7 @@ public class RectangleTransformations {
public static Rectangle2D bBoxUnionAbstractTextContainer(List<AbstractPageBlock> abstractPageBlocks) { public static Rectangle2D bBoxUnionAbstractTextContainer(List<AbstractPageBlock> abstractPageBlocks) {
return abstractPageBlocks.stream().map(RectangleTransformations::toRectangle2D).collect(new Rectangle2DUnion()); return abstractPageBlocks.stream().map(RectangleMapper::toRectangle2D).collect(new Rectangle2DUnion());
}
public static Rectangle2D bBoxUnionAtomicTextBlock(List<AtomicTextBlock> atomicTextBlocks) {
return atomicTextBlocks.stream().flatMap(atomicTextBlock -> atomicTextBlock.getPositions().stream()).collect(new Rectangle2DUnion());
}
public static Rectangle2D bBoxUnionRectangle(List<Rectangle> rectangles) {
return rectangles.stream().map(RectangleTransformations::toRectangle2D).collect(new Rectangle2DUnion());
}
public static Rectangle2D rectangleUnion(List<Rectangle2D> rectangle2DList) {
return rectangle2DList.stream().collect(new Rectangle2DUnion());
}
public static Rectangle2D toRectangle2D(AbstractPageBlock abstractPageBlock) {
return new Rectangle2D.Float(abstractPageBlock.getMinX(), abstractPageBlock.getMinY(), abstractPageBlock.getWidth(), abstractPageBlock.getHeight());
}
public static Rectangle2D toRectangle2D(RedRectangle2D redRectangle2D) {
return new Rectangle2D.Double(redRectangle2D.getX(), redRectangle2D.getY(), redRectangle2D.getWidth(), redRectangle2D.getHeight());
}
public static Rectangle2D toRectangle2D(Rectangle rectangle) {
return new Rectangle2D.Double(rectangle.getTopLeft().getX() - rectangle.getWidth(),
rectangle.getTopLeft().getY() - rectangle.getHeight(),
rectangle.getWidth(),
rectangle.getHeight());
}
public static Rectangle2D toRectangle2D(PDRectangle rectangle) {
return new Rectangle2D.Double(rectangle.getLowerLeftX(), rectangle.getLowerLeftY(), rectangle.getWidth(), rectangle.getHeight());
} }
@ -93,38 +43,21 @@ public class RectangleTransformations {
} }
public static Rectangle toRectangle(Rectangle2D rectangle2D, int pageNumber) { public static Rectangle2D bBoxUnionAtomicTextBlock(List<AtomicTextBlock> atomicTextBlocks) {
return new Rectangle(new Point((float) rectangle2D.getMaxX(), (float) rectangle2D.getMaxY()), (float) rectangle2D.getWidth(), (float) rectangle2D.getHeight(), pageNumber); return atomicTextBlocks.stream().flatMap(atomicTextBlock -> atomicTextBlock.getPositions().stream()).collect(new Rectangle2DUnion());
} }
public static com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle toAnnotationRectangle(Rectangle2D rectangle2D, int pageNumber) { public static Rectangle2D bBoxUnionRectangle(List<Rectangle> rectangles) {
return new com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle((float) rectangle2D.getMaxX(), return rectangles.stream().map(RectangleMapper::toRectangle2D).collect(new Rectangle2DUnion());
(float) rectangle2D.getMaxY(),
(float) rectangle2D.getWidth(),
(float) rectangle2D.getHeight(),
pageNumber);
} }
public static String toString(Rectangle2D rectangle2D) { public static Rectangle2D rectangleUnion(List<Rectangle2D> rectangle2DList) {
return format("%f,%f,%f,%f", rectangle2D.getX(), rectangle2D.getY(), rectangle2D.getWidth(), rectangle2D.getHeight()); return rectangle2DList.stream().collect(new Rectangle2DUnion());
}
public static Rectangle2D parseRectangle2D(String bBox) {
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));
}
public static Rectangle2D toRectangle2D(com.iqser.red.service.persistence.service.v1.api.shared.model.annotations.Rectangle rect) {
return new Rectangle2D.Double(rect.getTopLeftX() - rect.getWidth(), rect.getTopLeftY() - rect.getHeight(), rect.getWidth(), rect.getHeight());
} }

View File

@ -1,6 +1,6 @@
package com.iqser.red.service.redaction.v1.server.redaction.service; package com.iqser.red.service.redaction.v1.server.redaction.service;
import static com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleTransformations.toRectangle; import static com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleMapper.toRedactionLogRectangle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
@ -66,7 +66,7 @@ public class RedactionLogCreatorService {
List<Rectangle> rectanglesPerLine = redactionPosition.getRectanglePerLine() List<Rectangle> rectanglesPerLine = redactionPosition.getRectanglePerLine()
.stream() .stream()
.map(rectangle2D -> toRectangle(rectangle2D, redactionPosition.getPageNode().getNumber())) .map(rectangle2D -> toRedactionLogRectangle(rectangle2D, redactionPosition.getPageNode().getNumber()))
.toList(); .toList();
redactionLogEntry.setPositions(rectanglesPerLine); redactionLogEntry.setPositions(rectanglesPerLine);
@ -125,7 +125,7 @@ public class RedactionLogCreatorService {
.isHint(dictionaryService.isHint(image.getImageType().toString(), dossierTemplateId)) .isHint(dictionaryService.isHint(image.getImageType().toString(), dossierTemplateId))
.isDictionaryEntry(false) .isDictionaryEntry(false)
.isRecommendation(false) .isRecommendation(false)
.positions(List.of(toRectangle(image.getPosition(), image.getPage().getNumber()))) .positions(List.of(toRedactionLogRectangle(image.getPosition(), image.getPage().getNumber())))
.sectionNumber(image.getTocId().get(0)) .sectionNumber(image.getTocId().get(0))
.section(image.getParent().buildTextBlock().getSearchText()) .section(image.getParent().buildTextBlock().getSearchText())
.imageHasTransparency(image.isTransparent()) .imageHasTransparency(image.isTransparent())

View File

@ -37,7 +37,7 @@ import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlo
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.SectionGrid; import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.SectionGrid;
import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.SectionRectangle; import com.iqser.red.service.persistence.service.v1.api.shared.model.redactionlog.section.SectionRectangle;
import com.iqser.red.service.redaction.v1.server.exception.RedactionException; import com.iqser.red.service.redaction.v1.server.exception.RedactionException;
import com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleTransformations; import com.iqser.red.service.redaction.v1.server.layoutparsing.document.utils.RectangleMapper;
import com.iqser.red.service.redaction.v1.server.redaction.service.DictionaryService; import com.iqser.red.service.redaction.v1.server.redaction.service.DictionaryService;
import com.iqser.red.service.redaction.v1.server.storage.RedactionStorageService; import com.iqser.red.service.redaction.v1.server.storage.RedactionStorageService;
@ -175,7 +175,7 @@ public class AnnotationService {
public static List<Double> toQuadPoints(List<Rectangle> rectangles) { public static List<Double> toQuadPoints(List<Rectangle> rectangles) {
return rectangles.stream().map(RectangleTransformations::toRectangle2D).flatMap(AnnotationService::toQuadPoints).toList(); return rectangles.stream().map(RectangleMapper::toRectangle2D).flatMap(AnnotationService::toQuadPoints).toList();
} }