BoundingBox2D

Struct BoundingBox2D 

Source
pub struct BoundingBox2D {
    pub rect: Rect,
}
Expand description

A 2D axis-aligned bounding box.

Represents a rectangular area defined by minimum and maximum coordinates. This is a wrapper around geo::Rect with additional functionality.

Fields§

§rect: Rect

The underlying geometric rectangle

Implementations§

Source§

impl BoundingBox2D

Source

pub fn new(min_x: f64, min_y: f64, max_x: f64, max_y: f64) -> BoundingBox2D

Create a new bounding box from minimum and maximum coordinates.

§Arguments
  • min_x - Minimum longitude/x coordinate
  • min_y - Minimum latitude/y coordinate
  • max_x - Maximum longitude/x coordinate
  • max_y - Maximum latitude/y coordinate
§Examples
use spatio_types::bbox::BoundingBox2D;

let bbox = BoundingBox2D::new(-74.0, 40.7, -73.9, 40.8);
Examples found in repository?
examples/bbox_database.rs (line 22)
9fn main() -> Result<(), Box<dyn Error>> {
10    println!("=== Spatio - Bounding Box Database ===\n");
11
12    let mut db = Spatio::memory()?;
13    println!("✓ Created in-memory database\n");
14
15    // ========================================
16    // 1. Store Geographic Regions
17    // ========================================
18    println!("1. Storing Geographic Regions");
19    println!("------------------------------");
20
21    // Define NYC boroughs as bounding boxes
22    let manhattan = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
23    let brooklyn = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
24    let queens = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
25    let bronx = BoundingBox2D::new(-73.9338, 40.7855, -73.7654, 40.9176);
26    let staten_island = BoundingBox2D::new(-74.2558, 40.4960, -74.0526, 40.6490);
27
28    // Store regions in database
29    db.insert_bbox("region:manhattan", &manhattan, None)?;
30    db.insert_bbox("region:brooklyn", &brooklyn, None)?;
31    db.insert_bbox("region:queens", &queens, None)?;
32    db.insert_bbox("region:bronx", &bronx, None)?;
33    db.insert_bbox("region:staten_island", &staten_island, None)?;
34
35    println!("   ✓ Stored 5 NYC borough boundaries");
36
37    // ========================================
38    // 2. Retrieve Stored Regions
39    // ========================================
40    println!("\n2. Retrieving Stored Regions");
41    println!("-----------------------------");
42
43    if let Some(retrieved_manhattan) = db.get_bbox("region:manhattan")? {
44        println!("   Manhattan:");
45        println!(
46            "     Area: {:.4}° × {:.4}°",
47            retrieved_manhattan.width(),
48            retrieved_manhattan.height()
49        );
50        println!(
51            "     Center: ({:.4}, {:.4})",
52            retrieved_manhattan.center().x(),
53            retrieved_manhattan.center().y()
54        );
55    }
56
57    // ========================================
58    // 3. Store POIs and Query by Region
59    // ========================================
60    println!("\n3. Store POIs and Query by Region");
61    println!("-----------------------------------");
62
63    // Store points of interest
64    db.insert_point("poi", &Point::new(-73.9855, 40.7580), b"times_square", None)?;
65    db.insert_point("poi", &Point::new(-73.9665, 40.7829), b"central_park", None)?;
66    db.insert_point("poi", &Point::new(-73.9857, 40.7484), b"empire_state", None)?;
67    db.insert_point(
68        "poi",
69        &Point::new(-73.9969, 40.7061),
70        b"brooklyn_bridge",
71        None,
72    )?;
73    db.insert_point(
74        "poi",
75        &Point::new(-73.9690, 40.6602),
76        b"prospect_park",
77        None,
78    )?;
79    db.insert_point("poi", &Point::new(-73.9799, 40.5755), b"coney_island", None)?;
80
81    println!("   ✓ Stored 6 points of interest");
82
83    // Query POIs in Manhattan
84    let manhattan_pois = db.query_within_bbox("poi", &manhattan, 100)?;
85    println!("\n   POIs in Manhattan: {}", manhattan_pois.len());
86    for (point, data) in &manhattan_pois {
87        let name = String::from_utf8_lossy(data);
88        println!("     - {} at ({:.4}, {:.4})", name, point.x(), point.y());
89    }
90
91    // Query POIs in Brooklyn
92    let brooklyn_pois = db.query_within_bbox("poi", &brooklyn, 100)?;
93    println!("\n   POIs in Brooklyn: {}", brooklyn_pois.len());
94
95    // ========================================
96    // 4. Find Intersecting Regions
97    // ========================================
98    println!("\n4. Finding Intersecting Regions");
99    println!("--------------------------------");
100
101    // Create a search area (covering parts of Manhattan and Queens)
102    let search_area = BoundingBox2D::new(-73.98, 40.72, -73.92, 40.78);
103
104    let intersecting = db.find_intersecting_bboxes("region:", &search_area)?;
105    println!(
106        "   Search area intersects with {} boroughs:",
107        intersecting.len()
108    );
109    for (key, _bbox) in &intersecting {
110        println!("     - {}", key.replace("region:", ""));
111    }
112
113    // ========================================
114    // 5. Delivery Zone Management
115    // ========================================
116    println!("\n5. Delivery Zone Management");
117    println!("----------------------------");
118
119    // Define delivery zones
120    let zone_a = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
121    let zone_b = BoundingBox2D::new(-74.00, 40.72, -73.96, 40.76);
122    let zone_c = BoundingBox2D::new(-73.98, 40.74, -73.94, 40.78);
123
124    db.insert_bbox("delivery:zone_a", &zone_a, None)?;
125    db.insert_bbox("delivery:zone_b", &zone_b, None)?;
126    db.insert_bbox("delivery:zone_c", &zone_c, None)?;
127
128    println!("   ✓ Created 3 delivery zones");
129
130    // Check which zones overlap
131    let overlapping_with_a = db.find_intersecting_bboxes("delivery:", &zone_a)?;
132    println!(
133        "\n   Zone A overlaps with {} zones (including itself)",
134        overlapping_with_a.len()
135    );
136
137    // ========================================
138    // 6. Service Area Lookup
139    // ========================================
140    println!("\n6. Service Area Lookup");
141    println!("-----------------------");
142
143    // Check if various locations are in service areas
144    let locations = vec![
145        ("Customer 1", Point::new(-74.00, 40.72)),
146        ("Customer 2", Point::new(-73.97, 40.75)),
147        ("Customer 3", Point::new(-74.05, 40.68)),
148    ];
149
150    for (name, location) in &locations {
151        let mut in_zone = false;
152        for (zone_key, zone_bbox) in &overlapping_with_a {
153            if zone_bbox.contains_point(location) {
154                println!(
155                    "   {} at ({:.4}, {:.4}) is in {}",
156                    name,
157                    location.x(),
158                    location.y(),
159                    zone_key.replace("delivery:", "")
160                );
161                in_zone = true;
162                break;
163            }
164        }
165        if !in_zone {
166            println!(
167                "   {} at ({:.4}, {:.4}) is outside all zones",
168                name,
169                location.x(),
170                location.y()
171            );
172        }
173    }
174
175    // ========================================
176    // 7. Geofencing Example
177    // ========================================
178    println!("\n7. Geofencing Example");
179    println!("----------------------");
180
181    // Define restricted areas
182    let airport_zone = BoundingBox2D::new(-73.82, 40.63, -73.76, 40.66);
183    db.insert_bbox("restricted:jfk_airport", &airport_zone, None)?;
184
185    let military_zone = BoundingBox2D::new(-74.08, 40.60, -74.03, 40.64);
186    db.insert_bbox("restricted:military", &military_zone, None)?;
187
188    println!("   ✓ Defined 2 restricted zones");
189
190    // Check if drone locations are in restricted areas
191    let drone_locations = vec![
192        ("Drone 1", Point::new(-73.79, 40.64)),
193        ("Drone 2", Point::new(-74.00, 40.70)),
194    ];
195
196    for (drone, location) in &drone_locations {
197        let restricted = db.find_intersecting_bboxes(
198            "restricted:",
199            &BoundingBox2D::new(
200                location.x() - 0.001,
201                location.y() - 0.001,
202                location.x() + 0.001,
203                location.y() + 0.001,
204            ),
205        )?;
206
207        if !restricted.is_empty() {
208            println!(
209                "   ⚠ {} at ({:.4}, {:.4}) is in restricted area: {}",
210                drone,
211                location.x(),
212                location.y(),
213                restricted[0].0.replace("restricted:", "")
214            );
215        } else {
216            println!(
217                "   ✓ {} at ({:.4}, {:.4}) is in safe area",
218                drone,
219                location.x(),
220                location.y()
221            );
222        }
223    }
224
225    // ========================================
226    // 8. Spatial Analytics
227    // ========================================
228    println!("\n8. Spatial Analytics");
229    println!("---------------------");
230
231    // Calculate coverage area
232    let mut total_width = 0.0;
233    let mut total_height = 0.0;
234    let mut count = 0;
235
236    let all_regions = vec![
237        ("Manhattan", &manhattan),
238        ("Brooklyn", &brooklyn),
239        ("Queens", &queens),
240        ("Bronx", &bronx),
241        ("Staten Island", &staten_island),
242    ];
243
244    for (name, bbox) in &all_regions {
245        total_width += bbox.width();
246        total_height += bbox.height();
247        count += 1;
248        println!(
249            "   {} coverage: {:.4}° × {:.4}°",
250            name,
251            bbox.width(),
252            bbox.height()
253        );
254    }
255
256    let avg_width = total_width / count as f64;
257    let avg_height = total_height / count as f64;
258
259    println!(
260        "\n   Average borough size: {:.4}° × {:.4}°",
261        avg_width, avg_height
262    );
263
264    // ========================================
265    // 9. Database Statistics
266    // ========================================
267    println!("\n9. Database Statistics");
268    println!("-----------------------");
269
270    let stats = db.stats();
271    println!("   Total keys: {}", stats.key_count);
272    println!("   Total operations: {}", stats.operations_count);
273
274    // Count different types of data
275    let poi_count = manhattan_pois.len() + brooklyn_pois.len();
276    println!("   Stored POIs: {}", poi_count);
277    println!("   Stored regions: 5");
278    println!("   Delivery zones: 3");
279    println!("   Restricted zones: 2");
280
281    println!("\n=== Bounding Box Database Integration Complete! ===");
282    println!("\nKey Features Demonstrated:");
283    println!("  • Store and retrieve bounding boxes");
284    println!("  • Query POIs within regions");
285    println!("  • Find intersecting regions");
286    println!("  • Delivery zone management");
287    println!("  • Service area lookups");
288    println!("  • Geofencing and restricted areas");
289    println!("  • Spatial analytics");
290
291    Ok(())
292}
More examples
Hide additional examples
examples/bounding_boxes.rs (lines 24-27)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}
Source

