pub struct Point3d {
pub point: Point,
pub z: f64,
}Expand description
A 3D geographic point with x, y (longitude/latitude) and z (altitude/elevation).
This type represents a point in 3D space, typically used for altitude-aware geospatial applications like drone tracking, aviation, or multi-floor buildings.
§Examples
use spatio_types::point::Point3d;
use spatio_types::geo::Point;
// Create a 3D point for a drone at 100 meters altitude
let drone_position = Point3d::new(-74.0060, 40.7128, 100.0);
assert_eq!(drone_position.altitude(), 100.0);
// Calculate 3D distance to another point
let other = Point3d::new(-74.0070, 40.7138, 150.0);
let distance = drone_position.distance_3d(&other);Fields§
§point: PointThe 2D geographic point (longitude/latitude or x/y)
z: f64The altitude/elevation/z-coordinate (in meters typically)
Implementations§
Source§impl Point3d
impl Point3d
Sourcepub fn new(x: f64, y: f64, z: f64) -> Point3d
pub fn new(x: f64, y: f64, z: f64) -> Point3d
Create a new 3D point from x, y, and z coordinates.
§Arguments
x- Longitude or x-coordinatey- Latitude or y-coordinatez- Altitude/elevation in meters
§Examples
use spatio_types::point::Point3d;
let point = Point3d::new(-74.0060, 40.7128, 100.0);Examples found in repository?
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}Sourcepub fn from_point_and_altitude(point: Point, z: f64) -> Point3d
pub fn from_point_and_altitude(point: Point, z: f64) -> Point3d
Create a 3D point from a 2D point and altitude.
Sourcepub fn x(&self) -> f64
pub fn x(&self) -> f64
Get the x coordinate (longitude).
Examples found in repository?
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}Sourcepub fn y(&self) -> f64
pub fn y(&self) -> f64
Get the y coordinate (latitude).
Examples found in repository?
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}Sourcepub fn z(&self) -> f64
pub fn z(&self) -> f64
Get the z coordinate (altitude/elevation).
Examples found in repository?
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}Sourcepub fn distance_3d(&self, other: &Point3d) -> f64
pub fn distance_3d(&self, other: &Point3d) -> f64
Calculate the 3D Euclidean distance to another 3D point.
This calculates the straight-line distance in 3D space using the Pythagorean theorem.
§Examples
use spatio_types::point::Point3d;
let p1 = Point3d::new(0.0, 0.0, 0.0);
let p2 = Point3d::new(3.0, 4.0, 12.0);
let distance = p1.distance_3d(&p2);
assert_eq!(distance, 13.0); // 3-4-5 triangle extended to 3DSourcepub fn haversine_distances(&self, other: &Point3d) -> (f64, f64, f64)
pub fn haversine_distances(&self, other: &Point3d) -> (f64, f64, f64)
Calculate all distance components at once (horizontal, altitude, 3D).
This is more efficient than calling haversine_2d and haversine_3d separately as it calculates the haversine formula only once.
§Returns
Tuple of (horizontal_distance, altitude_difference, distance_3d) in meters.
§Examples
use spatio_types::point::Point3d;
let p1 = Point3d::new(-74.0060, 40.7128, 0.0);
let p2 = Point3d::new(-74.0070, 40.7138, 100.0);
let (h_dist, alt_diff, dist_3d) = p1.haversine_distances(&p2);Sourcepub fn haversine_3d(&self, other: &Point3d) -> f64
pub fn haversine_3d(&self, other: &Point3d) -> f64
Calculate the haversine distance combined with altitude difference.
This uses the haversine formula for the horizontal distance (considering Earth’s curvature) and combines it with the altitude difference using the Pythagorean theorem.
§Returns
Distance in meters.
§Examples
use spatio_types::point::Point3d;
let p1 = Point3d::new(-74.0060, 40.7128, 0.0); // NYC sea level
let p2 = Point3d::new(-74.0070, 40.7138, 100.0); // Nearby, 100m up
let distance = p1.haversine_3d(&p2);Sourcepub fn haversine_2d(&self, other: &Point3d) -> f64
pub fn haversine_2d(&self, other: &Point3d) -> f64
Examples found in repository?
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}Sourcepub fn altitude_difference(&self, other: &Point3d) -> f64
pub fn altitude_difference(&self, other: &Point3d) -> f64
Get the altitude difference to another point.
Examples found in repository?
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}Sourcepub fn to_geojson(&self) -> Result<String, GeoJsonError>
pub fn to_geojson(&self) -> Result<String, GeoJsonError>
Convert to GeoJSON string representation.
§Examples
use spatio_types::point::Point3d;
let point = Point3d::new(-74.0060, 40.7128, 100.0);
let json = point.to_geojson().unwrap();
assert!(json.contains("Point"));Sourcepub fn from_geojson(geojson: &str) -> Result<Point3d, GeoJsonError>
pub fn from_geojson(geojson: &str) -> Result<Point3d, GeoJsonError>
Parse from GeoJSON string. Defaults altitude to 0.0 if not present.
§Examples
use spatio_types::point::Point3d;
let json = r#"{"type":"Point","coordinates":[-74.006,40.7128,100.0]}"#;
let point = Point3d::from_geojson(json).unwrap();
assert_eq!(point.x(), -74.006);
assert_eq!(point.z(), 100.0);Trait Implementations§
Source§impl<'de> Deserialize<'de> for Point3d
impl<'de> Deserialize<'de> for Point3d
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<Point3d, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(
__deserializer: __D,
) -> Result<Point3d, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
Source§impl Serialize for Point3d
impl Serialize for Point3d
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
impl StructuralPartialEq for Point3d
Auto Trait Implementations§
impl Freeze for Point3d
impl RefUnwindSafe for Point3d
impl Send for Point3d
impl Sync for Point3d
impl Unpin for Point3d
impl UnwindSafe for Point3d
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more