transit_grid/algorithms/
edge_length.rs1use geo::{CoordFloat, Euclidean, Haversine, Length};
3use num_traits::FromPrimitive;
4use std::iter::Sum;
5
6use crate::core::TransitEdge;
7
8pub trait EdgeLength<T: CoordFloat + Sum> {
11 fn length(&self) -> T;
13
14 fn euclidean_length(&self) -> T;
16
17 fn haversine_length(&self) -> T;
19}
20
21impl<T: CoordFloat + FromPrimitive + Sum> EdgeLength<T> for TransitEdge<T> {
24 fn length(&self) -> T {
25 self.euclidean_length()
26 }
27
28 fn euclidean_length(&self) -> T {
29 Euclidean.length(&self.path)
30 }
31
32 fn haversine_length(&self) -> T {
33 Haversine.length(&self.path)
34 }
35}
36
37#[cfg(test)]
38mod tests {
39 use super::*;
40 use geo::LineString;
41
42 #[test]
43 fn test_edge_length() {
44 let line = LineString::from(vec![(0.0, 0.0), (1.0, 1.0)]);
45 let edge = TransitEdge {
46 id: 1,
47 source: 1,
48 target: 2,
49 length: 1.0,
50 path: line.clone(),
51 };
52
53 assert_eq!(edge.length(), (2f64).sqrt());
54 }
55
56 #[test]
57 fn test_euclidean_length() {
58 let line = LineString::from(vec![(0.0, 0.0), (1.0, 1.0)]);
59 let edge = TransitEdge {
60 id: 1,
61 source: 1,
62 target: 2,
63 length: 1.0,
64 path: line.clone(),
65 };
66
67 assert_eq!(edge.euclidean_length(), (2f64).sqrt());
68 }
69
70 #[test]
71 fn test_haversine_length() {
72 let line = LineString::from(vec![(-179.9, 0.0), (179.9, 0.0)]);
73 let edge = TransitEdge {
74 id: 1,
75 source: 1,
76 target: 2,
77 length: 1.0,
78 path: line.clone(),
79 };
80
81 let approx_circumference = 2.0 * std::f64::consts::PI * 6371.0 * 1000.0; let expected_length = approx_circumference * (0.2 / 360.0); assert!((edge.haversine_length() - expected_length).abs() < 1.0); }
85}