| Title: | Topographic Position Index-Based Landform Classification |
| Version: | 0.3.0 |
| 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. |
| Depends: | R (≥ 4.1.0) |
| Imports: | graphics, grDevices, stats, terra (≥ 1.7-3) |
| Suggests: | knitr, rmarkdown, testthat (≥ 3.0.0) |
| VignetteBuilder: | knitr |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| URL: | https://gianmarcoalberti.github.io/landform/, https://github.com/gianmarcoalberti/landform |
| BugReports: | https://github.com/gianmarcoalberti/landform/issues |
| Encoding: | UTF-8 |
| Config/testthat/edition: | 3 |
| Config/roxygen2/version: | 8.0.0 |
| NeedsCompilation: | no |
| Packaged: | 2026-10-22 07:24:49 UTC; gianmarcoalberti |
| Author: | Gianmarco Alberti [aut, cre] |
| Maintainer: | Gianmarco Alberti <gianmarcoalberti@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-10-22 12:50:02 UTC |
landform: Topographic Position Index-Based Landform Classification
Description
Classifies a landscape into slope-position or landform classes on the basis of the Topographic Position Index (TPI) and slope (Weiss 2001; Jenness 2006).
Details
Main functions:
-
landform: Slope Position and Landform classifications, returned as an object withprint,summaryandplotmethods; -
tpi: the TPI surface itself, raw or standardised; -
class_layers: one presence/absence layer per class; -
malta_dtm: a sample digital terrain model.
Author(s)
Maintainer: Gianmarco Alberti gianmarcoalberti@gmail.com
Authors:
Gianmarco Alberti gianmarcoalberti@gmail.com
See Also
Useful links:
Report bugs at https://github.com/gianmarcoalberti/landform/issues
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 |
absent |
Value given to cells not belonging to the class: |
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 |
scale |
Neighbourhood size for the Slope Position Classification. With
|
sn, ln |
Small and large neighbourhood sizes for the Landform
Classification, in the same units as |
class.type |
Either |
descriptive |
Logical. If |
leg.pos |
Position of the legend of the map, as a keyword accepted by
|
leg.cex |
Magnification of the legend text. Default |
units |
Either |
shape |
Neighbourhood shape: |
inner |
Inner radius (or radii) of the annulus, in the same units as
|
centre |
Logical. Include the focal cell in the neighbourhood mean?
Default |
std |
TPI standardisation: |
tpi.thr |
Two increasing positive thresholds (in standard deviation
units) used by the Slope Position Classification. Default
|
lf.thr |
Threshold (in standard deviation units) separating low, mid
and high TPI in the Landform Classification. Default |
slope.thr |
Slope threshold, in degrees, separating flat from sloping
terrain. Default |
plot |
Logical. Draw the map of the classes? Default |
shade |
Relief shading drawn underneath the classes: |
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 z the
standardised TPI, t_1 < t_2 the values of tpi.thr, and
s the slope in degrees:
| 1 Valley | z \le -t_2 |
| 2 Lower Slope | -t_2 < z \le -t_1 |
| 3 Flat Slope | -t_1 < z < t_1 and s \le slope.thr |
| 4 Middle Slope | -t_1 < z < t_1 and s > slope.thr |
| 5 Upper Slope | t_1 \le z \le t_2 |
| 6 Ridge | z > t_2
|
Landform Classification (Weiss 2001; Jenness 2006). With
SN and LN the standardised TPI at the small and large scales,
and t the value of lf.thr:
| 1 Canyons, Deeply Incised Streams | SN \le -t, LN \le -t |
| 2 Midslope Drainages, Shallow Valleys | SN \le -t, -t < LN < t |
| 3 Upland Drainages, Headwaters | SN \le -t, LN \ge t |
| 4 U-shaped Valleys | -t < SN < t, LN \le -t |
| 5 Plains | -t < SN < t, -t < LN < t, s \le slope.thr |
| 6 Open Slopes | -t < SN < t, -t < LN < t, s > slope.thr |
| 7 Upper Slopes, Mesas | -t < SN < t, LN \ge t |
| 8 Local Ridges, Hills in Valleys | SN \ge t, LN \le -t |
| 9 Midslope Ridges, Small Hills in Plains | SN \ge t, -t < LN < t |
| 10 Mountain Tops, High Ridges | SN \ge t, LN \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 t_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
classesa categorical
SpatRasterof the classes (integer codes with class names as levels and a colour table); per-class layers can be obtained withclass_layers;tpia
SpatRasterwith the raw (elevation units) and standardised TPI layers used in the classification;slopea
SpatRasterof slope (degrees);statsa data frame with, for every class, the number of cells, the area (km
^2), the percentage of the classified area, and the mean elevation and slope;demthe input elevation raster;
paramsa 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 |
what |
What to plot: |
shade |
Relief shading drawn underneath the classes or the TPI:
|
alpha |
Opacity (0 to 1) of the classes or TPI drawn over the shading.
Default |
leg.pos |
Legend position for the map (a |
leg.cex |
Magnification of the legend text. Default |
main |
Plot title; a sensible default is used if |
... |
Further arguments passed to |
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 |
scale |
Size of the neighbourhood. If |
units |
Either |
shape |
Shape of the neighbourhood: |
inner |
Inner radius of the annulus, in the same units as |
centre |
Logical. Should the focal cell be included when computing the
neighbourhood mean (and standard deviation)? Default |
std |
Standardisation: |
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
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")