Slope Position Classification

Topographic Analysis · TPI Tools · geoprocessing tool · by Jeff Jenness
Works at every ArcGIS Pro license level

Summary

Classifies a DEM into slope-position classes — valley bottom, lower, middle and upper slope, flat, and ridge — from a Topographic Position Index (TPI; Weiss 2001, after Guisan et al. 1999) plus slope, using a saved classification system. TPI is simply the difference between a cell's elevation and the mean elevation of a neighborhood around it: positive on hills and ridges, negative in valleys and channels, near zero on flats and mid-slopes, with slope telling the last two apart. The TPI and slope are computed internally from the DEM, with no Spatial Analyst extension, or you may supply pre-computed rasters. The neighborhood radius is often one of the most difficult parameters to estimate because we rarely have good data to guide us. The same point can be a valley bottom at one scale and a hilltop at another, and both are valid for different species or different questions.

Learn more About TPI explains the Topographic Position Index, why its scale is part of the answer, and how the six TPI tools fit together. The Topographic Position Index tool computes the TPI rasters this tool classifies, and the Landform Classification tool combines TPI at two scales.

Scale, units and classification systems

Neighborhood size is the scale of the analysis. A small neighborhood picks out local hills and hollows; a large one picks out broad ridges and valleys, and a point that is a valley bottom at one scale can be a hilltop at another. Choose the scale that matters for your question: a wide-ranging animal responds to major ridgelines hundreds of feet high, not to minor bumps underfoot, so a larger neighborhood suits it. The radius may be given in cells or in ground units, as a full circle or as an annulus that considers only a band of distances. On a geographic (latitude/longitude) DEM a ground radius is worked out per row on the spheroid, rounded east-west to a whole number of cells for each band of rows, so the neighborhood stays a circle on the ground to within about half a cell at any latitude.

Classification systems are reusable, named rule sets: the class thresholds, names and colors, saved as JSON in a per-user location that survives add-in reinstalls. The bundled defaults are a 6-class slope-position system adapted from Weiss (2001), Dickson and Beier's 4-class system, the Corridor Designer 4-Class Topographic Position system from the CorridorDesigner toolbox tutorial (Majka et al. 2007) (raw TPI, cells at least 12 m below their neighborhood mean are canyon bottom, at least 12 m above it are ridgetop, and everything between splits at a 6° slope into flat-gentle and steep slope), and the Land Facet Corridor Designer 3-Class Topographic Position system, the canyons, slopes and ridges that land facets are built within (raw TPI at −6 and +6 m, no slope criterion). New systems, including per-class colors that symbolize the output when it reaches the map, are authored in the Classification System Builder. Classification is applied cell by cell in one pass; a class is the AND of its criteria, and where classes overlap the lowest class value wins.

Raw versus standardized TPI. Raw TPI is in the DEM's elevation units, so a threshold is absolute: a 100 m hill is read the same way everywhere. That is usually the right choice for ecological questions, where absolute relief is what an animal experiences. Standardized TPI expresses the value relative to the variability of the terrain (Weiss's own default), so a 1 m bump on a plain and a 100 m hill in the mountains can fall in the same class; useful when a classification must adapt to each landscape, but ecologically misleading if you are expecting a 100 m hill to be treated the same everywhere. Each classification system records which form its thresholds assume, the dialog defaults to that form when you pick a system, and the tool warns, but still runs, if you override it.

Both choices, the neighborhood and the thresholds of the system, can be tried before a full run with the TPI Neighborhood Sampler: a snapshot of the DEM in the map view, a slider for the radius, a slider for a threshold in raw or neighborhood standard deviation units, and a pin that shows at which radii a chosen hill or valley falls into the class. What it finds goes into the on-the-fly neighborhood here and into the system's criteria in the Classification System Builder.

How the classes are defined

A slope-position class is a range of TPI, with slope added only where TPI alone cannot decide. A cell well above its neighborhood mean is a ridge; a cell well below it is a valley; and a cell near the mean is either flat ground or an even mid-slope, which slope tells apart. The profile below, from the manual of the ArcView 3.x TPI extension (Jenness 2006), shows how five of the classes of Weiss (2001) fall on a cross-section; the maps after it show all six.

