#' Get Theme Data from OneMap.Sg
#'
#' @description
#' This function is a wrapper for the \href{https://www.onemap.gov.sg/docs/#retrieve-theme}{Retrieve Theme API}. It returns the data as cleaned tibbles.
#'
#' @param token User's API token. This can be retrieved using \code{\link{get_token}}
#' @param theme OneMap theme in its \code{QUERYNAME} format. A tibble of available themes can be retrieved using \code{\link{search_themes}}
#' @param extents Optional, Location Extents for search. This should be in the format "Lat1,\%20Lng1,Lat2,\%20Lng2". For more information, consult the \href{https://www.onemap.gov.sg/docs/#retrieve-theme}{API Documentation}.
#' @param return_info Default = \code{FALSE}. If \code{FALSE}, function only returns a tibble for query results. If \code{TRUE}, function returns output as a list containing a tibble for query information and a tibble for query results.
#' @param read Optional, format to read output. Valid parameters are \code{tibble}, \code{sf} and \code{rgdal}. For "sf" objects, specify \code{read = "sf"} and for "sp" objects use \code{read = "rgdal"}. Defaults to \code{tibble} if any other value is used. Please ensure the \code{sf} package is installed, else this parameter return a tibble.
#'
#' @return If no error occurs:
#' \describe{
#' \item{query_info}{A 1 x 7 tibble containing information about the query. The variables are \code{FeatCount}, \code{Theme_Name}, \code{Category}, \code{Owner}, \code{DateTime.date}, \code{DateTime.timezone_type}, \code{DateTime.timezone}}
#' \item{query_result}{Returned if return_info = \code{TRUE}. A tibble containing the data retrieved from the query. The columns and rows vary depending on theme and user specification, however all tibbles will contain the variables: \code{NAME}, \code{DESCRIPTION}, \code{ADDRESSPOSTALCODE}, \code{ADDRESSSTREETNAME}, \code{Lat}, \code{Lng}, \code{ICON_NAME}}
#' }
#'
#' If an error occurs, the output will be \code{NULL}, along with a warning message.
#' For non-error queries where 0 results are returned, the output will be \code{query_info}, along with a warning message.
#'
#' @export
#'
#' @examples
#' # returns a tibble of output
#' \dontrun{get_theme(token, "hotels")}
#' \dontrun{get_theme(token, "monuments",
#' extents = "1.291789,%20103.7796402,1.3290461,%20103.8726032")}
#'
#' # returns a sf dataframe
#' \dontrun{get_theme(token, "hotels", read = "sf")}
#'
#' # returns a list of status tibble and output tibble
#' \dontrun{get_theme(token, "funeralparlours", return_info = TRUE)}
#'
#' # error: output is NULL, warning message shows status code
#' \dontrun{get_theme("invalid_token", "hotels")}
#'
#' # error: output is NULL, warning message shows error message from request
#' \dontrun{get_theme(token, "non-existent-theme")}
#'
#' # error: output is \code{query_info}, warning message query did not return any records
#' \dontrun{get_theme(token, "ura_parking_lot", "1.291789,%20103.7796402,1.3290461,%20103.8726032")}
get_theme <- function(token, theme, extents = NULL, return_info = FALSE, read = "tibble") {
# query API
url <- "https://developers.onemap.sg/privateapi/themesvc/retrieveTheme?"
query <- paste(url,
"queryName=", theme,
"&token=", token,
sep = "")
if (!is.null(extents)) {query <- paste(query, "&extents=", extents, sep = "")}
response <- GET(query)
query_results <- content(response)
# error check: invalid request
if (http_error(response)) {
status <- status_code(response)
output <- NULL
warning(paste("The request produced a", status, "error", sep = " "))
# else return output
} else {
# error check: invalid parameters
if (names(query_results[[1]][[1]][1]) == "ErrorMessage") {
output <- NULL
error_msg <- query_results[[1]][[1]][[1]][[1]]
warning(paste("The request returned the following error message:", error_msg, sep = " "))
# error check: output length 0
} else if (length(query_results$SrchResults) == 1) {
output <- query_results[[1]][[1]] %>%
unlist() %>% t() %>%
as_tibble()
warning("There are 0 matching records for your query.")
} else {
# transform output to dataframe
output <- query_results[[1]][-1] %>%
reduce(bind_rows) %>%
separate(col = "LatLng", into = c("Lat", "Lng"), sep = ",")
if (read %in% c("sf", "rgdal") & requireNamespace("sf", quietly = TRUE)) {
output <- sf::st_as_sf(output, coords = c("Lng", "Lat"))
if (read == "rgdal") {
output <- sf::as_Spatial(output)
}
}
# transform output to a list containing query info and query results if user wants info
if (return_info) {
# store query info
query_info <- query_results[[1]][[1]] %>%
unlist() %>% t() %>%
as_tibble()
# reformat output
output <- list(query_info = query_info, query_results = output)
}
}
}
output
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.