Skip to content

Commit 981d7db

Browse files
authored
Clarify resolution in terrain docstrings (#491)
1 parent 9345266 commit 981d7db

File tree

2 files changed

+34
-30
lines changed

2 files changed

+34
-30
lines changed

tests/test_terrain.py

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,16 @@ def test_attribute_functions_against_gdaldem(self, attribute: str) -> None:
8484
# warnings.simplefilter("error")
8585

8686
functions = {
87-
"slope_Horn": lambda dem: xdem.terrain.slope(dem.data, dem.res, degrees=True),
87+
"slope_Horn": lambda dem: xdem.terrain.slope(dem.data, resolution=dem.res, degrees=True),
8888
"aspect_Horn": lambda dem: xdem.terrain.aspect(dem.data, degrees=True),
89-
"hillshade_Horn": lambda dem: xdem.terrain.hillshade(dem.data, dem.res),
89+
"hillshade_Horn": lambda dem: xdem.terrain.hillshade(dem.data, resolution=dem.res),
9090
"slope_Zevenberg": lambda dem: xdem.terrain.slope(
91-
dem.data, dem.res, method="ZevenbergThorne", degrees=True
91+
dem.data, resolution=dem.res, method="ZevenbergThorne", degrees=True
9292
),
9393
"aspect_Zevenberg": lambda dem: xdem.terrain.aspect(dem.data, method="ZevenbergThorne", degrees=True),
94-
"hillshade_Zevenberg": lambda dem: xdem.terrain.hillshade(dem.data, dem.res, method="ZevenbergThorne"),
94+
"hillshade_Zevenberg": lambda dem: xdem.terrain.hillshade(
95+
dem.data, resolution=dem.res, method="ZevenbergThorne"
96+
),
9597
"tri_Riley": lambda dem: xdem.terrain.terrain_ruggedness_index(dem.data, method="Riley"),
9698
"tri_Wilson": lambda dem: xdem.terrain.terrain_ruggedness_index(dem.data, method="Wilson"),
9799
"tpi": lambda dem: xdem.terrain.topographic_position_index(dem.data),
@@ -190,12 +192,12 @@ def test_attribute_functions_against_richdem(self, attribute: str) -> None:
190192

191193
# Functions for xdem-implemented methods
192194
functions_xdem = {
193-
"slope_Horn": lambda dem: xdem.terrain.slope(dem, dem.res, degrees=True),
195+
"slope_Horn": lambda dem: xdem.terrain.slope(dem, resolution=dem.res, degrees=True),
194196
"aspect_Horn": lambda dem: xdem.terrain.aspect(dem.data, degrees=True),
195-
"hillshade_Horn": lambda dem: xdem.terrain.hillshade(dem.data, dem.res),
196-
"curvature": lambda dem: xdem.terrain.curvature(dem.data, dem.res),
197-
"profile_curvature": lambda dem: xdem.terrain.profile_curvature(dem.data, dem.res),
198-
"planform_curvature": lambda dem: xdem.terrain.planform_curvature(dem.data, dem.res),
197+
"hillshade_Horn": lambda dem: xdem.terrain.hillshade(dem.data, resolution=dem.res),
198+
"curvature": lambda dem: xdem.terrain.curvature(dem.data, resolution=dem.res),
199+
"profile_curvature": lambda dem: xdem.terrain.profile_curvature(dem.data, resolution=dem.res),
200+
"planform_curvature": lambda dem: xdem.terrain.planform_curvature(dem.data, resolution=dem.res),
199201
}
200202

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

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

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

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

280282
def test_hillshade(self) -> None:
281283
"""Test hillshade-specific settings."""
282284
warnings.simplefilter("error")
283-
zfactor_1 = xdem.terrain.hillshade(self.dem.data, self.dem.res, z_factor=1.0)
284-
zfactor_10 = xdem.terrain.hillshade(self.dem.data, self.dem.res, z_factor=10.0)
285+
zfactor_1 = xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, z_factor=1.0)
286+
zfactor_10 = xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, z_factor=10.0)
285287

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

