r.geomorphon(1)

okay bestie, welcome to the r.geomorphon(1) page from the GRASS GIS User's Manual 🌸 β€” it's a long one so we're doing this in parts, grab a snack πŸ“


✨ NAME ✨

r.geomorphon β€” she calculates geomorphons (aka terrain forms) plus all the associated geometry, using a machine vision approach πŸ’…


πŸ”‘ KEYWORDS πŸ”‘

raster, geomorphons, terrain patterns, machine vision geomorphometry


πŸŽ€ SYNOPSIS πŸŽ€

Like, here's the whole vibe in one block, no cap:

r.geomorphon
r.geomorphon --help
r.geomorphon [-me] elevation=name  [forms=name]   [ternary=name]
[positive=name]   [negative=name]   [intensity=name]   [exposition=name]
[range=name]   [variance=name]   [elongation=name]   [azimuth=name]
[extend=name]   [width=name]  search=integer skip=integer flat=float
dist=float  [comparison=string]   [coordinates=east,north]
[profiledata=name]   [profileformat=string]   [--overwrite]  [--help]
[--verbose]  [--quiet]  [--ui]

🌈 Flags

  • -m β€” use meters to define search units (the default is cells, bestie)
  • -e β€” use the extended form correction
  • --overwrite β€” let output files just overwrite existing files, periodt
  • --help β€” print the usage summary
  • --verbose β€” verbose module output, she's chatty
  • --quiet β€” quiet module output, she's mysterious
  • --ui β€” force launching the GUI dialog ✨

πŸ¦‹ Parameters

  • elevation=name [required] β€” name of the input elevation raster map. Required fr fr, you cannot skip her πŸ‘‘
  • forms=name β€” the most common geomorphic forms
  • ternary=name β€” code of ternary patterns
  • positive=name β€” code of binary positive patterns
  • negative=name β€” code of binary negative patterns
  • intensity=name β€” rasters containing mean relative elevation of the form
  • exposition=name β€” rasters containing the maximum difference between extend and central cell
  • range=name β€” rasters containing difference between max and min elevation of the form extend
  • variance=name β€” rasters containing variance of form boundary
  • elongation=name β€” rasters containing local elongation
  • azimuth=name β€” rasters containing local azimuth of the elongation
  • extend=name β€” rasters containing local extend (area) of the form
  • width=name β€” rasters containing local width of the form
  • search=integer [required] β€” outer search radius. Default: 3
  • skip=integer [required] β€” inner search radius. Default: 0
  • flat=float [required] β€” flatness threshold (in degrees). Default: 1
  • dist=float [required] β€” flatness distance, zero for none. Default: 0
  • comparison=string β€” comparison mode for the zenith/nadir line-of-sight search. Options: anglev1, anglev2, anglev2_distance. Default: anglev1
  • coordinates=east,north β€” coordinates to profile
  • profiledata=name β€” profile output file name ("-" for stdout)
  • profileformat=string β€” profile output format. Options: json, yaml, xml

πŸ’œ DESCRIPTION πŸ’œ

r.geomorphon calculates terrain forms using a machine-vision technique called geomorphons. Iconic behaviour honestly.

🌸 What is geomorphon:

Geomorphon is a whole new concept of presentation and analysis of terrain forms. The way that it works is it utilises an 8-tuple pattern of the visibility neighbourhood, and in doing so it breaks the well known limitation of the standard calculus approach, where all terrain forms cannot be detected in a single window size. That limitation? Gone. Not invited to the party πŸ™ˆ

The pattern arises from a comparison of a focus pixel with its eight neighbors, starting from the one located to the east and continuing counterclockwise, which produces a ternary operator. For example, a tuple {+,-,-,-,0,+,+,+} describes one possible pattern of relative measures {higher, lower, lower, lower, equal, higher, higher, higher} for the pixels surrounding the focus pixel.

It is important to stress (like, stress stress) that the visibility neighbors are not necessarily the immediate neighbors of the focus pixel in the grid β€” they're the pixels determined from the line-of-sight principle along the eight principal directions. This principle relates surface relief and horizontal distance by means of so-called zenith and nadir angles along the eight principal compass directions. The ternary operator converts the information contained in all the pairs of zenith and nadir angles into the ternary pattern (8-tuple) ✨

The result depends on the values of two parameters: the search radius (L) and the relief threshold (d). The search radius is the maximum allowable distance for calculation of zenith and nadir angles. The relief threshold is a minimum value of difference between LOSs angle (zenith and nadir) that is considered significantly different from the horizon. Two lines-of-sight are necessary, because zenith LOS only does not detect positive forms correctly. So like, both. Always both πŸ’…