pub fn from_rect(rect: Rect) -> BoundingBox2D

Create a bounding box from a geo::Rect.

Source

pub fn min_x(&self) -> f64

Get the minimum x coordinate.

Examples found in repository?
examples/bounding_boxes.rs (line 32)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}
Source

pub fn min_y(&self) -> f64

Get the minimum y coordinate.

Examples found in repository?
examples/bounding_boxes.rs (line 33)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}
Source

pub fn max_x(&self) -> f64

Get the maximum x coordinate.

Examples found in repository?
examples/bounding_boxes.rs (line 37)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}
Source

pub fn max_y(&self) -> f64

Get the maximum y coordinate.

Examples found in repository?
examples/bounding_boxes.rs (line 38)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}
Source

pub fn center(&self) -> Point

Get the center point of the bounding box.

Examples found in repository?
examples/bbox_database.rs (line 52)
9fn main() -> Result<(), Box<dyn Error>> {
10    println!("=== Spatio - Bounding Box Database ===\n");
11
12    let mut db = Spatio::memory()?;
13    println!("✓ Created in-memory database\n");
14
15    // ========================================
16    // 1. Store Geographic Regions
17    // ========================================
18    println!("1. Storing Geographic Regions");
19    println!("------------------------------");
20
21    // Define NYC boroughs as bounding boxes
22    let manhattan = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
23    let brooklyn = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
24    let queens = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
25    let bronx = BoundingBox2D::new(-73.9338, 40.7855, -73.7654, 40.9176);
26    let staten_island = BoundingBox2D::new(-74.2558, 40.4960, -74.0526, 40.6490);
27
28    // Store regions in database
29    db.insert_bbox("region:manhattan", &manhattan, None)?;
30    db.insert_bbox("region:brooklyn", &brooklyn, None)?;
31    db.insert_bbox("region:queens", &queens, None)?;
32    db.insert_bbox("region:bronx", &bronx, None)?;
33    db.insert_bbox("region:staten_island", &staten_island, None)?;
34
35    println!("   ✓ Stored 5 NYC borough boundaries");
36
37    // ========================================
38    // 2. Retrieve Stored Regions
39    // ========================================
40    println!("\n2. Retrieving Stored Regions");
41    println!("-----------------------------");
42
43    if let Some(retrieved_manhattan) = db.get_bbox("region:manhattan")? {
44        println!("   Manhattan:");
45        println!(
46            "     Area: {:.4}° × {:.4}°",
47            retrieved_manhattan.width(),
48            retrieved_manhattan.height()
49        );
50        println!(
51            "     Center: ({:.4}, {:.4})",
52            retrieved_manhattan.center().x(),
53            retrieved_manhattan.center().y()
54        );
55    }
56
57    // ========================================
58    // 3. Store POIs and Query by Region
59    // ========================================
60    println!("\n3. Store POIs and Query by Region");
61    println!("-----------------------------------");
62
63    // Store points of interest
64    db.insert_point("poi", &Point::new(-73.9855, 40.7580), b"times_square", None)?;
65    db.insert_point("poi", &Point::new(-73.9665, 40.7829), b"central_park", None)?;
66    db.insert_point("poi", &Point::new(-73.9857, 40.7484), b"empire_state", None)?;
67    db.insert_point(
68        "poi",
69        &Point::new(-73.9969, 40.7061),
70        b"brooklyn_bridge",
71        None,
72    )?;
73    db.insert_point(
74        "poi",
75        &Point::new(-73.9690, 40.6602),
76        b"prospect_park",
77        None,
78    )?;
79    db.insert_point("poi", &Point::new(-73.9799, 40.5755), b"coney_island", None)?;
80
81    println!("   ✓ Stored 6 points of interest");
82
83    // Query POIs in Manhattan
84    let manhattan_pois = db.query_within_bbox("poi", &manhattan, 100)?;
85    println!("\n   POIs in Manhattan: {}", manhattan_pois.len());
86    for (point, data) in &manhattan_pois {
87        let name = String::from_utf8_lossy(data);
88        println!("     - {} at ({:.4}, {:.4})", name, point.x(), point.y());
89    }
90
91    // Query POIs in Brooklyn
92    let brooklyn_pois = db.query_within_bbox("poi", &brooklyn, 100)?;
93    println!("\n   POIs in Brooklyn: {}", brooklyn_pois.len());
94
95    // ========================================
96    // 4. Find Intersecting Regions
97    // ========================================
98    println!("\n4. Finding Intersecting Regions");
99    println!("--------------------------------");
100
101    // Create a search area (covering parts of Manhattan and Queens)
102    let search_area = BoundingBox2D::new(-73.98, 40.72, -73.92, 40.78);
103
104    let intersecting = db.find_intersecting_bboxes("region:", &search_area)?;
105    println!(
106        "   Search area intersects with {} boroughs:",
107        intersecting.len()
108    );
109    for (key, _bbox) in &intersecting {
110        println!("     - {}", key.replace("region:", ""));
111    }
112
113    // ========================================
114    // 5. Delivery Zone Management
115    // ========================================
116    println!("\n5. Delivery Zone Management");
117    println!("----------------------------");
118
119    // Define delivery zones
120    let zone_a = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
121    let zone_b = BoundingBox2D::new(-74.00, 40.72, -73.96, 40.76);
122    let zone_c = BoundingBox2D::new(-73.98, 40.74, -73.94, 40.78);
123
124    db.insert_bbox("delivery:zone_a", &zone_a, None)?;
125    db.insert_bbox("delivery:zone_b", &zone_b, None)?;
126    db.insert_bbox("delivery:zone_c", &zone_c, None)?;
127
128    println!("   ✓ Created 3 delivery zones");
129
130    // Check which zones overlap
131    let overlapping_with_a = db.find_intersecting_bboxes("delivery:", &zone_a)?;
132    println!(
133        "\n   Zone A overlaps with {} zones (including itself)",
134        overlapping_with_a.len()
135    );
136
137    // ========================================
138    // 6. Service Area Lookup
139    // ========================================
140    println!("\n6. Service Area Lookup");
141    println!("-----------------------");
142
143    // Check if various locations are in service areas
144    let locations = vec![
145        ("Customer 1", Point::new(-74.00, 40.72)),
146        ("Customer 2", Point::new(-73.97, 40.75)),
147        ("Customer 3", Point::new(-74.05, 40.68)),
148    ];
149
150    for (name, location) in &locations {
151        let mut in_zone = false;
152        for (zone_key, zone_bbox) in &overlapping_with_a {
153            if zone_bbox.contains_point(location) {
154                println!(
155                    "   {} at ({:.4}, {:.4}) is in {}",
156                    name,
157                    location.x(),
158                    location.y(),
159                    zone_key.replace("delivery:", "")
160                );
161                in_zone = true;
162                break;
163            }
164        }
165        if !in_zone {
166            println!(
167                "   {} at ({:.4}, {:.4}) is outside all zones",
168                name,
169                location.x(),
170                location.y()
171            );
172        }
173    }
174
175    // ========================================
176    // 7. Geofencing Example
177    // ========================================
178    println!("\n7. Geofencing Example");
179    println!("----------------------");
180
181    // Define restricted areas
182    let airport_zone = BoundingBox2D::new(-73.82, 40.63, -73.76, 40.66);
183    db.insert_bbox("restricted:jfk_airport", &airport_zone, None)?;
184
185    let military_zone = BoundingBox2D::new(-74.08, 40.60, -74.03, 40.64);
186    db.insert_bbox("restricted:military", &military_zone, None)?;
187
188    println!("   ✓ Defined 2 restricted zones");
189
190    // Check if drone locations are in restricted areas
191    let drone_locations = vec![
192        ("Drone 1", Point::new(-73.79, 40.64)),
193        ("Drone 2", Point::new(-74.00, 40.70)),
194    ];
195
196    for (drone, location) in &drone_locations {
197        let restricted = db.find_intersecting_bboxes(
198            "restricted:",
199            &BoundingBox2D::new(
200                location.x() - 0.001,
201                location.y() - 0.001,
202                location.x() + 0.001,
203                location.y() + 0.001,
204            ),
205        )?;
206
207        if !restricted.is_empty() {
208            println!(
209                "   ⚠ {} at ({:.4}, {:.4}) is in restricted area: {}",
210                drone,
211                location.x(),
212                location.y(),
213                restricted[0].0.replace("restricted:", "")
214            );
215        } else {
216            println!(
217                "   ✓ {} at ({:.4}, {:.4}) is in safe area",
218                drone,
219                location.x(),
220                location.y()
221            );
222        }
223    }
224
225    // ========================================
226    // 8. Spatial Analytics
227    // ========================================
228    println!("\n8. Spatial Analytics");
229    println!("---------------------");
230
231    // Calculate coverage area
232    let mut total_width = 0.0;
233    let mut total_height = 0.0;
234    let mut count = 0;
235
236    let all_regions = vec![
237        ("Manhattan", &manhattan),
238        ("Brooklyn", &brooklyn),
239        ("Queens", &queens),
240        ("Bronx", &bronx),
241        ("Staten Island", &staten_island),
242    ];
243
244    for (name, bbox) in &all_regions {
245        total_width += bbox.width();
246        total_height += bbox.height();
247        count += 1;
248        println!(
249            "   {} coverage: {:.4}° × {:.4}°",
250            name,
251            bbox.width(),
252            bbox.height()
253        );
254    }
255
256    let avg_width = total_width / count as f64;
257    let avg_height = total_height / count as f64;
258
259    println!(
260        "\n   Average borough size: {:.4}° × {:.4}°",
261        avg_width, avg_height
262    );
263
264    // ========================================
265    // 9. Database Statistics
266    // ========================================
267    println!("\n9. Database Statistics");
268    println!("-----------------------");
269
270    let stats = db.stats();
271    println!("   Total keys: {}", stats.key_count);
272    println!("   Total operations: {}", stats.operations_count);
273
274    // Count different types of data
275    let poi_count = manhattan_pois.len() + brooklyn_pois.len();
276    println!("   Stored POIs: {}", poi_count);
277    println!("   Stored regions: 5");
278    println!("   Delivery zones: 3");
279    println!("   Restricted zones: 2");
280
281    println!("\n=== Bounding Box Database Integration Complete! ===");
282    println!("\nKey Features Demonstrated:");
283    println!("  • Store and retrieve bounding boxes");
284    println!("  • Query POIs within regions");
285    println!("  • Find intersecting regions");
286    println!("  • Delivery zone management");
287    println!("  • Service area lookups");
288    println!("  • Geofencing and restricted areas");
289    println!("  • Spatial analytics");
290
291    Ok(())
292}
More examples
Hide additional examples
examples/bounding_boxes.rs (line 42)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}
Source

