diff --git a/src/main.rs b/src/main.rs index 2e30197..402e929 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use { - clap::Parser, + clap::{Parser, Subcommand}, geo_types::Point, image::{ImageBuffer, Luma}, las::Read as LasRead, @@ -13,26 +13,46 @@ use { mod geonb; -#[derive(Parser, Debug)] -#[clap(author, version, about, long_about=None)] +#[derive(Parser)] +#[command(author, version, about, long_about=None)] struct Args { - // Latitude to fetch LIDAR tile at - #[clap(long)] - latitude: Option, - - // Longitude to fetch LIDAR tile at - #[clap(long)] - longitude: Option, - - // Print extra debug info when initializing raphics - #[clap(long)] + /// Print extra debug info when initializing graphics + #[arg(long)] debug_init: bool, - #[clap(long)] - laz_file: Option, + #[command(subcommand)] + command: Command, +} - #[clap(long)] - grid_cell_size: Option, +#[derive(Subcommand)] +enum Command { + /// Download data from GeoNB + GeoNB { + #[command(subcommand)] + command: GeoNBCommand, + }, + /// Create a grid DEM from point data + GridPoints { + #[arg(long, short = 'i')] + laz_filename: PathBuf, + + #[arg(long)] + grid_cell_size: f64, + }, +} + +#[derive(Subcommand)] +enum GeoNBCommand { + /// Download the LIDAR tile that includes a location + DownloadLidarTile { + /// Latitude to fetch LIDAR tile at + #[arg(long, allow_hyphen_values=true)] + latitude: f64, + + /// Longitude to fetch LIDAR tile at + #[arg(long, allow_hyphen_values=true)] + longitude: f64, + }, } trait FromFloatFloor { @@ -231,38 +251,47 @@ where async fn main() -> Result<(), anyhow::Error> { let args = Args::parse(); - if let (Some(latitude), Some(longitude)) = (args.latitude, args.longitude) { - let location = Proj::new_known_crs("+proj=longlat +datum=WGS84", "EPSG:2953", None) - .unwrap() - .convert(Point::new(longitude, latitude)) - .unwrap(); - println!("{:?}", location); - let mut las_reader = - tokio::io::BufReader::new(geonb::get_lidar_tile_around_point(location).await?); - let mut las_bytes = Vec::new(); - let mut buffer = [0_u8; 4096]; - let mut byte_count = 0; - loop { - let num_bytes = las_reader.read(&mut buffer).await?; - if num_bytes == 0 { - break; + match args.command { + Command::GeoNB { + command: + GeoNBCommand::DownloadLidarTile { + latitude, + longitude, + }, + } => { + let location = Proj::new_known_crs("+proj=longlat +datum=WGS84", "EPSG:2953", None) + .unwrap() + .convert(Point::new(longitude, latitude)) + .unwrap(); + println!("{:?}", location); + let mut las_reader = + tokio::io::BufReader::new(geonb::get_lidar_tile_around_point(location).await?); + let mut las_bytes = Vec::new(); + let mut buffer = [0_u8; 4096]; + let mut byte_count = 0; + loop { + let num_bytes = las_reader.read(&mut buffer).await?; + if num_bytes == 0 { + break; + } + byte_count += num_bytes; + print!("{} bytes read\r", byte_count); + las_bytes.extend_from_slice(&buffer[0..num_bytes]); } - byte_count += num_bytes; - print!("{} bytes read\r", byte_count); - las_bytes.extend_from_slice(&buffer[0..num_bytes]); + println!(); + let mut las_reader = las::Reader::new(std::io::Cursor::new(las_bytes))?; + for wrapped_point in las_reader.points().take(10) { + let point = wrapped_point.unwrap(); + println!("Point coordinates: ({}, {}, {})", point.x, point.y, point.z); + } + Ok(()) } - println!(); - let mut las_reader = las::Reader::new(std::io::Cursor::new(las_bytes))?; - for wrapped_point in las_reader.points().take(10) { - let point = wrapped_point.unwrap(); - println!("Point coordinates: ({}, {}, {})", point.x, point.y, point.z); - } - } - - if let Some(laz_filename) = args.laz_file { - let mut las_reader = las::Reader::from_path(laz_filename).unwrap(); - let bounds = las_reader.header().bounds(); - if let Some(grid_cell_size) = args.grid_cell_size { + Command::GridPoints { + laz_filename, + grid_cell_size, + } => { + let mut las_reader = las::Reader::from_path(laz_filename).unwrap(); + let bounds = las_reader.header().bounds(); let num_cells_x = ((bounds.max.x - bounds.min.x) / grid_cell_size).ceil() as usize; let num_cells_y = ((bounds.max.y - bounds.min.y) / grid_cell_size).ceil() as usize; let mut height_grid = Grid::new(num_cells_y, num_cells_x); @@ -288,8 +317,7 @@ async fn main() -> Result<(), anyhow::Error> { ImageBuffer::from_raw(num_cells_x as u32, num_cells_y as u32, grid_u8.data) .unwrap(); image.save("test.png")?; + Ok(()) } } - - Ok(()) }