1use spatio::{BoundingBox2D, Point, Spatio};
7use std::error::Error;
8
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 println!("1. Storing Geographic Regions");
19 println!("------------------------------");
20
21 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 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 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 println!("\n3. Store POIs and Query by Region");
61 println!("-----------------------------------");
62
63 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 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 let brooklyn_pois = db.query_within_bbox("poi", &brooklyn, 100)?;
93 println!("\n POIs in Brooklyn: {}", brooklyn_pois.len());
94
95 println!("\n4. Finding Intersecting Regions");
99 println!("--------------------------------");
100
101 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 println!("\n5. Delivery Zone Management");
117 println!("----------------------------");
118
119 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 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 println!("\n6. Service Area Lookup");
141 println!("-----------------------");
142
143 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 println!("\n7. Geofencing Example");
179 println!("----------------------");
180
181 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 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 println!("\n8. Spatial Analytics");
229 println!("---------------------");
230
231 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 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 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}