Skip to content

Commit

Permalink
Merge pull request #1 from lnicola/dem-cleanups
Browse files Browse the repository at this point in the history
DEM cleanups
  • Loading branch information
metasim authored Nov 16, 2023
2 parents 2e1c13e + e78c542 commit 11c8281
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 188 deletions.
22 changes: 12 additions & 10 deletions src/raster/processing/dem/aspect.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
use std::num::NonZeroUsize;

use super::options::common_dem_options;
use crate::cpl::CslStringList;
use crate::errors;
use crate::raster::processing::dem::DemSlopeAlg;
use std::num::NonZeroUsize;

/// Configuration options for [`aspect()`][super::aspect()].
#[derive(Debug, Clone, Default)]
pub struct AspectOptions {
input_band: Option<NonZeroUsize>,
compute_edges: bool,
compute_edges: Option<bool>,
output_format: Option<String>,
additional_options: CslStringList,
algorithm: Option<DemSlopeAlg>,
Expand Down Expand Up @@ -45,25 +47,25 @@ impl AspectOptions {

/// Render relevant common options into [`CslStringList`] values, as compatible with
/// [`gdal_sys::GDALDEMProcessing`].
pub fn to_options_list(&self) -> CslStringList {
pub fn to_options_list(&self) -> errors::Result<CslStringList> {
let mut opts = CslStringList::default();

self.store_common_options_to(&mut opts);
self.store_common_options_to(&mut opts)?;

if let Some(alg) = self.algorithm {
opts.add_string("-alg").unwrap();
opts.add_string(&alg.to_string()).unwrap();
opts.add_string("-alg")?;
opts.add_string(alg.to_gdal_option())?;
}

if self.zero_for_flat == Some(true) {
opts.add_string("-zero_for_flat").unwrap();
opts.add_string("-zero_for_flat")?;
}

if self.trigonometric == Some(true) {
opts.add_string("-trigonometric").unwrap();
opts.add_string("-trigonometric")?;
}

opts
Ok(opts)
}
}

Expand Down Expand Up @@ -93,7 +95,7 @@ mod tests {
let expected: CslStringList =
"-compute_edges -b 2 -of GTiff CPL_DEBUG=ON -alg ZevenbergenThorne -zero_for_flat -trigonometric"
.parse()?;
assert_eq!(expected.to_string(), proc.to_options_list().to_string());
assert_eq!(expected.to_string(), proc.to_options_list()?.to_string());

Ok(())
}
Expand Down
33 changes: 13 additions & 20 deletions src/raster/processing/dem/color_relief.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ use std::num::NonZeroUsize;
use std::path::{Path, PathBuf};

use crate::cpl::CslStringList;
use crate::errors;
use crate::raster::processing::dem::options::common_dem_options;

/// Configuration options for [`color_relief()`][super::color_relief()].
#[derive(Debug, Clone)]
pub struct ColorReliefOptions {
input_band: Option<NonZeroUsize>,
compute_edges: bool,
compute_edges: Option<bool>,
output_format: Option<String>,
additional_options: CslStringList,
color_config: PathBuf,
Expand Down Expand Up @@ -43,7 +44,7 @@ impl ColorReliefOptions {
///
/// # Example
/// Here's an example `.clr` file showing a number of the features described above.
///
///
/// ```text
/// 2600 white
/// 2000 235 220 175
Expand All @@ -57,7 +58,7 @@ impl ColorReliefOptions {
pub fn new<P: AsRef<Path>>(color_config: P) -> Self {
Self {
input_band: None,
compute_edges: false,
compute_edges: None,
output_format: None,
additional_options: Default::default(),
color_config: color_config.as_ref().to_path_buf(),
Expand All @@ -74,11 +75,6 @@ impl ColorReliefOptions {
self
}

/// Get path to the color relief configuration file.
pub fn color_config(&self) -> PathBuf {
self.color_config.to_owned()
}

/// Specify the color matching mode.
///
/// See [`ColorMatchingMode`] for details.
Expand All @@ -87,31 +83,28 @@ impl ColorReliefOptions {
self
}

/// Get the color matching mode to be used.
pub fn color_matching_mode(&self) -> ColorMatchingMode {
self.color_matching_mode
pub(crate) fn color_config(&self) -> &Path {
&self.color_config
}

/// Render relevant common options into [`CslStringList`] values, as compatible with
/// [`gdal_sys::GDALDEMProcessing`].
pub fn to_options_list(&self) -> CslStringList {
pub fn to_options_list(&self) -> errors::Result<CslStringList> {
let mut opts = CslStringList::default();

self.store_common_options_to(&mut opts);
self.store_common_options_to(&mut opts)?;

if self.alpha == Some(true) {
opts.add_string("-alpha").unwrap();
opts.add_string("-alpha")?;
}

match self.color_matching_mode {
ColorMatchingMode::ExactColorEntry => opts.add_string("-exact_color_entry").unwrap(),
ColorMatchingMode::NearestColorEntry => {
opts.add_string("-nearest_color_entry").unwrap()
}
ColorMatchingMode::ExactColorEntry => opts.add_string("-exact_color_entry")?,
ColorMatchingMode::NearestColorEntry => opts.add_string("-nearest_color_entry")?,
_ => {}
}

opts
Ok(opts)
}
}

Expand Down Expand Up @@ -155,7 +148,7 @@ mod tests {

let expected: CslStringList =
"-compute_edges -b 2 -of GTiff CPL_DEBUG=ON -alpha -nearest_color_entry".parse()?;
assert_eq!(expected.to_string(), proc.to_options_list().to_string());
assert_eq!(expected.to_string(), proc.to_options_list()?.to_string());

Ok(())
}
Expand Down
75 changes: 26 additions & 49 deletions src/raster/processing/dem/hillshade.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use std::num::NonZeroUsize;

use crate::cpl::CslStringList;
use crate::errors;
use crate::raster::processing::dem::options::common_dem_options;
use crate::raster::processing::dem::DemSlopeAlg;
use std::fmt::{Display, Formatter};
use std::num::NonZeroUsize;

/// Configuration options for [`hillshade()`][super::hillshade()].
#[derive(Debug, Clone, Default)]
pub struct HillshadeOptions {
input_band: Option<NonZeroUsize>,
compute_edges: bool,
compute_edges: Option<bool>,
output_format: Option<String>,
additional_options: CslStringList,
algorithm: Option<DemSlopeAlg>,
Expand All @@ -33,11 +34,6 @@ impl HillshadeOptions {
self
}

/// Fetch the specified slope computation algorithm
pub fn algorithm(&self) -> Option<DemSlopeAlg> {
self.algorithm
}

/// Specify the altitude of the light, in degrees.
///
/// `90` if the light comes from above the DEM, `0` if it is raking light.
Expand All @@ -46,11 +42,6 @@ impl HillshadeOptions {
self
}

/// Fetch the specified light altitude, in degrees.
pub fn altitude(&self) -> Option<f64> {
self.altitude
}

/// Specify the azimuth of the light, in degrees:
///
/// * `0` if it comes from the top of the raster,
Expand Down Expand Up @@ -82,13 +73,6 @@ impl HillshadeOptions {
self
}

/// Fetch the specified scaling factor.
///
/// Returns `None` if one has not been previously set vai [`Self::with_scale`].
pub fn scale(&self) -> Option<f64> {
self.scale
}

/// Specify the shading mode to render with.
///
/// See [`ShadingMode`] for mode descriptions.
Expand All @@ -97,59 +81,49 @@ impl HillshadeOptions {
self
}

/// Fetch the specified shading mode.
pub fn shading_mode(&self) -> Option<ShadingMode> {
self.shading
}

/// Vertical exaggeration used to pre-multiply the elevations
pub fn with_z_factor(&mut self, z_factor: f64) -> &mut Self {
self.z_factor = Some(z_factor);
self
}

/// Fetch the applied z-factor value.
pub fn z_factor(&self) -> Option<f64> {
self.z_factor
}

/// Render relevant common options into [`CslStringList`] values, as compatible with
/// [`gdal_sys::GDALDEMProcessing`].
pub fn to_options_list(&self) -> CslStringList {
pub fn to_options_list(&self) -> errors::Result<CslStringList> {
let mut opts = CslStringList::default();

self.store_common_options_to(&mut opts);
self.store_common_options_to(&mut opts)?;

if let Some(alg) = self.algorithm {
opts.add_string("-alg").unwrap();
opts.add_string(&alg.to_string()).unwrap();
opts.add_string("-alg")?;
opts.add_string(alg.to_gdal_option())?;
}

if let Some(scale) = self.scale {
opts.add_string("-s").unwrap();
opts.add_string(&scale.to_string()).unwrap();
opts.add_string("-s")?;
opts.add_string(&scale.to_string())?;
}

if let Some(mode) = self.shading {
opts.add_string(&format!("-{mode}")).unwrap();
opts.add_string(mode.to_gdal_option())?;
}

if let Some(factor) = self.z_factor {
opts.add_string("-z").unwrap();
opts.add_string(&factor.to_string()).unwrap();
opts.add_string("-z")?;
opts.add_string(&factor.to_string())?;
}

if let Some(altitude) = self.altitude {
opts.add_string("-alt").unwrap();
opts.add_string(&altitude.to_string()).unwrap();
opts.add_string("-alt")?;
opts.add_string(&altitude.to_string())?;
}

if let Some(azimuth) = self.azimuth {
opts.add_string("-az").unwrap();
opts.add_string(&azimuth.to_string()).unwrap();
opts.add_string("-az")?;
opts.add_string(&azimuth.to_string())?;
}

opts
Ok(opts)
}
}

Expand All @@ -172,10 +146,13 @@ pub enum ShadingMode {
Igor,
}

impl Display for ShadingMode {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let s = format!("{self:?}");
f.write_str(&s.to_lowercase())
impl ShadingMode {
fn to_gdal_option(self) -> &'static str {
match self {
ShadingMode::Combined => "-combined",
ShadingMode::Multidirectional => "-multidirectional",
ShadingMode::Igor => "-igor",
}
}
}

Expand Down Expand Up @@ -208,7 +185,7 @@ mod tests {
let expected: CslStringList =
"-compute_edges -b 2 -of GTiff CPL_DEBUG=ON -alg ZevenbergenThorne -s 98473 -igor -z 2 -alt 45 -az 330"
.parse()?;
assert_eq!(expected.to_string(), proc.to_options_list().to_string());
assert_eq!(expected.to_string(), proc.to_options_list()?.to_string());

Ok(())
}
Expand Down
Loading

0 comments on commit 11c8281

Please sign in to comment.