Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow reading block-size of Rasters #67

Merged
merged 4 commits into from
May 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
47 changes: 45 additions & 2 deletions src/raster/rasterband.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: let out = unsafe { gdal_sys::GDALGetRasterBandXSize(self.c_rasterband); }

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<T>' from a 'Dataset'. T implements 'GdalType'
/// # Arguments
/// * band_index - the band_index
Expand Down Expand Up @@ -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> {
Expand Down
26 changes: 26 additions & 0 deletions src/raster/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
30 changes: 29 additions & 1 deletion src/vector/dataset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::*;

Expand Down Expand Up @@ -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?

}
}


Expand Down