Package 'landform'

Title: Topographic Position Index-Based Landform Classification
Description: Classifies a landscape into slope-position and landform classes on the basis of the Topographic Position Index (TPI) and slope, following Weiss (2001) and Jenness (2006). Two classifications are offered: a six-class Slope Position Classification, based on one TPI scale, and a ten-class Landform Classification, based on a small and a large TPI scale. The TPI can be computed over square, circular or annular neighbourhoods, sized in cells or in map units, and standardised either over the whole grid (as in the original method) or locally. Results are returned as an object holding the classified raster, the TPI and slope surfaces, and per-class descriptive statistics, with methods for printing, summarising and plotting.
Authors: Gianmarco Alberti [aut, cre]
Maintainer: Gianmarco Alberti <[email protected]>
License: GPL (>= 2)
Version: 0.3.0
Built: 2026-10-22 13:26:25 UTC
Source: https://github.com/gianmarcoalberti/landform

Help Index


One layer per class

Description

Splits the classified raster of a "landform" object into one presence/absence layer per class, named after the classes. This replaces the list of per-class rasters returned by landform <= 0.2.

Usage

class_layers(x, absent = 0)

Arguments

x

An object of class "landform".

absent

Value given to cells not belonging to the class: 0 (default) or NA.

Value

A multi-layer SpatRaster with one layer for each class present in the classification (1 = cell belongs to the class); cells left unclassified are NA in every layer.

Examples

dem <- malta_dtm()
sp <- landform(dem, scale = 9, plot = FALSE)
layers <- class_layers(sp)
names(layers)
terra::plot(layers[["Ridge"]], main = "Ridge")

Landform Classification

Description

Classifies a landscape into slope-position or landform classes on the basis of the Topographic Position Index (TPI; see tpi) and slope, following Weiss (2001) and Jenness (2006). Two classifications are available: the six-class Slope Position Classification, based on one TPI scale, and the ten-class Landform Classification, based on a small and a large TPI scale.

Usage

landform(
  x,
  scale = 3,
  sn = 3,
  ln = 7,
  class.type = c("slope.position", "landform.classification"),
  descriptive = FALSE,
  leg.pos = NULL,
  leg.cex = 0.8,
  units = c("cells", "map"),
  shape = c("square", "circle", "annulus"),
  inner = NULL,
  centre = FALSE,
  std = c("global", "local"),
  tpi.thr = c(0.5, 1),
  lf.thr = 1,
  slope.thr = 5,
  plot = TRUE,
  shade = c("none", "slope", "hill"),
  col = NULL
)

Arguments

x

A single-layer SpatRaster (or a RasterLayer, which is converted internally) representing elevation. A projected coordinate system with the same horizontal and vertical units (e.g. metres) is recommended, since slope (and hence the slope threshold) depends on it.

scale

Neighbourhood size for the Slope Position Classification. With units = "cells" (default), the width of the moving window in cells (odd integer >= 3); with units = "map", the radius (half-width for square windows) in map units (metres for longitude/latitude rasters). Default 3.

sn, ln

Small and large neighbourhood sizes for the Landform Classification, in the same units as scale. Defaults 3 and 7; ln must be larger than sn.

class.type

Either "slope.position" (default) or "landform.classification".

descriptive

Logical. If TRUE, a bar plot of the area of each class is drawn in addition to the map (default FALSE). The descriptive statistics are always computed and stored in the returned object (see Value).

leg.pos

Position of the legend of the map, as a keyword accepted by legend (e.g. "topright"). The default, NULL, places the legend outside the map, to its right, so that no data are hidden.

leg.cex

Magnification of the legend text. Default 0.8.

units

Either "cells" (default) or "map"; see scale.

shape

Neighbourhood shape: "square" (default), "circle", or "annulus". See tpi.

inner

Inner radius (or radii) of the annulus, in the same units as scale: one value for the Slope Position Classification, two values (for sn and ln) for the Landform Classification. Ignored unless shape = "annulus".

centre

Logical. Include the focal cell in the neighbourhood mean? Default FALSE. See tpi.

std

TPI standardisation: "global" (default; Weiss 2001, Jenness 2006) or "local" (as in landform <= 0.2). See tpi for the difference, which can be substantial.

