diff --git a/NAMESPACE b/NAMESPACE index 217c644..1294323 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,6 +1,7 @@ # Generated by roxygen2: do not edit by hand export(address_to_coords) +export(coords_to_address) export(get_phylopic_image) export(get_world_basemap) export(hiking_time) diff --git a/R/coords_to_address.R b/R/coords_to_address.R new file mode 100644 index 0000000..7dee7ec --- /dev/null +++ b/R/coords_to_address.R @@ -0,0 +1,86 @@ +#' Retrieve OSM address from coordinates +#' +#' @description +#' Retrieves any location name in the World from geographic coordinates +#' (longitude and latitude) using the OpenStreetMap Data Search Engine Nominatim +#' \url{http://nominatim.openstreetmap.org}. +#' +#' @param coords a `numeric` of length 2. The first element is the `latitude` +#' and the second the `longitude`. +#' +#' @export +#' +#' @return A `character` of length 1 with the OSM name of the location. +#' +#' @examples +#' coords_to_address(c(43.61277, 3.873486)) +#' coords_to_address(c(29.75894, -95.3677)) + +coords_to_address <- function(coords) { + + ## Check args ---- + + if (missing(coords)) { + stop("Argument 'coords' is required", call. = FALSE) + } + + if (is.null(coords)) { + stop("Argument 'coords' cannot be NULL", call. = FALSE) + } + + if (!is.numeric(coords)) { + stop("Argument 'coords' must be numeric", call. = FALSE) + } + + if (length(coords) != 2) { + stop("Argument 'coords' must be numeric of length 2", call. = FALSE) + } + + if (coords[1] > 90 || coords[1] < -90) { + stop("Latitude must be the first element of 'coords'", call. = FALSE) + } + + + ## API URL ---- + + api_url <- "https://nominatim.openstreetmap.org/reverse" + + + ## Build request ---- + + full_url <- paste0(api_url, "?lat=", coords[1], "&lon=", coords[2], + "&format=json&limit=1") + + + ## Send request ---- + + results <- httr::GET(full_url) + + + ## Check status code ----- + + if (results$"status_code" != 200) { + stop("An error with the Nominatim API occurred", call. = FALSE) + } + + + ## Parse results ---- + + results <- httr::content(results, as = "text") + results <- jsonlite::fromJSON(results) + + + ## Clean results ---- + + if (length(results) == 0) { + + address <- NULL + + } else { + + address <- results$"display_name" + + } + + address +} diff --git a/man/coords_to_address.Rd b/man/coords_to_address.Rd new file mode 100644 index 0000000..f85e251 --- /dev/null +++ b/man/coords_to_address.Rd @@ -0,0 +1,24 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/coords_to_address.R +\name{coords_to_address} +\alias{coords_to_address} +\title{Retrieve OSM address from coordinates} +\usage{ +coords_to_address(coords) +} +\arguments{ +\item{coords}{a \code{numeric} of length 2. The first element is the \code{latitude} +and the second the \code{longitude}.} +} +\value{ +A \code{character} of length 1 with the OSM name of the location. +} +\description{ +Retrieves any location name in the World from geographic coordinates +(longitude and latitude) using the OpenStreetMap Data Search Engine Nominatim +\url{http://nominatim.openstreetmap.org}. +} +\examples{ +coords_to_address(c(43.61277, 3.873486)) +coords_to_address(c(29.75894, -95.3677)) +} diff --git a/tests/testthat/test-coords_to_address.R b/tests/testthat/test-coords_to_address.R new file mode 100644 index 0000000..e4f1006 --- /dev/null +++ b/tests/testthat/test-coords_to_address.R @@ -0,0 +1,64 @@ +## Test coords_to_address function ---- + +test_that("Function coords_to_address() - Test for error", { + + expect_error(coords_to_address(), + "Argument 'coords' is required", + fixed = TRUE) + + expect_error(coords_to_address(NULL), + "Argument 'coords' cannot be NULL", + fixed = TRUE) + + expect_error(coords_to_address(iris), + "Argument 'coords' must be numeric", + fixed = TRUE) + + expect_error(coords_to_address("character"), + "Argument 'coords' must be numeric", + fixed = TRUE) + + expect_error(coords_to_address(0.00), + "Argument 'coords' must be numeric of length 2", + fixed = TRUE) + + expect_error(coords_to_address(c(0.00, 0.00, 0.00)), + "Argument 'coords' must be numeric of length 2", + fixed = TRUE) + + expect_error(coords_to_address(c(180.00, 0.00)), + "Latitude must be the first element of 'coords'", + fixed = TRUE) +}) + + +test_that("Function coords_to_address() - Test for success", { + + ## Good address ---- + + expect_silent({ + x <- coords_to_address(c(29.75894, -95.3677)) + }) + + expect_equal(class(x), "character") + expect_equal(length(x), 1L) + + expect_null(names(x)) + + expect_equal(x, paste0("One Shell Plaza, 910, Louisiana Street, Houston, ", + "Harris County, Texas, 77002, United States")) + + + ## Bad address (Atlantic Ocean) ---- + + expect_silent({ + x <- coords_to_address(c(-40.429864, 21.471329)) + }) + + expect_equal(class(x), "NULL") + expect_equal(length(x), 0L) + + expect_null(names(x)) + + expect_null(x) +})