How do I slice a raster into different value ranges and calculate the area of each, doing this for many rasters?

728
3
05-04-2022 01:27 AM
Elijah
by
Occasional Contributor II

I have many rasters: The task is to slice each of the rasters into different value ranges (e.g, 0 -8, 8.0 -12 & 12.0 -15) and calculate the area of each slice. Somehow, I am not python-wise yet. Being a repetitive process I guess python will come in here. Any help in this regard would be appreciated as I can't imagine doing this manually for all the raster.

 

Thank you.

0 Kudos
3 Replies
JohannesLindner
MVP Frequent Contributor

You can use the arcpy.sa.Raster class, which has a built-in raster cell iterator:

def get_raster_areas(raster_path, upper_bounds):
    """Returns the areas of a raster that are below the given values.

    raster_path: str, path to the raster
    upper_bounds: [float], the upper bounds of your desired value bins

    """
    # get raster object
    raster = arcpy.sa.Raster(raster_path)
    # get cell area
    dimensions = raster.getRasterInfo().getCellSize()
    cell_area = dimensions[0] * dimensions[1]
    # initialize the area list
    upper_bounds.sort()  # it's important that upper_bounds is sorted
    areas = [0 for x in upper_bounds]

    # loop over the raster cells
    for row, col in raster:
        # loop over the upper_bounds
        for i, ub in enumerate(upper_bounds):
            # if raster cell value is below upper bound, 
            # add cell_area to the corresponding element in the areas list
            # and break, so this cell doesn't also get added to the other (higher) bins
            # (that's why we needed to make sure upper_bounds is sorted)
            if raster[row, col] < ub:
                areas[i] += cell_area
                break
    # return the area list
    return areas


rp = r"G:\...\DGM1_2017_HB1.TIF"  # 100x100m raster of elevations in a coastal town
bins = [0, 8, 12, 15]
areas = get_raster_areas(rp, bins)

for b in range(len(bins)):
    print(f"elevation < {bins[b]}m: {areas[b]}m²")
#elevation < 0m: 33.0m²      # below 0m
#elevation < 8m: 997968.0m²  # between 0m and 8m
#elevation < 12m: 0m²        # between 8m and 12m
#elevation < 15m: 0m²        # between 12m and 15m

Have a great day!
Johannes
Elijah
by
Occasional Contributor II

Thanks Johaness. I will try to see how to manage the codes. I appreciate.

0 Kudos
RyanDeBruyn
Esri Contributor

You could also look into the SA Reclassify/Slice and  Zonal Geometry tools

You could do this in a model builder environement or if wanting to script, Python samples are available on the respective tool help documents.

Good luck.

0 Kudos