Skip to content

Commit

Permalink
Added rasterband.rs and moved all band functions from dataset.rs to r…
Browse files Browse the repository at this point in the history
…asterband.rs.

Added more rasterband functions and tests.
  • Loading branch information
jdroenner committed Jun 15, 2016
1 parent 0f9e954 commit b0baa92
Show file tree
Hide file tree
Showing 6 changed files with 276 additions and 104 deletions.
25 changes: 25 additions & 0 deletions examples/rasterband.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
extern crate gdal;

use std::path::Path;
use gdal::raster::{Dataset, RasterBand};
use gdal::metadata::Metadata;

fn main() {

let path = Path::new("./fixtures/tinymarble.png");
let dataset = Dataset::open(path).unwrap();
println!("dataset description: {:?}", dataset.get_description());

let rasterband: RasterBand = dataset.get_rasterband(1).unwrap();
println!("rasterband description: {:?}", rasterband.get_description());
println!("rasterband no_data_value: {:?}", rasterband.get_no_data_value());
println!("rasterband type: {:?}", rasterband.get_band_type());
println!("rasterband scale: {:?}", rasterband.get_scale());
println!("rasterband offset: {:?}", rasterband.get_offset());
let rv = rasterband.read_as::<u8>(
(20, 30),
(2, 3),
(2, 3)
);
println!("{:?}", rv.data);
}
122 changes: 33 additions & 89 deletions src/raster/dataset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use libc::{c_int, c_double, c_void};
use std::ffi::CString;
use std::path::Path;
use utils::_string;
use raster::{gdal, Driver};
use raster::{gdal, Driver, RasterBand};
use raster::driver::_register_drivers;
use raster::gdal_enums::{GDALRWFlag, GDALAccess, GDALDataType};
use raster::gdal_enums::{GDALAccess, GDALDataType};
use raster::types::GdalType;
use gdal_major_object::MajorObject;
use metadata::Metadata;
Expand All @@ -22,8 +22,7 @@ impl MajorObject for Dataset {
}

impl Metadata for Dataset {}



impl Drop for Dataset {
fn drop(&mut self) {
unsafe { gdal::GDALClose(self.c_dataset); }
Expand All @@ -49,11 +48,22 @@ impl Dataset {

pub unsafe fn _c_ptr(&self) -> *const c_void {
return self.c_dataset;
}

pub fn size(&self) -> (isize, isize) {
let size_x = unsafe { gdal::GDALGetRasterXSize(self.c_dataset) } as isize;
let size_y = unsafe { gdal::GDALGetRasterYSize(self.c_dataset) } as isize;
}


pub fn get_rasterband<'a>(&'a self, band_index: isize) -> Option<RasterBand<'a>> {
unsafe {
let c_band = gdal::GDALGetRasterBand(self.c_dataset, band_index as c_int);
if c_band.is_null() {
return None;
}
Some(RasterBand::_with_c_ptr(c_band, self))
}
}

pub fn size(&self) -> (usize, usize) {
let size_x = unsafe { gdal::GDALGetRasterXSize(self.c_dataset) } as usize;
let size_y = unsafe { gdal::GDALGetRasterYSize(self.c_dataset) } as usize;
return (size_x, size_y);
}

Expand Down Expand Up @@ -122,7 +132,11 @@ impl Dataset {
true => None,
false => Some(Dataset{c_dataset: c_dataset}),
};
}
}

pub fn get_band_type(&self, band_index: isize) -> Option<GDALDataType> {
self.get_rasterband(band_index).map(|band| band.get_band_type())
}

/// Read a 'Buffer<u8>' from a 'Dataset'.
/// # Arguments
Expand All @@ -135,7 +149,7 @@ impl Dataset {
window: (isize, isize),
window_size: (usize, usize),
size: (usize, usize)
) -> ByteBuffer
) -> Option<ByteBuffer>
{
self.read_raster_as::<u8>(
band_index,
Expand All @@ -151,23 +165,10 @@ impl Dataset {
pub fn read_full_raster_as<T: Copy + GdalType>(
&self,
band_index: isize,
) -> Buffer<T>
) -> Option<Buffer<T>>
{
let size_x;
let size_y;

unsafe{
size_x = gdal::GDALGetRasterXSize(self.c_dataset) as usize;
size_y = gdal::GDALGetRasterYSize(self.c_dataset) as usize;
}

self.read_raster_as::<T>(
band_index,
(0, 0),
(size_x, size_y),
(size_y, size_y)
)
}
self.get_rasterband(band_index).map(|band| band.read_band_as())
}

/// Read a 'Buffer<T>' from a 'Dataset'. T implements 'GdalType'
/// # Arguments
Expand All @@ -181,34 +182,9 @@ impl Dataset {
window: (isize, isize),
window_size: (usize, usize),
size: (usize, usize),
) -> Buffer<T>
) -> Option<Buffer<T>>
{
let pixels = (size.0 * size.1) as usize;
let mut data: Vec<T> = Vec::with_capacity(pixels);
//let no_data:
unsafe {
let c_band = gdal::GDALGetRasterBand(self.c_dataset, band_index as c_int);
let rv = gdal::GDALRasterIO(
c_band,
GDALRWFlag::GF_Read,
window.0 as c_int,
window.1 as c_int,
window_size.0 as c_int,
window_size.1 as c_int,
data.as_mut_ptr() as *const c_void,
size.0 as c_int,
size.1 as c_int,
T::gdal_type(),
0,
0
) as isize;
assert!(rv == 0);
data.set_len(pixels);
};
Buffer{
size: size,
data: data,
}
self.get_rasterband(band_index).map(|band| band.read_as(window, window_size, size))
}

