Skip to content

Commit

Permalink
#369 generate route relations and route states
Browse files Browse the repository at this point in the history
  • Loading branch information
vmarc committed Feb 29, 2024
1 parent 6dfc0ca commit 224b50f
Show file tree
Hide file tree
Showing 13 changed files with 392 additions and 205 deletions.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package kpn.core.tools.next.database

import kpn.core.tools.next.domain.NextRoute
import kpn.core.tools.next.domain.NextRouteRelation
import kpn.core.tools.next.domain.NextRouteState
import kpn.database.base.DatabaseCollection
import org.mongodb.scala.MongoCollection

import scala.reflect.ClassTag

trait NextDatabase {

def getCollection[T: ClassTag](collectionName: String): MongoCollection[T]

def routes: DatabaseCollection[NextRoute]

def routeRelations: DatabaseCollection[NextRouteRelation]

def routeStates: DatabaseCollection[NextRouteState]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package kpn.core.tools.next.database

import kpn.core.tools.next.domain.NextRoute
import kpn.core.tools.next.domain.NextRouteRelation
import kpn.core.tools.next.domain.NextRouteState
import kpn.database.base.DatabaseCollection
import kpn.database.base.DatabaseCollectionImpl
import org.mongodb.scala.MongoCollection
import org.mongodb.scala.MongoDatabase

import scala.reflect.ClassTag

class NextDatabaseImpl(val database: MongoDatabase) extends NextDatabase {

override def getCollection[T: ClassTag](collectionName: String): MongoCollection[T] = {
database.getCollection[T](collectionName)
}

override def routes: DatabaseCollection[NextRoute] = {
new DatabaseCollectionImpl(database.getCollection[NextRoute]("routes"))
}

override def routeRelations: DatabaseCollection[NextRouteRelation] = {
new DatabaseCollectionImpl(database.getCollection[NextRouteRelation]("route-relations"))
}

override def routeStates: DatabaseCollection[NextRouteState] = {
new DatabaseCollectionImpl(database.getCollection[NextRouteState]("route-states"))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package kpn.core.tools.next.domain

case class NextRoute()
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package kpn.core.tools.next.domain

import kpn.api.base.WithId
import kpn.api.custom.Relation

case class NextRouteRelation(
_id: Long,
relation: Relation
) extends WithId
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package kpn.core.tools.next.domain

import kpn.api.base.WithId
import kpn.server.analyzer.engine.context.ElementIds

case class NextRouteState(
_id: Long, // relationId
tiles: Seq[String],
elementIds: ElementIds,
) extends WithId
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package kpn.core.tools.next.support

import kpn.core.data.Data
import kpn.core.loadOld.Parser
import kpn.core.overpass.OverpassQueryExecutor
import kpn.core.overpass.OverpassQueryExecutorRemoteImpl
import kpn.core.tools.next.database.NextDatabase
import kpn.core.tools.next.database.NextDatabaseImpl
import kpn.core.tools.next.domain.NextRouteRelation
import kpn.core.util.Log
import kpn.database.util.Mongo.codecRegistry
import kpn.server.monitor.route.update.RelationTopLevelDataBuilder
import org.apache.commons.io.FileUtils
import org.mongodb.scala.MongoClient

import java.io.File
import scala.xml.XML

object NextCreateRouteRelationsTool {
def main(args: Array[String]): Unit = {
val client = MongoClient("mongodb://localhost:27017")
try {
val mongoDatabase = client.getDatabase("kpn-next").withCodecRegistry(codecRegistry)
val database = new NextDatabaseImpl(mongoDatabase)
val overpassQueryExecutor = new OverpassQueryExecutorRemoteImpl()
val tool = new NextCreateRouteRelationsTool(database, overpassQueryExecutor)
tool.createMonitorRelations()
} finally {
client.close()
}
}
}

class NextCreateRouteRelationsTool(database: NextDatabase, overpassQueryExecutor: OverpassQueryExecutor) {

private val log = Log(classOf[NextCreateRouteRelationsTool])
private val batchSize = 100

def createMonitorRelations(): Unit = {
val routeIds = collectRouteIds()
log.info(s"collected ${routeIds.size} route ids")
routeIds.sliding(batchSize, batchSize).zipWithIndex.foreach { case (batchRouteIds, index) =>
log.info(s"${index * batchSize}/${routeIds.size}")
createMonitorRelations(batchRouteIds)
}
}

private def collectRouteIds(): Seq[Long] = {
val allRouteIds = FileUtils.readFileToString(new File("/kpn/next/route-ids.txt"), "UTF-8").split("\n").map(_.toLong)
val loadedRouteIds = database.routeRelations.stringIds().map(_.toLong)
(allRouteIds.toSet -- loadedRouteIds.toSet).toSeq.sorted
}

private def createMonitorRelations(routeRelationIds: Seq[Long]): Unit = {
val data = monitorRelationData(routeRelationIds)
routeRelationIds.foreach { routeRelationId =>
data.relations.get(routeRelationId) match {
case Some(relation) =>
database.routeRelations.save(NextRouteRelation(routeRelationId, relation))

case None =>
log.error(s"could note read routeId $routeRelationId")
None
}
}
}

private def monitorRelationData(relationIds: Seq[Long]): Data = {
val relations = relationIds.map(id => s"relation($id);").mkString
val query = s"($relations);(._;>;);out meta;"
val xmlString = overpassQueryExecutor.execute(query)
val xml = XML.loadString(xmlString)
val rawData = new Parser().parse(xml.head)
new RelationTopLevelDataBuilder(rawData, relationIds).data
}
}
Loading

0 comments on commit 224b50f

Please sign in to comment.