1use spatio::{BoundingBox2D, BoundingBox3D, Point, Spatio, TemporalBoundingBox2D};
7use std::error::Error;
8use std::time::SystemTime;
9
10fn main() -> Result<(), Box<dyn Error>> {
11 println!("=== Spatio - Bounding Box Examples ===\n");
12
13 let mut db = Spatio::memory()?;
15 println!("✓ Created in-memory database\n");
16
17 println!("1. Basic 2D Bounding Box");
21 println!("-------------------------");
22
23 let manhattan = BoundingBox2D::new(
25 -74.0479, 40.6829, -73.9067, 40.8820, );
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 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 println!("\n2. Bounding Box Intersection");
79 println!("-----------------------------");
80
81 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 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 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 println!("\n4. 3D Bounding Boxes");
130 println!("--------------------");
131
132 let one_world_trade = BoundingBox3D::new(
134 -74.0134, 40.7127, 0.0, -74.0118, 40.7143, 541.0, );
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 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 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 println!("\n6. Temporal Bounding Boxes");
200 println!("--------------------------");
201
202 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 println!("\n7. Storing Bounding Boxes");
236 println!("-------------------------");
237
238 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 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 println!("\n8. Practical Use Cases");
263 println!("----------------------");
264
265 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 let airspace = BoundingBox3D::new(
277 -74.1, 40.6, 0.0, -73.8, 40.9, 3000.0, );
280 let drone_altitude = 150.0; 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 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}