pub fn width(&self) -> f64

Get the width of the bounding box.

Examples found in repository?
examples/bbox_database.rs (line 47)
9fn main() -> Result<(), Box<dyn Error>> {
10    println!("=== Spatio - Bounding Box Database ===\n");
11
12    let mut db = Spatio::memory()?;
13    println!("✓ Created in-memory database\n");
14
15    // ========================================
16    // 1. Store Geographic Regions
17    // ========================================
18    println!("1. Storing Geographic Regions");
19    println!("------------------------------");
20
21    // Define NYC boroughs as bounding boxes
22    let manhattan = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
23    let brooklyn = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
24    let queens = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
25    let bronx = BoundingBox2D::new(-73.9338, 40.7855, -73.7654, 40.9176);
26    let staten_island = BoundingBox2D::new(-74.2558, 40.4960, -74.0526, 40.6490);
27
28    // Store regions in database
29    db.insert_bbox("region:manhattan", &manhattan, None)?;
30    db.insert_bbox("region:brooklyn", &brooklyn, None)?;
31    db.insert_bbox("region:queens", &queens, None)?;
32    db.insert_bbox("region:bronx", &bronx, None)?;
33    db.insert_bbox("region:staten_island", &staten_island, None)?;
34
35    println!("   ✓ Stored 5 NYC borough boundaries");
36
37    // ========================================
38    // 2. Retrieve Stored Regions
39    // ========================================
40    println!("\n2. Retrieving Stored Regions");
41    println!("-----------------------------");
42
43    if let Some(retrieved_manhattan) = db.get_bbox("region:manhattan")? {
44        println!("   Manhattan:");
45        println!(
46            "     Area: {:.4}° × {:.4}°",
47            retrieved_manhattan.width(),
48            retrieved_manhattan.height()
49        );
50        println!(
51            "     Center: ({:.4}, {:.4})",
52            retrieved_manhattan.center().x(),
53            retrieved_manhattan.center().y()
54        );
55    }
56
57    // ========================================
58    // 3. Store POIs and Query by Region
59    // ========================================
60    println!("\n3. Store POIs and Query by Region");
61    println!("-----------------------------------");
62
63    // Store points of interest
64    db.insert_point("poi", &Point::new(-73.9855, 40.7580), b"times_square", None)?;
65    db.insert_point("poi", &Point::new(-73.9665, 40.7829), b"central_park", None)?;
66    db.insert_point("poi", &Point::new(-73.9857, 40.7484), b"empire_state", None)?;
67    db.insert_point(
68        "poi",
69        &Point::new(-73.9969, 40.7061),
70        b"brooklyn_bridge",
71        None,
72    )?;
73    db.insert_point(
74        "poi",
75        &Point::new(-73.9690, 40.6602),
76        b"prospect_park",
77        None,
78    )?;
79    db.insert_point("poi", &Point::new(-73.9799, 40.5755), b"coney_island", None)?;
80
81    println!("   ✓ Stored 6 points of interest");
82
83    // Query POIs in Manhattan
84    let manhattan_pois = db.query_within_bbox("poi", &manhattan, 100)?;
85    println!("\n   POIs in Manhattan: {}", manhattan_pois.len());
86    for (point, data) in &manhattan_pois {
87        let name = String::from_utf8_lossy(data);
88        println!("     - {} at ({:.4}, {:.4})", name, point.x(), point.y());
89    }
90
91    // Query POIs in Brooklyn
92    let brooklyn_pois = db.query_within_bbox("poi", &brooklyn, 100)?;
93    println!("\n   POIs in Brooklyn: {}", brooklyn_pois.len());
94
95    // ========================================
96    // 4. Find Intersecting Regions
97    // ========================================
98    println!("\n4. Finding Intersecting Regions");
99    println!("--------------------------------");
100
101    // Create a search area (covering parts of Manhattan and Queens)
102    let search_area = BoundingBox2D::new(-73.98, 40.72, -73.92, 40.78);
103
104    let intersecting = db.find_intersecting_bboxes("region:", &search_area)?;
105    println!(
106        "   Search area intersects with {} boroughs:",
107        intersecting.len()
108    );
109    for (key, _bbox) in &intersecting {
110        println!("     - {}", key.replace("region:", ""));
111    }
112
113    // ========================================
114    // 5. Delivery Zone Management
115    // ========================================
116    println!("\n5. Delivery Zone Management");
117    println!("----------------------------");
118
119    // Define delivery zones
120    let zone_a = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
121    let zone_b = BoundingBox2D::new(-74.00, 40.72, -73.96, 40.76);
122    let zone_c = BoundingBox2D::new(-73.98, 40.74, -73.94, 40.78);
123
124    db.insert_bbox("delivery:zone_a", &zone_a, None)?;
125    db.insert_bbox("delivery:zone_b", &zone_b, None)?;
126    db.insert_bbox("delivery:zone_c", &zone_c, None)?;
127
128    println!("   ✓ Created 3 delivery zones");
129
130    // Check which zones overlap
131    let overlapping_with_a = db.find_intersecting_bboxes("delivery:", &zone_a)?;
132    println!(
133        "\n   Zone A overlaps with {} zones (including itself)",
134        overlapping_with_a.len()
135    );
136
137    // ========================================
138    // 6. Service Area Lookup
139    // ========================================
140    println!("\n6. Service Area Lookup");
141    println!("-----------------------");
142
143    // Check if various locations are in service areas
144    let locations = vec![
145        ("Customer 1", Point::new(-74.00, 40.72)),
146        ("Customer 2", Point::new(-73.97, 40.75)),
147        ("Customer 3", Point::new(-74.05, 40.68)),
148    ];
149
150    for (name, location) in &locations {
151        let mut in_zone = false;
152        for (zone_key, zone_bbox) in &overlapping_with_a {
153            if zone_bbox.contains_point(location) {
154                println!(
155                    "   {} at ({:.4}, {:.4}) is in {}",
156                    name,
157                    location.x(),
158                    location.y(),
159                    zone_key.replace("delivery:", "")
160                );
161                in_zone = true;
162                break;
163            }
164        }
165        if !in_zone {
166            println!(
167                "   {} at ({:.4}, {:.4}) is outside all zones",
168                name,
169                location.x(),
170                location.y()
171            );
172        }
173    }
174
175    // ========================================
176    // 7. Geofencing Example
177    // ========================================
178    println!("\n7. Geofencing Example");
179    println!("----------------------");
180
181    // Define restricted areas
182    let airport_zone = BoundingBox2D::new(-73.82, 40.63, -73.76, 40.66);
183    db.insert_bbox("restricted:jfk_airport", &airport_zone, None)?;
184
185    let military_zone = BoundingBox2D::new(-74.08, 40.60, -74.03, 40.64);
186    db.insert_bbox("restricted:military", &military_zone, None)?;
187
188    println!("   ✓ Defined 2 restricted zones");
189
190    // Check if drone locations are in restricted areas
191    let drone_locations = vec![
192        ("Drone 1", Point::new(-73.79, 40.64)),
193        ("Drone 2", Point::new(-74.00, 40.70)),
194    ];
195
196    for (drone, location) in &drone_locations {
197        let restricted = db.find_intersecting_bboxes(
198            "restricted:",
199            &BoundingBox2D::new(
200                location.x() - 0.001,
201                location.y() - 0.001,
202                location.x() + 0.001,
203                location.y() + 0.001,
204            ),
205        )?;
206
207        if !restricted.is_empty() {
208            println!(
209                "   ⚠ {} at ({:.4}, {:.4}) is in restricted area: {}",
210                drone,
211                location.x(),
212                location.y(),
213                restricted[0].0.replace("restricted:", "")
214            );
215        } else {
216            println!(
217                "   ✓ {} at ({:.4}, {:.4}) is in safe area",
218                drone,
219                location.x(),
220                location.y()
221            );
222        }
223    }
224
225    // ========================================
226    // 8. Spatial Analytics
227    // ========================================
228    println!("\n8. Spatial Analytics");
229    println!("---------------------");
230
231    // Calculate coverage area
232    let mut total_width = 0.0;
233    let mut total_height = 0.0;
234    let mut count = 0;
235
236    let all_regions = vec![
237        ("Manhattan", &manhattan),
238        ("Brooklyn", &brooklyn),
239        ("Queens", &queens),
240        ("Bronx", &bronx),
241        ("Staten Island", &staten_island),
242    ];
243
244    for (name, bbox) in &all_regions {
245        total_width += bbox.width();
246        total_height += bbox.height();
247        count += 1;
248        println!(
249            "   {} coverage: {:.4}° × {:.4}°",
250            name,
251            bbox.width(),
252            bbox.height()
253        );
254    }
255
256    let avg_width = total_width / count as f64;
257    let avg_height = total_height / count as f64;
258
259    println!(
260        "\n   Average borough size: {:.4}° × {:.4}°",
261        avg_width, avg_height
262    );
263
264    // ========================================
265    // 9. Database Statistics
266    // ========================================
267    println!("\n9. Database Statistics");
268    println!("-----------------------");
269
270    let stats = db.stats();
271    println!("   Total keys: {}", stats.key_count);
272    println!("   Total operations: {}", stats.operations_count);
273
274    // Count different types of data
275    let poi_count = manhattan_pois.len() + brooklyn_pois.len();
276    println!("   Stored POIs: {}", poi_count);
277    println!("   Stored regions: 5");
278    println!("   Delivery zones: 3");
279    println!("   Restricted zones: 2");
280
281    println!("\n=== Bounding Box Database Integration Complete! ===");
282    println!("\nKey Features Demonstrated:");
283    println!("  • Store and retrieve bounding boxes");
284    println!("  • Query POIs within regions");
285    println!("  • Find intersecting regions");
286    println!("  • Delivery zone management");
287    println!("  • Service area lookups");
288    println!("  • Geofencing and restricted areas");
289    println!("  • Spatial analytics");
290
291    Ok(())
292}
More examples
Hide additional examples
examples/bounding_boxes.rs (line 47)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}
Source

