4 Exercise 1: Delineation of the Zwalm catchment
4.1 Assignment
The delineation of a catchment based on a digital elevation model is often one of the first steps in a hydrological modelling study. The procedure is relatively straightforward, but the digital elevation model needs to be properly processed prior to the analysis. The pre-processing of the digital elevation model at least includes the removal of data gaps (i.e. spatial interpolation) and the removal of sinks (or depressions). Based on the processed DTM, the catchment can then be easily delineated using the simple principle that water always flows in the direction of the largest gradient. Different algorithms exist to do so (see course notes); here, only the gradient of every cell to its eight direct neighbours, the deterministic 8 (D8) algorithm, will be used.
The outlet of the Zwalm catchment is located in the vicinity of \(x\)=101673 m and \(y\)=17537 m
For this geospatial analysis, GRASS will be used, a powerful computational engine for raster, vector, and geospatial processing. It supports terrain and ecosystem modelling, hydrology, data management, and imagery processing. There are multiple ways of using GRASS. In this exercise, you can choose between 2 ways of interacting with GRASS:
With QGIS as Graphical User Inteface (GUI), all GRASS functionality can be accessed via the Procesing Toolbox
The Python GRASS interface allows programmatic access to GRASS functionality. For an in depth introduction, we refer to the documentation. In this exercise, we will use the grass.toolsinterface. The initial setup of the GRASS environment is provided inscripts/1_catchment_delineation.py, to which you can add your own code. All tools are accessible via thetoolsvariable defined there. For example if you want ot use ther.importfunction, you would calltools.r_import(input="PATH_TO_FILE",output="OUTPUT_NAME", overwrite=True). Note that:- It is recommended to set the
overwrite=Trueargument for all functions. - It is a general convention that the
.defined in the GRASS function name (as found in the tool manual)is replaced by_in the Python function name. - The output of a previous function (e.g.
OUTPUT_NAMEin the example above) can be used as input for a subsequent function. For example, if you want to use the output ofr.importas input (calledelevation) for a slope calculation withr.slope.aspect, you would calltools.r_slope_aspect(elevation="OUTPUT_NAME", slope="SLOPE", overwrite=True). - In
scripts/helper_functions.py, two helper functions are defined:get_data_array_from_rastergives you anxarray.DataArraygiven the name (e.g."OUTPUT_NAME") of a GRASS raster layer andplot_grass_rastermakes a plot of a GRASS raster layer (given its name as again). Use these functions to check intermediate results.
- It is recommended to set the
Irrespective of the choice of interface, an overview of all GRASS functions can be found in tool manual. Specific tips for each interface will be denoted by their logo in the steps below.
- Start by loading the DTM (see Section 3.2). Check if it is clipped to a reasonable region of interest around the Zwalm river (bounding box of approximately \(x_{\mathrm{min}}=\) 98000 m, \(x_{\mathrm{max}}\) = 116000 m, \(y_{\mathrm{min}}\) = 160000 m, \(y_{\mathrm{max}}\) = 180000 m).
Use the r.importfunction to load in raster data.
- Spatially gap-fill the DTM (i.e. make sure there are no missing values).
Use the r.fillnullsfunction to fill in missing values.
Use the Fill nodatatool (from GDAL).
- Filter the digital elevation model for sinks (or depressions) and fill them. Use the
r.fill.dirfunction. - Calculate the flow direction and accumulation into each grid cell of the domain. Use the
r.watershedfunction. Make sure that D8 is used as flow direction algorithm. Further more, ensure that the minimum size of an exterior watershed basins is set to 500. Keep both the accumulation (i.e. how many cells drain into each cell) and the flow direction map as outputs.
- Check if the accumulation map aligns with the actual river network of the Zwalm catchment from the Vlaamse Hydrografische Atlas (see Section 3.1). In the attributes of the shapefile, you can filter in
"NAMEN"for"Zwalmbeek - Dorenbosbeek"to only withhold the main Zwalm river.
Use get_data_array_from_rasterto get the accumulation map as anxarray.DataArray. Usegeopandas.read_fileto read in the river network shapefile.
- Find the point with the largest accumulation that is located within the Zwalm river network. Rasterise the river network to the same grid as the accumulation map to do so. This point is the outlet of the catchment.
Use the make_geocubefunction from thegeocubepackage. Use thelikeargument.
Use the Rasterize (vector to raster)tool (from GDAL).
- Given the outlet determined in the previous step, delineate the catchment using
r.water.outlet. Vectorize the resulting raster map of the catchment.
Convert the output raster to an xarray.DataArrayusing a helper function. Subsequently, thevectorizefunction from thegeocubepackage can be applied.
Use the Polygonize (raster to vector)tool (from GDAL).
- Repeat step 7 for the coordinates provided in Tip 4.1. Compare the resulting catchment boundary with the one obtained in step 7 and with the provided catchment boundary from the Oppervlaktewaterlichamen en hun afstroomgebieden, 2022-2027 dataset (see Section 3.1). What are the differences between these catchment boundaries? What could be the reasons for these differences?
- Calculate the catchment area.
In your results and discussion below, make sure to include an overview figure of the Zwalm catchment including the DTM, river network and catchment boundary.