Assignment 02
Runoff modelling
Deadline is 2021-12-20 11:59am
Late submission? 10% will be removed for each day that you are late.
You’re allowed for this assignment to work in a group of 2 (and thus submit only one solution for both of you). You are free to form a group yourself; if you’re looking for a partner let others know on Discord. If that doesn’t work out, let me know (Ken). If you prefer to work alone it’s also fine.
- Overview
- What you are given to start
- Help understanding the Metz et al. paper
- Data structure to use
- Tips
- Marking
- What to submit and how to submit it
Overview
The aim of this assignment is to implement basic runoff modelling based on the LCP algorithm, as described in the course book or in Section 2.1 of this paper (in much more detail), using a single flow direction (D8) on a grid DTM. In short, this will involve two steps:
- computing the flow direction;
- using the flow direction to compute the accumulated flow.
Everything should be implemented in Python or C++ (your choice). You are free to use any external modules you want, but only for reading/writing files and for handling matrices (to store rasters). If you’re using Python, we suggest rasterio (I/O) and numpy (matrices). If you’re using C++, we suggest GDAL (I/O) and handling matrices directly in your own code (eg using std::vector). You may also keep any external modules that you used for debugging or to visualise your results (eg matplotlib and seaborn for Python, matplotlib-cpp for C++).
What you are given to start
To encourage you to use C++, there’s a bit of code to help you in the /hw/02/
folder of the GitLab repository of the course. Feel free to use it (or not).
In addition, you should download an 30m SRTM tile of a region of your interest (eg your hometown or a hilly region of your country) through this website and use it for your assignment.
Help understanding the Metz et al. paper
The standard D8 method (as described in the lesson) defines the flow direction using the steepest downwards slope. This works fine in most areas, but it doesn’t give a good solution for flats or sinks.
The Metz et al. paper describes a method that is related to D8 but which solves both of these problems. It does this by visiting the cells in a very specific order, which is given by the priority queue. The priority is defined such that lower-elevation cells are visited first. If two cells have the same elevation, the cell that was added to the priority queue first is visited first.
As a result of the specific order, water is allowed to flow upstream in certain circumstances. A rough way to imagine it is that like in normal D8, the flow direction is set to the steepest downwards slope when possible. But when there are no neighbour cells with downwards slope, it sets the flow direction to the least steep upwards slope.
So, please make sure you add the cells to the priority queue exactly as described in the paper!
It’s not very clear in the paper, but the order in which you visit cells to compute the flow direction is the opposite order in which you should visit them to compute the flow accumulation.
Data structure to use
Part of implementing the LCP algorithm involves creating a priority queue. This is a data structure that has its elements sorted by priority. In this way, you can easily get the highest priority element to be processed by checking the first (or last) element in the queue.
If you’re using Python, we recommend you use heapq. If you’re using C++, we recommend you use std::priority_queue.
Tips
- The initial potential outlets should be all the pixels on the edges of the dataset (ie the top/bottom rows and the leftmost/rightmost columns).
- If there are very large large rivers/lakes/seas in the area, you might also want to mark all the cells neighbouring them (usually identifiable as large flat areas) as potential outlets. Hardcoding these (eg using a seeding point inside the area), or modifying the DEM to mark them is fine.
- You want to choose specific values that represent the 8 possible flow directions of a pixel (eg 10 for rightwards and 30 for downwards), as well as special values for pixels at the different stages of processing. Choose sensible values to make visualisation intuitive.
- We might test your code with other input. Let us know how to run it.
- rasterio allows you to clone a dataset’s properties using the profile dictionary, while the same applies to GDAL’s CreateCopy. This is very handy when you want to create a new raster with similar properties as an existing one. That being said, you might want to create a new raster in GDAL instead and only copy some properties of the original (eg CRS).
- Make sure that the raster data type you choose is able to fit the values that you want to store in it.
- You should have no loops in the flow directions raster. If you do, you’re doing something wrong.
- If you’re having performance problems, you may crop your input DEM. However, there will be a penalty if your code can only work with tiny datasets.
- The SRTM data is lat-long, but that doesn’t matter for LCP.
Marking
Criterion | Points |
---|---|
followed all rules and compiles/runs without modifications | 1 |
implementation of LCP algorithm | 3 |
implementation of flow accumulation | 3 |
quality of your results (submitted rasters) | 3 |
What to submit and how to submit it
You have to submit a ZIP file (or another compressed format) with:
- All files of your source code.
- The DEM of the area you chose (SRTM tile, cropped and with outlets marked if necessary).
- 2 raster files with the flow direction and flow accumulation for the DEM you chose (generated using your code).
- A text file with the names of your group members and instructions on how to run/edit your code (eg what are the command line parameters or which source code files/lines I should edit). Not mandatory, but I’d appreciate it if you also told me why you chose a particular region :-)
Submit your files by uploading them here.
[last updated: 2021-11-20 03:37]