A terrain cross-section labeled Small-Neighborhood Slope Position Classification: short neighborhood brackets mark a lower slope (low TPI), a ridge (very high TPI), a middle slope (mid TPI, steep slope), a flat slope (mid TPI, shallow slope) and a valley (very low TPI)
Slope-position classes on a profile, with a small neighborhood: TPI places the ridge, the valley and the lower slope, and slope separates the flat from the middle slope. The sixth class, upper slope, is not marked on this profile. From the TPI extension manual (Jenness 2006).
An elevation map and a slope map of a canyon system feeding two slope-position maps, one from a 500-meter neighborhood with fine ridges and valleys, one from a 2000-meter neighborhood with broad valleys in red and ridges in blue, with the Weiss 2001 sample criteria set in the legend: valley TPI at or below minus 1 SD, lower slope, flat slope with slope at most 5 degrees, middle slope with slope above 5 degrees, upper slope, and ridge above 1 SD
The same DEM classified with the Weiss (2001) sample criteria at two neighborhood radii, 500 m and 2,000 m. The criteria are the same; only the scale differs. From the TPI extension manual (Jenness 2006).

Six slope-position systems ship with the add-in. Three are adapted from the Weiss six-class scheme, one in each of the three TPI forms, two are four-class schemes from cougar and corridor work, and one is the three-class scheme of the land facet method (and remember that you can easily make your own system with the Classification System Builder). The table gives each system exactly as its file defines it. Where a cell satisfies more than one class, the lowest class value wins; none of the bundled systems has overlapping classes, so what happens to a cell exactly at a break is decided by the ≤, < and ≥ signs in the rules. In the Weiss systems a cell exactly at −1 is a Valley, at −0.5 a Lower Slope, at 0.5 or 1 an Upper Slope (the Flat and Middle Slope ranges are open at both ends), and above 1 a Ridge, with the same pattern at the raw and percentile breaks.

SystemValueClassRule
Weiss 6-Class Slope Position
TPI in neighborhood standard deviations; slope in degrees
1ValleyTPI ≤ −1
2Lower Slope−1 < TPI ≤ −0.5
3Flat Slope−0.5 < TPI < 0.5 and slope ≤ 5°
4Middle Slope−0.5 < TPI < 0.5 and slope > 5°
5Upper Slope0.5 ≤ TPI ≤ 1
6RidgeTPI > 1
Weiss 6-Class Slope Position, using Raw TPI values
TPI in elevation units; slope in degrees
1ValleyTPI ≤ −20
2Lower Slope−20 < TPI ≤ −5
3Flat Slope−5 < TPI < 5 and slope ≤ 5°
4Middle Slope−5 < TPI < 5 and slope > 5°
5Upper Slope5 ≤ TPI ≤ 20
6RidgeTPI > 20
Weiss 6-Class Slope Position, using Percentile TPI values
TPI in percentile units (0–100); slope in degrees
1ValleyTPI ≤ 10
2Lower Slope10 < TPI ≤ 45
3Flat Slope45 < TPI < 55 and slope ≤ 5°
4Middle Slope45 < TPI < 55 and slope > 5°
5Upper Slope55 ≤ TPI ≤ 90
6RidgeTPI > 90
Dickson & Beier 4-Class Slope Position
TPI in elevation units; slope in degrees
1RidgelineTPI ≥ 8
2Steep Slope−8 < TPI < 8 and slope ≥ 6°
3Gentle Slope−8 < TPI < 8 and slope < 6°
4Canyon BottomTPI ≤ −8
Corridor Designer 4-Class Topographic Position
TPI in elevation units; slope in degrees
1Canyon bottomTPI ≤ −12
2Flat-gentle slope−12 < TPI < 12 and slope ≤ 6°
3Steep slope−12 < TPI < 12 and slope > 6°
4RidgetopTPI ≥ 12
Land Facet Corridor Designer 3-Class Topographic Position
TPI in elevation units; no slope
1CanyonsTPI ≤ −6
2Slopes−6 < TPI ≤ 6
3RidgesTPI > 6

The Weiss system is adapted from the six-class scheme of his 2001 poster. As bundled here its thresholds are applied to TPI in standard deviations of the elevations within each cell's own neighborhood; the poster itself standardized each whole TPI raster to z-scores, a form the tools do not compute (see About TPI). The raw variant keeps the same shape with thresholds of ±5 and ±20 elevation units, and the percentile variant places its breaks at the 10th, 45th, 55th and 90th percentiles of the neighborhood, the percentile form of TPI described by Wilson and Gallant (2000). Because a cell is counted in its own circular neighborhood, its percentile can reach at most 100(n − 1)/n for n cells, 88.9 in the 9 cells of a 1.5-cell radius, so the Ridge class (above 90) needs a radius of at least 2 cells; the tool warns whenever a percentile class threshold cannot be reached with the neighborhood used. Both variants are meant as starting points: raw thresholds are absolute relief and should be adjusted to the DEM and the question. The Dickson and Beier system follows their study of topographic position and cougar movement in southern California (Dickson and Beier 2007), with raw thresholds of ±8 and a 6° slope split; its codes run from ridgeline (1) to canyon bottom (4). The Corridor Designer system reproduces the topographic position raster of the CorridorDesigner tutorial, with ±12 thresholds and the same 6° split, and its codes run the other way, from canyon bottom (1) to ridgetop (4); the two are not interchangeable in a model that keys on the codes.

