-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#368 improve RouteAnalysisContext report
- Loading branch information
Showing
8 changed files
with
331 additions
and
199 deletions.
There are no files selected for viewing
255 changes: 59 additions & 196 deletions
255
...cala/kpn/server/analyzer/engine/analysis/route/analyzers/RouteAnalysisContextReport.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,213 +1,76 @@ | ||
package kpn.server.analyzer.engine.analysis.route.analyzers | ||
|
||
import kpn.core.analysis.RouteMember | ||
import kpn.core.tools.config.Dirs | ||
import kpn.server.analyzer.engine.analysis.route.RouteSegmentData | ||
import kpn.server.analyzer.engine.analysis.route.domain.RouteAnalysisContext | ||
import kpn.server.analyzer.engine.analysis.route.structure.Structure | ||
import kpn.server.analyzer.engine.analysis.route.structure.StructureElementGroup | ||
import kpn.server.analyzer.engine.analysis.route.structure.StructurePath | ||
import kpn.server.analyzer.engine.analysis.route.report.RouteFactsReport | ||
import kpn.server.analyzer.engine.analysis.route.report.RouteMembersReport | ||
import kpn.server.analyzer.engine.analysis.route.report.RouteSegmentsReport | ||
import kpn.server.analyzer.engine.analysis.route.report.RouteSummaryReport | ||
import kpn.server.analyzer.engine.analysis.route.report.StructureElementGroupsReport | ||
import kpn.server.analyzer.engine.analysis.route.report.StructureReport | ||
|
||
import java.io.File | ||
import java.io.PrintWriter | ||
|
||
object RouteAnalysisContextReport { | ||
def report(context: RouteAnalysisContext): Unit = { | ||
new RouteAnalysisContextReport(context).report() | ||
} | ||
} | ||
|
||
class RouteAnalysisContextReport(context: RouteAnalysisContext) { | ||
|
||
private val out = { | ||
val dir = new File(Dirs.root, "routes") | ||
dir.mkdirs | ||
new PrintWriter(new File(dir, s"/${context.relation.id}.html")) | ||
} | ||
|
||
def report(): Unit = { | ||
reportStart() | ||
printSummary() | ||
printFacts() | ||
reportRouteMembers() | ||
context.segmentAnalysis.foreach { segmentAnalysis => | ||
printElementGroups(segmentAnalysis.elementGroups) | ||
printRouteSegments(segmentAnalysis.routeSegments) | ||
printStructure(segmentAnalysis.structure) | ||
val out = { | ||
val dir = new File(Dirs.root, "routes") | ||
dir.mkdirs | ||
new PrintWriter(new File(dir, s"/${context.relation.id}.html")) | ||
} | ||
reportEnd() | ||
} | ||
|
||
private def reportStart(): Unit = { | ||
out.println("<html>") | ||
|
||
out.println("<head>") | ||
out.println(""" <meta http-equiv="content-type" content="text/html; charset=UTF-8">""") | ||
out.println(""" <link href="styles.css" rel="stylesheet" type="text/css">""") | ||
out.println(s" <title>${context.relation.id} route</title>") | ||
out.println(" <style>") | ||
out.println(" body {") | ||
out.println(" font-family: monospace;") | ||
out.println(" }") | ||
out.println(" table {") | ||
out.println(" margin: 30;") | ||
out.println(" }") | ||
out.println(" table, th, td {") | ||
out.println(" border: 1px solid gray;") | ||
out.println(" border-collapse: collapse;") | ||
out.println(" }") | ||
out.println(" td {") | ||
out.println(" padding: .5em;") | ||
out.println(" }") | ||
out.println(" ") | ||
out.println(" </style>") | ||
out.println("</head>") | ||
|
||
out.println("<body>") | ||
} | ||
|
||
private def reportEnd(): Unit = { | ||
out.println("</body>") | ||
out.println("</html>") | ||
out.println(new RouteAnalysisContextReport(context).report()) | ||
out.close() | ||
} | ||
} | ||
|
||
private def printSummary(): Unit = { | ||
out.println("<table>") | ||
row("name", context.routeNameAnalysis.flatMap(_.name).getOrElse("?")) | ||
row("nodeNetwork", yes(context.nodeNetwork)) | ||
row("superRoute", yes(context.superRoute)) | ||
row("proposed", yes(context.proposed)) | ||
row("networkType", s"""${context.networkType.map(_.name).getOrElse("")}""") | ||
row("scopedNetworkType", s"""${context.scopedNetworkTypeOption.map(_.key).getOrElse("")}""") | ||
row("country", s"""${context.country.map(_.domain).getOrElse("")}""") | ||
row("unexpectedNodeIds", context.unexpectedNodeIds.toSeq.flatten.mkString(", ")) | ||
row("unexpectedRelationIds", context.unexpectedRelationIds.toSeq.flatten.mkString(", ")) | ||
out.println("</table>") | ||
|
||
context.routeNodeInfos.foreach { routeNodeInfo => | ||
/* | ||
node: Node, | ||
name: String, | ||
longName: Option[String] | ||
*/ | ||
} | ||
} | ||
|
||
private def row(key: String, value: String): Unit = { | ||
out.println(s"<tr><td>$key</td><td>$value</td></tr>") | ||
} | ||
|
||
private def reportRouteMembers(): Unit = { | ||
out.println("""<table>""") | ||
reportRouteMembersHeader() | ||
context.routeMembers.get.zipWithIndex.foreach { case (routeMember, index) => | ||
reportRouteMember(routeMember, index) | ||
} | ||
out.println("</table>") | ||
} | ||
|
||
private def reportRouteMembersHeader(): Unit = { | ||
out.println("<tr>") | ||
out.println("<td>nr</td>") | ||
out.println("<td></td>") | ||
out.println("<td>link</td>") | ||
out.println("<td>id</td>") | ||
out.println("<td>name</td>") | ||
out.println("<td>role</td>") | ||
out.println("<td>accessible</td>") | ||
out.println("</tr>") | ||
} | ||
|
||
private def reportRouteMember(routeMember: RouteMember, index: Int): Unit = { | ||
out.println("<tr>") | ||
out.println("<td>") | ||
out.println(s"""${index + 1}""") | ||
out.println("</td>") | ||
out.println("""<td style="padding:0">""") | ||
out.println(s"""<img src="images/${routeMember.linkName}.png"/>""") | ||
out.println("</td>") | ||
out.println("<td>") | ||
out.println("<pre>" + routeMember.link.map(_.reportString).getOrElse("") + "</pre>") | ||
out.println("</td>") | ||
out.println("<td>") | ||
out.println(s"""<a href="https://www.openstreetmap.org/${routeMember.memberType}/${routeMember.id}">${routeMember.id}</a>""") | ||
out.println("</td>") | ||
out.println("<td>") | ||
out.println(routeMember.name) | ||
out.println("</td>") | ||
out.println("<td>") | ||
out.println(routeMember.role.getOrElse("")) | ||
out.println("</td>") | ||
out.println("<td>") | ||
out.println(if (routeMember.accessible) "" else "no") | ||
out.println("</td>") | ||
out.println("</tr>") | ||
} | ||
|
||
private def printElementGroups(groups: Seq[StructureElementGroup]): Unit = { | ||
out.println("<pre>") | ||
out.println("elementGroups") | ||
groups.foreach { group => | ||
out.println(" StructureElementGroup") | ||
group.elements.foreach { element => | ||
out.println(" StructureElement") | ||
element.fragments.foreach { fragment => | ||
out.println(s""" StructureFragment way=${fragment.way.id} bidirectional=${fragment.bidirectional}, nodeIds=${fragment.nodeIds.mkString(",")}""") | ||
} | ||
} | ||
} | ||
out.println("</pre>") | ||
} | ||
|
||
private def printRouteSegments(routeSegments: Seq[RouteSegmentData]): Unit = { | ||
out.println("<pre>") | ||
out.println("routeSegments") | ||
routeSegments.foreach { routeSegment => | ||
out.println(s" id=${routeSegment.id}, id=${routeSegment.segment.id}, startNodeId=${routeSegment.segment.startNodeId}, endNodeId=${routeSegment.segment.endNodeId}") | ||
} | ||
out.println("</pre>") | ||
} | ||
|
||
private def printStructure(structure: Structure): Unit = { | ||
out.println("<pre>") | ||
out.println(s"Structure") | ||
structure.forwardPath.foreach { path => | ||
printStructurePath("forwardPath", path) | ||
} | ||
structure.backwardPath.foreach { path => | ||
printStructurePath("backwardPath", path) | ||
} | ||
structure.otherPaths.foreach { path => | ||
printStructurePath("otherPath", path) | ||
} | ||
out.println("</pre>") | ||
} | ||
|
||
private def printStructurePath(name: String, path: StructurePath): Unit = { | ||
out.println(s" StructurePath $name startNodeId=${path.startNodeId}, endNodeId=${path.endNodeId}") | ||
path.elements.foreach { pathElement => | ||
out.println(s" StructurePathElement reversed=${pathElement.reversed}") | ||
pathElement.element.fragments.foreach { fragment => | ||
out.println(s""" way=${fragment.way.id} bidirectional=${fragment.bidirectional}, nodeIds=${fragment.nodeIds.mkString(",")}""") | ||
} | ||
} | ||
} | ||
|
||
private def printFacts(): Unit = { | ||
out.println("<pre>") | ||
if (context.facts != context.oldFacts) { | ||
out.println("FACTS DO NOT MATCH") | ||
out.println(s" oldFacts=${context.oldFacts.map(_.name).mkString(", ")}") | ||
out.println(s" newFacts=${context.facts.map(_.name).mkString(", ")}") | ||
} | ||
else { | ||
out.println(s"facts=${context.facts.map(_.name).mkString(", ")}") | ||
} | ||
out.println("</pre>") | ||
} | ||
class RouteAnalysisContextReport(context: RouteAnalysisContext) { | ||
|
||
private def yes(value: Boolean): String = { | ||
if (value) "yes" else "" | ||
def report(): String = { | ||
s"""<html> | ||
|${head()} | ||
|<body> | ||
|${RouteSummaryReport.report(context)} | ||
|${RouteFactsReport.report(context)} | ||
|${RouteMembersReport.report(context)} | ||
|${RouteSegmentsReport.report(context)} | ||
|${StructureElementGroupsReport.report(context.segmentAnalysis.get.elementGroups)} | ||
|${StructureReport.report(context.segmentAnalysis.get.structure)} | ||
|</body> | ||
|</html> | ||
|""".stripMargin | ||
} | ||
|
||
private def head(): String = { | ||
s"""<head> | ||
| <meta http-equiv="content-type" content="text/html; charset=UTF-8"> | ||
| <link href="styles.css" rel="stylesheet" type="text/css"> | ||
| <title>${context.relation.id} route</title> | ||
| <style> | ||
| body { | ||
| font-family: monospace; | ||
| } | ||
| table { | ||
| margin: 30; | ||
| } | ||
| table, th, td { | ||
| border: 1px solid gray; | ||
| border-collapse: collapse; | ||
| } | ||
| td { | ||
| padding: .5em; | ||
| } | ||
| .header { | ||
| background-color: #f8f8f8; | ||
| } | ||
| .spacer { | ||
| min-width: 1em; | ||
| border-left: none; | ||
| border-right: none; | ||
| } | ||
| | ||
| </style> | ||
|</head> | ||
|""".stripMargin | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
...er/src/main/scala/kpn/server/analyzer/engine/analysis/route/report/RouteFactsReport.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package kpn.server.analyzer.engine.analysis.route.report | ||
|
||
import kpn.server.analyzer.engine.analysis.route.domain.RouteAnalysisContext | ||
|
||
object RouteFactsReport { | ||
|
||
def report(context: RouteAnalysisContext): String = { | ||
if (context.facts != context.oldFacts) { | ||
s"""<pre> | ||
|FACTS DO NOT MATCH | ||
| oldFacts=${context.oldFacts.map(_.name).mkString(", ")} | ||
| newFacts=${context.facts.map(_.name).mkString(", ")} | ||
|</pre> | ||
|""".stripMargin | ||
} | ||
else { | ||
s"""<pre> | ||
|facts=${context.facts.map(_.name).mkString(", ")} | ||
|</pre> | ||
|""".stripMargin | ||
} | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
.../src/main/scala/kpn/server/analyzer/engine/analysis/route/report/RouteMembersReport.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package kpn.server.analyzer.engine.analysis.route.report | ||
|
||
import kpn.core.analysis.RouteMember | ||
import kpn.server.analyzer.engine.analysis.route.domain.RouteAnalysisContext | ||
|
||
object RouteMembersReport { | ||
def report(context: RouteAnalysisContext): String = { | ||
new RouteMembersReport(context).report() | ||
} | ||
} | ||
|
||
class RouteMembersReport(context: RouteAnalysisContext) { | ||
def report(): String = { | ||
s"""<table> | ||
| <tr class="header"> | ||
| <td>nr</td> | ||
| <td></td> | ||
| <td>link</td> | ||
| <td>id</td> | ||
| <td>name</td> | ||
| <td>role</td> | ||
| <td>accessible</td> | ||
| </tr> | ||
|${routeMemberRows()} | ||
|</table> | ||
|""".stripMargin | ||
} | ||
|
||
private def routeMemberRows(): String = { | ||
context.routeMembers.get.zipWithIndex.map { case (routeMember, index) => | ||
routeMemberRow(routeMember, index) | ||
}.mkString | ||
} | ||
|
||
private def routeMemberRow(routeMember: RouteMember, index: Int): String = { | ||
s"""<tr> | ||
| <td> | ||
| ${index + 1} | ||
| </td> | ||
| <td style="padding:0"> | ||
| <img src="images/${routeMember.linkName}.png"/> | ||
| </td> | ||
| <td> | ||
| <pre>${routeMember.link.map(_.reportString).getOrElse("")}</pre> | ||
| </td> | ||
| <td> | ||
| <a href="https://www.openstreetmap.org/${routeMember.memberType}/${routeMember.id}">${routeMember.id}</a> | ||
| </td> | ||
| <td> | ||
| ${routeMember.name} | ||
| </td> | ||
| <td> | ||
| ${routeMember.role.getOrElse("")} | ||
| </td> | ||
| <td> | ||
| ${if (routeMember.accessible) "" else "no"} | ||
| </td> | ||
|</tr> | ||
|""".stripMargin | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
...src/main/scala/kpn/server/analyzer/engine/analysis/route/report/RouteSegmentsReport.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
package kpn.server.analyzer.engine.analysis.route.report | ||
|
||
import kpn.server.analyzer.engine.analysis.route.RouteSegmentData | ||
import kpn.server.analyzer.engine.analysis.route.domain.RouteAnalysisContext | ||
|
||
object RouteSegmentsReport { | ||
def report(context: RouteAnalysisContext): String = { | ||
s"""<pre> | ||
|routeSegments | ||
|${context.segmentAnalysis.get.routeSegments.map(segmentReport).mkString("\n")} | ||
|</pre> | ||
|""".stripMargin | ||
} | ||
|
||
private def segmentReport(routeSegment: RouteSegmentData): String = { | ||
s" id=${routeSegment.id}, id=${routeSegment.segment.id}, startNodeId=${routeSegment.segment.startNodeId}, endNodeId=${routeSegment.segment.endNodeId}" | ||
} | ||
} |
Oops, something went wrong.