Skip to content

Commit

Permalink
fixed mapping of parking lots to CityGML traffic spaces and areas
Browse files Browse the repository at this point in the history
  • Loading branch information
benediktschwab committed Aug 3, 2023
1 parent 391b51f commit fe47ddb
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ class LaneBuilder(
attribute("_curvePositionStart", roadMark.sOffset)
attribute("_width", roadMark.width)
attribute("_type", roadMark.typeAttribute.toString())
attribute("_weight", roadMark.weight.toString())
attribute("_weight", roadMark.weight.map { it.toString() })
attribute("_color", roadMark.color.toString())
attribute("_material", roadMark.material)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class RoadspaceBuilder(
attributes("${parameters.attributesPrefix}road_") {
attribute("length", road.length)
attribute("junction", road.getJunctionOption())
attribute("rule", road.rule.toString())
attribute("rule", road.rule.map { it.toString() })

road.link.tap { roadLink ->
roadLink.predecessor.tap { predecessor ->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,5 +149,6 @@ fun UnitOfMeasure.toGmlString(): String = when (this) {
UnitOfMeasure.METER_PER_SECOND -> "mps"
UnitOfMeasure.KILOMETER_PER_HOUR -> "kmph"
UnitOfMeasure.MILES_PER_HOUR -> "mph"
else -> TODO("Conversion of $this is not yet implemented.")
UnitOfMeasure.NONE -> TODO("Conversion of $this is not yet implemented.")
UnitOfMeasure.UNKNOWN -> TODO("Conversion of $this is not yet implemented.")
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import io.rtron.model.citygml.code.AuxiliaryTrafficAreaFunctionCode
import io.rtron.model.citygml.code.TrafficAreaAndAuxiliaryTrafficAreaSurfaceMaterialCode
import io.rtron.model.citygml.code.TrafficAreaFunctionCode
import io.rtron.model.citygml.code.TrafficAreaUsageCode
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectType
import io.rtron.model.roadspaces.roadspace.road.LaneMaterial
import io.rtron.model.roadspaces.roadspace.road.LaneType

Expand Down Expand Up @@ -142,4 +143,67 @@ object CodeAdder {
in "SPEC_CONCRETE_3D" -> TrafficAreaAndAuxiliaryTrafficAreaSurfaceMaterialCode.GRASS.some()
else -> None
}

fun mapToTrafficAreaFunctionCodes(roadObjectType: RoadObjectType): List<TrafficAreaFunctionCode> =
when (roadObjectType) {
RoadObjectType.NONE -> emptyList()
RoadObjectType.OBSTACLE -> emptyList()
RoadObjectType.POLE -> emptyList()
RoadObjectType.TREE -> emptyList()
RoadObjectType.VEGETATION -> emptyList()
RoadObjectType.BARRIER -> emptyList()
RoadObjectType.BUILDING -> emptyList()
RoadObjectType.PARKING_SPACE -> listOf(TrafficAreaFunctionCode.PARKING_LAY_BY)
RoadObjectType.PATCH -> emptyList()
RoadObjectType.RAILING -> emptyList()
RoadObjectType.TRAFFIC_ISLAND -> emptyList()
RoadObjectType.CROSSWALK -> listOf(TrafficAreaFunctionCode.CROSSWALK)
RoadObjectType.STREET_LAMP -> emptyList()
RoadObjectType.GANTRY -> emptyList()
RoadObjectType.SOUND_BARRIER -> emptyList()
RoadObjectType.ROAD_MARK -> emptyList()
RoadObjectType.SIGNAL -> emptyList()
}

fun mapToAuxiliaryTrafficAreaFunctionCodes(roadObjectType: RoadObjectType): List<AuxiliaryTrafficAreaFunctionCode> =
when (roadObjectType) {
RoadObjectType.NONE -> emptyList()
RoadObjectType.OBSTACLE -> emptyList()
RoadObjectType.POLE -> emptyList()
RoadObjectType.TREE -> emptyList()
RoadObjectType.VEGETATION -> emptyList()
RoadObjectType.BARRIER -> emptyList()
RoadObjectType.BUILDING -> emptyList()
RoadObjectType.PARKING_SPACE -> listOf(AuxiliaryTrafficAreaFunctionCode.PARKING_BAY)
RoadObjectType.PATCH -> emptyList()
RoadObjectType.RAILING -> emptyList()
RoadObjectType.TRAFFIC_ISLAND -> listOf(AuxiliaryTrafficAreaFunctionCode.TRAFFIC_ISLAND)
RoadObjectType.CROSSWALK -> emptyList()
RoadObjectType.STREET_LAMP -> emptyList()
RoadObjectType.GANTRY -> emptyList()
RoadObjectType.SOUND_BARRIER -> emptyList()
RoadObjectType.ROAD_MARK -> emptyList()
RoadObjectType.SIGNAL -> emptyList()
}

fun mapToTrafficAreaUsageCodes(roadObjectType: RoadObjectType): List<TrafficAreaUsageCode> =
when (roadObjectType) {
RoadObjectType.NONE -> emptyList()
RoadObjectType.OBSTACLE -> emptyList()
RoadObjectType.POLE -> emptyList()
RoadObjectType.TREE -> emptyList()
RoadObjectType.VEGETATION -> emptyList()
RoadObjectType.BARRIER -> emptyList()
RoadObjectType.BUILDING -> emptyList()
RoadObjectType.PARKING_SPACE -> listOf(TrafficAreaUsageCode.CAR)
RoadObjectType.PATCH -> emptyList()
RoadObjectType.RAILING -> emptyList()
RoadObjectType.TRAFFIC_ISLAND -> emptyList()
RoadObjectType.CROSSWALK -> listOf(TrafficAreaUsageCode.PEDESTRIAN)
RoadObjectType.STREET_LAMP -> emptyList()
RoadObjectType.GANTRY -> emptyList()
RoadObjectType.SOUND_BARRIER -> emptyList()
RoadObjectType.ROAD_MARK -> emptyList()
RoadObjectType.SIGNAL -> emptyList()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -89,28 +89,29 @@ class TransportationModuleBuilder(
val messageList = DefaultMessageList()

val trafficSpaceFeature = createTrafficSpaceFeature(TransportationGranularityValue.LANE)
// semantics
IdentifierAdder.addIdentifier(lane.id.deriveTrafficSpaceOrAuxiliaryTrafficSpaceGmlIdentifier(parameters.gmlIdPrefix), trafficSpaceFeature)
trafficSpaceFeature.usages = CodeAdder.mapToTrafficAreaUsageCodes(lane.type).map { it.code }
trafficSpaceFeature.functions = CodeAdder.mapToTrafficAreaFunctionCodes(lane.type).map { it.code }
attributesAdder.addAttributes(lane, trafficSpaceFeature)
relatedObjects.forEach { relationAdder.addRelatedToRelation(it, trafficSpaceFeature) }
// TODO: consider left-hand traffic (LHT)
trafficSpaceFeature.trafficDirection = if (lane.id.isForward()) TrafficDirectionValue.FORWARDS else TrafficDirectionValue.BACKWARDS

// line representation of lane
// geometry
val centerLineGeometryTransformer = GeometryTransformer(parameters).also { centerLine.accept(it) }
trafficSpaceFeature.populateLod2Geometry(centerLineGeometryTransformer)

// surface representation of lane
val trafficArea = createTrafficAreaFeature(lane.id, surface).handleMessageList { messageList += it }
trafficSpaceFeature.addBoundary(AbstractSpaceBoundaryProperty(trafficArea))

IdentifierAdder.addIdentifier(lane.id.deriveTrafficAreaOrAuxiliaryTrafficAreaGmlIdentifier(parameters.gmlIdPrefix), "Lane", trafficArea)
trafficArea.usages = CodeAdder.mapToTrafficAreaUsageCodes(lane.type).map { it.code }
trafficArea.functions = CodeAdder.mapToTrafficAreaFunctionCodes(lane.type).map { it.code }
// traffic area feature
val trafficAreaFeature = createTrafficAreaFeature(lane.id, surface).handleMessageList { messageList += it }
IdentifierAdder.addIdentifier(lane.id.deriveTrafficAreaOrAuxiliaryTrafficAreaGmlIdentifier(parameters.gmlIdPrefix), "Lane", trafficAreaFeature)
trafficAreaFeature.usages = CodeAdder.mapToTrafficAreaUsageCodes(lane.type).map { it.code }
trafficAreaFeature.functions = CodeAdder.mapToTrafficAreaFunctionCodes(lane.type).map { it.code }
lane.laneMaterial.flatMap { CodeAdder.mapToTrafficAreaAndAuxiliaryTrafficAreaSurfaceMaterialCode(it) }
.tap { trafficArea.surfaceMaterial = it.code }
attributesAdder.addAttributes(lane, trafficArea)
.tap { trafficAreaFeature.surfaceMaterial = it.code }
attributesAdder.addAttributes(lane, trafficAreaFeature)
trafficSpaceFeature.addBoundary(AbstractSpaceBoundaryProperty(trafficAreaFeature))

// filler surfaces
// filler surface features
lateralFillerSurface.tap { fillerSurface ->
val fillerTrafficArea = createTrafficAreaFeature(fillerSurface.id, fillerSurface.surface).handleMessageList { messageList += it }

Expand Down Expand Up @@ -146,26 +147,27 @@ class TransportationModuleBuilder(
dstTransportationSpace: AbstractTransportationSpace
): DefaultMessageList {
val messageList = DefaultMessageList()

val auxiliaryTrafficSpaceFeature = createAuxiliaryTrafficSpaceFeature(TransportationGranularityValue.LANE)
// semantics
IdentifierAdder.addIdentifier(lane.id.deriveTrafficSpaceOrAuxiliaryTrafficSpaceGmlIdentifier(parameters.gmlIdPrefix), auxiliaryTrafficSpaceFeature)
auxiliaryTrafficSpaceFeature.functions = CodeAdder.mapToAuxiliaryTrafficAreaFunctionCodes(lane.type).map { it.code }
attributesAdder.addAttributes(lane, auxiliaryTrafficSpaceFeature)

// line representation
// geometry
val centerLineGeometryTransformer = GeometryTransformer(parameters).also { centerLine.accept(it) }
auxiliaryTrafficSpaceFeature.populateLod2Geometry(centerLineGeometryTransformer)

// surface representation
val auxiliaryTrafficArea = createAuxiliaryTrafficAreaFeature(lane.id, surface)
// auxiliary traffic area feature
val auxiliaryTrafficAreaFeature = createAuxiliaryTrafficAreaFeature(lane.id, surface)
.handleMessageList { messageList += it }
auxiliaryTrafficSpaceFeature.addBoundary(AbstractSpaceBoundaryProperty(auxiliaryTrafficArea))

IdentifierAdder.addIdentifier(lane.id.deriveTrafficAreaOrAuxiliaryTrafficAreaGmlIdentifier(parameters.gmlIdPrefix), "Lane", auxiliaryTrafficArea)
auxiliaryTrafficArea.functions = CodeAdder.mapToAuxiliaryTrafficAreaFunctionCodes(lane.type).map { it.code }
IdentifierAdder.addIdentifier(lane.id.deriveTrafficAreaOrAuxiliaryTrafficAreaGmlIdentifier(parameters.gmlIdPrefix), "Lane", auxiliaryTrafficAreaFeature)
auxiliaryTrafficAreaFeature.functions = CodeAdder.mapToAuxiliaryTrafficAreaFunctionCodes(lane.type).map { it.code }
lane.laneMaterial.flatMap { CodeAdder.mapToTrafficAreaAndAuxiliaryTrafficAreaSurfaceMaterialCode(it) }
.tap { auxiliaryTrafficArea.surfaceMaterial = it.code }
attributesAdder.addAttributes(lane, auxiliaryTrafficArea)
.tap { auxiliaryTrafficAreaFeature.surfaceMaterial = it.code }
attributesAdder.addAttributes(lane, auxiliaryTrafficAreaFeature)
auxiliaryTrafficSpaceFeature.addBoundary(AbstractSpaceBoundaryProperty(auxiliaryTrafficAreaFeature))

// filler surfaces
// filler surface features
lateralFillerSurface.tap { fillerSurface ->
val fillerAuxiliaryTrafficArea = createAuxiliaryTrafficAreaFeature(fillerSurface.id, fillerSurface.surface).handleMessageList { messageList += it }

Expand All @@ -185,58 +187,72 @@ class TransportationModuleBuilder(
// populate transportation space
val auxiliaryTrafficSpaceProperty = AuxiliaryTrafficSpaceProperty(auxiliaryTrafficSpaceFeature)
dstTransportationSpace.auxiliaryTrafficSpaces.add(auxiliaryTrafficSpaceProperty)

return messageList
}

fun addTrafficSpaceFeature(roadspaceObject: RoadspaceObject, dstTransportationSpace: AbstractTransportationSpace): DefaultMessageList {
val messageList = DefaultMessageList()

val trafficSpaceFeature = createTrafficSpaceFeature(TransportationGranularityValue.LANE)
IdentifierAdder.addIdentifier(roadspaceObject.id.deriveTrafficSpaceOrAuxiliaryTrafficSpaceGmlIdentifier(parameters.gmlIdPrefix), trafficSpaceFeature)
trafficSpaceFeature.usages = CodeAdder.mapToTrafficAreaUsageCodes(roadspaceObject.type).map { it.code }
trafficSpaceFeature.functions = CodeAdder.mapToTrafficAreaFunctionCodes(roadspaceObject.type).map { it.code }
attributesAdder.addAttributes(roadspaceObject, trafficSpaceFeature)

// surface representation
roadspaceObject.complexGeometry.tap { currentComplexGeometry ->
val trafficAreaFeature = TrafficArea()
// semantics
IdentifierAdder.addIdentifier(roadspaceObject.id.deriveTrafficAreaOrAuxiliaryTrafficAreaGmlIdentifier(parameters.gmlIdPrefix), trafficAreaFeature)
trafficAreaFeature.usages = CodeAdder.mapToTrafficAreaUsageCodes(roadspaceObject.type).map { it.code }
trafficAreaFeature.functions = CodeAdder.mapToTrafficAreaFunctionCodes(roadspaceObject.type).map { it.code }
attributesAdder.addAttributes(roadspaceObject, trafficAreaFeature)

// geometry
val geometryTransformer = GeometryTransformer.of(currentComplexGeometry, parameters)
val solidFaceSelection = listOf(GeometryTransformer.FaceType.TOP, GeometryTransformer.FaceType.SIDE)
trafficAreaFeature.populateLod2MultiSurfaceFromSolidCutoutOrSurface(geometryTransformer, solidFaceSelection)
.onLeft { messageList += DefaultMessage.of("NoSuitableGeometryForTrafficAreaLod2", it.message, roadspaceObject.id, Severity.WARNING, wasFixed = true) }

// semantics
IdentifierAdder.addIdentifier(roadspaceObject.id.deriveTrafficAreaOrAuxiliaryTrafficAreaGmlIdentifier(parameters.gmlIdPrefix), trafficAreaFeature)
attributesAdder.addAttributes(roadspaceObject, trafficAreaFeature)

trafficSpaceFeature.addBoundary(AbstractSpaceBoundaryProperty(trafficAreaFeature))
}

// populate transportation space
val trafficSpaceProperty = TrafficSpaceProperty(trafficSpaceFeature)
dstTransportationSpace.trafficSpaces.add(trafficSpaceProperty)

return messageList
}

fun addAuxiliaryTrafficSpaceFeature(roadspaceObject: RoadspaceObject, dstTransportationSpace: AbstractTransportationSpace): DefaultMessageList {
val messageList = DefaultMessageList()

val auxiliaryTrafficSpaceFeature = createAuxiliaryTrafficSpaceFeature(TransportationGranularityValue.LANE)
IdentifierAdder.addIdentifier(roadspaceObject.id.deriveTrafficSpaceOrAuxiliaryTrafficSpaceGmlIdentifier(parameters.gmlIdPrefix), auxiliaryTrafficSpaceFeature)
auxiliaryTrafficSpaceFeature.functions = CodeAdder.mapToAuxiliaryTrafficAreaFunctionCodes(roadspaceObject.type).map { it.code }

// surface representation
roadspaceObject.complexGeometry.tap { currentComplexGeometry ->
val auxiliaryTrafficAreaFeature = AuxiliaryTrafficArea()
// semantics
IdentifierAdder.addIdentifier(roadspaceObject.id.deriveTrafficAreaOrAuxiliaryTrafficAreaGmlIdentifier(parameters.gmlIdPrefix), auxiliaryTrafficAreaFeature)
auxiliaryTrafficAreaFeature.functions = CodeAdder.mapToAuxiliaryTrafficAreaFunctionCodes(roadspaceObject.type).map { it.code }
attributesAdder.addAttributes(roadspaceObject, auxiliaryTrafficAreaFeature)

// geometry
val geometryTransformer = GeometryTransformer.of(currentComplexGeometry, parameters)
val solidFaceSelection = listOf(GeometryTransformer.FaceType.TOP, GeometryTransformer.FaceType.SIDE)
auxiliaryTrafficAreaFeature.populateLod2MultiSurfaceFromSolidCutoutOrSurface(geometryTransformer, solidFaceSelection)
.onLeft { messageList += DefaultMessage.of("NoSuitableGeometryForAuxiliaryTrafficAreaLod2", it.message, roadspaceObject.id, Severity.WARNING, wasFixed = true) }

// semantics
IdentifierAdder.addIdentifier(roadspaceObject.id.deriveTrafficAreaOrAuxiliaryTrafficAreaGmlIdentifier(parameters.gmlIdPrefix), auxiliaryTrafficAreaFeature)
attributesAdder.addAttributes(roadspaceObject, auxiliaryTrafficAreaFeature)

auxiliaryTrafficSpaceFeature.addBoundary(AbstractSpaceBoundaryProperty(auxiliaryTrafficAreaFeature))
}

// populate transportation space
val auxiliaryTrafficSpaceProperty = AuxiliaryTrafficSpaceProperty(auxiliaryTrafficSpaceFeature)
dstTransportationSpace.auxiliaryTrafficSpaces.add(auxiliaryTrafficSpaceProperty)

return messageList
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ object LaneRouter {
LaneType.BORDER -> CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE
LaneType.RESTRICTED -> CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE
LaneType.CURB -> CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE
LaneType.PARKING -> CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE
LaneType.PARKING -> CitygmlTargetFeatureType.TRANSPORTATION_TRAFFICSPACE
LaneType.BIDIRECTIONAL -> CitygmlTargetFeatureType.TRANSPORTATION_TRAFFICSPACE
LaneType.MEDIAN -> CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE
LaneType.SPECIAL_1 -> CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ object RoadspaceObjectRouter {
RoadObjectType.VEGETATION -> CitygmlTargetFeatureType.VEGETATION_SOLITARYVEGETATIONOBJECT
RoadObjectType.BARRIER -> CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE
RoadObjectType.BUILDING -> CitygmlTargetFeatureType.BUILDING_BUILDING
RoadObjectType.PARKING_SPACE -> CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE
RoadObjectType.PARKING_SPACE -> CitygmlTargetFeatureType.TRANSPORTATION_TRAFFICSPACE
RoadObjectType.PATCH -> CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE
RoadObjectType.RAILING -> CitygmlTargetFeatureType.CITYFURNITURE_CITYFURNITURE
RoadObjectType.TRAFFIC_ISLAND -> CitygmlTargetFeatureType.TRANSPORTATION_AUXILIARYTRAFFICSPACE
Expand Down

0 comments on commit fe47ddb

Please sign in to comment.