Merge Bathymetry with DEM data
merge-bathy-dem.Rmd
Lake bathymetry data is useful for a range of applications, including habitat mapping, water quality monitoring, and hydrodynamic modelling. However, lakes sit within a landscape, and it is often useful to know how the bathymetry data relates to the surrounding topography. This is particularly important for hydrodynamic modelling of lakes with large fluctuations in water level, or for flood risk assessments in the surrounding area.
This vignette demonstrates how to merge bathymetry data with a
Digital Elevation Model (DEM) raster using the
merge_bathy_dem()
function.
Load the data
We will use the bathytools package to merge bathymetry data with a DEM raster. The package includes example data for Lake Rotoma, New Zealand. The bathymetry data is stored as a XYZ data.frame in an .rds file within the package. Whereas the DEM data is stored as a raster in a TIF file. The DEM raster was prepared from LiDAR data provided by Land Information New Zealand and can be downloaded here.
We will also use a shapefile of the lake shoreline and a shapefile of the lake catchment. These were both sourced from the Freshwater Ecosytems of New Zealand database.
library(bathytools)
library(tmap) # Used for plotting spatial data
#> Breaking News: tmap 3.x is retiring. Please test v4, e.g. with
#> remotes::install_github('r-tmap/tmap')
shoreline <- readRDS(system.file("extdata/rotoma_shoreline.rds",
package = "bathytools"))
catchment <- readRDS(system.file("extdata/rotoma_catchment.rds",
package = "bathytools"))
The example lake we will be looking at is Lake Rotoma in the Bay of Plenty Region on the North Island of Aotearoa New Zealand. The lake is a popular recreational spot for fishing and boating.
The tmap package is used
to plot spatial data. The tmap_mode("view")
function is
used to display the map in the viewer pane in RStudio. The
tmap_options(basemaps = "Esri.WorldImagery")
function is
used to set the basemap to a satellite image. It is similar to the
ggplot2
package, but is specifically designed for spatial
data. Here we plot the lake shoreline in light blue and the lake
catchment in pink.
tmap_mode("view")
#> tmap mode set to interactive viewing
tmap_options(basemaps = "Esri.WorldImagery")
tm_shape(shoreline) +
tm_borders(col = "#8DA0CB", lwd = 2) +
tm_shape(catchment) +
tm_borders(col = "#E78AC3", lwd = 2)
The depth data is stored in XYZ format, with the x and y coordinates representing the location of the depth point, and the z coordinate representing the depth in meters. The depth data is stored as a data.frame in an .rds file within the package. Here we show the first few rows of the depth data.
point_data <- readRDS(system.file("extdata/depth_points.rds",
package = "bathytools"))
head(point_data)
#> lon lat depth
#> 1 176.5952 -38.03974 -3.88
#> 2 176.5853 -38.03590 -79.90
#> 3 176.5904 -38.03109 -63.30
#> 4 176.5960 -38.06580 -5.06
#> 5 176.5790 -38.03500 -38.51
#> 6 176.5691 -38.02957 -20.06
dem_raster <- terra::rast(system.file("extdata/dem_32m.tif",
package = "bathytools"))
tm_shape(dem_raster) +
tm_raster(alpha = 0.5, style = "cont", palette = "-YlGnBu") +
tm_shape(shoreline) +
tm_borders(col = "#FC8D62", lwd = 2) +
tm_shape(catchment) +
tm_borders(col = "#A6D854", lwd = 2)
Generate the bathymetry raster
The first step is to generate a bathymetry raster from the shoreline
and depth data. The rasterise_bathy()
function is used to
generate the bathymetry raster. The function takes the shoreline, depth
data, and the coordinate reference system (CRS) as inputs. The function
returns a SpatRaster
object representing the bathymetry
raster.
bathy_raster <- rasterise_bathy(shoreline = shoreline,
point_data = point_data, crs = 2193,
res = 8)
#> Generating depth points... [2024-11-13 23:09:49]
#> Finished! [2024-11-13 23:09:49]
#> Interpolating to raster... [2024-11-13 23:09:49]
#> Adjusting depths >= 0 to -0.82 m
#> Finished! [2024-11-13 23:09:50]
tm_shape(dem_raster) +
tm_raster(alpha = 0.5, style = "cont", palette = "-YlGnBu") +
tm_shape(bathy_raster) +
tm_raster(style = "cont", palette = "-viridis", breaks = seq(-90, 0, by = 10)) +
tm_shape(shoreline) +
tm_borders(col = "#FC8D62", lwd = 2) +
tm_shape(catchment) +
tm_borders(col = "#A6D854", lwd = 2)
Merge the bathymetry with the DEM
The next step is to merge the bathymetry raster with the DEM raster.
The merge_bathy_dem()
function is used to merge the
bathymetry raster with the DEM raster. The function takes the shoreline,
bathymetry raster, DEM raster, and catchment shapefile as inputs. The
function returns a SpatRaster
object representing the
merged bathymetry and DEM data.
If the resolution of the bathymetry raster is different from the DEM raster, the bathymetry raster will be resampled to match the resolution of the DEM raster.
dem_bath <- merge_bathy_dem(shoreline = shoreline, bathy_raster = bathy_raster,
dem_raster = dem_raster, catchment = catchment)
#> Warning: Resolutions of bathy_raster [8, 8] and dem_raster [32, 32] do notmatch. Resampling bathy_raster to match dem_raster
#> Lake surface elevation from DEM: 313.3 m
dem_bath
#> class : SpatRaster
#> dimensions : 217, 194, 1 (nrow, ncol, nlyr)
#> resolution : 32, 32 (x, y)
#> extent : 1911744, 1917952, 5779472, 5786416 (xmin, xmax, ymin, ymax)
#> coord. ref. : NZGD2000 / New Zealand Transverse Mercator 2000 (EPSG:2193)
#> source(s) : memory
#> varname : dem_32m
#> name : elevation
#> min value : 232.0779
#> max value : 599.1376
Spatial plot of the merged raster
Here we plot the merged raster with the lake and catchment boundaries.
tm_shape(dem_bath) +
tm_raster(alpha = 0.5, style = "cont", palette = "-YlGnBu") +
tm_shape(shoreline) +
tm_borders(col = "#FC8D62", lwd = 2) +
tm_shape(catchment) +
tm_borders(col = "#A6D854", lwd = 2)
The colours in this plot do not clearly distinguish between the
bathymetry and DEM data. We will add a break at the surface elevation of
the lake to better distinguish between the two datasets. We can extract
the water surface elevation from the DEM data using the
get_lake_surface_elevation()
function.
lake_elev <- get_lake_surface_elevation(dem_raster = dem_raster,
shoreline = shoreline)
#> Lake surface elevation from DEM: 313.3 m
We can now plot the merged raster with the lake surface elevation as the break in the colour palette.
tm_dem_bath(dem_bath = dem_bath, lake_elev = lake_elev)
Hypsograph of the merged raster
A hypsograph is a plot of the area of a lake at different depths. The
bathy_to_hypso()
function can be used to generate a
hypsograph from the bathymetry raster. The function takes the bathymetry
raster as input and returns a data frame with the depth and area at each
depth.
hyps <- bathy_to_hypso(bathy_raster = bathy_raster)
head(hyps)
#> depth area
#> 1 0 11240576
#> 2 -1 10494272
#> 3 -2 10215744
#> 4 -3 9997504
#> 5 -4 9797120
#> 6 -5 9604800
The hypsograph can be plotted to show the area of the lake at different depths.
3-D plot of the merged raster
The plot_raster_3d()
function can be used to create a
3-D plot of the merged raster. The function takes the merged raster and
the shoreline as inputs. The fact
argument controls the
aggregation factor for the raster. A higher factor will result in a
smoother plot, but will take longer to render.
p1 <- plot_raster_3d(x = dem_bath, shoreline = shoreline, split_lake = TRUE)
p1
Saving the merged raster
The merged raster can be saved to a file using the
terra::writeRaster()
function. The function takes the
raster object and the file path as inputs.
It is important to note that SpatRaster
can not be saved
as “.rds” files. They can also be quite large, so it is recommended to
save the raster in a compressed format, such as GeoTIFF.
terra::writeRaster(dem_bath, "dem_bath.tif", overwrite = TRUE)