Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import org.eclipse.set.application.cacheservice.CacheServiceImpl;
import org.eclipse.set.basis.constants.ContainerType;
import org.eclipse.set.basis.files.ToolboxFileRole;
import org.eclipse.set.basis.graph.TopPath;
import org.eclipse.set.basis.graph.TopPoint;
import org.eclipse.set.core.services.Services;
import org.eclipse.set.core.services.cache.CacheService;
Expand Down Expand Up @@ -127,7 +128,40 @@ void testFindShortedDistanceInDirection() throws Exception {
true);
// It given't relevant path from 60AA -> 60P1
assertFalse(testDistance3.isPresent());
}
}

@Test
void testFindShortesRelevantPath() throws Exception {
try (MockedStatic<Services> mockServices = Mockito
.mockStatic(Services.class)) {
setupTest(mockServices);
// 60L107X -> 60L106X
// it give no relevant path from 60L107X to 60L106X
final Optional<TopPath> testPath1 = testee
.findTopologicalShortesPath(
getTopPoint("2B347074-8B80-48F8-960D-DF2F8DC0244F"),
getTopPoint("78BB7C0E-A90D-4A6E-9F60-0A855A010B6B") //
);

assertTrue(testPath1.isEmpty());

// 60L107X -> 60L123Y
final Optional<TopPath> testPath2 = testee
.findTopologicalShortesPath(
getTopPoint("2B347074-8B80-48F8-960D-DF2F8DC0244F"),
getTopPoint("3941E450-42FE-4F9A-9370-262C50E2BC9F") //
);

assertTrue(testPath2.isPresent());

final Optional<BigDecimal> shortestDistance = testee
.findShortestDistance(
getTopPoint("2B347074-8B80-48F8-960D-DF2F8DC0244F"),
getTopPoint("3941E450-42FE-4F9A-9370-262C50E2BC9F") //
);

assertEquals(shortestDistance.get(), testPath2.get().length());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
import org.eclipse.set.utils.graph.AsSplitTopGraph.Node;
import org.jgrapht.GraphPath;
import org.jgrapht.alg.shortestpath.DijkstraShortestPath;
import org.jgrapht.alg.shortestpath.PathValidator;
import org.jgrapht.alg.shortestpath.YenKShortestPath;
import org.jgrapht.graph.WeightedPseudograph;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
Expand All @@ -64,6 +66,11 @@ public class TopologicalGraphServiceImpl
// Tolerance value by find path with topological direction
private final int TOLERANT_DISTANCE_TO_FIND_DIRECTION_PATH = 500;

private record InputData(AsSplitTopGraph graphView, Node fromNode,
Node toNode) {

}

@Reference
EventAdmin eventAdmin;
@Reference
Expand Down Expand Up @@ -164,6 +171,43 @@ public TopPath findPathBetween(final TopPoint from, final TopPoint to,
from, to, limit, condition);
}

@Override
public Optional<TopPath> findTopologicalShortesPath(final TopPoint from,
final TopPoint to) {
if (from.equalLocation(to)) {
return Optional.of(
new TopPath(List.of(from.edge()), BigDecimal.ZERO, from));
}
final PathValidator<AsSplitTopGraph.Node, AsSplitTopGraph.Edge> validator = getTopologicalPathValidator();

final InputData inputData = getInputData(from, to, Optional.empty());

final YenKShortestPath<Node, Edge> yenKShortestPath = new YenKShortestPath<>(
inputData.graphView, validator);
final List<GraphPath<Node, Edge>> paths = yenKShortestPath
.getPaths(inputData.fromNode, inputData.toNode, 1);
return paths.stream()
.map(p -> new TopPath(p.getEdgeList()
.stream()
.map(Edge::edge)
.distinct()
.toList(), getPathWeight(p), from))
.findFirst();

}

private static PathValidator<AsSplitTopGraph.Node, AsSplitTopGraph.Edge> getTopologicalPathValidator() {
final PathValidator<AsSplitTopGraph.Node, AsSplitTopGraph.Edge> validator = (
path, edge) -> {
if (path.getEdgeList().isEmpty()) {
return true;
}
return TopKanteExtensions.isRoute(edge.edge(),
path.getEdgeList().getLast().edge());
};
return validator;
}

@Override
public Optional<BigDecimal> findShortestDistanceInDirection(
final TopPoint from, final TopPoint to,
Expand All @@ -179,18 +223,10 @@ public Optional<TopPath> findShortestPath(final TopPoint from,
return Optional.of(
new TopPath(List.of(from.edge()), BigDecimal.ZERO, from));
}
final MultiContainer_AttributeGroup container = getContainer(
from.edge());
final PlanPro_Schnittstelle planProSchnittstelle = getPlanProSchnittstelle(
container);
final AsSplitTopGraph graphView = new AsSplitTopGraph(
getTopGraphBase(planProSchnittstelle));

final Node fromNode = graphView.splitGraphAt(from);
final Node toNode = graphView.splitGraphAt(to);

final InputData inputData = getInputData(from, to, Optional.empty());
return Optional.ofNullable( //
findPathBetween(graphView, fromNode, toNode))
findPathBetween(inputData.graphView, inputData.fromNode,
inputData.toNode))
.map(p -> new TopPath(p.getEdgeList()
.stream()
.map(Edge::edge)
Expand All @@ -209,15 +245,8 @@ public Optional<TopPath> findShortestPathInDirection(final TopPoint from,
distance.abs(), distance.abs()))
: Optional.empty();
}
final MultiContainer_AttributeGroup container = getContainer(
from.edge());
final PlanPro_Schnittstelle planProSchnittstelle = getPlanProSchnittstelle(
container);
final AsSplitTopGraph graphView = new AsSplitTopGraph(
getTopGraphBase(planProSchnittstelle));
final Node fromNode = graphView.splitGraphAt(from,
Boolean.valueOf(inTopDirection));
final Node toNode = graphView.splitGraphAt(to);
final InputData inputData = getInputData(from, to,
Optional.of(Boolean.valueOf(inTopDirection)));
final Optional<BigDecimal> shortestDistance = findShortestDistance(from,
to);

Expand All @@ -226,8 +255,10 @@ public Optional<TopPath> findShortestPathInDirection(final TopPoint from,
}

final TopPath path = AsDirectedTopGraph
.getPath(AsDirectedTopGraph.asDirectedTopGraph(graphView),
fromNode, toNode,
.getPath(
AsDirectedTopGraph
.asDirectedTopGraph(inputData.graphView),
inputData.fromNode, inputData.toNode,
shortestDistance.get().intValue()
+ TOLERANT_DISTANCE_TO_FIND_DIRECTION_PATH,
topPath -> {
Expand All @@ -254,7 +285,6 @@ private static GraphPath<AsSplitTopGraph.Node, AsSplitTopGraph.Edge> findPathBet
try {
return DijkstraShortestPath.findPathBetween(graphView, fromNode,
toNode);

} catch (final IllegalArgumentException ex) {
if (ex.getMessage().equals("Negative edge weight not allowed")) { //$NON-NLS-1$
throw new IllegalArgumentException("Invalid spot location", ex); //$NON-NLS-1$
Expand All @@ -280,26 +310,20 @@ public Optional<BigDecimal> findShortestDistance(final TopPoint from,
@Override
public Optional<TopPoint> findClosestPoint(final TopPoint from,
final List<TopPoint> points, final boolean searchInTopDirection) {
final MultiContainer_AttributeGroup container = getContainer(
from.edge());
final PlanPro_Schnittstelle planProSchnittstelle = getPlanProSchnittstelle(
container);
final AsSplitTopGraph graphView = new AsSplitTopGraph(
getTopGraphBase(planProSchnittstelle));
final Node fromNode = graphView.splitGraphAt(from,
Boolean.valueOf(searchInTopDirection));
final InputData inputData = getInputData(from, null,
Optional.of(Boolean.valueOf(searchInTopDirection)));

BigDecimal minWeight = BigDecimal.valueOf(1000000);
Optional<TopPoint> minPoint = Optional.empty();
for (final TopPoint point : points) {
Node toNode = null;
try {
toNode = graphView.splitGraphAt(point);
toNode = inputData.graphView.splitGraphAt(point);
} catch (final IllegalArgumentException e) {
continue;
}
final GraphPath<Node, Edge> path = findPathBetween(graphView,
fromNode, toNode);
final GraphPath<Node, Edge> path = findPathBetween(
inputData.graphView, inputData.fromNode, toNode);
if (path == null) {
continue;
}
Expand All @@ -313,4 +337,22 @@ public Optional<TopPoint> findClosestPoint(final TopPoint from,
return minPoint;
}

private InputData getInputData(final TopPoint from, final TopPoint to,
final Optional<Boolean> inTopDirection) {
final MultiContainer_AttributeGroup container = getContainer(
from.edge());
final PlanPro_Schnittstelle planProSchnittstelle = getPlanProSchnittstelle(
container);
final AsSplitTopGraph graphView = new AsSplitTopGraph(
getTopGraphBase(planProSchnittstelle));

final Node fromNode = inTopDirection.isPresent()
? graphView.splitGraphAt(from, inTopDirection.get())
: graphView.splitGraphAt(from);
if (to == null) {
return new InputData(graphView, fromNode, null);
}
final Node toNode = graphView.splitGraphAt(to);
return new InputData(graphView, fromNode, toNode);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,4 +112,15 @@ Optional<TopPath> findShortestPathInDirection(TopPoint from, TopPoint to,
*/
Optional<TopPoint> findClosestPoint(final TopPoint from,
final List<TopPoint> points, final boolean searchInTopDirection);

/**
* Finds the shortest path, which have plausible branch
*
* @param from
* starting point to search from
* @param to
* end point
* @return the optional of {@link TopPath}
*/
Optional<TopPath> findTopologicalShortesPath(TopPoint from, TopPoint to);
}
Original file line number Diff line number Diff line change
Expand Up @@ -807,11 +807,12 @@ class SszsTransformator extends AbstractPlanPro2TableModelTransformator {
val signal = etcsSignal.IDSignal?.value
if (signal !== null && po !== null) {
val signalTopPoint = new TopPoint(signal)
val topPoint = new TopPoint(po)
val distance = topGraphService.findShortestDistance(signalTopPoint,
topPoint)
if (distance.present) {
return distance.get
val distances = po.singlePoints.map [
topGraphService.findTopologicalShortesPath(signalTopPoint,
new TopPoint(it))
].filter[isPresent].map[get.length]
if (!distances.nullOrEmpty) {
return distances.min
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,27 +216,36 @@ private static LineString blosscurve(final GEO_Kante edge,
.getWert()
.doubleValue();
if (radiusA != 0 && radiusB != 0) {
// Bloss curve connecting two straight tracks
logger.warn("Form Bloss between straight tracks not supported."); //$NON-NLS-1$
return getGeometryFactory().createLineString(getCoordinates(edge));
// Bloss curve connecting two curve tracks
// logger.warn("Form Bloss between straight tracks not supported.");
// //$NON-NLS-1$
final Bloss bloss = new Bloss(radiusA, radiusB, length,
geometryOptions.precision());

return blosscurve(bloss, coordinateA, coordinateB, radiusA, length,
geometryOptions);
} else if (radiusA == 0) {
// Curve from node B to node A
return blosscurve(coordinateB, coordinateA, radiusB, length,
final Bloss bloss = new Bloss(Math.abs(radiusB), length,
geometryOptions.precision());
return blosscurve(bloss, coordinateB, coordinateA, radiusB, length,
geometryOptions);
}
// Curve from node A to node B
// Invert the radius, as left-right is also inverted due to the
// drawing direction
return blosscurve(coordinateA, coordinateB, -radiusA, length,
final Bloss bloss = new Bloss(Math.abs(radiusA), length,
geometryOptions.precision());
return blosscurve(bloss, coordinateA, coordinateB, -radiusA, length,
geometryOptions);

}

private static LineString blosscurve(final Coordinate fromCoordinate,
final Coordinate toCoordinate, final double radius,
final double length, final GeometryOptions geometryOptions) {
final Bloss bloss = new Bloss(Math.abs(radius), length,
geometryOptions.precision());
private static LineString blosscurve(final Bloss bloss,
final Coordinate fromCoordinate, final Coordinate toCoordinate,
final double radiusA, final double length,
final GeometryOptions geometryOptions) {

final int segmentCount = (int) Math.max(
length / geometryOptions.stepSize(),
geometryOptions.minSegmentCount());
Expand All @@ -245,7 +254,7 @@ private static LineString blosscurve(final Coordinate fromCoordinate,
.map(coor -> {
final Coordinate coordinate = new Coordinate(coor[0],
coor[1], 0);
return radius < 0 ? mirrorY(coordinate) : coordinate;
return radiusA < 0 ? mirrorY(coordinate) : coordinate;
})
.toList();

Expand Down
Loading
Loading