diff --git a/CITATION.cff b/CITATION.cff
index 5625ca1b..c901d9d2 100644
--- a/CITATION.cff
+++ b/CITATION.cff
@@ -8,7 +8,7 @@ message: 'To cite package "getRad" in publications use:'
type: software
license: MIT
title: 'getRad: Download Radar Data for Biological Research'
-version: 0.2.4
+version: 0.2.4.9000
doi: 10.32614/CRAN.package.getRad
abstract: Load polar volume and vertical profile data for aeroecological research
directly into R. With 'getRad' you can access data from several sources in Europe
@@ -45,4 +45,477 @@ keywords:
- r-package
- radar
- rstats
+references:
+- type: software
+ title: 'R: A Language and Environment for Statistical Computing'
+ notes: Depends
+ url: https://www.R-project.org/
+ authors:
+ - name: R Core Team
+ institution:
+ name: R Foundation for Statistical Computing
+ address: Vienna, Austria
+ year: '2026'
+ version: '>= 4.1.0'
+- type: software
+ title: bioRad
+ abstract: 'bioRad: Biological Analysis and Visualization of Weather Radar Data'
+ notes: Imports
+ url: https://github.com/adokter/bioRad/
+ repository: https://CRAN.R-project.org/package=bioRad
+ authors:
+ - family-names: Dokter
+ given-names: Adriaan M.
+ email: biorad@cornell.edu
+ orcid: https://orcid.org/0000-0001-6573-066X
+ - family-names: Desmet
+ given-names: Peter
+ email: peter.desmet@inbo.be
+ orcid: https://orcid.org/0000-0002-8442-8025
+ - family-names: Kranstauber
+ given-names: Bart
+ email: b.kranstauber@uva.nl
+ orcid: https://orcid.org/0000-0001-8303-780X
+ - family-names: Nilsson
+ given-names: Cecilia
+ email: cecilia.nilsson709@gmail.com
+ orcid: https://orcid.org/0000-0001-8957-4411
+ - family-names: Tedeschi
+ given-names: Alexander
+ email: alexander.tedeschi@cornell.edu
+ orcid: https://orcid.org/0000-0003-0772-6931
+ - family-names: Van Hoey
+ given-names: Stijn
+ email: stijnvanhoey@gmail.com
+ orcid: https://orcid.org/0000-0001-6413-3185
+ year: '2026'
+ doi: 10.32614/CRAN.package.bioRad
+- type: software
+ title: cachem
+ abstract: 'cachem: Cache R Objects with Automatic Pruning'
+ notes: Imports
+ url: https://cachem.r-lib.org/
+ repository: https://CRAN.R-project.org/package=cachem
+ authors:
+ - family-names: Chang
+ given-names: Winston
+ email: winston@posit.co
+ year: '2026'
+ doi: 10.32614/CRAN.package.cachem
+- type: software
+ title: cli
+ abstract: 'cli: Helpers for Developing Command Line Interfaces'
+ notes: Imports
+ url: https://cli.r-lib.org
+ repository: https://CRAN.R-project.org/package=cli
+ authors:
+ - family-names: Csárdi
+ given-names: Gábor
+ email: gabor@posit.co
+ year: '2026'
+ doi: 10.32614/CRAN.package.cli
+- type: software
+ title: dplyr
+ abstract: 'dplyr: A Grammar of Data Manipulation'
+ notes: Imports
+ url: https://dplyr.tidyverse.org
+ repository: https://CRAN.R-project.org/package=dplyr
+ authors:
+ - family-names: Wickham
+ given-names: Hadley
+ email: hadley@posit.co
+ orcid: https://orcid.org/0000-0003-4757-117X
+ - family-names: François
+ given-names: Romain
+ orcid: https://orcid.org/0000-0002-2444-4226
+ - family-names: Henry
+ given-names: Lionel
+ - family-names: Müller
+ given-names: Kirill
+ orcid: https://orcid.org/0000-0002-1416-3412
+ - family-names: Vaughan
+ given-names: Davis
+ email: davis@posit.co
+ orcid: https://orcid.org/0000-0003-4777-038X
+ year: '2026'
+ doi: 10.32614/CRAN.package.dplyr
+ version: '>= 1.1.0'
+- type: software
+ title: glue
+ abstract: 'glue: Interpreted String Literals'
+ notes: Imports
+ url: https://glue.tidyverse.org/
+ repository: https://CRAN.R-project.org/package=glue
+ authors:
+ - family-names: Hester
+ given-names: Jim
+ orcid: https://orcid.org/0000-0002-2739-7082
+ - family-names: Bryan
+ given-names: Jennifer
+ email: jenny@posit.co
+ orcid: https://orcid.org/0000-0002-6983-2759
+ year: '2026'
+ doi: 10.32614/CRAN.package.glue
+- type: software
+ title: httr2
+ abstract: 'httr2: Perform HTTP Requests and Process the Responses'
+ notes: Imports
+ url: https://httr2.r-lib.org
+ repository: https://CRAN.R-project.org/package=httr2
+ authors:
+ - family-names: Wickham
+ given-names: Hadley
+ email: hadley@posit.co
+ year: '2026'
+ doi: 10.32614/CRAN.package.httr2
+ version: '>= 1.1.1'
+- type: software
+ title: lubridate
+ abstract: 'lubridate: Make Dealing with Dates a Little Easier'
+ notes: Imports
+ url: https://lubridate.tidyverse.org
+ repository: https://CRAN.R-project.org/package=lubridate
+ authors:
+ - family-names: Spinu
+ given-names: Vitalie
+ email: spinuvit@gmail.com
+ - family-names: Grolemund
+ given-names: Garrett
+ - family-names: Wickham
+ given-names: Hadley
+ year: '2026'
+ doi: 10.32614/CRAN.package.lubridate
+- type: software
+ title: purrr
+ abstract: 'purrr: Functional Programming Tools'
+ notes: Imports
+ url: https://purrr.tidyverse.org/
+ repository: https://CRAN.R-project.org/package=purrr
+ authors:
+ - family-names: Wickham
+ given-names: Hadley
+ email: hadley@posit.co
+ orcid: https://orcid.org/0000-0003-4757-117X
+ - family-names: Henry
+ given-names: Lionel
+ email: lionel@posit.co
+ year: '2026'
+ doi: 10.32614/CRAN.package.purrr
+ version: '>= 1.0.0'
+- type: software
+ title: rlang
+ abstract: 'rlang: Functions for Base Types and Core R and ''Tidyverse'' Features'
+ notes: Imports
+ url: https://rlang.r-lib.org
+ repository: https://CRAN.R-project.org/package=rlang
+ authors:
+ - family-names: Henry
+ given-names: Lionel
+ email: lionel@posit.co
+ - family-names: Wickham
+ given-names: Hadley
+ email: hadley@posit.co
+ year: '2026'
+ doi: 10.32614/CRAN.package.rlang
+- type: software
+ title: tibble
+ abstract: 'tibble: Simple Data Frames'
+ notes: Imports
+ url: https://tibble.tidyverse.org/
+ repository: https://CRAN.R-project.org/package=tibble
+ authors:
+ - family-names: Müller
+ given-names: Kirill
+ email: kirill@cynkra.com
+ orcid: https://orcid.org/0000-0002-1416-3412
+ - family-names: Wickham
+ given-names: Hadley
+ email: hadley@rstudio.com
+ year: '2026'
+ doi: 10.32614/CRAN.package.tibble
+- type: software
+ title: tools
+ abstract: 'R: A Language and Environment for Statistical Computing'
+ notes: Imports
+ authors:
+ - name: R Core Team
+ institution:
+ name: R Foundation for Statistical Computing
+ address: Vienna, Austria
+ year: '2026'
+- type: software
+ title: utils
+ abstract: 'R: A Language and Environment for Statistical Computing'
+ notes: Imports
+ authors:
+ - name: R Core Team
+ institution:
+ name: R Foundation for Statistical Computing
+ address: Vienna, Austria
+ year: '2026'
+- type: software
+ title: vroom
+ abstract: 'vroom: Read and Write Rectangular Text Data Quickly'
+ notes: Imports
+ url: https://vroom.tidyverse.org
+ repository: https://CRAN.R-project.org/package=vroom
+ authors:
+ - family-names: Hester
+ given-names: Jim
+ orcid: https://orcid.org/0000-0002-2739-7082
+ - family-names: Wickham
+ given-names: Hadley
+ email: hadley@posit.co
+ orcid: https://orcid.org/0000-0003-4757-117X
+ - family-names: Bryan
+ given-names: Jennifer
+ email: jenny@posit.co
+ orcid: https://orcid.org/0000-0002-6983-2759
+ year: '2026'
+ doi: 10.32614/CRAN.package.vroom
+- type: software
+ title: withr
+ abstract: 'withr: Run Code ''With'' Temporarily Modified Global State'
+ notes: Imports
+ url: https://withr.r-lib.org
+ repository: https://CRAN.R-project.org/package=withr
+ authors:
+ - family-names: Hester
+ given-names: Jim
+ - family-names: Henry
+ given-names: Lionel
+ email: lionel@posit.co
+ - family-names: Müller
+ given-names: Kirill
+ email: krlmlr+r@mailbox.org
+ - family-names: Ushey
+ given-names: Kevin
+ email: kevinushey@gmail.com
+ - family-names: Wickham
+ given-names: Hadley
+ email: hadley@posit.co
+ - family-names: Chang
+ given-names: Winston
+ year: '2026'
+ doi: 10.32614/CRAN.package.withr
+- type: software
+ title: xml2
+ abstract: 'xml2: Parse XML'
+ notes: Imports
+ url: https://xml2.r-lib.org
+ repository: https://CRAN.R-project.org/package=xml2
+ authors:
+ - family-names: Wickham
+ given-names: Hadley
+ - family-names: Hester
+ given-names: Jim
+ - family-names: Ooms
+ given-names: Jeroen
+ email: jeroenooms@gmail.com
+ year: '2026'
+ doi: 10.32614/CRAN.package.xml2
+- type: software
+ title: askpass
+ abstract: 'askpass: Password Entry Utilities for R, Git, and SSH'
+ notes: Suggests
+ url: https://r-lib.r-universe.dev/askpass
+ repository: https://CRAN.R-project.org/package=askpass
+ authors:
+ - family-names: Ooms
+ given-names: Jeroen
+ email: jeroenooms@gmail.com
+ orcid: https://orcid.org/0000-0002-4035-0289
+ year: '2026'
+ doi: 10.32614/CRAN.package.askpass
+- type: software
+ title: htmltools
+ abstract: 'htmltools: Tools for HTML'
+ notes: Suggests
+ url: https://rstudio.github.io/htmltools/
+ repository: https://CRAN.R-project.org/package=htmltools
+ authors:
+ - family-names: Cheng
+ given-names: Joe
+ email: joe@posit.co
+ - family-names: Sievert
+ given-names: Carson
+ email: carson@posit.co
+ orcid: https://orcid.org/0000-0002-4958-2844
+ - family-names: Schloerke
+ given-names: Barret
+ email: barret@posit.co
+ orcid: https://orcid.org/0000-0001-9986-114X
+ - family-names: Chang
+ given-names: Winston
+ email: winston@posit.co
+ orcid: https://orcid.org/0000-0002-1576-2126
+ - family-names: Xie
+ given-names: Yihui
+ email: yihui@posit.co
+ - family-names: Allen
+ given-names: Jeff
+ year: '2026'
+ doi: 10.32614/CRAN.package.htmltools
+- type: software
+ title: keyring
+ abstract: 'keyring: Access the System Credential Store from R'
+ notes: Suggests
+ url: https://keyring.r-lib.org/
+ repository: https://CRAN.R-project.org/package=keyring
+ authors:
+ - family-names: Csárdi
+ given-names: Gábor
+ email: csardi.gabor@gmail.com
+ year: '2026'
+ doi: 10.32614/CRAN.package.keyring
+- type: software
+ title: knitr
+ abstract: 'knitr: A General-Purpose Package for Dynamic Report Generation in R'
+ notes: Suggests
+ url: https://yihui.org/knitr/
+ repository: https://CRAN.R-project.org/package=knitr
+ authors:
+ - family-names: Xie
+ given-names: Yihui
+ email: xie@yihui.name
+ orcid: https://orcid.org/0000-0003-0645-5666
+ year: '2026'
+ doi: 10.32614/CRAN.package.knitr
+- type: software
+ title: leaflet
+ abstract: 'leaflet: Create Interactive Web Maps with the JavaScript ''Leaflet''
+ Library'
+ notes: Suggests
+ url: https://rstudio.github.io/leaflet/
+ repository: https://CRAN.R-project.org/package=leaflet
+ authors:
+ - family-names: Cheng
+ given-names: Joe
+ email: joe@posit.co
+ - family-names: Schloerke
+ given-names: Barret
+ email: barret@posit.co
+ orcid: https://orcid.org/0000-0001-9986-114X
+ - family-names: Karambelkar
+ given-names: Bhaskar
+ - family-names: Xie
+ given-names: Yihui
+ - family-names: Aden-Buie
+ given-names: Garrick
+ email: garrick@posit.co
+ orcid: https://orcid.org/0000-0002-7111-0077
+ year: '2026'
+ doi: 10.32614/CRAN.package.leaflet
+- type: software
+ title: rhdf5
+ abstract: 'rhdf5: R Interface to HDF5'
+ notes: Suggests
+ url: https://github.com/Huber-group-EMBL/rhdf5
+ repository: https://bioconductor.org/
+ authors:
+ - family-names: Fischer
+ given-names: Bernd
+ - family-names: Smith
+ given-names: Mike
+ email: mike.smith@embl.de
+ orcid: https://orcid.org/0000-0002-7800-3848
+ - family-names: Pau
+ given-names: Gregoire
+ year: '2026'
+ doi: 10.18129/B9.bioc.rhdf5
+- type: software
+ title: rnaturalearth
+ abstract: 'rnaturalearth: World Map Data from Natural Earth'
+ notes: Suggests
+ url: https://docs.ropensci.org/rnaturalearth/
+ repository: https://CRAN.R-project.org/package=rnaturalearth
+ authors:
+ - family-names: Massicotte
+ given-names: Philippe
+ email: pmassicotte@hotmail.com
+ orcid: https://orcid.org/0000-0002-5919-4116
+ - family-names: South
+ given-names: Andy
+ email: southandy@gmail.com
+ year: '2026'
+ doi: 10.32614/CRAN.package.rnaturalearth
+- type: software
+ title: rnaturalearthdata
+ abstract: 'rnaturalearthdata: World Vector Map Data from Natural Earth Used in ''rnaturalearth'''
+ notes: Suggests
+ url: https://docs.ropensci.org/rnaturalearthdata/
+ repository: https://CRAN.R-project.org/package=rnaturalearthdata
+ authors:
+ - family-names: South
+ given-names: Andy
+ email: southandy@gmail.com
+ orcid: https://orcid.org/0000-0003-4051-6135
+ - family-names: Michael
+ given-names: Schramm
+ email: mpschramm@gmail.com
+ - family-names: Massicotte
+ given-names: Philippe
+ email: pmassicotte@hotmail.com
+ orcid: https://orcid.org/0000-0002-5919-4116
+ year: '2026'
+ doi: 10.32614/CRAN.package.rnaturalearthdata
+- type: software
+ title: sf
+ abstract: 'sf: Simple Features for R'
+ notes: Suggests
+ url: https://r-spatial.github.io/sf/
+ repository: https://CRAN.R-project.org/package=sf
+ authors:
+ - family-names: Pebesma
+ given-names: Edzer
+ email: edzer.pebesma@uni-muenster.de
+ orcid: https://orcid.org/0000-0001-8049-7069
+ year: '2026'
+ doi: 10.32614/CRAN.package.sf
+- type: software
+ title: testthat
+ abstract: 'testthat: Unit Testing for R'
+ notes: Suggests
+ url: https://testthat.r-lib.org
+ repository: https://CRAN.R-project.org/package=testthat
+ authors:
+ - family-names: Wickham
+ given-names: Hadley
+ email: hadley@posit.co
+ year: '2026'
+ doi: 10.32614/CRAN.package.testthat
+ version: '>= 3.0.0'
+- type: software
+ title: tidyr
+ abstract: 'tidyr: Tidy Messy Data'
+ notes: Suggests
+ url: https://tidyr.tidyverse.org
+ repository: https://CRAN.R-project.org/package=tidyr
+ authors:
+ - family-names: Wickham
+ given-names: Hadley
+ email: hadley@posit.co
+ - family-names: Vaughan
+ given-names: Davis
+ email: davis@posit.co
+ - family-names: Girlich
+ given-names: Maximilian
+ year: '2026'
+ doi: 10.32614/CRAN.package.tidyr
+- type: software
+ title: vol2birdR
+ abstract: 'vol2birdR: Vertical Profiles of Biological Signals in Weather Radar Data'
+ notes: Suggests
+ url: https://github.com/adokter/vol2birdR/
+ repository: https://CRAN.R-project.org/package=vol2birdR
+ authors:
+ - family-names: Henja
+ given-names: Anders
+ email: anders.henja@gmail.com
+ - family-names: Dokter
+ given-names: Adriaan M.
+ email: vol2birdr@cornell.edu
+ orcid: https://orcid.org/0000-0001-6573-066X
+ year: '2026'
+ doi: 10.32614/CRAN.package.vol2birdR
diff --git a/DESCRIPTION b/DESCRIPTION
index c025fd2d..23b3d96f 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -65,8 +65,8 @@ VignetteBuilder:
Config/testthat/edition: 3
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
-RoxygenNote: 7.3.2
Config/Needs/website:
rmarkdown,
leafpop,
htmltools
+Config/roxygen2/version: 8.0.0
diff --git a/NAMESPACE b/NAMESPACE
index 365c657c..46be60d9 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -8,3 +8,4 @@ export(get_weather_radars)
export(set_secret)
importFrom(dplyr,.data)
importFrom(lubridate,"%within%")
+importFrom(rlang,.env)
diff --git a/NEWS.md b/NEWS.md
index 4e051dda..628027f4 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,7 +1,12 @@
# getRad (development version)
+* Implement download of `vpts` data from birdcast by Alexander Tedeschi.
* Implement reading `vpts` data from a local directory (#135).
* Clarify HTTP 429 error for the Netherlands (#165).
+* Clarify error for Estonia and propagate call (#173).
+* Include the hochficht radar in Austria (#169).
+* For Romania match deviating file format (thanks to Sorin Burcea, #167).
+* Fix download for Czechia as multiple scans were found (#183).
# getRad 0.2.4
diff --git a/R/getRad-package.R b/R/getRad-package.R
index 0c6cd517..7036fb97 100644
--- a/R/getRad-package.R
+++ b/R/getRad-package.R
@@ -3,6 +3,7 @@
## usethis namespace: start
#' @importFrom dplyr .data
+#' @importFrom rlang .env
#' @importFrom lubridate %within%
## usethis namespace: end
NULL
diff --git a/R/get_pvol.R b/R/get_pvol.R
index 95091f0a..132a64f1 100644
--- a/R/get_pvol.R
+++ b/R/get_pvol.R
@@ -38,7 +38,9 @@
#' as.POSIXct(Sys.Date())
#' )
get_pvol <- function(radar = NULL, datetime = NULL, ...) {
- check_odim_nexrad(radar)
+ if (!identical(radar, "hochficht")) {
+ check_odim_nexrad(setdiff(radar, 'hochficht'))
+ }
if (anyDuplicated(radar)) {
cli::cli_abort(
"{.arg radar} contains duplications that must be removed.",
@@ -129,9 +131,13 @@ get_pvol <- function(radar = NULL, datetime = NULL, ...) {
# Helper function to find the function for a specific radar
# This function is only helpful in get_pvol and therefor not in a utils file
select_get_pvol_function <- function(radar, ..., call = rlang::caller_env()) {
+ if (radar == "hochficht") {
+ return("get_pvol_hochficht")
+ }
if (is_nexrad(radar)) {
return("get_pvol_us")
}
+
cntry_code <- substr(radar, 1, 2) # nolint
fun <- (dplyr::case_when(
cntry_code == "nl" ~ "get_pvol_nl",
diff --git a/R/get_pvol_at.R b/R/get_pvol_at.R
new file mode 100644
index 00000000..287371d0
--- /dev/null
+++ b/R/get_pvol_at.R
@@ -0,0 +1,29 @@
+get_pvol_hochficht <- function(radar, time, ..., call = rlang::caller_env()) {
+ url <- glue::glue(
+ getOption(
+ "getRad.at_hochficht_url",
+ default = "https://public.hub.geosphere.at/datahub/resources/radar_volumen_hochficht-v1-5min/filelisting/WXRHOF_{strftime(time,'%Y%m%d%H%M', tz='UTC')}.hdf"
+ )
+ )
+ pvol <- withr::with_tempfile("file", fileext = ".h5", {
+ tryCatch(
+ req <-
+ httr2::request(url) |>
+ req_user_agent_getrad() |>
+ httr2::req_perform(path = file, error_call = call),
+ httr2_http_403 = function(cnd) {
+ cli::cli_abort(
+ c(
+ "There is data found for download.",
+ "i" = "Data for the Hochficht radar is only available for the last three days."
+ ),
+ cnd = cnd,
+ class = "getRad_error_get_pvol_at_no_data",
+ call = call
+ )
+ }
+ )
+ bioRad::read_pvolfile(file, ...)
+ })
+ return(pvol)
+}
diff --git a/R/get_pvol_cz.R b/R/get_pvol_cz.R
index f050fafe..ab696631 100644
--- a/R/get_pvol_cz.R
+++ b/R/get_pvol_cz.R
@@ -1,7 +1,7 @@
# http://opendata.chmi.cz/meteorology/weather/radar/sites/ska/vol_z/hdf5/
get_pvol_cz <- function(radar, time, ..., call = rlang::caller_env()) {
- time_chr <- time_pos <- base <- resp <- NULL
+ time_chr <- time_pos <- base <- NULL
# All parameters are retrieved from separate files
# Here all urls are generated
params <- c("z", "u", "v", "w", "zdr", "rhohv", "phidp")
@@ -37,10 +37,55 @@ get_pvol_cz <- function(radar, time, ..., call = rlang::caller_env()) {
time,
time + lubridate::minutes(5)
)
- ))
- pvol <- read_pvol_from_url_per_param(paste0(
- files_to_get$base,
- files_to_get$file
+ )) |>
+ dplyr::mutate(url = paste0(base, file))
+ # There are sometimes multiple pvols, generally one with 12 scans
+ # additionally there are (sometimes) scans in separate files for
+ # the 0.3 and 1.5 elevation angle. These are not always both present.
+ # It all seems a bit irregular
+ pvols <- lapply(
+ split(files_to_get$url, files_to_get$time_chr),
+ read_pvol_from_url_per_param
+ )
+ if (length(pvols) == 1) {
+ return(pvols[[1]])
+ }
+ attr <- purrr::map(pvols, purrr::pluck, "attributes") |>
+ purrr::map(purrr::assign_in, where = c("what", "time"), purrr::zap()) |>
+ purrr::map(purrr::assign_in, where = c("what", "date"), purrr::zap()) |>
+ purrr::map(purrr::assign_in, where = c("how", "scan_count"), purrr::zap())
+ if (!all(unlist(lapply(attr[-1], identical, attr[[1]])))) {
+ cli::cli_abort(
+ c(
+ "The attributes of the polar volumes about to be merged differ"
+ ),
+ class = "getRad_error_czechia_attributes_differ",
+ call = call
+ )
+ }
+ pvol <- purrr::pluck(pvols, 1)
+ pvol$scans <- purrr::list_flatten(purrr::map(pvols, "scans"))
+ pvol$attributes$how$scan_count <- length(pvol$scans)
+ pvol$datetime <- max(purrr::map_vec(pvols, "datetime"))
+ pvol$attributes$what$time <- max(purrr::map_vec(
+ pvols,
+ c("attributes", "what", "time")
+ ))
+ pvol$attributes$what$date <- max(purrr::map_vec(
+ pvols,
+ c("attributes", "what", "date")
))
- pvol
+ if (anyDuplicated(get_elevation_angles(pvol))) {
+ # Note that if scanning pattern changes this might flag false positive, but
+ # currently the check is there to prevent falsely merging scans from two iterations
+ # of the scanning pattern
+ cli::cli_abort(
+ c(
+ "There are duplicated elevation angles, likely as a result of merging the wrong scans."
+ ),
+ class = "getRad_error_czechia_duplicated_elevation_angles",
+ call = call
+ )
+ }
+ return(pvol)
}
diff --git a/R/get_pvol_ee.R b/R/get_pvol_ee.R
index 5414404c..a62a1664 100644
--- a/R/get_pvol_ee.R
+++ b/R/get_pvol_ee.R
@@ -71,8 +71,9 @@ get_pvol_ee <- function(radar, time, ..., call = rlang::caller_env()) {
httr2::resp_body_json()
if (files$numFound == 0 || length(files$documents) != 1) {
cli::cli_abort(
- "The expected number of files is not found.",
- class = "getRad_error_get_pvol_ee_differing_n_files"
+ "The expected number of files is not found for this Estonian Radar. This can occur when no data is available.",
+ class = "getRad_error_get_pvol_ee_differing_n_files",
+ call = call
)
}
pvol <- withr::with_tempfile("file", fileext = ".h5", {
diff --git a/R/get_pvol_ro.R b/R/get_pvol_ro.R
index bc52ff81..6a7d0e63 100644
--- a/R/get_pvol_ro.R
+++ b/R/get_pvol_ro.R
@@ -3,5 +3,19 @@ get_pvol_ro <- function(radar, time, ..., call = rlang::caller_env()) {
urls <- glue::glue(
"https://opendata.meteoromania.ro/radar/{toupper(substr(radar,3,5))}/{toupper(substr(radar,3,5))}_{strftime(time,'%Y%m%d%H%M', tz='UTC')}0200{params}.hdf"
)
- read_pvol_from_url_per_param(urls, param = "all", call = call)
+ tryCatch(
+ read_pvol_from_url_per_param(urls, param = "all", call = call),
+ error = function(cnd) {
+ urls_updated <- glue::glue(
+ "https://opendata.meteoromania.ro/radar/{toupper(substr(radar,3,5))}/{toupper(substr(radar,3,5))}_{strftime(time,'%Y%m%d%H%M', tz='UTC')}0300{params}.hdf"
+ )
+ if (
+ rlang::has_name(cnd, "parent") && inherits(cnd$parent, "httr2_http_404")
+ ) {
+ read_pvol_from_url_per_param(urls_updated, param = "all", call = call)
+ } else {
+ return(cnd)
+ }
+ }
+ )
}
diff --git a/R/get_vpts.R b/R/get_vpts.R
index 9b3826c0..6fc3707d 100644
--- a/R/get_vpts.R
+++ b/R/get_vpts.R
@@ -34,8 +34,8 @@
#' - A vector of datetimes or dates, between which all data files are
#' downloaded.
#' - A [lubridate::interval()], between which all data files are downloaded.
-#' @param source Source of the data. One of `"baltrad"`, `"uva"`, `"ecog-04003"`
-#' or `"rmi"`. Only one source can be queried at a time. If not provided,
+#' @param source Source of the data. One of `"baltrad"`, `"uva"`, `"ecog-04003"`,
+#' `"rmi"`, or `"birdcast"`. Only one source can be queried at a time. If not provided,
#' `"baltrad"` is used. Alternatively a local directory can be specified,
#' see details for an explanation of the file format.
#' @param return_type Type of object that should be returned. Either:
@@ -77,10 +77,12 @@
#' source = "baltrad",
#' return_type = "tibble"
#' )
+#' #' Get VPTS data from the public BirdCast NEXRAD archive
+#' get_vpts(radar = "KABR", datetime = "2023-01-01", source = "birdcast")
get_vpts <- function(
radar,
datetime,
- source = c("baltrad", "uva", "ecog-04003", "rmi"),
+ source = c("baltrad", "uva", "ecog-04003", "rmi", "birdcast"),
return_type = c("vpts", "tibble")
) {
# Input checks ----
@@ -205,14 +207,19 @@ get_vpts <- function(
# Query the selected radars ----
# Directing to the correct get_vpts_* helper based on source.
cl <- rlang::caller_env(0)
+
+ aloft_sources <- eval(formals("get_vpts_aloft")$source)
+
+ source_type <- dplyr::case_when(
+ source == "rmi" ~ "rmi",
+ source == "birdcast" ~ "birdcast",
+ source %in% aloft_sources ~ "aloft",
+ dir.exists(source) ~ "local"
+ )
+
fetched_vpts <-
switch(
- dplyr::case_when(
- source == "rmi" ~ "rmi",
- source %in% eval(formals("get_vpts_aloft")$source) ~ "aloft",
- # this is the last option to avoid using a local source if an online exists
- dir.exists(source) ~ "local"
- ),
+ source_type,
rmi = purrr::map(
radar,
~ get_vpts_rmi(.x, rounded_interval),
@@ -227,6 +234,14 @@ get_vpts <- function(
),
.purrr_error_call = cl
),
+ birdcast = purrr::map(
+ radar,
+ ~ get_vpts_birdcast(
+ .x,
+ rounded_interval = rounded_interval
+ ),
+ .purrr_error_call = cl
+ ),
local = get_vpts_local(radar, rounded_interval, directory = source)
) |>
radar_to_name()
diff --git a/R/get_vpts_aloft.R b/R/get_vpts_aloft.R
index 29a51b5a..b41fc839 100644
--- a/R/get_vpts_aloft.R
+++ b/R/get_vpts_aloft.R
@@ -25,12 +25,14 @@
#' @param coverage A data frame containing the coverage of the Aloft bucket.
#' If not provided, it will be fetched from via the internet.
#' @return A tibble with VPTS data.
-#' @keywords internal
+#' @noRd
get_vpts_aloft <- function(
radar_odim_code,
rounded_interval,
source = c("baltrad", "uva", "ecog-04003"),
- coverage = get_vpts_coverage_aloft()
+ coverage = get_vpts_coverage_aloft(),
+ ...,
+ call = rlang::caller_env()
) {
# rename source argument for readability
selected_source <- source
@@ -45,7 +47,8 @@ get_vpts_aloft <- function(
"Can't find radar {.val {missing_radar}} in the coverage file (see
{.fun get_vpts_coverage}).",
missing_radar = missing_radar,
- class = "getRad_error_aloft_radar_not_found"
+ class = "getRad_error_aloft_radar_not_found",
+ call = call
)
}
@@ -61,7 +64,8 @@ get_vpts_aloft <- function(
if (!at_least_one_radar_date_combination_exists) {
cli::cli_abort(
"Can't find any data for the requested radar(s) and date(s).",
- class = "getRad_error_date_not_found"
+ class = "getRad_error_date_not_found",
+ call = call
)
}
@@ -79,7 +83,8 @@ get_vpts_aloft <- function(
cli::cli_abort(
"Can't find radar{?s} {.val {missing_radars}} in the coverage file (see
{.fun get_vpts_coverage}).",
- class = "getRad_error_radar_not_found"
+ class = "getRad_error_radar_not_found",
+ call = call
)
}
diff --git a/R/get_vpts_birdcast.R b/R/get_vpts_birdcast.R
new file mode 100644
index 00000000..4cf428dd
--- /dev/null
+++ b/R/get_vpts_birdcast.R
@@ -0,0 +1,95 @@
+#' Get VPTS data from the public BirdCast NEXRAD archive
+#'
+#' Gets VPTS data from the public BirdCast NEXRAD archive.
+#'
+#' @details
+#' By default, data are retrieved from the public BirdCast S3 archive at
+#' `https://birdcastdata.s3.amazonaws.com/nexrad/daily`.
+#'
+#' The expected path format is:
+#' `"{radar}/{year}/{radar}_vpts_{year}{month}{day}.csv"`.
+#'
+#' @section Inner working:
+#' - Checks that the requested radar is present in the NEXRAD coverage file.
+#' - Checks that data exist for the requested radar/date combination.
+#' - Constructs the S3 paths for the daily VPTS files from the coverage file.
+#' - Performs parallel HTTP requests to fetch the VPTS CSV data.
+#' - Parses the response bodies with the shared VPTS column classes.
+#' - Uses uppercase NEXRAD radar codes for archive paths.
+#' - Adds a column with the radar source.
+#'
+#' @param radar NEXRAD radar code.
+#' @param rounded_interval Interval to fetch data for, rounded to nearest day.
+#' @param coverage A data frame containing the coverage of the BirdCast NEXRAD
+#' archive. If not provided, it will be fetched via the internet.
+#' @param ... Used to prevent accidentally using the `call` argument
+#' @param call A call used for error messaging.
+#' @return A tibble with VPTS data.
+#' @noRd
+get_vpts_birdcast <- function(
+ radar,
+ rounded_interval,
+ coverage = get_vpts_coverage_birdcast(),
+ ...,
+ call = rlang::caller_env()
+) {
+ radar <- toupper(radar)
+
+ # Check that only one radar is provided.
+ check_odim_nexrad_scalar(radar)
+
+ # Check if the requested radar is present in the coverage.
+ if (!all(radar %in% coverage$radar)) {
+ missing_radar <- radar[!radar %in% coverage$radar]
+
+ cli::cli_abort(
+ "Can't find radar {.val {missing_radar}} in the birdcast coverage file
+ (see {.fun get_vpts_coverage}).",
+ missing_radar = missing_radar,
+ class = "getRad_error_birdcast_radar_not_found",
+ call = call
+ )
+ }
+
+ # Check if the requested radar/date combination is present in the coverage.
+ filtered_coverage <- dplyr::filter(
+ coverage,
+ .data$radar %in% .env$radar,
+ .data$date %within% rounded_interval
+ )
+
+ if (nrow(filtered_coverage) == 0) {
+ cli::cli_abort(
+ "Can't find any data for the requested radar(s) and date(s).",
+ class = "getRad_error_date_not_found",
+ call = call
+ )
+ }
+
+ # Convert the selected coverage rows into paths on the BirdCast NEXRAD archive.
+ s3_paths <- filtered_coverage |>
+ dplyr::mutate(
+ path = glue::glue(
+ "{radar}/{year}/{radar}_vpts_{year}{month}{day}.csv",
+ radar = .data$radar,
+ year = lubridate::year(.data$date),
+ month = sprintf("%02d", lubridate::month(.data$date)),
+ day = sprintf("%02d", lubridate::day(.data$date))
+ )
+ ) |>
+ dplyr::pull(.data$path)
+
+ # Read the VPTS CSV files.
+ birdcast_data_url <- getOption("getRad.birdcast_vpts_data_url")
+ radar_out <- tolower(radar)
+
+ out <- paste(birdcast_data_url, "nexrad", "daily", s3_paths, sep = "/") |>
+ read_vpts_from_url() |>
+ purrr::keep(.p = ~ as.logical(nrow(.x))) |>
+ purrr::list_rbind()
+
+ out$radar <- radar_out
+ out$source <- "birdcast"
+
+ out
+}
diff --git a/R/get_vpts_coverage.R b/R/get_vpts_coverage.R
index 303aa660..e9f94851 100644
--- a/R/get_vpts_coverage.R
+++ b/R/get_vpts_coverage.R
@@ -3,7 +3,7 @@
#' Gets the VPTS file coverage from supported sources per radar and date.
#'
#' @param source Source of the data. One or more of `"baltrad"`, `"uva"`,
-#' `"ecog-04003"` or `"rmi"`. If not provided, `"baltrad"` is used.
+#' `"ecog-04003"` or `"rmi"` or `"birdcast"`. If not provided, `"baltrad"` is used.
#' Alternatively `"all"` can be used if data from all sources should be
#' returned.
#' @param ... Arguments passed on to internal functions.
@@ -13,7 +13,7 @@
#' @examplesIf interactive()
#' get_vpts_coverage()
get_vpts_coverage <- function(
- source = c("baltrad", "uva", "ecog-04003", "rmi"),
+ source = c("baltrad", "uva", "ecog-04003", "rmi", "birdcast"),
...
) {
# argument all returns all possible sources
@@ -40,7 +40,8 @@ get_vpts_coverage <- function(
rmi = get_vpts_coverage_rmi,
baltrad = get_vpts_coverage_aloft,
uva = get_vpts_coverage_aloft,
- "ecog-04003" = get_vpts_coverage_aloft
+ "ecog-04003" = get_vpts_coverage_aloft,
+ birdcast = get_vpts_coverage_birdcast
)
cl <- rlang::caller_env(0)
# Run the helpers, but every helper only once.
diff --git a/R/get_vpts_coverage_aloft.R b/R/get_vpts_coverage_aloft.R
index 1ad43f86..6c29b96d 100644
--- a/R/get_vpts_coverage_aloft.R
+++ b/R/get_vpts_coverage_aloft.R
@@ -25,7 +25,6 @@ get_vpts_coverage_aloft <- function(
req_user_agent_getrad() |>
req_retry_getrad() |>
req_cache_getrad(use_cache = use_cache) |>
- httr2::req_progress(type = "down") |>
httr2::req_perform(error_call = call) |>
httr2::resp_body_raw()
diff --git a/R/get_vpts_coverage_birdcast.R b/R/get_vpts_coverage_birdcast.R
new file mode 100644
index 00000000..208cd476
--- /dev/null
+++ b/R/get_vpts_coverage_birdcast.R
@@ -0,0 +1,49 @@
+#' Get VPTS file coverage from the public BirdCast NEXRAD archive
+#'
+#' Gets the VPTS file coverage from the public BirdCast NEXRAD archive. This is
+#' derived from a coverage file at
+#' <`r file.path(getOption("getRad.birdcast_vpts_data_url"), "coverage.csv")`>. By
+#' default this file is cached for 6 hours.
+#'
+#' @param ... Used to prevent accidentally using the `call` argument
+#' @param call A call used for error messaging.
+#' @inheritParams req_cache_getrad
+#' @return A data frame of the coverage file in the birdcast VPTS archive.
+#' @noRd
+#' @examplesIf interactive()
+#' get_vpts_coverage_birdcast()
+get_vpts_coverage_birdcast <- function(
+ use_cache = TRUE,
+ ...,
+ call = rlang::caller_env()
+) {
+ birdcast_vpts_data_url <- getOption("getRad.birdcast_vpts_data_url")
+
+ coverage_raw <-
+ httr2::request(birdcast_vpts_data_url) |>
+ httr2::req_url_path_append("coverage.csv") |>
+ req_user_agent_getrad() |>
+ req_retry_getrad() |>
+ req_cache_getrad(use_cache = use_cache) |>
+ httr2::req_perform(error_call = call) |>
+ httr2::resp_body_raw()
+
+ coverage <-
+ vroom::vroom(
+ coverage_raw,
+ progress = FALSE,
+ show_col_types = FALSE
+ ) |>
+ dplyr::mutate(
+ source = "birdcast",
+ radar = string_extract(.data$directory, "(?<=daily\\/)[A-Z0-9]{4}"),
+ date = as.Date(
+ string_extract(
+ .data$directory,
+ "[0-9]{4}\\/[0-9]{2}\\/[0-9]{2}$"
+ )
+ )
+ )
+
+ return(coverage)
+}
diff --git a/R/get_vpts_rmi.R b/R/get_vpts_rmi.R
index 6dc2a0bb..f6a053e8 100644
--- a/R/get_vpts_rmi.R
+++ b/R/get_vpts_rmi.R
@@ -5,7 +5,7 @@
#'
#' @inheritParams get_vpts_aloft
#' @return A tibble with VPTS data.
-#' @keywords internal
+#' @noRd
get_vpts_rmi <- function(radar_odim_code, rounded_interval) {
# Check the coverage for data availability
diff --git a/R/get_weather_radars.R b/R/get_weather_radars.R
index 14051aef..1b7ed82f 100644
--- a/R/get_weather_radars.R
+++ b/R/get_weather_radars.R
@@ -15,9 +15,11 @@
#' from.
#' - For `nexrad`: [nexrad-stations.txt](https://www.ncei.noaa.gov/access/homr/file/nexrad-stations.txt).
#'
-#' @inheritParams req_cache_getrad
#' @param source Source of the metadata. `"opera"`, `"nexrad"` or `"all"`.
#' If not provided, `"opera"` is used.
+#' @param use_cache Logical indicating whether to use the cache. Default is
+#' `TRUE`. If `FALSE` the cache is ignored and the file is fetched anew.
+#' This can also be useful if you want to force a refresh of the cache.
#' @param ... Additional arguments passed on to reading functions per source,
#' currently not used.
#' @return A sf or tibble with weather radar metadata. In all cases the column `source` is
diff --git a/R/utils.R b/R/utils.R
index c765c5b2..e2c729c8 100644
--- a/R/utils.R
+++ b/R/utils.R
@@ -183,7 +183,6 @@ radar_to_name <- function(vpts_df_list) {
#'
#' @param x Character vector.
#' @return An integer vector.
-#' @seealso [as_numeric_shh()] [as_logical_shh()]
#' @noRd
#' @examples
#' as_integer_shh(c("1", "2", "3"))
@@ -278,11 +277,9 @@ req_retry_getrad <- function(
#'
#' @inheritParams httr2::req_cache
#' @param req `httr2` request.
-#' @param use_cache Logical indicating whether to use the cache. Default is
-#' `TRUE`. If `FALSE` the cache is ignored and the file is fetched anew.
-#' This can also be useful if you want to force a refresh of the cache.
+#' @inheritParams get_weather_radars use_cache
#' @param ... Additional arguments passed to `httr2::req_cache()`.
-#' @keywords internal
+#' @noRd
req_cache_getrad <- function(
req,
use_cache = TRUE,
@@ -524,3 +521,11 @@ get_element_regex <- function(html, regex) {
string_extract(regex) |>
(\(vec) vec[!is.na(vec)])()
}
+
+#' Wrapper of bioRad::get_elevation_angles
+#' This function is wrapped so it can be mocked in
+#' `testhat::with_mocked_bindings()` and thus allows for testing an error
+#' in`get_pvol_cz()`.
+#'
+#' @noRd
+get_elevation_angles <- bioRad::get_elevation_angles
diff --git a/R/utils_pvol.R b/R/utils_pvol.R
index dc7ff835..c238180f 100644
--- a/R/utils_pvol.R
+++ b/R/utils_pvol.R
@@ -5,7 +5,7 @@
#'
#' @param urls A character vector with urls to h5 files to read
#' @param ... arguments to bioRad::read_pvolfile
-#' @param call
+#' @inheritParams radar_recode call
#'
#' @returns a pvol
#' @noRd
@@ -42,9 +42,12 @@ read_pvol_from_url_per_param <- function(
bioRad::attribute_table
)
all_params_same_attributes <- all(unlist(lapply(
- lapply(list_of_attribute_tables[-1], dplyr::select, -"param"),
- all.equal,
- dplyr::select(list_of_attribute_tables[[1]], -"param")
+ lapply(
+ lapply(list_of_attribute_tables[-1], dplyr::select, -"param"),
+ all.equal,
+ dplyr::select(list_of_attribute_tables[[1]], -"param")
+ ),
+ isTRUE
)))
if (!all_params_same_attributes) {
cli::cli_abort(
diff --git a/R/zzz.R b/R/zzz.R
index c5bfef36..bd016b2f 100644
--- a/R/zzz.R
+++ b/R/zzz.R
@@ -21,6 +21,7 @@
),
getRad.aloft_data_url = "https://aloftdata.s3-eu-west-1.amazonaws.com",
getRad.nexrad_data_url = "https://unidata-nexrad-level2.s3.amazonaws.com",
+ getRad.birdcast_vpts_data_url = "https://birdcastdata.s3.amazonaws.com",
getRad.cache = cachem::cache_mem(
max_size = 128 * 1024^2,
max_age = 60^2 * 24
diff --git a/README.Rmd b/README.Rmd
index c5c38587..91a4f816 100644
--- a/README.Rmd
+++ b/README.Rmd
@@ -29,17 +29,17 @@ getRad is an R package that provides a unified interface to download radar data
## Installation
-Install the latest released version from CRAN:
+Install the released version of getRad from CRAN:
-```{r, eval = FALSE}
+``` r
install.packages("getRad")
```
-Or the development version from [GitHub](https://github.com/aloftdata/getRad):
+Or install the development version from [GitHub](https://github.com/) with:
-```{r, eval = FALSE}
-# install.packages("devtools")
-devtools::install_github("aloftdata/getRad")
+``` r
+# install.packages("pak")
+pak::pak("aloftdata/getRad")
```
## Usage
@@ -49,6 +49,7 @@ Download a polar volume, and then plot it using `bioRad`:
```{r example}
library(getRad)
library(bioRad)
+
# Plot daytime insect movements in Finland (Mäkinen et al. 2022)
pvol <- get_pvol("fianj", as.POSIXct("2012-05-17 14:00", tz = "UTC"))
plot(project_as_ppi(get_scan(pvol, 0), range_max = 75000))
@@ -80,7 +81,7 @@ for (i in names(vpts_list)) {
## Meta
-- We welcome [contributions](https://aloftdata.github.io/getRad/CONTRIBUTING.html) including bug reports.
+- We welcome [contributions](.github/CONTRIBUTING.md) including bug reports.
- License: MIT
-- Get [citation information](https://aloftdata.github.io/getRad/authors.html#citation) for getRad in R doing `citation("getRad")`.
-- Please note that this project is released with a [Contributor Code of Conduct](https://aloftdata.github.io/getRad/CODE_OF_CONDUCT.html). By participating in this project you agree to abide by its terms.
+- Get citation information for getRad in R with `citation("getRad")`.
+- Please note that this project is released with a [Contributor Code of Conduct](.github/CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms.
diff --git a/README.md b/README.md
index 3036594b..80ee2117 100644
--- a/README.md
+++ b/README.md
@@ -25,18 +25,18 @@ exploration of the data by other tools such as
## Installation
-Install the latest released version from CRAN:
+Install the released version of getRad from CRAN:
``` r
install.packages("getRad")
```
-Or the development version from
-[GitHub](https://github.com/aloftdata/getRad):
+Or install the development version from [GitHub](https://github.com/)
+with:
``` r
-# install.packages("devtools")
-devtools::install_github("aloftdata/getRad")
+# install.packages("pak")
+pak::pak("aloftdata/getRad")
```
## Usage
@@ -46,18 +46,19 @@ Download a polar volume, and then plot it using `bioRad`:
``` r
library(getRad)
library(bioRad)
+
# Plot daytime insect movements in Finland (Mäkinen et al. 2022)
pvol <- get_pvol("fianj", as.POSIXct("2012-05-17 14:00", tz = "UTC"))
plot(project_as_ppi(get_scan(pvol, 0), range_max = 75000))
```
-
+
``` r
plot(calculate_vp(pvol, h_layer = 50, n_layer = 40, warning = FALSE))
```
-
+
``` r
@@ -66,13 +67,13 @@ pvol <- get_pvol("fianj", as.POSIXct("2012-05-11 23:00", tz = "UTC"))
plot(project_as_ppi(get_scan(pvol, 0), range_max = 75000))
```
-
+
``` r
plot(calculate_vp(pvol, h_layer = 50, n_layer = 40, warning = FALSE))
```
-
+
Download a vertical profile time series from the [Aloft
bucket](https://aloftdata.eu/browse/):
@@ -93,17 +94,14 @@ for (i in names(vpts_list)) {
}
```
-
+
## Meta
-- We welcome
- [contributions](https://aloftdata.github.io/getRad/CONTRIBUTING.html)
- including bug reports.
+- We welcome [contributions](.github/CONTRIBUTING.md) including bug
+ reports.
- License: MIT
-- Get [citation
- information](https://aloftdata.github.io/getRad/authors.html#citation)
- for getRad in R doing `citation("getRad")`.
+- Get citation information for getRad in R with `citation("getRad")`.
- Please note that this project is released with a [Contributor Code of
- Conduct](https://aloftdata.github.io/getRad/CODE_OF_CONDUCT.html). By
- participating in this project you agree to abide by its terms.
+ Conduct](.github/CODE_OF_CONDUCT.md). By participating in this project
+ you agree to abide by its terms.
diff --git a/man/getRad-package.Rd b/man/getRad-package.Rd
index 0c0c6c52..786d872e 100644
--- a/man/getRad-package.Rd
+++ b/man/getRad-package.Rd
@@ -18,21 +18,22 @@ Useful links:
}
\author{
-\strong{Maintainer}: Bart Kranstauber \email{b.kranstauber@uva.nl} (\href{https://orcid.org/0000-0001-8303-780X}{ORCID}) (University of Amsterdam)
+\strong{Maintainer}: Bart Kranstauber \email{b.kranstauber@uva.nl} (\href{https://orcid.org/0000-0001-8303-780X}{ORCID}) (affiliation: University of Amsterdam)
Authors:
\itemize{
- \item Pieter Huybrechts \email{pieter.huybrechts@inbo.be} (\href{https://orcid.org/0000-0002-6658-6062}{ORCID}) (Research Institute for Nature and Forest (INBO))
- \item Peter Desmet \email{peter.desmet@inbo.be} (\href{https://orcid.org/0000-0002-8442-8025}{ORCID}) (Research Institute for Nature and Forest (INBO))
+ \item Bart Kranstauber \email{b.kranstauber@uva.nl} (\href{https://orcid.org/0000-0001-8303-780X}{ORCID}) (affiliation: University of Amsterdam)
+ \item Pieter Huybrechts \email{pieter.huybrechts@inbo.be} (\href{https://orcid.org/0000-0002-6658-6062}{ORCID}) (affiliation: Research Institute for Nature and Forest (INBO))
+ \item Peter Desmet \email{peter.desmet@inbo.be} (\href{https://orcid.org/0000-0002-8442-8025}{ORCID}) (affiliation: Research Institute for Nature and Forest (INBO))
}
Other contributors:
\itemize{
- \item Cecilia Nilsson \email{cecilia.nilsson@biol.lu.se} (\href{https://orcid.org/0000-0001-8957-4411}{ORCID}) (Lund University) [contributor]
- \item Alexander Tedeschi \email{at744@cornell.edu} (\href{https://orcid.org/0000-0003-0772-6931}{ORCID}) (Cornell Lab of Ornithology) [contributor]
- \item Hidde Leijnse (\href{https://orcid.org/0000-0001-7835-4480}{ORCID}) (Royal Netherlands Meteorological Institute) [contributor]
- \item Bart Hoekstra (\href{https://orcid.org/0000-0002-7085-3805}{ORCID}) (University of Amsterdam) [contributor]
- \item University of Amsterdam (04dkp9463) [copyright holder]
+ \item Cecilia Nilsson \email{cecilia.nilsson@biol.lu.se} (\href{https://orcid.org/0000-0001-8957-4411}{ORCID}) (affiliation: Lund University) [contributor]
+ \item Alexander Tedeschi \email{at744@cornell.edu} (\href{https://orcid.org/0000-0003-0772-6931}{ORCID}) (affiliation: Cornell Lab of Ornithology) [contributor]
+ \item Hidde Leijnse (\href{https://orcid.org/0000-0001-7835-4480}{ORCID}) (affiliation: Royal Netherlands Meteorological Institute) [contributor]
+ \item Bart Hoekstra (\href{https://orcid.org/0000-0002-7085-3805}{ORCID}) (affiliation: University of Amsterdam) [contributor]
+ \item University of Amsterdam (\href{https://ror.org/04dkp9463}{ROR}) [copyright holder]
\item Biodiversa+ (https://hirad.science/) [funder]
}
diff --git a/man/get_pvol.Rd b/man/get_pvol.Rd
index 5e54b674..1960ec25 100644
--- a/man/get_pvol.Rd
+++ b/man/get_pvol.Rd
@@ -42,7 +42,7 @@ with the Terminal Doppler Weather Radar (TDWR) program can not be read. These ca
be identified using the \code{stntype} column in \code{get_weather_radars("nexrad")}.
}
\examples{
-\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
+\dontshow{if (interactive()) withAutoprint(\{ # examplesIf}
# Get PVOL data for a single radar and datetime
get_pvol("deess", as.POSIXct(Sys.Date()))
diff --git a/man/get_vpts.Rd b/man/get_vpts.Rd
index dd6512a7..23b74da8 100644
--- a/man/get_vpts.Rd
+++ b/man/get_vpts.Rd
@@ -7,7 +7,7 @@
get_vpts(
radar,
datetime,
- source = c("baltrad", "uva", "ecog-04003", "rmi"),
+ source = c("baltrad", "uva", "ecog-04003", "rmi", "birdcast"),
return_type = c("vpts", "tibble")
)
}
@@ -26,15 +26,15 @@ downloaded.
\item A \code{\link[lubridate:interval]{lubridate::interval()}}, between which all data files are downloaded.
}}
-\item{source}{Source of the data. One of \code{"baltrad"}, \code{"uva"}, \code{"ecog-04003"}
-or \code{"rmi"}. Only one source can be queried at a time. If not provided,
+\item{source}{Source of the data. One of \code{"baltrad"}, \code{"uva"}, \code{"ecog-04003"},
+\code{"rmi"}, or \code{"birdcast"}. Only one source can be queried at a time. If not provided,
\code{"baltrad"} is used. Alternatively a local directory can be specified,
see details for an explanation of the file format.}
\item{return_type}{Type of object that should be returned. Either:
\itemize{
\item \code{"vpts"}: vpts object(s) (default).
-\item \code{"tibble"}: a \code{\link[dplyr:reexports]{dplyr::tibble()}}.
+\item \code{"tibble"}: a \code{\link[dplyr:tibble]{dplyr::tibble()}}.
}}
}
\value{
@@ -44,7 +44,7 @@ Either a vpts object, a list of vpts objects or a tibble. See
\description{
Gets vertical profile time series data from supported sources and returns it
as a (list of) of \link[bioRad:summary.vpts]{vpts objects} or a
-\code{\link[dplyr:reexports]{dplyr::tibble()}}.
+\code{\link[dplyr:tibble]{dplyr::tibble()}}.
}
\details{
For more details on supported sources, see \code{vignette("supported_sources")}.
@@ -68,7 +68,7 @@ data is stored in aloft data
Besides the examples above there is a \code{date} object available for formatting.
}
\examples{
-\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
+\dontshow{if (interactive()) withAutoprint(\{ # examplesIf}
# Get VPTS data for a single radar and date
get_vpts(radar = "bejab", datetime = "2023-01-01", source = "baltrad")
get_vpts(radar = "bejab", datetime = "2020-01-19", source = "rmi")
@@ -101,5 +101,7 @@ get_vpts(
source = "baltrad",
return_type = "tibble"
)
+#' Get VPTS data from the public BirdCast NEXRAD archive
+get_vpts(radar = "KABR", datetime = "2023-01-01", source = "birdcast")
\dontshow{\}) # examplesIf}
}
diff --git a/man/get_vpts_aloft.Rd b/man/get_vpts_aloft.Rd
deleted file mode 100644
index 32451589..00000000
--- a/man/get_vpts_aloft.Rd
+++ /dev/null
@@ -1,47 +0,0 @@
-% Generated by roxygen2: do not edit by hand
-% Please edit documentation in R/get_vpts_aloft.R
-\name{get_vpts_aloft}
-\alias{get_vpts_aloft}
-\title{Get VPTS data from the Aloft bucket}
-\usage{
-get_vpts_aloft(
- radar_odim_code,
- rounded_interval,
- source = c("baltrad", "uva", "ecog-04003"),
- coverage = get_vpts_coverage_aloft()
-)
-}
-\arguments{
-\item{radar_odim_code}{Radar ODIM code.}
-
-\item{rounded_interval}{Interval to fetch data for, rounded to nearest day.}
-
-\item{source}{Source of the data. One of \code{baltrad}, \code{uva} or \code{ecog-04003}.}
-
-\item{coverage}{A data frame containing the coverage of the Aloft bucket.
-If not provided, it will be fetched from via the internet.}
-}
-\value{
-A tibble with VPTS data.
-}
-\description{
-Gets VPTS data from the Aloft bucket.
-}
-\details{
-By default, data from the \href{https://aloftdata.eu/browse/}{Aloft bucket} are
-retrieved from \url{https://aloftdata.s3-eu-west-1.amazonaws.com}. This can be changed by
-setting \code{options(getRad.aloft_data_url)} to any desired url.
-}
-\section{Inner working}{
-
-\itemize{
-\item Constructs the S3 paths for the VPTS files based on the input.
-\item Performs parallel HTTP requests to fetch the VPTS CSV data.
-\item Parses the response bodies with some assumptions about the column classes.
-\item Adds a column with the radar source.
-\item Overwrites the radar column with the radar_odim_code, all other values for
-this column are considered in error.
-}
-}
-
-\keyword{internal}
diff --git a/man/get_vpts_coverage.Rd b/man/get_vpts_coverage.Rd
index af8087e1..ac0d0034 100644
--- a/man/get_vpts_coverage.Rd
+++ b/man/get_vpts_coverage.Rd
@@ -4,11 +4,14 @@
\alias{get_vpts_coverage}
\title{Get VPTS file coverage from supported sources}
\usage{
-get_vpts_coverage(source = c("baltrad", "uva", "ecog-04003", "rmi"), ...)
+get_vpts_coverage(
+ source = c("baltrad", "uva", "ecog-04003", "rmi", "birdcast"),
+ ...
+)
}
\arguments{
\item{source}{Source of the data. One or more of \code{"baltrad"}, \code{"uva"},
-\code{"ecog-04003"} or \code{"rmi"}. If not provided, \code{"baltrad"} is used.
+\code{"ecog-04003"} or \code{"rmi"} or \code{"birdcast"}. If not provided, \code{"baltrad"} is used.
Alternatively \code{"all"} can be used if data from all sources should be
returned.}
@@ -22,7 +25,7 @@ A \code{data.frame} or \code{tibble} with at least three columns, \code{source},
Gets the VPTS file coverage from supported sources per radar and date.
}
\examples{
-\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
+\dontshow{if (interactive()) withAutoprint(\{ # examplesIf}
get_vpts_coverage()
\dontshow{\}) # examplesIf}
}
diff --git a/man/get_vpts_rmi.Rd b/man/get_vpts_rmi.Rd
deleted file mode 100644
index 6854ac62..00000000
--- a/man/get_vpts_rmi.Rd
+++ /dev/null
@@ -1,20 +0,0 @@
-% Generated by roxygen2: do not edit by hand
-% Please edit documentation in R/get_vpts_rmi.R
-\name{get_vpts_rmi}
-\alias{get_vpts_rmi}
-\title{Get VPTS data from RMI}
-\usage{
-get_vpts_rmi(radar_odim_code, rounded_interval)
-}
-\arguments{
-\item{radar_odim_code}{Radar ODIM code.}
-
-\item{rounded_interval}{Interval to fetch data for, rounded to nearest day.}
-}
-\value{
-A tibble with VPTS data.
-}
-\description{
-Get VPTS data from \href{https://opendata.meteo.be/geonetwork/srv/eng/catalog.search#/metadata/RMI_DATASET_CROW}{RMI_DATASET_CROW}.
-}
-\keyword{internal}
diff --git a/man/get_weather_radars.Rd b/man/get_weather_radars.Rd
index ae12c983..81d352d7 100644
--- a/man/get_weather_radars.Rd
+++ b/man/get_weather_radars.Rd
@@ -37,7 +37,7 @@ from.
}
}
\examples{
-\dontshow{if (interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
+\dontshow{if (interactive()) withAutoprint(\{ # examplesIf}
# Get radar metadata from OPERA
get_weather_radars(source = "opera")
diff --git a/man/req_cache_getrad.Rd b/man/req_cache_getrad.Rd
deleted file mode 100644
index 90a4b5a5..00000000
--- a/man/req_cache_getrad.Rd
+++ /dev/null
@@ -1,40 +0,0 @@
-% Generated by roxygen2: do not edit by hand
-% Please edit documentation in R/utils.R
-\name{req_cache_getrad}
-\alias{req_cache_getrad}
-\title{Function to set the cache for a getRad specific httr2 request}
-\usage{
-req_cache_getrad(
- req,
- use_cache = TRUE,
- max_age = getOption("getRad.max_cache_age_seconds", default = 6 * 60 * 60),
- max_n = getOption("getRad.max_cache_n", default = Inf),
- max_size = getOption("getRad.max_cache_size_bytes", default = 1024 * 1024 * 1024),
- ...
-)
-}
-\arguments{
-\item{req}{\code{httr2} request.}
-
-\item{use_cache}{Logical indicating whether to use the cache. Default is
-\code{TRUE}. If \code{FALSE} the cache is ignored and the file is fetched anew.
-This can also be useful if you want to force a refresh of the cache.}
-
-\item{max_n, max_age, max_size}{Automatically prune the cache by specifying
-one or more of:
-\itemize{
-\item \code{max_age}: to delete files older than this number of seconds.
-\item \code{max_n}: to delete files (from oldest to newest) to preserve at
-most this many files.
-\item \code{max_size}: to delete files (from oldest to newest) to preserve at
-most this many bytes.
-}
-
-The cache pruning is performed at most once per minute.}
-
-\item{...}{Additional arguments passed to \code{httr2::req_cache()}.}
-}
-\description{
-Function to set the cache for a getRad specific httr2 request
-}
-\keyword{internal}
diff --git a/tests/testthat/test-get_pvol_at.R b/tests/testthat/test-get_pvol_at.R
new file mode 100644
index 00000000..089a2234
--- /dev/null
+++ b/tests/testthat/test-get_pvol_at.R
@@ -0,0 +1,33 @@
+test_that("Pvol for hochficht in austria can be downloaded", {
+ skip_if_offline("public.hub.geosphere.at")
+ time <- as.POSIXct(Sys.time() - 10000, tz = "Europe/Helsinki")
+ pvol <- expect_s3_class(get_pvol("hochficht", time, param = "all"), "pvol")
+ expect_true(bioRad::is.pvol(pvol))
+ expect_identical(
+ pvol$datetime,
+ lubridate::floor_date(lubridate::with_tz(time, "UTC"), "5 min")
+ )
+})
+
+test_that("Pvol for hochficht in austria can be downloaded", {
+ skip_if_offline("public.hub.geosphere.at")
+ time <- as.POSIXct(
+ Sys.time() - 10000 - 24 * 3 * 60 * 60,
+ tz = "Europe/Helsinki"
+ )
+ expect_error(
+ get_pvol("hochficht", time, param = "all"),
+ class = "getRad_error_get_pvol_at_no_data"
+ )
+})
+test_that("hochficht can be combined with other radars", {
+ suppressMessages(expect_type(
+ pvol_lst <- get_pvol(
+ c("depro", "hochficht", "KABX"),
+ as.POSIXct(Sys.Date())
+ ),
+ "list"
+ ))
+ expect_all_true(purrr::map_lgl(pvol_lst, inherits, "pvol"))
+ expect_length(pvol_lst, 3L)
+})
diff --git a/tests/testthat/test-get_pvol_cz.R b/tests/testthat/test-get_pvol_cz.R
index 138032e4..d9e5eb4e 100644
--- a/tests/testthat/test-get_pvol_cz.R
+++ b/tests/testthat/test-get_pvol_cz.R
@@ -1,5 +1,5 @@
test_that("Check if the available attributes changed", {
- skip_if_offline()
+ skip_if_offline("opendata.chmi.cz")
expect_identical(
httr2::request(
"http://opendata.chmi.cz/meteorology/weather/radar/sites/ska"
@@ -21,7 +21,7 @@ test_that("Check if the available attributes changed", {
)
})
test_that("Pvol for Czechia can be downloaded", {
- skip_if_offline()
+ skip_if_offline("opendata.chmi.cz")
time <- lubridate::floor_date(
as.POSIXct(Sys.time(), tz = "Europe/Helsinki") - lubridate::hours(10),
"5 mins"
@@ -33,3 +33,20 @@ test_that("Pvol for Czechia can be downloaded", {
lubridate::with_tz(time, "UTC")
)
})
+
+test_that("get_pvol_cz() returns error on duplicate elevation angles", {
+ skip_if_offline("opendata.chmi.cz")
+ time <- lubridate::floor_date(
+ as.POSIXct(Sys.time(), tz = "Europe/Helsinki") - lubridate::hours(10),
+ "5 mins"
+ )
+ with_mocked_bindings(
+ code = {
+ expect_error(
+ get_pvol("czska", time, param = "all"),
+ class = "getRad_error_czechia_duplicated_elevation_angles"
+ )
+ },
+ get_elevation_angles = function(...) c("dup_angle", "dup_angle")
+ )
+})
diff --git a/tests/testthat/test-get_pvol_ee.R b/tests/testthat/test-get_pvol_ee.R
index 8a353d26..a8722f7a 100644
--- a/tests/testthat/test-get_pvol_ee.R
+++ b/tests/testthat/test-get_pvol_ee.R
@@ -1,20 +1,38 @@
test_that("Pvol for estonia can be downloaded", {
skip_if_offline()
withr::local_options(list(httr2_progress = FALSE))
- # The api frequently sends a 429 response therefore test is allowed to fail
+
+ time <- as.POSIXct("2024-4-4 21:00:00", tz = "Europe/Helsinki")
+
+ # The API frequently sends 429/500 responses, therefore this test is allowed
+ # to skip when the download is unsuccessful.
show_failure(expect_no_error(
pvol <- get_pvol(
"eesur",
- time <- as.POSIXct("2024-4-4 21:00:00", tz = "Europe/Helsinki"),
+ time,
param = "all"
)
))
- ## If get_pvol() returns an error, the other tests are skipped.
+
skip_if_not(
inherits(pvol, "pvol"),
- message = "PVOL download for estonia was unsuccesful, succes is variable in testing environments"
+ message = paste(
+ "PVOL download for Estonia was unsuccessful;",
+ "success is variable in testing environments"
+ )
)
+
expect_s3_class(pvol, "pvol")
expect_true(bioRad::is.pvol(pvol))
expect_identical(pvol$datetime, lubridate::with_tz(time, "UTC"))
})
+
+test_that("Pvol for estonia fails on missing data", {
+ expect_error(
+ get_pvol(
+ radar = "eesur",
+ structure(1776221700, class = c("POSIXct", "POSIXt"))
+ ),
+ class = "getRad_error_get_pvol_ee_differing_n_files"
+ )
+})
diff --git a/tests/testthat/test-get_pvol_se.R b/tests/testthat/test-get_pvol_se.R
index 963e67e8..0a1fd728 100644
--- a/tests/testthat/test-get_pvol_se.R
+++ b/tests/testthat/test-get_pvol_se.R
@@ -34,8 +34,8 @@ test_that("Pvol for Sweden can be downloaded", {
test_that("Pvol for Sweden fails out of time range", {
skip_if_offline("opendata-download-radar.smhi.se")
+ skip_if_se_not_updated("hudiksvall", Sys.time() - lubridate::hours(4))
time <- Sys.time() - lubridate::hours(40)
- skip_if_se_not_updated("hudiksvall", time)
expect_error(
get_pvol("sehuv", time),
diff --git a/tests/testthat/test-get_vpts_birdcast.R b/tests/testthat/test-get_vpts_birdcast.R
new file mode 100644
index 00000000..d65fc448
--- /dev/null
+++ b/tests/testthat/test-get_vpts_birdcast.R
@@ -0,0 +1,132 @@
+birdcast_coverage <- tibble::tibble(
+ radar = "KABR",
+ date = as.Date(c("2013-09-01", "2013-09-02"))
+)
+
+test_that("get_vpts_birdcast() returns error on invalid radar code", {
+ expect_error(
+ getRad:::get_vpts_birdcast(
+ radar = "KAB",
+ rounded_interval = lubridate::interval("2013-09-01", "2013-09-02"),
+ coverage = birdcast_coverage
+ ),
+ class = "getRad_error_radar_not_single_odim_nexrad"
+ )
+
+ expect_error(
+ getRad:::get_vpts_birdcast(
+ radar = 12345,
+ rounded_interval = lubridate::interval("2013-09-01", "2013-09-02"),
+ coverage = birdcast_coverage
+ ),
+ class = "getRad_error_radar_not_single_odim_nexrad"
+ )
+})
+
+test_that("get_vpts_birdcast() returns error when multiple radars are queried", {
+ expect_error(
+ getRad:::get_vpts_birdcast(
+ radar = c("KABR", "KABX"),
+ rounded_interval = lubridate::interval("2013-09-01", "2013-09-02"),
+ coverage = birdcast_coverage
+ ),
+ class = "getRad_error_radar_not_single_odim_nexrad"
+ )
+})
+
+test_that("get_vpts_birdcast() returns error when radar is not found in coverage", {
+ expect_error(
+ getRad:::get_vpts_birdcast(
+ radar = "ZZZZ",
+ rounded_interval = lubridate::interval("2013-09-01", "2013-09-02"),
+ coverage = birdcast_coverage
+ ),
+ class = "getRad_error_birdcast_radar_not_found"
+ )
+
+ expect_identical(
+ rlang::catch_cnd(
+ getRad:::get_vpts_birdcast(
+ radar = "ZZZZ",
+ rounded_interval = lubridate::interval("2013-09-01", "2013-09-02"),
+ coverage = birdcast_coverage
+ ),
+ classes = "getRad_error_birdcast_radar_not_found"
+ )$missing_radar,
+ "ZZZZ"
+ )
+})
+
+test_that("get_vpts_birdcast() returns error when date is requested not in coverage", {
+ expect_error(
+ getRad:::get_vpts_birdcast(
+ radar = "KABR",
+ rounded_interval = lubridate::interval("1900-01-01", "1900-01-02"),
+ coverage = birdcast_coverage
+ ),
+ class = "getRad_error_date_not_found"
+ )
+})
+
+test_that("get_vpts_birdcast() can fetch daily VPTS data from BirdCast archive", {
+ skip_if_offline()
+
+ birdcast_vpts_tbl <- getRad:::get_vpts_birdcast(
+ radar = "KABR",
+ rounded_interval = lubridate::interval("2013-09-01", "2013-09-02"),
+ coverage = birdcast_coverage
+ )
+
+ expect_type(birdcast_vpts_tbl, "list")
+ expect_s3_class(birdcast_vpts_tbl, "tbl_df")
+
+ expect_named(
+ birdcast_vpts_tbl,
+ c(
+ "radar",
+ "datetime",
+ "height",
+ "height_reference",
+ "u",
+ "v",
+ "w",
+ "ff",
+ "dd",
+ "sd_vvp",
+ "gap",
+ "eta",
+ "dens",
+ "dbz",
+ "dbz_all",
+ "n",
+ "n_dbz",
+ "n_all",
+ "n_dbz_all",
+ "rcs",
+ "sd_vvp_threshold",
+ "vcp",
+ "radar_latitude",
+ "radar_longitude",
+ "radar_height",
+ "radar_wavelength",
+ "source_file",
+ "source"
+ )
+ )
+
+ expect_true(nrow(birdcast_vpts_tbl) > 0)
+ expect_true(all(birdcast_vpts_tbl$radar == "kabr"))
+ expect_true(all(birdcast_vpts_tbl$source == "birdcast"))
+})
+test_that("get_vpts() can fetch daily VPTS data from BirdCast archive", {
+ skip_if_offline()
+ date <- as.Date("2026-4-1")
+ vpts <- getRad:::get_vpts(
+ radar = "KABX",
+ date,
+ source = "birdcast"
+ )
+ expect_s3_class(vpts, "vpts")
+ expect_all_true(as.Date(vpts$datetime) == date)
+ expect_false(vpts$regular)
+})
diff --git a/tests/testthat/test-get_vpts_coverage.R b/tests/testthat/test-get_vpts_coverage.R
index 2c69aa9f..6e93262d 100644
--- a/tests/testthat/test-get_vpts_coverage.R
+++ b/tests/testthat/test-get_vpts_coverage.R
@@ -10,7 +10,7 @@ test_that("Source argument as expected", {
)
})
-test_that("format as expect for aloft", {
+test_that("format as expected for aloft", {
skip_if_offline()
data <- get_vpts_coverage("uva")
@@ -19,7 +19,7 @@ test_that("format as expect for aloft", {
expect_true(all(is_odim(data$radar)))
})
-test_that("format as expect for rmi", {
+test_that("format as expected for rmi", {
skip_if_offline("opendata.meteo.be")
data <- get_vpts_coverage("rmi")
@@ -28,6 +28,16 @@ test_that("format as expect for rmi", {
expect_true(all(is_odim(data$radar)))
})
+test_that("format as expected for birdcast", {
+ skip_if_offline()
+
+ data <- get_vpts_coverage("birdcast")
+ expect_true(all(c("source", "radar", "date") %in% names(data)))
+ expect_s3_class(data$date, "Date")
+ expect_true(all(grepl("^[A-Z0-9]{4}$", data$radar)))
+ expect_true(all(data$source == "birdcast"))
+})
+
test_that("combined retrieval works", {
skip_if_offline("opendata.meteo.be")
@@ -48,8 +58,9 @@ test_that("get_vpts_coverage() returns 'baltrad' as a default source", {
test_that("The argument source='all' returns all data", {
+ all_coverage <- get_vpts_coverage(source = "all")
expect_equal(
- get_vpts_coverage(source = "all") |>
+ all_coverage |>
dplyr::pull(source) |>
table(),
get_vpts_coverage(
@@ -58,4 +69,9 @@ test_that("The argument source='all' returns all data", {
dplyr::pull(source) |>
table()
)
+
+ expect_identical(
+ sort(unique(all_coverage$source)),
+ sort(eval(rlang::fn_fmls(get_vpts_coverage)$source))
+ )
})
diff --git a/tests/testthat/test-get_vpts_coverage_birdcast.R b/tests/testthat/test-get_vpts_coverage_birdcast.R
new file mode 100644
index 00000000..cba1559d
--- /dev/null
+++ b/tests/testthat/test-get_vpts_coverage_birdcast.R
@@ -0,0 +1,30 @@
+test_that("get_vpts_coverage_birdcast() returns a tibble", {
+ skip_if_offline()
+ expect_s3_class(
+ get_vpts_coverage_birdcast(),
+ "tbl_df"
+ )
+})
+
+test_that("get_vpts_coverage_birdcast() returns the expected columns", {
+ skip_if_offline()
+
+ expect_named(
+ get_vpts_coverage_birdcast(),
+ c("directory", "file_count", "source", "radar", "date")
+ )
+})
+
+test_that("get_vpts_coverage_birdcast() returns expected NEXRAD values", {
+ skip_if_offline()
+
+ coverage <- get_vpts_coverage_birdcast()
+
+ expect_all_true(coverage$source == "birdcast")
+ expect_s3_class(coverage$date, "Date")
+ expect_true(all(grepl("^[A-Z0-9]{4}$", coverage$radar)))
+ expect_true(all(grepl(
+ "^nexrad/daily/[A-Z0-9]{4}/[0-9]{4}/[0-9]{2}/[0-9]{2}$",
+ coverage$directory
+ )))
+})
diff --git a/vignettes/articles/vpts_coverage.Rmd b/vignettes/articles/vpts_coverage.Rmd
index 400aa569..0c215d90 100644
--- a/vignettes/articles/vpts_coverage.Rmd
+++ b/vignettes/articles/vpts_coverage.Rmd
@@ -23,12 +23,91 @@ library(htmltools)
```
```{r data}
-cvr <- get_vpts_coverage(source = "all")
-wr <- get_weather_radars("opera") |>
+cvr <- get_vpts_coverage("all")
+wr <- get_weather_radars("all") |>
group_by(radar) |>
arrange(status) |>
slice_tail(n = 1)
```
+```{r}
+# there is a with issue in the svg, here is a temporary solution: https://github.com/r-spatial/leafpop/issues/25
+assignInNamespace("popupSVGraph",function(graphs, #dsn = tempdir(),
+ width = 300, height = 300, ...) {
+ lapply(1:length(graphs), function(i) {
+ #nm = paste0("tmp_", i, ".svg")
+ #fls = file.path(dsn, nm)
+
+ inch_wdth = width / 96
+ inch_hght = height / 96
+
+ #svg(filename = fls, width = inch_wdth, height = inch_hght, ...)
+ #print(graphs[[i]])
+ #dev.off()
+ lns <- svglite::svgstring(
+ width = inch_wdth,
+ height = inch_hght,
+ standalone = FALSE
+ )
+ print(graphs[[i]])
+ dev.off()
+
+ svg_str <- lns()
+
+ # this is a temporary solution to work around svglite
+ # non-specific CSS styles
+ # perhaps we should separate out into its own function/utility
+ # also adds uuid dependency
+ svg_id <- paste0("x",uuid::UUIDgenerate())
+ svg_str <- gsub(
+ x = svg_str,
+ pattern = "