There are 3**8 = 6561 possible ternary patterns (8-tuples). By removing all patterns that are the result of either rotation or reflection of other patterns, a set of 498 patterns remains, and those are referred to as geomorphons. This is a comprehensive and exhaustive set of idealized landforms that are independent of the size, relief, and orientation of the actual landform. Queen behaviour, truly πŸ‘‘

Form recognition depends on two free parameters: the search radius and the flatness threshold. Using larger values of L is tantamount to terrain classification from a higher and wider perspective, whereas using smaller values of L is tantamount to terrain classification from a local point of view. The character of the map depends on the value of L:

  • Using a small value of L gives you a map that correctly identifies landforms if their size is smaller than L; landforms having larger sizes get broken down into components 😭
  • Using larger values of L allows simultaneous identification of landforms on a variety of sizes, at the expense of recognizing smaller, second-order forms

There are two additional parameters: the skip radius, used to eliminate the impact of small irregularities. On the contrary, the flatness distance eliminates the impact of very high distance (in meters) of the search radius, which may not detect elevation difference if this is at a very far distance. Important especially with low resolution DEMs β€” like, so important 🫢


bestie that's the first half β€” the rest of the page is coming right up, don't go anywhere πŸ’–

✨ OPTIONS ✨

  • -m β€” okay so normally every distance you give me (that's search, skip, and flat distances) is measured in cells, but flip this flag and bestie, they're in meters instead πŸŽ€. Now here's the little brain-teaser: to dodge the cursed situation where the distance you typed in is smaller than one single cell, the program first checks whether your supplied distance is longer than one cell in both the NS and the WE directions. For LatLong projection only the NS distance gets checked, because in latitude the angular unit is always a bigger-or-equal distance than the longitude one, iykyk 🌈. And if you give distance in cells? Then for all projections it gets recalculated into meters with this formula, periodt:
number_of_cells*resolution_along_NS_direction

This lowkey matters a LOT if you're computing geomorphons over big areas in LatLong projection πŸ‘‘

  • elevation β€” your Digital Elevation Model, the moment πŸ’–. Data can be of any type and any projection, no gatekeeping. During the calculation the DEM gets stored as a floating point raster.
  • search β€” sets the length of the geodesic distances in all eight directions where the line-of-sight gets calculated πŸ”­. To keep things speedy, it only determines those cells whose centers fall into the distance.
  • skip β€” sets the length of the geodesic distances at the beginning of the calculation in all eight directions where line-of-sight is yet calculated. For speed, this distance is always recalculated into a number of cells which get skipped at the start of every line-of-sight, and it's equal in all directions 🌸. This parameter eliminates forms of very small extent β€” anything smaller than the skip parameter, basically.
  • flat β€” the difference (in degrees) between the zenith and nadir line-of-sight that indicates a flat direction. Higher threshold = more flat maps, that's just the vibe πŸ“. But heads up: if your map's resolution is low (more than 1 km per cell) the threshold should be very small (much smaller than 1 degree), because over that kind of distance 1 degree of difference means several meters of height difference 😭.
  • dist β€” Flat distance. This is the extra parameter that defines the distance above which the threshold starts to decrease, to avoid problems with pseudo-flat line-of-sights if a real elevation difference shows up at the distance where its value is higher (TO BE CORRECTED). πŸ™ˆ
  • comparison β€” your comparison mode for the zenith/nadir line-of-sight search πŸ’…. "anglev1" is the original r.geomorphon comparison mode. "anglev2" is the improved one, which better handles angle thresholds and zenith/nadir angles that are exactly equal. And "anglev2_distance" does all of that plus takes the zenith/nadir distances into account when the angles are exactly equal. Iconic.
  • forms β€” returns a geomorphic map with the 10 most popular terrestrial forms πŸ‘‘. The legend for the forms, its definition by the number of + and -, and its idealized visualisation are all presented at the image. πŸ¦‹

Forms represented by geomorphons:

  • ternary β€” returns the code of one of 498 unique ternary patterns for every cell. That code is the decimal representation of an 8-tuple of minimalised patterns written in ternary system. The full list of patterns lives in the source code directory as patterns.txt πŸ“œ. You can use this map to build an alternative form classification with a supervised approach.
  • positive and negative β€” returns the codes of binary patterns for the zenith (positive) and nadir (negative) line-of-sights. The code is a decimal representation of an 8-tuple of minimalised patterns written in binary system. Full list of patterns is available in the source code directory as patterns.txt ✨.
  • coordinates β€” the central point of a single geomorphon to profile πŸ“. The central point must be within the computational region, which should be large enough to accommodate the search radius. Setting the region larger than that will not produce more accurate data β€” but in the current implementation it will slow the computation down πŸ’€. For the best results, remember to align the region to the raster cells. Profiling is mutually exclusive with any raster outputs, but other parameters and flags (such as elevation, search, comparison, -m and -e) work as usual.
  • profiledata β€” the output file name for the complete profile data. "-" means write to the standard output πŸ–¨οΈ. The data is in a machine-readable format and it includes assorted values describing the computation context and parameters, as well as its intermediate and final results.
  • profileformat β€” format of the profile data: "json", "yaml" or "xml" πŸ’œ.
NOTE: the parameters below are experimental πŸ™ˆ. The usefulness of these parameters is currently under investigation.
  • intensity β€” returns the average difference between the central cell of the geomorphon and the eight cells in the visibility neighbourhood. This parameter shows the local (as is visible) exposition/abasement of the form in the terrain.
  • range β€” returns the difference between the minimum and maximum values of the visibility neighbourhood.
  • variance β€” returns the variance (difference between particular values and the mean value) of the visibility neighbourhood.
  • extend β€” returns the area of the polygon created by the 8 points where the line-of-sight cuts the terrain (peep the image in the description section πŸ“Έ).
  • azimuth β€” returns the orientation of the polygon constituting the geomorphon. This orientation is currently calculated as the orientation of a least square fit line to the eight verticles of this polygon.
  • elongation β€” returns the proportion between the sides of the bounding box rectangle calculated for the geomorphon rotated to fit the least square line.
  • width β€” returns the length of the shorter side of the bounding box rectangle calculated for the geomorphon rotated to fit the least square line.

πŸ“ NOTES

So from a computational point of view there are, like, no limitations on the input DEM and the free parameters used in the calculation, bestie πŸ’…. BUT. In practice there are some real issues around DEM resolution and search radius 😭.

Low resolution DEM β€” especially above 1 km per cell β€” requires a smaller than default flatness threshold. On the other hand, only forms with high local elevation difference will get detected correctly. Why? Because at very high distances (of the order of kilometers or higher) even a relatively high elevation difference gets recognized as flat πŸ’€. For example, at a distance of 8 km (that's 8 cells with a 1 km resolution DEM) a relative elevation difference of at least 136 m is required to be noticed as non-flat. The flatness distance threshold may be helpful to avoid this problem 🌈.


🌸 EXAMPLES 🌸

Geomorphon calculation: extraction of terrestrial landforms

Geomorphon calculation example using the EU DEM 25m:

g.region raster=eu_dem_25m -p
r.geomorphon elevation=eu_dem_25m forms=eu_dem_25m_geomorph
# verify terrestrial landforms found in DEM
r.category eu_dem_25m_geomorph
 1  flat
 2  peak
 3  ridge
 4  shoulder
 5  spur
 6  slope
 7  hollow
 8  footslope
 9  valley
 10 pit

Extraction of peaks

Using the resulting terrestrial landforms map, single landforms can be extracted β€” e.g. the peaks β€” and converted into a vector point map ⛰️:

r.mapcalc expression="eu_dem_25m_peaks = if(eu_dem_25m_geomorph == 2, 1, null())"
r.thin input=eu_dem_25m_peaks output=eu_dem_25m_peaks_thinned
r.to.vect input=eu_dem_25m_peaks_thinned output=eu_dem_25m_peaks type=point
v.info input=eu_dem_25m_peaks

πŸ“š REFERENCES

  • Stepinski, T., Jasiewicz, J., 2011, Geomorphons - a new approach to classification of landform, in : Eds: Hengl, T., Evans, I.S., Wilson, J.P., and Gould, M., Proceedings of Geomorphometry 2011, Redlands, 109-112 (PDF)
  • Jasiewicz, J., Stepinski, T., 2013, Geomorphons - a pattern recognition approach to classification and mapping of landforms, Geomorphology, vol. 182, 147-156 (DOI: 10.1016/j.geomorph.2012.11.005)

πŸ‘€ SEE ALSO

r.param.scale


🫢 AUTHORS

Jarek Jasiewicz, Tomek Stepinski (merit contribution)


πŸ’» SOURCE CODE

Available at: r.geomorphon source code (history)

Accessed: Saturday Jan 17 05:40:47 2026

Main index | Raster index | Topics index | Keywords index | Graphical index | Full index


That's the whole page, bestie β€” go make some geomorphons πŸ’–βœ¨ This is GRASS GIS 8.4.2, page r.geomorphon(1), snagged on Saturday Jan 17 05:40:47 2026, and the copyright is Β© 2003-2025 GRASS Development Team πŸŽ€πŸ¦‹ Slay, go map some landforms πŸ‘‘

πŸ“¦ where this page comes from