Skip to content

Commit

Permalink
adapt to new geo::Bearing output
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelkirk committed Oct 30, 2024
1 parent 07f80c0 commit c5cefc5
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 44 deletions.
32 changes: 2 additions & 30 deletions common/ferrostar/src/algorithms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,6 @@ use std::time::SystemTime;
#[cfg(all(test, feature = "web-time"))]
use web_time::SystemTime;

/// Normalizes a bearing returned from several `geo` crate functions,
/// which may be negative, into a positive unsigned integer.
///
/// NOTE: This function assumes that the input values are in the range -360 to +360,
/// and does not check the inputs for validity.
pub(crate) fn normalize_bearing(degrees: f64) -> u16 {
let rounded = degrees.round();
let normalized = if rounded < 0.0 {
rounded + 360.0
} else if rounded >= 360.0 {
rounded - 360.0
} else {
rounded
};
normalized.round() as u16
}

/// Get the index of the closest *segment* to the user's location within a [`LineString`].
///
/// A [`LineString`] is a set of points (ex: representing the geometry of a maneuver),
Expand Down Expand Up @@ -85,13 +68,8 @@ fn get_bearing_to_next_point(
let current = points.next()?;
let next = points.next()?;

// This function may return negative bearing values, but we want to always normalize to [0, 360)
let degrees = normalize_bearing(Geodesic::bearing(current, next));

Some(CourseOverGround {
degrees,
accuracy: None,
})
let degrees = Geodesic::bearing(current, next);
Some(CourseOverGround::new(degrees, None))
}

/// Apply a snapped course to a user location.
Expand Down Expand Up @@ -730,12 +708,6 @@ proptest! {
prop_assert!(index < (coord_len - 1) as u64);
}

#[test]
fn test_bearing_correction_valid_range(bearing in -360f64..360f64) {
let result = normalize_bearing(bearing);
prop_assert!(result < 360);
}

#[test]
fn test_bearing_fuzz(coords in vec(arb_coord(), 2..500), index in 0usize..1_000usize) {
let line = LineString::new(coords);
Expand Down
13 changes: 11 additions & 2 deletions common/ferrostar/src/models.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,17 @@ pub struct CourseOverGround {
}

impl CourseOverGround {
pub fn new(degrees: u16, accuracy: Option<u16>) -> Self {
Self { degrees, accuracy }
/// # Arguments
///
/// - degrees: The direction in which the user's device is traveling, measured in clockwise degrees from
/// true north (N = 0, E = 90, S = 180, W = 270).
/// - accuracy: the accuracy of the course value, measured in degrees.
pub fn new(degrees: f64, accuracy: Option<u16>) -> Self {
debug_assert!(degrees >= 0.0 && degrees <= 360.0);
Self {
degrees: degrees.round() as u16,
accuracy,
}
}
}

Expand Down
15 changes: 4 additions & 11 deletions common/ferrostar/src/simulation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
//! # }
//! ```

use crate::algorithms::{normalize_bearing, trunc_float};
use crate::algorithms::trunc_float;
use crate::models::{CourseOverGround, GeographicCoordinate, Route, UserLocation};
use geo::{coord, Bearing, Densify, Geodesic, Haversine, LineString, Point};
use polyline::decode_polyline;
Expand Down Expand Up @@ -105,10 +105,7 @@ pub fn location_simulation_from_coordinates(
let current_location = UserLocation {
coordinates: *current,
horizontal_accuracy: 0.0,
course_over_ground: Some(CourseOverGround {
degrees: bearing.round() as u16,
accuracy: None,
}),
course_over_ground: Some(CourseOverGround::new(bearing, None)),
timestamp: SystemTime::now(),
speed: None,
};
Expand Down Expand Up @@ -199,15 +196,11 @@ pub fn advance_location_simulation(state: &LocationSimulationState) -> LocationS
if let Some((next_coordinate, rest)) = state.remaining_locations.split_first() {
let current_point = Point::from(state.current_location.coordinates);
let next_point = Point::from(*next_coordinate);
let bearing = normalize_bearing(Geodesic::bearing(current_point, next_point));

let bearing = Geodesic::bearing(current_point, next_point);
let next_location = UserLocation {
coordinates: *next_coordinate,
horizontal_accuracy: 0.0,
course_over_ground: Some(CourseOverGround {
degrees: bearing,
accuracy: None,
}),
course_over_ground: Some(CourseOverGround::new(bearing, None)),
timestamp: SystemTime::now(),
speed: None,
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
source: ferrostar/src/simulation.rs
assertion_line: 329
assertion_line: 322
expression: state
---
current_location:
Expand Down

0 comments on commit c5cefc5

Please sign in to comment.