tpi.thr

Two increasing positive thresholds (in standard deviation units) used by the Slope Position Classification. Default c(0.5, 1) (Weiss 2001).

lf.thr

Threshold (in standard deviation units) separating low, mid and high TPI in the Landform Classification. Default 1 (Weiss 2001).

slope.thr

Slope threshold, in degrees, separating flat from sloping terrain. Default 5 (Weiss 2001).

plot

Logical. Draw the map of the classes? Default TRUE.

shade

Relief shading drawn underneath the classes: "none" (default), "slope" (slopeshade) or "hill" (hillshade). See plot.landform.

col

Optional vector of colours, one per class. By default the Slope Position Classification uses an ordinal blue-to-brown palette (valley to ridge) that remains readable with the common forms of colour blindness; the Landform Classification groups hues by landform family (drainages and valleys in blues, plains and slopes in yellows and greens, ridges and tops in oranges, reds and purple). With ten classes no palette is fully colour-blind safe; supply your own if needed.

Details

Slope Position Classification (Weiss 2001). With zz the standardised TPI, t1<t2t_1 < t_2 the values of tpi.thr, and ss the slope in degrees:

1 Valley z≤−t2z \le -t_2
2 Lower Slope −t2<z≤−t1-t_2 < z \le -t_1
3 Flat Slope −t1<z<t1-t_1 < z < t_1 and s≤s \le slope.thr
4 Middle Slope −t1<z<t1-t_1 < z < t_1 and s>s > slope.thr
5 Upper Slope t1≤z≤t2t_1 \le z \le t_2
6 Ridge z>t2z > t_2

Landform Classification (Weiss 2001; Jenness 2006). With SNSN and LNLN the standardised TPI at the small and large scales, and tt the value of lf.thr:

1 Canyons, Deeply Incised Streams SN≤−tSN \le -t, LN≤−tLN \le -t
2 Midslope Drainages, Shallow Valleys SN≤−tSN \le -t, −t<LN<t-t < LN < t
3 Upland Drainages, Headwaters SN≤−tSN \le -t, LN≥tLN \ge t
4 U-shaped Valleys −t<SN<t-t < SN < t, LN≤−tLN \le -t
5 Plains −t<SN<t-t < SN < t, −t<LN<t-t < LN < t, s≤s \le slope.thr
6 Open Slopes −t<SN<t-t < SN < t, −t<LN<t-t < LN < t, s>s > slope.thr
7 Upper Slopes, Mesas −t<SN<t-t < SN < t, LN≥tLN \ge t
8 Local Ridges, Hills in Valleys SN≥tSN \ge t, LN≤−tLN \le -t
9 Midslope Ridges, Small Hills in Plains SN≥tSN \ge t, −t<LN<t-t < LN < t
10 Mountain Tops, High Ridges SN≥tSN \ge t, LN≥tLN \ge t

Both sets of rules assign every cell to exactly one class.

Edges and NA cells. Slope cannot be computed for the outermost cells of the raster and for cells adjacent to NA cells; these cells are left unclassified (NA) for every class, so that the class frequencies are not biased by edge effects.

Area. Class areas are computed with cellSize, and are therefore correct also for longitude/latitude rasters; for projected rasters they are ground areas, which may differ slightly from the nominal cell area (resolution squared) because of the scale distortion of the projection. If the raster has no coordinate reference system, map units are assumed to be metres.

Reproducing results of landform <= 0.2. Use std = "local", centre = TRUE (with the default square window in cells). Cells whose standardised TPI equalled exactly t1t_1 were left unclassified by earlier versions and are now classified as Upper Slope; edge cells are now consistently NA.

Value

An object of class "landform": a list with elements

classes

a categorical SpatRaster of the classes (integer codes with class names as levels and a colour table); per-class layers can be obtained with class_layers;

tpi

a SpatRaster with the raw (elevation units) and standardised TPI layers used in the classification;

slope

a SpatRaster of slope (degrees);

stats

a data frame with, for every class, the number of cells, the area (km2^2), the percentage of the classified area, and the mean elevation and slope;

