[GIS] Using slope and total height for terrain analysis in QGIS

maxheightqgisslopeterrain

Using QGIS I'm trying to analyse an area/DEM with these two criteria:
-Even sloping terrain steeper than 1:20 and total slope height > 5 m.

Finding areas with slope of 1:20 (5% slope) could be done with the slope function. But I can't figure out an easy way to filter these areas to only include areas with slope height over 5 meter. I.e. the vertical height form start of slope to top should be at least 5 meters.

Anyone have any ideas or thoughts on this problem?

Background: The criteria are to identity possible land slide areas (quick clay), so it's already clipped to only include areas of old marine sediments. https://www.ngu.no/en/topic/quick-clay-and-quick-clay-landslides

Best Answer

This can be done in a few ways, but using QGIS specifically, the best way I can think of is using Map Algebra. The idea is to first get all areas with a slope above your desired threshold, then calculate the Zonal Statistics for it. The step-by-step is as follows:

  1. Generate slope with Raster -> Analysis -> DEM -> Slope (input raster must be in projected CRS)
  2. Create mask raster with only your chosen threshold. Go to Raster -> Raster Calculator, and evaluate a new raster with [slope raster] >= [threshold] in the expression field. This is a binary raster.
  3. Merge smaller zones into larger ones. This is done so you don't end up with a 1-2 pixel zone (which can happen, since slope is calculated on a per-pixel basis). To do so go to Processing Toolbox -> Sieve, and decide a minimum pixel count for areas.
  4. Now you'll need to identify the different areas (they all have a value of 1 in your mask raster). To do so, first go to Raster -> Convert -> Poligonize, chosing a field name for your values column. Then, with this layer in edit mode, go to Field Calculator and update your value field with if([value field] > 0, '$id', [value field]). This way each zone will get a specific number associated with it, and the zones with gentle slopes remain as 0. Finally, rasterize this polygon layer again, attributing the field value to pixel value (the QGIS Rasterize tool may not work properly, if so consider using either the GDAL or the SAGA Rasterize tools in the Processing Toolbox).
  5. Now, call the r.univar GRASS function from the Processing Toolbox, pass to it your original DEM (the one used to calculate the slope), and the rasterized raster from the previous step as a mask. The output will be a text file with statistics for each zone. They look like this:

    zone 1 
    
    total null and non-null cells: 31
    total null cells: 0
    
    Of the non-null cells:
    ----------------------
    n: 31
    minimum: 579
    maximum: 645
    range: 66
    mean: 603.581
    mean of absolute values: 603.581
    standard deviation: 16.2218
    variance: 263.147
    variation coefficient: 2.68759 %
    sum: 18711
    

    repeated for each zone. The only info you want is zone number, minimum and maximum. Format this table into a CSV where each line is zone,minimum,maximum.

  6. Import this CSV into QGIS by going to Layer -> Add Layer -> Add Delimited Text Layer. Then, do a join with your polygon layer from step 4, joining by the zone number.
  7. Finally, create a new field and calculate maximum - minimum. Whichever features are above 5 in this resulting field will be your areas of interest.

UPDATE

As per user ThingumaBob's comment, one can simplify this procedure by using the Zonal Statistics tool that comes with QGIS, and which works with a vector layer as zones input.

As such, from step 4, after polygonizing the raster, one would go to Processing Toolbox -> Zonal Statistics, and enter the DEM as input raster and the polygon zones layer as input mask. The output is the same polygon layer, with extra fields for the calculated stats (hence, the end of step 6).

Related Question