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: RectThe underlying geometric rectangle
Implementations§
Source§impl BoundingBox2D
impl BoundingBox2D
Sourcepub fn new(min_x: f64, min_y: f64, max_x: f64, max_y: f64) -> BoundingBox2D
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 coordinatemin_y- Minimum latitude/y coordinatemax_x- Maximum longitude/x coordinatemax_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
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(×_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(¤t_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}Sourcepub fn from_rect(rect: Rect) -> BoundingBox2D
pub fn from_rect(rect: Rect) -> BoundingBox2D
Create a bounding box from a geo::Rect.
Sourcepub fn min_x(&self) -> f64
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(×_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(¤t_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}Sourcepub fn min_y(&self) -> f64
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(×_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(¤t_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}Sourcepub fn max_x(&self) -> f64
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(×_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(¤t_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}Sourcepub fn max_y(&self) -> f64
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(×_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(¤t_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}Sourcepub fn center(&self) -> Point
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
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(×_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(¤t_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}Sourcepub fn width(&self) -> f64
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
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(×_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(¤t_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}Sourcepub fn height(&self) -> f64
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
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(×_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(¤t_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}Sourcepub fn contains_point(&self, point: &Point) -> bool
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
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(×_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(¤t_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}Sourcepub fn intersects(&self, other: &BoundingBox2D) -> bool
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(×_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(¤t_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}Sourcepub fn expand(&self, amount: f64) -> BoundingBox2D
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(×_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(¤t_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
impl Clone for BoundingBox2D
Source§fn clone(&self) -> BoundingBox2D
fn clone(&self) -> BoundingBox2D
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for BoundingBox2D
impl Debug for BoundingBox2D
Source§impl<'de> Deserialize<'de> for BoundingBox2D
impl<'de> Deserialize<'de> for BoundingBox2D
Source§fn deserialize<__D>(
__deserializer: __D,
) -> Result<BoundingBox2D, <__D as Deserializer<'de>>::Error>where
__D: Deserializer<'de>,
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
impl PartialEq for BoundingBox2D
Source§impl Serialize for BoundingBox2D
impl Serialize for BoundingBox2D
Source§fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
fn serialize<__S>(
&self,
__serializer: __S,
) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>where
__S: Serializer,
Serialize this value into the given Serde serializer. Read more
impl StructuralPartialEq for BoundingBox2D
Auto Trait Implementations§
impl Freeze for BoundingBox2D
impl RefUnwindSafe for BoundingBox2D
impl Send for BoundingBox2D
impl Sync for BoundingBox2D
impl Unpin for BoundingBox2D
impl UnwindSafe for BoundingBox2D
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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