API Example Using R
# This data frame contains the coordinate pairs for the vertices of the polygon # for an AOI. You can get an equivalent data frame from an sf polygon object # using sf::st_coordinates(). Note that the first and last coordinates are # identical in order to close the polygon. aoi_vertex_coords <- data.frame(X = c(-106.416024, -106.157845, -106.146859, -106.328133, -106.388558, -106.454476, -106.416024), Y = c(44.086577, 44.228451, 44.471990, 44.417086, 44.318914, 44.193015, 44.086577)) # This creates the coordinate strings formatted for use in a geoJSON using the # data frame of coordinates. The expected format for a coordinate pair is # "[-106.454476,44.193015]". This could be achieved with an apply() but using # mutate() from the package dplyr is more readable. aoi_vertex_coords <- dplyr::mutate(.data = aoi_vertex_coords, # This creates a new variable with the strings # for each row. coordinate_string = paste0("[", X, ",", Y, "]")) # These are the pieces of the geoJSON string that go before and after the # coordinates. In the postcoordinate string, you may define "mask" as true to # ignore cropland, development, and open water or false to include those. # Note that in order for this to work, the strings defining the geoJSON *must* # use quotation marks internally, so the strings themselves need to be wrapped # in aprostrophes, e.g. '{"type":"Feature"}' and not "{'type':'Feature'}". geojson_precoordinate_string <-'{"type":"Feature", "geometry": {"geodesic":false, "type":"Polygon", "coordinates":[[' geojson_postcoordinate_string <- ']]}, "properties": {"mask":true, "year":null} }' # The components can be assembled into a single geoJSON string. # The coordinate strings in the data frame need to be collapsed into a single # string where each pair is separated by a comma. aoi_geojson <- paste0(geojson_precoordinate_string, paste(aoi_vertex_coords[["coordinate_string"]], collapse = ","), geojson_postcoordinate_string) # Using httr::RETRY() will let R make multiple attempts to retrieve the data # before giving up. Importantly, the verb argument must be "POST", the URL must # point to the correct API endpoint for the data you want, config should at # least specify that the desired return format is JSON, and the body argument # needs to be the geoJSON string constructed for the AOI. rap_json <- httr::RETRY(verb = "POST", url = "https://us-central1-rap-data-365417.cloudfunctions.net/production16dayV3", config = httr::content_type_json(), body = aoi_geojson) # httr::content() will convert the returned JSON into more conventional R # objects: nested lists containing the various kinds of values in the JSON. rap_obj <- httr::content(x = rap_json, as = "parsed") # The returned and parsed object will be a list. One of the values in the list # will be another list named "properties" which contains yet another list of # each of the rows in the returned dataset, including the variable names as the # first vector in the list. In this case, the data are for 16-day production. returned_data_raw_list <- rap_obj$properties$production16day # There's no "correct" way way to convert the list into a data frame. One of the # more straightforward is by turning each list of values in the list into a # data frame then combining those with dplyr:bind_rows(). returned_data_raw_list <- lapply(X = returned_data_raw_list[2:length(returned_data_raw_list)], variable_names = returned_data_raw_list[[1]], FUN = function(X, variable_names){ # The current values need the variable names, # so this makes sure that variable_names is a # vector before assigning them to the current # row's values which are called X within the # lapply(). names(X) <- unlist(variable_names) # Make a wide-format data frame out of the # current values by binding them column-wise # which results in a single data frame with # correctly-named variables thanks to the # naming of X above. dplyr::bind_cols(X) }) returned_data_raw_dataframe <- dplyr::bind_rows(returned_data_raw_list) # The data returned will include some values that need to be adjusted before # using, which can be accomplished with dplyr::mutate(). returned_data <- dplyr::mutate(.data = returned_data_raw_dataframe, # Convert the date from a character string to a # value of class "date". date = as.Date(date), # Make sure the year is numeric because it may be # a character string. year = as.numeric(year), # Make sure the day of the year is also numeric # and adjust so that the highest value is 365 and # not 366. doy = as.numeric(doy) - 1, # The rest of the variables should be numeric and # rounded to 3 decimal places. Additionally, any # values of -99 should be considered NA values. # Using dplyr::across() here applies the # replacement, conversion, and rounding to all # variables after the first three, i.e., after # date, year, and doy. dplyr::across(.cols = -c(1:3), .fns = ~ replace(x = .x, list = .x == -99, values = NA) |> as.numeric(x = _) |> round(x = _, digits = 3)))