1use spatio::{BoundingBox3D, Point3d, Spatio};
7use std::error::Error;
8
9fn main() -> Result<(), Box<dyn Error>> {
10 println!("=== 3D Spatial Tracking with Spatio ===\n");
11
12 let mut db = Spatio::memory()?;
14
15 println!("1. Drone Fleet Tracking");
17 println!(" Tracking multiple drones at different altitudes\n");
18
19 let drones = vec![
21 (
22 "drone-001",
23 -74.0060,
24 40.7128,
25 50.0,
26 "Delivery drone - Package A",
27 ),
28 (
29 "drone-002",
30 -74.0070,
31 40.7138,
32 75.0,
33 "Delivery drone - Package B",
34 ),
35 (
36 "drone-003",
37 -74.0050,
38 40.7118,
39 100.0,
40 "Survey drone - Area mapping",
41 ),
42 (
43 "drone-004",
44 -74.0080,
45 40.7148,
46 125.0,
47 "Inspection drone - Building check",
48 ),
49 (
50 "drone-005",
51 -74.0065,
52 40.7133,
53 150.0,
54 "Emergency response drone",
55 ),
56 ];
57
58 for (id, lon, lat, alt, description) in &drones {
59 let position = Point3d::new(*lon, *lat, *alt);
60 db.insert_point_3d("drones", &position, description.as_bytes(), None)?;
61 println!(" ✓ Registered {}: altitude {}m", id, alt);
62 }
63 println!();
64
65 println!("2. Spherical 3D Query");
67 println!(" Finding drones within 3D radius\n");
68
69 let control_center = Point3d::new(-74.0065, 40.7133, 100.0);
70 let search_radius = 200.0; let nearby_drones = db.query_within_sphere_3d("drones", &control_center, search_radius, 10)?;
73
74 println!(
75 " Control center: ({:.4}, {:.4}, {}m)",
76 control_center.x(),
77 control_center.y(),
78 control_center.z()
79 );
80 println!(" Search radius: {}m (3D)\n", search_radius);
81 println!(" Found {} drones within range:", nearby_drones.len());
82
83 for (point, data, distance) in &nearby_drones {
84 let description = String::from_utf8_lossy(data);
85 println!(
86 " - {} at ({:.4}, {:.4}, {}m) - distance: {:.1}m",
87 description,
88 point.x(),
89 point.y(),
90 point.z(),
91 distance
92 );
93 }
94 println!();
95
96 println!("3. Cylindrical Query");
98 println!(" Finding drones in specific altitude corridor\n");
99
100 let airspace_center = Point3d::new(-74.0065, 40.7133, 0.0);
101 let min_altitude = 60.0;
102 let max_altitude = 120.0;
103 let horizontal_radius = 5000.0; let corridor_drones = db.query_within_cylinder_3d(
106 "drones",
107 &airspace_center,
108 min_altitude,
109 max_altitude,
110 horizontal_radius,
111 10,
112 )?;
113
114 println!(
115 " Altitude corridor: {}m - {}m",
116 min_altitude, max_altitude
117 );
118 println!(" Horizontal radius: {}m\n", horizontal_radius);
119 println!(" Found {} drones in corridor:", corridor_drones.len());
120
121 for (point, data, h_dist) in &corridor_drones {
122 let description = String::from_utf8_lossy(data);
123 println!(
124 " - {} at altitude {}m (horizontal: {:.1}m)",
125 description,
126 point.z(),
127 h_dist
128 );
129 }
130 println!();
131
132 println!("4. 3D Bounding Box Query");
134 println!(" Searching within a 3D volume\n");
135
136 let bbox = BoundingBox3D::new(
138 -74.0080, 40.7120, 40.0, -74.0050, 40.7150, 110.0, );
141
142 let boxed_drones = db.query_within_bbox_3d("drones", &bbox, 100)?;
143
144 println!(" Bounding box:");
145 println!(" - X: {:.4} to {:.4}", bbox.min_x, bbox.max_x);
146 println!(" - Y: {:.4} to {:.4}", bbox.min_y, bbox.max_y);
147 println!(" - Z: {}m to {}m\n", bbox.min_z, bbox.max_z);
148 println!(" Found {} drones in volume:", boxed_drones.len());
149
150 for (point, data) in &boxed_drones {
151 let description = String::from_utf8_lossy(data);
152 println!(
153 " - {} at ({:.4}, {:.4}, {}m)",
154 description,
155 point.x(),
156 point.y(),
157 point.z()
158 );
159 }
160 println!();
161
162 println!("5. K-Nearest Neighbors (3D)");
164 println!(" Finding closest drones to emergency location\n");
165
166 let emergency_location = Point3d::new(-74.0062, 40.7130, 80.0);
167 let k = 3;
168
169 let nearest = db.knn_3d("drones", &emergency_location, k)?;
170
171 println!(
172 " Emergency at: ({:.4}, {:.4}, {}m)",
173 emergency_location.x(),
174 emergency_location.y(),
175 emergency_location.z()
176 );
177 println!(" Finding {} nearest drones:\n", k);
178
179 for (i, (point, data, distance)) in nearest.iter().enumerate() {
180 let description = String::from_utf8_lossy(data);
181 println!(" {}. {} - {:.1}m away", i + 1, description, distance);
182 println!(
183 " Position: ({:.4}, {:.4}, {}m)",
184 point.x(),
185 point.y(),
186 point.z()
187 );
188 }
189 println!();
190
191 println!("6. Aircraft Tracking");
193 println!(" Managing commercial flights at cruising altitude\n");
194
195 let flights = vec![
196 ("AA123", -74.0100, 40.7200, 10000.0, "NYC to BOS"),
197 ("UA456", -74.0200, 40.7300, 10500.0, "NYC to LAX"),
198 ("DL789", -74.0150, 40.7250, 9800.0, "NYC to MIA"),
199 ("SW321", -74.0050, 40.7150, 11000.0, "NYC to CHI"),
200 ];
201
202 for (flight, lon, lat, alt, route) in &flights {
203 let position = Point3d::new(*lon, *lat, *alt);
204 let info = format!("{} - {}", flight, route);
205 db.insert_point_3d("aircraft", &position, info.as_bytes(), None)?;
206 println!(" ✓ Tracking {}: {}m altitude", flight, alt);
207 }
208 println!();
209
210 let fl_center = Point3d::new(-74.0150, 40.7250, 0.0);
212 let fl_min = 9500.0; let fl_max = 10500.0; let radar_range = 50000.0; let tracked_flights =
217 db.query_within_cylinder_3d("aircraft", &fl_center, fl_min, fl_max, radar_range, 20)?;
218
219 println!(" Air traffic in flight levels FL310-FL345:");
220 println!(" Radar range: {}km\n", radar_range / 1000.0);
221
222 for (point, data, h_dist) in &tracked_flights {
223 let info = String::from_utf8_lossy(data);
224 println!(
225 " - {} at FL{:.0} ({}km away)",
226 info,
227 point.z() / 30.48 / 100.0,
228 h_dist / 1000.0
229 );
230 }
231 println!();
232
233 println!("7. 3D Distance Calculations");
235 println!(" Computing distances between 3D points\n");
236
237 let point_a = Point3d::new(-74.0060, 40.7128, 100.0);
238 let point_b = Point3d::new(-74.0070, 40.7138, 200.0);
239
240 let dist_3d = db.distance_between_3d(&point_a, &point_b)?;
241 let horizontal_dist = point_a.haversine_2d(&point_b);
242 let altitude_diff = point_a.altitude_difference(&point_b);
243
244 println!(
245 " Point A: ({:.4}, {:.4}, {}m)",
246 point_a.x(),
247 point_a.y(),
248 point_a.z()
249 );
250 println!(
251 " Point B: ({:.4}, {:.4}, {}m)",
252 point_b.x(),
253 point_b.y(),
254 point_b.z()
255 );
256 println!();
257 println!(" 3D distance: {:.2}m", dist_3d);
258 println!(" Horizontal distance: {:.2}m", horizontal_dist);
259 println!(" Altitude difference: {:.2}m", altitude_diff);
260 println!();
261
262 println!("8. Multi-Floor Building Navigation");
264 println!(" Tracking sensors in a multi-story building\n");
265
266 for floor in 0..10 {
269 let altitude = floor as f64 * 3.0;
270 let _sensor_id = format!("sensor-floor-{:02}", floor);
271 let position = Point3d::new(-74.0060, 40.7128, altitude);
272 let info = format!("Temperature sensor - Floor {}", floor);
273 db.insert_point_3d("building-sensors", &position, info.as_bytes(), None)?;
274 }
275
276 let building_location = Point3d::new(-74.0060, 40.7128, 0.0);
278 let floor_3_altitude = 3.0 * 3.0;
279 let floor_7_altitude = 7.0 * 3.0;
280
281 let mid_floor_sensors = db.query_within_cylinder_3d(
282 "building-sensors",
283 &building_location,
284 floor_3_altitude,
285 floor_7_altitude,
286 10.0, 20,
288 )?;
289
290 println!(" Building sensors on floors 3-7:");
291 for (point, data, _) in &mid_floor_sensors {
292 let info = String::from_utf8_lossy(data);
293 let floor = (point.z() / 3.0).round() as i32;
294 println!(" - Floor {}: {}", floor, info);
295 }
296 println!();
297
298 println!("=== Summary ===");
300 println!("Demonstrated 3D spatial capabilities:");
301 println!("✓ 3D point insertion with altitude");
302 println!("✓ Spherical queries (3D radius)");
303 println!("✓ Cylindrical queries (altitude corridors)");
304 println!("✓ 3D bounding box queries");
305 println!("✓ K-nearest neighbors in 3D space");
306 println!("✓ 3D distance calculations");
307 println!("✓ Multi-altitude tracking (drones, aircraft, buildings)");
308
309 Ok(())
310}