Skip to content

Commit

Permalink
#368 migrate structure tests
Browse files Browse the repository at this point in the history
  • Loading branch information
vmarc committed Jul 12, 2024
1 parent f19bef1 commit e7c5362
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 41 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,6 @@ class RouteLinksReport(context: RouteDetailAnalysisContext) {

private def networkNodeStrings(nodeIds: Seq[Long], nodeType: String, routeNodeDatas: Seq[RouteNodeData]): Seq[String] = {
val routeNodeDatasInFragment = routeNodeDatas.filter(n => nodeIds.contains(n.node.id))
routeNodeDatasInFragment.map(routeNodeData => s"$nodeType=${routeNodeData.name}(${routeNodeData.node.id})")
routeNodeDatasInFragment.map(routeNodeData => s"$nodeType=${routeNodeData.node.id}(${routeNodeData.name})")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class RoutePathReport(context: RouteDetailAnalysisContext) {
context.paths.map { path =>
val fromNode = path.elements.head.fromNetworkNode
val toNode = path.elements.last.toNetworkNode
val from = fromNode.map(n => s"${n.name}(${ReportUtil.osmNodeLink(n.node.id)})").getOrElse("")
val to = toNode.map(n => s"${n.name}(${ReportUtil.osmNodeLink(n.node.id)})").getOrElse("")
val from = fromNode.map(n => s"${ReportUtil.osmNodeLink(n.node.id)}(${n.name})").getOrElse("")
val to = toNode.map(n => s"${ReportUtil.osmNodeLink(n.node.id)}(${n.name})").getOrElse("")
val elementIds = path.elements.map(element => element.id).mkString(", ")

s"""<tr>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ class RouteSegmentReport(context: RouteDetailAnalysisContext) {

private def segmentElements(segment: NewRouteSegment): String = {
segment.elements.map { element =>
val from = element.fromNetworkNode.map(node => s"from=${node.name}(${ReportUtil.osmNodeLink(node.node.id)})").getOrElse("")
val to = element.toNetworkNode.map(node => s"to=${node.name}(${ReportUtil.osmNodeLink(node.node.id)})").getOrElse("")
val from = element.fromNetworkNode.map(node => s"from=${ReportUtil.osmNodeLink(node.node.id)}(${node.name})").getOrElse("")
val to = element.toNetworkNode.map(node => s"to=${ReportUtil.osmNodeLink(node.node.id)}(${node.name})").getOrElse("")
s"""<tr>
| <td colspan="5">
| Segment element ${element.id} ${element.direction.toString.toLowerCase} $from $to
Expand Down Expand Up @@ -135,6 +135,6 @@ class RouteSegmentReport(context: RouteDetailAnalysisContext) {

private def networkNodeStrings(nodeIds: Seq[Long], nodeType: String, routeNodeDatas: Seq[RouteNodeData]): Seq[String] = {
val routeNodeDatasInFragment = routeNodeDatas.filter(n => nodeIds.contains(n.node.id))
routeNodeDatasInFragment.map(routeNodeData => s"$nodeType=${routeNodeData.name}(${routeNodeData.node.id})")
routeNodeDatasInFragment.map(routeNodeData => s"$nodeType=${routeNodeData.node.id}(${routeNodeData.name})")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package kpn.server.analyzer.engine.analysis.route.structure
import kpn.server.analyzer.engine.analysis.route.RouteNodeAnalysis
import kpn.server.analyzer.engine.analysis.route.RouteNodeData

import scala.annotation.tailrec

class StructureAnalyzer(traceEnabled: Boolean = false) {

def analyze(
Expand Down Expand Up @@ -70,40 +72,59 @@ class StructureAnalyzer(traceEnabled: Boolean = false) {
): Option[Structure] = {

val forwardPath: Option[StructurePath] = {
paths.find(_.fromNodeId == mainStartNode.node.id) match {
case None => None
case Some(firstForwardPath) =>
val index = paths.indexWhere(_.fromNodeId == mainStartNode.node.id)
if (index < 0) {
None
}
else {
val firstForwardPath = paths(index)
val element = StructurePathElement(
firstForwardPath,
reversed = false
)
val remainingPaths = paths.drop(index + 1)
val elements = findForwardPath(Seq(element), remainingPaths, mainEndNode.node.id)
if (elements.nonEmpty) {
Some(
StructurePath(
mainStartNode.node.id,
mainEndNode.node.id,
Seq(
StructurePathElement(
firstForwardPath,
reversed = false
)
)
elements
)
)
}
else {
None
}
}
}

val backwardPath: Option[StructurePath] = {
paths.find(_.toNodeId == mainEndNode.node.id) match {
case None => None
case Some(lastBackwardPath) =>
val index = paths.indexWhere(_.toNodeId == mainEndNode.node.id)
if (index < 0) {
None
}
else {
val lastBackwardPath = paths(index)
val remainingPaths = paths.take(index).reverse
val reversed = lastBackwardPath.direction == RoutePathDirection.Bidirectional
val element = StructurePathElement(
lastBackwardPath,
reversed
)
val elements = findBackwardPath(Seq(element), remainingPaths, mainStartNode.node.id)
if (elements.nonEmpty) {
Some(
StructurePath(
mainStartNode.node.id,
mainEndNode.node.id,
Seq(
StructurePathElement(
lastBackwardPath,
reversed = true
)
)
elements.reverse
)
)
}
else {
None
}
}
}

Expand Down Expand Up @@ -419,4 +440,63 @@ class StructureAnalyzer(traceEnabled: Boolean = false) {
// a.endNodeId == b.startNodeId
// }
// }

@tailrec
private def findForwardPath(pathElements: Seq[StructurePathElement], paths: Seq[RoutePath], endNodeId: Long): Seq[StructurePathElement] = {
val lastEndNodeId = pathElements.last.endNodeId
if (lastEndNodeId == endNodeId) {
pathElements // found end of forward path
}
else if (paths.isEmpty) {
Seq.empty // could not find forward path to end node
}
else {
paths.find { path =>
(path.direction == RoutePathDirection.Bidirectional || path.direction == RoutePathDirection.Forward) &&
path.fromNodeId == lastEndNodeId
} match {
case None => Seq.empty // could not find forward path to end node
case Some(nextForwardPath) =>
val remainingPaths = paths.filterNot(p => p.id == nextForwardPath.id)
val element = StructurePathElement(
nextForwardPath,
reversed = false
)
findForwardPath(pathElements :+ element, remainingPaths, endNodeId)
}
}
}

@tailrec
private def findBackwardPath(pathElements: Seq[StructurePathElement], paths: Seq[RoutePath], startNodeId: Long): Seq[StructurePathElement] = {
val lastStartNodeId = pathElements.last.endNodeId
if (lastStartNodeId == startNodeId) {
pathElements // found start of backward path
}
else if (paths.isEmpty) {
Seq.empty // could not find backward path to start node
}
else {
paths.find { path =>
if (path.direction == RoutePathDirection.Bidirectional) {
path.toNodeId == lastStartNodeId
} else if (path.direction == RoutePathDirection.Backward) {
path.fromNodeId == lastStartNodeId
}
else {
false
}
} match {
case None => Seq.empty // could not find forward path to end node
case Some(nextBackwardPath) =>
val remainingPaths = paths.filterNot(p => p.id == nextBackwardPath.id)
val reversed = nextBackwardPath.direction == RoutePathDirection.Bidirectional
val element = StructurePathElement(
nextBackwardPath,
reversed = reversed
)
findBackwardPath(pathElements :+ element, remainingPaths, startNodeId)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -93,21 +93,12 @@ class Structure_N09_Test extends UnitTest {
)
)

/*
startNode(1)
endNode(10)
forward(1, 2, 3, 4, 5, 6, 9, 10)
backward(10, 9, 6, 8, 7, 3, 2, 1)
*/
pending
context.pathDetails.shouldMatchTo(
Seq(
"forward=1>10 nodes=1, 2, 3", // TODO nok
"backward=1>10 nodes=10, 9, 6",
"other=3>6 nodes=3, 4, 5, 6",
"other=6>3 nodes=3, 7, 8, 6",
"forward=1>10 nodes=1, 2, 3, 4, 5, 6, 9, 10",
"backward=10>1 nodes=10, 9, 6, 8, 7, 3, 2, 1",
)
)
pending
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class Structure_N10_Test extends UnitTest {
)
)

pending
context.pathDetails.shouldMatchTo(
Seq(
"forward=1>10 nodes=1, 2, 3", // TODO forward(1, 2, 3, 4, 5, 6, 9, 10)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,12 @@ class Structure_N11_Test extends UnitTest {
)
)

pending
context.pathDetails.shouldMatchTo(
Seq(
"forward=1>10 nodes=1, 2, 4", // TODO forward(1, 2, 4, 5, 6, 7, 9, 10)
"backward=1>10 nodes=10, 9, 7", // TODO backward(10, 9, 7, 8, 3, 4, 2, 1)
"other=4>7 nodes=4, 5, 6, 7",
"other=7>4 nodes=4, 3, 8, 7",
"forward=1>10 nodes=1, 2, 4, 5, 6, 7, 9, 10", // TODO forward(1, 2, 4, 5, 6, 7, 9, 10)
"backward=10>1 nodes=10, 9, 7, 8, 3, 4, 2, 1", // TODO backward(10, 9, 7, 8, 3, 4, 2, 1)
)
)
pending
}
}

0 comments on commit e7c5362

Please sign in to comment.