Aspect identifies the downslope direction of the maximum rate of change in value from each cell to its neighbors. Aspect can be thought of as the slope direction. The values of the output raster will be the compass direction of the aspect. A moving window visits each cell in the input raster and for each cell in the center of the window, an aspect value is calculated using an algorithm that incorporates the values of the cell's eight neighbors. If any neighborhood cells are NoData, they are first assigned the value of the center cell, then the aspect is computed. The cells are identified as letters 'a' to 'i', with 'e' representing the cell for which the aspect is being calculated. The rate of change in the x direction for cell 'e' is calculated with the following algorithm:
[dz/dx] = ((c + 2f + i) - (a + 2d + g)) / 8
The rate of change in the y direction for cell 'e' is calculated with the following algorithm:
[dz/dy] = ((g + 2h + i) - (a + 2b + c)) / 8
Taking the rate of change in both the x and y direction for cell 'e', aspect is calculated using:
aspect = 57.29578 * atan2 ([dz/dy], -[dz/dx])
The aspect value is then converted to compass direction values (0–2pi rad), according to the following rule:
if aspect < 0
cell = pi/2 - aspect
else if aspect > pi/2
cell = 2pi - aspect + pi/2
else
cell = pi/2 - aspect
Flat areas in the input raster—areas where the slope is zero are assigned an aspect of -1.
Reference:
Burrough, P. A. and McDonell, R.A., 1998. Principles of Geographical Information Systems (Oxford University Press, New York), p. 190
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(grid_real), | intent(in) | :: | dem | |||
type(grid_real), | intent(out) | :: | aspect |
Type | Visibility | Attributes | Name | Initial | |||
---|---|---|---|---|---|---|---|
real(kind=float), | public | :: | a |
elevation of N-W cell |
|||
real(kind=float), | public | :: | aspectIJ | ||||
real(kind=float), | public | :: | b |
elevation of N cell |
|||
real(kind=float), | public | :: | c |
elevation of N-E cell |
|||
real(kind=float), | public | :: | d |
elevation of W cell |
|||
real(kind=float), | public | :: | dZdX |
rate of change in the x direction |
|||
real(kind=float), | public | :: | dZdY |
rate of change in the y direction |
|||
real(kind=float), | public | :: | f |
elevation of E cell |
|||
real(kind=float), | public | :: | g |
elevation of S-W cell |
|||
real(kind=float), | public | :: | h |
elevation of S cell |
|||
real(kind=float), | public | :: | i |
elevation of S-E cell |
|||
integer, | public | :: | ii | ||||
integer, | public | :: | jj |
SUBROUTINE DeriveAspect & ! (dem, aspect) IMPLICIT NONE !arguments with intent in TYPE(grid_real), INTENT(in):: dem !arguments with intent out TYPE (grid_real), INTENT (out) :: aspect !(rad) !local variables INTEGER :: ii,jj REAL (KIND = float) :: dZdX !!rate of change in the x direction REAL (KIND = float) :: dZdY !!rate of change in the y direction REAL (KIND = float) :: aspectIJ REAL (KIND = float) :: a !!elevation of N-W cell REAL (KIND = float) :: b !!elevation of N cell REAL (KIND = float) :: c !!elevation of N-E cell REAL (KIND = float) :: d !!elevation of W cell REAL (KIND = float) :: f !!elevation of E cell REAL (KIND = float) :: g !!elevation of S-W cell REAL (KIND = float) :: h !!elevation of S cell REAL (KIND = float) :: i !!elevation of S-E cell !------------------------------end of declaration ----------------------------- !allocate aspect grid CALL NewGrid (aspect,dem) !loop through dem grid idim: DO ii = 1, dem % idim jdim: DO jj = 1, dem % jdim IF (dem % mat(ii,jj) /= dem % nodata) THEN !north-west cell IF ( .NOT. IsOutOfGrid (ii-1,jj-1,dem) ) THEN IF ( dem % mat (ii-1,jj-1) /= dem % nodata) THEN a = dem % mat (ii-1,jj-1) ELSE a = dem % mat (ii,jj) END IF ELSE a = dem % mat (ii,jj) END IF !north cell IF ( .NOT. IsOutOfGrid (ii-1,jj,dem) ) THEN IF ( dem % mat (ii-1,jj) /= dem % nodata) THEN b = dem % mat (ii-1,jj) ELSE b = dem % mat (ii,jj) END IF ELSE b = dem % mat (ii,jj) END IF !north-east cell IF ( .NOT. IsOutOfGrid (ii-1,jj+1,dem) ) THEN IF ( dem % mat (ii-1,jj+1) /= dem % nodata) THEN c = dem % mat (ii-1,jj+1) ELSE c = dem % mat (ii,jj) END IF ELSE c = dem % mat (ii,jj) END IF !west cell IF ( .NOT. IsOutOfGrid (ii,jj-1,dem) ) THEN IF ( dem % mat (ii,jj-1) /= dem % nodata) THEN d = dem % mat (ii,jj-1) ELSE d = dem % mat (ii,jj) END IF ELSE d = dem % mat (ii,jj) END IF !east cell IF ( .NOT. IsOutOfGrid (ii,jj+1,dem) ) THEN IF ( dem % mat (ii,jj+1) /= dem % nodata) THEN f = dem % mat (ii,jj+1) ELSE f = dem % mat (ii,jj) END IF ELSE f = dem % mat (ii,jj) END IF !south-west cell IF ( .NOT. IsOutOfGrid (ii+1,jj-1,dem) ) THEN IF ( dem % mat (ii+1,jj-1) /= dem % nodata) THEN g = dem % mat (ii+1,jj-1) ELSE g = dem % mat (ii,jj) END IF ELSE g = dem % mat (ii,jj) END IF !south cell IF ( .NOT. IsOutOfGrid (ii+1,jj,dem) ) THEN IF ( dem % mat (ii+1,jj) /= dem % nodata) THEN h = dem % mat (ii+1,jj) ELSE h = dem % mat (ii,jj) END IF ELSE h = dem % mat (ii,jj) END IF !south-east cell IF ( .NOT. IsOutOfGrid (ii+1,jj+1,dem) ) THEN IF ( dem % mat (ii+1,jj+1) /= dem % nodata) THEN i = dem % mat (ii+1,jj+1) ELSE i = dem % mat (ii,jj) END IF ELSE i = dem % mat (ii,jj) END IF !compute the rate of change in the x direction dZdX = ((c + 2.*f + i) - (a + 2.*d + g)) / 8. !compute the rate of change in the y direction dZdY = ((g + 2.*h + i) - (a + 2.*b + c)) / 8. !compute aspect IF (dZdX == 0. .AND. dZdY == 0.) THEN aspect % mat (ii,jj) = -1. CYCLE ELSE aspectIJ = ATAN2 (dZdY, -dZdX) END IF !convert aspect value to compass direction values (0–2Pi radians) IF (aspectIJ < 0) THEN aspect % mat (ii,jj) = pi/2. - aspectIJ ELSE IF (aspectIJ > pi /2.) THEN aspect % mat (ii,jj) = 2.*pi - aspectIJ + pi/2. ELSE aspect % mat (ii,jj) = pi/2. - aspectIJ END IF END IF END DO jdim END DO idim RETURN END SUBROUTINE DeriveAspect