Add documentation
+ add docs for `Dataset` and `RasterBand`.
+ fix `cfg()` for GDAL OpenEx flags.
MODIFY
src/dataset.rs
src/dataset.rs
@@ -16,9 +16,23 @@ use std::convert::TryInto;
use bitflags::bitflags;
+/// A 2-D affine transform mapping pixel coordiates to world
+/// coordinates. See [GDALGetGeoTransform] for more details.
+///
+/// [GDALGetGeoTransform]: https://gdal.org/api/gdaldataset_cpp.html#classGDALDataset_1a5101119705f5fa2bc1344ab26f66fd1d
pub type GeoTransform = [c_double; 6];
static START: Once = Once::new();
+/// Wrapper around a [`GDALDataset`][GDALDataset] object.
+///
+/// Represents both a [vector dataset][vector-data-model]
+/// containing a collection of layers; and a [raster
+/// dataset][raster-data-model] containing a collection of
+/// rasterbands.
+///
+/// [vector-data-model]: https://gdal.org/user/vector_data_model.html
+/// [raster-data-model]: https://gdal.org/user/raster_data_model.html
+/// [GDALDataset]: https://gdal.org/api/gdaldataset_cpp.html#_CPPv411GDALDataset
#[derive(Debug)]
pub struct Dataset {
c_dataset: GDALDatasetH,
@@ -32,44 +46,54 @@ pub fn _register_drivers() {
}
}
-// GDal extended open flags, skipped by bindgen
-//
-// Note that the `GDAL_OF_SHARED` option is removed from the set
-// of allowed option because it subverts the [`Send`] implementation
-// that allow passing the dataset the another thread.
-// See https://github.com/georust/gdal/issues/154.
+// These are skipped by bindgen and manually updated.
#[cfg(major_ge_2)]
bitflags! {
+ /// GDal extended open flags used by [`Dataset::open_ex`].
+ ///
+ /// Used in the `nOpenFlags` argument to [`GDALOpenEx`].
+ ///
+ /// Note that the `GDAL_OF_SHARED` option is removed
+ /// from the set of allowed option because it subverts
+ /// the [`Send`] implementation that allow passing the
+ /// dataset the another thread. See
+ /// https://github.com/georust/gdal/issues/154.
+ ///
+ /// [`GDALOpenEx`]: https://gdal.org/doxygen/gdal_8h.html#a9cb8585d0b3c16726b08e25bcc94274a
pub struct GdalOpenFlags: c_uint {
+ /// Open in read-only mode (default).
const GDAL_OF_READONLY = 0x00;
- // Open in update mode.
+ /// Open in update mode.
const GDAL_OF_UPDATE = 0x01;
- // Allow raster and vector drivers to be used.
+ /// Allow raster and vector drivers to be used.
const GDAL_OF_ALL = 0x00;
- // Allow raster drivers to be used.
+ /// Allow raster drivers to be used.
const GDAL_OF_RASTER = 0x02;
- // Allow vector drivers to be used.
+ /// Allow vector drivers to be used.
const GDAL_OF_VECTOR = 0x04;
- // Allow gnm drivers to be used.
- #[cfg(all(major_ge_2,minor_ge_1))]
+ /// Allow gnm drivers to be used.
+ #[cfg(any( all(major_ge_2,minor_ge_1), major_ge_3 ))]
const GDAL_OF_GNM = 0x08;
- // Allow multidimensional raster drivers to be used.
+ /// Allow multidimensional raster drivers to be used.
#[cfg(all(major_ge_3,minor_ge_1))]
const GDAL_OF_MULTIDIM_RASTER = 0x10;
- // Emit error message in case of failed open.
+ /// Emit error message in case of failed open.
const GDAL_OF_VERBOSE_ERROR = 0x40;
- // Open as internal dataset. Such dataset isn't registered in the global list
- // of opened dataset. Cannot be used with GDAL_OF_SHARED.
+ /// Open as internal dataset. Such dataset isn't
+ /// registered in the global list of opened dataset.
+ /// Cannot be used with GDAL_OF_SHARED.
const GDAL_OF_INTERNAL = 0x80;
- // Let GDAL decide if a array-based or hashset-based storage strategy for
- // cached blocks must be used.
- // GDAL_OF_DEFAULT_BLOCK_ACCESS, GDAL_OF_ARRAY_BLOCK_ACCESS and
- // GDAL_OF_HASHSET_BLOCK_ACCESS are mutually exclusive.
- #[cfg(all(major_ge_2,minor_ge_1))]
+
+ /// Default strategy for cached blocks.
+ #[cfg(any( all(major_ge_2,minor_ge_1), major_ge_3 ))]
const GDAL_OF_DEFAULT_BLOCK_ACCESS = 0;
- #[cfg(all(major_ge_2,minor_ge_1))]
+
+ /// Array based strategy for cached blocks.
+ #[cfg(any( all(major_ge_2,minor_ge_1), major_ge_3 ))]
const GDAL_OF_ARRAY_BLOCK_ACCESS = 0x100;
- #[cfg(all(major_ge_2,minor_ge_1))]
+
+ /// Hashset based strategy for cached blocks.
+ #[cfg(any( all(major_ge_2,minor_ge_1), major_ge_3 ))]
const GDAL_OF_HASHSET_BLOCK_ACCESS = 0x200;
}
}
@@ -115,10 +139,14 @@ impl Dataset {
self.c_dataset
}
+ /// Open a dataset at the given `path` with default
+ /// options.
pub fn open(path: &Path) -> Result<Dataset> {
Self::open_ex(path, DatasetOptions::default())
}
+ /// Open a dataset with extended options. See
+ /// [GDALOpenEx].
pub fn open_ex(path: &Path, options: DatasetOptions) -> Result<Dataset> {
_register_drivers();
let filename = path.to_string_lossy();
@@ -217,11 +245,13 @@ impl Dataset {
Dataset { c_dataset }
}
+ /// Fetch the projection definition string for this dataset.
pub fn projection(&self) -> String {
let rv = unsafe { gdal_sys::GDALGetProjectionRef(self.c_dataset) };
_string(rv)
}
+ /// Set the projection reference string for this dataset.
pub fn set_projection(&self, projection: &str) -> Result<()> {
let c_projection = CString::new(projection)?;
unsafe { gdal_sys::GDALSetProjection(self.c_dataset, c_projection.as_ptr()) };
@@ -229,11 +259,13 @@ impl Dataset {
}
#[cfg(major_ge_3)]
+ /// Get the spatial reference system for this dataset.
pub fn spatial_ref(&self) -> Result<SpatialRef> {
unsafe { SpatialRef::from_c_obj(gdal_sys::GDALGetSpatialRef(self.c_dataset)) }
}
#[cfg(major_ge_3)]
+ /// Set the spatial reference system for this dataset.
pub fn set_spatial_ref(&self, spatial_ref: &SpatialRef) -> Result<()> {
let rv = unsafe { gdal_sys::GDALSetSpatialRef(self.c_dataset, spatial_ref.to_c_hsrs()) };
if rv != CPLErr::CE_None {
@@ -261,6 +293,7 @@ impl Dataset {
Ok(unsafe { Dataset::from_c_dataset(c_dataset) })
}
+ /// Fetch the driver to which this dataset relates.
pub fn driver(&self) -> Driver {
unsafe {
let c_driver = gdal_sys::GDALGetDatasetDriver(self.c_dataset);
@@ -268,6 +301,10 @@ impl Dataset {
}
}
+ /// Fetch a band object for a dataset.
+ ///
+ /// Applies to raster datasets, and fetches the
+ /// rasterband at the given _1-based_ index.
pub fn rasterband(&self, band_index: isize) -> Result<RasterBand> {
unsafe {
let c_band = gdal_sys::GDALGetRasterBand(self.c_dataset, band_index as c_int);
@@ -282,10 +319,15 @@ impl Dataset {
unsafe { Layer::from_c_layer(self, c_layer) }
}
+ /// Get the number of layers in this dataset.
pub fn layer_count(&self) -> isize {
(unsafe { gdal_sys::OGR_DS_GetLayerCount(self.c_dataset) }) as isize
}
+ /// Fetch a layer by index.
+ ///
+ /// Applies to vector datasets, and fetches by the given
+ /// _0-based_ index.
pub fn layer(&mut self, idx: isize) -> Result<Layer> {
let c_layer = unsafe { gdal_sys::OGR_DS_GetLayer(self.c_dataset, idx as c_int) };
if c_layer.is_null() {
@@ -294,6 +336,7 @@ impl Dataset {
Ok(self.child_layer(c_layer))
}
+ /// Fetch a layer by name.
pub fn layer_by_name(&mut self, name: &str) -> Result<Layer> {
let c_name = CString::new(name)?;
let c_layer = unsafe { gdal_sys::OGR_DS_GetLayerByName(self.c_dataset(), c_name.as_ptr()) };
@@ -303,14 +346,17 @@ impl Dataset {
Ok(self.child_layer(c_layer))
}
+ /// Returns an iterator over the layers of the dataset.
pub fn layers(&self) -> LayerIterator {
LayerIterator::with_dataset(self)
}
+ /// Fetch the number of raster bands on this dataset.
pub fn raster_count(&self) -> isize {
(unsafe { gdal_sys::GDALGetRasterCount(self.c_dataset) }) as isize
}
+ /// Returns the raster dimensions: (width, height).
pub fn raster_size(&self) -> (usize, usize) {
let size_x = unsafe { gdal_sys::GDALGetRasterXSize(self.c_dataset) } as usize;
let size_y = unsafe { gdal_sys::GDALGetRasterYSize(self.c_dataset) } as usize;

MODIFY
src/raster/rasterband.rs
src/raster/rasterband.rs
@@ -202,7 +202,7 @@ impl<'a> RasterBand<'a> {
Array2::from_shape_vec((size.1, size.0), data).map_err(Into::into)
}
- // Write a 'Buffer<T>' into a 'Dataset'.
+ /// Write a 'Buffer<T>' into a 'Dataset'.
/// # Arguments
/// * band_index - the band_index
/// * window - the window position from top left
@@ -236,10 +236,12 @@ impl<'a> RasterBand<'a> {
Ok(())
}
+ /// Returns the pixel datatype of this band.
pub fn band_type(&self) -> GDALDataType::Type {
unsafe { gdal_sys::GDALGetRasterDataType(self.c_rasterband) }
}
+ /// Returns the no data value of this band.
pub fn no_data_value(&self) -> Option<f64> {
let mut pb_success = 1;
let no_data =
@@ -250,6 +252,7 @@ impl<'a> RasterBand<'a> {
None
}
+ /// Set the no data value of this band.
pub fn set_no_data_value(&self, no_data: f64) -> Result<()> {
let rv = unsafe { gdal_sys::GDALSetRasterNoDataValue(self.c_rasterband, no_data) };
if rv != CPLErr::CE_None {
@@ -258,6 +261,7 @@ impl<'a> RasterBand<'a> {
Ok(())
}
+ /// Returns the scale of this band if set.
pub fn scale(&self) -> Option<f64> {
let mut pb_success = 1;
let scale = unsafe { gdal_sys::GDALGetRasterScale(self.c_rasterband, &mut pb_success) };
@@ -267,6 +271,7 @@ impl<'a> RasterBand<'a> {
None
}
+ /// Returns the offset of this band if set.
pub fn offset(&self) -> Option<f64> {
let mut pb_success = 1;
let offset = unsafe { gdal_sys::GDALGetRasterOffset(self.c_rasterband, &mut pb_success) };

Add documentation

+ add docs for `Dataset` and `RasterBand`.
+ fix `cfg()` for GDAL OpenEx flags.