pub fn height(&self) -> f64

Get the height of the bounding box.

Examples found in repository?
examples/bbox_database.rs (line 48)
9fn main() -> Result<(), Box<dyn Error>> {
10    println!("=== Spatio - Bounding Box Database ===\n");
11
12    let mut db = Spatio::memory()?;
13    println!("✓ Created in-memory database\n");
14
15    // ========================================
16    // 1. Store Geographic Regions
17    // ========================================
18    println!("1. Storing Geographic Regions");
19    println!("------------------------------");
20
21    // Define NYC boroughs as bounding boxes
22    let manhattan = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
23    let brooklyn = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
24    let queens = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
25    let bronx = BoundingBox2D::new(-73.9338, 40.7855, -73.7654, 40.9176);
26    let staten_island = BoundingBox2D::new(-74.2558, 40.4960, -74.0526, 40.6490);
27
28    // Store regions in database
29    db.insert_bbox("region:manhattan", &manhattan, None)?;
30    db.insert_bbox("region:brooklyn", &brooklyn, None)?;
31    db.insert_bbox("region:queens", &queens, None)?;
32    db.insert_bbox("region:bronx", &bronx, None)?;
33    db.insert_bbox("region:staten_island", &staten_island, None)?;
34
35    println!("   ✓ Stored 5 NYC borough boundaries");
36
37    // ========================================
38    // 2. Retrieve Stored Regions
39    // ========================================
40    println!("\n2. Retrieving Stored Regions");
41    println!("-----------------------------");
42
43    if let Some(retrieved_manhattan) = db.get_bbox("region:manhattan")? {
44        println!("   Manhattan:");
45        println!(
46            "     Area: {:.4}° × {:.4}°",
47            retrieved_manhattan.width(),
48            retrieved_manhattan.height()
49        );
50        println!(
51            "     Center: ({:.4}, {:.4})",
52            retrieved_manhattan.center().x(),
53            retrieved_manhattan.center().y()
54        );
55    }
56
57    // ========================================
58    // 3. Store POIs and Query by Region
59    // ========================================
60    println!("\n3. Store POIs and Query by Region");
61    println!("-----------------------------------");
62
63    // Store points of interest
64    db.insert_point("poi", &Point::new(-73.9855, 40.7580), b"times_square", None)?;
65    db.insert_point("poi", &Point::new(-73.9665, 40.7829), b"central_park", None)?;
66    db.insert_point("poi", &Point::new(-73.9857, 40.7484), b"empire_state", None)?;
67    db.insert_point(
68        "poi",
69        &Point::new(-73.9969, 40.7061),
70        b"brooklyn_bridge",
71        None,
72    )?;
73    db.insert_point(
74        "poi",
75        &Point::new(-73.9690, 40.6602),
76        b"prospect_park",
77        None,
78    )?;
79    db.insert_point("poi", &Point::new(-73.9799, 40.5755), b"coney_island", None)?;
80
81    println!("   ✓ Stored 6 points of interest");
82
83    // Query POIs in Manhattan
84    let manhattan_pois = db.query_within_bbox("poi", &manhattan, 100)?;
85    println!("\n   POIs in Manhattan: {}", manhattan_pois.len());
86    for (point, data) in &manhattan_pois {
87        let name = String::from_utf8_lossy(data);
88        println!("     - {} at ({:.4}, {:.4})", name, point.x(), point.y());
89    }
90
91    // Query POIs in Brooklyn
92    let brooklyn_pois = db.query_within_bbox("poi", &brooklyn, 100)?;
93    println!("\n   POIs in Brooklyn: {}", brooklyn_pois.len());
94
95    // ========================================
96    // 4. Find Intersecting Regions
97    // ========================================
98    println!("\n4. Finding Intersecting Regions");
99    println!("--------------------------------");
100
101    // Create a search area (covering parts of Manhattan and Queens)
102    let search_area = BoundingBox2D::new(-73.98, 40.72, -73.92, 40.78);
103
104    let intersecting = db.find_intersecting_bboxes("region:", &search_area)?;
105    println!(
106        "   Search area intersects with {} boroughs:",
107        intersecting.len()
108    );
109    for (key, _bbox) in &intersecting {
110        println!("     - {}", key.replace("region:", ""));
111    }
112
113    // ========================================
114    // 5. Delivery Zone Management
115    // ========================================
116    println!("\n5. Delivery Zone Management");
117    println!("----------------------------");
118
119    // Define delivery zones
120    let zone_a = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
121    let zone_b = BoundingBox2D::new(-74.00, 40.72, -73.96, 40.76);
122    let zone_c = BoundingBox2D::new(-73.98, 40.74, -73.94, 40.78);
123
124    db.insert_bbox("delivery:zone_a", &zone_a, None)?;
125    db.insert_bbox("delivery:zone_b", &zone_b, None)?;
126    db.insert_bbox("delivery:zone_c", &zone_c, None)?;
127
128    println!("   ✓ Created 3 delivery zones");
129
130    // Check which zones overlap
131    let overlapping_with_a = db.find_intersecting_bboxes("delivery:", &zone_a)?;
132    println!(
133        "\n   Zone A overlaps with {} zones (including itself)",
134        overlapping_with_a.len()
135    );
136
137    // ========================================
138    // 6. Service Area Lookup
139    // ========================================
140    println!("\n6. Service Area Lookup");
141    println!("-----------------------");
142
143    // Check if various locations are in service areas
144    let locations = vec![
145        ("Customer 1", Point::new(-74.00, 40.72)),
146        ("Customer 2", Point::new(-73.97, 40.75)),
147        ("Customer 3", Point::new(-74.05, 40.68)),
148    ];
149
150    for (name, location) in &locations {
151        let mut in_zone = false;
152        for (zone_key, zone_bbox) in &overlapping_with_a {
153            if zone_bbox.contains_point(location) {
154                println!(
155                    "   {} at ({:.4}, {:.4}) is in {}",
156                    name,
157                    location.x(),
158                    location.y(),
159                    zone_key.replace("delivery:", "")
160                );
161                in_zone = true;
162                break;
163            }
164        }
165        if !in_zone {
166            println!(
167                "   {} at ({:.4}, {:.4}) is outside all zones",
168                name,
169                location.x(),
170                location.y()
171            );
172        }
173    }
174
175    // ========================================
176    // 7. Geofencing Example
177    // ========================================
178    println!("\n7. Geofencing Example");
179    println!("----------------------");
180
181    // Define restricted areas
182    let airport_zone = BoundingBox2D::new(-73.82, 40.63, -73.76, 40.66);
183    db.insert_bbox("restricted:jfk_airport", &airport_zone, None)?;
184
185    let military_zone = BoundingBox2D::new(-74.08, 40.60, -74.03, 40.64);
186    db.insert_bbox("restricted:military", &military_zone, None)?;
187
188    println!("   ✓ Defined 2 restricted zones");
189
190    // Check if drone locations are in restricted areas
191    let drone_locations = vec![
192        ("Drone 1", Point::new(-73.79, 40.64)),
193        ("Drone 2", Point::new(-74.00, 40.70)),
194    ];
195
196    for (drone, location) in &drone_locations {
197        let restricted = db.find_intersecting_bboxes(
198            "restricted:",
199            &BoundingBox2D::new(
200                location.x() - 0.001,
201                location.y() - 0.001,
202                location.x() + 0.001,
203                location.y() + 0.001,
204            ),
205        )?;
206
207        if !restricted.is_empty() {
208            println!(
209                "   ⚠ {} at ({:.4}, {:.4}) is in restricted area: {}",
210                drone,
211                location.x(),
212                location.y(),
213                restricted[0].0.replace("restricted:", "")
214            );
215        } else {
216            println!(
217                "   ✓ {} at ({:.4}, {:.4}) is in safe area",
218                drone,
219                location.x(),
220                location.y()
221            );
222        }
223    }
224
225    // ========================================
226    // 8. Spatial Analytics
227    // ========================================
228    println!("\n8. Spatial Analytics");
229    println!("---------------------");
230
231    // Calculate coverage area
232    let mut total_width = 0.0;
233    let mut total_height = 0.0;
234    let mut count = 0;
235
236    let all_regions = vec![
237        ("Manhattan", &manhattan),
238        ("Brooklyn", &brooklyn),
239        ("Queens", &queens),
240        ("Bronx", &bronx),
241        ("Staten Island", &staten_island),
242    ];
243
244    for (name, bbox) in &all_regions {
245        total_width += bbox.width();
246        total_height += bbox.height();
247        count += 1;
248        println!(
249            "   {} coverage: {:.4}° × {:.4}°",
250            name,
251            bbox.width(),
252            bbox.height()
253        );
254    }
255
256    let avg_width = total_width / count as f64;
257    let avg_height = total_height / count as f64;
258
259    println!(
260        "\n   Average borough size: {:.4}° × {:.4}°",
261        avg_width, avg_height
262    );
263
264    // ========================================
265    // 9. Database Statistics
266    // ========================================
267    println!("\n9. Database Statistics");
268    println!("-----------------------");
269
270    let stats = db.stats();
271    println!("   Total keys: {}", stats.key_count);
272    println!("   Total operations: {}", stats.operations_count);
273
274    // Count different types of data
275    let poi_count = manhattan_pois.len() + brooklyn_pois.len();
276    println!("   Stored POIs: {}", poi_count);
277    println!("   Stored regions: 5");
278    println!("   Delivery zones: 3");
279    println!("   Restricted zones: 2");
280
281    println!("\n=== Bounding Box Database Integration Complete! ===");
282    println!("\nKey Features Demonstrated:");
283    println!("  • Store and retrieve bounding boxes");
284    println!("  • Query POIs within regions");
285    println!("  • Find intersecting regions");
286    println!("  • Delivery zone management");
287    println!("  • Service area lookups");
288    println!("  • Geofencing and restricted areas");
289    println!("  • Spatial analytics");
290
291    Ok(())
292}
More examples
Hide additional examples
examples/bounding_boxes.rs (line 48)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}
Source

