From 8e3ba0062bf157b1b752902775279c9cfc3df1ec Mon Sep 17 00:00:00 2001 From: Rajsekar Manokaran Date: Wed, 27 Feb 2019 10:00:01 +0530 Subject: [PATCH 1/3] Allow reading block-size of Rasters 1. implemented GetBlockSize 2. added feature flag "gdal_2_2" to enable recent GDAL functions. 3. implemented GetActualBlockSize (behind "gdal_2_2" flag) --- Cargo.toml | 1 + src/raster/rasterband.rs | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index f932a997..f46f9be1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ documentation = "https://georust.github.io/gdal/" [features] bindgen = ["gdal-sys/bindgen"] +gdal_2_2 = ["gdal-sys/min_gdal_version_2_2"] [dependencies] failure = "0.1" diff --git a/src/raster/rasterband.rs b/src/raster/rasterband.rs index 703429dc..36cba3b5 100644 --- a/src/raster/rasterband.rs +++ b/src/raster/rasterband.rs @@ -150,6 +150,35 @@ impl <'a> RasterBand<'a> { } None } + + pub fn block_size(&self) -> (usize, usize) { + let mut block_size_x = 0; + let mut block_size_y = 0; + unsafe { gdal_sys::GDALGetBlockSize( + self.c_rasterband, + &mut block_size_x, + &mut block_size_y, + )} + (block_size_x as usize, block_size_y as usize) + } + + #[cfg(feature = "gdal_2_2")] + pub fn actual_block_size(&self, offset: (isize, isize)) + -> Result<(usize, usize)>{ + let mut block_size_x = 0; + let mut block_size_y = 0; + let rv = unsafe { gdal_sys::GDALGetActualBlockSize( + self.c_rasterband, + offset.0 as libc::c_int, + offset.1 as libc::c_int, + &mut block_size_x, + &mut block_size_y, + )}; + if rv != CPLErr::CE_None { + Err(_last_cpl_err(rv))?; + } + Ok((block_size_x as usize, block_size_y as usize)) + } } impl<'a> MajorObject for RasterBand<'a> { From 1e821898d54d8b69466450fd9e89fcf4a2bb560d Mon Sep 17 00:00:00 2001 From: Rajsekar Manokaran Date: Fri, 29 Mar 2019 09:12:40 +0530 Subject: [PATCH 2/3] Allow creating vector layer with geometry info --- src/vector/dataset.rs | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/src/vector/dataset.rs b/src/vector/dataset.rs index 7978e017..9106adef 100644 --- a/src/vector/dataset.rs +++ b/src/vector/dataset.rs @@ -8,7 +8,7 @@ use gdal_major_object::MajorObject; use metadata::Metadata; use gdal_sys::{self, GDALMajorObjectH, OGRDataSourceH, OGRLayerH, OGRwkbGeometryType}; use utils::_last_null_pointer_err; - +use spatial_ref::SpatialRef; use errors::*; @@ -98,6 +98,34 @@ impl Dataset { self._child_layer(c_layer); Ok(self.layers.last_mut().unwrap()) // TODO: is this safe? } + + /// Create a new layer with name, spatial ref. and type. + pub fn create_layer_ext( + &mut self, + name: &str, + srs: Option<&SpatialRef>, + ty: OGRwkbGeometryType::Type, + ) -> Result<&mut Layer> { + let c_name = CString::new(name)?; + let c_srs = match srs { + Some(srs) => srs.to_c_hsrs(), + None => null_mut(), + }; + + let c_layer = unsafe { gdal_sys::OGR_DS_CreateLayer( + self.c_dataset, + c_name.as_ptr(), + c_srs, + ty, + null_mut(), + ) }; + if c_layer.is_null() { + Err(_last_null_pointer_err("OGR_DS_CreateLayer"))?; + }; + self._child_layer(c_layer); + Ok(self.layers.last_mut().unwrap()) // TODO: is this safe? + + } } From a8e0be193b57529e32cf71b7219053f7609f7ce0 Mon Sep 17 00:00:00 2001 From: Rajsekar Manokaran Date: Sat, 30 Mar 2019 01:02:40 +0530 Subject: [PATCH 3/3] Added support for getting dimensions of a RasterBand + added `x_size()`, `y_size()`, and `size()` to `RasterBand` + added tests --- src/raster/rasterband.rs | 40 +++++++++++++++++++++++++++------------- src/raster/tests.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/raster/rasterband.rs b/src/raster/rasterband.rs index c2de36bd..c25d0854 100644 --- a/src/raster/rasterband.rs +++ b/src/raster/rasterband.rs @@ -26,8 +26,6 @@ impl <'a> RasterBand<'a> { } /// Get block size from a 'Dataset'. - /// # Arguments - /// * band_index - the band_index pub fn block_size(&self) -> (usize, usize) { let mut size_x = 0; let mut size_y = 0; @@ -42,6 +40,31 @@ impl <'a> RasterBand<'a> { (size_x as usize, size_y as usize) } + /// Get x-size of the band + pub fn x_size(&self) -> usize { + let out; + unsafe { + out = gdal_sys::GDALGetRasterBandXSize(self.c_rasterband); + } + out as usize + } + + /// Get y-size of the band + pub fn y_size(&self) -> usize { + let out; + unsafe { + out = gdal_sys::GDALGetRasterBandYSize(self.c_rasterband) + } + out as usize + } + + /// Get dimensions of the band. + /// Note that this may not be the same as `size` on the + /// `owning_dataset` due to scale. + pub fn size(&self) -> (usize, usize) { + (self.x_size(), self.y_size()) + } + /// Read a 'Buffer' from a 'Dataset'. T implements 'GdalType' /// # Arguments /// * band_index - the band_index @@ -252,17 +275,8 @@ impl <'a> RasterBand<'a> { None } - pub fn block_size(&self) -> (usize, usize) { - let mut block_size_x = 0; - let mut block_size_y = 0; - unsafe { gdal_sys::GDALGetBlockSize( - self.c_rasterband, - &mut block_size_x, - &mut block_size_y, - )} - (block_size_x as usize, block_size_y as usize) - } - + /// Get actual block size (at the edges) when block size + /// does not divide band size. #[cfg(feature = "gdal_2_2")] pub fn actual_block_size(&self, offset: (isize, isize)) -> Result<(usize, usize)>{ diff --git a/src/raster/tests.rs b/src/raster/tests.rs index a502c091..bb00fcd7 100644 --- a/src/raster/tests.rs +++ b/src/raster/tests.rs @@ -365,3 +365,29 @@ fn test_get_offset() { let offset = rasterband.offset(); assert_eq!(offset, Some(0.0)); } + + +#[test] +fn test_get_rasterband_size() { + let dataset = Dataset::open(fixture!("tinymarble.png")).unwrap(); + let rasterband = dataset.rasterband(1).unwrap(); + let size = rasterband.size(); + assert_eq!(size, (100, 50)); +} + +#[test] +fn test_get_rasterband_block_size() { + let dataset = Dataset::open(fixture!("tinymarble.png")).unwrap(); + let rasterband = dataset.rasterband(1).unwrap(); + let size = rasterband.block_size(); + assert_eq!(size, (100, 1)); +} + +#[test] +#[cfg(feature = "gdal_2_2")] +fn test_get_rasterband_actual_block_size() { + let dataset = Dataset::open(fixture!("tinymarble.png")).unwrap(); + let rasterband = dataset.rasterband(1).unwrap(); + let size = rasterband.actual_block_size((0,40)); + assert_eq!(size.unwrap(), (100, 1)); +}