Catalyst.earth Logo
Catalyst.earth Logo

Volumetric Analysis with CATALYST Professional

Image of rsz-sar-video-featured-image

Volumetric analysis is a powerful technique used to estimate the volume of natural and man-made features from elevation data. Whether measuring stockpiles at a mine, calculating the capacity of an excavation, or monitoring changes in terrain over time, accurate volume calculations provide valuable insights for planning, resource management, and quality control. This tutorial walks through the steps involved in the workflow using the CATALYST Professional Python API, with a Digital Surface Model (DSM), Digital Terrain Model (DTM), and polygon boundaries that define the area of interest (AOI).

The process involves generating a height difference raster from the DSM and DTM, identifying the elevation differences within each stockpile boundary, and calculating the total volume based on the height difference and pixel area.

Integrating Jupyter Notebook & Python Open-Source Libraries into the Workflow

To accompany this tutorial, a Jupyter Notebook that implements the workflow using the CATALYST Python API alongside open-source Python libraries is provided. This notebook serves as a practical example that can be followed, modified, and adapted to different datasets.

CATALYST Volumetric Analysis Jupyter Notebook - Stockpile_Volumetric_Analysis.ipynb

1. DSM & DTM Extraction

Before performing volumetric analysis, both DSM and DTM elevation data are required. The process of creating these datasets is covered in detail in various tutorials, which are linked below. If these files are already available, you can proceed to the next section to calculate the height difference.

2. Height Difference Raster Generation

Once the DSM and DTM rasters have been generated, the next step is to create a raster containing the elevation difference between the surface and underlying terrain. This is done by subtracting the DTM from the DSM on a pixel-by-pixel basis. The resulting image values correspond to the height of the objects above the ground, which will be the primary input for the volume calculations.

The Change Detection tool is well-suited for this step, as it computes the difference between a working raster and reference raster. In this scenario, the DSM is used as the working raster and the DTM as the reference raster. When automating the workflow in Python, the CHDETOP algorithm provides the equivalent functionality, allowing the difference raster to be generated programmatically.

To generate the height difference raster in Focus:

  1. In Focus, open the Change Detection tool - Analysis > Change Detection...
  2. Under Working raster (A), click Browse and navigate to the DSM file.
    • Select the Extracted DEM layer.
  3. Under Reference raster (B), click Browse and navigate to the DTM file.
    • Select the Extracted DTM layer.
  4. In the Algorithm dropdown menu, select Difference (A-B).
  5. Uncheck the Absolute value and Percentile boxes.
  6. Change the Output display to Grayscale.
  7. Click Run.

3. Stockpile Segment Extraction

The stockpile segments are extracted through image segmentation, which groups neighbouring pixels with similar characteristics into distinct regions to represent individual objects. This way, each stockpile is isolated from the surrounding terrain and neighbouring stockpiles, allowing for easy volume calculation. The EXPOLRAS algorithm is used here to extract and refine the vectors.

To extract the stockpile polygons:

  1. Open the Algorithm Librarian and search for EXPOLRAS - Tools > Algorithm Librarian > EXPOLRAS.
  2. Select the height difference raster as the Input Raster Layer.
  3. In the Output Ports section, browse to the output file location and check the box. This will write the resulting vectors to a file.
  4. In the Input Params 1 tab, set the threshold, area, and compactness fields appropriately.
  5. Click Run.
Figure 1: Stockpile polygon generated from EXPOLRAS

4. Volume Calculation

With the stockpile boundaries extracted and the height difference raster generated, the final step is to calculate the volume of each stockpile. This is accomplished by combining the height information from the raster with the area represented by the image resolution. For each pixel contained within a segment, the product of the height difference and the pixel area is calculated. The sum of these values across all pixels within a segment represents the estimated stockpile volume.

This can be done in Python with the help of the numPy, rasterio, and geopandas open-source libraries along with the CATALYST Python API.

import numpy as np
import rasterio
from rasterio.mask import mask
import geopandas as gpd
import pci
from pci.api import datasource as ds

# Calculate Volume of stockpile segments
stockpile_gpd = gpd.read_file(stockpile_poly)
height_diff = rasterio.open(height_diff)
volumes = []

with ds.open_dataset(dsm, ds.eAM_READ) as dataset:
    resolution = dataset.resolution_in_meters
    pixel_area = resolution[0] * resolution[1]

    for idx, row in stockpile_gpd.iterrows():
        # Clip difference raster to stockpile polygon
        clipped, _ = mask(height_diff, [row.geometry], crop=True, filled=False)
        
        # Remove band dimension
        delta_height = clipped[0]

        # Sum height values
        height_sum = np.sum(delta_height)

        # Calculate volume
        volume = height_sum * pixel_area
        volumes.append(volume)

# Save to file
stockpile_gpd["volume_m3"] = volumes
stockpile_gpd.to_file(os.path.join(stockpile_vol_dir, "stockpile_volume.shp"))
height_diff.close()

In this sample script, stockpile_poly represents the stockpile segments extracted using the EXPOLRAS algorithm, height_diff represents the height difference raster generated with the change detection tool.

The image resolution is obtained from the CATALYST Python API dataset object's resolution_in_meters tuple property. The x and y resolution values are multiplied to determine the area represented by a single pixel. Next, the height_sum parameter accumulates the height difference values for all pixels within a stockpile segment. Multiplying this accumulated height by pixel_area produces the estimated volume for that stockpile.

Once the volume has been calculated for each segment, the resulting values are added as a new attribute to the stockpile geopandas object. The updated dataset is then exported as a shapefile, allowing the calculated volumes to be viewed, analyzed, or used in other GIS applications.

The estimated volume of the stockpile, as shown in Figure 1, is 416,799.78 cubic metres (m3).

envelopephone-handsetcross