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.ImportedRedaction;
|
||||||
import com.iqser.red.service.redaction.v1.model.ImportedRedactions;
|
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.Rectangle;
|
||||||
import com.iqser.red.service.redaction.v1.model.RedactionLogEntry;
|
import com.iqser.red.service.redaction.v1.model.RedactionLogEntry;
|
||||||
import com.iqser.red.service.redaction.v1.server.storage.RedactionStorageService;
|
import com.iqser.red.service.redaction.v1.server.storage.RedactionStorageService;
|
||||||
@ -70,12 +71,13 @@ public class ImportedRedactionService {
|
|||||||
private void addIntersections(RedactionLogEntry redactionLogEntry, ImportedRedactions importedRedactions) {
|
private void addIntersections(RedactionLogEntry redactionLogEntry, ImportedRedactions importedRedactions) {
|
||||||
|
|
||||||
for (Rectangle rectangle : redactionLogEntry.getPositions()) {
|
for (Rectangle rectangle : redactionLogEntry.getPositions()) {
|
||||||
|
var normalizedRectangle = normalize(rectangle);
|
||||||
if (importedRedactions.getImportedRedactions().containsKey(rectangle.getPage())) {
|
if (importedRedactions.getImportedRedactions().containsKey(rectangle.getPage())) {
|
||||||
var importedRedactionsOnPage = importedRedactions.getImportedRedactions().get(rectangle.getPage());
|
var importedRedactionsOnPage = importedRedactions.getImportedRedactions().get(rectangle.getPage());
|
||||||
for (ImportedRedaction importedRedaction : importedRedactionsOnPage) {
|
for (ImportedRedaction importedRedaction : importedRedactionsOnPage) {
|
||||||
for (Rectangle importedRedactionPosition : importedRedaction.getPositions()) {
|
for (Rectangle importedRedactionPosition : importedRedaction.getPositions()) {
|
||||||
if (intersects(importedRedactionPosition, rectangle)) {
|
if (rectOverlap(normalizedRectangle, normalize(importedRedactionPosition))) {
|
||||||
if(redactionLogEntry.getImportedRedactionIntersections() == null){
|
if (redactionLogEntry.getImportedRedactionIntersections() == null) {
|
||||||
redactionLogEntry.setImportedRedactionIntersections(new HashSet<>());
|
redactionLogEntry.setImportedRedactionIntersections(new HashSet<>());
|
||||||
}
|
}
|
||||||
redactionLogEntry.getImportedRedactionIntersections().add(importedRedaction.getId());
|
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()
|
return round(value) >= round(min) && round(value) <= round(max);
|
||||||
.getX() + redactionLogPosition.getWidth() > importedPosition.getTopLeft()
|
}
|
||||||
.getX() && redactionLogPosition.getTopLeft()
|
|
||||||
.getY() + redactionLogPosition.getHeight() > importedPosition.getTopLeft()
|
|
||||||
.getY() && redactionLogPosition.getTopLeft().getX() < importedPosition.getTopLeft()
|
boolean rectOverlap(Rectangle a, Rectangle b) {
|
||||||
.getX() + importedPosition.getWidth() && redactionLogPosition.getTopLeft()
|
|
||||||
.getY() < importedPosition.getTopLeft().getY() + importedPosition.getHeight();
|
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(LOGO, "#ffe187");
|
||||||
typeColorMap.put(FORMULA, "#ffe187");
|
typeColorMap.put(FORMULA, "#ffe187");
|
||||||
typeColorMap.put(SIGNATURE, "#ffe187");
|
typeColorMap.put(SIGNATURE, "#ffe187");
|
||||||
typeColorMap.put(IMPORTED_REDACTION, "#32a852");
|
typeColorMap.put(IMPORTED_REDACTION, "#fcfbe6");
|
||||||
|
|
||||||
hintTypeMap.put(VERTEBRATE, true);
|
hintTypeMap.put(VERTEBRATE, true);
|
||||||
hintTypeMap.put(ADDRESS, false);
|
hintTypeMap.put(ADDRESS, false);
|
||||||
@ -1668,8 +1668,8 @@ public class RedactionIntegrationTest {
|
|||||||
public void testImportedRedactions() throws IOException {
|
public void testImportedRedactions() throws IOException {
|
||||||
|
|
||||||
String outputFileName = OsUtils.getTemporaryDirectory() + "/Annotated.pdf";
|
String outputFileName = OsUtils.getTemporaryDirectory() + "/Annotated.pdf";
|
||||||
ClassPathResource pdfFileResource = new ClassPathResource("files/ImportedRedactions/ImportedRedactions.pdf");
|
ClassPathResource pdfFileResource = new ClassPathResource("files/ImportedRedactions/RotateTestFile_without_highlights.pdf");
|
||||||
ClassPathResource importedRedactions = new ClassPathResource("files/ImportedRedactions/ImportedRedactions.json");
|
ClassPathResource importedRedactions = new ClassPathResource("files/ImportedRedactions/RotateTestFile_without_highlights.IMPORTED_REDACTIONS.json");
|
||||||
|
|
||||||
AnalyzeRequest request = prepareStorage(pdfFileResource.getInputStream());
|
AnalyzeRequest request = prepareStorage(pdfFileResource.getInputStream());
|
||||||
storageService.storeObject(RedactionStorageService.StorageIdUtils.getStorageId(TEST_DOSSIER_ID, TEST_FILE_ID, FileType.IMPORTED_REDACTIONS), IOUtils.toByteArray(importedRedactions.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)
|
.fileId(TEST_FILE_ID)
|
||||||
.build());
|
.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)) {
|
try (FileOutputStream fileOutputStream = new FileOutputStream(outputFileName)) {
|
||||||
fileOutputStream.write(annotateResponse.getDocument());
|
fileOutputStream.write(annotateResponse.getDocument());
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,5 +11,5 @@ Sude Halide Nurullah
|
|||||||
Xinyi Y. Tao
|
Xinyi Y. Tao
|
||||||
Dorn
|
Dorn
|
||||||
Prasher
|
Prasher
|
||||||
RuleAnnotation270GradP
|
David
|
||||||
RuleAnnotation270GradLS
|
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