From 70e8250f1ab5597347b043a7cbae1658f00d54b3 Mon Sep 17 00:00:00 2001 From: nicolas-f Date: Tue, 8 Oct 2024 15:20:41 +0200 Subject: [PATCH] fix image source fetching --- .../pathfinder/MirrorReceiverResult.java | 17 +++ .../pathfinder/MirrorReceiverResultIndex.java | 20 ++- .../pathfinder/TestWallReflection.java | 115 +++++++----------- 3 files changed, 75 insertions(+), 77 deletions(-) diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/MirrorReceiverResult.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/MirrorReceiverResult.java index b0c9f6d97..5f4ce87d2 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/MirrorReceiverResult.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/MirrorReceiverResult.java @@ -34,6 +34,7 @@ package org.noise_planet.noisemodelling.pathfinder; import org.locationtech.jts.geom.Coordinate; +import org.locationtech.jts.geom.Polygon; import java.util.Objects; @@ -48,6 +49,10 @@ public class MirrorReceiverResult { private final ProfileBuilder.Wall wall; private final int buildingId; // building that belongs to this wall private final ProfileBuilder.IntersectionType type; + /** + * This data is not stored in the RTREE as it is not used after the creation of the index + */ + Polygon imageReceiverVisibilityCone; /** * @return coordinate of mirrored receiver @@ -60,6 +65,10 @@ public void setReceiverPos(Coordinate receiverPos) { this.receiverPos = receiverPos; } + public MirrorReceiverResult copyWithoutCone() { + return new MirrorReceiverResult(receiverPos, parentMirror == null ? null : parentMirror.copyWithoutCone(), + wall, buildingId, type); + } /** * @return Other MirrorReceiverResult index, -1 for the first reflexion */ @@ -95,6 +104,14 @@ public MirrorReceiverResult(Coordinate receiverPos, MirrorReceiverResult parentM this.type = type; } + public Polygon getImageReceiverVisibilityCone() { + return imageReceiverVisibilityCone; + } + + public void setImageReceiverVisibilityCone(Polygon imageReceiverVisibilityCone) { + this.imageReceiverVisibilityCone = imageReceiverVisibilityCone; + } + /** * Copy constructor * @param cpy ref diff --git a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/MirrorReceiverResultIndex.java b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/MirrorReceiverResultIndex.java index 0768a7a27..9d5484a16 100644 --- a/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/MirrorReceiverResultIndex.java +++ b/noisemodelling-pathfinder/src/main/java/org/noise_planet/noisemodelling/pathfinder/MirrorReceiverResultIndex.java @@ -119,6 +119,7 @@ public static Polygon createWallReflectionVisibilityCone(Coordinate receiverImag public MirrorReceiverResultIndex(List buildWalls, Coordinate receiverCoordinates, int reflectionOrder, double maximumPropagationDistance, double maximumDistanceFromWall) { + GeometryFactory gf = new GeometryFactory(); this.receiverCoordinate = receiverCoordinates; this.buildWalls = buildWalls; this.maximumDistanceFromWall = maximumDistanceFromWall; @@ -132,6 +133,13 @@ public MirrorReceiverResultIndex(List buildWalls, Coordinat ArrayList nextParentsToProcess = new ArrayList<>(); for(MirrorReceiverResult parent : parentsToProcess) { for (ProfileBuilder.Wall wall : buildWalls) { + if(parent != null) { + // check if the wall is visible from the previous image receiver + if(!parent.getImageReceiverVisibilityCone().intersects( + wall.getLineSegment().toGeometry(new GeometryFactory()))) { + continue; // this wall is out of the bound of the receiver visibility + } + } Coordinate receiverImage; if (parent != null) { if(wall == parent.getWall()) { @@ -150,13 +158,14 @@ public MirrorReceiverResultIndex(List buildWalls, Coordinat // wall is too far from the receiver image, there is no receiver image continue; } - MirrorReceiverResult receiverResult = new MirrorReceiverResult(rcvMirror, parent, wall, - wall.getOriginId(), wall.getType()); // create the visibility cone of this receiver image Polygon imageReceiverVisibilityCone = createWallReflectionVisibilityCone(rcvMirror, wall.getLineSegment(), maximumPropagationDistance, maximumDistanceFromWall); - mirrorReceiverTree.insert(imageReceiverVisibilityCone.getEnvelopeInternal(), receiverResult); - nextParentsToProcess.add(receiverResult); + MirrorReceiverResult receiverResultNext = new MirrorReceiverResult(rcvMirror, parent, wall, + wall.getOriginId(), wall.getType()); + receiverResultNext.setImageReceiverVisibilityCone(imageReceiverVisibilityCone); + mirrorReceiverTree.insert(imageReceiverVisibilityCone.getEnvelopeInternal(),receiverResultNext.copyWithoutCone()); + nextParentsToProcess.add(receiverResultNext); numberOfImageReceivers++; if(numberOfImageReceivers >= mirrorReceiverCapacity) { return; @@ -294,6 +303,9 @@ public void visitItem(Object item) { if(!li.hasIntersection()) { // No reflection on this wall return; + } else{ + // update reflection point for inferior reflection order + reflectionPoint = li.getIntersection(0); } currentReceiverImage = currentReceiverImage.getParentMirror(); } diff --git a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestWallReflection.java b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestWallReflection.java index 42a76accb..394fba009 100644 --- a/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestWallReflection.java +++ b/noisemodelling-pathfinder/src/test/java/org/noise_planet/noisemodelling/pathfinder/TestWallReflection.java @@ -49,10 +49,7 @@ import java.io.*; import java.sql.ResultSet; import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.util.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; @@ -127,84 +124,56 @@ public void testNReflexion() throws ParseException, IOException, SQLException { MirrorReceiverResultIndex receiverMirrorIndex = new MirrorReceiverResultIndex(buildWalls, receiver, inputData.reflexionOrder, inputData.maxSrcDist, inputData.maxRefDist); - //Keep only mirror receivers potentially visible from the source - List mirrorResults = receiverMirrorIndex.findCloseMirrorReceivers( - inputData.sourceGeometries.get(0).getCoordinate()); -// var lst = receiverMirrorIndex.mirrorReceiverTree.query(new Envelope(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, -// Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)); -// for(var item : lst) { -// if(item instanceof MirrorReceiverResult) { -// mirrorResults.add((MirrorReceiverResult) item); -// } -// } List propagationPaths = computeRays.computeReflexion(receiver, inputData.sourceGeometries.get(0).getCoordinate(), false, new Orientation(), receiverMirrorIndex); + // Only one second order reflexion propagation path must be found + assertEquals(1, propagationPaths.size()); - try { - try (FileWriter fileWriter = new FileWriter("target/testVisibilityCone.csv")) { - StringBuilder sb = new StringBuilder(); - receiverMirrorIndex.exportVisibility(sb, inputData.maxSrcDist, inputData.maxRefDist, - 0, mirrorResults, true); - fileWriter.write(sb.toString()); - } - } catch (IOException ex) { - //ignore - } - assertEquals(16, mirrorResults.size()); - assertEquals(16, propagationPaths.size()); +// int idPath = 1; +// for(PropagationPath path : propagationPaths) { +// try { +// try (FileWriter fileWriter = new FileWriter(String.format(Locale.ROOT, "target/testVisibilityPath_%03d.geojson", idPath))) { +// fileWriter.write(path.asGeom())); +// } +// } catch (IOException ex) { +// //ignore +// } +// idPath++; +// } + + // Keep only mirror receivers potentially visible from the source + List mirrorResults = receiverMirrorIndex.findCloseMirrorReceivers(inputData. + sourceGeometries.get(0).getCoordinate()); + assertEquals(18, mirrorResults.size()); + + // // Or Take all reflections + // List mirrorResults = new ArrayList<>(); + // var lst = receiverMirrorIndex.mirrorReceiverTree.query(new Envelope(Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY, + // Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY)); + // for(var item : lst) { + // if(item instanceof MirrorReceiverResult) { + // mirrorResults.add((MirrorReceiverResult) item); + // } + // } + // try { + // try (FileWriter fileWriter = new FileWriter("target/testVisibilityCone.csv")) { + // StringBuilder sb = new StringBuilder(); + // receiverMirrorIndex.exportVisibility(sb, inputData.maxSrcDist, inputData.maxRefDist, + // 0, mirrorResults, true); + // fileWriter.write(sb.toString()); + // } + // } catch (IOException ex) { + // //ignore + // } + // - } -// @Test -// public void testExportVisibilityCones() throws Exception { -// double maxPropagationDistance = 30; -// double maxPropagationDistanceFromWall = 9999; -// int reflectionOrder = 4; -// -// List buildWalls = new ArrayList<>(); -// Coordinate cA = new Coordinate(1, 1, 5); -// Coordinate cB = new Coordinate(1, 8, 5); -// Coordinate cC = new Coordinate(8, 8, 5); -// Coordinate cD = new Coordinate(8, 5, 5); -// Coordinate cE = new Coordinate(5, 5, 5); -// Coordinate cF = new Coordinate(5, 1, 5); -// Coordinate cG = new Coordinate(10, -5, 2.5); -// Coordinate cH = new Coordinate(13, 8, 2.5); -// Coordinate cI = new Coordinate(8, 9, 2.5); -// Coordinate cJ = new Coordinate(12, 8, 2.5); -// buildWalls.add(new ProfileBuilder.Wall(cE, cF, 0, ProfileBuilder.IntersectionType.WALL)); -// buildWalls.add(new ProfileBuilder.Wall(cG, cH, 2, ProfileBuilder.IntersectionType.WALL)); -// buildWalls.add(new ProfileBuilder.Wall(cI, cJ, 2, ProfileBuilder.IntersectionType.WALL)); -// -// -// GeometryFactory factory = new GeometryFactory(); -// List pts = new ArrayList<>(); -// LineString pathReceiver = factory.createLineString(new Coordinate[] { -// new Coordinate(5, -1, 0.1), -// new Coordinate(7.8, 1.62, 0.1), -// new Coordinate(8.06, 6.01, 0.1), -// new Coordinate(4.73, 9.95) -// }); -// -// ComputeCnossosRays.splitLineStringIntoPoints(pathReceiver, 0.5 ,pts); -// -// WKTWriter wktWriter = new WKTWriter(); -// try(FileWriter fileWriter = new FileWriter("target/testVisibilityCone.csv")) { -// fileWriter.write("geom, type, time\n"); -// int t = 0; -// for (Coordinate receiverCoordinates : pts) { -// MirrorReceiverResultIndex mirrorReceiverResultIndex = new MirrorReceiverResultIndex(buildWalls, receiverCoordinates, reflectionOrder, maxPropagationDistance, maxPropagationDistanceFromWall); -// StringBuilder sb = new StringBuilder(); -// mirrorReceiverResultIndex.exportVisibility(sb, maxPropagationDistance, maxPropagationDistanceFromWall, t); -// fileWriter.write(sb.toString()); -// t+=1; -// } -// } -// } + + } }