Skip to content

Commit cc33e20

Browse files
authored
Merge pull request #192 from elipousson/supportsPagination-fix
Fix #191 and #188
2 parents bd83f9f + 347159e commit cc33e20

File tree

3 files changed

+96
-22
lines changed

3 files changed

+96
-22
lines changed

NEWS.md

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
- Add `pull_field_aliases()` utility function
66
- `arc_select()` now uses `arcgisutils::rbind_results()` for faster row-binding if `{collapse}`, `{data.table}`, `{vctrs}` are installed (#175)
77
- Preserve order of `fields` column names for `arc_select()` (fixes minor bug with `arc_read` handling of `col_names`) (#185)
8+
- Set CRS for a FeatureLayer or ImageServer using `"wkid"` or `"wkt"` value if `"latestWkid"` is missing. (#188)
9+
- Fix issue with `arc_select()` when layer can't support pagination. (#191)
810

911
# arcgislayers 0.2.0
1012

R/arc-select.R

+67-19
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ collect_layer <- function(
156156
page_size = NULL,
157157
...,
158158
error_call = rlang::caller_env()) {
159-
160159
# 1. Make base request
161160
# 2. Identify necessary query parameters
162161
# 3. Figure out offsets and update query parameters
@@ -203,28 +202,22 @@ collect_layer <- function(
203202
# Offsets -----------------------------------------------------------------
204203

205204
# count the number of features in a query
206-
n_feats <- count_results(req, query_params, n_max = n_max, error_call = error_call)
205+
n_feats <- count_results(
206+
req = req,
207+
query = query_params,
208+
n_max = n_max,
209+
error_call = error_call
210+
)
207211

208-
# create a list of record counts based on number of features, page size and max records
209-
record_offsets <- set_record_offsets(
212+
all_resps <- get_query_resps(
213+
x = x,
214+
req = req,
210215
n_feats = n_feats,
211216
page_size = page_size,
212-
max_records = x[["maxRecordCount"]],
217+
query_params = query_params,
213218
error_call = error_call
214219
)
215220

216-
# create a list of requests from the offset and page sizes
217-
all_requests <- mapply(
218-
add_offset,
219-
.offset = record_offsets[["offsets"]],
220-
.page_size = record_offsets[["counts"]],
221-
MoreArgs = list(.req = req, .params = query_params),
222-
SIMPLIFY = FALSE
223-
)
224-
225-
# make all requests and store responses in list
226-
all_resps <- httr2::req_perform_parallel(all_requests, on_error = "continue")
227-
228221
# identify any errors
229222
# TODO: determine how to handle errors
230223
# has_error <- vapply(all_resps, function(x) inherits(x, "error"), logical(1))
@@ -264,6 +257,62 @@ collect_layer <- function(
264257
res
265258
}
266259

260+
#' Get query responses with handling for layers that don't support pagination
261+
#' @noRd
262+
get_query_resps <- function(
263+
req,
264+
x,
265+
n_feats,
266+
page_size = NULL,
267+
query_params = list(),
268+
error_call = rlang::caller_env()) {
269+
# If pagination is not supported, we create one query and return the results
270+
# in a list with a warning. This way the maximum number of results is returned
271+
# but the user is also informed that they will not get tha maximum number of
272+
# records. Otherwise, we continue and utilize the pagination
273+
if (isFALSE(x[["advancedQueryCapabilities"]][["supportsPagination"]])) {
274+
if (n_feats > x[["maxRecordCount"]]) {
275+
cli::cli_warn(
276+
c(
277+
"{class(x)} {.val {x[['name']]}} does not support pagination and
278+
complete results can't be returned.",
279+
"i" = "{n_feats} features are selected by the query and the maximum
280+
is {x[['maxRecordCount']]} records."
281+
)
282+
)
283+
}
284+
285+
req <- httr2::req_body_form(
286+
httr2::req_url_path_append(req, "query"),
287+
!!!query_params
288+
)
289+
290+
resp <- httr2::req_perform(req, error_call = error_call)
291+
292+
return(list(resp))
293+
}
294+
295+
# create a list of record counts based on number of features, page size and max records
296+
record_offsets <- set_record_offsets(
297+
n_feats = n_feats,
298+
page_size = page_size,
299+
max_records = x[["maxRecordCount"]],
300+
error_call = error_call
301+
)
302+
303+
# create a list of requests from the offset and page sizes
304+
all_requests <- mapply(
305+
add_offset,
306+
.offset = record_offsets[["offsets"]],
307+
.page_size = record_offsets[["counts"]],
308+
MoreArgs = list(.req = req, .params = query_params),
309+
SIMPLIFY = FALSE
310+
)
311+
312+
# make all requests and store responses in list
313+
httr2::req_perform_parallel(all_requests, on_error = "continue")
314+
}
315+
267316

268317
# utility -----------------------------------------------------------------
269318

@@ -425,8 +474,7 @@ count_results <- function(req, query, n_max = Inf, error_call = rlang::caller_en
425474
validate_results_count <- function(
426475
n_results = NULL,
427476
n_max = Inf,
428-
error_call = rlang::caller_env()
429-
) {
477+
error_call = rlang::caller_env()) {
430478
if (is.null(n_results)) {
431479
cli::cli_abort(
432480
c(

R/sf-methods.R

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,36 @@
1-
21
# st_crs method for feature layer
32
st_crs.FeatureLayer <- function(obj, ...) {
4-
sf::st_crs(obj[["extent"]][["spatialReference"]][["latestWkid"]])
3+
arc_sr_as_crs(obj)
54
}
65

76
st_crs.ImageServer <- function(obj, ...) {
8-
sf::st_crs(obj[["extent"]][["spatialReference"]][["latestWkid"]])
7+
arc_sr_as_crs(obj)
98
}
109

10+
#' Get a Coordinate Reference System from a FeatureLayer or ImageServer spatial
11+
#' reference
12+
#'
13+
#' [arc_sr_as_crs()] converts a FeatureLayer or ImageServer into a coordinate
14+
#' reference system (CRS) using [sf::st_crs()].
15+
#'
16+
#' @param x A FeatureLayer or ImageServer or another object with a named
17+
#' `"spatialReference"` element that can be converted to a coordinate
18+
#' reference system with [sf::st_crs()].
19+
#' @seealso [arcgisutils::validate_crs()]
20+
#' @returns An object of class crs of length 2.
21+
#' @noRd
22+
arc_sr_as_crs <- function(x) {
23+
if (rlang::has_name(x, "extent")) {
24+
spatialReference <- x[["extent"]][["spatialReference"]]
25+
} else {
26+
spatialReference <- x[["spatialReference"]] %||% list()
27+
}
28+
29+
x_crs <- spatialReference[["latestWkid"]] %||%
30+
spatialReference[["wkid"]] %||%
31+
spatialReference[["wkt"]]
32+
33+
sf::st_crs(x_crs)
34+
}
1135

1236
# Implement `st_transform()`

0 commit comments

Comments
 (0)