#' Get by FIDs
#'
#' Get a layer by querying the FIDs
#'
#' This function works by checking if the requested return count is less tha the max record count.
#' If so, it doesn't bother with getting the FIDs and just requests the data and returns it.
#' Getting FIDs is a big overhea so this should be avoided where possible.
#' @param endpoint a string defining the enpoint url.
#' It can be generated by the \code{feature_server_endpoint} and \code{map_server_endpoint} functons.
#' See https://developers.arcgis.com/rest/services-reference/get-started-with-the-services-directory.htm
#' @param my_token an access token acquired via \code{get_token}
#' @param query the query to POST
#' @param return_geometry should the geometry be returned or just a table?
#' @param return_n how many features (maximum) should be returned by the query?
#' @param layer_details the layer details returned by the get_layer_details function
#' @param out_fields the fields of the layer to return (character vector)
#' @param object_ids a vector of object IDs to return if this argument is NULL the function will get them
#' but passing them in aids performance if they have already been returned
#' @return a tibble or sf object
#' @importFrom progress progress_bar
#' @importFrom purrr map
#' @importFrom dplyr bind_rows
#' @importFrom utils modifyList
get_by_fids <-
function(endpoint,
query,
my_token,
return_geometry,
return_n,
layer_details,
out_fields,
object_ids = NULL) {
# This function works by checking if the requested return count is less tha the max record count.
# If so, it doesnn't bother with getting the FIDs and just requests the data and returns it.
# Getting FIDs is a big overhea so this should be avoided where possible.
query_url <- paste0(endpoint, "/query")
if(is.null(object_ids)){
# If Object IDs are null then get them for the query
# The FIDs are used for two things: first to determine if any results will be returned by a query;
# second to get the data by FIDs
object_ids <-
get_feature_ids(endpoint = endpoint,
query = query,
my_token = my_token)
}
# Check if any FIDs will be returned by the query, if not return an empty tibble avoiding the query
if (length(object_ids$objectIds) == 0) {
warning("No data matching query, returning an empty tibble")
return(
make_empty_table(
field_names = field_names(layer_details),
out_fields = out_fields,
id_field = object_ids$objectIdFieldName,
return_geometry = return_geometry
)
)
}
# Then split the vector so it doesn't exceed the max record count
object_ids_split <-
split_vector(x = object_ids$objectIds,
max_length = layer_details$maxRecordCount)
querys <-
purrr::map(object_ids_split,
~ utils::modifyList(
query,
id_query(object_id_name = object_ids$objectIdFieldName, object_ids = .x, map_server = map_server(endpoint))
), keep.null = FALSE)
# Define a progress bar
pb <- progress::progress_bar$new(
total = length(querys),
clear = FALSE,
width = 60,
format = " Downloading data [:bar] :percent in :elapsed eta: :eta"
)
# Download the data for each query
data_list <- purrr::map(
querys,
~ get_data(
query_url = query_url,
query = .x,
my_token = my_token,
pb = pb
)
)
# Need to add some error checking functionality here
# any(names(data_list) == "error") stop() message(cat(data_list))
# Parse the json returned by the api
parse_esri_data(data_list,
geometry = return_geometry & !is_table(layer_details))
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.