use geo::{Closest, LineString, Point};
pub type SegmentId = u32;
pub type IntersectionId = u32;
pub type Timestamp = f64;
#[derive(Debug, Clone, PartialEq)]
pub struct GpsMeasurement {
pub point: Point<f64>,
pub timestamp: Timestamp,
}
#[derive(Debug, Clone, PartialEq)]
pub struct RoadSegment {
pub id: SegmentId,
pub geometry: LineString<f64>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct CandidatePoint<'a> {
pub segment_id: SegmentId,
pub segment: &'a RoadSegment,
pub gps_point: Point<f64>,
}
impl<'a> CandidatePoint<'a> {
pub fn projected_point(&self) -> Result<Point<f64>, &'static str> {
use geo::algorithm::closest_point::ClosestPoint;
match self.segment.geometry.closest_point(&self.gps_point) {
Closest::SinglePoint(point) => Ok(point),
Closest::Intersection(point) => Ok(point),
Closest::Indeterminate => Err(
"Cannot determine closest point on segment - geometry may be malformed",
),
}
}
pub fn distance_to_gps(&self) -> f64 {
use geo::algorithm::euclidean_distance::EuclideanDistance;
self.segment.geometry.euclidean_distance(&self.gps_point)
}
}