Skip to content

Commit

Permalink
added belong to relations
Browse files Browse the repository at this point in the history
  • Loading branch information
benediktschwab committed Jul 12, 2023
1 parent 34acd5f commit 52468dd
Show file tree
Hide file tree
Showing 13 changed files with 107 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ data class LaneIdentifierRange(
val lowerLaneId get() = LaneIdentifier(laneIdRange.lowerEndpointOrNull()!!, laneSectionIdentifier)
val upperLaneId get() = LaneIdentifier(laneIdRange.upperEndpointOrNull()!!, laneSectionIdentifier)

// Methods

/** Returns all lane identifiers contained in this range. */
fun getAllLaneIdentifiers(): List<LaneIdentifier> = (laneIdRange.lowerEndpointOrNull()!!..laneIdRange.upperEndpointOrNull()!!).map { LaneIdentifier(it, this.laneSectionIdentifier) }

/** Returns true, if the [laneIdentifier] is contained in this range. */
fun contains(laneIdentifier: LaneIdentifier) = this.laneSectionIdentifier == laneIdentifier.laneSectionIdentifier && this.laneIdRange.contains(laneIdentifier.laneId)

// Conversions
override fun toStringMap(): Map<String, String> =
mapOf("lowerLaneId" to laneIdRange.lowerEndpointOrNull()!!.toString(), "upperLaneId" to laneIdRange.upperEndpointOrNull()!!.toString()) + laneSectionIdentifier.toStringMap()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package io.rtron.model.roadspaces.roadspace.objects

import io.rtron.math.geometry.euclidean.threed.AbstractGeometry3D
import io.rtron.model.roadspaces.identifier.LaneIdentifier
import io.rtron.model.roadspaces.identifier.LaneIdentifierRange
import io.rtron.model.roadspaces.identifier.RoadspaceObjectIdentifier
import io.rtron.model.roadspaces.roadspace.attribute.AttributeList
Expand All @@ -39,6 +40,11 @@ data class RoadspaceObject(
// Properties and Initializers
val name get() = id.roadspaceObjectName

// Methods

/** Returns true, if the lane with [laneIdentifier] is related to this object. */
fun isRelatedToLane(laneIdentifier: LaneIdentifier) = laneRelations.any { it.contains(laneIdentifier) }

// Conversions
override fun toString(): String {
return "RoadObject(attributes=$attributes, geometry=$geometry)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,12 +119,6 @@ data class LaneSection(
laneHeightOffset
}

/**
* Returns the true, if the [curveRelativePoint] is within this [LaneSection] bounds.
*
**/
fun contains(curveRelativePoint: CurveRelativeVector1D) = curvePositionDomain.contains(curveRelativePoint.curvePosition)

private fun getOuterLaneHeightOffset(laneIdentifier: LaneIdentifier):
Either<IllegalArgumentException, UnivariateFunction> =
getLane(laneIdentifier).map { it.outerHeightOffset }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import io.rtron.math.geometry.euclidean.threed.surface.CompositeSurface3D
import io.rtron.math.geometry.euclidean.threed.surface.LinearRing3D
import io.rtron.math.geometry.toIllegalStateException
import io.rtron.math.range.Range
import io.rtron.math.range.fuzzyContains
import io.rtron.math.range.fuzzyEncloses
import io.rtron.math.range.length
import io.rtron.model.roadspaces.common.LateralFillerSurface
Expand Down Expand Up @@ -137,9 +138,14 @@ class Road(

/** Returns the lane section of the [curveRelativePoint]; if it does not exist, an [Either.Left] is returned. */
fun getLaneSection(curveRelativePoint: CurveRelativeVector1D): Either<IllegalArgumentException, LaneSection> {
val selectedLaneSections: List<LaneSection> = laneSections.filter { it.contains(curveRelativePoint) }
return when (selectedLaneSections.size) {
1 -> selectedLaneSections.first().right()
val selectedLaneSections = laneSections.filter { it.curvePositionDomain.contains(curveRelativePoint.curvePosition) }
if (selectedLaneSections.size == 1) {
return selectedLaneSections.first().right()
}

val fuzzySelectedLaneSections = laneSections.filter { it.curvePositionDomain.fuzzyContains(curveRelativePoint.curvePosition, geometricalTolerance) }
return when (fuzzySelectedLaneSections.size) {
1 -> fuzzySelectedLaneSections.first().right()
0 -> IllegalArgumentException("No laneSection found").left()
else -> throw IllegalArgumentException("Domains of lane sections must close flush.")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class BuildingModuleBuilder(
private val identifierAdder: IdentifierAdder
) {
// Properties and Initializers
private val relationAdder = RelationAdder(parameters)
private val attributesAdder = AttributesAdder(parameters)

// Methods
Expand All @@ -61,6 +62,7 @@ class BuildingModuleBuilder(

// semantics
identifierAdder.addIdentifier(roadspaceObject.id, roadspaceObject.name.getOrElse { "" }, buildingFeature) // TODO fix option
relationAdder.addBelongToRelations(roadspaceObject, buildingFeature)
attributesAdder.addAttributes(roadspaceObject, buildingFeature)

return ContextMessageList(buildingFeature, messageList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class CityFurnitureModuleBuilder(
private val identifierAdder: IdentifierAdder
) {
// Properties and Initializers
private val relationAdder = RelationAdder(parameters)
private val attributesAdder = AttributesAdder(parameters)

// Methods
Expand All @@ -55,6 +56,7 @@ class CityFurnitureModuleBuilder(

// semantics
identifierAdder.addIdentifier(roadspaceObject.id, roadspaceObject.name.getOrElse { "" }, cityFurnitureFeature) // TODO fix option
relationAdder.addBelongToRelations(roadspaceObject, cityFurnitureFeature)
attributesAdder.addAttributes(roadspaceObject, cityFurnitureFeature)

return ContextMessageList(cityFurnitureFeature, messageList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ class GenericsModuleBuilder(
private val identifierAdder: IdentifierAdder
) {
// Properties and Initializers
private val relationAdder = RelationAdder(parameters)
private val attributesAdder = AttributesAdder(parameters)

// Methods
Expand All @@ -55,6 +56,7 @@ class GenericsModuleBuilder(

// semantics
identifierAdder.addUniqueIdentifier(roadspaceObject.id, genericOccupiedSpace)
relationAdder.addBelongToRelations(roadspaceObject, genericOccupiedSpace)
attributesAdder.addAttributes(roadspaceObject, genericOccupiedSpace)

return ContextMessageList(genericOccupiedSpace, messageList)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright 2019-2023 Chair of Geoinformatics, Technical University of Munich
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.rtron.transformer.converter.roadspaces2citygml.module

import io.rtron.model.roadspaces.roadspace.objects.RoadspaceObject
import io.rtron.transformer.converter.roadspaces2citygml.Roadspaces2CitygmlParameters
import io.rtron.transformer.converter.roadspaces2citygml.router.RoadspaceObjectRouter
import org.citygml4j.core.model.core.AbstractCityObject
import org.citygml4j.core.model.core.CityObjectRelation
import org.citygml4j.core.model.core.CityObjectRelationProperty
import org.xmlobjects.gml.model.basictypes.Code

/**
* Adds object identifiers from the RoadSpaces model to an [AbstractCityObject] (CityGML model).
*/
class RelationAdder(
private val parameters: Roadspaces2CitygmlParameters
) {

// Methods
fun addRelatedToRelation(roadspaceObject: RoadspaceObject, dstCityObject: AbstractCityObject) {
val relationType = "related" + when (RoadspaceObjectRouter.route(roadspaceObject)) {
RoadspaceObjectRouter.CitygmlTargetFeatureType.BUILDING_BUILDING -> "Building"
RoadspaceObjectRouter.CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE -> "Furniture"
RoadspaceObjectRouter.CitygmlTargetFeatureType.GENERICS_GENERICOCCUPIEDSPACE -> "OccupiedSpace"
RoadspaceObjectRouter.CitygmlTargetFeatureType.TRANSPORTATION_TRAFFICSPACE -> return
RoadspaceObjectRouter.CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE -> return
RoadspaceObjectRouter.CitygmlTargetFeatureType.TRANSPORTATION_MARKING -> return
RoadspaceObjectRouter.CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGETATIONOBJECT -> "Vegetation"
}

// dstCityObject.relatedTo +
// dstCityObject.relatedTo = listOf(createCityObjectRelation(roadspaceObject.id.hashedId, relationType))
}

fun addBelongToRelations(roadspaceObject: RoadspaceObject, dstCityObject: AbstractCityObject) {
dstCityObject.relatedTo = roadspaceObject.laneRelations.flatMap { it.getAllLaneIdentifiers() }.map { createCityObjectRelation(it.hashedId, "belongsTo") }
}

private fun createCityObjectRelation(id: String, type: String): CityObjectRelationProperty {
val relation = CityObjectRelation(parameters.xlinkPrefix + parameters.gmlIdPrefix + id)
relation.relationType = Code(type)

return CityObjectRelationProperty(relation)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class TransportationModuleBuilder(
private val identifierAdder: IdentifierAdder
) {
// Properties and Initializers
private val relationAdder = RelationAdder(parameters)
private val attributesAdder = AttributesAdder(parameters)

// Methods
Expand All @@ -88,11 +89,12 @@ class TransportationModuleBuilder(
* Transforms a [lane] with a [surface] and [centerLine] representation and its [fillerSurfaces] to a
* CityGML [TrafficSpace] and adds it to the [dstTransportationSpace].
*/
fun addTrafficSpaceFeature(lane: Lane, surface: AbstractSurface3D, centerLine: AbstractCurve3D, fillerSurfaces: List<FillerSurface>, dstTransportationSpace: AbstractTransportationSpace): DefaultMessageList {
fun addTrafficSpaceFeature(lane: Lane, surface: AbstractSurface3D, centerLine: AbstractCurve3D, fillerSurfaces: List<FillerSurface>, relatedObjects: List<RoadspaceObject>, dstTransportationSpace: AbstractTransportationSpace): DefaultMessageList {
val messageList = DefaultMessageList()

val trafficSpaceFeature = createTrafficSpaceFeature(TransportationGranularityValue.LANE)
identifierAdder.addUniqueIdentifier(lane.id, trafficSpaceFeature)
relatedObjects.forEach { relationAdder.addRelatedToRelation(it, trafficSpaceFeature) }
// TODO: consider left-hand traffic (LHT)
if (lane.id.isRight() || lane.id.isCenter()) {
trafficSpaceFeature.trafficDirection = TrafficDirectionValue.FORWARDS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class VegetationModuleBuilder(
private val identifierAdder: IdentifierAdder
) {
// Properties and Initializers
private val relationAdder = RelationAdder(parameters)
private val attributesAdder = AttributesAdder(parameters)

// Methods
Expand All @@ -60,6 +61,7 @@ class VegetationModuleBuilder(

// semantics
identifierAdder.addUniqueIdentifier(roadspaceObject.id, solitaryVegetationObjectFeature)
relationAdder.addBelongToRelations(roadspaceObject, solitaryVegetationObjectFeature)
attributesAdder.addAttributes(roadspaceObject, solitaryVegetationObjectFeature)

return ContextMessageList(solitaryVegetationObjectFeature, messageList)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ object RoadspaceObjectRouter {
TRANSPORTATION_TRAFFICSPACE,
TRANSPORTATION_AUXILIARYTRAFFICSPACE,
TRANSPORTATION_MARKING,
VEGETATION_SOLITARYVEGEATIONOBJECT
VEGETATION_SOLITARYVEGETATIONOBJECT
}

/**
Expand All @@ -52,7 +52,7 @@ object RoadspaceObjectRouter {
"trafficIsland" -> return CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE
"trafficLight" -> return CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE
"trafficSign" -> return CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE
"tree" -> return CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGEATIONOBJECT
"tree" -> return CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGETATIONOBJECT
"unknown" -> return CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE
"wall" -> return CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE
}
Expand All @@ -62,8 +62,8 @@ object RoadspaceObjectRouter {
RoadObjectType.NONE -> CitygmlTargetFeatureType.GENERICS_GENERICOCCUPIEDSPACE
RoadObjectType.OBSTACLE -> CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE
RoadObjectType.POLE -> CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE
RoadObjectType.TREE -> CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGEATIONOBJECT
RoadObjectType.VEGETATION -> CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGEATIONOBJECT
RoadObjectType.TREE -> CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGETATIONOBJECT
RoadObjectType.VEGETATION -> CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGETATIONOBJECT
RoadObjectType.BARRIER -> CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE
RoadObjectType.BUILDING -> CitygmlTargetFeatureType.BUILDING_BUILDING
RoadObjectType.PARKING_SPACE -> CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,8 @@ class RoadsTransformer(
} else {
emptyList()
}
messageList += addSingleLane(laneId, roadspace.road, fillerSurface, dstTransportationSpace)
val relatedObjects = roadspace.roadspaceObjects.filter { it.isRelatedToLane(laneId) }
messageList += addSingleLane(laneId, roadspace.road, fillerSurface, relatedObjects, dstTransportationSpace)
}
roadspace.roadspaceObjects.forEach { addSingleRoadspaceObject(it, dstTransportationSpace) }
roadspace.road.getAllLaneIdentifiers().forEach {
Expand All @@ -176,7 +177,7 @@ class RoadsTransformer(
return messageList
}

private fun addSingleLane(id: LaneIdentifier, road: Road, longitudinalFillerSurfaces: List<FillerSurface>, dstTransportationSpace: AbstractTransportationSpace): DefaultMessageList {
private fun addSingleLane(id: LaneIdentifier, road: Road, longitudinalFillerSurfaces: List<FillerSurface>, relatedObjects: List<RoadspaceObject>, dstTransportationSpace: AbstractTransportationSpace): DefaultMessageList {
val messageList = DefaultMessageList()
val lane = road.getLane(id)
.getOrElse { messageList += DefaultMessage.of("", "${it.message} Ignoring lane.", id, Severity.WARNING, wasFixed = true); return messageList }
Expand All @@ -188,12 +189,13 @@ class RoadsTransformer(
.getOrElse { messageList += DefaultMessage.of("", "${it.message} Ignoring lane.", id, Severity.WARNING, wasFixed = true); return messageList }.toList()
val fillerSurfaces = innerLateralFillerSurface + longitudinalFillerSurfaces

when (LaneRouter.route(lane)) {
messageList += when (LaneRouter.route(lane)) {
LaneRouter.CitygmlTargetFeatureType.TRANSPORTATION_TRAFFICSPACE -> {
messageList += transportationModuleBuilder.addTrafficSpaceFeature(lane, surface, centerLine, fillerSurfaces, dstTransportationSpace)
transportationModuleBuilder.addTrafficSpaceFeature(lane, surface, centerLine, fillerSurfaces, relatedObjects, dstTransportationSpace)
}

LaneRouter.CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE -> {
messageList += transportationModuleBuilder.addAuxiliaryTrafficSpaceFeature(lane, surface, centerLine, fillerSurfaces, dstTransportationSpace)
transportationModuleBuilder.addAuxiliaryTrafficSpaceFeature(lane, surface, centerLine, fillerSurfaces, dstTransportationSpace)
}
}

Expand All @@ -216,7 +218,7 @@ class RoadsTransformer(
RoadspaceObjectRouter.CitygmlTargetFeatureType.BUILDING_BUILDING -> {}
RoadspaceObjectRouter.CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE -> {}
RoadspaceObjectRouter.CitygmlTargetFeatureType.GENERICS_GENERICOCCUPIEDSPACE -> {}
RoadspaceObjectRouter.CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGEATIONOBJECT -> {}
RoadspaceObjectRouter.CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGETATIONOBJECT -> {}
}

return messageList
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class RoadspaceObjectTransformer(
RoadspaceObjectRouter.CitygmlTargetFeatureType.TRANSPORTATION_TRAFFICSPACE -> None
RoadspaceObjectRouter.CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE -> None
RoadspaceObjectRouter.CitygmlTargetFeatureType.TRANSPORTATION_MARKING -> None
RoadspaceObjectRouter.CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGEATIONOBJECT -> vegetationModuleBuilder.createSolitaryVegetationFeature(roadspaceObject).handleMessageList { messageList += it }.some()
RoadspaceObjectRouter.CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGETATIONOBJECT -> vegetationModuleBuilder.createSolitaryVegetationFeature(roadspaceObject).handleMessageList { messageList += it }.some()
}

return ContextMessageList(cityObjects, messageList)
Expand Down

0 comments on commit 52468dd

Please sign in to comment.