use flatgeobuf::{FallibleStreamingIterator, FgbReader, FgbWriter, GeometryType}; use geo::{GeometryCollection, MultiPoint, Voronoi, VoronoiClip, VoronoiParams}; use geozero::ToGeo; use std::fs::File; use std::io::{BufReader, BufWriter}; use std::time::Instant; fn main() -> Result<(), Box> { // Read input FlatGeobuf // Input is EPSG:27700 (British National Grid) let input_path = "data/uk_postcodes_bng.fgb"; let rstart = Instant::now(); let file = BufReader::new(File::open(input_path)?); let mut reader = FgbReader::open(file)?.select_all()?; let mut geoms_vec: Vec = Vec::new(); while let Some(feature) = reader.next()? { if let Ok(geom) = feature.to_geo() { geoms_vec.push(geom); } } let geoms = GeometryCollection::from(geoms_vec); println!( "Loaded {} points from {}. Took {:?}", geoms.0.len(), input_path, rstart.elapsed() ); let points: MultiPoint = geoms .into_iter() .map(|geom| match geom { geo::Geometry::Point(point) => point, _ => panic!("Expected Point geometry"), }) .collect(); let vstart = Instant::now(); let voronoi_cells = points.voronoi_cells_with_params(VoronoiParams::new().clip(VoronoiClip::Envelope))?; println!("Voronoi calculation took {:?}", vstart.elapsed()); let geometry_collection = GeometryCollection::from_iter(voronoi_cells); // Write output FlatGeobuf (in EPSG:27700) let wstart = Instant::now(); let output_path = "data/voronoi_output.fgb"; let mut fgb = FgbWriter::create("voronoi", GeometryType::Polygon)?; for polygon in geometry_collection.0 { fgb.add_feature_geom(polygon, |_feat| {})?; } let mut fout = BufWriter::new(File::create(output_path)?); fgb.write(&mut fout)?; println!( "Wrote Voronoi diagram to {}. Took {:?}", output_path, wstart.elapsed() ); Ok(()) }