Two ways to supply the TPI and slope. The TPI and slope source setting at the top of the dialog chooses between calculating both from a DEM, with the neighborhood, TPI type, slope method and slope units set in the dialog, and classifying TPI and slope rasters that already exist, for example outputs of the Topographic Position Index tool or rasters saved by an earlier run of this one. In either case the tool classifies the values it is given as they are; it never converts a raw TPI to standardized units or back. What it does check is whether the values match what the system expects. Rasters written by these tools carry their TPI type, their neighborhood radius and their slope units in their metadata, and the tool reads those stamps; for a raster made elsewhere, the two Declare dropdowns let you state its type and units. If the type or the units do not match the system's thresholds, the tool warns, writes the warning into the output's metadata as well, and still runs. The warning compares kinds only, raw, standard-deviation or percentile: the DEM-scale and experimental outputs of the Topographic Position Index tool both count as standard-deviation kinds and pass a system written for the neighborhood-standardized TPI without a warning.

A tour of the dialog

The example is the first step of the Land Facet Tutorial, where topographic position is the first-pass classification that the land facets are then built within. The Corridor Design Tutorial runs the same tool with a 200 m radius to make the topographic position factor of a habitat suitability model.

The Topographic Analysis Tools gallery open on the ribbon, with the Slope Position Classification button, in the TPI Tools row, outlined in blue
Where to find it: Slope Position Classification is in the TPI Tools row of the Topographic Analysis Tools gallery, in the Topographic Analysis group of the Wildlife and Forestry tab.
The Slope Position Classification geoprocessing pane: TPI and slope calculated on the fly from dem_m, circle neighborhood, radius 10 cells, raw TPI in elevation units, meters, geodesic slope in degrees, the generated slope raster saved as Slope_Degrees, the Corridor Designer 4-Class Topographic Position system, output Topographic_Position
Calculating on the fly: the DEM, the neighborhood shape, radius and units, the TPI type, the DEM's elevation units, the slope method and units, two optional outputs for the intermediate TPI and slope rasters, and the classification system. Choosing Use Existing TPI and Slope Rasters instead swaps this group for the two existing-raster inputs.
The output topographic position raster over a hillshade: canyon bottoms in blue, flat-gentle slopes in pale green, steep slopes in tan and ridgetops in red, with two wildland block polygons outlined
The output: an integer raster with a Value and Class_Name attribute table and the system's color map, so it draws as named, colored classes the moment it is added to the map. Here, canyon bottoms in blue, flat-gentle slopes in green, steep slopes in tan and ridgetops in red.

Classifying existing rasters: a Grand Canyon example

The second example classifies rasters that already exist: the raw TPI of the Walhalla Plateau in the Grand Canyon, computed with a 500 m circular neighborhood on the Topographic Position Index page, and a slope raster of the same area. With Use Existing TPI and Slope Rasters chosen, the DEM and neighborhood settings drop out of the dialog, and only the two rasters, their optional Declare dropdowns, the classification system and the output remain.

The Slope Position Classification pane in Use Existing TPI and Slope Rasters mode: existing TPI raster Grand Canyon: Raw TPI Units with a warning icon, existing slope raster Grand_Canyon_Slope, Declare TPI type Raw (elevation units), classification system Weiss 6-Class Slope Position, output Grand_Canyon_TPI_SlopePos; a pop-up on the TPI raster says the TPI is raw TPI (elevation units) but the system expects standard-deviation units, applying it as-is may misclassify, and the tool still runs
A mismatch caught before running. The TPI raster was made by the Topographic Position Index tool, so its metadata says it is raw TPI in meters, and the Declare dropdown filled itself in accordingly. The Weiss 6-Class Slope Position system expects standard-deviation units, so the dialog warns that the thresholds of ±0.5 and ±1 would be read as half a meter and one meter. The tool would still run.