dem

the input elevation raster;

params

a list of the settings used.

The object has print, summary and plot methods (see plot.landform). The map (and, with descriptive = TRUE, the bar plot of class areas) is drawn as a side effect when plot = TRUE; the object is returned invisibly in that case.

References

Jenness, J. (2006). Topographic Position Index (tpi_jen.avx) extension for ArcView 3.x, v. 1.2. Jenness Enterprises.

Weiss, A. (2001). Topographic Position and Landforms Analysis. Poster presentation, ESRI User Conference, San Diego, CA.

See tpi for references on the TPI and its standardisation.

See Also

tpi, plot.landform, class_layers, malta_dtm, terrain

Examples

dem <- malta_dtm()

# Slope Position Classification, 9 x 9 cell window
sp <- landform(dem, scale = 9)
sp
summary(sp)

# Landform Classification, circular neighbourhoods of 120 m and 480 m
lf <- landform(dem, class.type = "landform.classification",
               sn = 120, ln = 480, units = "map", shape = "circle")


# the standardisation used by landform <= 0.2, for comparison
sp_local <- landform(dem, scale = 9, std = "local", centre = TRUE)


# the same, over a slopeshade, with the bar plot of class areas
plot(lf, shade = "slope")
plot(lf, what = "area")

# one layer per class
layers <- class_layers(lf)

Sample digital terrain model of Malta

Description

Returns a digital terrain model (DTM) of the island of Malta (Maltese archipelago), bundled with the package as a GeoTIFF file and read on demand. The sea is coded as NA, which makes the dataset suitable for showing how landform handles irregular study areas.

Usage

malta_dtm()

Format

A single-layer SpatRaster: 535 rows by 580 columns, 40 m resolution, elevation in metres, coordinate reference system ED50 / UTM zone 33N (EPSG:23033).

Value

A SpatRaster.

Source

The same DTM is distributed with the movecost package by the same author (movecost::mc_malta_dtm()).

Examples

dem <- malta_dtm()
terra::plot(dem, main = "Malta DTM (m)")

Plot a landform classification

Description

Plots the map of the classes, a bar plot of the area of each class, or the standardised TPI surface(s), from an object returned by landform.

Usage

## S3 method for class 'landform'
plot(
  x,
  what = c("classes", "area", "tpi"),
  shade = c("none", "slope", "hill"),
  alpha = 0.6,
  leg.pos = NULL,
  leg.cex = 0.8,
  main = NULL,
  ...
)

Arguments

x

An object of class "landform".

what

What to plot: "classes" (default), "area", or "tpi".

shade

Relief shading drawn underneath the classes or the TPI: "none" (default), "slope" (a slopeshade, that is the slope in grey levels from white for flat terrain to black for the steepest slopes), or "hill" (a hillshade, lit from the north-west at 45 degrees). See Details.

alpha

Opacity (0 to 1) of the classes or TPI drawn over the shading. Default 0.6. Ignored when shade = "none".

leg.pos

Legend position for the map (a legend keyword); NULL (default) places it outside the map, to its right.

leg.cex

Magnification of the legend text. Default 0.8.

main

Plot title; a sensible default is used if NULL.

...

Further arguments passed to plot (for maps) or barplot (for what = "area").

Details

A slopeshade conveys relief without the directional bias of a hillshade: features facing away from the light are not darkened, and steepness is shown in the same way whatever the aspect. The grey scale is stretched between 0 degrees and the 99th percentile of slope, so that a few very steep cells do not flatten the contrast elsewhere.

Value

x, invisibly.

Examples

dem <- malta_dtm()
sp <- landform(dem, scale = 9, plot = FALSE)
plot(sp)
plot(sp, shade = "slope")
plot(sp, what = "area")
plot(sp, what = "tpi", shade = "slope", alpha = 0.5)

Topographic Position Index

Description

Calculates the Topographic Position Index (TPI), that is the difference between the elevation of each cell and the mean elevation of its neighbourhood (Guisan et al. 1999; Weiss 2001), optionally standardised. This is the quantity on which landform bases its classifications; it is exported so that the TPI surfaces can be inspected, mapped, or used in other analyses.

Usage

