hyd1d is an R package that provides an S4-class and several functions to compute 1-dimensional water levels along the German federal waterways Elbe and Rhine.
The package hyd1d is available from CRAN. To install it run:
To install the recent developmental version from Github execute the following commands:
Afterwards hyd1d can be loaded like every other R package with the following command:
All water level computations with hyd1d are based on
the S4-class WaterLevelDataFrame
.
To compute water levels with one of the waterLevel…()
-functions,
a WaterLevelDataFrame
has to be initialized with the homonymous
WaterLevelDataFrame()
-function:
wldf <- WaterLevelDataFrame(river = "Elbe",
time = as.POSIXct("2016-12-21"),
station = seq(257, 262, 0.1))
The required information to initialize a WaterLevelDataFrame
are the function arguments river
, time
and at
least one of the two possible station arguments (station
or
station_int
). With this information an object of class
WaterLevelDataFrame
can be created, which has the following structure:
str(wldf)
#> 'data.frame': 51 obs. of 3 variables:
#> Formal class 'WaterLevelDataFrame' [package "hyd1d"] with 9 slots
#> ..@ .Data :List of 3
#> .. ..$ : num 257 257 257 257 257 ...
#> .. ..$ : int 257000 257100 257200 257300 257400 257500 257600 257700 257800 257900 ...
#> .. ..$ : num NA NA NA NA NA NA NA NA NA NA ...
#> ..@ river : chr "Elbe"
#> ..@ time : POSIXct, format: "2016-12-21"
#> ..@ gauging_stations :'data.frame': 0 obs. of 27 variables:
#> .. ..$ id : int
#> .. ..$ gauging_station : chr
#> .. ..$ uuid : chr
#> .. ..$ km : num
#> .. ..$ km_qps : num
#> .. ..$ river : chr
#> .. ..$ longitude : num
#> .. ..$ latitude : num
#> .. ..$ mw : num
#> .. ..$ mw_timespan : chr
#> .. ..$ pnp : num
#> .. ..$ w : num
#> .. ..$ wl : num
#> .. ..$ n_wls_below_w_do : int
#> .. ..$ n_wls_above_w_do : int
#> .. ..$ n_wls_below_w_up : int
#> .. ..$ n_wls_above_w_up : int
#> .. ..$ name_wl_below_w_do: chr
#> .. ..$ name_wl_above_w_do: chr
#> .. ..$ name_wl_below_w_up: chr
#> .. ..$ name_wl_above_w_up: chr
#> .. ..$ w_wl_below_w_do : num
#> .. ..$ w_wl_above_w_do : num
#> .. ..$ w_wl_below_w_up : num
#> .. ..$ w_wl_above_w_up : num
#> .. ..$ weight_up : num
#> .. ..$ weight_do : num
#> ..@ gauging_stations_missing: chr NA
#> ..@ comment : chr "Initialised by WaterLevelDataFrame()."
#> ..@ names : chr "station" "station_int" "w"
#> ..@ row.names : int 1 2 3 4 5 6 7 8 9 10 ...
#> ..@ .S3Class : chr "data.frame"
summary(wldf)
#> $slots
#>
#> river Elbe
#> time 2016-12-21
#> gauging_stations None
#> gauging_stations_missing None
#> comment Initialised by WaterLevelDataFrame().
#>
#> $data
#> station station_int w
#> Min. :257.0 Min. :257000 Min. : NA
#> 1st Qu.:258.2 1st Qu.:258250 1st Qu.: NA
#> Median :259.5 Median :259500 Median : NA
#> Mean :259.5 Mean :259500 Mean :NaN
#> 3rd Qu.:260.8 3rd Qu.:260750 3rd Qu.: NA
#> Max. :262.0 Max. :262000 Max. : NA
#> NA's :51
The actual water level information is stored in the S4-slot
.Data
, which is in fact a data.frame
with the
columns station
, station_int
and
w
. The columns station
and
station_int
contain a stationing information, which
corresponds to the official stationing of the German Waterways and
Shipping Administration (Wasserstraßen- und Schifffahrtsverwaltung
(WSV)). The stationing information is duplicated to enable database
joins with GIS data through the integer
-type column
station_int
. The column w
contains the actual
water level in the height reference system DHHN92 (1992 German height
reference system), but is usually empty after initialization and gets
filled throught the application of one of the waterLevel…()
-functions.
For the application of waterLevel…()
-functions
information stored in the S4-slots river
and where
appropriate time
is essential. They enable a distinct
localization of the stationing along the rivers Elbe and Rhine and a
determination of the time of water level computation. The other slots of
an object of class WaterLevelDataFrame
are filled during the water level computation and contain partial
results needed to visualize the results (gauging_station
)
or serve information purposes ( gauging_stations_missing
,
comment
).
The most advanced function to interpolate FLYS3
water levels (Bundesanstalt für
Gewässerkunde, 2013, 2016)
with local gauging data is implemented in the
waterLevel()
-function. This function uses package-internal
gauging data from the dataset df.gauging_data
,
which contains daily-averaged gauging data since 1960-01-01. Therefore
waterLevel()
can be applied for the time period between
1960-01-01 and yesterday.
After the initialization of a
WaterLevelDataFrame
the application is very simple:
wldf <- waterLevel(wldf)
summary(wldf)
#> $slots
#>
#> river Elbe
#> time 2016-12-21
#> gauging_stations VOCKERODE, ROSSLAU, DESSAU, AKEN
#> gauging_stations_missing None
#> comment Computed by waterLevel().
#>
#> $data
#> station station_int w
#> Min. :257.0 Min. :257000 Min. :54.42
#> 1st Qu.:258.2 1st Qu.:258250 1st Qu.:54.67
#> Median :259.5 Median :259500 Median :54.82
#> Mean :259.5 Mean :259500 Mean :54.87
#> 3rd Qu.:260.8 3rd Qu.:260750 3rd Qu.:55.11
#> Max. :262.0 Max. :262000 Max. :55.35
And if you want to visualize the results using
plotShiny()
the additional argument
shiny = TRUE
has to be used. Thereby the columns
section
, weight_x
and weight_y
get created in the .Data
-Slot, which are required for
visualization.
wldf <- waterLevel(wldf, shiny = TRUE)
summary(wldf)
#> $slots
#>
#> river Elbe
#> time 2016-12-21
#> gauging_stations VOCKERODE, ROSSLAU, DESSAU, AKEN
#> gauging_stations_missing None
#> comment Computed by waterLevel().
#>
#> $data
#> station station_int w section
#> Min. :257.0 Min. :257000 Min. :54.42 Min. :1.00
#> 1st Qu.:258.2 1st Qu.:258250 1st Qu.:54.67 1st Qu.:2.00
#> Median :259.5 Median :259500 Median :54.82 Median :2.00
#> Mean :259.5 Mean :259500 Mean :54.87 Mean :2.02
#> 3rd Qu.:260.8 3rd Qu.:260750 3rd Qu.:55.11 3rd Qu.:2.00
#> Max. :262.0 Max. :262000 Max. :55.35 Max. :3.00
#> weight_x weight_y
#> Min. :0.008197 Min. :0.1000
#> 1st Qu.:0.161765 1st Qu.:0.1911
#> Median :0.529412 Median :0.2640
#> Mean :0.520204 Mean :0.3192
#> 3rd Qu.:0.897059 3rd Qu.:0.4294
#> Max. :1.000000 Max. :0.6302
xlim_min <- 257
xlim_max <- 263
{
plotShiny(wldf, TRUE, TRUE, TRUE, xlim = c(xlim_min, xlim_max),
xlab = "river station (km)",
ylab = "elevation (m a.s.l. (DHHN92))")
legend("topright",
col = c("darkblue", "darkblue", "darkblue", "red", "black"),
pch = c(21, NA, NA, NA, NA),
pt.bg = c("darkblue", NA, NA, NA, NA),
pt.cex = c(1, NA, NA, NA, NA),
lty = c(0, 0, 1, 1, 1),
lwd = c(0, 0, 1, 0.6, 0.6),
legend = c("gauge height", "gauge weight", "waterLevel",
"upper FLYS w.l.", "lower FLYS w.l."),
text.col = c(1, "darkblue", 1, 1, 1),
cex = 0.7, bty = "n")
}
The way how the waterLevelPegelonline()
-function
computes a water level is equivalent to the
waterLevel()
-function. Just the data source of the gauging
data is different, since it does not use package-internal data, but
online data provided by https://pegelonline.wsv.de/gast/start (Wasserstraßen- und
Schifffahrtsverwaltung des Bundes (WSV), 2022). Because data
provided by PEGELONLINE are only
available for the past 30 days, the application of this function is
limited to recent time periods, but with a high temporal resolution.
# one hour ago
time <- as.POSIXct(Sys.time() - 3600)
# initialize a WaterLevelDataFrame
wldf <- WaterLevelDataFrame(river = "Elbe",
time = time,
station = seq(257, 262, 0.1))
# compute w
wldf <- waterLevelPegelonline(wldf, shiny = TRUE)
summary(wldf)
#> $slots
#>
#> river Elbe
#> time 2024-11-04 04:20:16.242203
#> gauging_stations VOCKERODE, ROSSLAU, DESSAU, AKEN
#> gauging_stations_missing None
#> comment Computed by waterLevelPegelonline().
#>
#> $data
#> station station_int w section
#> Min. :257.0 Min. :257000 Min. :54.59 Min. :1.00
#> 1st Qu.:258.2 1st Qu.:258250 1st Qu.:54.85 1st Qu.:2.00
#> Median :259.5 Median :259500 Median :55.06 Median :2.00
#> Mean :259.5 Mean :259500 Mean :55.11 Mean :2.02
#> 3rd Qu.:260.8 3rd Qu.:260750 3rd Qu.:55.40 3rd Qu.:2.00
#> Max. :262.0 Max. :262000 Max. :55.68 Max. :3.00
#> weight_x weight_y
#> Min. :0.008197 Min. :0.3615
#> 1st Qu.:0.161765 1st Qu.:0.4354
#> Median :0.529412 Median :0.6404
#> Mean :0.520204 Mean :0.6421
#> 3rd Qu.:0.897059 3rd Qu.:0.8454
#> Max. :1.000000 Max. :0.9192
# and plot the results
{
plotShiny(wldf, TRUE, TRUE, TRUE, xlim = c(xlim_min, xlim_max),
xlab = "river station (km)",
ylab = "elevation (m a.s.l. (DHHN92))")
legend("topright",
col = c("darkblue", "darkblue", "darkblue", "red", "black"),
pch = c(21, NA, NA, NA, NA),
pt.bg = c("darkblue", NA, NA, NA, NA),
pt.cex = c(1, NA, NA, NA, NA),
lty = c(0, 0, 1, 1, 1),
lwd = c(0, 0, 1, 0.6, 0.6),
legend = c("gauge height", "gauge weight", "waterLevel",
"upper FLYS w.l.", "lower FLYS w.l."),
text.col = c(1, "darkblue", 1, 1, 1),
cex = 0.7, bty = "n")
}
To compare the newly developed functions waterLevel()
and waterLevelPegelonline()
to existing computation
methods, the functions waterLevelFlood1()
and
waterLevelFlood2()
have been implemented. These functions
compute water levels according to the Flood1- and Flood2-methods of the
modelling environment INFORM
(Rosenzweig, Giebel, & Schleuter,
2011). They either shift the reference water level
MQ vertically, so that it intersects with the gauge
height at a selected reference gauging station, or linearly interpolate
water levels with neighboring gauging stations.
wldf <- WaterLevelDataFrame(river = "Elbe",
time = as.POSIXct("2016-12-21"),
station = seq(257, 262, 0.1))
wldf1 <- waterLevelFlood1(wldf, "ROSSLAU", shiny = TRUE)
summary(wldf1)
#> $slots
#>
#> river Elbe
#> time 2016-12-21
#> gauging_stations ROSSLAU
#> gauging_stations_missing None
#> comment Computed by waterLevelFlood1(): gauging_station = ROSSLAU, w = 137
#>
#> $data
#> station station_int w section weight_x
#> Min. :257.0 Min. :257000 Min. :54.15 Min. :1 Min. :1
#> 1st Qu.:258.2 1st Qu.:258250 1st Qu.:54.44 1st Qu.:1 1st Qu.:1
#> Median :259.5 Median :259500 Median :54.68 Median :1 Median :1
#> Mean :259.5 Mean :259500 Mean :54.73 Mean :1 Mean :1
#> 3rd Qu.:260.8 3rd Qu.:260750 3rd Qu.:55.05 3rd Qu.:1 3rd Qu.:1
#> Max. :262.0 Max. :262000 Max. :55.36 Max. :1 Max. :1
#> weight_y
#> Min. :-0.92
#> 1st Qu.:-0.92
#> Median :-0.92
#> Mean :-0.92
#> 3rd Qu.:-0.92
#> Max. :-0.92
wldf2 <- waterLevelFlood1(wldf, "DESSAU", shiny = TRUE)
summary(wldf2)
#> $slots
#>
#> river Elbe
#> time 2016-12-21
#> gauging_stations DESSAU
#> gauging_stations_missing None
#> comment Computed by waterLevelFlood1(): gauging_station = DESSAU, w = 165
#>
#> $data
#> station station_int w section weight_x
#> Min. :257.0 Min. :257000 Min. :54.43 Min. :1 Min. :1
#> 1st Qu.:258.2 1st Qu.:258250 1st Qu.:54.72 1st Qu.:1 1st Qu.:1
#> Median :259.5 Median :259500 Median :54.96 Median :1 Median :1
#> Mean :259.5 Mean :259500 Mean :55.01 Mean :1 Mean :1
#> 3rd Qu.:260.8 3rd Qu.:260750 3rd Qu.:55.33 3rd Qu.:1 3rd Qu.:1
#> Max. :262.0 Max. :262000 Max. :55.64 Max. :1 Max. :1
#> weight_y
#> Min. :-0.64
#> 1st Qu.:-0.64
#> Median :-0.64
#> Mean :-0.64
#> 3rd Qu.:-0.64
#> Max. :-0.64
wldf3 <- waterLevelFlood2(wldf)
summary(wldf3)
#> $slots
#>
#> river Elbe
#> time 2016-12-21
#> gauging_stations VOCKERODE, ROSSLAU, DESSAU, AKEN
#> gauging_stations_missing None
#> comment Computed by waterLevelFlood2()
#>
#> $data
#> station station_int w
#> Min. :257.0 Min. :257000 Min. :54.43
#> 1st Qu.:258.2 1st Qu.:258250 1st Qu.:54.68
#> Median :259.5 Median :259500 Median :54.90
#> Mean :259.5 Mean :259500 Mean :54.90
#> 3rd Qu.:260.8 3rd Qu.:260750 3rd Qu.:55.12
#> Max. :262.0 Max. :262000 Max. :55.35
To compare the newly developed functions waterLevel()
and waterLevelPegelonline
to existing computation methods of FLYS3,
the function waterLevelFlys3InterpolateY()
has been
implemented. This function computes a water level according to the
method implemented in the W-INFO-module of FLYS3.
This function determines the relative position of the gauge height at a
reference gauge to the two surrounding FLYS3
water levels and uses this weight for a longitudinal interpolation
between both water levels.
wldf <- waterLevelFlys3InterpolateY(wldf, "ROSSLAU", shiny = TRUE)
summary(wldf)
#> $slots
#>
#> river Elbe
#> time 2016-12-21
#> gauging_stations ROSSLAU
#> gauging_stations_missing None
#> comment Computed by waterLevelFlys3InterpolateY(): gauging_station = ROSSLAU, w = 137
#>
#> $data
#> station station_int w section weight_x
#> Min. :257.0 Min. :257000 Min. :54.11 Min. :1 Min. :1
#> 1st Qu.:258.2 1st Qu.:258250 1st Qu.:54.42 1st Qu.:1 1st Qu.:1
#> Median :259.5 Median :259500 Median :54.67 Median :1 Median :1
#> Mean :259.5 Mean :259500 Mean :54.72 Mean :1 Mean :1
#> 3rd Qu.:260.8 3rd Qu.:260750 3rd Qu.:55.08 3rd Qu.:1 3rd Qu.:1
#> Max. :262.0 Max. :262000 Max. :55.35 Max. :1 Max. :1
#> weight_y
#> Min. :0.1786
#> 1st Qu.:0.1786
#> Median :0.1786
#> Mean :0.1786
#> 3rd Qu.:0.1786
#> Max. :0.1786
All other waterLevelFlys3...()
-functions
(waterLevelFlys3()
, waterLevelFlys3Seq()
and
waterLevelFlys3InterpolateX()
) serve exclusively for the
preparation and querying of stationary FLYS3
water levels. They can be used to extract water levels from the dataset
df.flys
and interpolate the water levels linearly along the x-axis, but without
modifying the dataset contents. These functionalities are needed for
all waterLevel…()
-functions
described in this vignette and are mentioned here for completeness.
The waterLevel()
function is the central function of the
package hyd1d. To apply it only three input parameters,
that are needed to initialize a WaterLevelDataFrame
,
are required. That predestines this function to embed it into an
interactive Shiny Application:
https://shiny.bafg.de/waterlevel/
The same is true for the function waterLevelPegelonline()
.
Since this function queries gauging data through the internet and not
from package-internal datasets, the resulting shiny application is well
suited to generate up-to-date water level information.
https://shiny.bafg.de/waterlevelpegelonline/
The R package hydflood enables the modelling of flood extents and durations through an extrapolation of water levels computed along the river axis with functions provided within R package hyd1d to cross section areas and GIS operations comparing these water levels to digital elevation models. Daily flood extents can be aggregated over longer time periods to flood durations (e.g. days/year). More details to this method can be found on the corresponding package documentation of hydflood: