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
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
2883load_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}
0 commit comments