use core::slice;
use super::{Junction, Landmark, LandmarkList, Waypoint, WaypointList};
use crate::{
error::ffi::with_ffi_error,
geom::{GeoLocation, Location, Transform},
road::{LaneId, LaneType, RoadId},
};
use autocxx::WithinUniquePtr;
use carla_sys::carla_rust::client::{FfiMap, FfiTransformList};
use cxx::{SharedPtr, UniquePtr};
use derivative::Derivative;
use static_assertions::assert_impl_all;
#[derive(Clone, Derivative)]
#[derivative(Debug)]
#[repr(transparent)]
pub struct Map {
#[derivative(Debug = "ignore")]
inner: SharedPtr<FfiMap>,
}
impl Map {
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.name](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.name)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.name](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.name)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.name](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.name)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn name(&self) -> String {
self.inner.GetName().to_string()
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.to_opendrive](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.to_opendrive)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.to_opendrive](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.to_opendrive)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.to_opendrive](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.to_opendrive)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn to_open_drive(&self) -> String {
self.inner.GetOpenDrive().to_string()
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.get_spawn_points](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.get_spawn_points)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.get_spawn_points](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.get_spawn_points)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.get_spawn_points](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.get_spawn_points)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn recommended_spawn_points(&self) -> crate::Result<RecommendedSpawnPoints> {
let ptr = with_ffi_error("recommended_spawn_points", |e| {
self.inner.GetRecommendedSpawnPoints(e).within_unique_ptr()
})?;
Ok(unsafe { RecommendedSpawnPoints::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.get_waypoint](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.get_waypoint)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.get_waypoint](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.get_waypoint)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.get_waypoint](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.get_waypoint)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn waypoint_at(&self, location: &Location) -> crate::Result<Option<Waypoint>> {
let ptr = with_ffi_error("waypoint_at", |e| {
self.inner
.GetWaypoint(location.as_ffi(), true, LaneType::Driving as i32, e)
})?;
Ok(Waypoint::from_cxx(ptr))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.get_waypoint](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.get_waypoint)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.get_waypoint](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.get_waypoint)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.get_waypoint](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.get_waypoint)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn waypoint_opt(
&self,
location: &Location,
project_to_road: bool,
lane_type: LaneType,
) -> crate::Result<Option<Waypoint>> {
let ptr = with_ffi_error("waypoint_opt", |e| {
self.inner
.GetWaypoint(location.as_ffi(), project_to_road, lane_type as i32, e)
})?;
Ok(Waypoint::from_cxx(ptr))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.get_waypoint_xodr](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.get_waypoint_xodr)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.get_waypoint_xodr](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.get_waypoint_xodr)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.get_waypoint_xodr](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.get_waypoint_xodr)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn waypoint_xodr(
&self,
road_id: RoadId,
lane_id: LaneId,
distance: f32,
) -> crate::Result<Option<Waypoint>> {
let ptr = with_ffi_error("waypoint_xodr", |e| {
self.inner
.GetWaypointXODR(road_id.into(), lane_id.into(), distance, e)
})?;
Ok(Waypoint::from_cxx(ptr))
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.generate_waypoints](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.generate_waypoints)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.generate_waypoints](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.generate_waypoints)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.generate_waypoints](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.generate_waypoints)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn generate_waypoints(&self, distance: f64) -> crate::Result<WaypointList> {
let waypoints = with_ffi_error("generate_waypoints", |e| {
self.inner.GenerateWaypoints(distance, e)
})?;
Ok(unsafe { WaypointList::from_cxx(waypoints).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.get_junction](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.get_junction)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.get_junction](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.get_junction)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.get_junction](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.get_junction)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn junction(&self, waypoint: &Waypoint) -> crate::Result<Junction> {
let junction = with_ffi_error("junction", |e| self.inner.GetJunction(&waypoint.inner, e))?;
Ok(unsafe { Junction::from_cxx(junction).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.get_all_landmarks](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.get_all_landmarks)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.get_all_landmarks](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.get_all_landmarks)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.get_all_landmarks](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.get_all_landmarks)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn all_landmarks(&self) -> crate::Result<LandmarkList> {
let ptr = with_ffi_error("all_landmarks", |e| self.inner.GetAllLandmarks(e))?;
Ok(unsafe { LandmarkList::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.get_landmark_from_id](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.get_landmark_from_id)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.get_landmark_from_id](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.get_landmark_from_id)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.get_landmark_from_id](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.get_landmark_from_id)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn landmarks_from_id(&self, id: &str) -> crate::Result<LandmarkList> {
let ptr = with_ffi_error("landmarks_from_id", |e| {
self.inner.GetLandmarksFromId(id, e)
})?;
Ok(unsafe { LandmarkList::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.get_all_landmarks_of_type](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.get_all_landmarks_of_type)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.get_all_landmarks_of_type](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.get_all_landmarks_of_type)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.get_all_landmarks_of_type](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.get_all_landmarks_of_type)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn all_landmarks_of_type(&self, type_: &str) -> crate::Result<LandmarkList> {
let ptr = with_ffi_error("all_landmarks_of_type", |e| {
self.inner.GetAllLandmarksOfType(type_, e)
})?;
Ok(unsafe { LandmarkList::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.get_landmark_group](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.get_landmark_group)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.get_landmark_group](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.get_landmark_group)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.get_landmark_group](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.get_landmark_group)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn landmark_group(&self, landmark: &Landmark) -> crate::Result<LandmarkList> {
let ptr = with_ffi_error("landmark_group", |e| {
self.inner.GetLandmarkGroup(&landmark.inner, e)
})?;
Ok(unsafe { LandmarkList::from_cxx(ptr).unwrap_unchecked() })
}
#[cfg_attr(
carla_version_0916,
doc = " See [carla.Map.get_topology](https://carla.readthedocs.io/en/0.9.16/python_api/#carla.Map.get_topology)"
)]
#[cfg_attr(
carla_version_0915,
doc = " See [carla.Map.get_topology](https://carla.readthedocs.io/en/0.9.15/python_api/#carla.Map.get_topology)"
)]
#[cfg_attr(
carla_version_0914,
doc = " See [carla.Map.get_topology](https://carla.readthedocs.io/en/0.9.14/python_api/#carla.Map.get_topology)"
)]
#[cfg_attr(
any(carla_version_0916, carla_version_0915, carla_version_0914),
doc = " in the Python API."
)]
pub fn topology(&self) -> crate::Result<Vec<(Waypoint, Waypoint)>> {
let topology_pairs = with_ffi_error("topology", |e| self.inner.GetTopology(e))?;
let mut result = Vec::with_capacity(topology_pairs.len());
for pair in topology_pairs.iter() {
let first = pair.first();
let second = pair.second();
if let (Some(start), Some(end)) =
(Waypoint::from_cxx(first), Waypoint::from_cxx(second))
{
result.push((start, end));
}
}
Ok(result)
}
pub fn geo_reference(&self) -> crate::Result<GeoLocation> {
let geo = with_ffi_error("geo_reference", |e| self.inner.GetGeoReference(e))?;
Ok(GeoLocation::from_ffi(geo))
}
pub fn crosswalk_zones(&self) -> crate::Result<Vec<Location>> {
let zones = with_ffi_error("crosswalk_zones", |e| self.inner.GetAllCrosswalkZones(e))?;
Ok(zones
.iter()
.map(|loc| Location::new(loc.x, loc.y, loc.z))
.collect())
}
pub fn cook_in_memory_map(&self, path: &str) -> crate::Result<()> {
with_ffi_error("cook_in_memory_map", |e| {
self.inner.CookInMemoryMap(path.to_string(), e)
})
}
}
impl Map {
pub fn from_cxx(ptr: SharedPtr<FfiMap>) -> Option<Self> {
if ptr.is_null() {
None
} else {
Some(Self { inner: ptr })
}
}
}
#[derive(Derivative)]
#[derivative(Debug)]
#[repr(transparent)]
pub struct RecommendedSpawnPoints {
#[derivative(Debug = "ignore")]
inner: UniquePtr<FfiTransformList>,
}
impl RecommendedSpawnPoints {
pub fn len(&self) -> usize {
self.inner.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.len() == 0
}
pub fn as_slice(&self) -> &[Transform] {
unsafe { slice::from_raw_parts(self.inner.data() as *const Transform, self.len()) }
}
pub fn get(&self, index: usize) -> Option<&Transform> {
self.as_slice().get(index)
}
pub fn iter(&self) -> impl Iterator<Item = &Transform> + Send + '_ {
self.as_slice().iter()
}
fn from_cxx(ptr: UniquePtr<FfiTransformList>) -> Option<Self> {
if ptr.is_null() {
None
} else {
Some(Self { inner: ptr })
}
}
}
assert_impl_all!(Map: Send, Sync);
assert_impl_all!(RecommendedSpawnPoints: Send, Sync);