Skip to content

Commit 8e890b9

Browse files
committed
feat(geo-example): refactor bbox fn
1 parent b143b4b commit 8e890b9

File tree

1 file changed

+42
-29
lines changed

1 file changed

+42
-29
lines changed

crates/examples/src/geo_rest_catalog.rs

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,39 +53,44 @@ struct GeoFeature {
5353
}
5454

5555
impl GeoFeature {
56-
fn bbox(&self) -> (f64, f64, f64, f64) {
56+
fn bbox(&self) -> Option<(f64, f64, f64, f64)> {
5757
match &self.geometry {
5858
Geometry::Point(point) => {
5959
let coord = point.0;
60-
(coord.x, coord.y, coord.x, coord.y)
60+
Some((coord.x, coord.y, coord.x, coord.y))
6161
}
62-
Geometry::LineString(line) => {
63-
let coords: Vec<_> = line.coords().collect();
64-
let xs: Vec<f64> = coords.iter().map(|p| p.x).collect();
65-
let ys: Vec<f64> = coords.iter().map(|p| p.y).collect();
66-
(
67-
xs.iter().cloned().fold(f64::INFINITY, f64::min),
68-
ys.iter().cloned().fold(f64::INFINITY, f64::min),
69-
xs.iter().cloned().fold(f64::NEG_INFINITY, f64::max),
70-
ys.iter().cloned().fold(f64::NEG_INFINITY, f64::max),
71-
)
62+
Geometry::LineString(line) => Self::coords_to_bbox(line.coords()),
63+
Geometry::Polygon(poly) => Self::coords_to_bbox(poly.exterior().coords()),
64+
Geometry::MultiPoint(mp) => Self::coords_to_bbox(mp.iter().map(|p| &p.0)),
65+
Geometry::MultiLineString(mls) => {
66+
Self::coords_to_bbox(mls.iter().flat_map(|line| line.coords()))
7267
}
73-
Geometry::Polygon(poly) => {
74-
let exterior = poly.exterior();
75-
let coords: Vec<_> = exterior.coords().collect();
76-
let xs: Vec<f64> = coords.iter().map(|p| p.x).collect();
77-
let ys: Vec<f64> = coords.iter().map(|p| p.y).collect();
78-
(
79-
xs.iter().cloned().fold(f64::INFINITY, f64::min),
80-
ys.iter().cloned().fold(f64::INFINITY, f64::min),
81-
xs.iter().cloned().fold(f64::NEG_INFINITY, f64::max),
82-
ys.iter().cloned().fold(f64::NEG_INFINITY, f64::max),
83-
)
68+
Geometry::MultiPolygon(mpoly) => {
69+
Self::coords_to_bbox(mpoly.iter().flat_map(|poly| poly.exterior().coords()))
8470
}
85-
_ => (0.0, 0.0, 0.0, 0.0),
71+
_ => None,
8672
}
8773
}
8874

75+
fn coords_to_bbox<'a>(
76+
mut coords: impl Iterator<Item = &'a geo_types::Coord>,
77+
) -> Option<(f64, f64, f64, f64)> {
78+
// Start with first coord, then fold over the rest
79+
coords.next().map(|first| {
80+
coords.fold(
81+
(first.x, first.y, first.x, first.y),
82+
|(min_x, min_y, max_x, max_y), coord| {
83+
(
84+
min_x.min(coord.x),
85+
min_y.min(coord.y),
86+
max_x.max(coord.x),
87+
max_y.max(coord.y),
88+
)
89+
},
90+
)
91+
})
92+
}
93+
8994
fn geometry_type(&self) -> &str {
9095
match &self.geometry {
9196
Geometry::Point(_) => "Point",
@@ -291,16 +296,24 @@ async fn main() {
291296
features.iter().map(|f| f.srid),
292297
));
293298
let bbox_min_xs: ArrayRef = Arc::new(Float64Array::from_iter_values(
294-
features.iter().map(|f| f.bbox().0),
299+
features
300+
.iter()
301+
.map(|f| f.bbox().expect("geometry must have valid bbox").0),
295302
));
296303
let bbox_min_ys: ArrayRef = Arc::new(Float64Array::from_iter_values(
297-
features.iter().map(|f| f.bbox().1),
304+
features
305+
.iter()
306+
.map(|f| f.bbox().expect("geometry must have valid bbox").1),
298307
));
299308
let bbox_max_xs: ArrayRef = Arc::new(Float64Array::from_iter_values(
300-
features.iter().map(|f| f.bbox().2),
309+
features
310+
.iter()
311+
.map(|f| f.bbox().expect("geometry must have valid bbox").2),
301312
));
302313
let bbox_max_ys: ArrayRef = Arc::new(Float64Array::from_iter_values(
303-
features.iter().map(|f| f.bbox().3),
314+
features
315+
.iter()
316+
.map(|f| f.bbox().expect("geometry must have valid bbox").3),
304317
));
305318

306319
let countries: ArrayRef = Arc::new(StringArray::from_iter_values(
@@ -331,7 +344,7 @@ async fn main() {
331344
.unwrap();
332345

333346
data_file_writer.write(record_batch.clone()).await.unwrap();
334-
let data_file = data_file_writer.close().await.unwrap();
347+
let _data_file = data_file_writer.close().await.unwrap();
335348

336349
let loaded_table = catalog.load_table(&table_ident).await.unwrap();
337350
println!("Table {TABLE_NAME} loaded!\n\nTable: {loaded_table:?}");

0 commit comments

Comments
 (0)