Skip to content

Commit 99412da

Browse files
refactor road object types to include subtypes
1 parent 72c3ae5 commit 99412da

File tree

6 files changed

+365
-44
lines changed

6 files changed

+365
-44
lines changed
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
/*
2+
* Copyright 2019-2024 Chair of Geoinformatics, Technical University of Munich
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.rtron.model.roadspaces.roadspace.objects
18+
19+
import arrow.core.Option
20+
import arrow.core.toOption
21+
22+
/**
23+
* Represents a subtype of a road object, providing additional classification and context.
24+
*
25+
* @property identifier A unique string that identifies the specific road object subtype.
26+
*
27+
* @see <a href="https://publications.pages.asam.net/standards/ASAM_OpenDRIVE/ASAM_OpenDRIVE_Specification/latest/specification/13_objects/13_14_object_examples.html">ASAM OpenDRIVE Object Examples</a>
28+
*/
29+
sealed interface RoadObjectSubType {
30+
val identifier: String
31+
32+
companion object {
33+
inline fun <reified T> fromIdentifier(identifier: String): Option<T> where T : RoadObjectSubType, T : Enum<T> {
34+
return enumValues<T>().find { it.identifier == identifier }.toOption()
35+
}
36+
}
37+
}
38+
39+
enum class RoadObjectBarrierSubType(override val identifier: String) : RoadObjectSubType {
40+
/** common hedge made out of vegetation and bushes without gaps */
41+
HEDGE("hedge"),
42+
43+
/** metal guard rail along the side of the road (without the vertical poles) */
44+
GUARD_RAIL("guardRail"),
45+
46+
/** lower wall mostly made out of concrete to separate driving lanes */
47+
JERSEY_BARRIER("jerseyBarrier"),
48+
49+
/** higher wall out of concrete, bricks, stones ... */
50+
WALL("wall"),
51+
52+
/** any kind of railing along the roadside */
53+
RAILING("railing"),
54+
55+
/** metal or wooden fence */
56+
FENCE("fence"),
57+
58+
/** higher wall for noise protection */
59+
NOISE_PROTECTIONS("noiseProtections"),
60+
}
61+
62+
enum class RoadObjectBuildingSubType(override val identifier: String) : RoadObjectSubType {
63+
/** regular building like a house or office */
64+
BUILDING("building"),
65+
66+
/** bus stop with little roof and sign */
67+
BUS_STOP("busStop"),
68+
69+
/** small building with a barrier to collect tolls or charges */
70+
TOLL_BOOTH("tollBooth"),
71+
}
72+
73+
enum class RoadObjectCrosswalkSubType(override val identifier: String) : RoadObjectSubType {
74+
/** pedestrian crosswalk without zebra markings */
75+
PEDESTRIAN("pedestrian"),
76+
77+
/** bicycle crossing, in Germany normally with red paint */
78+
BICYCLE("bicycle"),
79+
80+
/** zebra crossing */
81+
ZEBRA("zebra"),
82+
83+
/** invisible crosswalk */
84+
VIRTUAL("virtual"),
85+
}
86+
87+
enum class RoadObjectGantrySubType(override val identifier: String) : RoadObjectSubType {
88+
/** has poles on either side of lanes and an overhead construction between them */
89+
GANTRY("gantry"),
90+
91+
/** has a pole on one side of the road and an overhead construction attached to it */
92+
GANTRY_HALF("gantryHalf"),
93+
}
94+
95+
enum class RoadObjectObstacleSubType(override val identifier: String) : RoadObjectSubType {
96+
ADVERTISING_COLUMN("advertisingColumn"),
97+
ART("art"),
98+
SEATING("seating"),
99+
PICK_NICK("picknick"),
100+
BOX("box"),
101+
PHONE_BOOTH("phonebooth"),
102+
CHARGING_STATION("chargingStation"),
103+
104+
/** for example, electrical, communication */
105+
DISTRIBUTION_BOX("distributionBox"),
106+
CRASH_BOX("crashBox"),
107+
DUMPSTER("dumpster"),
108+
DUST_BIN("dustbin"),
109+
FOUNTAIN("fountain"),
110+
GRIT_CONTAINER("gritContainer"),
111+
HYDRANT("hydrant"),
112+
PARKING_METER("parkingMeter"),
113+
114+
/** for example, bridge pillars */
115+
PILLAR("pillar"),
116+
PLANT_POT("plantPot"),
117+
POST_BOX("postBox"),
118+
119+
/** for example, bicycle stand, handrail */
120+
RAILING("railing"),
121+
ROCK("rock"),
122+
ROAD_BLOCKAGE("roadBlockage"),
123+
WALL("wall"),
124+
FENCE("fence"),
125+
}
126+
127+
enum class RoadObjectParkingSpaceSubType(override val identifier: String) : RoadObjectSubType {
128+
/** typically outdoors, no limit to the top */
129+
OPEN_SPACE("openSpace"),
130+
131+
/** typically indoors, limit to the top for example, inside a building */
132+
CLOSED_SPACE("closedSpace"),
133+
}
134+
135+
enum class RoadObjectPoleSubType(override val identifier: String) : RoadObjectSubType {
136+
EMERGENCY_CALL_BOX("emergencyCallBox"),
137+
PERMANENT_DELINEATOR("permanentDelineator"),
138+
BOLLARD("bollard"),
139+
140+
/** pole for Traffic Signs */
141+
TRAFFIC_SIGN("trafficSign"),
142+
143+
/** pole for trafficLight and trafficSign objects */
144+
TRAFFIC_LIGHT("trafficLight"),
145+
146+
/** has power cables attached */
147+
POWER_POLE("powerPole"),
148+
149+
/** has a light source. Might also have trafficSigns or trafficLights attached to it */
150+
STREET_LAMP("streetLamp"),
151+
WIND_TURBINE("windTurbine"),
152+
}
153+
154+
enum class RoadObjectRoadMarkSubType(override val identifier: String) : RoadObjectSubType {
155+
ARROW_LEFT("arrowLeft"),
156+
ARROW_LEFT_LEFT("arrowLeftLeft"),
157+
ARROW_LEFT_RIGHT("arrowLeftRight"),
158+
ARROW_RIGHT("arrowRight"),
159+
ARROW_RIGHT_RIGHT("arrowRightRight"),
160+
ARROW_RIGHT_LEFT("arrowRightLeft"),
161+
ARROW_STRAIGHT("arrowStraight"),
162+
ARROW_STRAIGHT_LEFT("arrowStraightLeft"),
163+
ARROW_STRAIGHT_RIGHT("arrowStraightRight"),
164+
ARROW_STRAIGHT_LEFT_RIGHT("arrowStraightLeftRight"),
165+
ARROW_MERGE_LEFT("arrowMergeLeft"),
166+
ARROW_MERGE_RIGHT("arrowMergeRight"),
167+
168+
/** these are referenced by a signal */
169+
SIGNAL_LINES("signalLines"),
170+
171+
/** for example, YIELD or 50, might be referenced by a signal */
172+
TEXT("text"),
173+
174+
/** for example, Wheelchair or bicycle */
175+
SYMBOL("symbol"),
176+
PAINT("paint"),
177+
178+
/** for example, restricted area, keep clear area */
179+
AREA("area"),
180+
}
181+
182+
enum class RoadObjectRoadSurfaceSubType(override val identifier: String) : RoadObjectSubType {
183+
/** mostly metal cover to access sewerage tunnels */
184+
MANHOLE("manhole"),
185+
186+
/** road damage */
187+
POTHOLE("pothole"),
188+
189+
/** road damage that has been fixed */
190+
PATCH("patch"),
191+
192+
/** mostly raised surface to prevent higher speeds **/
193+
SPEED_BUMP("speedbump"),
194+
195+
/** water drainage */
196+
DRAIN_GUTTER("drainGutter"),
197+
}
198+
199+
enum class RoadObjectTrafficIslandSubType(override val identifier: String) : RoadObjectSubType {
200+
/** typical traffic island with some curbstone, road mark */
201+
ISLAND("island"),
202+
}
203+
204+
enum class RoadObjectTreeSubType(override val identifier: String) : RoadObjectSubType {
205+
/** needle tree */
206+
NEEDLE("needle"),
207+
208+
/** leaf tree */
209+
LEAF("leaf"),
210+
211+
/** palm tree */
212+
PALM("palm"),
213+
}
214+
215+
enum class RoadObjectVegetationSubType(override val identifier: String) : RoadObjectSubType {
216+
/** a single bush */
217+
BUSH("bush"),
218+
219+
/** an area that is a forest */
220+
FOREST("forest"),
221+
222+
/** a single hedge */
223+
HEDGE("hedge"),
224+
}