pub fn contains_point(&self, point: &Point) -> bool

Check if a point is contained within this bounding box.

Examples found in repository?
examples/bbox_database.rs (line 153)
9fn main() -> Result<(), Box<dyn Error>> {
10    println!("=== Spatio - Bounding Box Database ===\n");
11
12    let mut db = Spatio::memory()?;
13    println!("✓ Created in-memory database\n");
14
15    // ========================================
16    // 1. Store Geographic Regions
17    // ========================================
18    println!("1. Storing Geographic Regions");
19    println!("------------------------------");
20
21    // Define NYC boroughs as bounding boxes
22    let manhattan = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
23    let brooklyn = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
24    let queens = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
25    let bronx = BoundingBox2D::new(-73.9338, 40.7855, -73.7654, 40.9176);
26    let staten_island = BoundingBox2D::new(-74.2558, 40.4960, -74.0526, 40.6490);
27
28    // Store regions in database
29    db.insert_bbox("region:manhattan", &manhattan, None)?;
30    db.insert_bbox("region:brooklyn", &brooklyn, None)?;
31    db.insert_bbox("region:queens", &queens, None)?;
32    db.insert_bbox("region:bronx", &bronx, None)?;
33    db.insert_bbox("region:staten_island", &staten_island, None)?;
34
35    println!("   ✓ Stored 5 NYC borough boundaries");
36
37    // ========================================
38    // 2. Retrieve Stored Regions
39    // ========================================
40    println!("\n2. Retrieving Stored Regions");
41    println!("-----------------------------");
42
43    if let Some(retrieved_manhattan) = db.get_bbox("region:manhattan")? {
44        println!("   Manhattan:");
45        println!(
46            "     Area: {:.4}° × {:.4}°",
47            retrieved_manhattan.width(),
48            retrieved_manhattan.height()
49        );
50        println!(
51            "     Center: ({:.4}, {:.4})",
52            retrieved_manhattan.center().x(),
53            retrieved_manhattan.center().y()
54        );
55    }
56
57    // ========================================
58    // 3. Store POIs and Query by Region
59    // ========================================
60    println!("\n3. Store POIs and Query by Region");
61    println!("-----------------------------------");
62
63    // Store points of interest
64    db.insert_point("poi", &Point::new(-73.9855, 40.7580), b"times_square", None)?;
65    db.insert_point("poi", &Point::new(-73.9665, 40.7829), b"central_park", None)?;
66    db.insert_point("poi", &Point::new(-73.9857, 40.7484), b"empire_state", None)?;
67    db.insert_point(
68        "poi",
69        &Point::new(-73.9969, 40.7061),
70        b"brooklyn_bridge",
71        None,
72    )?;
73    db.insert_point(
74        "poi",
75        &Point::new(-73.9690, 40.6602),
76        b"prospect_park",
77        None,
78    )?;
79    db.insert_point("poi", &Point::new(-73.9799, 40.5755), b"coney_island", None)?;
80
81    println!("   ✓ Stored 6 points of interest");
82
83    // Query POIs in Manhattan
84    let manhattan_pois = db.query_within_bbox("poi", &manhattan, 100)?;
85    println!("\n   POIs in Manhattan: {}", manhattan_pois.len());
86    for (point, data) in &manhattan_pois {
87        let name = String::from_utf8_lossy(data);
88        println!("     - {} at ({:.4}, {:.4})", name, point.x(), point.y());
89    }
90
91    // Query POIs in Brooklyn
92    let brooklyn_pois = db.query_within_bbox("poi", &brooklyn, 100)?;
93    println!("\n   POIs in Brooklyn: {}", brooklyn_pois.len());
94
95    // ========================================
96    // 4. Find Intersecting Regions
97    // ========================================
98    println!("\n4. Finding Intersecting Regions");
99    println!("--------------------------------");
100
101    // Create a search area (covering parts of Manhattan and Queens)
102    let search_area = BoundingBox2D::new(-73.98, 40.72, -73.92, 40.78);
103
104    let intersecting = db.find_intersecting_bboxes("region:", &search_area)?;
105    println!(
106        "   Search area intersects with {} boroughs:",
107        intersecting.len()
108    );
109    for (key, _bbox) in &intersecting {
110        println!("     - {}", key.replace("region:", ""));
111    }
112
113    // ========================================
114    // 5. Delivery Zone Management
115    // ========================================
116    println!("\n5. Delivery Zone Management");
117    println!("----------------------------");
118
119    // Define delivery zones
120    let zone_a = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
121    let zone_b = BoundingBox2D::new(-74.00, 40.72, -73.96, 40.76);
122    let zone_c = BoundingBox2D::new(-73.98, 40.74, -73.94, 40.78);
123
124    db.insert_bbox("delivery:zone_a", &zone_a, None)?;
125    db.insert_bbox("delivery:zone_b", &zone_b, None)?;
126    db.insert_bbox("delivery:zone_c", &zone_c, None)?;
127
128    println!("   ✓ Created 3 delivery zones");
129
130    // Check which zones overlap
131    let overlapping_with_a = db.find_intersecting_bboxes("delivery:", &zone_a)?;
132    println!(
133        "\n   Zone A overlaps with {} zones (including itself)",
134        overlapping_with_a.len()
135    );
136
137    // ========================================
138    // 6. Service Area Lookup
139    // ========================================
140    println!("\n6. Service Area Lookup");
141    println!("-----------------------");
142
143    // Check if various locations are in service areas
144    let locations = vec![
145        ("Customer 1", Point::new(-74.00, 40.72)),
146        ("Customer 2", Point::new(-73.97, 40.75)),
147        ("Customer 3", Point::new(-74.05, 40.68)),
148    ];
149
150    for (name, location) in &locations {
151        let mut in_zone = false;
152        for (zone_key, zone_bbox) in &overlapping_with_a {
153            if zone_bbox.contains_point(location) {
154                println!(
155                    "   {} at ({:.4}, {:.4}) is in {}",
156                    name,
157                    location.x(),
158                    location.y(),
159                    zone_key.replace("delivery:", "")
160                );
161                in_zone = true;
162                break;
163            }
164        }
165        if !in_zone {
166            println!(
167                "   {} at ({:.4}, {:.4}) is outside all zones",
168                name,
169                location.x(),
170                location.y()
171            );
172        }
173    }
174
175    // ========================================
176    // 7. Geofencing Example
177    // ========================================
178    println!("\n7. Geofencing Example");
179    println!("----------------------");
180
181    // Define restricted areas
182    let airport_zone = BoundingBox2D::new(-73.82, 40.63, -73.76, 40.66);
183    db.insert_bbox("restricted:jfk_airport", &airport_zone, None)?;
184
185    let military_zone = BoundingBox2D::new(-74.08, 40.60, -74.03, 40.64);
186    db.insert_bbox("restricted:military", &military_zone, None)?;
187
188    println!("   ✓ Defined 2 restricted zones");
189
190    // Check if drone locations are in restricted areas
191    let drone_locations = vec![
192        ("Drone 1", Point::new(-73.79, 40.64)),
193        ("Drone 2", Point::new(-74.00, 40.70)),
194    ];
195
196    for (drone, location) in &drone_locations {
197        let restricted = db.find_intersecting_bboxes(
198            "restricted:",
199            &BoundingBox2D::new(
200                location.x() - 0.001,
201                location.y() - 0.001,
202                location.x() + 0.001,
203                location.y() + 0.001,
204            ),
205        )?;
206
207        if !restricted.is_empty() {
208            println!(
209                "   ⚠ {} at ({:.4}, {:.4}) is in restricted area: {}",
210                drone,
211                location.x(),
212                location.y(),
213                restricted[0].0.replace("restricted:", "")
214            );
215        } else {
216            println!(
217                "   ✓ {} at ({:.4}, {:.4}) is in safe area",
218                drone,
219                location.x(),
220                location.y()
221            );
222        }
223    }
224
225    // ========================================
226    // 8. Spatial Analytics
227    // ========================================
228    println!("\n8. Spatial Analytics");
229    println!("---------------------");
230
231    // Calculate coverage area
232    let mut total_width = 0.0;
233    let mut total_height = 0.0;
234    let mut count = 0;
235
236    let all_regions = vec![
237        ("Manhattan", &manhattan),
238        ("Brooklyn", &brooklyn),
239        ("Queens", &queens),
240        ("Bronx", &bronx),
241        ("Staten Island", &staten_island),
242    ];
243
244    for (name, bbox) in &all_regions {
245        total_width += bbox.width();
246        total_height += bbox.height();
247        count += 1;
248        println!(
249            "   {} coverage: {:.4}° × {:.4}°",
250            name,
251            bbox.width(),
252            bbox.height()
253        );
254    }
255
256    let avg_width = total_width / count as f64;
257    let avg_height = total_height / count as f64;
258
259    println!(
260        "\n   Average borough size: {:.4}° × {:.4}°",
261        avg_width, avg_height
262    );
263
264    // ========================================
265    // 9. Database Statistics
266    // ========================================
267    println!("\n9. Database Statistics");
268    println!("-----------------------");
269
270    let stats = db.stats();
271    println!("   Total keys: {}", stats.key_count);
272    println!("   Total operations: {}", stats.operations_count);
273
274    // Count different types of data
275    let poi_count = manhattan_pois.len() + brooklyn_pois.len();
276    println!("   Stored POIs: {}", poi_count);
277    println!("   Stored regions: 5");
278    println!("   Delivery zones: 3");
279    println!("   Restricted zones: 2");
280
281    println!("\n=== Bounding Box Database Integration Complete! ===");
282    println!("\nKey Features Demonstrated:");
283    println!("  • Store and retrieve bounding boxes");
284    println!("  • Query POIs within regions");
285    println!("  • Find intersecting regions");
286    println!("  • Delivery zone management");
287    println!("  • Service area lookups");
288    println!("  • Geofencing and restricted areas");
289    println!("  • Spatial analytics");
290
291    Ok(())
292}
More examples
Hide additional examples
examples/bounding_boxes.rs (line 60)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}
Source

