trajectory_tracking/
trajectory_tracking.rs

1use spatio::{Point, Spatio, TemporalPoint};
2use std::time::{Duration, UNIX_EPOCH};
3
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5    println!("=== Spatio - Trajectory Tracking ===\n");
6
7    let mut db = Spatio::memory()?;
8    println!("✓ Created in-memory database\n");
9
10    // === 1. BASIC TRAJECTORY STORAGE ===
11    println!("1. Basic Trajectory Storage");
12    println!("---------------------------");
13
14    // Create a simple delivery route
15    let delivery_route = vec![
16        TemporalPoint {
17            point: Point::new(-74.0060, 40.7128), // NYC
18            timestamp: UNIX_EPOCH + Duration::from_secs(1640995200),
19        },
20        TemporalPoint {
21            point: Point::new(-74.0040, 40.7150),
22            timestamp: UNIX_EPOCH + Duration::from_secs(1640995260), // +1 min
23        },
24        TemporalPoint {
25            point: Point::new(-74.0020, 40.7172),
26            timestamp: UNIX_EPOCH + Duration::from_secs(1640995320), // +2 min
27        },
28        TemporalPoint {
29            point: Point::new(-74.0000, 40.7194),
30            timestamp: UNIX_EPOCH + Duration::from_secs(1640995380), // +3 min
31        },
32    ];
33
34    db.insert_trajectory("vehicle:truck001", &delivery_route, None)?;
35    println!(
36        "   Stored delivery truck trajectory with {} waypoints\n",
37        delivery_route.len()
38    );
39
40    // === 2. QUERY FULL TRAJECTORY ===
41    println!("2. Query Full Trajectory");
42    println!("------------------------");
43
44    let full_path = db.query_trajectory("vehicle:truck001", 1640995200, 1640995400)?;
45    println!("   Retrieved {} waypoints:", full_path.len());
46    for (i, tp) in full_path.iter().enumerate() {
47        println!(
48            "     {}. Point ({:.4}°, {:.4}°) at timestamp {}",
49            i + 1,
50            tp.point.x(),
51            tp.point.y(),
52            tp.timestamp.duration_since(UNIX_EPOCH).unwrap().as_secs()
53        );
54    }
55    println!();
56
57    // === 3. QUERY TIME RANGE ===
58    println!("3. Query Specific Time Range");
59    println!("----------------------------");
60
61    // Get only first 2 minutes of trajectory
62    let partial_path = db.query_trajectory("vehicle:truck001", 1640995200, 1640995320)?;
63    println!("   First 2 minutes: {} waypoints", partial_path.len());
64
65    // Get only middle segment
66    let middle_segment = db.query_trajectory("vehicle:truck001", 1640995260, 1640995320)?;
67    println!("   Middle segment: {} waypoints\n", middle_segment.len());
68
69    // === 4. MULTIPLE TRAJECTORIES ===
70    println!("4. Multiple Trajectories");
71    println!("------------------------");
72
73    // Add taxi route
74    let taxi_route = vec![
75        TemporalPoint {
76            point: Point::new(-0.1278, 51.5074), // London
77            timestamp: UNIX_EPOCH + Duration::from_secs(1640995200),
78        },
79        TemporalPoint {
80            point: Point::new(-0.1195, 51.5033),
81            timestamp: UNIX_EPOCH + Duration::from_secs(1640995260),
82        },
83        TemporalPoint {
84            point: Point::new(-0.1245, 51.4994),
85            timestamp: UNIX_EPOCH + Duration::from_secs(1640995320),
86        },
87    ];
88
89    db.insert_trajectory("vehicle:taxi042", &taxi_route, None)?;
90    println!(
91        "   Stored taxi trajectory with {} waypoints",
92        taxi_route.len()
93    );
94
95    // Add bus route
96    let bus_route = vec![
97        TemporalPoint {
98            point: Point::new(2.3522, 48.8566), // Paris
99            timestamp: UNIX_EPOCH + Duration::from_secs(1640995200),
100        },
101        TemporalPoint {
102            point: Point::new(2.3550, 48.8580),
103            timestamp: UNIX_EPOCH + Duration::from_secs(1640995300),
104        },
105        TemporalPoint {
106            point: Point::new(2.3580, 48.8600),
107            timestamp: UNIX_EPOCH + Duration::from_secs(1640995400),
108        },
109        TemporalPoint {
110            point: Point::new(2.3610, 48.8620),
111            timestamp: UNIX_EPOCH + Duration::from_secs(1640995500),
112        },
113        TemporalPoint {
114            point: Point::new(2.3640, 48.8640),
115            timestamp: UNIX_EPOCH + Duration::from_secs(1640995600),
116        },
117    ];
118
119    db.insert_trajectory("vehicle:bus123", &bus_route, None)?;
120    println!(
121        "   Stored bus trajectory with {} waypoints\n",
122        bus_route.len()
123    );
124
125    // === 5. QUERY DIFFERENT VEHICLES ===
126    println!("5. Query Different Vehicles");
127    println!("---------------------------");
128
129    let truck_path = db.query_trajectory("vehicle:truck001", 1640995200, 1640995400)?;
130    let taxi_path = db.query_trajectory("vehicle:taxi042", 1640995200, 1640995400)?;
131    let bus_path = db.query_trajectory("vehicle:bus123", 1640995200, 1640995700)?;
132
133    println!("   Truck waypoints: {}", truck_path.len());
134    println!("   Taxi waypoints: {}", taxi_path.len());
135    println!("   Bus waypoints: {}\n", bus_path.len());
136
137    // === 6. LONG-RUNNING TRAJECTORY ===
138    println!("6. Long-Running Trajectory (High Frequency)");
139    println!("-------------------------------------------");
140
141    // Simulate a drone with frequent position updates
142    let mut drone_path = Vec::new();
143    let start_time = 1641000000;
144
145    for i in 0..60 {
146        // 60 waypoints, 1 per second
147        drone_path.push(TemporalPoint {
148            point: Point::new(
149                -122.4194 + (i as f64 * 0.0001), // San Francisco area
150                37.7749 + (i as f64 * 0.0001),
151            ),
152            timestamp: UNIX_EPOCH + Duration::from_secs(start_time + i),
153        });
154    }
155
156    db.insert_trajectory("drone:delivery001", &drone_path, None)?;
157    println!(
158        "   Stored drone trajectory with {} waypoints",
159        drone_path.len()
160    );
161
162    // Query specific time window (10 seconds)
163    let window = db.query_trajectory("drone:delivery001", start_time, start_time + 10)?;
164    println!(
165        "   Retrieved 10-second window: {} waypoints\n",
166        window.len()
167    );
168
169    // === 7. TRAJECTORY UPDATES ===
170    println!("7. Trajectory Updates");
171    println!("---------------------");
172
173    // Add more waypoints to existing trajectory
174    let extended_route = vec![
175        TemporalPoint {
176            point: Point::new(-74.0060, 40.7128),
177            timestamp: UNIX_EPOCH + Duration::from_secs(1640995200),
178        },
179        TemporalPoint {
180            point: Point::new(-74.0040, 40.7150),
181            timestamp: UNIX_EPOCH + Duration::from_secs(1640995260),
182        },
183        TemporalPoint {
184            point: Point::new(-74.0020, 40.7172),
185            timestamp: UNIX_EPOCH + Duration::from_secs(1640995320),
186        },
187        TemporalPoint {
188            point: Point::new(-74.0000, 40.7194),
189            timestamp: UNIX_EPOCH + Duration::from_secs(1640995380),
190        },
191        // New waypoints
192        TemporalPoint {
193            point: Point::new(-73.9980, 40.7216),
194            timestamp: UNIX_EPOCH + Duration::from_secs(1640995440),
195        },
196        TemporalPoint {
197            point: Point::new(-73.9960, 40.7238),
198            timestamp: UNIX_EPOCH + Duration::from_secs(1640995500),
199        },
200    ];
201
202    db.insert_trajectory("vehicle:truck001", &extended_route, None)?;
203    let updated_path = db.query_trajectory("vehicle:truck001", 1640995200, 1640995600)?;
204    println!(
205        "   Extended truck trajectory from 4 to {} waypoints\n",
206        updated_path.len()
207    );
208
209    // === 8. DATABASE STATISTICS ===
210    println!("8. Database Statistics");
211    println!("----------------------");
212
213    let stats = db.stats();
214    println!("   Total keys in database: {}", stats.key_count);
215    println!("   Total operations: {}\n", stats.operations_count);
216
217    // === 9. USE CASES ===
218    println!("=== Common Use Cases ===\n");
219
220    println!("Fleet Management:");
221    println!("  • Track multiple vehicles in real-time");
222    println!("  • Query historical routes for analysis");
223    println!("  • Retrieve specific time windows for incidents\n");
224
225    println!("Delivery Tracking:");
226    println!("  • Store complete delivery routes");
227    println!("  • Query progress during specific periods");
228    println!("  • Analyze route efficiency\n");
229
230    println!("Drone Operations:");
231    println!("  • High-frequency position updates");
232    println!("  • Flight path analysis");
233    println!("  • Time-based route queries\n");
234
235    println!("Asset Tracking:");
236    println!("  • Monitor movement of valuable items");
237    println!("  • Historical location queries");
238    println!("  • Route verification\n");
239
240    println!("=== Trajectory Tracking Complete! ===");
241    println!("\nKey Features Demonstrated:");
242    println!("  • Store trajectories with timestamps");
243    println!("  • Query full trajectories");
244    println!("  • Query specific time ranges");
245    println!("  • Track multiple vehicles/objects");
246    println!("  • High-frequency updates");
247    println!("  • Trajectory extensions/updates");
248
249    Ok(())
250}