Skip to content

Commit e6cfb2b

Browse files
committed
load_tree_data(): fix up and add to documentation
1 parent 02e7777 commit e6cfb2b

4 files changed

Lines changed: 165 additions & 12 deletions

File tree

DESCRIPTION

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Imports:
2424
methods,
2525
spatstat.geom
2626
Suggests:
27+
glue (>= 1.6.0),
2728
spatstat.explore,
2829
spelling,
2930
testthat (>= 3.0.0)

R/load_tree_data.R

Lines changed: 100 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,59 @@
88
#' without prior download (see Details).
99
#'
1010
#' @details
11-
#' A data source is typically specified as one of the following: **WIP**
11+
#' A data source is typically specified as one of the following:
12+
#'
13+
#' CSV file\cr
14+
#' Path to a text file with `".csv"` extension. For files structured as CSV,
15+
#' but not ending with the `".csv"` extension, a `"CSV:"` prefix can be added
16+
#' before the filename to force loading as CSV format.
17+
#'
18+
#' SQLite database\cr
19+
#' Path to a SQLite file. File extensions are typically `".db"` or `".sqlite"`.
20+
#' GeoPackage SQLite files with `".gpkg"` extension are also supported.
21+
#'
22+
#' PostgreSQL database\cr
23+
#' A connection string in one of the following formats:
24+
#' ```
25+
#' src <- "PG:dbname=databasename"
26+
#'
27+
#' src <- "PG:dbname='db' host='addr' port='5432' user='x' password='y'"
28+
#'
29+
#' src <- "PG:service=servicename"
30+
#'
31+
#' src <- "postgresql://[usr[:pwd]@][netloc][:port][/db][?param1=val1&...]"
32+
#' ```
33+
#'
34+
#' GDAL Virtual File Systems are also supported. This allows, for example,
35+
#' reading from compressed archives such as `".zip"` without prior extraction.
36+
#' The syntax in that case uses the `"/vsizip/"` prefix:
37+
#' ```
38+
#' # relative path to the .zip:
39+
#' src <- "/vsizip/MT_CSV.zip/MT_TREE.csv"
40+
#'
41+
#' # absolute path to the .zip:
42+
#' src <- "/vsizip//home/ctoney/data/MT_CSV.zip/MT_TREE.csv"
43+
#'
44+
#' # on Windows:
45+
#' src <- "/vsizip/c:/users/ctoney/MT_CSV.zip/MT_TREE.csv"
46+
#' ```
47+
#'
48+
#' Network-hosted files can also be read without prior download using the
49+
#' `"vsicurl"` prefix:
50+
#' ```
51+
#' src <- "/vsicurl/https://apps.fs.usda.gov/fia/datamart/CSV/MT_TREE.csv"
52+
#' ```
53+
#'
54+
#' For more details, including supported VSI prefixes for cloud storage services
55+
#' and other virtual file systems, see
56+
#' \url{https://gdal.org/en/stable/user/virtual_file_systems.html}.
1257
#'
1358
#' @param src A character string specifying the data source as a file name or
1459
#' database connection string (see Details).
1560
#' @param table Optional character string giving the name of a table in `src`
16-
#' from which tree records will be fetched. Generally needed with RDBMS sources
17-
#' containing multiple tables, as opposed to a single-table source such as a
18-
#' CSV file.
61+
#' from which tree records will be fetched. Generally needed with database
62+
#' sources containing multiple tables, as opposed to a single-table source such
63+
#' as a CSV file.
1964
#' @param columns Optional character vector specifying a subset of column names
2065
#' in the source table to include in the result set.
2166
#' @param sql Optional character string containing a SQL SELECT statement to
@@ -24,6 +69,16 @@
2469
#' @return
2570
#' A data frame containing the tree records fetched from `src`.
2671
#'
72+
#' @note
73+
#' `src` can be any GDAL supported dataset. A full list of formats supported by
74+
#' the current GDAL installation can be obtained with:
75+
#' ```
76+
#' fmt <- gdalraster::gdal_formats()
77+
#' fmt$long_name[fmt$vector]
78+
#' ```
79+
#'
80+
#' For more details: \url{https://gdal.org/en/stable/drivers/vector/index.html}
81+
#'
2782
#' @export
2883
load_tree_data <- function(src, table = NULL, columns = DEFAULT_TREE_COLUMNS,
2984
sql = NULL) {
@@ -34,6 +89,11 @@ load_tree_data <- function(src, table = NULL, columns = DEFAULT_TREE_COLUMNS,
3489
if (!(is.character(src) && length(src) == 1))
3590
stop("'src' must be a single character string")
3691

92+
if (!gdalraster::ogr_ds_exists(src)) {
93+
cli::cli_alert_danger("connection to {.path {src}} failed")
94+
stop("could not connect to 'src'", call. = FALSE)
95+
}
96+
3797
if (!is.null(table) && !is.null(sql))
3898
stop("'table' and 'sql' are mutually exclusive", call. = FALSE)
3999

@@ -46,6 +106,26 @@ load_tree_data <- function(src, table = NULL, columns = DEFAULT_TREE_COLUMNS,
46106
if (!is.null(sql) && !(is.character(sql) && length(sql == 1)))
47107
stop("'sql' must be a single character string")
48108

109+
if (is.null(sql) && !is.null(columns)) {
110+
if (any(c("DIST", "AZIMUTH") %in% columns)) {
111+
tbl <- ""
112+
if (!is.null(table))
113+
tbl <- table
114+
115+
if (gdalraster::ogr_field_index(src, tbl, "DIST") < 0 ||
116+
gdalraster::ogr_field_index(src, tbl, "AZIMUTH") < 0) {
117+
118+
cli::cli_alert_warning(c(
119+
"The data source does not have ",
120+
"{.field DIST} and/or {.field AZIMUTH}"))
121+
122+
columns <- columns[!columns %in% c("DIST", "AZIMUTH")]
123+
if (length(columns) == 0)
124+
columns = ""
125+
}
126+
}
127+
}
128+
49129
ds <- NULL
50130
if (is.null(table) && is.null(sql)) {
51131
ds <- try(methods::new(gdalraster::GDALVector, src), silent = TRUE)
@@ -56,15 +136,27 @@ load_tree_data <- function(src, table = NULL, columns = DEFAULT_TREE_COLUMNS,
56136
ds <- try(methods::new(gdalraster::GDALVector, src, sql), silent = TRUE)
57137
}
58138

59-
if (!methods::is(ds, "Rcpp_GDALVector"))
60-
stop("failed to establish a connection to 'src'", call. = FALSE)
139+
if (!methods::is(ds, "Rcpp_GDALVector")) {
140+
cli::cli_alert_danger("failed to access tree data in {.path {src}}")
141+
if (!is.null(sql))
142+
stop("execute SQL failed on 'src'", call. = FALSE)
143+
else
144+
stop("table access failed on 'src'", call. = FALSE)
145+
} else {
146+
on.exit(ds$close(), add = TRUE)
147+
}
61148

62149
if (!is.null(columns) && columns[1] != "")
63150
ds$setSelectedFields(columns)
64151

65-
cli::cli_progress_step("Fetching tree records")
152+
cli::cli_progress_step("Fetching tree data...")
66153
d <- ds$fetch(-1)
154+
cli::cli_progress_done()
155+
156+
if (nrow(d) == 0)
157+
cli::cli_alert_danger("No tree records were returned")
158+
else
159+
cli::cli_alert_info("{.val {nrow(d)}} tree records returned")
67160

68-
ds$close()
69161
return(d)
70162
}

inst/WORDLIST

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ FIA
2020
FIADB
2121
Finco
2222
Furnas
23+
GDAL
2324
Garman
25+
GeoPackage
2426
Geoinformation
2527
Goerndt
2628
ISSN
@@ -59,6 +61,7 @@ Spaeth
5961
Tavernia
6062
Tobin
6163
Tolk
64+
VSI
6265
Vogelmann
6366
Vojta
6467
WO
@@ -68,6 +71,7 @@ Xuexia
6871
al
6972
allometric
7073
et
74+
gpkg
7175
loblolly
7276
macroplot
7377
microplot
@@ -78,3 +82,4 @@ ownerships
7882
rangeland
7983
rangelands
8084
spatstat
85+
sqlite

man/load_tree_data.Rd

Lines changed: 59 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)