Pull request #411: RED-4129: Fixed calculation of imported redaction intersections for all rotation cases
Merge in RED/redaction-service from RED-4129 to master * commit '2a6ee02f9f8f527546f01cf98542dfc7e39b259a': RED-4129: Fixed calculation of imported redaction intersections for all rotation cases
This commit is contained in:
commit
2d5ba8f447
@ -7,6 +7,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import com.iqser.red.service.redaction.v1.model.ImportedRedaction;
|
||||
import com.iqser.red.service.redaction.v1.model.ImportedRedactions;
|
||||
import com.iqser.red.service.redaction.v1.model.Point;
|
||||
import com.iqser.red.service.redaction.v1.model.Rectangle;
|
||||
import com.iqser.red.service.redaction.v1.model.RedactionLogEntry;
|
||||
import com.iqser.red.service.redaction.v1.server.storage.RedactionStorageService;
|
||||
@ -70,12 +71,13 @@ public class ImportedRedactionService {
|
||||
private void addIntersections(RedactionLogEntry redactionLogEntry, ImportedRedactions importedRedactions) {
|
||||
|
||||
for (Rectangle rectangle : redactionLogEntry.getPositions()) {
|
||||
var normalizedRectangle = normalize(rectangle);
|
||||
if (importedRedactions.getImportedRedactions().containsKey(rectangle.getPage())) {
|
||||
var importedRedactionsOnPage = importedRedactions.getImportedRedactions().get(rectangle.getPage());
|
||||
for (ImportedRedaction importedRedaction : importedRedactionsOnPage) {
|
||||
for (Rectangle importedRedactionPosition : importedRedaction.getPositions()) {
|
||||
if (intersects(importedRedactionPosition, rectangle)) {
|
||||
if(redactionLogEntry.getImportedRedactionIntersections() == null){
|
||||
if (rectOverlap(normalizedRectangle, normalize(importedRedactionPosition))) {
|
||||
if (redactionLogEntry.getImportedRedactionIntersections() == null) {
|
||||
redactionLogEntry.setImportedRedactionIntersections(new HashSet<>());
|
||||
}
|
||||
redactionLogEntry.getImportedRedactionIntersections().add(importedRedaction.getId());
|
||||
@ -87,15 +89,56 @@ public class ImportedRedactionService {
|
||||
}
|
||||
|
||||
|
||||
private boolean intersects(Rectangle importedPosition, Rectangle redactionLogPosition) {
|
||||
boolean valueInRange(float value, float min, float max) {
|
||||
|
||||
return redactionLogPosition.getTopLeft()
|
||||
.getX() + redactionLogPosition.getWidth() > importedPosition.getTopLeft()
|
||||
.getX() && redactionLogPosition.getTopLeft()
|
||||
.getY() + redactionLogPosition.getHeight() > importedPosition.getTopLeft()
|
||||
.getY() && redactionLogPosition.getTopLeft().getX() < importedPosition.getTopLeft()
|
||||
.getX() + importedPosition.getWidth() && redactionLogPosition.getTopLeft()
|
||||
.getY() < importedPosition.getTopLeft().getY() + importedPosition.getHeight();
|
||||
return round(value) >= round(min) && round(value) <= round(max);
|
||||
}
|
||||
|
||||
|
||||
boolean rectOverlap(Rectangle a, Rectangle b) {
|
||||
|
||||
boolean xOverlap = valueInRange(a.getTopLeft().getX(), b.getTopLeft().getX(), b.getTopLeft()
|
||||
.getX() + b.getWidth()) || valueInRange(b.getTopLeft().getX(), a.getTopLeft().getX(), a.getTopLeft()
|
||||
.getX() + a.getWidth());
|
||||
|
||||
boolean yOverlap = valueInRange(a.getTopLeft().getY(), b.getTopLeft().getY(), b.getTopLeft()
|
||||
.getY() + b.getHeight()) || valueInRange(b.getTopLeft().getY(), a.getTopLeft().getY(), a.getTopLeft()
|
||||
.getY() + a.getHeight());
|
||||
|
||||
return xOverlap && yOverlap;
|
||||
}
|
||||
|
||||
|
||||
private Rectangle normalize(Rectangle rectangle) {
|
||||
|
||||
Rectangle r = new Rectangle();
|
||||
Point p = new Point();
|
||||
|
||||
if (rectangle.getWidth() < 0) {
|
||||
p.setX(rectangle.getTopLeft().getX() - rectangle.getWidth());
|
||||
r.setWidth(Math.abs(rectangle.getWidth()));
|
||||
} else {
|
||||
p.setX(rectangle.getTopLeft().getX());
|
||||
r.setWidth(rectangle.getWidth());
|
||||
}
|
||||
|
||||
if (rectangle.getHeight() < 0) {
|
||||
p.setY(rectangle.getTopLeft().getY() + rectangle.getHeight());
|
||||
r.setHeight(Math.abs(rectangle.getHeight()));
|
||||
} else {
|
||||
p.setY(rectangle.getTopLeft().getY());
|
||||
}
|
||||
|
||||
r.setTopLeft(p);
|
||||
r.setPage(rectangle.getPage());
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
private float round(float value) {
|
||||
|
||||
double d = Math.pow(10, 0);
|
||||
return (float) (Math.round(value * d) / d);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -1511,7 +1511,7 @@ public class RedactionIntegrationTest {
|
||||
typeColorMap.put(LOGO, "#ffe187");
|
||||
typeColorMap.put(FORMULA, "#ffe187");
|
||||
typeColorMap.put(SIGNATURE, "#ffe187");
|
||||
typeColorMap.put(IMPORTED_REDACTION, "#32a852");
|
||||
typeColorMap.put(IMPORTED_REDACTION, "#fcfbe6");
|
||||
|
||||
hintTypeMap.put(VERTEBRATE, true);
|
||||
hintTypeMap.put(ADDRESS, false);
|
||||
@ -1668,8 +1668,8 @@ public class RedactionIntegrationTest {
|
||||
public void testImportedRedactions() throws IOException {
|
||||
|
||||
String outputFileName = OsUtils.getTemporaryDirectory() + "/Annotated.pdf";
|
||||
ClassPathResource pdfFileResource = new ClassPathResource("files/ImportedRedactions/ImportedRedactions.pdf");
|
||||
ClassPathResource importedRedactions = new ClassPathResource("files/ImportedRedactions/ImportedRedactions.json");
|
||||
ClassPathResource pdfFileResource = new ClassPathResource("files/ImportedRedactions/RotateTestFile_without_highlights.pdf");
|
||||
ClassPathResource importedRedactions = new ClassPathResource("files/ImportedRedactions/RotateTestFile_without_highlights.IMPORTED_REDACTIONS.json");
|
||||
|
||||
AnalyzeRequest request = prepareStorage(pdfFileResource.getInputStream());
|
||||
storageService.storeObject(RedactionStorageService.StorageIdUtils.getStorageId(TEST_DOSSIER_ID, TEST_FILE_ID, FileType.IMPORTED_REDACTIONS), IOUtils.toByteArray(importedRedactions.getInputStream()));
|
||||
@ -1684,6 +1684,18 @@ public class RedactionIntegrationTest {
|
||||
.fileId(TEST_FILE_ID)
|
||||
.build());
|
||||
|
||||
redactionLog.getRedactionLogEntry().forEach(entry -> {
|
||||
if (entry.getValue() == null) {
|
||||
return;
|
||||
}
|
||||
if (entry.getValue().equals("David")){
|
||||
assertThat(entry.getImportedRedactionIntersections().size()).isEqualTo(1);
|
||||
}
|
||||
if (entry.getValue().equals("annotation")){
|
||||
assertThat(entry.getImportedRedactionIntersections().size()).isEqualTo(0);
|
||||
}
|
||||
});
|
||||
|
||||
try (FileOutputStream fileOutputStream = new FileOutputStream(outputFileName)) {
|
||||
fileOutputStream.write(annotateResponse.getDocument());
|
||||
}
|
||||
|
||||
@ -11,5 +11,5 @@ Sude Halide Nurullah
|
||||
Xinyi Y. Tao
|
||||
Dorn
|
||||
Prasher
|
||||
RuleAnnotation270GradP
|
||||
RuleAnnotation270GradLS
|
||||
David
|
||||
annotation
|
||||
@ -1 +0,0 @@
|
||||
{"importedRedactions":{"1":[{"id":"755273b5ddc6933eff7f6b6e055c803f","positions":[{"topLeft":{"x":275.0,"y":520.504},"width":55.675,"height":15.582,"page":1}]},{"id":"5e517d2c890272fc140578a26971b459","positions":[{"topLeft":{"x":164.0,"y":316.492},"width":50.7,"height":15.658,"page":1},{"topLeft":{"x":127.0,"y":302.613},"width":119.675,"height":14.902,"page":1},{"topLeft":{"x":81.0,"y":289.622},"width":210.025,"height":14.846,"page":1},{"topLeft":{"x":136.0,"y":275.912},"width":94.2,"height":13.033,"page":1},{"topLeft":{"x":158.0,"y":261.402},"width":52.793,"height":16.218,"page":1},{"topLeft":{"x":177.0,"y":247.413},"width":15.507,"height":16.148,"page":1}]}]}}
|
||||
Binary file not shown.
@ -0,0 +1,236 @@
|
||||
{
|
||||
"importedRedactions": {
|
||||
"1": [
|
||||
{
|
||||
"id": "e9b15eafe60232957c4805439d41b4bb",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 173.4,
|
||||
"y": 396.0
|
||||
},
|
||||
"width": -29.5,
|
||||
"height": -8.1,
|
||||
"page": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "5dc06b8f402a5ea6f4a71e7f0ae5f42e",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 189.4,
|
||||
"y": 694.0
|
||||
},
|
||||
"width": 28.0,
|
||||
"height": -12.1,
|
||||
"page": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "42ced0b82072cd154f05f917b5063c23",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 181.8,
|
||||
"y": 593.3
|
||||
},
|
||||
"width": -10.1,
|
||||
"height": -30.0,
|
||||
"page": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "8569561e9cca5d96f2fe966d1f470fbe",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 168.0,
|
||||
"y": 180.1
|
||||
},
|
||||
"width": 10.1,
|
||||
"height": 30.8,
|
||||
"page": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"2": [
|
||||
{
|
||||
"id": "22f46754f11d153e4693c64dd95a0f5f",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 398.8,
|
||||
"y": 302.1
|
||||
},
|
||||
"width": -27.6,
|
||||
"height": -12.1,
|
||||
"page": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "27386f133b866d27a25ceafcb4bd4774",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 153.1,
|
||||
"y": 258.2
|
||||
},
|
||||
"width": 25.5,
|
||||
"height": -10.1,
|
||||
"page": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "294b8d00efd202e4aa51f6fc5e225e80",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 46.3,
|
||||
"y": 304.8
|
||||
},
|
||||
"width": 10.1,
|
||||
"height": -25.5,
|
||||
"page": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "2f7142be7b26f9efd1cd608ceaae8f25",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 523.6,
|
||||
"y": 238.9
|
||||
},
|
||||
"width": -10.1,
|
||||
"height": 25.5,
|
||||
"page": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"3": [
|
||||
{
|
||||
"id": "2566b5f6f11eb7609d0d9722513d6bec",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 444.1,
|
||||
"y": 415.4
|
||||
},
|
||||
"width": 28.0,
|
||||
"height": -12.1,
|
||||
"page": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "84350bb01e0e93be7146a09f975c3065",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 448.6,
|
||||
"y": 615.9
|
||||
},
|
||||
"width": -10.1,
|
||||
"height": -27.5,
|
||||
"page": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "e1dc39e4f5006fa11e6dde38003d4b08",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 434.8,
|
||||
"y": 208.2
|
||||
},
|
||||
"width": 10.1,
|
||||
"height": 27.8,
|
||||
"page": 3
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "75e67d849627e16becb66ec1ba51c7c8",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 428.2,
|
||||
"y": 117.5
|
||||
},
|
||||
"width": -29.4,
|
||||
"height": -8.1,
|
||||
"page": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"4": [
|
||||
{
|
||||
"id": "1c1a66ed056257e6e5ebc58b882acaee",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 526.6,
|
||||
"y": 487.8
|
||||
},
|
||||
"width": 10.1,
|
||||
"height": 27.9,
|
||||
"page": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "7f79cfc276f448f5ee46c3fa2c84ed8b",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 212.6,
|
||||
"y": 504.9
|
||||
},
|
||||
"width": -27.5,
|
||||
"height": -8.1,
|
||||
"page": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "64b11b7d6143f1deb4f1fd3bd72c0464",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 69.5,
|
||||
"y": 558.5
|
||||
},
|
||||
"width": -10.1,
|
||||
"height": -27.9,
|
||||
"page": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "d77ea54e7d2b2276efa7cd9f1d08b411",
|
||||
"positions": [
|
||||
{
|
||||
"topLeft": {
|
||||
"x": 404.4,
|
||||
"y": 545.8
|
||||
},
|
||||
"width": 27.1,
|
||||
"height": -9.1,
|
||||
"page": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user