rtron-model/src/main/kotlin/io/rtron/model/roadspaces/roadspace/objects/RoadspaceObject.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package io.rtron.model.roadspaces.roadspace.objects
1818

19+
import arrow.core.None
1920
import arrow.core.Option
2021
import io.rtron.math.geometry.euclidean.threed.AbstractGeometry3D
2122
import io.rtron.math.geometry.euclidean.threed.point.AbstractPoint3D
@@ -34,6 +35,7 @@ import io.rtron.model.roadspaces.roadspace.attribute.AttributeList
3435
data class RoadspaceObject(
3536
val id: RoadspaceObjectIdentifier,
3637
val type: RoadObjectType = RoadObjectType.NONE,
38+
val subType: Option<RoadObjectSubType> = None,
3739
val pointGeometry: AbstractPoint3D,
3840
val boundingBoxGeometry: Option<AbstractGeometry3D>,
3941
val complexGeometry: Option<AbstractGeometry3D>,

rtron-transformer/src/main/kotlin/io/rtron/transformer/converter/opendrive2roadspaces/roadspaces/RoadspaceObjectBuilder.kt

Lines changed: 57 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,20 @@ import io.rtron.model.roadspaces.identifier.RoadspaceIdentifier
4646
import io.rtron.model.roadspaces.identifier.RoadspaceObjectIdentifier
4747
import io.rtron.model.roadspaces.roadspace.attribute.AttributeList
4848
import io.rtron.model.roadspaces.roadspace.attribute.attributes
49+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectBarrierSubType
50+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectBuildingSubType
51+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectCrosswalkSubType
52+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectGantrySubType
53+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectObstacleSubType
54+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectParkingSpaceSubType
55+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectPoleSubType
56+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectRoadMarkSubType
57+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectRoadSurfaceSubType
58+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectSubType
59+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectTrafficIslandSubType
60+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectTreeSubType
4961
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectType
62+
import io.rtron.model.roadspaces.roadspace.objects.RoadObjectVegetationSubType
5063
import io.rtron.model.roadspaces.roadspace.objects.RoadspaceObject
5164
import io.rtron.std.toInt
5265
import io.rtron.transformer.converter.opendrive2roadspaces.Opendrive2RoadspacesParameters
@@ -97,7 +110,7 @@ class RoadspaceObjectBuilder(
97110
val issueList = DefaultIssueList()
98111

99112
// get general object type and geometry representation
100-
val type = getObjectType(roadObject)
113+
val (type, subType) = getObjectType(roadObject)
101114

102115
// build attributes
103116
val attributes =
@@ -127,6 +140,7 @@ class RoadspaceObjectBuilder(
127140
RoadspaceObject(
128141
roadspaceObjectId,
129142
type,
143+
subType,
130144
pointGeometry,
131145
boundingBoxGeometry,
132146
complexGeometry,
@@ -146,6 +160,7 @@ class RoadspaceObjectBuilder(
146160
RoadspaceObject(
147161
roadspaceObjectId,
148162
type,
163+
subType,
149164
pointGeometry,
150165
boundingBoxGeometry,
151166
complexGeometry,
@@ -161,24 +176,47 @@ class RoadspaceObjectBuilder(
161176
return ContextIssueList(roadObjects, issueList)
162177
}
163178

164-
private fun getObjectType(roadObject: OpendriveRoadObject): RoadObjectType =
165-
roadObject.type.fold({ RoadObjectType.NONE }, {
166-
when (it) {
167-
EObjectType.NONE -> RoadObjectType.NONE
168-
EObjectType.OBSTACLE -> RoadObjectType.OBSTACLE
169-
EObjectType.POLE -> RoadObjectType.POLE
170-
EObjectType.TREE -> RoadObjectType.TREE
171-
EObjectType.VEGETATION -> RoadObjectType.VEGETATION
172-
EObjectType.BARRIER -> RoadObjectType.BARRIER
173-
EObjectType.BUILDING -> RoadObjectType.BUILDING
174-
EObjectType.PARKING_SPACE -> RoadObjectType.PARKING_SPACE
175-
EObjectType.TRAFFIC_ISLAND -> RoadObjectType.TRAFFIC_ISLAND
176-
EObjectType.CROSSWALK -> RoadObjectType.CROSSWALK
177-
EObjectType.GANTRY -> RoadObjectType.GANTRY
178-
EObjectType.ROAD_MARK -> RoadObjectType.ROAD_MARK
179-
EObjectType.ROAD_SURFACE -> RoadObjectType.ROAD_SURFACE
179+
private fun getObjectType(roadObject: OpendriveRoadObject): Pair<RoadObjectType, Option<RoadObjectSubType>> {
180+
val type =
181+
roadObject.type.fold({ RoadObjectType.NONE }, {
182+
when (it) {
183+
EObjectType.NONE -> RoadObjectType.NONE
184+
EObjectType.OBSTACLE -> RoadObjectType.OBSTACLE
185+
EObjectType.POLE -> RoadObjectType.POLE
186+
EObjectType.TREE -> RoadObjectType.TREE
187+
EObjectType.VEGETATION -> RoadObjectType.VEGETATION
188+
EObjectType.BARRIER -> RoadObjectType.BARRIER
189+
EObjectType.BUILDING -> RoadObjectType.BUILDING
190+
EObjectType.PARKING_SPACE -> RoadObjectType.PARKING_SPACE
191+
EObjectType.TRAFFIC_ISLAND -> RoadObjectType.TRAFFIC_ISLAND
192+
EObjectType.CROSSWALK -> RoadObjectType.CROSSWALK
193+
EObjectType.GANTRY -> RoadObjectType.GANTRY
194+
EObjectType.ROAD_MARK -> RoadObjectType.ROAD_MARK
195+
EObjectType.ROAD_SURFACE -> RoadObjectType.ROAD_SURFACE
196+
}
197+
})
198+
199+
val roadObjectSubType = roadObject.subtype.fold({ return type to None }, { it })
200+
val subType: Option<RoadObjectSubType> =
201+
when (type) {
202+
RoadObjectType.NONE -> None
203+
RoadObjectType.OBSTACLE -> RoadObjectSubType.fromIdentifier<RoadObjectObstacleSubType>(roadObjectSubType)
204+
RoadObjectType.POLE -> RoadObjectSubType.fromIdentifier<RoadObjectPoleSubType>(roadObjectSubType)
205+
RoadObjectType.TREE -> RoadObjectSubType.fromIdentifier<RoadObjectTreeSubType>(roadObjectSubType)
206+
RoadObjectType.VEGETATION -> RoadObjectSubType.fromIdentifier<RoadObjectVegetationSubType>(roadObjectSubType)
207+
RoadObjectType.BARRIER -> RoadObjectSubType.fromIdentifier<RoadObjectBarrierSubType>(roadObjectSubType)
208+
RoadObjectType.BUILDING -> RoadObjectSubType.fromIdentifier<RoadObjectBuildingSubType>(roadObjectSubType)
209+
RoadObjectType.PARKING_SPACE -> RoadObjectSubType.fromIdentifier<RoadObjectParkingSpaceSubType>(roadObjectSubType)
210+
RoadObjectType.TRAFFIC_ISLAND -> RoadObjectSubType.fromIdentifier<RoadObjectTrafficIslandSubType>(roadObjectSubType)
211+
RoadObjectType.CROSSWALK -> RoadObjectSubType.fromIdentifier<RoadObjectCrosswalkSubType>(roadObjectSubType)
212+
RoadObjectType.GANTRY -> RoadObjectSubType.fromIdentifier<RoadObjectGantrySubType>(roadObjectSubType)
213+
RoadObjectType.ROAD_MARK -> RoadObjectSubType.fromIdentifier<RoadObjectRoadMarkSubType>(roadObjectSubType)
214+
RoadObjectType.ROAD_SURFACE -> RoadObjectSubType.fromIdentifier<RoadObjectRoadSurfaceSubType>(roadObjectSubType)
215+
RoadObjectType.SIGNAL -> None
180216
}
181-
})
217+
218+
return type to subType
219+
}
182220

183221
private fun buildPointGeometry(
184222
roadObject: OpendriveRoadObject,
@@ -410,6 +448,7 @@ class RoadspaceObjectBuilder(
410448
RoadspaceObject(
411449
objectId,
412450
RoadObjectType.SIGNAL,
451+
None,
413452
pointGeometry,
414453
None,
415454
complexGeometry,

0 commit comments

Comments
 (0)