I want to create a Habitat Suitability Index (HSI). I have several variables (raster layers containing information about e.g. precipitation, slope, food resources, etc.).

I have to create an "index" for each raster layer. That means that i have to reclassify all layers on a scale from 0 to 1, where 0 is not suitable and 1 is really suitable. This is were I am stuck. I know how to reclassify data in terms of assigning values to specific classes. But for some variables, I have to create a continuous index

I have troubles explaining, since english is not my first language and I'm new to the topic, but I will try:

I need to reclassfy the data continuously, according to my guidelines. For example altitude (image 1): The plot below shows, how i have to reclassify altitude. in summer, an altitude from 1200 to 1500 meter is perfect, for higher altitues the HSI slowly decreases, but not linear unfortunately. This is the same for example for the index for the crown projection (second image). I have to reclassify the values on a scale from 1 to 100, but again, it is not linear.

index for altitude

index for Crown projection

My first thought was to apply some kind of funtion on the raster, but unfortunately, I could not find the right answer on google, so I'm afraid I'm searching for the wrong keywords.

I am using QGIS (3.16.1 and 3.10.13), I am quite experienced in SAGA, GDAL, Grass and OTB and I have a bit of knowledge in R.

5 Answers 5


I think you're looking for the Raster Calculator tool. It will let you apply an equation to each raster. What that equation is (i.e. what function defines the curved line in each graph above) you'll have to figure out based on your research or other literature on the subject.

Then you can also use Raster Calculator to combine your variables once they are in a 0-1 scale. If all variables have equal weight this would just be a simple sum, but if for example elevation is twice as important as vegetation you could do something like (2*elevation + vegetation).


I didn't find how to put conditions with equations in the qgis raster calculator, so I wrote a tutorial to help you in ArcGIS. ArcGIS has free 21-day trial, he just needs your sign up (ArcGIS trial). I use the ArcGIS Desktop but ESRI developed the ArcGIS PRO too, both presents free trials.

I have worked with the summer line and defined some inflection points. enter image description here With the point data, I used the Excel to calculated the line equation (I'm too lazy to do it by hand), and, then I wrote the condition equations to implement in Raster Calculator. enter image description here

enter image description here

The equations are:

Con((Topo > 0) & (Topo < 1500), 1, 0)
Con((Topo > 1500) & (Topo < 1700), -0.001*Topo + 2.5, 0)
Con((Topo > 1700) & (Topo < 1900), -0.0015*Topo + 3.35, 0)
Con((Topo > 1900) & (Topo < 2000), -0.001*Topo + 2.4, 0)
Con((Topo > 2000) & (Topo < 5000), 0, 0)
>>> Place your raster name in Topo 

I uploaded the data and a model with the equations, you hust need to input with your data.

After you install the ArcGis:

  1. Open ArcGIS Catalog
  2. Click in Connect to Fold (a folder with plus sign)
  3. Go to the folder where you save my data
  4. Click in the Workflow
  5. Click with mouse right botton in the HSI_model and Edit
  6. Replace my input file

My results are here:

Topography Topography

Classes enter image description here

HSI enter image description here

The second task, you may use Large (or MSLarge) function in Fuzzy Membership with Mean in 55. In parameter spread you will have to test the values. The documentation is here

enter image description here

All file are in my github

And good luck :)

  • thank you so much! I have to do it more often in the future, so I can't do it on ArcMap, but i managed to adapt your method in QGIS.
    – Paula_123
    Jan 10, 2021 at 17:13

I think you may use the Fuzzy function in Grass or Arc-SDM3. In this way, you could input several condition.

  1. Fuzzy example is here.
  2. You can download Arc-SDM3 here.
  3. Application of Fuzzy in the ArcSDM3 here.
  • Thanks! fuzzy was exactly the keyword I was looking for.
    – Paula_123
    Jan 10, 2021 at 17:14

Another option is the GRASS GIS module r.rescale (manual page), available in the Processing Toolbox. You set the minimum and maximum values that you want, and all (continuous) raster values are scaled to that range.

i.e. (If you have an elevation raster "elev":

r.rescale input=elev output=elev_rescaled to=0,1

Just came across this post, and I know it's several years old, but using a scripting language like Python or R is probably the most efficient way of approaching this problem, especially if you are applying it to different areas or conditions, or if your preference function isn't a recognizable function (e.g. it's based on a table).

Using R since OP mentioned familiarity


  1. For each of the environmental variables, a table of break values or inflection points and the corresponding preference value for that variable.
  2. Rasters of each environmental variable at the same scale, resolution, and projection.

You can then use approxfun(variable, preference) to create a function that takes converts your environmental variable to a preference. This will do the work of calculating your line functions to linearly interpolate between inflection points. Then you apply the function to your raster. Combine individual preference rasters to form composite HSI.

Creating functions:

ALT = c(15, 17, 19)  # Altitude
AF = c(1, .8, .5)  # Altitude preference value

CPT = c(10, 30, 60, 70, 90)  # values picked off second example plot
ICP3 = c(0.05, 0.2, 0.6, 0.75, 1) # preference values for CPT, picked off plot and visually rescaled

alt_preference = approxfun(ALT, AF)
cpt_preference = approxfun(CPT, ICP3)

 # testing
[1] 0.9
[1] 0.575

[1] 0.125
[1] 0.875

Then read in your raster and apply functions:
Not run, since I don't have example rasters

library(terra) # package for handling raster data in R
A = rast("ALT_file.tif")  # Making up name for file
B = rast("CPT_data_file.tif")  # Making up name for file

A_pref = alt_preference(A) ## Converts ALT to preference values
B_pref = cpt_preference(B) ## Converts CPT to ICP3 values

HSI_raster =  sqrt(D_pref * B_pref)  ## Combining using geometric mean
writeRaster(HSI_raster, "FileName.tif")  # saving output raster to disk

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.