-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add terrain attributes (TRI, TPI, Roughness, Rugosity), add methods o…
…f slope, aspect, hillshade and test robustness against GDAL and richDEM (#227) * fix deramp residual and optimizer * add terrain references in function doc * add tpi, tri, roughness and tests * add maximum curvature * add rugosity draft * incremental commit * fix documentation * fix hillshade, refine tests comparing attributes to GDALDEM * Add slope methods from Horn (1981) and slope_method and tri_method arguments * fix spatial_tools package * Fix scipy.ndimage.morphology deprecation for binary dilation * Update doctest quadric coefficients * Fix quadratic test on finite values now that default edge method had changed * Add rugosity wrapper and references * Fix doctests * Add test skipping for coreg failures, issue opened * Remove test on finite values for terrain attributes because default fill_method and edge_method do not fill gaps anymore * Update value of patches method test with new NaNs of dataset diff * Fix minor sphinx errors * Fix tests after update of the diff example data * Catch DeprecationWarning to exclude them from fatal test errors * Fix quantile calculation for data with NaNs * Fix the zeroing of profile and planform curvature to avoid NaNs on flat surfaces, and re-add a test of finite values * Add warning for rugosity computation and window sizes * Add or refine documentation and gallery example for all terrain attributes * Move richDEM wrapper functions, move terrain ruggedness to maintain consistent order of roughness indexes, and fix minor docstrings issues * Capitalize TRI and TPI attributes * Correct error in profile curvature calculation, add docstring examples for all attributes * Add missing return to line in docstring test * Fix bug in rugosity calculation * Add test for rugosity calculation * Fix typo and clarify * Adapt colorbar * Fix and add rugosity tests * Move rugosity to quadratic_coefficient due to fixed window size and need of resolution, and fix doctests * Fix doctests * Add richDEM methods, tests based on richDEM against curvatures and slope/aspect, tests on errors raised, changed default edge and fill methods to None and adjusted doctests * Add richdem dev dependency for testing terrain attributes * Fix doctests signs and spacing * Fix doctest spacing issue * Try to fix RuntimeWarning on NaN addition * Add slope method example, add multiplot to terrain attribute example, modify thumbnails and link those examples to the documentation chapter * Add comment to describe regex escape in test to catch raised errors * Add fractal roughness, fix edge detection of get_windowed_indexes * Fix doctest * Add fractal roughness to documentation * Fix addresses of scrapped gallery images * Refine doc descriptions of individiual terrain attributes * Clarify attribute units in documentation chapter * Filter warning in aspect calculation and reenable test failure from warnings
- Loading branch information
Showing
15 changed files
with
1,644 additions
and
240 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
""" | ||
Slope and aspect methods | ||
======================== | ||
Terrain slope and aspect can be estimated using different methods. | ||
Here is an example of how to generate the two with each method, and understand their differences. | ||
For more information, see the :ref:`terrain_attributes` chapter and the | ||
:ref:`sphx_glr_auto_examples_plot_terrain_attributes.py` example. | ||
""" | ||
import matplotlib.pyplot as plt | ||
import numpy as np | ||
|
||
import xdem | ||
|
||
# %% | ||
# **Example data** | ||
|
||
dem = xdem.DEM(xdem.examples.get_path("longyearbyen_ref_dem")) | ||
|
||
|
||
def plot_attribute(attribute, cmap, label=None, vlim=None): | ||
plt.figure(figsize=(8, 5)) | ||
|
||
if vlim is not None: | ||
if isinstance(vlim, (int, float)): | ||
vlims = {"vmin": -vlim, "vmax": vlim} | ||
elif len(vlim) == 2: | ||
vlims = {"vmin": vlim[0], "vmax": vlim[1]} | ||
else: | ||
vlims = {} | ||
|
||
plt.imshow( | ||
attribute.squeeze(), | ||
cmap=cmap, | ||
extent=[dem.bounds.left, dem.bounds.right, dem.bounds.bottom, dem.bounds.top], | ||
**vlims | ||
) | ||
if label is not None: | ||
cbar = plt.colorbar() | ||
cbar.set_label(label) | ||
|
||
plt.xticks([]) | ||
plt.yticks([]) | ||
plt.tight_layout() | ||
|
||
plt.show() | ||
|
||
|
||
# %% | ||
# Slope with method of `Horn (1981) <http://dx.doi.org/10.1109/PROC.1981.11918>`_ (GDAL default), based on a refined | ||
# approximation of the gradient (page 18, bottom left, and pages 20-21). | ||
|
||
slope_horn = xdem.terrain.slope(dem.data, resolution=dem.res) | ||
|
||
plot_attribute(slope_horn, "Reds", "Slope of Horn (1981) (°)") | ||
|
||
# %% | ||
# Slope with method of `Zevenbergen and Thorne (1987) <http://dx.doi.org/10.1002/esp.3290120107>`_, Equation 13. | ||
|
||
slope_zevenberg = xdem.terrain.slope(dem.data, resolution=dem.res, method='ZevenbergThorne') | ||
|
||
plot_attribute(slope_zevenberg, "Reds", "Slope of Zevenberg and Thorne (1987) (°)") | ||
|
||
# %% | ||
# We compute the difference between the slopes computed with each method. | ||
|
||
diff_slope = slope_horn - slope_zevenberg | ||
|
||
plot_attribute(diff_slope, "RdYlBu", "Slope of Horn (1981) minus\n slope of Zevenberg and Thorne (1987) (°)", vlim=3) | ||
|
||
# %% | ||
# The differences are negative, implying that the method of Horn always provides flatter slopes. | ||
# Additionally, they seem to occur in places of high curvatures. We verify this by plotting the maximum curvature. | ||
|
||
maxc = xdem.terrain.maximum_curvature(dem.data, resolution=dem.res) | ||
|
||
plot_attribute(maxc, "RdYlBu", "Maximum curvature (100 m $^{-1}$)", vlim=2) | ||
|
||
# %% | ||
# We quantify the relationship by computing the median of slope differences in bins of curvatures, and plot the | ||
# result. We define custom bins for curvature, due to its skewed distribution. | ||
|
||
df_bin = xdem.spatialstats.nd_binning(values=diff_slope[:],list_var=[maxc[:]], list_var_names=["maxc"], | ||
list_var_bins=30, statistics=[np.nanmedian, "count"]) | ||
|
||
xdem.spatialstats.plot_1d_binning(df_bin, var_name="maxc", statistic_name="nanmedian", | ||
label_var="Maximum absolute curvature (100 m$^{-1}$)", | ||
label_statistic="Slope of Horn (1981) minus\n " | ||
"slope of Zevenberg and Thorne (1987) (°)") | ||
|
||
|
||
# %% | ||
# We perform the same exercise to analyze the differences in terrain aspect. We compute the difference modulo 360°, | ||
# to account for the circularity of aspect. | ||
|
||
aspect_horn = xdem.terrain.aspect(dem.data) | ||
aspect_zevenberg = xdem.terrain.aspect(dem.data, method='ZevenbergThorne') | ||
|
||
diff_aspect = aspect_horn - aspect_zevenberg | ||
diff_aspect_mod = np.minimum(np.mod(diff_aspect, 360), 360 - np.mod(diff_aspect, 360)) | ||
|
||
plot_attribute(diff_aspect_mod, "Spectral", "Aspect of Horn (1981) minus\n aspect of Zevenberg and Thorne (1987) (°)", | ||
vlim=[0, 90]) | ||
|
||
# %% | ||
# Same as for slope, differences in aspect seem to coincide with high curvature areas. We observe also observe large | ||
# differences for areas with nearly flat slopes, owing to the high sensitivity of orientation estimation | ||
# for flat terrain. | ||
|
||
# Note: the default aspect for a 0° slope is 180°, as in GDAL. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.