Skip to content

Commit

Permalink
Merge ccf98c2 into 9345266
Browse files Browse the repository at this point in the history
  • Loading branch information
rhugonnet committed Mar 18, 2024
2 parents 9345266 + ccf98c2 commit 15df281
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 30 deletions.
36 changes: 19 additions & 17 deletions tests/test_terrain.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,16 @@ def test_attribute_functions_against_gdaldem(self, attribute: str) -> None:
# warnings.simplefilter("error")

functions = {
"slope_Horn": lambda dem: xdem.terrain.slope(dem.data, dem.res, degrees=True),
"slope_Horn": lambda dem: xdem.terrain.slope(dem.data, resolution=dem.res, degrees=True),
"aspect_Horn": lambda dem: xdem.terrain.aspect(dem.data, degrees=True),
"hillshade_Horn": lambda dem: xdem.terrain.hillshade(dem.data, dem.res),
"hillshade_Horn": lambda dem: xdem.terrain.hillshade(dem.data, resolution=dem.res),
"slope_Zevenberg": lambda dem: xdem.terrain.slope(
dem.data, dem.res, method="ZevenbergThorne", degrees=True
dem.data, resolution=dem.res, method="ZevenbergThorne", degrees=True
),
"aspect_Zevenberg": lambda dem: xdem.terrain.aspect(dem.data, method="ZevenbergThorne", degrees=True),
"hillshade_Zevenberg": lambda dem: xdem.terrain.hillshade(dem.data, dem.res, method="ZevenbergThorne"),
"hillshade_Zevenberg": lambda dem: xdem.terrain.hillshade(
dem.data, resolution=dem.res, method="ZevenbergThorne"
),
"tri_Riley": lambda dem: xdem.terrain.terrain_ruggedness_index(dem.data, method="Riley"),
"tri_Wilson": lambda dem: xdem.terrain.terrain_ruggedness_index(dem.data, method="Wilson"),
"tpi": lambda dem: xdem.terrain.topographic_position_index(dem.data),
Expand Down Expand Up @@ -190,12 +192,12 @@ def test_attribute_functions_against_richdem(self, attribute: str) -> None:

# Functions for xdem-implemented methods
functions_xdem = {
"slope_Horn": lambda dem: xdem.terrain.slope(dem, dem.res, degrees=True),
"slope_Horn": lambda dem: xdem.terrain.slope(dem, resolution=dem.res, degrees=True),
"aspect_Horn": lambda dem: xdem.terrain.aspect(dem.data, degrees=True),
"hillshade_Horn": lambda dem: xdem.terrain.hillshade(dem.data, dem.res),
"curvature": lambda dem: xdem.terrain.curvature(dem.data, dem.res),
"profile_curvature": lambda dem: xdem.terrain.profile_curvature(dem.data, dem.res),
"planform_curvature": lambda dem: xdem.terrain.planform_curvature(dem.data, dem.res),
"hillshade_Horn": lambda dem: xdem.terrain.hillshade(dem.data, resolution=dem.res),
"curvature": lambda dem: xdem.terrain.curvature(dem.data, resolution=dem.res),
"profile_curvature": lambda dem: xdem.terrain.profile_curvature(dem.data, resolution=dem.res),
"planform_curvature": lambda dem: xdem.terrain.planform_curvature(dem.data, resolution=dem.res),
}

# Functions for RichDEM wrapper methods
Expand Down Expand Up @@ -269,25 +271,25 @@ def test_hillshade_errors(self) -> None:
warnings.simplefilter("error")

with pytest.raises(ValueError, match="Azimuth must be a value between 0 and 360"):
xdem.terrain.hillshade(self.dem.data, self.dem.res, azimuth=361)
xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, azimuth=361)

with pytest.raises(ValueError, match="Altitude must be a value between 0 and 90"):
xdem.terrain.hillshade(self.dem.data, self.dem.res, altitude=91)
xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, altitude=91)

with pytest.raises(ValueError, match="z_factor must be a non-negative finite value"):
xdem.terrain.hillshade(self.dem.data, self.dem.res, z_factor=np.inf)
xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, z_factor=np.inf)

def test_hillshade(self) -> None:
"""Test hillshade-specific settings."""
warnings.simplefilter("error")
zfactor_1 = xdem.terrain.hillshade(self.dem.data, self.dem.res, z_factor=1.0)
zfactor_10 = xdem.terrain.hillshade(self.dem.data, self.dem.res, z_factor=10.0)
zfactor_1 = xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, z_factor=1.0)
zfactor_10 = xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, z_factor=10.0)

# A higher z-factor should be more variable than a low one.
assert np.nanstd(zfactor_1) < np.nanstd(zfactor_10)

low_altitude = xdem.terrain.hillshade(self.dem.data, self.dem.res, altitude=10)
high_altitude = xdem.terrain.hillshade(self.dem.data, self.dem.res, altitude=80)
low_altitude = xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, altitude=10)
high_altitude = xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, altitude=80)

# A low altitude should be darker than a high altitude.
assert np.nanmean(low_altitude) < np.nanmean(high_altitude)
Expand Down Expand Up @@ -339,7 +341,7 @@ def test_get_terrain_attribute(self) -> None:
)

# Create a hillshade using its own function
hillshade2 = xdem.terrain.hillshade(self.dem.data, self.dem.res)
hillshade2 = xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res)

