In addition to a river's centerline and width, we can also extract information about the banks of the river, such as their aspect and total length. To identify the banks, we simply dilate the channel mask and compare it to the original channel mask. These images' differences represent the land pixels adjacent to the channel mask.
var bankMask = channelmask.focal_max(1).neq(channelmask);
Next, we will calculate the aspect, or compass direction, of the bank faces. We use the
Image.cumulativeCost method with the entire river channel as our source to create a new image
(bankDistance) with increasing values away from the river channel, similar to an elevation map of
river banks. In this image, the banks will 'slope' towards the river channel and we can take advantage of the
terrain methods in EE. We will call the Terrain.aspect method on the bank distance and select the
bank pixels by applying the bank mask. In the end, our bank aspect data will give us the direction from each bank
pixel towards the center of the channel. These data could be useful for interpreting any directional preferences
in erosion as a result of geological features or thawed permafrost soils from solar radiation.
var bankDistance = channelmask.not().cumulativeCost({
source: channelmask,
maxDistance: 1E2,
geodeticDistance: false
});
var bankAspect = ee.Terrain.aspect(bankDistance)
.multiply(Math.PI).divide(180)
.mask(bankMask).rename('bankAspect');
Last, we calculate the length represented by each bank pixel by convolving the bank mask with a Euclidean distance kernel. Sections of bank oriented along the pixel edges will have a value of 30 m per pixel, whereas a diagonal section will have a value of 2 * 30 m per pixel.
var distanceKernel = ee.Kernel.euclidean({
radius: 30,
units: 'meters',
magnitude: 0.5
});
var bankLength = bankMask.convolve(distanceKernel)
.mask(bankMask).rename('bankLength');
var radianVis = {
min: 0,
max: 2 * Math.PI,
palette: ['red', 'yellow', 'green', 'teal', 'blue', 'magenta', 'red']
};
Map.addLayer(rpj(bankAspect), radianVis, 'bank aspect', false);
Map.addLayer(rpj(bankLength), {
min: 0,
max: 60
}, 'bank length', false);