1use std::collections::HashMap;
32use strum_macros::{Display, EnumString};
33
34#[derive(Debug, Copy, Clone, PartialEq, Eq, EnumString, Display)]
35pub enum RoadObjectType {
37 Unknown,
38 Barrier,
39 GuardWall,
40 GuardRail,
41 Building,
42 Gantry,
43 Obstacle,
44 Pole,
45 TrafficIsland,
46 Tree,
47 Vegetation,
48 Pylon,
49 Delineator,
50}
51
52fn road_object_type_from_cpp(obj_type: maliput_sys::api::objects::ffi::RoadObjectType) -> RoadObjectType {
53 match obj_type {
54 maliput_sys::api::objects::ffi::RoadObjectType::kUnknown => RoadObjectType::Unknown,
55 maliput_sys::api::objects::ffi::RoadObjectType::kBarrier => RoadObjectType::Barrier,
56 maliput_sys::api::objects::ffi::RoadObjectType::kGuardWall => RoadObjectType::GuardWall,
57 maliput_sys::api::objects::ffi::RoadObjectType::kGuardRail => RoadObjectType::GuardRail,
58 maliput_sys::api::objects::ffi::RoadObjectType::kBuilding => RoadObjectType::Building,
59 maliput_sys::api::objects::ffi::RoadObjectType::kGantry => RoadObjectType::Gantry,
60 maliput_sys::api::objects::ffi::RoadObjectType::kObstacle => RoadObjectType::Obstacle,
61 maliput_sys::api::objects::ffi::RoadObjectType::kPole => RoadObjectType::Pole,
62 maliput_sys::api::objects::ffi::RoadObjectType::kTrafficIsland => RoadObjectType::TrafficIsland,
63 maliput_sys::api::objects::ffi::RoadObjectType::kTree => RoadObjectType::Tree,
64 maliput_sys::api::objects::ffi::RoadObjectType::kVegetation => RoadObjectType::Vegetation,
65 maliput_sys::api::objects::ffi::RoadObjectType::kPylon => RoadObjectType::Pylon,
66 maliput_sys::api::objects::ffi::RoadObjectType::kDelineator => RoadObjectType::Delineator,
67 _ => RoadObjectType::Unknown,
68 }
69}
70
71fn road_object_type_to_cpp(obj_type: &RoadObjectType) -> maliput_sys::api::objects::ffi::RoadObjectType {
72 match obj_type {
73 RoadObjectType::Unknown => maliput_sys::api::objects::ffi::RoadObjectType::kUnknown,
74 RoadObjectType::Barrier => maliput_sys::api::objects::ffi::RoadObjectType::kBarrier,
75 RoadObjectType::GuardWall => maliput_sys::api::objects::ffi::RoadObjectType::kGuardWall,
76 RoadObjectType::GuardRail => maliput_sys::api::objects::ffi::RoadObjectType::kGuardRail,
77 RoadObjectType::Building => maliput_sys::api::objects::ffi::RoadObjectType::kBuilding,
78 RoadObjectType::Gantry => maliput_sys::api::objects::ffi::RoadObjectType::kGantry,
79 RoadObjectType::Obstacle => maliput_sys::api::objects::ffi::RoadObjectType::kObstacle,
80 RoadObjectType::Pole => maliput_sys::api::objects::ffi::RoadObjectType::kPole,
81 RoadObjectType::TrafficIsland => maliput_sys::api::objects::ffi::RoadObjectType::kTrafficIsland,
82 RoadObjectType::Tree => maliput_sys::api::objects::ffi::RoadObjectType::kTree,
83 RoadObjectType::Vegetation => maliput_sys::api::objects::ffi::RoadObjectType::kVegetation,
84 RoadObjectType::Pylon => maliput_sys::api::objects::ffi::RoadObjectType::kPylon,
85 RoadObjectType::Delineator => maliput_sys::api::objects::ffi::RoadObjectType::kDelineator,
86 }
87}
88
89pub struct RoadObjectPosition {
94 pub inertial_position: crate::api::InertialPosition,
95 pub lane_position: Option<(String, f64, f64, f64)>,
96}
97
98pub struct OutlineCorner {
102 pub x: f64,
103 pub y: f64,
104 pub z: f64,
105 pub height: Option<f64>,
106}
107
108pub struct Outline<'a> {
110 pub(crate) outline: &'a maliput_sys::api::objects::ffi::Outline,
111}
112
113impl<'a> Outline<'a> {
114 pub fn id(&self) -> String {
116 maliput_sys::api::objects::ffi::Outline_id(self.outline)
117 }
118
119 pub fn is_closed(&self) -> bool {
121 maliput_sys::api::objects::ffi::Outline_is_closed(self.outline)
122 }
123
124 pub fn num_corners(&self) -> i32 {
126 maliput_sys::api::objects::ffi::Outline_num_corners(self.outline)
127 }
128
129 pub fn corners(&self) -> Vec<OutlineCorner> {
131 maliput_sys::api::objects::ffi::Outline_corners(self.outline)
132 .into_iter()
133 .map(|c| OutlineCorner {
134 x: c.x,
135 y: c.y,
136 z: c.z,
137 height: if c.has_height { Some(c.height) } else { None },
138 })
139 .collect()
140 }
141}
142
143pub struct RoadObject<'a> {
148 pub(crate) road_object: &'a maliput_sys::api::objects::ffi::RoadObject,
149}
150
151impl<'a> RoadObject<'a> {
152 pub fn id(&self) -> String {
154 maliput_sys::api::objects::ffi::RoadObject_id(self.road_object)
155 }
156
157 pub fn name(&self) -> Option<String> {
159 let wrapper = maliput_sys::api::objects::ffi::RoadObject_name(self.road_object);
160 if wrapper.is_null() {
161 return None;
162 }
163 Some(wrapper.value.clone())
164 }
165
166 pub fn object_type(&self) -> RoadObjectType {
168 let t = maliput_sys::api::objects::ffi::RoadObject_object_type(self.road_object);
169 road_object_type_from_cpp(t)
170 }
171
172 pub fn subtype(&self) -> Option<String> {
174 let wrapper = maliput_sys::api::objects::ffi::RoadObject_subtype(self.road_object);
175 if wrapper.is_null() {
176 return None;
177 }
178 Some(wrapper.value.clone())
179 }
180
181 pub fn position(&self) -> RoadObjectPosition {
183 let inertial_position = maliput_sys::api::objects::ffi::RoadObject_position_inertial(self.road_object);
184 let has_lane = maliput_sys::api::objects::ffi::RoadObject_position_has_lane_position(self.road_object);
185 let lane_position = if has_lane {
186 Some((
187 maliput_sys::api::objects::ffi::RoadObject_position_lane_id(self.road_object),
188 maliput_sys::api::objects::ffi::RoadObject_position_lane_s(self.road_object),
189 maliput_sys::api::objects::ffi::RoadObject_position_lane_r(self.road_object),
190 maliput_sys::api::objects::ffi::RoadObject_position_lane_h(self.road_object),
191 ))
192 } else {
193 None
194 };
195 RoadObjectPosition {
196 inertial_position: crate::api::InertialPosition { ip: inertial_position },
197 lane_position,
198 }
199 }
200
201 pub fn orientation(&self) -> crate::api::Rotation {
203 let rotation = maliput_sys::api::objects::ffi::RoadObject_orientation(self.road_object);
204 crate::api::Rotation { r: rotation }
205 }
206
207 pub fn bounding_box(&self) -> crate::math::BoundingBox {
209 let b = maliput_sys::api::objects::ffi::RoadObject_bounding_box(self.road_object);
210 crate::math::BoundingBox { b }
211 }
212
213 pub fn is_dynamic(&self) -> bool {
215 maliput_sys::api::objects::ffi::RoadObject::is_dynamic(self.road_object)
216 }
217
218 pub fn is_movable(&self) -> bool {
220 maliput_sys::api::objects::ffi::RoadObject::is_movable(self.road_object)
221 }
222
223 pub fn related_lanes(&self) -> Vec<String> {
225 maliput_sys::api::objects::ffi::RoadObject_related_lanes(self.road_object)
226 }
227
228 pub fn num_outlines(&self) -> i32 {
230 maliput_sys::api::objects::ffi::RoadObject::num_outlines(self.road_object)
231 }
232
233 pub fn outlines(&self) -> Vec<Outline<'_>> {
235 maliput_sys::api::objects::ffi::RoadObject_outlines(self.road_object)
236 .into_iter()
237 .map(|ptr| Outline {
238 outline: unsafe { ptr.outline.as_ref().expect("Outline pointer is null") },
239 })
240 .collect()
241 }
242
243 pub fn properties(&self) -> HashMap<String, String> {
245 maliput_sys::api::objects::ffi::RoadObject_properties(self.road_object)
246 .into_iter()
247 .map(|p| (p.key, p.value))
248 .collect()
249 }
250}
251
252pub struct RoadObjectBook<'a> {
254 pub(super) road_object_book: &'a maliput_sys::api::objects::ffi::RoadObjectBook,
255}
256
257impl<'a> RoadObjectBook<'a> {
258 pub fn road_objects(&self) -> Vec<RoadObject<'_>> {
260 maliput_sys::api::objects::ffi::RoadObjectBook_RoadObjects(self.road_object_book)
261 .into_iter()
262 .map(|ptr| RoadObject {
263 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
264 })
265 .collect()
266 }
267
268 pub fn get_road_object(&self, id: &String) -> Option<RoadObject<'_>> {
270 let ptr = maliput_sys::api::objects::ffi::RoadObjectBook_GetRoadObject(self.road_object_book, id);
271 if ptr.is_null() {
272 return None;
273 }
274 Some(RoadObject {
275 road_object: unsafe { ptr.as_ref().expect("Unable to get underlying RoadObject pointer") },
276 })
277 }
278
279 pub fn find_by_type(&self, obj_type: &RoadObjectType) -> Vec<RoadObject<'_>> {
281 let obj_type_ffi = road_object_type_to_cpp(obj_type);
282 maliput_sys::api::objects::ffi::RoadObjectBook_FindByType(self.road_object_book, obj_type_ffi)
283 .into_iter()
284 .map(|ptr| RoadObject {
285 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
286 })
287 .collect()
288 }
289
290 pub fn find_by_lane(&self, lane_id: &String) -> Vec<RoadObject<'_>> {
292 maliput_sys::api::objects::ffi::RoadObjectBook_FindByLane(self.road_object_book, lane_id)
293 .into_iter()
294 .map(|ptr| RoadObject {
295 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
296 })
297 .collect()
298 }
299
300 pub fn find_in_radius(&self, x: f64, y: f64, z: f64, radius: f64) -> Vec<RoadObject<'_>> {
302 maliput_sys::api::objects::ffi::RoadObjectBook_FindInRadius(self.road_object_book, x, y, z, radius)
303 .into_iter()
304 .map(|ptr| RoadObject {
305 road_object: unsafe { ptr.road_object.as_ref().expect("RoadObject pointer is null") },
306 })
307 .collect()
308 }
309}
310
311pub type RoadMarkingType = crate::api::rules::TrafficControlDeviceType;
313
314#[derive(Debug, Copy, Clone, PartialEq, Eq)]
315pub enum RoadMarkingValueUnit {
317 MetersPerSecond,
318 KilometersPerHour,
319 MilesPerHour,
320}
321
322fn road_marking_value_unit_from_cpp(u: maliput_sys::api::objects::ffi::RoadMarkingValueUnit) -> RoadMarkingValueUnit {
323 match u {
324 maliput_sys::api::objects::ffi::RoadMarkingValueUnit::kMetersPerSecond => RoadMarkingValueUnit::MetersPerSecond,
325 maliput_sys::api::objects::ffi::RoadMarkingValueUnit::kKilometersPerHour => {
326 RoadMarkingValueUnit::KilometersPerHour
327 }
328 maliput_sys::api::objects::ffi::RoadMarkingValueUnit::kMilesPerHour => RoadMarkingValueUnit::MilesPerHour,
329 _ => RoadMarkingValueUnit::MetersPerSecond,
330 }
331}
332
333#[derive(Debug, Copy, Clone, PartialEq)]
335pub struct RoadMarkingValue {
336 pub value: f64,
337 pub unit: RoadMarkingValueUnit,
338}
339
340pub struct RoadMarking<'a> {
342 pub(crate) road_marking: &'a maliput_sys::api::objects::ffi::RoadMarking,
343}
344
345impl<'a> RoadMarking<'a> {
346 pub fn id(&self) -> String {
348 maliput_sys::api::objects::ffi::RoadMarking_id(self.road_marking)
349 }
350
351 pub fn name(&self) -> Option<String> {
353 let wrapper = maliput_sys::api::objects::ffi::RoadMarking_name(self.road_marking);
354 if wrapper.is_null() {
355 return None;
356 }
357 Some(wrapper.value.clone())
358 }
359
360 pub fn marking_type(&self) -> RoadMarkingType {
362 let t = maliput_sys::api::objects::ffi::RoadMarking_marking_type(self.road_marking);
363 crate::api::rules::traffic_control_device_type_from_cpp(&t)
364 }
365
366 pub fn position(&self) -> RoadObjectPosition {
368 let inertial_position = maliput_sys::api::objects::ffi::RoadMarking_position_inertial(self.road_marking);
369 let has_lane = maliput_sys::api::objects::ffi::RoadMarking_position_has_lane_position(self.road_marking);
370 let lane_position = if has_lane {
371 Some((
372 maliput_sys::api::objects::ffi::RoadMarking_position_lane_id(self.road_marking),
373 maliput_sys::api::objects::ffi::RoadMarking_position_lane_s(self.road_marking),
374 maliput_sys::api::objects::ffi::RoadMarking_position_lane_r(self.road_marking),
375 maliput_sys::api::objects::ffi::RoadMarking_position_lane_h(self.road_marking),
376 ))
377 } else {
378 None
379 };
380 RoadObjectPosition {
381 inertial_position: crate::api::InertialPosition { ip: inertial_position },
382 lane_position,
383 }
384 }
385
386 pub fn orientation(&self) -> crate::api::Rotation {
388 let rotation = maliput_sys::api::objects::ffi::RoadMarking_orientation(self.road_marking);
389 crate::api::Rotation { r: rotation }
390 }
391
392 pub fn bounding_box(&self) -> crate::math::BoundingBox {
394 let b = maliput_sys::api::objects::ffi::RoadMarking_bounding_box(self.road_marking);
395 crate::math::BoundingBox { b }
396 }
397
398 pub fn related_lanes(&self) -> Vec<String> {
400 maliput_sys::api::objects::ffi::RoadMarking_related_lanes(self.road_marking)
401 }
402
403 pub fn num_outlines(&self) -> i32 {
405 maliput_sys::api::objects::ffi::RoadMarking::num_outlines(self.road_marking)
406 }
407
408 pub fn outlines(&self) -> Vec<Outline<'_>> {
410 maliput_sys::api::objects::ffi::RoadMarking_outlines(self.road_marking)
411 .into_iter()
412 .map(|ptr| Outline {
413 outline: unsafe { ptr.outline.as_ref().expect("Outline pointer is null") },
414 })
415 .collect()
416 }
417
418 pub fn value(&self) -> Option<RoadMarkingValue> {
420 let data = maliput_sys::api::objects::ffi::RoadMarking_value(self.road_marking);
421 if !data.has_value {
422 return None;
423 }
424 Some(RoadMarkingValue {
425 value: data.value,
426 unit: road_marking_value_unit_from_cpp(data.unit),
427 })
428 }
429}
430
431pub struct RoadMarkingBook<'a> {
433 pub(super) road_marking_book: &'a maliput_sys::api::objects::ffi::RoadMarkingBook,
434}
435
436impl<'a> RoadMarkingBook<'a> {
437 pub fn road_markings(&self) -> Vec<RoadMarking<'_>> {
439 maliput_sys::api::objects::ffi::RoadMarkingBook_RoadMarkings(self.road_marking_book)
440 .into_iter()
441 .map(|ptr| RoadMarking {
442 road_marking: unsafe { ptr.road_marking.as_ref().expect("RoadMarking pointer is null") },
443 })
444 .collect()
445 }
446
447 pub fn get_road_marking(&self, id: &String) -> Option<RoadMarking<'_>> {
449 let ptr = maliput_sys::api::objects::ffi::RoadMarkingBook_GetRoadMarking(self.road_marking_book, id);
450 if ptr.is_null() {
451 return None;
452 }
453 Some(RoadMarking {
454 road_marking: unsafe { ptr.as_ref().expect("Unable to get underlying RoadMarking pointer") },
455 })
456 }
457
458 pub fn find_by_lane(&self, lane_id: &String) -> Vec<RoadMarking<'_>> {
460 maliput_sys::api::objects::ffi::RoadMarkingBook_FindByLane(self.road_marking_book, lane_id)
461 .into_iter()
462 .map(|ptr| RoadMarking {
463 road_marking: unsafe { ptr.road_marking.as_ref().expect("RoadMarking pointer is null") },
464 })
465 .collect()
466 }
467
468 pub fn find_by_type(&self, marking_type: &RoadMarkingType) -> Vec<RoadMarking<'_>> {
470 let t_ffi = crate::api::rules::traffic_control_device_type_to_cpp(marking_type);
471 maliput_sys::api::objects::ffi::RoadMarkingBook_FindByType(self.road_marking_book, t_ffi)
472 .into_iter()
473 .map(|ptr| RoadMarking {
474 road_marking: unsafe { ptr.road_marking.as_ref().expect("RoadMarking pointer is null") },
475 })
476 .collect()
477 }
478}