Point3d

Struct Point3d 

Source
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: Point

The 2D geographic point (longitude/latitude or x/y)

§z: f64

The altitude/elevation/z-coordinate (in meters typically)

Implementations§

Source§

impl Point3d

Source

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-coordinate
  • y - Latitude or y-coordinate
  • z - Altitude/elevation in meters
§Examples
use spatio_types::point::Point3d;

let point = Point3d::new(-74.0060, 40.7128, 100.0);
Examples found in repository?
examples/3d_spatial_tracking.rs (line 59)
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}
Source

pub fn from_point_and_altitude(point: Point, z: f64) -> Point3d

Create a 3D point from a 2D point and altitude.

Source

pub fn x(&self) -> f64

Get the x coordinate (longitude).

Examples found in repository?
examples/3d_spatial_tracking.rs (line 76)
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}
Source

pub fn y(&self) -> f64

Get the y coordinate (latitude).

Examples found in repository?
examples/3d_spatial_tracking.rs (line 77)
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}
Source

pub fn z(&self) -> f64

Get the z coordinate (altitude/elevation).

Examples found in repository?
examples/3d_spatial_tracking.rs (line 78)
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}
Source

pub fn altitude(&self) -> f64

Get the altitude (alias for z()).

Source

pub fn point_2d(&self) -> &Point

Get a reference to the underlying 2D point.

Source

pub fn to_2d(&self) -> Point

Project this 3D point to 2D by discarding the z coordinate.

Source

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 3D
Source

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);
Source

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);
Source

pub fn haversine_2d(&self, other: &Point3d) -> f64

Calculate the haversine distance on the 2D plane (ignoring altitude).

§Returns

Distance in meters.

Examples found in repository?
examples/3d_spatial_tracking.rs (line 241)
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}
Source

pub fn altitude_difference(&self, other: &Point3d) -> f64

Get the altitude difference to another point.

Examples found in repository?
examples/3d_spatial_tracking.rs (line 242)
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}
Source

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"));
Source

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 Clone for Point3d

Source§

fn clone(&self) -> Point3d

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for Point3d

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<'de> Deserialize<'de> for Point3d

Source§

fn deserialize<__D>( __deserializer: __D, ) -> Result<Point3d, <__D as Deserializer<'de>>::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl PartialEq for Point3d

Source§

fn eq(&self, other: &Point3d) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for Point3d

Source§

fn serialize<__S>( &self, __serializer: __S, ) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl StructuralPartialEq for Point3d

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<G1, G2> Within<G2> for G1
where G2: Contains<G1>,

Source§

fn is_within(&self, b: &G2) -> bool

Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,