1use spatio::{BoundingBox, Point, Spatio};
2
3fn main() -> Result<(), Box<dyn std::error::Error>> {
4 println!("Spatio - Spatio-Temporal Queries Example");
5 println!("=================================");
6
7 let db = Spatio::memory()?;
9 println!("Created spatio-temporal database");
10
11 let cities = vec![
13 ("New York", Point::new(40.7128, -74.0060)),
14 ("London", Point::new(51.5074, -0.1278)),
15 ("Tokyo", Point::new(35.6762, 139.6503)),
16 ("Sydney", Point::new(-33.8688, 151.2093)),
17 ("Paris", Point::new(48.8566, 2.3522)),
18 ("Berlin", Point::new(52.5200, 13.4050)),
19 ("Mumbai", Point::new(19.0760, 72.8777)),
20 ("Cairo", Point::new(30.0444, 31.2357)),
21 ("São Paulo", Point::new(-23.5505, -46.6333)),
22 ("Mexico City", Point::new(19.4326, -99.1332)),
23 ];
24
25 for (name, point) in &cities {
27 db.insert_point("world_cities", point, name.as_bytes(), None)?;
28 }
29 println!("Added {} cities to spatial index", cities.len());
30
31 let reference_point = Point::new(51.5074, -0.1278);
33 println!("Using London as reference point: {}", reference_point);
34
35 println!("\nCities within 1000km of London:");
37 let nearby_cities =
38 db.query_within_radius("world_cities", &reference_point, 1_000_000.0, 10)?;
39
40 for (point, data) in &nearby_cities {
41 let city_name = String::from_utf8_lossy(data);
42 let distance_km = reference_point.distance_to(point) / 1000.0;
43 println!(" - {} ({:.0} km away)", city_name, distance_km);
44 }
45
46 println!("\nCities within 2000km of London:");
48 let medium_range_cities =
49 db.query_within_radius("world_cities", &reference_point, 2_000_000.0, 10)?;
50
51 for (point, data) in &medium_range_cities {
52 let city_name = String::from_utf8_lossy(data);
53 let distance_km = reference_point.distance_to(point) / 1000.0;
54 println!(" - {} ({:.0} km away)", city_name, distance_km);
55 }
56
57 println!("\n3 closest cities to London:");
59 let closest_cities =
60 db.query_within_radius("world_cities", &reference_point, f64::INFINITY, 3)?;
61
62 for (i, (point, data)) in closest_cities.iter().enumerate() {
63 let city_name = String::from_utf8_lossy(data);
64 let distance_km = reference_point.distance_to(point) / 1000.0;
65 println!(" {}. {} ({:.0} km away)", i + 1, city_name, distance_km);
66 }
67
68 println!("\nDistance calculations:");
70 let nyc = Point::new(40.7128, -74.0060);
71 let tokyo = Point::new(35.6762, 139.6503);
72 let sydney = Point::new(-33.8688, 151.2093);
73
74 println!(
75 " - New York ↔ London: {:.0} km",
76 nyc.distance_to(&reference_point) / 1000.0
77 );
78 println!(
79 " - London ↔ Tokyo: {:.0} km",
80 reference_point.distance_to(&tokyo) / 1000.0
81 );
82 println!(
83 " - Tokyo ↔ Sydney: {:.0} km",
84 tokyo.distance_to(&sydney) / 1000.0
85 );
86
87 let london_poi = vec![
89 ("Tower Bridge", Point::new(51.5055, -0.0754)),
90 ("Big Ben", Point::new(51.4994, -0.1245)),
91 ("London Eye", Point::new(51.5033, -0.1195)),
92 ("Buckingham Palace", Point::new(51.5014, -0.1419)),
93 ("Hyde Park", Point::new(51.5074, -0.1657)),
94 ];
95
96 for (name, point) in &london_poi {
97 db.insert_point("london_poi", point, name.as_bytes(), None)?;
98 }
99 println!("\nAdded {} London points of interest", london_poi.len());
100
101 let big_ben = Point::new(51.4994, -0.1245);
103 println!("\nPoints of interest within 2km of Big Ben:");
104 let nearby_poi = db.query_within_radius("london_poi", &big_ben, 2000.0, 10)?;
105
106 for (point, data) in &nearby_poi {
107 let poi_name = String::from_utf8_lossy(data);
108 let distance_m = big_ben.distance_to(point);
109 if distance_m < 10.0 {
110 println!(" - {} (same location)", poi_name);
111 } else {
112 println!(" - {} ({:.0}m away)", poi_name, distance_m);
113 }
114 }
115
116 let stats = db.stats()?;
118 println!("\nDatabase statistics:");
119 println!(" - Total keys: {}", stats.key_count);
120 println!(" - Operations performed: {}", stats.operations_count);
121
122 println!("\nAdvanced Spatial Query Methods:");
124
125 let has_nearby_cities = db.contains_point("world_cities", &reference_point, 1_000_000.0)?;
127 println!(
128 " Cities within 1000km of London exist: {}",
129 has_nearby_cities
130 );
131
132 let count_500km = db.count_within_radius("world_cities", &reference_point, 500_000.0)?;
134 let count_1000km = db.count_within_radius("world_cities", &reference_point, 1_000_000.0)?;
135 let count_2000km = db.count_within_radius("world_cities", &reference_point, 2_000_000.0)?;
136
137 println!(" Cities within 500km: {}", count_500km);
138 println!(" Cities within 1000km: {}", count_1000km);
139 println!(" Cities within 2000km: {}", count_2000km);
140
141 let europe_bounds = (45.0, -10.0, 60.0, 30.0); let has_european_cities = db.intersects_bounds(
144 "world_cities",
145 europe_bounds.0,
146 europe_bounds.1,
147 europe_bounds.2,
148 europe_bounds.3,
149 )?;
150 println!(" European cities exist: {}", has_european_cities);
151
152 let european_cities = db.find_within_bounds(
154 "world_cities",
155 europe_bounds.0,
156 europe_bounds.1,
157 europe_bounds.2,
158 europe_bounds.3,
159 10,
160 )?;
161
162 println!(" Cities in European region:");
163 for (point, data) in &european_cities {
164 let city_name = String::from_utf8_lossy(data);
165 println!(" - {} at {}", city_name, point);
166 }
167
168 let london_area = (51.0, -1.0, 52.0, 1.0);
170 let london_area_cities = db.find_within_bounds(
171 "world_cities",
172 london_area.0,
173 london_area.1,
174 london_area.2,
175 london_area.3,
176 5,
177 )?;
178
179 println!(" Cities in London area:");
180 for (point, data) in &london_area_cities {
181 let city_name = String::from_utf8_lossy(data);
182 println!(" - {} at {}", city_name, point);
183 }
184
185 let asia_pacific = BoundingBox::new(-50.0, 100.0, 50.0, 180.0);
187 let europe_box = BoundingBox::new(35.0, -10.0, 70.0, 40.0);
188
189 println!(" BoundingBox intersection test:");
190 println!(
191 " - Asia-Pacific and Europe intersect: {}",
192 asia_pacific.intersects(&europe_box)
193 );
194
195 println!(" Point containment tests:");
197 let central_london = Point::new(51.5074, -0.1278);
198 let tower_bridge = Point::new(51.5055, -0.0754);
199
200 println!(
201 " - Tower Bridge within 5km of Central London: {}",
202 central_london.contains_point(&tower_bridge, 5000.0)
203 );
204 println!(
205 " - Central London within 2km of Tower Bridge: {}",
206 tower_bridge.contains_point(¢ral_london, 2000.0)
207 );
208
209 println!("\nEnhanced spatial queries example completed successfully!");
210 println!("\nNew spatial query features demonstrated:");
211 println!("- contains_point: Check if points exist within a circular region");
212 println!("- count_within_radius: Count points within a radius (efficient)");
213 println!("- intersects_bounds: Check if points exist within a bounding box");
214 println!("- find_within_bounds: Find all points within a rectangular region");
215 println!("- BoundingBox: Dedicated struct for bounding box operations");
216 println!("- Point containment methods for distance-based checks");
217 println!("\nPrevious features:");
218 println!("- Automatic spatial indexing of geographic points");
219 println!("- Efficient nearby point searches with distance filtering");
220 println!("- Distance calculations between any two points");
221 println!("- Multiple namespaces (world_cities, london_poi)");
222 println!("- Flexible radius-based and count-based queries");
223
224 Ok(())
225}