diff --git a/Cargo.toml b/Cargo.toml index 4761344c..6649b572 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"] array = ["ndarray"] [dependencies] diff --git a/src/raster/rasterband.rs b/src/raster/rasterband.rs index 092bb4a6..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 @@ -251,6 +274,26 @@ impl <'a> RasterBand<'a> { } None } + + /// 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)>{ + 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> { 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)); +} 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? + + } }