pub fn intersects(&self, other: &BoundingBox2D) -> bool

Check if this bounding box intersects with another.

Examples found in repository?
examples/bounding_boxes.rs (line 88)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}
Source

pub fn expand(&self, amount: f64) -> BoundingBox2D

Expand the bounding box by a given amount in all directions.

Examples found in repository?
examples/bounding_boxes.rs (line 114)
10fn main() -> Result<(), Box<dyn Error>> {
11    println!("=== Spatio - Bounding Box Examples ===\n");
12
13    // Create an in-memory database
14    let mut db = Spatio::memory()?;
15    println!("✓ Created in-memory database\n");
16
17    // ========================================
18    // 1. Basic 2D Bounding Box Operations
19    // ========================================
20    println!("1. Basic 2D Bounding Box");
21    println!("-------------------------");
22
23    // Create a bounding box for Manhattan
24    let manhattan = BoundingBox2D::new(
25        -74.0479, 40.6829, // Southwest corner (Battery Park)
26        -73.9067, 40.8820, // Northeast corner (Inwood)
27    );
28
29    println!("   Manhattan bounding box:");
30    println!(
31        "     Min: ({:.4}, {:.4})",
32        manhattan.min_x(),
33        manhattan.min_y()
34    );
35    println!(
36        "     Max: ({:.4}, {:.4})",
37        manhattan.max_x(),
38        manhattan.max_y()
39    );
40    println!(
41        "     Center: ({:.4}, {:.4})",
42        manhattan.center().x(),
43        manhattan.center().y()
44    );
45    println!(
46        "     Width: {:.4}°, Height: {:.4}°",
47        manhattan.width(),
48        manhattan.height()
49    );
50
51    // Check if points are within Manhattan
52    let times_square = Point::new(-73.9855, 40.7580);
53    let brooklyn_bridge = Point::new(-73.9969, 40.7061);
54    let statue_of_liberty = Point::new(-74.0445, 40.6892);
55    let jfk_airport = Point::new(-73.7781, 40.6413);
56
57    println!("\n   Point containment checks:");
58    println!(
59        "     Times Square: {}",
60        manhattan.contains_point(&times_square)
61    );
62    println!(
63        "     Brooklyn Bridge: {}",
64        manhattan.contains_point(&brooklyn_bridge)
65    );
66    println!(
67        "     Statue of Liberty: {}",
68        manhattan.contains_point(&statue_of_liberty)
69    );
70    println!(
71        "     JFK Airport: {}",
72        manhattan.contains_point(&jfk_airport)
73    );
74
75    // ========================================
76    // 2. Bounding Box Intersection
77    // ========================================
78    println!("\n2. Bounding Box Intersection");
79    println!("-----------------------------");
80
81    // Create bounding boxes for different NYC boroughs
82    let manhattan_bbox = BoundingBox2D::new(-74.0479, 40.6829, -73.9067, 40.8820);
83    let brooklyn_bbox = BoundingBox2D::new(-74.0421, 40.5707, -73.8333, 40.7395);
84    let queens_bbox = BoundingBox2D::new(-73.9626, 40.5431, -73.7004, 40.8007);
85
86    println!(
87        "   Manhattan ∩ Brooklyn: {}",
88        manhattan_bbox.intersects(&brooklyn_bbox)
89    );
90    println!(
91        "   Manhattan ∩ Queens: {}",
92        manhattan_bbox.intersects(&queens_bbox)
93    );
94    println!(
95        "   Brooklyn ∩ Queens: {}",
96        brooklyn_bbox.intersects(&queens_bbox)
97    );
98
99    // ========================================
100    // 3. Expanding Bounding Boxes
101    // ========================================
102    println!("\n3. Expanding Bounding Boxes");
103    println!("----------------------------");
104
105    let central_park = BoundingBox2D::new(-73.9812, 40.7644, -73.9492, 40.8003);
106    println!("   Central Park original:");
107    println!(
108        "     Width: {:.4}°, Height: {:.4}°",
109        central_park.width(),
110        central_park.height()
111    );
112
113    // Expand by 0.01 degrees (~1 km)
114    let expanded = central_park.expand(0.01);
115    println!("\n   Expanded by 0.01°:");
116    println!(
117        "     Width: {:.4}°, Height: {:.4}°",
118        expanded.width(),
119        expanded.height()
120    );
121    println!(
122        "     Growth: {:.4}° in each direction",
123        (expanded.width() - central_park.width()) / 2.0
124    );
125
126    // ========================================
127    // 4. 3D Bounding Boxes
128    // ========================================
129    println!("\n4. 3D Bounding Boxes");
130    println!("--------------------");
131
132    // Create a 3D bounding box for a tall building's footprint with height
133    let one_world_trade = BoundingBox3D::new(
134        -74.0134, 40.7127, 0.0, // Ground level southwest
135        -74.0118, 40.7143, 541.0, // Top level northeast (541m height)
136    );
137
138    println!("   One World Trade Center:");
139    println!(
140        "     Footprint: {:.4}° × {:.4}°",
141        one_world_trade.width(),
142        one_world_trade.height()
143    );
144    println!("     Height: {:.1} meters", one_world_trade.depth());
145    println!(
146        "     Volume: {:.6} cubic degrees×meters",
147        one_world_trade.volume()
148    );
149
150    let (cx, cy, cz) = one_world_trade.center();
151    println!("     Center: ({:.4}, {:.4}, {:.1}m)", cx, cy, cz);
152
153    // Check if points at different altitudes are within the building
154    println!("\n   Altitude containment checks:");
155    println!(
156        "     Ground level (0m): {}",
157        one_world_trade.contains_point(-74.0126, 40.7135, 0.0)
158    );
159    println!(
160        "     Mid-level (270m): {}",
161        one_world_trade.contains_point(-74.0126, 40.7135, 270.0)
162    );
163    println!(
164        "     Top (540m): {}",
165        one_world_trade.contains_point(-74.0126, 40.7135, 540.0)
166    );
167    println!(
168        "     Above (600m): {}",
169        one_world_trade.contains_point(-74.0126, 40.7135, 600.0)
170    );
171
172    // ========================================
173    // 5. 3D to 2D Projection
174    // ========================================
175    println!("\n5. 3D to 2D Projection");
176    println!("----------------------");
177
178    let building_3d = BoundingBox3D::new(-74.0, 40.7, 0.0, -73.9, 40.8, 200.0);
179    let building_2d = building_3d.to_2d();
180
181    println!("   3D Bounding Box:");
182    println!(
183        "     Dimensions: {:.4}° × {:.4}° × {:.1}m",
184        building_3d.width(),
185        building_3d.height(),
186        building_3d.depth()
187    );
188
189    println!("\n   Projected to 2D:");
190    println!(
191        "     Dimensions: {:.4}° × {:.4}°",
192        building_2d.width(),
193        building_2d.height()
194    );
195
196    // ========================================
197    // 6. Temporal Bounding Boxes
198    // ========================================
199    println!("\n6. Temporal Bounding Boxes");
200    println!("--------------------------");
201
202    // Track how a delivery zone changes over time
203    let morning_zone = BoundingBox2D::new(-74.01, 40.71, -73.99, 40.73);
204    let afternoon_zone = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.74);
205
206    let morning_time = SystemTime::now();
207    let afternoon_time = SystemTime::now();
208
209    let temporal_morning = TemporalBoundingBox2D::new(morning_zone.clone(), morning_time);
210    let temporal_afternoon = TemporalBoundingBox2D::new(afternoon_zone.clone(), afternoon_time);
211
212    println!("   Morning delivery zone:");
213    println!(
214        "     Area: {:.4}° × {:.4}°",
215        temporal_morning.bbox().width(),
216        temporal_morning.bbox().height()
217    );
218
219    println!("\n   Afternoon delivery zone:");
220    println!(
221        "     Area: {:.4}° × {:.4}°",
222        temporal_afternoon.bbox().width(),
223        temporal_afternoon.bbox().height()
224    );
225
226    println!(
227        "     Expansion: {:.4}° wider, {:.4}° taller",
228        afternoon_zone.width() - morning_zone.width(),
229        afternoon_zone.height() - morning_zone.height()
230    );
231
232    // ========================================
233    // 7. Storing Bounding Boxes in Database
234    // ========================================
235    println!("\n7. Storing Bounding Boxes");
236    println!("-------------------------");
237
238    // Serialize and store bounding boxes
239    let bbox_json = serde_json::to_vec(&manhattan)?;
240    db.insert("zones:manhattan", bbox_json, None)?;
241
242    let bbox3d_json = serde_json::to_vec(&one_world_trade)?;
243    db.insert("buildings:wtc", bbox3d_json, None)?;
244
245    println!("   ✓ Stored Manhattan bounding box");
246    println!("   ✓ Stored One World Trade Center 3D box");
247
248    // Retrieve and deserialize
249    if let Some(data) = db.get("zones:manhattan")? {
250        let retrieved: BoundingBox2D = serde_json::from_slice(&data)?;
251        println!("\n   Retrieved Manhattan box:");
252        println!(
253            "     Center: ({:.4}, {:.4})",
254            retrieved.center().x(),
255            retrieved.center().y()
256        );
257    }
258
259    // ========================================
260    // 8. Practical Use Cases
261    // ========================================
262    println!("\n8. Practical Use Cases");
263    println!("----------------------");
264
265    // Geofencing
266    let delivery_area = BoundingBox2D::new(-74.02, 40.70, -73.98, 40.75);
267    let current_location = Point::new(-74.00, 40.72);
268
269    if delivery_area.contains_point(&current_location) {
270        println!("   ✓ Delivery driver is within service area");
271    } else {
272        println!("   ✗ Delivery driver is outside service area");
273    }
274
275    // Airspace management
276    let airspace = BoundingBox3D::new(
277        -74.1, 40.6, 0.0, // Ground level
278        -73.8, 40.9, 3000.0, // 3000m ceiling
279    );
280    let drone_altitude = 150.0; // meters
281    let drone_location = (-74.0, 40.75, drone_altitude);
282
283    if airspace.contains_point(drone_location.0, drone_location.1, drone_location.2) {
284        println!("   ✓ Drone is within authorized airspace");
285    }
286
287    // Region overlap detection
288    let zone_a = BoundingBox2D::new(-74.05, 40.70, -74.00, 40.75);
289    let zone_b = BoundingBox2D::new(-74.02, 40.72, -73.97, 40.77);
290
291    if zone_a.intersects(&zone_b) {
292        println!("   ⚠ Service zones A and B overlap - coordination needed");
293    }
294
295    println!("\n=== Bounding Box Examples Complete! ===");
296    println!("\nKey Features Demonstrated:");
297    println!("  • Create and manipulate 2D/3D bounding boxes");
298    println!("  • Check point containment");
299    println!("  • Detect box intersections");
300    println!("  • Expand regions");
301    println!("  • Project 3D to 2D");
302    println!("  • Track temporal changes");
303    println!("  • Serialize and store in database");
304    println!("  • Geofencing and airspace management");
305
306    Ok(())
307}

Trait Implementations§

Source§

impl Clone for BoundingBox2D

Source§

fn clone(&self) -> BoundingBox2D

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 BoundingBox2D

Source§

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

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

impl<'de> Deserialize<'de> for BoundingBox2D

Source§

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

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

impl PartialEq for BoundingBox2D

Source§

fn eq(&self, other: &BoundingBox2D) -> 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 BoundingBox2D

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 BoundingBox2D

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>,