# Validate that the "batch-created" hillshades and slopes are the same as the "single-created"
assert np.array_equal(hillshade, hillshade2, equal_nan=True)
Expand Down
28 changes: 15 additions & 13 deletions xdem/terrain.py
Original file line number Diff line number Diff line change
Expand Up @@ -1114,9 +1114,9 @@ def get_terrain_attribute(
@overload
def slope(
dem: NDArrayf | MArrayf,
resolution: float | tuple[float, float] | None = None,
method: str = "Horn",
degrees: bool = True,
resolution: float | tuple[float, float] | None = None,
use_richdem: bool = False,
) -> NDArrayf:
...
Expand All @@ -1125,19 +1125,19 @@ def slope(
@overload
def slope(
dem: RasterType,
resolution: float | tuple[float, float] | None = None,
method: str = "Horn",
degrees: bool = True,
resolution: float | tuple[float, float] | None = None,
use_richdem: bool = False,
) -> Raster:
...


def slope(
dem: NDArrayf | MArrayf | RasterType,
resolution: float | tuple[float, float] | None = None,
method: str = "Horn",
degrees: bool = True,
resolution: float | tuple[float, float] | None = None,
use_richdem: bool = False,
) -> NDArrayf | Raster:
"""
Expand All @@ -1147,9 +1147,9 @@ def slope(
http://dx.doi.org/10.1002/esp.3290120107.
:param dem: The DEM to generate a slope map for.
:param resolution: The X/Y or (X, Y) resolution of the DEM.
:param method: Method to calculate slope: "Horn" or "ZevenbergThorne".
:param degrees: Whether to use degrees or radians (False means radians).
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
:param use_richdem: Whether to use RichDEM to compute the attribute.
:examples:
Expand Down Expand Up @@ -1205,6 +1205,8 @@ def aspect(
0=N, 90=E, 180=S, 270=W.
Note that aspect, representing only the orientation of the slope, is independent of the grid resolution.
:param dem: The DEM to calculate the aspect from.
:param method: Method to calculate aspect: "Horn" or "ZevenbergThorne".
:param degrees: Whether to use degrees or radians (False means radians).
Expand Down Expand Up @@ -1234,11 +1236,11 @@ def aspect(
@overload
def hillshade(
dem: NDArrayf | MArrayf,
resolution: float | tuple[float, float] | None = None,
method: str = "Horn",
azimuth: float = 315.0,
altitude: float = 45.0,
z_factor: float = 1.0,
resolution: float | tuple[float, float] | None = None,
use_richdem: bool = False,
) -> NDArrayf:
...
Expand All @@ -1247,23 +1249,23 @@ def hillshade(
@overload
def hillshade(
dem: RasterType,
resolution: float | tuple[float, float] | None = None,
method: str = "Horn",
azimuth: float = 315.0,
altitude: float = 45.0,
z_factor: float = 1.0,
resolution: float | tuple[float, float] | None = None,
use_richdem: bool = False,
) -> RasterType:
...


def hillshade(
dem: NDArrayf | MArrayf,
resolution: float | tuple[float, float] | None = None,
method: str = "Horn",
azimuth: float = 315.0,
altitude: float = 45.0,
z_factor: float = 1.0,
resolution: float | tuple[float, float] | None = None,
use_richdem: bool = False,
) -> NDArrayf | RasterType:
"""
Expand All @@ -1272,11 +1274,11 @@ def hillshade(
Based on Horn (1981), http://dx.doi.org/10.1109/PROC.1981.11918.
:param dem: The input DEM to calculate the hillshade from.
:param resolution: One or two values specifying the resolution of the DEM.
:param method: Method to calculate the slope and aspect used for hillshading.
:param azimuth: The shading azimuth in degrees (0-360°) going clockwise, starting from north.
:param altitude: The shading altitude in degrees (0-90°). 90° is straight from above.
:param z_factor: Vertical exaggeration factor.
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
:param use_richdem: Whether to use RichDEM to compute the slope and aspect used for the hillshade.
Expand Down Expand Up @@ -1334,7 +1336,7 @@ def curvature(
See xdem.terrain.get_quadric_coefficients() for more information.
:param dem: The DEM to calculate the curvature from.
:param resolution: The X/Y resolution of the DEM.
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
:param use_richdem: Whether to use RichDEM to compute the attribute.
:raises ValueError: If the inputs are poorly formatted.
Expand Down Expand Up @@ -1380,7 +1382,7 @@ def planform_curvature(
Based on Zevenbergen and Thorne (1987), http://dx.doi.org/10.1002/esp.3290120107.
:param dem: The DEM to calculate the curvature from.
:param resolution: The X/Y resolution of the DEM.
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
:param use_richdem: Whether to use RichDEM to compute the attribute.
:raises ValueError: If the inputs are poorly formatted.
Expand Down Expand Up @@ -1433,7 +1435,7 @@ def profile_curvature(
Based on Zevenbergen and Thorne (1987), http://dx.doi.org/10.1002/esp.3290120107.
:param dem: The DEM to calculate the curvature from.
:param resolution: The X/Y resolution of the DEM.
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
:param use_richdem: Whether to use RichDEM to compute the attribute.
:raises ValueError: If the inputs are poorly formatted.
Expand Down Expand Up @@ -1485,7 +1487,7 @@ def maximum_curvature(
Based on Zevenbergen and Thorne (1987), http://dx.doi.org/10.1002/esp.3290120107.
:param dem: The DEM to calculate the curvature from.
:param resolution: The X/Y resolution of the DEM.
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
:param use_richdem: Whether to use RichDEM to compute the attribute.
:raises ValueError: If the inputs are poorly formatted.
Expand Down Expand Up @@ -1648,7 +1650,7 @@ def rugosity(
Based on: Jenness (2004), https://doi.org/10.2193/0091-7648(2004)032[0829:CLSAFD]2.0.CO;2.
:param dem: The DEM to calculate the rugosity from.
:param resolution: The X/Y resolution of the DEM.
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
:raises ValueError: If the inputs are poorly formatted.
Expand Down

0 comments on commit 15df281

Please sign in to comment.