1use spatio::{Point, SetOptions, Spatio};
2use std::time::Duration;
3
4fn main() -> Result<(), Box<dyn std::error::Error>> {
5 println!("Spatio - Trajectory Tracking Example");
6 println!("========================================");
7
8 let db = Spatio::memory()?;
10 println!("Created in-memory database");
11
12 println!("\n--- Vehicle Trajectory Tracking ---");
14
15 let delivery_truck_route = vec![
17 (Point::new(40.7128, -74.0060), 1640995200), (Point::new(40.7180, -74.0020), 1640995260), (Point::new(40.7230, -73.9980), 1640995320), (Point::new(40.7280, -73.9940), 1640995380), (Point::new(40.7330, -73.9900), 1640995440), (Point::new(40.7380, -73.9860), 1640995500), (Point::new(40.7430, -73.9820), 1640995560), (Point::new(40.7480, -73.9780), 1640995620), (Point::new(40.7530, -73.9740), 1640995680), (Point::new(40.7580, -73.9700), 1640995740), ];
28
29 db.insert_trajectory("vehicle:truck001", &delivery_truck_route, None)?;
30 println!(
31 "Inserted delivery truck trajectory with {} waypoints",
32 delivery_truck_route.len()
33 );
34
35 let taxi_route = vec![
37 (Point::new(40.7484, -73.9857), 1640995200), (Point::new(40.7490, -73.9850), 1640995210), (Point::new(40.7496, -73.9843), 1640995220), (Point::new(40.7502, -73.9836), 1640995230), (Point::new(40.7508, -73.9829), 1640995240), (Point::new(40.7514, -73.9822), 1640995250), (Point::new(40.7520, -73.9815), 1640995260), (Point::new(40.7526, -73.9808), 1640995270), (Point::new(40.7532, -73.9801), 1640995280), (Point::new(40.7538, -73.9794), 1640995290), ];
48
49 db.insert_trajectory("vehicle:taxi042", &taxi_route, None)?;
50 println!(
51 "Inserted taxi trajectory with {} high-frequency waypoints",
52 taxi_route.len()
53 );
54
55 println!("\n--- Drone Flight Path ---");
57
58 let drone_pattern = vec![
60 (Point::new(40.7589, -73.9851), 1640995300), (Point::new(40.7600, -73.9851), 1640995330), (Point::new(40.7600, -73.9840), 1640995360), (Point::new(40.7589, -73.9840), 1640995390), (Point::new(40.7589, -73.9851), 1640995420), (Point::new(40.7600, -73.9851), 1640995450), (Point::new(40.7600, -73.9840), 1640995480), (Point::new(40.7589, -73.9840), 1640995510), (Point::new(40.7589, -73.9851), 1640995540), ];
70
71 db.insert_trajectory("drone:survey001", &drone_pattern, None)?;
72 println!(
73 "Inserted drone surveillance pattern with {} waypoints",
74 drone_pattern.len()
75 );
76
77 println!("\n--- Pedestrian Tracking ---");
79
80 let jogger_route = vec![
82 (Point::new(40.7679, -73.9781), 1640995600), (Point::new(40.7700, -73.9770), 1640995660), (Point::new(40.7720, -73.9750), 1640995720), (Point::new(40.7740, -73.9730), 1640995780), (Point::new(40.7760, -73.9710), 1640995840), (Point::new(40.7780, -73.9730), 1640995900), (Point::new(40.7800, -73.9750), 1640995960), (Point::new(40.7820, -73.9770), 1640996020), (Point::new(40.7800, -73.9790), 1640996080), (Point::new(40.7780, -73.9810), 1640996140), ];
93
94 let ttl_opts = Some(SetOptions::with_ttl(Duration::from_secs(3600))); db.insert_trajectory("pedestrian:jogger123", &jogger_route, ttl_opts)?;
96 println!(
97 "Inserted jogger trajectory with {} waypoints (1-hour TTL)",
98 jogger_route.len()
99 );
100
101 println!("\n--- Trajectory Queries ---");
103
104 let truck_path = db.query_trajectory("vehicle:truck001", 1640995200, 1640995740)?;
106 println!("Retrieved truck trajectory: {} points", truck_path.len());
107
108 let taxi_path = db.query_trajectory("vehicle:taxi042", 1640995200, 1640995290)?;
109 println!("Retrieved taxi trajectory: {} points", taxi_path.len());
110
111 let truck_midjourney = db.query_trajectory("vehicle:truck001", 1640995320, 1640995560)?;
113 println!(
114 "Truck mid-journey segment: {} points",
115 truck_midjourney.len()
116 );
117
118 let taxi_start = db.query_trajectory("vehicle:taxi042", 1640995200, 1640995240)?;
119 println!("Taxi first 40 seconds: {} points", taxi_start.len());
120
121 println!("\n--- Trajectory Analysis ---");
123
124 println!("Calculating trajectory metrics...");
126
127 let mut truck_total_distance = 0.0;
129 for i in 1..delivery_truck_route.len() {
130 let distance = delivery_truck_route[i - 1]
131 .0
132 .distance_to(&delivery_truck_route[i].0);
133 truck_total_distance += distance;
134 }
135 let truck_duration =
136 delivery_truck_route.last().unwrap().1 - delivery_truck_route.first().unwrap().1;
137 let truck_avg_speed = (truck_total_distance / truck_duration as f64) * 3.6; println!("Delivery Truck Analysis:");
140 println!(" Total distance: {:.2} km", truck_total_distance / 1000.0);
141 println!(" Duration: {} seconds", truck_duration);
142 println!(" Average speed: {:.1} km/h", truck_avg_speed);
143
144 let mut taxi_total_distance = 0.0;
146 for i in 1..taxi_route.len() {
147 let distance = taxi_route[i - 1].0.distance_to(&taxi_route[i].0);
148 taxi_total_distance += distance;
149 }
150 let taxi_duration = taxi_route.last().unwrap().1 - taxi_route.first().unwrap().1;
151 let taxi_avg_speed = (taxi_total_distance / taxi_duration as f64) * 3.6; println!("\nTaxi Analysis:");
154 println!(" Total distance: {:.2} km", taxi_total_distance / 1000.0);
155 println!(" Duration: {} seconds", taxi_duration);
156 println!(" Average speed: {:.1} km/h", taxi_avg_speed);
157
158 println!("\n--- Real-Time Tracking Simulation ---");
160
161 let current_time = 1640996200u64;
163 let bike_positions = [
164 Point::new(40.7505, -73.9934), Point::new(40.7510, -73.9930), Point::new(40.7515, -73.9926), Point::new(40.7520, -73.9922), Point::new(40.7525, -73.9918), ];
170
171 for (i, position) in bike_positions.iter().enumerate() {
172 let timestamp = current_time + (i as u64 * 30); let single_point_trajectory = vec![(*position, timestamp)];
174
175 db.insert_trajectory(
177 &format!("vehicle:bike007:segment_{}", i),
178 &single_point_trajectory,
179 Some(SetOptions::with_ttl(Duration::from_secs(1800))), )?;
181 }
182 println!("Inserted real-time bike messenger updates");
183
184 println!("\n--- Geofencing and Alerts ---");
186
187 let restricted_center = Point::new(40.7614, -73.9776); let restricted_radius = 200.0; println!("Checking trajectories for geofence violations...");
192 println!(
193 "Restricted zone: {:.4}°N, {:.4}°E (radius: {}m)",
194 restricted_center.lat, restricted_center.lon, restricted_radius
195 );
196
197 let trajectories = [
199 ("vehicle:truck001", &delivery_truck_route),
200 ("vehicle:taxi042", &taxi_route),
201 ("drone:survey001", &drone_pattern),
202 ("pedestrian:jogger123", &jogger_route),
203 ];
204
205 for (vehicle_id, trajectory) in &trajectories {
206 let mut violations = 0;
207 for (point, timestamp) in trajectory.iter() {
208 let distance = point.distance_to(&restricted_center);
209 if distance <= restricted_radius {
210 violations += 1;
211 if violations == 1 {
212 println!(
213 "WARNING: {} entered restricted zone at timestamp {}",
214 vehicle_id, timestamp
215 );
216 }
217 }
218 }
219 if violations == 0 {
220 println!("{} stayed outside restricted zone", vehicle_id);
221 } else {
222 println!(
223 " {} had {} geofence violations total",
224 vehicle_id, violations
225 );
226 }
227 }
228
229 println!("\n--- Trajectory Intersections ---");
231
232 println!("Analyzing trajectory intersections (within 100m)...");
234
235 let proximity_threshold = 100.0; let mut intersections_found = 0;
237
238 for (truck_point, truck_time) in &delivery_truck_route {
239 for (taxi_point, taxi_time) in &taxi_route {
240 let distance = truck_point.distance_to(taxi_point);
241 let time_diff = truck_time.abs_diff(*taxi_time);
242
243 if distance <= proximity_threshold && time_diff <= 60 {
244 intersections_found += 1;
245 println!(
246 " Truck and taxi within {:.0}m at times {} and {} ({}s apart)",
247 distance, truck_time, taxi_time, time_diff
248 );
249 }
250 }
251 }
252
253 if intersections_found == 0 {
254 println!(" No close encounters found between truck and taxi");
255 }
256
257 println!("\n--- Database Statistics ---");
259
260 let stats = db.stats()?;
261
262 println!("Total database keys: {}", stats.key_count);
263
264 println!("Trajectory-related operations completed successfully");
266
267 println!("\nTrajectory tracking example completed successfully!");
268 println!("\nKey capabilities demonstrated:");
269 println!("- Multi-vehicle trajectory storage and retrieval");
270 println!("- Time-windowed trajectory queries");
271 println!("- Real-time position updates with TTL");
272 println!("- Trajectory analysis (distance, speed, duration)");
273 println!("- Geofencing and violation detection");
274 println!("- Trajectory intersection analysis");
275 println!("- Mixed vehicle types (truck, taxi, drone, pedestrian, bike)");
276
277 Ok(())
278}