289-
low_altitude = xdem.terrain.hillshade(self.dem.data, self.dem.res, altitude=10)
290-
high_altitude = xdem.terrain.hillshade(self.dem.data, self.dem.res, altitude=80)
291+
low_altitude = xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, altitude=10)
292+
high_altitude = xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res, altitude=80)
291293

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

341343
# Create a hillshade using its own function
342-
hillshade2 = xdem.terrain.hillshade(self.dem.data, self.dem.res)
344+
hillshade2 = xdem.terrain.hillshade(self.dem.data, resolution=self.dem.res)
343345

344346
# Validate that the "batch-created" hillshades and slopes are the same as the "single-created"
345347
assert np.array_equal(hillshade, hillshade2, equal_nan=True)

xdem/terrain.py

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1114,9 +1114,9 @@ def get_terrain_attribute(
11141114
@overload
11151115
def slope(
11161116
dem: NDArrayf | MArrayf,
1117-
resolution: float | tuple[float, float] | None = None,
11181117
method: str = "Horn",
11191118
degrees: bool = True,
1119+
resolution: float | tuple[float, float] | None = None,
11201120
use_richdem: bool = False,
11211121
) -> NDArrayf:
11221122
...
@@ -1125,19 +1125,19 @@ def slope(
11251125
@overload
11261126
def slope(
11271127
dem: RasterType,
1128-
resolution: float | tuple[float, float] | None = None,
11291128
method: str = "Horn",
11301129
degrees: bool = True,
1130+
resolution: float | tuple[float, float] | None = None,
11311131
use_richdem: bool = False,
11321132
) -> Raster:
11331133
...
11341134

11351135

11361136
def slope(
11371137
dem: NDArrayf | MArrayf | RasterType,
1138-
resolution: float | tuple[float, float] | None = None,
11391138
method: str = "Horn",
11401139
degrees: bool = True,
1140+
resolution: float | tuple[float, float] | None = None,
11411141
use_richdem: bool = False,
11421142
) -> NDArrayf | Raster:
11431143
"""
@@ -1147,9 +1147,9 @@ def slope(
11471147
http://dx.doi.org/10.1002/esp.3290120107.
11481148
11491149
:param dem: The DEM to generate a slope map for.
1150-
:param resolution: The X/Y or (X, Y) resolution of the DEM.
11511150
:param method: Method to calculate slope: "Horn" or "ZevenbergThorne".
11521151
:param degrees: Whether to use degrees or radians (False means radians).
1152+
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
11531153
:param use_richdem: Whether to use RichDEM to compute the attribute.
11541154
11551155
:examples:
@@ -1205,6 +1205,8 @@ def aspect(
12051205
12061206
0=N, 90=E, 180=S, 270=W.
12071207
1208+
Note that aspect, representing only the orientation of the slope, is independent of the grid resolution.
1209+
12081210
:param dem: The DEM to calculate the aspect from.
12091211
:param method: Method to calculate aspect: "Horn" or "ZevenbergThorne".
12101212
:param degrees: Whether to use degrees or radians (False means radians).
@@ -1234,11 +1236,11 @@ def aspect(
12341236
@overload
12351237
def hillshade(
12361238
dem: NDArrayf | MArrayf,
1237-
resolution: float | tuple[float, float] | None = None,
12381239
method: str = "Horn",
12391240
azimuth: float = 315.0,
12401241
altitude: float = 45.0,
12411242
z_factor: float = 1.0,
1243+
resolution: float | tuple[float, float] | None = None,
12421244
use_richdem: bool = False,
12431245
) -> NDArrayf:
12441246
...
@@ -1247,23 +1249,23 @@ def hillshade(
12471249
@overload
12481250
def hillshade(
12491251
dem: RasterType,
1250-
resolution: float | tuple[float, float] | None = None,
12511252
method: str = "Horn",
12521253
azimuth: float = 315.0,
12531254
altitude: float = 45.0,
12541255
z_factor: float = 1.0,
1256+
resolution: float | tuple[float, float] | None = None,
12551257
use_richdem: bool = False,
12561258
) -> RasterType:
12571259
...
12581260

12591261

12601262
def hillshade(
12611263
dem: NDArrayf | MArrayf,
1262-
resolution: float | tuple[float, float] | None = None,
12631264
method: str = "Horn",
12641265
azimuth: float = 315.0,
12651266
altitude: float = 45.0,
12661267
z_factor: float = 1.0,
1268+
resolution: float | tuple[float, float] | None = None,
12671269
use_richdem: bool = False,
12681270
) -> NDArrayf | RasterType:
12691271
"""
@@ -1272,11 +1274,11 @@ def hillshade(
12721274
Based on Horn (1981), http://dx.doi.org/10.1109/PROC.1981.11918.
12731275
12741276
:param dem: The input DEM to calculate the hillshade from.
1275-
:param resolution: One or two values specifying the resolution of the DEM.
12761277
:param method: Method to calculate the slope and aspect used for hillshading.
12771278
:param azimuth: The shading azimuth in degrees (0-360°) going clockwise, starting from north.
12781279
:param altitude: The shading altitude in degrees (0-90°). 90° is straight from above.
12791280
:param z_factor: Vertical exaggeration factor.
1281+
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
12801282
:param use_richdem: Whether to use RichDEM to compute the slope and aspect used for the hillshade.
12811283
12821284
@@ -1334,7 +1336,7 @@ def curvature(
13341336
See xdem.terrain.get_quadric_coefficients() for more information.
13351337
13361338
:param dem: The DEM to calculate the curvature from.
1337-
:param resolution: The X/Y resolution of the DEM.
1339+
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
13381340
:param use_richdem: Whether to use RichDEM to compute the attribute.
13391341
13401342
:raises ValueError: If the inputs are poorly formatted.
@@ -1380,7 +1382,7 @@ def planform_curvature(
13801382
Based on Zevenbergen and Thorne (1987), http://dx.doi.org/10.1002/esp.3290120107.
13811383
13821384
:param dem: The DEM to calculate the curvature from.
1383-
:param resolution: The X/Y resolution of the DEM.
1385+
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
13841386
:param use_richdem: Whether to use RichDEM to compute the attribute.
13851387
13861388
:raises ValueError: If the inputs are poorly formatted.
@@ -1433,7 +1435,7 @@ def profile_curvature(
14331435
Based on Zevenbergen and Thorne (1987), http://dx.doi.org/10.1002/esp.3290120107.
14341436
14351437
:param dem: The DEM to calculate the curvature from.
1436-
:param resolution: The X/Y resolution of the DEM.
1438+
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
14371439
:param use_richdem: Whether to use RichDEM to compute the attribute.
14381440
14391441
:raises ValueError: If the inputs are poorly formatted.
@@ -1485,7 +1487,7 @@ def maximum_curvature(
14851487
Based on Zevenbergen and Thorne (1987), http://dx.doi.org/10.1002/esp.3290120107.
14861488
14871489
:param dem: The DEM to calculate the curvature from.
1488-
:param resolution: The X/Y resolution of the DEM.
1490+
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
14891491
:param use_richdem: Whether to use RichDEM to compute the attribute.
14901492
14911493
:raises ValueError: If the inputs are poorly formatted.
@@ -1648,7 +1650,7 @@ def rugosity(
16481650
Based on: Jenness (2004), https://doi.org/10.2193/0091-7648(2004)032[0829:CLSAFD]2.0.CO;2.
16491651
16501652
:param dem: The DEM to calculate the rugosity from.
1651-
:param resolution: The X/Y resolution of the DEM.
1653+
:param resolution: The X/Y resolution of the DEM, only if passed as an array.
16521654
16531655
:raises ValueError: If the inputs are poorly formatted.
16541656

0 commit comments

Comments
 (0)