From 0747743e276953891635d7ae6b1590ea1ca3e667 Mon Sep 17 00:00:00 2001 From: Teschl <69400012+Teschl@users.noreply.github.com> Date: Tue, 21 Jan 2025 16:35:08 +0100 Subject: [PATCH 1/3] Add aspect --- src/topotoolbox/grid_object.py | 47 +++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/src/topotoolbox/grid_object.py b/src/topotoolbox/grid_object.py index 84743ca..898eefa 100755 --- a/src/topotoolbox/grid_object.py +++ b/src/topotoolbox/grid_object.py @@ -12,7 +12,8 @@ generic_filter, grey_erosion, grey_dilation, - distance_transform_edt) + distance_transform_edt, + sobel) from scipy.signal import wiener from rasterio import CRS from rasterio.warp import reproject @@ -74,7 +75,8 @@ def dims(self): if self.z.flags.f_contiguous: return (self.rows, self.columns) - raise TypeError("Grid is not stored as a contiguous row- or column-major array") + raise TypeError( + "Grid is not stored as a contiguous row- or column-major array") def reproject(self, crs: 'CRS', @@ -703,6 +705,44 @@ def evansslope( result.z = slope return result + def aspect(self, classify: bool = False) -> 'GridObject': + """Aspect returns the slope exposition of each cell in a digital + elevation model in degrees. In contrast to the second output of + gradient8 which returns the steepest slope direction, aspect + returns the angle of the slope. + + Parameters + ---------- + classify : bool, optional + directions are classified according to the scheme proposed by + Gomez-Plaza et al. (2001), by default False + + Returns + ------- + GridObject + A GridObject containing the computed aspect data. + """ + + # [Nx,Ny] = surfnorm(Z); + # ASP = cart2pol(Nx,Ny); + # ASP = mod(90+ASP/pi*180,360); + grad_y, grad_x = np.gradient(self.z) + aspect = np.arctan2(-grad_x, grad_y) + aspect = np.degrees(aspect) + aspect = np.mod(aspect, 360) + + if classify: + aspclass = np.array([1, 3, 5, 7, 8, 6, 4, 2]) + aspedges = aspect // 45 + 1 + aspedges = aspedges.astype(np.int8) + + aspect[aspedges > 0] = aspclass[aspedges[aspedges > 0]-1] + aspect = aspect.astype(np.int8) + + result = copy.copy(self) + result.z = aspect + return result + def _gwdt_computecosts(self) -> np.ndarray: """ Compute the cost array used in the gradient-weighted distance @@ -837,12 +877,11 @@ def shufflelabel(self): result = copy.copy(self) labels = self.z - u,indices = np.unique(labels,return_inverse=True) + u, indices = np.unique(labels, return_inverse=True) result.z = np.random.permutation(u)[indices] return result - # 'Magic' functions: # ------------------------------------------------------------------------ From c3d61c96b6b7fb620734f30746ddb1fb5b827c00 Mon Sep 17 00:00:00 2001 From: Teschl <69400012+Teschl@users.noreply.github.com> Date: Tue, 21 Jan 2025 16:35:35 +0100 Subject: [PATCH 2/3] Remove Matlab references --- src/topotoolbox/grid_object.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/topotoolbox/grid_object.py b/src/topotoolbox/grid_object.py index 898eefa..e1b57ce 100755 --- a/src/topotoolbox/grid_object.py +++ b/src/topotoolbox/grid_object.py @@ -723,9 +723,6 @@ def aspect(self, classify: bool = False) -> 'GridObject': A GridObject containing the computed aspect data. """ - # [Nx,Ny] = surfnorm(Z); - # ASP = cart2pol(Nx,Ny); - # ASP = mod(90+ASP/pi*180,360); grad_y, grad_x = np.gradient(self.z) aspect = np.arctan2(-grad_x, grad_y) aspect = np.degrees(aspect) From 1e10c5a444807bb2e2b0f3e70afde63734e5aefc Mon Sep 17 00:00:00 2001 From: Teschl <69400012+Teschl@users.noreply.github.com> Date: Wed, 22 Jan 2025 14:49:54 +0100 Subject: [PATCH 3/3] Modify edge_order --- src/topotoolbox/grid_object.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/topotoolbox/grid_object.py b/src/topotoolbox/grid_object.py index e1b57ce..f53bd9d 100755 --- a/src/topotoolbox/grid_object.py +++ b/src/topotoolbox/grid_object.py @@ -12,8 +12,8 @@ generic_filter, grey_erosion, grey_dilation, - distance_transform_edt, - sobel) + distance_transform_edt +) from scipy.signal import wiener from rasterio import CRS from rasterio.warp import reproject @@ -723,17 +723,17 @@ def aspect(self, classify: bool = False) -> 'GridObject': A GridObject containing the computed aspect data. """ - grad_y, grad_x = np.gradient(self.z) - aspect = np.arctan2(-grad_x, grad_y) + grad_y, grad_x = np.gradient(self.z, edge_order=2) + aspect: np.ndarray = np.arctan2(-grad_x, grad_y) aspect = np.degrees(aspect) aspect = np.mod(aspect, 360) if classify: aspclass = np.array([1, 3, 5, 7, 8, 6, 4, 2]) - aspedges = aspect // 45 + 1 + aspedges = aspect // 45 aspedges = aspedges.astype(np.int8) - aspect[aspedges > 0] = aspclass[aspedges[aspedges > 0]-1] + aspect = aspclass[aspedges] aspect = aspect.astype(np.int8) result = copy.copy(self)