rmp_route_optimizer/types.rs
1//! Core types for route optimization
2
3use serde::{Deserialize, Serialize};
4
5/// A geographic node (location) in the routing graph
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Node {
8 /// Unique identifier for the node
9 pub id: i64,
10 /// Latitude in decimal degrees
11 pub lat: f64,
12 /// Longitude in decimal degrees
13 pub lon: f64,
14}
15
16/// Pickup side constraint for waste collection
17#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
18#[serde(rename_all = "lowercase")]
19pub enum PickupSide {
20 /// Pickup on left side of street
21 Left,
22 /// Pickup on right side of street
23 Right,
24 /// Pickup on either side
25 Either,
26}
27
28/// An edge (road segment) in the routing graph
29#[derive(Debug, Clone, Serialize, Deserialize)]
30pub struct Edge {
31 /// Source node ID
32 pub from: i64,
33 /// Destination node ID
34 pub to: i64,
35 /// Edge cost (distance, time, etc.)
36 pub cost: f64,
37 /// Whether this is a one-way edge
38 pub oneway: bool,
39 /// Pickup side constraint
40 pub side: PickupSide,
41}
42
43/// Result of Eulerian circuit optimization
44#[derive(Debug, Clone, Serialize, Deserialize)]
45pub struct EulerianCircuit {
46 /// Ordered sequence of node IDs forming the circuit
47 pub nodes: Vec<i64>,
48 /// Edges traversed in the circuit
49 pub edges: Vec<Edge>,
50 /// Total cost of the circuit
51 pub total_cost: f64,
52 /// Number of edges added to make graph Eulerian
53 pub augmenting_edges: usize,
54}
55
56impl Node {
57 /// Create a new node
58 pub fn new(id: i64, lat: f64, lon: f64) -> Self {
59 Self { id, lat, lon }
60 }
61}
62
63impl Edge {
64 /// Create a new edge
65 pub fn new(from: i64, to: i64, cost: f64, oneway: bool, side: PickupSide) -> Self {
66 Self {
67 from,
68 to,
69 cost,
70 oneway,
71 side,
72 }
73 }
74}