Skip to content

Commit

Permalink
#368 improve route tag analysis
Browse files Browse the repository at this point in the history
  • Loading branch information
vmarc committed Jun 21, 2024
1 parent 7f36c4b commit 96d3b80
Show file tree
Hide file tree
Showing 11 changed files with 81 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ class RouteAnalysisTool(config: AnalysisStartConfiguration) {

def analyze(): Unit = {
log.info("Start")
analyzeRoutes(Seq(13844575L))
// analyzeRoutes(Seq(13844575)) // ok route
// analyzeRoutes(Seq(8831649)) // LAW-9 deel 1 - 01
analyzeRoutes(Seq(3952592)) // broken route
// analyzeRoutes(Seq(7973533)) // LAW-9 super route containing other super routes
buildTiles()
log.info(s"Done")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package kpn.server.analyzer.engine.analysis.route

import kpn.server.analyzer.engine.monitor.structure.Structure

case class RouteSegmentAnalysis(
osmDistance: Long,
routeSegments: Seq[RouteSegmentData]
routeSegments: Seq[RouteSegmentData],
structure: Structure
) {
def startNodeId: Option[Long] = routeSegments.headOption.map(_.segment.startNodeId)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import kpn.server.analyzer.engine.context.PreconditionMissingException

object ExpectedNameRouteAnalyzer extends RouteAnalyzer {
def analyze(context: RouteAnalysisContext): RouteAnalysisContext = {
new ExpectedNameRouteAnalyzer(context).analyze
if (context.nodeNetwork) {
new ExpectedNameRouteAnalyzer(context).analyze
}
else {
context
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class RouteAnalysisBuilder(context: RouteAnalysisContext) {
context.routeMap.get,
context.unexpectedNodeIds.get,
context.unexpectedRelationIds.get,
context.expectedName.get,
context.expectedName.getOrElse(""),
context.structure.get,
context.routeNodeAnalysis.get
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,18 @@ package kpn.server.analyzer.engine.analysis.route.analyzers

import kpn.api.custom.Fact
import kpn.core.util.Util.isDigits
import kpn.server.analyzer.engine.analysis.route.RouteNameAnalysis
import kpn.server.analyzer.engine.analysis.route.domain.RouteAnalysisContext
import kpn.server.analyzer.engine.analysis.route.{RouteNameAnalysis, RouteNodeAnalysis}
import kpn.server.analyzer.engine.context.PreconditionMissingException

object RouteNameFromNodesAnalyzer extends RouteAnalyzer {
def analyze(context: RouteAnalysisContext): RouteAnalysisContext = {
new RouteNameFromNodesAnalyzer(context).analyze
if (context.nodeNetwork) {
new RouteNameFromNodesAnalyzer(context).analyze
}
else {
context
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,12 @@ import scala.collection.mutable.ListBuffer
*/
object RouteNodeAnalyzer extends RouteAnalyzer {
def analyze(context: RouteAnalysisContext): RouteAnalysisContext = {
new RouteNodeAnalyzer(context).analyze
if (context.nodeNetwork) {
new RouteNodeAnalyzer(context).analyze
}
else {
context.copy(routeNodeAnalysis = Some(RouteNodeAnalysis()))
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import kpn.server.analyzer.engine.analysis.route.RouteSegmentData
import kpn.server.analyzer.engine.analysis.route.domain.RouteAnalysisContext
import kpn.server.analyzer.engine.monitor.MonitorRouteAnalysisSupport
import kpn.server.analyzer.engine.monitor.structure.ElementDirection
import kpn.server.analyzer.engine.monitor.structure.StructureAnalyzer
import kpn.server.analyzer.engine.monitor.structure.StructureElementAnalyzer
import org.locationtech.jts.geom.Coordinate
import org.locationtech.jts.geom.GeometryFactory
Expand Down Expand Up @@ -46,6 +47,8 @@ class RouteSegmentAnalyzer {
Seq.empty
}

val structure = new StructureAnalyzer().analyze(elementGroups)

val routeSegments = elementGroups.zipWithIndex.flatMap { case (elementGroup, index) =>
val lineStrings = elementGroup.elements.map { element =>
val coordinates = element.nodeIds.flatMap(nodeMap.get)
Expand Down Expand Up @@ -98,7 +101,8 @@ class RouteSegmentAnalyzer {

RouteSegmentAnalysis(
osmDistance,
routeSegments
routeSegments,
structure
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,11 @@ class RouteStructureAnalyzer(context: RouteAnalysisContext) {

private def analyzeStructure(routeNodeAnalysis: RouteNodeAnalysis): RouteStructure = {

val networkType = context.networkType.getOrElse(throw new PreconditionMissingException)

if (isAnalysisImpossible(routeNodeAnalysis)) {
RouteStructure(
unusedSegments = new SegmentBuilder(context.networkType, fragmentMap).segments(fragmentMap.ids)
unusedSegments = new SegmentBuilder(networkType, fragmentMap).segments(fragmentMap.ids)
)
}
else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import kpn.api.custom.Fact
import kpn.api.custom.Fact.RouteTagInvalid
import kpn.api.custom.Fact.RouteTagMissing
import kpn.api.custom.Fact.RouteUnsupportedNetworkType
import kpn.api.custom.NetworkType
import kpn.api.custom.ScopedNetworkType
import kpn.server.analyzer.engine.analysis.route.domain.RouteAnalysisContext

Expand All @@ -18,32 +19,39 @@ object RouteTagAnalyzer extends RouteAnalyzer {
class RouteTagAnalyzer(context: RouteAnalysisContext) {

def analyze: RouteAnalysisContext = {

val facts = ListBuffer[Fact]()

val scopedNetworkTypeOption = context.relation.tagValue("network") match {
case None => None
case Some(key) =>
ScopedNetworkType.withKey(key) match {
case None =>
facts += RouteUnsupportedNetworkType
None

case Some(scopedNetworkType) =>
context.relation.tagValue("route") match {
case None => facts += RouteTagMissing
case Some(routeTagValue) =>
if (!context.relation.hasTag("route", scopedNetworkType.networkType.routeTagValues *)) {
facts += RouteTagInvalid
}
}
Some(scopedNetworkType)
}
if (!context.relation.hasTag("type", "route", "superroute")) {
context.copy(abort = true).withFacts(RouteTagMissing)
}
else {
context.relation.tagValue("route") match {
case None => context.copy(abort = true).withFacts(RouteTagMissing)
case Some(routeTagValue) =>
NetworkType.all.find(_.routeTagValues.contains(routeTagValue)) match {
case None => context.copy(abort = true).withFacts(RouteUnsupportedNetworkType)
case Some(networkType) =>
val superRoute = context.relation.hasTag("type", "superroute")
val nodeNetwork = context.relation.hasTag("network:type", "node_network")
val facts = ListBuffer[Fact]()
val scopedNetworkTypeOption = context.relation.tagValue("network") match {
case None => None
case Some(key) =>
ScopedNetworkType.withKey(key) match {
case None => None
case Some(scopedNetworkType) =>
if (!context.relation.hasTag("route", scopedNetworkType.networkType.routeTagValues *)) {
facts += RouteTagInvalid
}
Some(scopedNetworkType)
}
}
context.copy(
superRoute = superRoute,
nodeNetwork = nodeNetwork,
networkType = Some(networkType),
scopedNetworkTypeOption = scopedNetworkTypeOption
).withFacts(facts.toSeq *)
}
}
}

context.copy(
abort = scopedNetworkTypeOption.isEmpty,
scopedNetworkTypeOption = scopedNetworkTypeOption
).withFacts(facts.toSeq *)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,15 @@ case class RouteAnalysisContext(
analysisContext: AnalysisContext,
relation: Relation,
// analysis results start here...
segmentAnalysis: Option[RouteSegmentAnalysis] = None,
routeNodeInfos: Map[Long, RouteNodeInfo] = Map.empty,
scopedNetworkTypeOption: Option[ScopedNetworkType] = None,
country: Option[Country] = None,
active: Boolean = true,
superRoute: Boolean = false,
nodeNetwork: Boolean = false,
proposed: Boolean = false,
networkType: Option[NetworkType] = None,
scopedNetworkTypeOption: Option[ScopedNetworkType] = None,
country: Option[Country] = None,
segmentAnalysis: Option[RouteSegmentAnalysis] = None,
routeNodeInfos: Map[Long, RouteNodeInfo] = Map.empty,
facts: Seq[Fact] = Seq.empty,
unexpectedNodeIds: Option[Seq[Long]] = None,
unexpectedRelationIds: Option[Seq[Long]] = None,
Expand Down Expand Up @@ -62,10 +65,6 @@ case class RouteAnalysisContext(
}
}

def networkType: NetworkType = {
scopedNetworkType.networkType
}

def withFact(fact: Fact): RouteAnalysisContext = {
copy(facts = facts :+ fact)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ class StructureAnalyzer(traceEnabled: Boolean = false) {

def analyze(relation: Relation): Structure = {
val elementGroups = StructureElementAnalyzer.analyze(relation.members, traceEnabled)
analyze(elementGroups)
}

def analyze(elementGroups: Seq[StructureElementGroup]): Structure = {
if (elementGroups.size != 1) {
Structure(
None,
Expand Down

0 comments on commit 96d3b80

Please sign in to comment.