/// Write a 'Buffer<T>' into a 'Dataset'.
Expand All @@ -223,41 +199,9 @@ impl Dataset {
window_size: (usize, usize),
buffer: Buffer<T>
) {
assert_eq!(buffer.data.len(), buffer.size.0 * buffer.size.1);
unsafe {
let c_band = gdal::GDALGetRasterBand(self.c_dataset, band_index as c_int);
let rv = gdal::GDALRasterIO(
c_band,
GDALRWFlag::GF_Write,
window.0 as c_int,
window.1 as c_int,
window_size.0 as c_int,
window_size.1 as c_int,
buffer.data.as_ptr() as *const c_void,
buffer.size.0 as c_int,
buffer.size.1 as c_int,
T::gdal_type(),
0,
0
) as isize;
assert!(rv == 0);
};
}


pub fn get_band_type(&self, band_index: isize) -> Option<GDALDataType> {

let band_count = self.count();
if band_index < 1 || band_count < band_index {
return None
}

let gdal_type: c_int;
unsafe{
gdal_type = gdal::GDALGetRasterDataType(gdal::GDALGetRasterBand(self.c_dataset, band_index as c_int));
}
Some(GDALDataType::from_c_int(gdal_type))
self.get_rasterband(band_index).expect("Invalid RasterBand").write(window, window_size, buffer)
}

}

pub struct Buffer<T: GdalType> {
Expand All @@ -271,4 +215,4 @@ impl<T: GdalType> Buffer<T> {
}
}

pub type ByteBuffer = Buffer<u8>;
pub type ByteBuffer = Buffer<u8>;
16 changes: 11 additions & 5 deletions src/raster/gdal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use super::gdal_enums::*;

#[link(name="gdal")]
extern {
// driver
pub fn GDALAllRegister();
pub fn GDALGetDriverByName(pszName: *const c_char) -> *const c_void;
pub fn GDALGetDriverShortName(hDriver: *const c_void) -> *const c_char;
Expand All @@ -26,17 +27,22 @@ extern {
pProgressData: *const c_void
) -> *const c_void;
pub fn GDALOpen(pszFilename: *const c_char, eAccess: GDALAccess) -> *const c_void;
// dataset
pub fn GDALClose(hDS: *const c_void);
pub fn GDALGetDatasetDriver(hDataset: *const c_void) -> *const c_void;
pub fn GDALGetRasterXSize(hDataset: *const c_void) -> c_int;
pub fn GDALGetRasterYSize(hDataset: *const c_void) -> c_int;
pub fn GDALGetRasterCount(hDataset: *const c_void) -> c_int;
pub fn GDALGetProjectionRef(hDataset: *const c_void) -> *const c_char;
pub fn GDALSetProjection(hDataset: *const c_void, pszProjection: *const c_char) -> c_int;
pub fn GDALSetGeoTransform(hDataset: *const c_void, padfTransform: *const c_double) -> c_int;
pub fn GDALGetGeoTransform(hDataset: *const c_void, padfTransform: *mut c_double) -> c_int;
pub fn GDALGetRasterBand(hDataset: *const c_void, nBandId: c_int) -> *const c_void;
// band
pub fn GDALGetRasterDataType(hBand: *const c_void) -> c_int;
pub fn GDALGetProjectionRef(hDS: *const c_void) -> *const c_char;
pub fn GDALSetProjection(hDS: *const c_void, pszProjection: *const c_char) -> c_int;
pub fn GDALSetGeoTransform(hDS: *const c_void, padfTransform: *const c_double) -> c_int;
pub fn GDALGetGeoTransform(hDS: *const c_void, padfTransform: *mut c_double) -> c_int;
pub fn GDALGetRasterBand(hDS: *const c_void, nBandId: c_int) -> *const c_void;
pub fn GDALGetRasterNoDataValue(hBand: *const c_void, pbSuccess: *mut c_int) -> c_double;
pub fn GDALGetRasterOffset(hBand: *const c_void, pbSuccess: *mut c_int) -> c_double;
pub fn GDALGetRasterScale(hBand: *const c_void, pbSuccess: *mut c_int) -> c_double;
pub fn GDALRasterIO(
hBand: *const c_void,
eRWFlag: GDALRWFlag,
Expand Down
6 changes: 4 additions & 2 deletions src/raster/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
pub use raster::dataset::{Dataset, Buffer, ByteBuffer};
pub use raster::driver::Driver;
pub use raster::warp::reproject;
pub use raster::warp::reproject;
pub use raster::rasterband::{RasterBand};

mod gdal;
mod types;
mod gdal_enums;
pub mod dataset;
pub mod driver;
pub mod warp;
pub mod warp;
pub mod rasterband;

#[cfg(test)]
mod tests;
Loading

0 comments on commit b0baa92

Please sign in to comment.