tpi(
  x,
  scale = 3,
  units = c("cells", "map"),
  shape = c("square", "circle", "annulus"),
  inner = NULL,
  centre = FALSE,
  std = c("global", "local", "none")
)

Arguments

x

A single-layer SpatRaster (or a RasterLayer, which is converted internally) representing elevation.

scale

Size of the neighbourhood. If units = "cells" (default), the width of the moving window in cells (an odd integer >= 3; e.g. 3 gives a 3 x 3 window). If units = "map", the radius of the neighbourhood (or the half-width of the window, for shape = "square") in map units; for longitude/latitude rasters, map units are metres.

units

Either "cells" (default) or "map"; see scale.

shape

Shape of the neighbourhood: "square" (default), "circle", or "annulus" (a ring; requires inner).

inner

Inner radius of the annulus, in the same units as scale (for units = "cells", a radius in cells). Ignored unless shape = "annulus".

centre

Logical. Should the focal cell be included when computing the neighbourhood mean (and standard deviation)? Default FALSE, in line with the definition of TPI as the difference between a cell and its surroundings. See Details.

std

Standardisation: "global" (default), "local", or "none". See Details.

Details

Standardisation. With std = "global" the TPI is converted to z-scores using the mean and standard deviation of the TPI over the whole raster, so that values express the number of standard deviations from the grid mean. This is the standardisation used by Weiss (2001) and in Jenness's TPI extension (Jenness 2006), to which the classification thresholds in landform refer.
With std = "local" the TPI of each cell is divided by the standard deviation of elevation within its own neighbourhood. This is the "deviation from mean elevation" (DEV) of Wilson and Gallant (2000), which De Reu et al. (2013) found preferable in landscapes whose relief varies strongly from place to place. Be aware that, in nearly flat areas, the local standard deviation is very small, so that minimal elevation noise is magnified into large standardised values; on perfectly flat areas the local standardisation is undefined (NA). This was the (only) standardisation used by landform up to version 0.2.
With std = "none" the raw TPI (in elevation units) is returned.

Focal cell. With std = "global", including or excluding the focal cell rescales every TPI value by the same constant (n-1)/n, which cancels out in the z-scores; the choice therefore only affects cells close to the raster edges or to NA cells, where the neighbourhood is incomplete. It matters with std = "local" and std = "none".

Edges. Cells beyond the raster boundary, and NA cells, are ignored when averaging; TPI near edges is therefore computed from an incomplete neighbourhood.

Map units for longitude/latitude rasters. Cell sizes in metres are approximated at the latitude of the centre of the raster; over large latitudinal extents the neighbourhood is therefore only approximately constant in ground size.

Value

A single-layer SpatRaster with the (standardised) TPI.

References

De Reu, J., Bourgeois, J., Bats, M., Zwertvaegher, A., Gelorini, V., De Smedt, P., Chu, W., Antrop, M., De Maeyer, P., Finke, P., Van Meirvenne, M., Verniers, J. and Crombé, P. (2013). Application of the topographic position index to heterogeneous landscapes. Geomorphology, 186, 39-49.

Guisan, A., Weiss, S. B. and Weiss, A. D. (1999). GLM versus CCA spatial modeling of plant species distribution. Plant Ecology, 143, 107-122.

Jenness, J. (2006). Topographic Position Index (tpi_jen.avx) extension for ArcView 3.x, v. 1.2. Jenness Enterprises.

Weiss, A. (2001). Topographic Position and Landforms Analysis. Poster presentation, ESRI User Conference, San Diego, CA.

Wilson, J. P. and Gallant, J. C. (eds) (2000). Terrain Analysis: Principles and Applications. Wiley, New York.

See Also

landform, focal

Examples

dem <- malta_dtm()

# standardised TPI, 9 x 9 cell window (360 m at 40 m resolution)
t9 <- tpi(dem, scale = 9)
terra::plot(t9, main = "Standardised TPI (9 x 9 cells)")

# raw TPI over a 500 m circular neighbourhood
t500 <- tpi(dem, scale = 500, units = "map", shape = "circle", std = "none")
terra::plot(t500, main = "TPI (m), 500 m radius")