Static topographic analysis
This page contains the documentation of the main functions related to the static analysis.
TrapStructure
The TrapStructure
contains all the fundamental results from running spillanalysis
. This includes the identified traps, their volumes, footprints, how they are connected, and the associated watersheds and spill point locations. TrapStructure
also contains the spillfield (how flow is directed between gridcells), as well as a copy of the topography, buildings and sinks that went into the analysis.
SurfaceWaterIntegratedModeling.TrapStructure
— Typestruct TrapStructure{T<:Real}
A struct representing a watershed drainage trap for topographical analysis.
Fieldnames
topography::Matrix{T}
: raster grid of terrain height values.spillfield::Matrix{Int8}
: local direction of streamline (seespillfield
)regions::Matrix{Int}
: raster grid with region numbers (seespillregions
)spillpoints::Vector{Spillpoint}
: vector with spill point information per trap (seespillpoints
)trapvolumes::Vector{T}
: computed trap volumes (seetrapvolumes
)subvolumes::Vector{T}
: the part of each trap's volume that is fully contained within its subtrapsfootprints::Vector{Vector{Int}}
: one entry per trap, listing the (linear) indices of all its cellslowest_subtraps_for::Vector{Vector{Int}}
: one entry per trap, listing all its lowest-level subtrapssupertraps_of::Vector{Vector{Int}}
: one entry per lowest-level trap, listing all the supertraps it belongs to (including itself).agglomerations::Graphs.SimpleDiGraph
: hierarchy of sub/supertraps, presented as a graph structurebuilding_mask::Union{Matrix{Bool}, Nothing}
: building mask (0: terrain, 1: building)sinks::Union{Vector{Tuple{Int, Int}}, Nothing}
: list of sinks, in term of grid cell coordinates
SurfaceWaterIntegratedModeling.numregions
— Methodnumregions(tstruct)
Returns the number of regions identified in the TrapStructure
tstruct
. The number of regions is identical to the number of lowest-level traps.
SurfaceWaterIntegratedModeling.numtraps
— Methodnumtraps(tstruct)
Returns the number of traps identified in the TrapStructure
tstruct
. This includes the lowest-level traps as well as all higher-level traps.
SurfaceWaterIntegratedModeling.parentof
— Methodparentof(tstruct, trap_ix)
Given a TrapStructure
tstruct, returns the index of the parent trap (immediate higher-level trap) of the trap indexed trap_ix
. If this trap does not have a parent trap, nothing is returned.
SurfaceWaterIntegratedModeling.subtrapsof
— Methodsubtrapsof(tstruct, trap_ix)
Given a TrapStructure
tstruct, returns the indices to the immediate subtraps of the trap indexed trap_ix
. This is usually zero or two, but can be higher than two in degenerate cases.
Spill analysis
The function spillanalysis
runs a complete analysis on a provided terrain grid and associated buildings and sinks, and returns a TrapStructure
as output. This is the central function for static topographic analysis in SWIM.
SurfaceWaterIntegratedModeling.spillanalysis
— Methodspillanalysis(grid, usediags=true, building_mask=nothing, sinks=nothing,
lengths=nothing, domain=nothing, merge_outregions=false,
verbose=false)
Analyse a terrain and compute all key information regarding its trap structure.
This information includes the spillfield, all the spill regions, traps with their volumes, spillpoints and footprints, the upstream/downstream trap hierarchy, and the supertrap/subtrap hierarchy.
All computed information is returned as a TrapStructure
. Refer to its documentation for details.
Arguments
grid::Matrix{<:Real}
: topograpical grid to analyseusediags::Bool
: if true, also consider slopes along diagonalsbuilding_mask::Union{Matrix{<:Bool}, BitMatrix, Nothing}
: if present, provides a mask that specifies the footprint of buildings. These parts of the domain will be clipped away.sinks::Union{Vector{Tuple{Int, Int}}, Matrix{Bool}, Nothing}
: vector containing (i, j) grid coordinates of any point sinks in the grid, if any. Can also be a Matrix{Bool} of same size asgrid
, indicating the sink locations.lengths::Union{Tuple{<:Real}, Nothing}
: tuple expressing the length and width of the grid (used to compute aspect ratios)domain::Union{Domain2D, Nothing}
: restrict computation to the specified domain of the grid. @@ Note that this is not fully supported yet for this function.merge_outregions::Bool
: iftrue
, all "outside" regions will be merged and represented as region -1. Otherwise, each "outside" region will be represented by its own negative integer.verbose::Bool
: iftrue
, print information showing progress in the computation along the way.
See also TrapStructure
, fill_sequence
.
Lower-level functions
The functions listed below are used by the spillanalysis
function. They can however also be run independently.
Spillfield
The spillfield
function computes the basic gravity-driven flow pattern on a terrain. For each cell, it determines the direction of flow and the correpsonding neighbor downstream cell, using either a 4-element or 8-element stencil.
SurfaceWaterIntegratedModeling._spillfield!
— Method_spillfield!(dir, slope, grid, usediags=true, lengths=nothing)
Mutating version of spillfield. The results 'dir' and 'slope' are not returned, but passed as arguments. See documentation of 'spillfield' for a general description. A key difference in the mutating version is that the results (dir and slope) retain the full size of the grid, even though only a subdomain is addressed. (In the non-mutating version, the returned grids are limited to the size of the addressed subdomain.)
SurfaceWaterIntegratedModeling.hconcat_spillfields
— Methodhconcat_spillfields(dir1, slope1, grid1, dir2, slope2, grid2, usediags=true,
lengths=nothing)
Concatenate two spill fields along the 'horizontal' direction (adding columns).
In addition to the spill fields dir1
and dir2
to concatenate, the corresponding slopes and original terrain grids are also given (slope1
, slope2
, grid1
, grid2
). These are used to re-compute the spill directions for gridcells on the 'seam' between the two spill fields.
The function returns the combined spill field (corresponding to [dir1, dir2]
), as well as the associated slopes (corresponding to [slope1, slope2]
)
Arguments
dir1::Matrix{Int8}
: first spill fieldslope1::Matrix{<:Real}
: matrix with local slopes for first spill fieldgrid1::Matrix{<:Real}
: topography grid from whichdir1
was computeddir2::Matrix{Int8}
: second spill fieldslope2::Matrix{<:Real}
: matrix with local slopes for second spill fieldgrid2::Matrix{<:Real}
: topography grid from whichdir2
was computedusediags::Bool
: if true, also consider slopes along diagonalslengths::Union{Tuple{<:Real}, Nothing}
: tuple expressing the length and width of the combined grid (used to compute aspect ratios)
See also spillfield
, vconcat_spillfields
.
SurfaceWaterIntegratedModeling.spillfield
— Methodspillfield(grid, usediags=true, lengths=nothing, domain=nothing,
tiling=nothing, building_mask=nothing)
Compute the spillfield of a raster terrain, represented by grid
.
The spillfield is returned an integer array of same shape as grid
, to be interpreted as follows:
- -3 : sink (any passing streamline is terminated here)
- -2 : covered by building / clipped away
- -1 : no downward slope (gridcell is a trap)
- 0 : steepest slope towards (i-1, j)
- 1 : steepest slope towards (i+1, j)
- 2 : steepest slope towards (i, j-1)
- 3 : steepest slope towards (i, j+1)
- 4 : steepest slope towards (i-1, j-1)
- 5 : steepest slope towards (i+1, j+1)
- 6 : steepest slope towards (i+1, j-1)
- 7 : steepest slope towards (i-1, j+1)
Trap bottoms, i.e. cells for which there exists no downward slope, are given the value -1.
In addition, a matrix with the value of the steepest slope in each point is returned as a second argument.
Arguments
grid::Matrix{<:Real}
: terrain raster grid with height valuesusediags::Bool
: if true, also consider slopes along diagonalsbuilding_mask::Union{Matrix{Bool}, BitMatrix, Nothing}
: a grid of logicals, specifying which cells are masked by buildings (true), and thus inactive. These cells will be assigned a spill field value of -2 (see list above).sinks::Union{Vector{Tuple{Int, Int}}, Nothing}
: vector containing (i, j) grid coordinates of any point sinks in the grid, if anylengths::Union{Tuple{<:Real}, Nothing}
: tuple expressing the length and width of the grid (used to compute aspect ratios)domain::Union{Domain2D, Nothing}
: restrict computation to the specified domain of the gridtiling::Union{Tuple{Int, Int}, Nothing}
: tuple specifying number of 'tiles' to subdivide surface in for parallel processing. Default is (1,1), which means the whole surface is treated as a single tile (no parallel processing).
See also update_spillfield!
.
SurfaceWaterIntegratedModeling.update_spillfield!
— Methodupdate_spillfield!(dir, slope, grid, domain, usediags=true, lengths=nothing)
Update an existing spill field in-place within a specific rectangular domain (where the topography grid has presumably changed).
Arguments
dir::Matrix{Int}
: the spillfield, as described in the documentation of thespillfield
function. Will be updated within the specified domain.slope::Array{<:Real}
: the steepest slope in each grid point, as returned by thespillfield
function. Will be updated within the specified domain.grid::Matrix{<:Real}
: terrain raster grid with height values. This grid has presumably already been changed within the specified domain.domain::Domain2D
: the domain in which to update the information indir
andslope
usediags::Bool=true
: if true, also consider slopes along diagonalslengths::Union{Tuple{<:Real}, Nothing}
: tuple expressing the length and width of the grid (used to compute aspect ratios)building_mask::Union{Matrix{Bool}, Nothing}
: a grid of logicals, specifying which cells are masked by buildings (true), and thus inactive. These cells will be assigned a spill field value of -2 (see list of possible fieldvalues in documentation ofspillfield
.)sinks::Vector{Union{Tuple{Int, Int}, Nothing}}
: vector containing (i, j) grid coordinates of any point sinks in the grid, if any.
See also spillfield
.
SurfaceWaterIntegratedModeling.vconcat_spillfields
— Methodvconcat_spillfields(dir1, slope1, grid1, dir2, slope2, grid2, usediags=true,
lengths=nothing)
Concatenate two spill fields along the 'vertical' direction (adding rows).
In addition to the spill fields dir1
and dir2
to concatenate, the corresponding slopes and original terrain grids are also given (slope1
, slope2
, grid1
, grid2
). These are used to re-compute the spill directions for gridcells on the 'seam' between the two spill fields.
The function returns the combined spill field (corresponding to [dir1; dir2]
), as well as the associated slopes (corresponding to [slope1; slope2]
)
Arguments
dir1::Matrix{Int8}
: first spill fieldslope1::Matrix{<:Real}
: matrix with local slopes for first spill fieldgrid1::Matrix{<:Real}
: topography grid from whichdir1
was computeddir2::Matrix{Int8}
: second spill fieldslope2::Matrix{<:Real}
: matrix with local slopes for second spill fieldgrid2::Matrix{<:Real}
: topography grid from whichdir2
was computedusediags::Bool
: if true, also consider slopes along diagonalslengths::Union{Tuple{<:Real}, Nothing}
: tuple expressing the length and width of the combined grid (used to compute aspect ratios)
See also spillfield
, hconcat_spillfields
.
Spillregions
For a given spillfield (as computed by the spillfield
function), the spillregions
function separates the terain into individual watersheds, each associated with a local minimum in the terrain surface.
SurfaceWaterIntegratedModeling.spillregions
— Methodspillregions(spillfield)
Identify all spill regions to be derived from a given spillfield
.
A spill region is a group of cells that flow into the same trap (here: the lowest-level traps).
Returns a Matrix{Int} of the same shape as spillfield
, where all cells with the same integer value belong to the same spill region. Spill regions that exit the domain are assigned negative region numbers.
Arguments
spillfield::Matrix{Int}
: the matrix containing the spillfield already computed from thespillfield
function.usediags
: iftrue
, diagonal connections between cells will also be consideredtiling::Union{Tuple{Int, Int}, Nothing}
: tuple specifying number of 'tiles' to subdivide surface in for parallel processing. Default is (1,1), which means the whole surface is treated as a single tile (no parallel processing).
See also spillfield
, update_spillregions!
.
SurfaceWaterIntegratedModeling.update_spillregions!
— Methodupdate_spillregions!(regions, spillfield, domain; usediags=true,
return_region_reindex=false)
Update a previously computed spillregion field inside a limited domain (where the spillfield has presumably changed).
Arguments
regions::Matrix{Int}
: the previously computed spillregion fieldspillfield::Matrix{Int8}
: the locally updated spill fielddomain::Domain2D
: domain within which the spillfield has changed, and thus regions need to be updatedusediags{Bool}
: iftrue
, diagonal connections between cells will also be considered- `returnregionreindex{Bool}' : compute and return correspondence between old and new region indices as a 2-column matrix, first column represents old region numbers and second column the new ones. Note that there may be both one-to-one, one-to-many and many-to-one correspondences.
See also spillregions
.
Spillpoints
The Spillpoint
struct contains the information for a particular spill point, i.e. the point where a trap/lake spills over. Spillpoint
contains the index of the downstream region, the location of the spillpoint itself, as well as its vertical elevation.
The spillpoints
function is used to compute all the spillpoints associated with a set of spill regions (which has been previously computed using spillregions
).
SurfaceWaterIntegratedModeling.Spillpoint
— Typestruct Spillpoint
A struct representing the spillpoint of a trap. It has the following fields:
downstream_region::Int
: index of the downstream region.current_region_cell::Int
: index of the cell in the current region bordering on the spillpointdownstream_region_cell::Int
: index of the cell in the downstream region bordering on the spillpointelevation::Real
: the elevation (vertical height) of the spillpoint
SurfaceWaterIntegratedModeling.Spillpoint
— MethodDefault constructor of a Spillpoint instance sets all indices to zero and elevation to infinity.
SurfaceWaterIntegratedModeling.spillpoints
— Methodspillpoints(grid, spillregions, usediags)
Compute the spillpoint positions for each (low-level) spill region in the grid.
Also computes the topology of the lowest-level spill network (the graph describing the upstream/downstream relationship between spill regions).
Returns a vector of Spillpoint
with one entry per spill region (numbered from 1 upwards. Each Spillpoint
contains information on downstream spill region index, cell indices for the cell in the current region and downstream region that border on the spill point, and the heigh volume of the spill point.
In addition, returns a vector of 'boundaries', one per spill point. The boundary for spill region 'i' is defined by all the cell pairs (i, j) such that cell 'i', and 'j' are neighbors, cell 'i' is in spill region 'i', and cell 'j' is in a different spill region 'j'.
Arguments
grid::Matrix{<:Real}
- the terrain grid (matrix) with height valuesspillregions::Matrix{Int}
: the matrix containing the regions already computed from thespillregions
functionusediags::Bool
: iftrue
(default), diagonal connections between cells will also be consideredtiling::Union{Tuple{Int, Int}, Nothing}
: tuple specifying number of 'tiles' to subdivide surface in for parallel processing. Default is (1,1), which means the whole surface is treated as a single tile (no parallel processing).
See also Spillpoint
.
Subtrap-supertrap hierarchy
The sshierarchy!
identifies higher-level traps from a set of subtraps. In other words, it identifies those traps that emerges when smaller traps coalesce as they fill up. It requires the output of spillregions
and spillpoints
as part of it input.
SurfaceWaterIntegratedModeling.sshierarchy!
— Methodsshierarchy!(grid, spillregions, spillpoints, boundaries)
Identify higher-level traps and spillpoints, resulting from merger of lower-level traps that flow into each other.
The vector of spillpoints, and the associated spillregion boundaries will be updated with the higher-level spillpoints and traps.
The arguments grid
and spillregions
will remain unmodified.
The function also returns a graph representing the hierarchy of subtraps and supertraps, and a vector listing the indices of the lowest-level spillregions contained within each trap. For lowest-level traps, this list only references the trap itself, whereas for higher-level traps, it references all the low-level traps whose merger leads to the higher-level trap.
Arguments
grid::Matrix{<:Real}
: terrain raster grid with height values. This input argument remains unmodified.spillregions::Matrix{Int}
: the matrix containing the lowest-level regions, already computed from thespillregions
function. This input argument remains unmodified.spillpoints::Vector{Spillpoint}
: vector of lowest-level spillpoints (corresponding to the lowest-level regions), as computed by thespillpoints
function. This vector will be modified, as it will be supplemented with the newly identified, higher-level spillpoints.boundaries::Vector{Vector{Tuple{Int, Int}}}
: vector containing the boundaries for each of the lowest-level spill regions. This vector will be modified, as it will be extended with the boundaries of the newly found higher-level spill regions. Each boundary is represented by a vector of integer pairs, where each integer pair are the indices of two neighbor cells in the grid; one on each side of the region boundary.
Trap volumes
The function [trapvolumes
][@ref] is used to compute the volumes of all traps and subtraps identified on an analysed surface. It requires the result of spillregions
and spillpoints
as input parameters.
SurfaceWaterIntegratedModeling.trapvolumes
— Methodtrapvolumes(grid, spillregions, spillpoints, lowest_regions)
Compute the volume of all traps (at all levels) identified for a topography grid.
The necessary input to this function can be provided by spillregions
, spillpoints
and sshierarchy!
. The result is returned in form of a vector of floating point numbers, with one entry per trap, giving the volume of that trap.
Arguments
- `grid::Matrix{<:Real}`: the topographical grid that has been analysed
- `spillregions::Matrix{Int}`: of same size as `grid`, where the integer at entry
(i, j) gives the region number of cell (i, j) in `grid`.
- `spillpoints::Vector{Spillpoint}`: vector with the identified spillpoints, as
provided by the [`spillpoints`](@ref) function.
There is one spillpoint per trap.
- `lowest_regions::Vector{Vector{Int}}`: each entry in this vector corresponds to
a trap, and list all the low-level regions
that combined constitute the spill region
of this trap.
See also spillregions
, spillpoints
and sshierarchy!
.
Domain
The Domain2D
struct represent a rectangular subpart of a terrain grid. It is mainly used to specify subsets of a terrain that should be updated or processed in parallel.
SurfaceWaterIntegratedModeling.Domain2D
— Typestruct Domain2D
Type representing a Cartesian (sub)domain of a grid, defined by all gridcells indexed (ix, iy) such that ix ∈ xrange and iy ∈ yrange.
Fields
xrange::UnitRange{Int}
: range of domain in the first coordinate directionyrange::UnitRange{Int}
: range of domain in the second coordinate direction
Base.max
— Methodmax(d::Domain2D, dir::Int)
Return maximum value of 2D domain d
, in first or second direction
Base.min
— Methodmin(d::Domain2D, dir::Int)
Return minimum value of 2D domain d
, in first or second direction
Base.size
— Methodsize(d::Domain2D)
Return size of 2D domain d
SurfaceWaterIntegratedModeling.tiledomain
— Methodtiledomain(dom, tilenum_x, tilenum_y)
Divide a given domain up into a cartesian grid of subdomains ('tiles')
The domain 'dom' is split up into a grid of domains, with 'tilenum_x' number of domain in the first coordinate direction, and 'tilenum_y number of domains in the second.
Returns a Vector{Domain2D} with all the resulting subdomains. A second return argument gives a tuple of integer vectors specifying where the splits happened in the first and second coordinate directions.
See also Domain2D
SurfaceWaterIntegratedModeling.tiles
— Methodtiles(xsplit::Vector{Int}, ysplit::Vector{Int})
Divide a domain up into a cartesian grid of subdomains ('tiles')
The vectors xsplit
and ysplit
should be monotonously increasing integer vectors that specify where to split an underlying 2D region into subdomains.
The function will return a vector of Domain2D
that tile the domain. If xsplit
is of length Nx and ysplit
of length Ny, the number of tiles generated will be (Nx-1) x (Ny-1).