The bundled raw-TPI version of the Weiss scheme would match the units, but its thresholds of 5 and 20 m are far too small for a canyon where the TPI runs from −350 to +447 m, where even modest side canyons and spurs would clear them. This is exactly the case the Classification System Builder is for. Starting from the raw-TPI Weiss system and widening its thresholds to ±50 and ±100 m gives a system suited to Grand Canyon relief, saved under its own name so the bundled one stays as it was.

The Classification System Builder with a system named Custom Grand Canyon, using Raw TPI values, family slope_position, slope units Degrees, six classes Valley, Lower Slope, Flat Slope, Middle Slope, Upper Slope and Ridge with their colors, and the criteria for Lower Slope: tpi, raw, greater than -100 and less than or equal to -50
A custom system in the Classification System Builder: the six Weiss classes with raw thresholds of ±50 and ±100 m. The lower slope, selected here, is TPI above −100 and at or below −50 m.
The Slope Position Classification pane with the same two existing rasters, Declare TPI type Raw (elevation units), classification system Custom Grand Canyon, using Raw TPI values, and output Grand_Canyon_Slope_Class, with no warning
The same rasters with the custom system: the units agree, and the warning is gone.
Two maps of the Walhalla Plateau over a hillshade: on the left the raw TPI in a blue-white-red stretch from about -350 to 447; on the right the six-class slope-position output, with valleys in blue and lower slopes in blue-green down the side canyons, ridges in red along the canyon rims and spurs, upper slopes in orange, middle slopes in tan, and the plateau top largely flat slope in pale yellow; a 10 kilometer scale bar
The raw TPI (left) and the six classes it produces with the custom system (right). The side canyons are valleys and lower slopes, the rims and spurs between them are ridges and upper slopes, the canyon walls are middle slopes, and the gentle top of the plateau is mostly flat slope, where the slope criterion separates flat ground from the middle slopes.

The tool holds the whole raster in memory at once, so the memory it needs grows with the number of cells. On most rasters that is no concern. On a very large one the tool may need more memory than your computer has free, and then one of two things happens: Windows starts using the disk as overflow memory and the tool slows to a crawl, or the tool stops with an out-of-memory error. There is no fixed limit; it depends on how much memory your computer has free. If a raster is too large, clip it to the area you need first.

ModelBuilder

A ModelBuilder diagram: dem_m feeding Slope Position Classification, producing the optional saved TPI raster, the optional saved slope raster, and the Topographic_Position output
The DEM in; the class raster out, with the intermediate TPI and slope rasters as optional extra outputs that downstream tools can pick up.
A ModelBuilder diagram: Grand Canyon: Raw TPI Units and Grand_Canyon_Slope both feeding Slope Position Classification, producing Grand_Canyon_Slope_Class and the two optional save outputs
The existing-rasters version of the Grand Canyon run: two inputs, the TPI and the slope. Calculating on the fly, as in the diagram above, needs only the DEM.

Parameters

