1use std::collections::HashMap;
32use strum_macros::{Display, EnumString};
33
34#[derive(Debug, Copy, Clone, PartialEq, Eq, EnumString, Display)]
35pub enum RoadObjectType {
37 None,
38 Unknown,
39 Barrier,
40 GuardWall,
41 GuardRail,
42 Building,
43 Gantry,
44 Obstacle,
45 Pole,
46 TrafficIsland,
47 Tree,
48 Vegetation,
49 Pylon,
50 Delineator,
51 BikeStatic,
52 BusStatic,
53 CarStatic,
54 MotorbikeStatic,
55 Patch,
56 PedestrianStatic,
57 Railing,
58 RoadSurface,
59 SoundBarrier,
60 StreetLamp,
61 TrailerStatic,
62 TrainStatic,
63 TramStatic,
64 VanStatic,
65 Wind,
66}
67
68fn road_object_type_from_cpp(obj_type: maliput_sys::api::objects::ffi::RoadObjectType) -> RoadObjectType {
69 match obj_type {
70 maliput_sys::api::objects::ffi::RoadObjectType::kUnknown => RoadObjectType::Unknown,
71 maliput_sys::api::objects::ffi::RoadObjectType::kBarrier => RoadObjectType::Barrier,
72 maliput_sys::api::objects::ffi::RoadObjectType::kGuardWall => RoadObjectType::GuardWall,
73 maliput_sys::api::objects::ffi::RoadObjectType::kGuardRail => RoadObjectType::GuardRail,
74 maliput_sys::api::objects::ffi::RoadObjectType::kBuilding => RoadObjectType::Building,
75 maliput_sys::api::objects::ffi::RoadObjectType::kGantry => RoadObjectType::Gantry,
76 maliput_sys::api::objects::ffi::RoadObjectType::kObstacle => RoadObjectType::Obstacle,
77 maliput_sys::api::objects::ffi::RoadObjectType::kPole => RoadObjectType::Pole,
78 maliput_sys::api::objects::ffi::RoadObjectType::kTrafficIsland => RoadObjectType::TrafficIsland,
79 maliput_sys::api::objects::ffi::RoadObjectType::kTree => RoadObjectType::Tree,
80 maliput_sys::api::objects::ffi::RoadObjectType::kVegetation => RoadObjectType::Vegetation,
81 maliput_sys::api::objects::ffi::RoadObjectType::kPylon => RoadObjectType::Pylon,
82 maliput_sys::api::objects::ffi::RoadObjectType::kDelineator => RoadObjectType::Delineator,
83 maliput_sys::api::objects::ffi::RoadObjectType::kBikeStatic => RoadObjectType::BikeStatic,
84 maliput_sys::api::objects::ffi::RoadObjectType::kBusStatic => RoadObjectType::BusStatic,
85 maliput_sys::api::objects::ffi::RoadObjectType::kCarStatic => RoadObjectType::CarStatic,
86 maliput_sys::api::objects::ffi::RoadObjectType::kMotorbikeStatic => RoadObjectType::MotorbikeStatic,
87 maliput_sys::api::objects::ffi::RoadObjectType::kPatch => RoadObjectType::Patch,
88 maliput_sys::api::objects::ffi::RoadObjectType::kPedestrianStatic => RoadObjectType::PedestrianStatic,
89 maliput_sys::api::objects::ffi::RoadObjectType::kRailing => RoadObjectType::Railing,
90 maliput_sys::api::objects::ffi::RoadObjectType::kRoadSurface => RoadObjectType::RoadSurface,
91 maliput_sys::api::objects::ffi::RoadObjectType::kSoundBarrier => RoadObjectType::SoundBarrier,
92 maliput_sys::api::objects::ffi::RoadObjectType::kStreetLamp => RoadObjectType::StreetLamp,
93 maliput_sys::api::objects::ffi::RoadObjectType::kTrailerStatic => RoadObjectType::TrailerStatic,
94 maliput_sys::api::objects::ffi::RoadObjectType::kTrainStatic => RoadObjectType::TrainStatic,
95 maliput_sys::api::objects::ffi::RoadObjectType::kTramStatic => RoadObjectType::TramStatic,
96 maliput_sys::api::objects::ffi::RoadObjectType::kVanStatic => RoadObjectType::VanStatic,
97 maliput_sys::api::objects::ffi::RoadObjectType::kWind => RoadObjectType::Wind,
98 _ => RoadObjectType::None,
99 }
100}
101
102fn road_object_type_to_cpp(obj_type: &RoadObjectType) -> maliput_sys::api::objects::ffi::RoadObjectType {
103 match obj_type {
104 RoadObjectType::None => maliput_sys::api::objects::ffi::RoadObjectType::kUnknown,
105 RoadObjectType::Unknown => maliput_sys::api::objects::ffi::RoadObjectType::kUnknown,
106 RoadObjectType::Barrier => maliput_sys::api::objects::ffi::RoadObjectType::kBarrier,
107 RoadObjectType::GuardWall => maliput_sys::api::objects::ffi::RoadObjectType::kGuardWall,
108 RoadObjectType::GuardRail => maliput_sys::api::objects::ffi::RoadObjectType::kGuardRail,
109 RoadObjectType::Building => maliput_sys::api::objects::ffi::RoadObjectType::kBuilding,
110 RoadObjectType::Gantry => maliput_sys::api::objects::ffi::RoadObjectType::kGantry,
111 RoadObjectType::Obstacle => maliput_sys::api::objects::ffi::RoadObjectType::kObstacle,
112 RoadObjectType::Pole => maliput_sys::api::objects::ffi::RoadObjectType::kPole,
113 RoadObjectType::TrafficIsland => maliput_sys::api::objects::ffi::RoadObjectType::kTrafficIsland,
114 RoadObjectType::Tree => maliput_sys::api::objects::ffi::RoadObjectType::kTree,
115 RoadObjectType::Vegetation => maliput_sys::api::objects::ffi::RoadObjectType::kVegetation,
116 RoadObjectType::Pylon => maliput_sys::api::objects::ffi::RoadObjectType::kPylon,
117 RoadObjectType::Delineator => maliput_sys::api::objects::ffi::RoadObjectType::kDelineator,
118 RoadObjectType::BikeStatic => maliput_sys::api::objects::ffi::RoadObjectType::kBikeStatic,
119 RoadObjectType::BusStatic => maliput_sys::api::objects::ffi::RoadObjectType::kBusStatic,
120 RoadObjectType::CarStatic => maliput_sys::api::objects::ffi::RoadObjectType::kCarStatic,
121 RoadObjectType::MotorbikeStatic => maliput_sys::api::objects::ffi::RoadObjectType::kMotorbikeStatic,
122 RoadObjectType::Patch => maliput_sys::api::objects::ffi::RoadObjectType::kPatch,
123 RoadObjectType::PedestrianStatic => maliput_sys::api::objects::ffi::RoadObjectType::kPedestrianStatic,
124 RoadObjectType::Railing => maliput_sys::api::objects::ffi::RoadObjectType::kRailing,
125 RoadObjectType::RoadSurface => maliput_sys::api::objects::ffi::RoadObjectType::kRoadSurface,
126 RoadObjectType::SoundBarrier => maliput_sys::api::objects::ffi::RoadObjectType::kSoundBarrier,
127 RoadObjectType::StreetLamp => maliput_sys::api::objects::ffi::RoadObjectType::kStreetLamp,
128 RoadObjectType::TrailerStatic => maliput_sys::api::objects::ffi::RoadObjectType::kTrailerStatic,
129 RoadObjectType::TrainStatic => maliput_sys::api::objects::ffi::RoadObjectType::kTrainStatic,
130 RoadObjectType::TramStatic => maliput_sys::api::objects::ffi::RoadObjectType::kTramStatic,
131 RoadObjectType::VanStatic => maliput_sys::api::objects::ffi::RoadObjectType::kVanStatic,
132 RoadObjectType::Wind => maliput_sys::api::objects::ffi::RoadObjectType::kWind,
133 }
134}
135
136#[cfg(test)]
137mod tests {
138 use super::{road_object_type_from_cpp, road_object_type_to_cpp, RoadObjectType};
139
140 #[test]
141 fn unknown_from_cpp_stays_unknown() {
142 let cpp = maliput_sys::api::objects::ffi::RoadObjectType::kUnknown;
143 assert_eq!(road_object_type_from_cpp(cpp), RoadObjectType::Unknown);
144 }
145
146 #[test]
147 fn none_to_cpp_maps_to_unknown() {
148 assert!(
149 road_object_type_to_cpp(&RoadObjectType::None) == maliput_sys::api::objects::ffi::RoadObjectType::kUnknown
150 );
151 }
152}
153
154pub struct RoadObjectPosition {
159 pub inertial_position: crate::api::InertialPosition,
160 pub lane_position: Option<(String, f64, f64, f64)>,
161}
162
163pub struct OutlineCorner {
167 pub x: f64,
168 pub y: f64,
169 pub z: f64,
170 pub height: Option<f64>,
171}
172
173pub struct Outline<'a> {
175 pub(crate) outline: &'a maliput_sys::api::objects::ffi::Outline,
176}
177
178impl<'a> Outline<'a> {
179 pub fn id(&self) -> String {
181 maliput_sys::api::objects::ffi::Outline_id(self.outline)
182 }
183
184 pub fn is_closed(&self) -> bool {
186 maliput_sys::api::objects::ffi::Outline_is_closed(self.outline)
187 }
188
189 pub fn num_corners(&self) -> i32 {
191 maliput_sys::api::objects::ffi::Outline_num_corners(self.outline)
192 }
193
194 pub fn corners(&self) -> Vec<OutlineCorner> {
196 maliput_sys::api::objects::ffi::Outline_corners(self.outline)
197 .into_iter()
198 .map(|c| OutlineCorner {
199 x: c.x,
200 y: c.y,
201 z: c.z,
202 height: if c.has_height { Some(c.height) } else { None },
203 })
204 .collect()
205 }
206}
207
208pub struct RoadObject<'a> {
213 pub(crate) road_object: &'a maliput_sys::api::objects::ffi::RoadObject,
214}
215
216impl<'a> RoadObject<'a> {
217 pub fn id(&self) -> String {
219 maliput_sys::api::objects::ffi::RoadObject_id(self.road_object)
220 }
221
222 pub fn name(&self) -> Option<String> {
224 let wrapper = maliput_sys::api::objects::ffi::RoadObject_name(self.road_object);
225 if wrapper.is_null() {
226 return None;
227 }
228 Some(wrapper.value.clone())
229 }
230
231 pub fn object_type(&self) -> RoadObjectType {
233 let t = maliput_sys::api::objects::ffi::RoadObject_object_type(self.road_object);
234 road_object_type_from_cpp(t)
235 }
236
237 pub fn subtype(&self) -> Option<String> {
239 let wrapper = maliput_sys::api::objects::ffi::RoadObject_subtype(self.road_object);
240 if wrapper.is_null() {
241 return None;
242 }
243 Some(wrapper.value.clone())
244 }
245
246 pub fn position(&self) -> RoadObjectPosition {
248 let inertial_position = maliput_sys::api::objects::ffi::RoadObject_position_inertial(self.road_object);
249 let has_lane = maliput_sys::api::objects::ffi::RoadObject_position_has_lane_position(self.road_object);
250 let lane_position = if has_lane {
251 Some((
252 maliput_sys::api::objects::ffi::RoadObject_position_lane_id(self.road_object),
253 maliput_sys::api::objects::ffi::RoadObject_position_lane_s(self.road_object),
254 maliput_sys::api::objects::ffi::RoadObject_position_lane_r(self.road_object),
255 maliput_sys::api::objects::ffi::RoadObject_position_lane_h(self.road_object),
256 ))
257 } else {
258 None
259 };
260 RoadObjectPosition {
261 inertial_position: crate::api::InertialPosition { ip: inertial_position },
262 lane_position,
263 }
264 }
265
266 pub fn orientation(&self) -> crate::api::Rotation {
268 let rotation = maliput_sys::api::objects::ffi::RoadObject_orientation(self.road_object);
269 crate::api::Rotation { r: rotation }
270 }
271
272 pub fn bounding_box(&self) -> crate::math::BoundingBox {
274 let b = maliput_sys::api::objects::ffi::RoadObject_bounding_box(self.road_object);
275 crate::math::BoundingBox { b }
276 }
277
278 pub fn is_dynamic(&self) -> bool {
280 maliput_sys::api::objects::ffi::RoadObject::is_dynamic(self.road_object)
281 }
282
283 pub fn is_movable(&self) -> bool {
285 maliput_sys::api::objects::ffi::RoadObject::is_movable(self.road_object)
286 }
287
288 pub fn related_lanes(&self) -> Vec<String> {
290 maliput_sys::api::objects::ffi::RoadObject_related_lanes(self.road_object)
291 }
292
293 pub fn num_outlines(&self) -> i32 {
295 maliput_sys::api::objects::ffi::RoadObject::num_outlines(self.road_object)
296 }
297
298 pub fn outlines(&self) -> Vec<Outline<'_>> {
300 maliput_sys::api::objects::ffi::RoadObject_outlines(self.road_object)
301 .into_iter()
302 .map(|ptr| Outline {
303 outline: unsafe { ptr.outline.as_ref().expect("Outline pointer is null") },
304 })
305 .collect()
306 }
307
308 pub fn properties(&self) -> HashMap<String, String> {
310 maliput_sys::api::objects::ffi::RoadObject_properties(self.road_object)
311 .into_iter()
312 .map(|p| (p.key, p.value))
313 .collect()
314 }
315}
316
317pub struct RoadObjectBook<'a> {
319 pub(super) road_object_book: &'a maliput_sys::api::objects::ffi::RoadObjectBook,
320}
321
322impl<'a> RoadObjectBook<'a> {
323 pub fn road_objects(&self) -> Vec<RoadObject<'_>> {
325 maliput_sys::api::objects::ffi::RoadObjectBook_RoadObjects(self.road_object_book)
326 .into_iter()
327 .map(|ptr| RoadObject {
328 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
329 })
330 .collect()
331 }
332
333 pub fn get_road_object(&self, id: &String) -> Option<RoadObject<'_>> {
335 let ptr = maliput_sys::api::objects::ffi::RoadObjectBook_GetRoadObject(self.road_object_book, id);
336 if ptr.is_null() {
337 return None;
338 }
339 Some(RoadObject {
340 road_object: unsafe { ptr.as_ref().expect("Unable to get underlying RoadObject pointer") },
341 })
342 }
343
344 pub fn find_by_type(&self, obj_type: &RoadObjectType) -> Vec<RoadObject<'_>> {
346 let obj_type_ffi = road_object_type_to_cpp(obj_type);
347 maliput_sys::api::objects::ffi::RoadObjectBook_FindByType(self.road_object_book, obj_type_ffi)
348 .into_iter()
349 .map(|ptr| RoadObject {
350 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
351 })
352 .collect()
353 }
354
355 pub fn find_by_lane(&self, lane_id: &String) -> Vec<RoadObject<'_>> {
357 maliput_sys::api::objects::ffi::RoadObjectBook_FindByLane(self.road_object_book, lane_id)
358 .into_iter()
359 .map(|ptr| RoadObject {
360 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
361 })
362 .collect()
363 }
364
365 pub fn find_in_radius(&self, x: f64, y: f64, z: f64, radius: f64) -> Vec<RoadObject<'_>> {
367 maliput_sys::api::objects::ffi::RoadObjectBook_FindInRadius(self.road_object_book, x, y, z, radius)
368 .into_iter()
369 .map(|ptr| RoadObject {
370 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
371 })
372 .collect()
373 }
374}
375
376pub type RoadMarkingType = crate::api::rules::TrafficControlDeviceType;
378
379#[derive(Debug, Copy, Clone, PartialEq, Eq)]
380pub enum RoadMarkingValueUnit {
382 MetersPerSecond,
383 KilometersPerHour,
384 MilesPerHour,
385}
386
387fn road_marking_value_unit_from_cpp(u: maliput_sys::api::objects::ffi::RoadMarkingValueUnit) -> RoadMarkingValueUnit {
388 match u {
389 maliput_sys::api::objects::ffi::RoadMarkingValueUnit::kMetersPerSecond => RoadMarkingValueUnit::MetersPerSecond,
390 maliput_sys::api::objects::ffi::RoadMarkingValueUnit::kKilometersPerHour => {
391 RoadMarkingValueUnit::KilometersPerHour
392 }
393 maliput_sys::api::objects::ffi::RoadMarkingValueUnit::kMilesPerHour => RoadMarkingValueUnit::MilesPerHour,
394 _ => RoadMarkingValueUnit::MetersPerSecond,
395 }
396}
397
398#[derive(Debug, Copy, Clone, PartialEq)]
400pub struct RoadMarkingValue {
401 pub value: f64,
402 pub unit: RoadMarkingValueUnit,
403}
404
405pub struct RoadMarking<'a> {
407 pub(crate) road_marking: &'a maliput_sys::api::objects::ffi::RoadMarking,
408}
409
410impl<'a> RoadMarking<'a> {
411 pub fn id(&self) -> String {
413 maliput_sys::api::objects::ffi::RoadMarking_id(self.road_marking)
414 }
415
416 pub fn name(&self) -> Option<String> {
418 let wrapper = maliput_sys::api::objects::ffi::RoadMarking_name(self.road_marking);
419 if wrapper.is_null() {
420 return None;
421 }
422 Some(wrapper.value.clone())
423 }
424
425 pub fn marking_type(&self) -> RoadMarkingType {
427 let t = maliput_sys::api::objects::ffi::RoadMarking_marking_type(self.road_marking);
428 crate::api::rules::traffic_control_device_type_from_cpp(&t)
429 }
430
431 pub fn position(&self) -> RoadObjectPosition {
433 let inertial_position = maliput_sys::api::objects::ffi::RoadMarking_position_inertial(self.road_marking);
434 let has_lane = maliput_sys::api::objects::ffi::RoadMarking_position_has_lane_position(self.road_marking);
435 let lane_position = if has_lane {
436 Some((
437 maliput_sys::api::objects::ffi::RoadMarking_position_lane_id(self.road_marking),
438 maliput_sys::api::objects::ffi::RoadMarking_position_lane_s(self.road_marking),
439 maliput_sys::api::objects::ffi::RoadMarking_position_lane_r(self.road_marking),
440 maliput_sys::api::objects::ffi::RoadMarking_position_lane_h(self.road_marking),
441 ))
442 } else {
443 None
444 };
445 RoadObjectPosition {
446 inertial_position: crate::api::InertialPosition { ip: inertial_position },
447 lane_position,
448 }
449 }
450
451 pub fn orientation(&self) -> crate::api::Rotation {
453 let rotation = maliput_sys::api::objects::ffi::RoadMarking_orientation(self.road_marking);
454 crate::api::Rotation { r: rotation }
455 }
456
457 pub fn bounding_box(&self) -> crate::math::BoundingBox {
459 let b = maliput_sys::api::objects::ffi::RoadMarking_bounding_box(self.road_marking);
460 crate::math::BoundingBox { b }
461 }
462
463 pub fn related_lanes(&self) -> Vec<String> {
465 maliput_sys::api::objects::ffi::RoadMarking_related_lanes(self.road_marking)
466 }
467
468 pub fn num_outlines(&self) -> i32 {
470 maliput_sys::api::objects::ffi::RoadMarking::num_outlines(self.road_marking)
471 }
472
473 pub fn outlines(&self) -> Vec<Outline<'_>> {
475 maliput_sys::api::objects::ffi::RoadMarking_outlines(self.road_marking)
476 .into_iter()
477 .map(|ptr| Outline {
478 outline: unsafe { ptr.outline.as_ref().expect("Outline pointer is null") },
479 })
480 .collect()
481 }
482
483 pub fn value(&self) -> Option<RoadMarkingValue> {
485 let data = maliput_sys::api::objects::ffi::RoadMarking_value(self.road_marking);
486 if !data.has_value {
487 return None;
488 }
489 Some(RoadMarkingValue {
490 value: data.value,
491 unit: road_marking_value_unit_from_cpp(data.unit),
492 })
493 }
494}
495
496pub struct RoadMarkingBook<'a> {
498 pub(super) road_marking_book: &'a maliput_sys::api::objects::ffi::RoadMarkingBook,
499}
500
501impl<'a> RoadMarkingBook<'a> {
502 pub fn road_markings(&self) -> Vec<RoadMarking<'_>> {
504 maliput_sys::api::objects::ffi::RoadMarkingBook_RoadMarkings(self.road_marking_book)
505 .into_iter()
506 .map(|ptr| RoadMarking {
507 road_marking: unsafe { ptr.road_marking.as_ref().expect("RoadMarking pointer is null") },
508 })
509 .collect()
510 }
511
512 pub fn get_road_marking(&self, id: &String) -> Option<RoadMarking<'_>> {
514 let ptr = maliput_sys::api::objects::ffi::RoadMarkingBook_GetRoadMarking(self.road_marking_book, id);
515 if ptr.is_null() {
516 return None;
517 }
518 Some(RoadMarking {
519 road_marking: unsafe { ptr.as_ref().expect("Unable to get underlying RoadMarking pointer") },
520 })
521 }
522
523 pub fn find_by_lane(&self, lane_id: &String) -> Vec<RoadMarking<'_>> {
525 maliput_sys::api::objects::ffi::RoadMarkingBook_FindByLane(self.road_marking_book, lane_id)
526 .into_iter()
527 .map(|ptr| RoadMarking {
528 road_marking: unsafe { ptr.road_marking.as_ref().expect("RoadMarking pointer is null") },
529 })
530 .collect()
531 }
532
533 pub fn find_by_type(&self, marking_type: &RoadMarkingType) -> Vec<RoadMarking<'_>> {
535 let t_ffi = crate::api::rules::traffic_control_device_type_to_cpp(marking_type);
536 maliput_sys::api::objects::ffi::RoadMarkingBook_FindByType(self.road_marking_book, t_ffi)
537 .into_iter()
538 .map(|ptr| RoadMarking {
539 road_marking: unsafe { ptr.road_marking.as_ref().expect("RoadMarking pointer is null") },
540 })
541 .collect()
542 }
543}