@@ -53,39 +53,44 @@ struct GeoFeature {
5353}
5454
5555impl 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 \n Table: {loaded_table:?}" ) ;
0 commit comments