LabelExplanationData type
TPI and slope sourceRequired · tpi_source Calculate TPI and Slope on-the-fly from DEM (default) computes both from the DEM with the settings below; Use Existing TPI and Slope Rasters classifies rasters you already have, as they are. String
Input elevation raster (DEM)Optional · in_raster Single-band DEM, projected or geographic; required when calculating on the fly. Raster Layer or Dataset
Neighborhood shapeRequired · nb_shape Circle (all cells within the radius) or Annulus (a ring between an inner and outer radius). Default Circle. String
Neighborhood radiusRequired · nb_outer The (outer) radius: the scale of the analysis. Default 10. Double
Neighborhood inner radius (annulus only)Optional · nb_inner For an annulus, cells nearer than this are excluded. Double
Neighborhood radius unitsRequired · nb_units Cells, or a ground unit (meters, kilometers, feet, miles) converted from the cell size; per row on the spheroid for geographic DEMs. Default Cells. String
TPI type (on-the-fly)Required · tpi_type Raw (elevation units), Neighborhood standard deviation or Percentile. Defaults to what the chosen system expects (Neighborhood standard deviation for the Weiss 6-class); a mismatch warns and still runs. String
Elevation unitsOptional · elev_units Meters or feet, for the slope calculation; detected and locked when the DEM has a vertical coordinate system. String
Slope method (projected DEMs)Optional · slope_method Planar (matches Esri's Slope tool) or Geodesic; geographic DEMs are always geodesic. Default Planar. String
Slope output unitsRequired · slope_units Degrees or percent rise; defaults to the system's assumption (Degrees for the bundled systems) and warns on a mismatch. String
Save generated TPI raster (optional)Optional · save_tpi Keep the intermediate TPI raster, stamped with its TPI type. Blank keeps it in memory only. Raster Dataset
Save generated slope raster (optional)Optional · save_slope Keep the intermediate slope raster, stamped with its units. Raster Dataset
Existing TPI rasterOptional · in_tpi When using existing rasters: the TPI to classify, as is. Must have the same number of rows and columns as the slope raster; the tool checks the dimensions, not the extent. Raster Layer or Dataset
Existing slope rasterOptional · in_slope When using existing rasters: the slope raster; required when the system uses slope. Raster Layer or Dataset
Declare TPI type (optional, for warnings)Optional · declare_tpi_type What kind of TPI an existing raster holds, when its metadata does not say; used only for the compatibility warning. String
Declare slope units (optional, for warnings)Optional · declare_slope_units Degrees or percent for an existing slope raster, when its metadata does not say; warnings only. String
Classification systemRequired · system The saved system to apply: thresholds, names and colors. Picking one sets the TPI-type and slope-unit defaults. Default Weiss 6-Class Slope Position. String
Output slope-position rasterRequired · out_raster Integer class raster with a Value / Class_Name table and the system's color map. Cells matching no class are unclassified. Any unit warnings are written into its metadata. Raster Dataset

Python

import arcpy
arcpy.ImportToolbox(r"C:\path\to\JennessEnterprisesTools.pyt")  # your install path
arcpy.jenness.SlopePositionClassification(
    tpi_source="Calculate TPI and Slope on-the-fly from DEM",
    in_raster=r"D:\tutorial.gdb\dem_m",
    nb_shape="Circle", nb_outer=10, nb_units="Cells",
    tpi_type="Raw (elevation units)", elev_units="Meters",
    slope_method="Geodesic", slope_units="Degrees",
    save_slope=r"D:\tutorial.gdb\Slope_Degrees",
    system="Corridor Designer 4-Class Topographic Position",
    out_raster=r"D:\tutorial.gdb\Topographic_Position")

# Classify TPI and slope rasters that already exist, as they are.
# The declare_* arguments are optional; rasters made by these tools
# carry their type and units in their metadata.
arcpy.jenness.SlopePositionClassification(
    tpi_source="Use Existing TPI and Slope Rasters",
    in_tpi=r"D:\tutorial.gdb\dem_TPI", in_slope=r"D:\tutorial.gdb\Slope_Degrees",
    declare_tpi_type="Neighborhood standard deviation",
    declare_slope_units="Degrees",
    system="Weiss 6-Class Slope Position",
    out_raster=r"D:\tutorial.gdb\Slope_Position_Weiss")

The list-driven parameters take these strings exactly: tpi_source is "Calculate TPI and Slope on-the-fly from DEM" or "Use Existing TPI and Slope Rasters"; nb_shape is "Circle" or "Annulus"; nb_units is "Cells", "Meters", "Kilometers", "Feet" or "Miles"; tpi_type is "Raw (elevation units)", "Neighborhood standard deviation" or "Percentile"; elev_units is "Meters" or "Feet"; slope_method is "Planar" or "Geodesic"; slope_units and declare_slope_units are "Degrees" or "Percent"; declare_tpi_type adds "DEM-scale standard deviation" to the three TPI types; and system is the name of any slope-position system in the store, bundled or your own. The names of the systems on your computer are listed in the Classification System Builder; they are also the "name" entries of the JSON files in %LOCALAPPDATA%\JennessEnterprises\WildlifeTools\classification_systems\, but if you look them up there, take care not to change anything: an edited file can leave a system unreadable.

Recommended citation

Jenness, J. 2026. Slope Position Classification. Wildlife and Forestry Tools add-in for ArcGIS Pro, v. 1.99 (September 2026). Jenness Enterprises. Available at: https://github.com/JeffJenness/Wildlife_Tools.

Credits and references

By Jeff Jenness, Jenness Enterprises (www.jennessent.com), modernizing his Topographic Position Index extension for ArcView 3.x. The Corridor Designer 4-class system reproduces the Create Topographic Position Raster tool by Dan Majka in the CorridorDesigner toolbox (Beier, Majka and Jenness 2007).

Licensing information

Works at every ArcGIS Pro license level (Basic, Standard, Advanced). No extension licenses are required; the TPI and slope are computed internally, without Spatial Analyst.