3d_spatial_tracking/
3d_spatial_tracking.rs

1//! 3D Spatial Tracking Example
2//!
3//! This example demonstrates Spatio's 3D spatial indexing capabilities for
4//! altitude-aware applications like drone tracking, aviation, and multi-floor navigation.
5
6use 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    // Create an in-memory database
13    let mut db = Spatio::memory()?;
14
15    // === Example 1: Drone Fleet Tracking ===
16    println!("1. Drone Fleet Tracking");
17    println!("   Tracking multiple drones at different altitudes\n");
18
19    // Insert drones at various positions and altitudes
20    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    // === Example 2: Spherical 3D Query ===
66    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; // 200 meters in 3D space
71
72    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    // === Example 3: Cylindrical Query (Altitude Range) ===
97    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; // 5km horizontal
104
105    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    // === Example 4: 3D Bounding Box Query ===
133    println!("4. 3D Bounding Box Query");
134    println!("   Searching within a 3D volume\n");
135
136    // Define a 3D box covering a specific area and altitude range
137    let bbox = BoundingBox3D::new(
138        -74.0080, 40.7120, 40.0, // min x, y, z
139        -74.0050, 40.7150, 110.0, // max x, y, z
140    );
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    // === Example 5: K-Nearest Neighbors in 3D ===
163    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    // === Example 6: Aircraft Tracking ===
192    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    // Query aircraft in specific flight level
211    let fl_center = Point3d::new(-74.0150, 40.7250, 0.0);
212    let fl_min = 9500.0; // Flight level 310 (approx)
213    let fl_max = 10500.0; // Flight level 345 (approx)
214    let radar_range = 50000.0; // 50km
215
216    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    // === Example 7: 3D Distance Calculations ===
234    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    // === Example 8: Multi-Floor Building Navigation ===
263    println!("8. Multi-Floor Building Navigation");
264    println!("   Tracking sensors in a multi-story building\n");
265
266    // Simulate a 10-floor building with sensors on each floor
267    // Each floor is ~3 meters tall
268    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    // Query sensors on floors 3-7
277    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, // 10m horizontal tolerance (same building)
287        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    // === Summary ===
299    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}