1use spatio::{Point, Spatio};
2
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("=== Spatio - Spatial Queries ===\n");
5
6 let mut db = Spatio::memory()?;
7 println!("✓ Created in-memory database\n");
8
9 println!("Setting up test data...");
11
12 let cities = vec![
13 ("New York", Point::new(-74.0060, 40.7128)),
14 ("London", Point::new(-0.1278, 51.5074)),
15 ("Paris", Point::new(2.3522, 48.8566)),
16 ("Berlin", Point::new(13.4050, 52.5200)),
17 ("Madrid", Point::new(-3.7038, 40.4168)),
18 ("Rome", Point::new(12.4964, 41.9028)),
19 ("Tokyo", Point::new(139.6503, 35.6762)),
20 ("Sydney", Point::new(151.2093, -33.8688)),
21 ("Mumbai", Point::new(72.8777, 19.0760)),
22 ("Cairo", Point::new(31.2357, 30.0444)),
23 ("São Paulo", Point::new(-46.6333, -23.5505)),
24 ("Mexico City", Point::new(-99.1332, 19.4326)),
25 ];
26
27 for (name, point) in &cities {
28 db.insert_point("world_cities", point, name.as_bytes(), None)?;
29 }
30 println!(" Added {} cities to spatial index\n", cities.len());
31
32 println!("1. Radius-Based Queries (query_within_radius)");
34 println!("----------------------------------------------");
35
36 let london = Point::new(-0.1278, 51.5074);
37
38 let nearby_500km = db.query_within_radius("world_cities", &london, 500_000.0, 10)?;
40 println!(" Cities within 500km of London: {}", nearby_500km.len());
41 for (_, data, _) in &nearby_500km {
42 println!(" - {}", String::from_utf8_lossy(data));
43 }
44
45 let nearby_2000km = db.query_within_radius("world_cities", &london, 2_000_000.0, 10)?;
47 println!(
48 "\n Cities within 2000km of London: {}",
49 nearby_2000km.len()
50 );
51 for (_, data, _) in &nearby_2000km {
52 println!(" - {}", String::from_utf8_lossy(data));
53 }
54
55 let closest_3 = db.query_within_radius("world_cities", &london, f64::INFINITY, 3)?;
57 println!("\n Closest 3 cities to London:");
58 for (i, (_, data, _)) in closest_3.iter().enumerate() {
59 println!(" {}. {}", i + 1, String::from_utf8_lossy(data));
60 }
61 println!();
62
63 println!("2. Existence Checks (contains_point)");
65 println!("-------------------------------------");
66
67 let has_nearby_500km = db.intersects_radius("world_cities", &london, 500_000.0)?;
68 let has_nearby_100km = db.intersects_radius("world_cities", &london, 100_000.0)?;
69
70 println!(" Any cities within 500km of London? {}", has_nearby_500km);
71 println!(" Any cities within 100km of London? {}", has_nearby_100km);
72
73 println!("3. Counting Points (count_within_radius)");
75 println!("----------------------------------------");
76
77 let count_500km = db.count_within_radius("world_cities", &london, 500_000.0)?;
78 let count_1000km = db.count_within_radius("world_cities", &london, 1_000_000.0)?;
79 let count_2000km = db.count_within_radius("world_cities", &london, 2_000_000.0)?;
80
81 println!(" Cities within 500km of London: {}", count_500km);
82 println!(" Cities within 1000km of London: {}", count_1000km);
83 println!(" Cities within 2000km of London: {}", count_2000km);
84 println!();
85
86 println!("4. Bounding Box Queries");
88 println!("-----------------------");
89
90 println!(" European region (lon: -10 to 20, lat: 40 to 60):");
92 let europe_cities = db.find_within_bounds("world_cities", -10.0, 40.0, 20.0, 60.0, 20)?;
93 println!(" Found {} cities:", europe_cities.len());
94 for (point, data) in &europe_cities {
95 println!(
96 " - {} at ({:.2}°, {:.2}°)",
97 String::from_utf8_lossy(data),
98 point.x(),
99 point.y()
100 );
101 }
102
103 println!("\n Asia-Pacific region (lon: 70 to 180, lat: -40 to 40):");
105 let asia_cities = db.find_within_bounds("world_cities", 70.0, -40.0, 180.0, 40.0, 20)?;
106 println!(" Found {} cities:", asia_cities.len());
107 for (_, data) in &asia_cities {
108 println!(" - {}", String::from_utf8_lossy(data));
109 }
110
111 println!("\n Americas region (lon: -130 to -30, lat: -60 to 60):");
113 let americas_cities = db.find_within_bounds("world_cities", -130.0, -60.0, -30.0, 60.0, 20)?;
114 println!(" Found {} cities:", americas_cities.len());
115 for (_, data) in &americas_cities {
116 println!(" - {}", String::from_utf8_lossy(data));
117 }
118 println!();
119
120 println!("5. Bounding Box Intersection (intersects_bounds)");
122 println!("------------------------------------------------");
123
124 let has_european = db.intersects_bounds("world_cities", -10.0, 40.0, 20.0, 60.0)?;
125 let has_antarctica = db.intersects_bounds("world_cities", -180.0, -90.0, 180.0, -60.0)?;
126
127 println!(" European region has cities? {}", has_european);
128 println!(" Antarctica region has cities? {}", has_antarctica);
129 println!();
130
131 println!("6. Multiple Namespaces");
133 println!("----------------------");
134
135 let london_landmarks = vec![
137 ("Big Ben", Point::new(-0.1245, 51.4994)),
138 ("Tower Bridge", Point::new(-0.0754, 51.5055)),
139 ("London Eye", Point::new(-0.1195, 51.5033)),
140 ("Buckingham Palace", Point::new(-0.1419, 51.5014)),
141 ];
142
143 for (name, point) in &london_landmarks {
144 db.insert_point("landmarks", point, name.as_bytes(), None)?;
145 }
146
147 println!(" Added {} London landmarks", london_landmarks.len());
148
149 let center_london = Point::new(-0.1278, 51.5074);
151
152 let nearby_cities = db.query_within_radius("world_cities", ¢er_london, 10_000.0, 10)?;
153 let nearby_landmarks = db.query_within_radius("landmarks", ¢er_london, 10_000.0, 10)?;
154
155 println!(" Within 10km of center London:");
156 println!(" Cities: {}", nearby_cities.len());
157 println!(" Landmarks: {}", nearby_landmarks.len());
158
159 println!("\n Landmarks within 2km:");
160 let close_landmarks = db.query_within_radius("landmarks", ¢er_london, 2_000.0, 10)?;
161 for (_, data, _) in &close_landmarks {
162 println!(" - {}", String::from_utf8_lossy(data));
163 }
164 println!();
165
166 println!("7. Query Result Limiting");
168 println!("------------------------");
169
170 let all_cities = db.query_within_radius("world_cities", &london, f64::INFINITY, 100)?;
171 let top_5 = db.query_within_radius("world_cities", &london, f64::INFINITY, 5)?;
172 let top_3 = db.query_within_radius("world_cities", &london, f64::INFINITY, 3)?;
173
174 println!(" Total cities in database: {}", all_cities.len());
175 println!(" With limit=5: {} cities", top_5.len());
176 println!(" With limit=3: {} cities", top_3.len());
177 println!();
178
179 let stats = db.stats();
181 println!("=== Query Summary ===");
182 println!("Database statistics:");
183 println!(" Total keys: {}", stats.key_count);
184 println!(" Operations: {}", stats.operations_count);
185
186 println!("\nSpatial query methods demonstrated:");
187 println!(" • query_within_radius - Find points within distance");
188 println!(" • contains_point - Check if points exist in radius");
189 println!(" • count_within_radius - Count points efficiently");
190 println!(" • find_within_bounds - Rectangular region queries");
191 println!(" • intersects_bounds - Check bounding box intersection");
192 println!(" • Multiple namespaces - Organize different point types");
193 println!(" • Result limiting - Control query result size");
194
195 Ok(())
196}