diff --git a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/redaction/service/ImportedRedactionService.java b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/redaction/service/ImportedRedactionService.java index 358c9ce8..098626a6 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/redaction/service/ImportedRedactionService.java +++ b/redaction-service-v1/redaction-service-server-v1/src/main/java/com/iqser/red/service/redaction/v1/server/redaction/service/ImportedRedactionService.java @@ -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); } 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 54962f1e..bd1029ac 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 @@ -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()); } diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/resources/dictionaries/PII.txt b/redaction-service-v1/redaction-service-server-v1/src/test/resources/dictionaries/PII.txt index e278ccaf..d3d1ad7d 100644 --- a/redaction-service-v1/redaction-service-server-v1/src/test/resources/dictionaries/PII.txt +++ b/redaction-service-v1/redaction-service-server-v1/src/test/resources/dictionaries/PII.txt @@ -11,5 +11,5 @@ Sude Halide Nurullah Xinyi Y. Tao Dorn Prasher -RuleAnnotation270GradP -RuleAnnotation270GradLS \ No newline at end of file +David +annotation \ No newline at end of file diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/ImportedRedactions.json b/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/ImportedRedactions.json deleted file mode 100644 index c1289bff..00000000 --- a/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/ImportedRedactions.json +++ /dev/null @@ -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}]}]}} \ No newline at end of file diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/ImportedRedactions.pdf b/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/ImportedRedactions.pdf deleted file mode 100644 index 43afe3eb..00000000 Binary files a/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/ImportedRedactions.pdf and /dev/null differ diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/RotateTestFile_without_highlights.IMPORTED_REDACTIONS.json b/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/RotateTestFile_without_highlights.IMPORTED_REDACTIONS.json new file mode 100644 index 00000000..9e6e8911 --- /dev/null +++ b/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/RotateTestFile_without_highlights.IMPORTED_REDACTIONS.json @@ -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 + } + ] + } + ] + } +} \ No newline at end of file diff --git a/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/RotateTestFile_without_highlights.pdf b/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/RotateTestFile_without_highlights.pdf new file mode 100644 index 00000000..572b6c65 Binary files /dev/null and b/redaction-service-v1/redaction-service-server-v1/src/test/resources/files/ImportedRedactions/RotateTestFile_without_highlights.pdf differ