diff --git a/.Rbuildignore b/.Rbuildignore
index fb4e26f..b7f369c 100644
--- a/.Rbuildignore
+++ b/.Rbuildignore
@@ -1,16 +1,15 @@
^.*\.Rproj$
^\.Rproj\.user$
-^\.travis\.yml$
docs
tests
_pkgdown.yml
vignettes
cran-checks.md
-Documentation.pdf
-.Rd2pdf27338
paper
pkgdown
^README.Rmd
.github
^codemeta\.json$
data-raw
+.covrignore
+codecov.yml
diff --git a/.covrignore b/.covrignore
new file mode 100644
index 0000000..44cd488
--- /dev/null
+++ b/.covrignore
@@ -0,0 +1 @@
+R/aoi_draw.R
diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml
new file mode 100644
index 0000000..b1f84b8
--- /dev/null
+++ b/.github/workflows/test-coverage.yaml
@@ -0,0 +1,28 @@
+on:
+ push:
+ branches: [main, master]
+ pull_request:
+ branches: [main, master]
+
+name: Test coverage
+
+jobs:
+ test-coverage:
+ runs-on: ubuntu-latest
+ env:
+ GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - uses: r-lib/actions/setup-r@v2
+ with:
+ use-public-rspm: true
+
+ - uses: r-lib/actions/setup-r-dependencies@v2
+ with:
+ extra-packages: covr
+
+ - name: Test coverage
+ run: covr::codecov()
+ shell: Rscript {0}
diff --git a/.gitignore b/.gitignore
index 6466ea4..e2cd5c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,4 @@
pkgdown
.DS_Store
paper
+inst/doc
diff --git a/DESCRIPTION b/DESCRIPTION
index dd16e0d..a6f859d 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -3,26 +3,42 @@ Type: Package
Title: Areas of Interest
Version: 0.3.0
Authors@R: c(person(given = "Mike", family = "Johnson", role = c("aut", "cre"), email = "mikecp11@gmail.com", comment = c(ORCID = "0000-0002-5288-8350")),
- person(given = "Justin", family = "Singh-Mohudpur", role = "rev", email = "justin@justinsingh.me", comment = c(ORCID = "0000-0002-5233-5799")))
+ person(given = "Justin", family = "Singh-Mohudpur", role = "ctb", email = "justin@justinsingh.me", comment = c(ORCID = "0000-0002-5233-5799")))
BugReports: https://github.com/mikejohnson51/AOI/issues
Description: A consistent tool kit for forward and reverse geocoding and defining boundaries for spatial analysis.
-Depends:
+Depends:
R(>= 3.5.0)
-Imports:
- rvest,
+Imports:
+ datasets,
+ dplyr,
fipio,
+ htmlwidgets,
jsonlite,
- sf,
+ leaflet,
+ leaflet.extras,
rnaturalearth,
- tidygeocoder
-Suggests:
- testthat,
- covr,
+ rvest,
+ sf,
shiny,
- leaflet,
- leaflet.extras
+ terra,
+ tidygeocoder,
+ units
+Suggests:
+ climateR,
+ distill,
+ FedData,
+ gdalio,
+ knitr,
+ mapview,
+ nhdplusTools,
+ osmdata,
+ raster,
+ rmarkdown,
+ testthat,
+ zonal
License: MIT + file LICENSE
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.2.3
URL: https://github.com/mikejohnson51/AOI/
+VignetteBuilder: knitr
diff --git a/NAMESPACE b/NAMESPACE
index b7d623e..e05aecb 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -1,22 +1,26 @@
# Generated by roxygen2: do not edit by hand
-export(alt_page)
-export(aoi_buffer)
export(aoi_describe)
export(aoi_draw)
+export(aoi_ext)
export(aoi_get)
export(aoi_inside)
export(aoi_map)
export(bbox_coords)
export(bbox_get)
+export(discritize)
export(fip_meta)
export(geocode)
-export(geocodeAOI)
export(geocode_rev)
export(geocode_wiki)
-export(getClip)
export(getFiat)
export(list_states)
+importFrom(dplyr,`%>%`)
+importFrom(dplyr,any_of)
+importFrom(dplyr,contains)
+importFrom(dplyr,mutate)
+importFrom(dplyr,rename)
+importFrom(dplyr,select)
importFrom(fipio,as_fips)
importFrom(fipio,fips_metadata)
importFrom(jsonlite,fromJSON)
@@ -27,18 +31,26 @@ importFrom(rvest,html_table)
importFrom(rvest,html_text)
importFrom(rvest,read_html)
importFrom(sf,`%>%`)
+importFrom(sf,st_area)
importFrom(sf,st_as_sf)
importFrom(sf,st_as_sfc)
importFrom(sf,st_bbox)
importFrom(sf,st_buffer)
importFrom(sf,st_cast)
importFrom(sf,st_crs)
+importFrom(sf,st_drop_geometry)
importFrom(sf,st_geometry_type)
importFrom(sf,st_intersection)
importFrom(sf,st_intersects)
+importFrom(sf,st_is)
+importFrom(sf,st_is_longlat)
+importFrom(sf,st_point)
importFrom(sf,st_polygon)
+importFrom(sf,st_set_crs)
importFrom(sf,st_sf)
importFrom(sf,st_sfc)
importFrom(sf,st_transform)
importFrom(sf,st_union)
importFrom(tidygeocoder,geo)
+importFrom(tidygeocoder,reverse_geo)
+importFrom(units,set_units)
diff --git a/NEWS.md b/NEWS.md
index 3d67aed..bb11990 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -1,6 +1,29 @@
-AOI 0.2.0 (2021-03-30)
+AOI 0.3.0 (2023-09)
=========================
### NEW FEATURES
- * `aoi_draw()` - Interactivly draw an Area of Interest (AOI) using a `shiny` app.
\ No newline at end of file
+ * Change original OpenStreetMap geocoder to `tidygeocoder` due to new restrictions
+ * Previously, we allowed the following for place based area requests:
+ - c(GEO, distance, distance) --> POLYGON
+ - c(lat, lng, distance, distance) --> POLYGON
+
+ * We now support:
+ - c(lat, lng) --> POINT
+ - c(lat, lng, distance) --> POLYGON
+
+ * All of these have been moved from aoi_get to aoi_ext which uses:
+ - geo
+ - xy
+ - wh
+
+ * materialize_grid from zonal was moved here and called discritize
+
+ * Works with terra not raster objects
+
+AOI 0.2.0 (2021-03)
+=========================
+
+### NEW FEATURES
+
+ * `aoi_draw()` - Interactively draw an Area of Interest (AOI) using a `shiny` app.
diff --git a/R/aoi_describe.R b/R/aoi_describe.R
index d9a37fb..1d46953 100644
--- a/R/aoi_describe.R
+++ b/R/aoi_describe.R
@@ -10,21 +10,19 @@
#' nc <- sf::read_sf(fname)
#' aoi_describe(AOI = nc[1, ])
#' }
-#' @importFrom sf st_transform st_bbox
-#'
aoi_describe = function(AOI){
- if(any(sf::st_is(AOI, "POLYGON") | sf::st_is(AOI, "MULTIPOLYGON"))){
- tot_area = sum(sf::st_area(AOI)) / 1e6
- bb = sf::st_bbox(AOI)
- bb_area = sf::st_area(sf::st_as_sfc(bb)) / 1e6
+ if(any(st_is(AOI, "POLYGON") | st_is(AOI, "MULTIPOLYGON"))){
+ tot_area = sum(st_area(AOI)) / 1e6
+ bb = st_bbox(AOI)
+ bb_area = st_area(st_as_sfc(bb)) / 1e6
coverage_per = 100 * (tot_area / bb_area)
tot_units = nrow(AOI)
geom = "POLYGON"
} else {
tot_area = NULL
- bb = sf::st_bbox(AOI)
+ bb = st_bbox(AOI)
bb_area = NULL
coverage_per = NULL
tot_units = nrow(AOI)
diff --git a/R/aoi_draw.R b/R/aoi_draw.R
index f12d80a..a29036b 100644
--- a/R/aoi_draw.R
+++ b/R/aoi_draw.R
@@ -93,7 +93,7 @@ aoi_draw <- function() {
# store the sf in a reactiveValues
values <- shiny::reactiveValues()
- values$sf <- sf::st_sf(sf::st_sfc(crs = 4326))
+ values$sf <- st_sf(st_sfc(crs = 4326))
# update map with user input
shiny::observeEvent(input$aoi_draw_new_feature, {
@@ -107,7 +107,7 @@ aoi_draw <- function() {
tmp <- shiny::isolate(
sf::st_as_sf(
sf::st_sf(
- geometry = sf::st_sfc(sf::st_polygon(list(coords))),
+ geometry = st_sfc(st_polygon(list(coords))),
crs = 4326
)
)
@@ -116,7 +116,7 @@ aoi_draw <- function() {
if (feature_type %in% c("rectangle", "polygon")) {
new_sf <- tmp
} else {
- new_sf <- sf::st_cast(tmp, "POINT")
+ new_sf <- st_cast(tmp, "POINT")
}
shiny::isolate(values$sf <- rbind(values$sf, new_sf))
diff --git a/R/aoi_ext.R b/R/aoi_ext.R
new file mode 100644
index 0000000..90bb7e8
--- /dev/null
+++ b/R/aoi_ext.R
@@ -0,0 +1,150 @@
+#' AOI extent
+#'
+#' Build an extent surrinding by location point (longitude, latitude) based on a width and height.
+#'
+#'
+#' @param geo an origion specificed by a name
+#' @param xy a orign specified as a numeric vector
+#' @param wh width and height (can be a single number) in units (see units arg)
+#' @param units units of wh expansion
+#' @param crs output crs
+#' @param bbox return bbox object?
+#' @return vector or sf object
+#' @export
+
+aoi_ext = function(geo = NULL, xy = NULL, wh = NULL, units = default_units,
+ crs = default_crs, bbox = FALSE){
+
+ if(!is.null(geo) & is.null(wh)){
+ out = geocode(geo, pt = TRUE)
+ }
+
+ if(!is.null(geo) & !is.null(wh)){
+ xy = geocode(geo, xy = TRUE)
+ if(length(wh) == 1){ wh = c(wh, wh) }
+ out = .domain(xy, wh, units, crs, bbox)
+ }
+
+ if(!is.null(xy) & is.null(wh)){
+ out = st_point(x = xy, dim = "XY") %>%
+ st_sfc(crs = 4326) %>%
+ st_transform(crs)
+ }
+
+ if(!is.null(xy) & !is.null(wh)){
+ if(length(wh) == 1){ wh = c(wh, wh) }
+ out = .domain(xy, wh, units, crs, bbox)
+ }
+
+ out
+
+}
+
+
+#' Build Domain
+#' @inheritParams aoi_ext
+#' @return vector or sf object
+
+.domain = function(xy, wh, units = default_units, crs = default_crs, bbox = FALSE){
+
+ projection <- sprintf("+proj=%s +lon_0=%f +lat_0=%f +datum=WGS84", "laea", xy[1], xy[2])
+
+ pt = st_point(x = xy, dim = "XY") %>%
+ st_sfc(crs = crs) %>%
+ st_transform(projection)
+
+ w = wh[1]
+ units(w) <- units
+ w = as.numeric(set_units(w, "metre"))
+
+ h = wh[2]
+ units(h) <- units
+ h = as.numeric(set_units(h, "metre"))
+
+ bb = c(xmin = as.numeric(xy[1] - w),
+ xmax = as.numeric(xy[1] + w),
+ ymin = as.numeric(xy[2] - h),
+ ymax = as.numeric(xy[2] + h))
+
+ xx = st_bbox(bb) %>%
+ st_as_sfc() %>%
+ st_set_crs(projection) %>%
+ st_transform(crs)
+
+ if(!bbox){
+ return(st_bbox(xx))
+ } else {
+ return(xx)
+ }
+}
+
+#' Materialize Grid from File or inputs
+#' @param ext extent (xmin, xmax, ymin, ymax) in some coordinate system
+#' @param dim dimension (number of columns, number of rows)
+#' @param in_crs projection of input ext
+#' @param out_crs projection of output object
+#' @param spatrast should a SpatRaster object be returned? Default is FALSE
+#' @param fillValue in spatrast is TRUE, what values should fill the object
+#' @param showWarnings should warnings be shown?
+#' @return list or SpatRaster object
+#' @export
+
+discritize = function (ext = NULL,
+ dim = default_dim,
+ in_crs = default_crs,
+ out_crs = default_crs,
+ spatrast = FALSE,
+ fillValue = NULL,
+ showWarnings = TRUE) {
+
+
+ if (is.null(ext)) { stop("ext required.") }
+
+ tmp_crs = tryCatch({st_crs(ext)}, error = function(e){ NA })
+
+ if(!is.na(tmp_crs)){
+ in_crs = tmp_crs
+ } else {
+ if(in_crs == default_crs & showWarnings){
+ warning('Assuming the input is in CRS 4326', call. = FALSE)
+ }
+ }
+
+ projection = st_crs(out_crs)
+
+ ext = suppressWarnings({
+ bbox_get(ext) %>%
+ st_set_crs(in_crs) %>%
+ st_transform(projection$proj4string) %>%
+ st_bbox()
+ })
+
+ ext = ext[c(1,3,2,4)]
+
+ xl <- diff(ext[c(1,2)])
+ yl <- diff(ext[c(3,4)])
+ asp <- xl/yl * ifelse(st_is_longlat(projection$proj4string), cos(mean(yl) * pi/180), 1)
+
+ dims <- as.numeric(round(dim * sort(c(1, asp))))
+
+ if(spatrast){
+
+ check_pkg('terra')
+
+ r = terra::rast(terra::ext(ext),
+ nrows = dims[2],
+ ncols = dims[1],
+ crs = projection$proj4string)
+
+ if(!is.null(fillValue)){ r[] = fillValue }
+
+ } else {
+ r = list(extent = ext,
+ dimension = dims,
+ projection = projection$proj4string)
+ }
+
+ r
+}
+
+
diff --git a/R/aoi_get.R b/R/aoi_get.R
index 3e5ba77..5a243af 100644
--- a/R/aoi_get.R
+++ b/R/aoi_get.R
@@ -1,16 +1,8 @@
#' @title Get Area of Interest (AOI) geometry
#' @description Generate a spatial geometry from:
-#' \enumerate{
-#' \item Country name, 2-digit or 3-digit ISO abbreviation(s)
-#' \item Country Region or Continent (e.g. South Asia, Africa)
-#' \item US state name(s) or abbreviation(s)
-#' \item US region (e.g. Northeast, South, North Central, West)
-#' \item US state, county pair(s)
-#' \item a spatial, sf or raster object
-#' \item a clip unit (see details)
-#' }
+#' @param x \code{sf}, or a \code{Spat*} object
#' @param country \code{character}. Full name, ISO 3166-1 2 or 3 digit code.
-#' Not case senstive. Data comes from Natural Earth.
+#' Not case sensitive. Data comes from Natural Earth.
#' @param state \code{character}. Full name or two character abbreviation.
#' Not case sensitive. If \code{state = 'conus'}, the lower 48
#' states will be returned. If \code{state = 'all'}, all states
@@ -18,85 +10,16 @@
#' @param county \code{character}. County name(s). Requires \code{state} input.
#' Not case sensitive If 'all' then all counties in a state
#' are returned
-#' @param x \code{spatial}, \code{raster}, \code{sf} or a \code{list} object
-#' (see details for list parameters)
-#' @param fip a 2 or 3 digit US fip code
-#' @param km \code{logical}. If \code{TRUE} distances are in kilometers,
-#' default is \code{FALSE} with distances in miles
+#' @param fip a 2 or 5 digit US fip code
+#' @param zipcode a US zip code. Will return a centroid.
#' @param union \code{logical}. If TRUE objects are unioned into a single object
-#' @details
-#' A \code{x} unit can be described by just a place name (e.g. 'UCSB').
-#' In doing so the associated boundaries determined by \code{\link{geocode}}
-#' will be returned. To have greater control over the clip unit it can be
-#' defined as a list with a minimum of 3 inputs:
-#' \enumerate{
-#' \item A point:
-#' \itemize{
-#' \item 'place name' (\code{character}) ex: "UCSB" - or -
-#' \item 'lat/lon' pair: ex: "-36, -120"
-#' }
-#' \item A bounding box height (\code{numeric})
-#' \itemize{
-#' \item{in miles} ex: 10
-#' }
-#' \item A bounding box width (\code{numeric})
-#' \itemize{
-#' \item{in miles} ex: 10
-#' }
-#' }
-#'
-#' The bounding box is always drawn in relation to the point.
-#' By default, the point is treated as the center of the box.
-#' To define the relative location of the point to the bounding box,
-#' a fourth input can be used:
-#' \enumerate{
-#' \item Origin \itemize{
-#' \item 'center' (default)
-#' \item 'upperleft'
-#' \item 'upperright'
-#' \item 'lowerleft'
-#' \item 'lowerright'
-#' }
-#' }
-#' In total, 1 to 5 elements can be used to define \code{clip} element
-#' and \strong{ORDER MATTERS} (point, height, width, origin).
-#' Acceptable variations include:
-#' \itemize{
-#' \item 1 member: (1) place name
-#' \itemize{
-#' \item \emph{"UCSB"}
-#' }
-#' \item 1 member: (1) lat/lon pair
-#' \itemize{
-#' \item \emph{c(36, -119)}
-#' }
-#' \item 3 members: (1) location name, (2) height, (3) width
-#' \itemize{
-#' \item \emph{list("UCSB", 10, 10)}
-#' }
-#' \item 4 members: (1) lat, (2) lon, (3) height, (4) width
-#' \itemize{
-#' \item \emph{list(36, -120, 10, 10)}
-#' }
-#' \item 4 members: (1) place name, (2) height, (3) width, (4) origin
-#' \itemize{
-#' \item \emph{list("UCSB", 10, 10, "lowerright)}
-#' }
-#' \item 5 members: (1) lat, (2) lon, (3) height, (4) width, (5) origin
-#' \itemize{
-#' \item \emph{list(36,-120, 10, 10, "upperright)}
-#' }
-#' }
-#' @return a sf geometry projected to \emph{EPSG:4269}.
+#' @return a sf geometry projected to \emph{EPSG:4326}.
#' @export
#' @examples
#' \dontrun{
#' # Get AOI for a country
#' aoi_get(country = "Brazil")
-#'
-#' # Get AOI for a location
-#' aoi_get(x = "Sacramento")
-#'
+
#' # Get AOI defined by a state(s)
#' aoi_get(state = "CA")
#' aoi_get(state = c("CA", "nevada"))
@@ -109,34 +32,33 @@
#' aoi_get(state = "California", county = "Santa Barbara")
#' aoi_get(state = "CA", county = c("Santa Barbara", "ventura"))
#'
-#'
#' # Get AOI defined by state & all counties
#' aoi_get(state = "California", county = "all")
-#'
-#' # Get AOI defined by 10 mile bounding box using lat/lon
-#' aoi_get(c(35, -119, 10, 10))
-#'
-#' # Get AOI defined by 10 mile2 bounding box using the 'KMART near UCSB' as lower left corner
-#' aoi_get(x = list("UCSB", 10, 10, "lowerleft"))
#' }
-#' @importFrom sf st_union st_transform
aoi_get <- function(x = NULL,
country = NULL,
state = NULL,
county = NULL,
fip = NULL,
- km = FALSE,
+ zipcode = NULL,
union = FALSE) {
meta <- list_states()
+ if(all(is.null(x),
+ is.null(country),
+ is.null(state),
+ is.null(county),
+ is.null(fip),
+ is.null(zipcode))) {
+ stop("All entries cannot be NULL.")
+ }
+
+
# Error Catching
if (is.null(country)) {
if (!is.null(state)) {
- if (!is.null(x)) {
- stop("Only 'state' or 'x' can be used. Set the other to NULL")
- }
for (value in state) {
if (!is.character(value)) { stop("State must be a character value.") }
@@ -158,32 +80,52 @@ aoi_get <- function(x = NULL,
if (!is.null(county)) {
stop("The use of 'county' requires a 'state' parameter.")
}
- if (is.null(x) & is.null(fip)) {
- stop("Requires an 'x' or 'state' parameter to execute.")
- }
}
}
- # Fiat Boundary Definition (Existing Spatial/Raster Feature or getFiat())
shp <- if (is.null(x)) {
- getFiat(country = country, state = state, county = county, fip = fip)
+
+ if(!is.null(zipcode)){
+
+ print(zipcode)
+ locs <- zipcodes[match(as.numeric(zipcode), zipcodes$zipcode), ]
+ print(locs)
+ failed <- zipcode[!zipcode %in% locs$zip]
+
+ if (length(failed) > 0 & all(is.na(locs$lat))) {
+ stop("Zipcodes ", paste(failed, collapse = ", "), " not found.")
+ } else if (length(failed) > 0 ){
+ warning("Zipcodes ", paste(failed, collapse = ", "), " not found.")
+ locs = locs[!is.na(locs$zipcode),]
+ }
+
+ st_as_sf(locs, coords = c("lon", "lat"), crs = 4269) %>%
+ rename_geometry("geometry")
+
+ } else {
+ getFiat(country = country, state = state, county = county, fip = fip)
+ }
+
} else if (any(
- inherits(x, "Raster"),
+ inherits(x, "SpatRaster"),
inherits(x, "Spatial"),
inherits(x, "sf")
)) {
+
st_bbox(x) %>%
sf::st_as_sfc() %>%
st_as_sf() %>%
st_transform(4326) %>%
rename_geometry("geometry")
- } else {
- getClip(x, km)
+
+ } else {
+ stop()
}
+
# Return AOI
if (union) {
- sf::st_union(shp) %>%
+ st_union(shp) %>%
st_as_sf() %>%
rename_geometry("geometry")
} else {
diff --git a/R/aoi_map.R b/R/aoi_map.R
index 1c747db..59c750c 100644
--- a/R/aoi_map.R
+++ b/R/aoi_map.R
@@ -34,7 +34,6 @@
#' htmlwidgets::saveWidget(m, file = paste0(getwd(), "/myMap.html"))
#' }
#' @export
-#' @importFrom sf st_geometry_type
aoi_map <- function(AOI = NULL, returnMap = FALSE) {
diff --git a/R/aoi_utilities.R b/R/aoi_utilities.R
index 4102365..cde24c9 100644
--- a/R/aoi_utilities.R
+++ b/R/aoi_utilities.R
@@ -1,48 +1,3 @@
-#' @title Buffer AOI
-#' @description Add or subtract a uniform distance to/from a
-#' spatial object in either miles or kilometers.
-#' @param AOI a spatial, raster or simple features object
-#' @param d \code{numeric}.The distance by which to modify each edge
-#' @param km \code{logical}. If \code{TRUE} distances are in kilometers,
-#' default is \code{FALSE} with distances in miles
-#' @return a spatial geometry of the same class as the input AOI
-#' (if Raster sp returned)
-#' @export
-#' @examples
-#' \dontrun{
-#' # get an AOI of 'Garden of the Gods' and add a 2 mile buffer
-#' AOI <- aoi_get(x = "Garden of the Gods") %>% modify(2)
-#'
-#' # get an AOI of 'Garden of the Gods' and add a 2 kilometer buffer
-#' getAOI("Garden of the Gods") %>% modify(2, km = TRUE)
-#'
-#' # get and AOI for Colorado Springs and subtract 3 miles
-#' getAOI("Colorado Springs") %>% modify(-3)
-#' }
-#' @importFrom sf st_crs st_transform st_buffer
-
-aoi_buffer <- function(AOI, d, km = FALSE) {
- AOI <- make_sf(AOI)
-
- crs <- sf::st_crs(AOI)
-
- if (km) {
- u <- d * 3280.84
- } # kilometers to feet
- if (!km) {
- u <- d * 5280
- } # miles to feet
-
- sf::st_transform(AOI, 6829) %>%
- sf::st_buffer(
- dist = u,
- joinStyle = "MITRE",
- endCapStyle = "SQUARE",
- mitreLimit = 2
- ) %>%
- sf::st_transform(crs)
-}
-
#' @title Is Inside
#' @description A check to see if one object is inside another
#' @param obj object 1
@@ -89,7 +44,7 @@ aoi_inside <- function(AOI, obj, total = TRUE) {
#' @importFrom sf st_as_sf
make_sf <- function(x) {
- if (inherits(x, "Raster")) {
+ if (inherits(x, "SpatRaster")) {
x <- bbox_get(x)
} else if (inherits(x, "Spatial")) {
x <- sf::st_as_sf(x)
@@ -122,8 +77,8 @@ rename_geometry = function(g, name) {
list_states <- function() {
return(data.frame(
state_abbr = datasets::state.abb,
- name = datasets::state.name,
- region = datasets::state.region
+ name = datasets::state.name,
+ region = datasets::state.region
))
}
@@ -145,139 +100,3 @@ fip_meta <- function(state, county = NULL) {
st_as_sf()
}
-
-#' @title defineClip
-#' @description
-#' Parse a clip list from user input. \code{defineClip} parses
-#' user supplied lists to a format usable by \code{\link{getClip}}
-#' @param x a user supplied list (see \code{\link{aoi_get}})
-#' @param km \code{logical}. If \code{TRUE} distance are in kilometers,
-#' default is \code{FALSE} with distances in miles
-#' @noRd
-#' @keywords internal
-#' @return a 4-element list of features defining an AO
-
-defineClip <- function(x = NULL, km = FALSE) {
-
- # AOI defined by location and bounding box width and height
-
- if (length(x) == 1) {
- if (!inherits(x, "character")) {
- stop(
- "If only one item is entered for 'x' it must be a character place name"
- )
- } else {
- location <- x
- h <- NULL
- w <- NULL
- o <- NULL
- }
- }
-
- if (length(x) == 3) {
- if (all(is.numeric(unlist(x)))) {
- stop(
- paste(
- "A x with length 3 must be defined by:",
- "1. A name (i.e 'UCSB') (character)",
- "2. A bound box height (in miles) (numeric)",
- "3. A bound box width (in miles) (numeric)",
- sep = "\n"
- )
- )
- } else {
- location <- x[[1]]
- h <- x[[2]]
- w <- x[[3]]
- o <- "center"
- }
- }
-
- # AOI defined by (centroid lat, long, and bounding box width and height)
- # or (loaction, width, height, origin)
-
- if (length(x) == 4) {
- if (any(
- !is.numeric(x[[2]]),
- !is.numeric(x[[3]]),
- all(!is.character(x[[1]]), is.character(x[[4]])),
- all(is.character(x[[1]]), !is.character(x[[4]]))
- )) {
- stop(
- paste0(
- "A x with length 4 must be defined by:\n",
- "1. A latitude (numeric)",
- "2. A longitude (numeric)\n",
- "2. A bounding box height (in miles) (numeric)\n",
- "3. A bounding box width (in miles) (numeric)\n\n",
- "OR\n\n",
- "1. A location (character)\n",
- "2. A bound box height (in miles) (numeric)\n",
- "3. A bounding box width (in miles) (numeric)\n",
- "4. A bounding box origin (character)"
- )
- )
- } else if (all(
- is.numeric(x[[1]]),
- is.numeric(x[[2]]),
- is.numeric(x[[3]]),
- is.numeric(x[[4]])
- )) {
- if (x[[1]] <= -90 | x[[1]] >= 90) {
- stop("Latitude must be vector element 1 and between -90 and 90")
- }
-
- if (x[[2]] <= -179.229655487 | x[[2]] >= 179.856674735) {
- stop("Longitude must be vector element 2 and between -180 and 180")
- }
-
- location <- c(x[[1]], x[[2]])
- h <- x[[3]]
- w <- x[[4]]
- o <- "center"
- } else if (all(
- is.character(x[[1]]),
- is.numeric(x[[2]]),
- is.numeric(x[[3]]),
- is.character(x[[4]])
- )) {
- location <- x[[1]]
- h <- x[[2]]
- w <- x[[3]]
- o <- x[[4]]
- }
- }
-
- # if AOI defined by lat, long, width, height, origin
-
- if (length(x) == 5) {
- if (all(
- is.numeric(x[[1]]),
- is.numeric(x[[2]]),
- is.numeric(x[[3]]),
- is.numeric(x[[4]]),
- is.character(x[[5]])
- )) {
- location <- c(x[[1]], x[[2]])
- h <- x[[3]]
- w <- x[[4]]
- o <- x[[5]]
- }
- }
-
- return(list(
- location = location,
- h = if (is.null(h)) {
- NULL
- } else {
- ifelse(km, (h * 0.62137119224), h)
- },
- w = if (is.null(w)) {
- NULL
- } else {
- ifelse(km, (w * 0.62137119224), w)
- },
- o = o
- ))
-}
-
diff --git a/R/geoCode.R b/R/geoCode.R
index 83bb48b..3c8c608 100644
--- a/R/geoCode.R
+++ b/R/geoCode.R
@@ -1,186 +1,210 @@
-#' @title geocodeOSM
-#' @description
-#' Geocode via Open Street Maps API. \code{geocodeOSM}
-#' takes an input string and converts it to a geolocation.
-#' Additionally it can return the location as a simple
-#' features point and the minimum bounding area
-#' of the location extent.
-#' @param location a place name
-#' @param pt if TRUE a simple feature point is appended to returned list
-#' @param bb if TRUE the OSM bounding area of the location is appended
-#' to returned list
-#' @param all if TRUE the point and bounding box representations are returned
-#' @param method the geocoding service to be used. See ?tidygeocoder::geocode
-#' @return at minimum a data.frame of lat, long
-#' @export
-#' @examples
-#' \dontrun{
-#' geocodeAOI("UCSB")
-#' geocodeAOI("Garden of the Gods", bb = TRUE)
-#' }
-#' @importFrom tidygeocoder geo
-#' @importFrom sf st_as_sf
+#' @title .geocode
+#' @inheritParams geocode
+#' @inherit geocode return
-geocodeAOI <- function(location, pt = FALSE, bb = FALSE,
- all = FALSE, method = "arcgis") {
+.geocode <- function(geo,
+ pt = FALSE,
+ bbox = FALSE,
+ all = FALSE,
+ method = default_method,
+ crs = default_crs) {
- if (sum(pt, bb, all) > 1) {
- stop("Only pt, bb, or all can be TRUE. Leave others as FALSE")
+ request <- long <- lat <- score <- . <- NULL
+
+ if (sum(pt, bbox, all) > 1) {
+ stop("Only pt, bbox, or all can be TRUE. Leave others as FALSE")
}
- if (!inherits(location, "character")) {
- stop(paste(
- "",
- "Input location is not a place name. ",
- "You might be looking for reverse geocodeing.",
- "Try: AOI::geocode_rev()",
- sep = "\n"
- ))
+ if (!inherits(geo, "character")) {
+ stop(
+ paste(
+ "",
+ "Input geo is not a place name. ",
+ "You might be looking for reverse geocodeing.",
+ "Try: AOI::geocode_rev()",
+ sep = "\n"
+ )
+ )
}
ret = suppressMessages({
- tidygeocoder::geo(location, progress_bar = FALSE, method = method, full_results = TRUE)
+ geo(
+ geo,
+ progress_bar = FALSE,
+ method = method,
+ full_results = TRUE,
+ verbose = FALSE
+ ) %>%
+ mutate(request = geo) %>%
+ select(request,
+ x = long,
+ y = lat,
+ score,
+ contains("_address"),
+ contains("extent"))
})
-
-
- ret$lon = ret$long
- ret$long = NULL
- ret$request = location
- ret$address = NULL
-
- if(all(is.na(ret$lat))){
+ if (all(is.na(ret$y))) {
return(ret)
}
- bbs = list()
+ point <-
+ st_as_sf(x = ret,
+ coords = c("x", "y"),
+ crs = 4326) %>%
+ rename_geometry("geometry") %>%
+ st_transform(crs) %>%
+ mutate(x = sf::st_coordinates(.)[,1],
+ y = sf::st_coordinates(.)[,2]) %>%
+ select(-contains("extent"))
+
+ if(nrow(point) > 1){
+ bbs = bbox_get(point)
+ } else {
+ bbs = list()
+
+ for (i in 1:nrow(ret)) {
+ bbs[[i]] <-
+ st_bbox(
+ c(
+ xmin = ret$extent.xmin[i],
+ xmax = ret$extent.xmax[i],
+ ymin = ret$extent.ymin[i],
+ ymax = ret$extent.ymax[i]
+ ),
+ crs = 4326
+ ) %>%
+ st_as_sfc() %>%
+ st_as_sf() %>%
+ rename_geometry("geometry") %>%
+ st_transform(crs)
+ }
- for(i in 1:nrow(ret)){
- bbs[[i]] <- st_bbox(c(xmin = ret$extent.xmin[i],
- xmax = ret$extent.xmax[i],
- ymin = ret$extent.ymin[i],
- ymax = ret$extent.ymax[i]), crs = 4326) %>%
- sf::st_as_sfc() %>%
- sf::st_as_sf() %>%
- rename_geometry("geometry")
+ bbs = do.call(rbind, bbs)
+ bbs$request = ret$request
+ bbs = merge(bbs, st_drop_geometry(point))
}
- bbs = do.call(rbind, bbs)
- bbs$request = ret$request
-
- ret = ret[, !grepl("[.]", names(ret))]
-
- bbs = merge(bbs, ret)
-
- point <- sf::st_as_sf(x = ret, coords = c("lon", "lat"), crs = 4269)
-
-
- if (pt) { return(point) }
- if (bb) { return(bbs) }
- if (all) { return(list(coords = ret, pt = point, bbox = bbs)) }
+ if (pt) { return(point) }
+ if (bbox){ return(bbs) }
+ if (all) {
+ return(list(pt = point, bbox = bbs ))
+ }
- return(ret)
+ return(st_drop_geometry(point))
}
#' @title Geocoding
#' @description
-#' A wrapper around the OpenSteetMap geocoding web-services.
-#' Users can request a lat/lon pair, spatial points, and/or
-#' a bounding box geometries. One or more place name can be
-#' given at a time. If a single point is requested, `geocode`
+#' A wrapper around the tidygeocoding and Wikipedia services.
+#' Users can request a data.frame (default), vector (xy = TRUE), point (pt = TRUE), and/or a bounding box (bbox = TRUE) representation of a place/location (geo) or event. One or more can be given at a time.
+#'
+#' If a single entitiy is requested, `geocode`
#' will provide a data.frame of lat/lon values and, if requested,
-#' a spatial point object and the geocode derived bounding box.
-#' If multiple place names are given, the returned objects will
+#' a point object and the derived bounding box of the geo/event.
+#'
+#' If multiple entities are requested, the returned objects will
#' be a data.frame with columns for input name-lat-lon; if requested,
-#' a SpatialPoints object will be returned; and a minimum bounding box
-#' of all place names.
-#' @param location \code{character}. Place name(s)
-#' @param zipcode \code{character}. USA zipcode(s)
-#' @param event \code{character}. a term to search for on wikipedia
-#' @param pt \code{logical}. If TRUE point geometery is appended
-#' to the returned list()
-#' @param bb \code{logical}. If TRUE bounding box geometry is
-#' appended to the returned list()
-#' @param full \code{logical}. If TRUE all attributes reuturned
-#' with query, else just the lat/long pair.
-#' @param all if TRUE the point and bounding box representations are returned
-#' @return at minimum a data.frame of lat/lon coordinates.
-#' Possible list with appended spatial features of
-#' type \code{sf} or \code{sp}
+#' a POINT object will be returned. Here, the bbox argument will return the
+#' minimum bounding box of all place names.
+#' @param geo \code{character}. Place name(s)
+#' @param event \code{character}. a term to search for on Wikipedia
+#' @param pt \code{logical}. If TRUE point geometry is created.
+#' @param bbox \code{logical}. If TRUE bounding box geometry is created
+#' @param xy \code{logical}. If TRUE a named xy numeric vector is created
+#' @param all \code{logical}. If TRUE the point, bbox and xy representations are returned as a list
+#' @param method the geocoding service to be used. See ?tidygeocoder::geocode
+#' @param crs desired CRS. Defaults to AOI::default_crs
+#' @return a data.frame, sf object, or vector
#' @export
-#' @author Mike Johnson
+#' @family geocode
#' @examples
#' \dontrun{
-#' ## geocode a single location
+#' ## geocode a single locations
#' geocode("UCSB")
#'
-#' ## geocode a single location and return a SpatialPoints object
+#' ## geocode a single location and return a POINT object
#' geocode("UCSB", pt = TRUE)
#'
-#' ## geocode a single location and derived bounding box of location
-#' geocode(location = "UCSB", bb = TRUE)
+#' ## geocode a single location and derived bbox of location
+#' geocode(location = "UCSB", bbox = TRUE)
#'
#' ## geocode multiple locations
#' geocode(c("UCSB", "Goleta", "Santa Barbara"))
#'
#' ## geocode multiple points and generate a minimum bounding box of all locations and spatial points
-#' geocode(c("UCSB", "Goleta", "Santa Barbara"), bb = T, pt = T)
+#' geocode(c("UCSB", "Goleta", "Santa Barbara"), bbox = T, pt = T)
#' }
-#'
-geocode <- function(location = NULL,
- zipcode = NULL,
+
+geocode <- function(geo = NULL,
event = NULL,
pt = FALSE,
- bb = FALSE,
+ bbox = FALSE,
all = FALSE,
- full = FALSE) {
+ xy = FALSE,
+ method = default_method,
+ crs = default_crs) {
+
+
if (!is.null(event)) {
+ locs = list()
+
suppressWarnings({
- locs <- do.call(rbind,lapply(event, geocode_wiki))
+ locs$event <- do.call(rbind, lapply(event, geocode_wiki)) %>%
+ st_as_sf(coords = c("x", "y"), crs = 4326) %>%
+ st_transform(crs)
})
- if(pt | bb | all){
- locs = sf::st_as_sf(locs, coords = c("lon", "lat"), crs = 4269)
- }
- }
-
- if (!is.null(zipcode)) {
+ if (pt | all | bbox) {
+ locs$pt = st_as_sf(locs$event,
+ coords = c("x", "y"),
+ crs = 4326) %>%
+ st_transform(crs)
- locs <- AOI::zipcodes[match(as.numeric(zipcode), AOI::zipcodes$zipcode), ]
+ locs$event = NULL
+ }
- failed <- zipcode[!zipcode %in% locs$zip]
+ if (bbox | all) {
+ if (nrow(locs$pt) > 1) {
+ locs$bbox = st_as_sf(merge(st_drop_geometry(locs$pt), bbox_get(locs$pt)))
+ } else {
+ locs$bbox = locs$pt
+ }
- if (length(failed) > 0 & all(is.na(locs$lat))) {
- stop("Zipcodes ", paste(failed, collapse = ", "), " not found.")
- } else if (length(failed) > 0 ){
- warning("Zipcodes ", paste(failed, collapse = ", "), " not found.")
- locs = locs[!is.na(locs$zipcode),]
+ if (bbox) {
+ locs$pt = NULL
+ }
}
- if(pt | bb | all){
- locs = sf::st_as_sf(locs, coords = c("lon", "lat"), crs = 4269)
+ if (length(locs) == 1) {
+ locs = locs[[1]]
}
}
- if (!is.null(location)) {
- locs = geocodeAOI(location, pt, bb, all)
+ if (!is.null(geo)) {
+ locs = .geocode(geo,
+ pt,
+ bbox,
+ all,
+ method,
+ crs = crs)
+ }
+
+ if (xy) {
+ locs = c(locs$x,locs$y)
}
return(locs)
}
-
#' @title Alternate Page Finder
#' @description Find linked pages to a wikipedia call
#' @param loc a wikipedia structured call
-#' @param pts \code{logical}. If TRUE point geometery
+#' @param pt \code{logical}. If TRUE point geometery
#' is appended to the returned list()
#' @return at minimum a data.frame of lat, long
-#' @author Mike Johnson
-#' @keywords internal
-#' @export
#' @examples
#' \dontrun{
#' alt_page("Twin_towers")
@@ -188,29 +212,30 @@ geocode <- function(location = NULL,
#' @importFrom rvest read_html html_nodes html_attr html_text
alt_page <- function(loc, pt = FALSE) {
+ tt <- read_html(
+ paste0(
+ "https://en.wikipedia.org/w/index.php?search=",
+ loc,
+ "&title=Special%3ASearch&go=Go"
+ )
+ )
- tt <- rvest::read_html(paste0(
- "https://en.wikipedia.org/w/index.php?search=",
- loc,
- "&title=Special%3ASearch&go=Go"
- ))
-
- a <- rvest::html_nodes(tt, "a")
-
- url_ <- rvest::html_attr(a, "href")
-
- link_ <- rvest::html_text(a)
+ a <- html_nodes(tt, "a")
+ url_ <- html_attr(a, "href")
+ link_ <- html_text(a)
df_new <- data.frame(urls = url_, links = link_)
- df_new <- df_new[!is.na(df_new$urls), ]
- df_new <- df_new[!is.na(df_new$links), ]
- df_new <- df_new[grepl("/wiki/", df_new$urls), ]
- df_new <- df_new[!grepl(":", df_new$urls), ]
- df_new <- df_new[!grepl("Main_Page", df_new$urls), ]
- df_new <- df_new[!grepl("Privacy_Policy", df_new$urls), ]
- df_new <- df_new[!grepl("Terms_of_use", df_new$urls), ]
-
- if(nrow(df_new) == 0) { df_new <- NULL }
+ df_new <- df_new[!is.na(df_new$urls),]
+ df_new <- df_new[!is.na(df_new$links),]
+ df_new <- df_new[grepl("/wiki/", df_new$urls),]
+ df_new <- df_new[!grepl(":", df_new$urls),]
+ df_new <- df_new[!grepl("Main_Page", df_new$urls),]
+ df_new <- df_new[!grepl("Privacy_Policy", df_new$urls),]
+ df_new <- df_new[!grepl("Terms_of_use", df_new$urls),]
+
+ if (nrow(df_new) == 0) {
+ df_new <- NULL
+ }
return(df_new)
}
@@ -222,8 +247,9 @@ alt_page <- function(loc, pt = FALSE) {
#' @param event \code{character}. a term to search for on wikipeida
#' @param pt \code{logical}. If TRUE point geometery is appended
#' to the returned list()
-#' @return aa data.frame of lat/lon coordinates
+#' @return a data.frame of lat/lon coordinates
#' @export
+#' @family geocode
#' @examples
#' \dontrun{
#' ## geocode an Agency
@@ -241,10 +267,6 @@ alt_page <- function(loc, pt = FALSE) {
#' ## geocode an event
#' geocode_wiki("Hurricane Harvey")
#' }
-#' @importFrom jsonlite fromJSON
-#' @importFrom rvest read_html html_nodes html_table
-#' @importFrom rnaturalearth ne_countries
-#' @importFrom sf st_as_sf
geocode_wiki <- function(event = NULL, pt = FALSE) {
@@ -256,7 +278,7 @@ geocode_wiki <- function(event = NULL, pt = FALSE) {
"&limit=1&format=json&redirects=resolve"
)
- url <- unlist(jsonlite::fromJSON(u))
+ url <- unlist(fromJSON(u))
url <- url[grepl("http", url)]
call <- gsub("https://en.wikipedia.org/wiki/", "", url)
@@ -272,17 +294,23 @@ geocode_wiki <- function(event = NULL, pt = FALSE) {
return(df_new)
} else {
-
- coord_url <- paste0('https://en.wikipedia.org/w/api.php?action=query&prop=coordinates&titles=',
- paste(call, collapse = "|"),
- '&format=json')
-
-
- fin <- jsonlite::fromJSON(coord_url)
-
- extract = function(x){
- if(!is.null(x$coordinates)){
- data.frame(title = x$title, lat = x$coordinates$lat, lon = x$coordinates$lon)
+ coord_url <-
+ paste0(
+ 'https://en.wikipedia.org/w/api.php?action=query&prop=coordinates&titles=',
+ paste(call, collapse = "|"),
+ '&format=json'
+ )
+
+
+ fin <- fromJSON(coord_url)
+
+ extract = function(x) {
+ if (!is.null(x$coordinates)) {
+ data.frame(
+ title = x$title,
+ lat = x$coordinates$lat,
+ lon = x$coordinates$lon
+ )
} else {
NULL
}
@@ -292,8 +320,8 @@ geocode_wiki <- function(event = NULL, pt = FALSE) {
if (is.null(df)) {
infobox <-
- rvest::read_html(url, header = FALSE) %>%
- rvest::html_nodes(xpath = '//table[contains(@class, "infobox")]')
+ read_html(url, header = FALSE) %>%
+ html_nodes(xpath = '//table[contains(@class, "infobox")]')
if (length(infobox) == 0) {
df_new <- alt_page(loc)
@@ -305,10 +333,8 @@ geocode_wiki <- function(event = NULL, pt = FALSE) {
)
return(df_new)
} else {
- y <- as.data.frame(
- rvest::html_table(infobox[1], header = F)[[1]],
- stringsAsFactors = FALSE
- )
+ y <- as.data.frame(html_table(infobox[1], header = F)[[1]],
+ stringsAsFactors = FALSE)
search <- y$X2[which(y$X1 == "Location")]
}
@@ -318,14 +344,17 @@ geocode_wiki <- function(event = NULL, pt = FALSE) {
if (length(search) == 0) {
meta <- list_states()
- countries <- rnaturalearth::ne_countries(returnclass = "sf")
- y <- y[y$X1 != y$X2, ]
- x <- y[grepl(tolower(paste0(c(meta$name, countries$name), collapse = "|")), tolower(y$X2)), ]
+ countries <- ne_countries(returnclass = "sf")
+ y <- y[y$X1 != y$X2,]
+ x <-
+ y[grepl(tolower(paste0(
+ c(meta$name, countries$name), collapse = "|"
+ )), tolower(y$X2)),]
all <- strsplit(gsub(", ", ",", x[1, 2]), ",")[[1]]
df <- list()
for (i in seq_len(length(all))) {
- df[[i]] <- geocode(all[i], full = FALSE)
+ df[[i]] <- geocode(all[i])
}
df <- cbind(all, do.call(rbind, df))
@@ -335,17 +364,24 @@ geocode_wiki <- function(event = NULL, pt = FALSE) {
df <- NULL
i <- 0
- while (NROW(df) == 0) {
+ while (nrow(df) == 0) {
i <- i + 1
def <- gsub('/"', "", do.call(paste, list(s1[c(1:i)])))
- df <- geocode(def, full = TRUE)
+ df <- geocode(def)
}
}
}
}
+ lookup <- c(y = "lat", x = "lon")
+
+ df = df %>%
+ rename(any_of(lookup))
+
if (pt) {
- sf::st_as_sf(x = df, coords = c("lon", "lat"), crs = 4269)
+ st_as_sf(x = df,
+ coords = c("x", "y"),
+ crs = default_crs)
} else {
data.frame(cbind(request = loc, df))
}
@@ -355,97 +391,43 @@ geocode_wiki <- function(event = NULL, pt = FALSE) {
#' @title Reverse Geocoding
#' @description
#' Describe a location using the ERSI and OSM reverse geocoding web-services.
-#' This service provides tradional reverse geocoding (lat/lon to placename)
-#' but can also be use to get more information about a place name.
-#' @param x a point provided by \code{numeric} lat/lon pair or
-#' \code{character} place name
-#' @param method "osm" (deafalt) or "ersi"
-#' @return a data.frame of descriptive features
+#' This service provides traditional reverse geocoding (lat/lon to placename)
+#' but can also be use to get more information about a place name. xy must contain geographic coordinates!
+#' @inheritParams geocode
+#' @inherit geocode return
#' @export
-#' @author Mike Johnson
+#' @family geocode
#' @examples
#' \dontrun{
-#' geocode_rev(x = c(38,-115))
-#' geocode_rev("UCSB")
+#' geocode_rev(xy = c(38,-115))
#' }
-#' @importFrom jsonlite fromJSON
-geocode_rev <- function(x, method = "osm") {
-
- if (inherits(x, "character")) {
- pt <- geocode(x)
- } else if(inherits(x, "numeric")){
- pt <- data.frame(
- lat = x[1],
- lon = x[2]
- )
- } else {
- coords = sf::st_coordinates(sf::st_centroid(x))
- pt <- data.frame(
- lat = coords[2],
- lon = coords[1]
- )
+geocode_rev <- function(xy,
+ pt = FALSE,
+ method = default_method) {
+
+ address <- long <- lat <- NULL
+
+ if (inherits(xy, "character")) {
+ stop("Reverse geocoding opperates on numeric xy coordinates. Maybe try geocode?")
+ } else if (length(xy) != 2) {
+ stop("xy must be of length 2")
+ } else if (inherits(xy, "numeric")) {
+ tmp = reverse_geo(
+ lat = xy[2],
+ long = xy[1],
+ method = method,
+ progress_bar = FALSE,
+ quiet = TRUE
+ ) %>%
+ select(address, x = long, y = lat)
}
- # ESRI Rgeocode -----------------------------------------------------------
-
- if(method == "esri"){
- esri_url <- paste0(
- "https://geocode.arcgis.com/",
- "arcgis/rest/services/World/GeocodeServer/reverseGeocode",
- "?f=pjson&featureTypes=&location=",
- paste(pt$lon, pt$lat, sep = ",")
- )
-
- ll <- jsonlite::fromJSON(esri_url)
- xr <- unlist(ll)
- esri <- data.frame(t(xr), stringsAsFactors = F)
- names(esri) <- gsub(
- "address\\.|location\\.|spatialReference\\.",
- "",
- names(xr)
- )
-
- names(esri)[which(names(esri) == "x")] <- "lon"
- names(esri)[which(names(esri) == "y")] <- "lat"
- names(esri)[which(names(esri) == "boundingbox3")] <- "xmin"
- names(esri)[which(names(esri) == "boundingbox4")] <- "xmax"
- names(esri)[which(names(esri) == "boundingbox1")] <- "ymin"
- names(esri)[which(names(esri) == "boundingbox2")] <- "ymax"
- esri[grepl("latest", names(esri))] <- NULL
- tmp = esri
+ if (pt) {
+ tmp = st_as_sf(x = tmp,
+ coords = c("x", "y"),
+ crs = 4326)
}
- # OSM Rgeocode ------------------------------------------------------------
- if(method == "osm"){
- osm_url <- paste0(
- "https://nominatim.openstreetmap.org/reverse?format=json&lat=",
- pt$lat,
- "&lon=",
- pt$lon,
- "&zoom=18&addressdetails=1"
- )
-
- ll <- jsonlite::fromJSON(osm_url)
- xr <- unlist(ll)
- osm <- data.frame(t(xr), stringsAsFactors = FALSE)
- names(osm) <- gsub("address\\.|location\\.|spatialReference\\.", "", names(xr))
-
- osm$licence <- NULL
-
- osm$bb <- paste(
- osm$boundingbox3,
- osm$boundingbox4,
- osm$boundingbox1,
- osm$boundingbox2,
- sep = ","
- )
-
- osm[grepl("boundingbox", names(osm))] <- NULL
- osm[grepl("lat", names(osm))] <- NULL
- osm[grepl("lon", names(osm))] <- NULL
- tmp = osm
- }
-
- tmp
+ return(tmp)
}
diff --git a/R/getClip.R b/R/getClip.R
deleted file mode 100644
index 7d378e0..0000000
--- a/R/getClip.R
+++ /dev/null
@@ -1,90 +0,0 @@
-#' @title Convert clip unit ot geometry
-#' @description
-#' \code{getClip} generates a Spatial object based on a point;
-#' bounding box dimisions; and their relation to the point.
-#' @param location Defined by a location or lat, long pair
-#' @param height Define the height of the desired bounding box in miles
-#' @param width Define the width of the desired bounding box in miles
-#' @param origin Define the position of the point with respect to the
-#' bounding box. Default is set to center. Options include:
-#' \itemize{
-#' \item{"center"}
-#' \item{"lowerleft"}
-#' \item{"lowerright"}
-#' \item{"upperright"}
-#' \item{"upperleft"}
-#' }
-#' @return a \code{SpatialPolygons} object projected to \emph{EPSG:4269}.
-#' @export
-#' @keywords internal
-
-
-
-getClip <- function(x, km = FALSE) {
-
- fin <- defineClip(x, km = km)
-
- location <- fin$location
-
- origin <- fin$o
-
- if (all(is.null(fin$h), is.null(fin$w), is.null(origin))) {
- poly <- geocode(location, bb = TRUE, full = FALSE)
- } else {
- if (inherits(location, "numeric")) {
- location <- list(lat = location[1], lon = location[2])
- }
-
- if (inherits(location, "character")) {
- location <- geocode(location = location, full = FALSE)
- if(is.na(location$lat)){stop("location not found in OSM", call. = FALSE)}
- }
-
- df <- (fin$h / 2) / 69 # north/south
- dl <- ((fin$w / 2) / 69) / cos(location$lat * pi / 180) # east/west
-
- if (origin == "center") {
- south <- location$lat - df
- north <- location$lat + df
- west <- location$lon - dl
- east <- location$lon + dl
- }
-
- if (origin == "lowerleft") {
- south <- location$lat
- north <- location$lat + (2 * df)
- west <- location$lon
- east <- location$lon + (2 * dl)
- }
-
- if (origin == "lowerright") {
- south <- location$lat
- north <- location$lat + (2 * df)
- west <- location$lon - (2 * dl)
- east <- location$lon
- }
-
- if (origin == "upperright") {
- south <- location$lat - (2 * df)
- north <- location$lat
- west <- location$lon - (2 * dl)
- east <- location$lon
- }
-
- if (origin == "upperleft") {
- south <- location$lat - (2 * df)
- north <- location$lat
- west <- location$lon
- east <- location$lon + (2 * dl)
- }
-
- poly <- st_bbox(c(xmin = west,
- xmax = east,
- ymin = south,
- ymax = north), crs = 4326) %>%
- sf::st_as_sfc() %>%
- sf::st_as_sf() %>%
- rename_geometry("geometry")
-}
- return(poly)
-}
diff --git a/R/getFiat.R b/R/getFiat.R
index 68fe65f..f75d007 100644
--- a/R/getFiat.R
+++ b/R/getFiat.R
@@ -40,7 +40,7 @@ getFiat <- function(country = NULL, state = NULL, county = NULL, fip = NULL) {
map0 <- map1 <- map2 <- map3 <- NULL
if (!is.null(country)) {
- countries <- rnaturalearth::ne_countries(returnclass = "sf")
+ countries <- ne_countries(returnclass = "sf")
region1 <- tolower(country)
region2 <- gsub("south", "southern", region1)
@@ -51,7 +51,9 @@ getFiat <- function(country = NULL, state = NULL, county = NULL, fip = NULL) {
region <- unique(unlist(c(
sapply(c(region1, region2), .find, vec = countries$subregion, full = countries$name),
- sapply(c(region1, region2), .find, vec = countries$continent, full = countries$name)
+ sapply(c(region1, region2), .find, vec = countries$continent, full = countries$name),
+ sapply(c(region1, region2), .find, vec = countries$region_un, full = countries$name),
+ sapply(c(region1, region2), .find, vec = countries$region_wb, full = countries$name)
)))
map0 <- countries[countries$name %in% region, ]
@@ -59,7 +61,8 @@ getFiat <- function(country = NULL, state = NULL, county = NULL, fip = NULL) {
country <- unlist(c(
sapply(country, .find, vec = countries$name, full = countries$name),
sapply(country, .find, vec = countries$iso_a2, full = countries$name),
- sapply(country, .find, vec = countries$iso_a3, full = countries$name)
+ sapply(country, .find, vec = countries$iso_a3, full = countries$name),
+ sapply(country, .find, vec = countries$iso_n3, full = countries$name)
))
map1 <- countries[countries$name %in% country, ]
@@ -71,10 +74,7 @@ getFiat <- function(country = NULL, state = NULL, county = NULL, fip = NULL) {
if (!is.null(state)) {
- ret = tryCatch({
- fip_meta(state = state, county = county)
- },
- error = function(e){ NULL })
+ ret = fip_meta(state = state, county = county)
ret = ret[!sf::st_is_empty(ret),]
@@ -87,6 +87,8 @@ getFiat <- function(country = NULL, state = NULL, county = NULL, fip = NULL) {
all.x = TRUE)
}
+ ret = ret[!sf::st_is_empty(ret),]
+
if(nrow(ret) == 0 ){ stop('State, county pair(s) not found', call. = FALSE) }
map2 <- ret
@@ -97,7 +99,7 @@ getFiat <- function(country = NULL, state = NULL, county = NULL, fip = NULL) {
if(!nchar(fip) %in% c(2,5)){
stop("FIP codes must be of length 2 or 5")
} else {
- map3 <- fipio::fips_metadata(fip, geometry = TRUE)
+ map3 <- st_as_sf(fipio::fips_metadata(fip, geometry = TRUE))
}
}
diff --git a/R/package_AOI.R b/R/package_AOI.R
index e70d4fe..e05c019 100644
--- a/R/package_AOI.R
+++ b/R/package_AOI.R
@@ -3,28 +3,25 @@
#' An area of interest (AOI) is a geographic extent.
#' The aim of this package is to help users create these -
#' turning locations, place names, and political boundaries
-#' into servicable geometries for spatial analysis.
-#' The package is written using the simple features paradigm,
-#' projected to EPSG:4269.\cr
-#'
-#' The primary functions are \code{\link{geocode}},
-#' \code{\link{geocode_rev}}, \code{\link{aoi_get}},
-#' and \code{\link{bbox_get}}.
-#'
-#' The first returns a data.frame of coordinates from place
-#' names using the OSM API; the second returns a list of descriptive
-#' features from a known place name or lat/lon pair; the third returns
-#' a spatial (sf) geometry from a country, state, county, or defined
-#' region, and the last an extent encompassing a set of input features.
-#' \code{\link{aoi_map}} helps users visualize AOIs in a interactive map;
-#' and \code{\link{aoi_buffer}} which allows AOIs to be modified by uniform
-#' distances. Finally, \code{\link{aoi_describe}} breaks existing spatial
-#' features into \code{\link{aoi_get}} parameters to improve the
-#' reproducibility of geometry generation.
-#' \cr
+#' into servicable representation for spatial analysis.
+#' The package defaults to EPSG:4326\cr
#'
#' See the \href{https://github.com/mikejohnson51/AOI}{README} on github,
#' and the project webpage for examples
#' \href{https://mikejohnson51.github.io/AOI/}{here}.
#'
#' @docType package
+
+#' @importFrom tidygeocoder geo reverse_geo
+#' @importFrom dplyr `%>%` select contains mutate rename any_of
+#' @importFrom sf st_union st_transform st_as_sf st_bbox st_area st_as_sfc st_is st_sf st_sfc st_polygon st_cast st_geometry_type st_crs st_buffer st_drop_geometry st_point st_set_crs st_is_longlat
+#' @importFrom rvest html_nodes html_nodes html_text html_nodes html_table
+#' @importFrom jsonlite fromJSON
+#' @importFrom rnaturalearth ne_countries
+#' @importFrom units set_units
+#' @importFrom fipio fips_metadata
+
+default_crs = 4326
+default_method = "arcgis"
+default_units = "meter"
+default_dim = c(512)
diff --git a/README.Rmd b/README.Rmd
index b92ea4e..a3faaba 100644
--- a/README.Rmd
+++ b/README.Rmd
@@ -14,6 +14,7 @@ knitr::opts_chunk$set(
)
library(AOI)
+library(sf)
```
# AOI
@@ -26,11 +27,11 @@ library(AOI)
[](https://codecov.io/github/mikejohnson51/AOI)
-The purpose of AOI is to help create reproducible, programmatic boundaries for analysis and mapping workflows. The package targets five main use cases:
+AOI helps create reproducible, programmatic boundaries for analysis and mapping workflows. The package targets five main use cases:
-## 1. Flexable, term based geocoding
+## 1. Term based geocoding
-The aim of the AOI geooding service is to provide flexible, term-based geocoding via the OSM Notimun and Wikipedia APIs and the Wikipedia. If you have more ridgid addresses `tidygeocoder` is great!
+AOI uses `tidygeocoder` as a backend for term-based geooding and Wikipedia APIs. If you have more ridgid addresses `tidygeocoder` is great!
### Foward (from name to location)
@@ -51,11 +52,10 @@ geocode('500 Linden St, Fort Collins, CO 80524', pt = TRUE)
# Single events
geocode(event = 'D-day')
-# Multi-location events
-geocode(event = 'Hurricane Harvey')
-
# Multi-location events with BBOX
-geocode(event = 'Hurricane Harvey', bb = TRUE)
+(harvey = geocode(event = 'Hurricane Harvey', bb = TRUE))
+
+mapview::mapview(harvey)
```
### Reverse (from location to term)
@@ -101,21 +101,23 @@ aoi_describe(USA_south)
```{r}
# 100 square mile region around Longs Peaks
-aoi_get(list("Long Peaks", 10, 10))
+aoi_ext("Long Peaks", wh = 10)
```
#### Location and Diminsions
```{r}
# 200 square mile region around 37,-119
-aoi_get(list(37, -119, 20, 10))
+aoi_ext(xy = c(x = 119, y = 37), wh = c(20, 10))
```
#### Event and Diminsions
```{r}
-# 10,000 square mile region around Normandy Landings
-aoi_get(list("D-day", 100, 100))
+# 10,000 square meter region around Normandy Landings
+aoi_ext(geo = "white house", wh = 10000, bbox = TRUE) |>
+ st_as_sf() |>
+ aoi_map(returnMap = T)
```
### 4. View and Draw
@@ -125,7 +127,7 @@ aoi_get(list("D-day", 100, 100))
Sometimes it is useful to view the created AOIs. `aoi_map` offers a quickly formatted `leaflet` map (not all that dissimilar from `mapview` so this may retire).
```{r}
-AOI = geocode(location = c("Paris", "Amsterdam", "Prague", "England"), pt = TRUE)
+AOI = geocode(geo = c("Paris", "Amsterdam", "Prague", "England"), pt = TRUE)
aoi_map(AOI, returnMap = TRUE)
```
@@ -146,19 +148,21 @@ knitr::include_graphics('man/figures/shiny-app.png')
The need for AOI's is rampant in the r-spatial community. AOI plays nicely with the following non-exhaustive list helping users be to the meat of their utilities without getting hung up on boundary definition.
-- ggmap
-- opendap.catalog
-- nhdplusTools
-- elevatr
-- terrainr
-- climateR
-- dataRetrivial
-- soilDB
-- nwmTools
-- osmdata
-- FedData
-- hereR
-- Please add more!
+| package |
+|---|
+| ggmap |
+| nhdplusTools |
+| elevatr |
+| terrainr |
+| climateR |
+| dataRetrivial |
+| soilDB |
+| nwmTools |
+| FedData |
+| hereR |
+
+
+Please add more!
### Installation:
@@ -166,9 +170,6 @@ The need for AOI's is rampant in the r-spatial community. AOI plays nicely with
remotes::install_github("mikejohnson51/AOI")
```
-### Resources
-See the package [website](https://mikejohnson51.github.io/AOI/) vignettes showing the general workflow and functionality.
-
### Support:
diff --git a/README.md b/README.md
index 24871a1..284027b 100644
--- a/README.md
+++ b/README.md
@@ -14,15 +14,14 @@ MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://choosealicens
[](https://codecov.io/github/mikejohnson51/AOI)
-The purpose of AOI is to help create reproducible, programmatic
-boundaries for analysis and mapping workflows. The package targets five
-main use cases:
+AOI helps create reproducible, programmatic boundaries for analysis and
+mapping workflows. The package targets five main use cases:
-## 1. Flexable, term based geocoding
+## 1. Term based geocoding
-The aim of the AOI geooding service is to provide flexible, term-based
-geocoding via the OSM Notimun and Wikipedia APIs and the Wikipedia. If
-you have more ridgid addresses `tidygeocoder` is great!
+AOI uses `tidygeocoder` as a backend for term-based geooding and
+Wikipedia APIs. If you have more ridgid addresses `tidygeocoder` is
+great!
### Foward (from name to location)
@@ -30,10 +29,12 @@ you have more ridgid addresses `tidygeocoder` is great!
``` r
geocode(c('Colorado State University', "University of Colorado", 'NOAA'))
-#> request lat lon
-#> 1 Colorado State University 40.57066 -105.08540
-#> 2 University of Colorado 40.00760 -105.26910
-#> 3 NOAA 25.73289 -80.16056
+#> # A tibble: 3 × 5
+#> request score arcgis_address x y
+#> *
+#> 1 Colorado State University 100 Colorado State University -105. 40.6
+#> 2 University of Colorado 100 University of Colorado -105. 40.0
+#> 3 NOAA 100 Noaa -94.8 29.3
```
#### Addresses
@@ -41,13 +42,15 @@ geocode(c('Colorado State University', "University of Colorado", 'NOAA'))
``` r
# Address with POINT representation
geocode('500 Linden St, Fort Collins, CO 80524', pt = TRUE)
-#> Simple feature collection with 1 feature and 1 field
+#> Simple feature collection with 1 feature and 5 fields
#> Geometry type: POINT
#> Dimension: XY
-#> Bounding box: xmin: -105.0678 ymin: 40.59336 xmax: -105.0678 ymax: 40.59336
-#> Geodetic CRS: NAD83
-#> request geometry
-#> 1 500 Linden St, Fort Collins, CO 80524 POINT (-105.0678 40.59336)
+#> Bounding box: xmin: -105.0665 ymin: 40.59362 xmax: -105.0665 ymax: 40.59362
+#> Geodetic CRS: WGS 84
+#> # A tibble: 1 × 6
+#> request score arcgis_address geometry x y
+#>
+#> 1 500 Linden St, For… 100 500 Linden St… (-105.0665 40.59362) -105. 40.6
```
#### Events
@@ -55,45 +58,85 @@ geocode('500 Linden St, Fort Collins, CO 80524', pt = TRUE)
``` r
# Single events
geocode(event = 'D-day')
-#> request title lat lon
-#> 252854 D-day Normandy landings 49.33333 -0.5666667
-
-# Multi-location events
-geocode(event = 'Hurricane Harvey')
-#> request all request.1 lat lon
-#> 1 Hurricane+Harvey Windward Islands Windward Islands 13.400000 -61.16000
-#> 2 Hurricane+Harvey Suriname Suriname 4.141303 -56.07712
-#> 3 Hurricane+Harvey Guyana Guyana 4.841710 -58.64169
-#> 4 Hurricane+Harvey Nicaragua Nicaragua 12.609016 -85.29369
-#> 5 Hurricane+Harvey Honduras Honduras 15.257243 -86.07551
-#> 6 Hurricane+Harvey Belize Belize 16.825979 -88.76009
-#> 7 Hurricane+Harvey Cayman Islands Cayman Islands 19.703182 -79.91746
-#> 8 Hurricane+Harvey Yucatán Peninsula Yucatán Peninsula 18.801686 -89.74270
-#> 10 Hurricane+Harvey Louisiana) Louisiana) 30.870388 -92.00713
+#> Simple feature collection with 1 feature and 2 fields
+#> Geometry type: POINT
+#> Dimension: XY
+#> Bounding box: xmin: -0.6 ymin: 49.34 xmax: -0.6 ymax: 49.34
+#> Geodetic CRS: WGS 84
+#> request title geometry
+#> 252854 D-day Normandy landings POINT (-0.6 49.34)
# Multi-location events with BBOX
-geocode(event = 'Hurricane Harvey', bb = TRUE)
-#> Simple feature collection with 1 feature and 0 fields
+(harvey = geocode(event = 'Hurricane Harvey', bb = TRUE))
+#> Simple feature collection with 9 features and 5 fields
#> Geometry type: POLYGON
#> Dimension: XY
-#> Bounding box: xmin: -92.00713 ymin: 4.141302 xmax: -56.07712 ymax: 30.87039
-#> Geodetic CRS: NAD83
+#> Bounding box: xmin: -96.81531 ymin: 3.931777 xmax: -56.01361 ymax: 32.83577
+#> Geodetic CRS: WGS 84
+#> request
+#> 1 Hurricane+Harvey
+#> 2 Hurricane+Harvey
+#> 3 Hurricane+Harvey
+#> 4 Hurricane+Harvey
+#> 5 Hurricane+Harvey
+#> 6 Hurricane+Harvey
+#> 7 Hurricane+Harvey
+#> 8 Hurricane+Harvey
+#> 9 Hurricane+Harvey
+#> all
+#> 1 Windward Islands
+#> 2 Suriname
+#> 3 Guyana
+#> 4 Nicaragua
+#> 5 Honduras
+#> 6 Belize
+#> 7 Cayman Islands
+#> 8 Yucatán Peninsula
+#> 9 Southern and Eastern United States (especially Texas and Louisiana)
+#> request.1 score
+#> 1 Windward Islands 100.00
+#> 2 Suriname 100.00
+#> 3 Guyana 100.00
+#> 4 Nicaragua 100.00
+#> 5 Honduras 100.00
+#> 6 Belize 100.00
+#> 7 Cayman Islands 100.00
+#> 8 Yucatán Peninsula 100.00
+#> 9 Southern and Eastern United States (especially Texas and Louisiana) 93.73
+#> arcgis_address
+#> 1 Windward Islands
+#> 2 Suriname
+#> 3 Guyana
+#> 4 Nicaragua
+#> 5 Honduras
+#> 6 Belize
+#> 7 Cayman Islands
+#> 8 Yucatan Peninsula
+#> 9 Southern Ave & Eastern Ave, Dallas, Texas, 75209
#> geometry
-#> 1 POLYGON ((-92.00713 4.14130...
+#> 1 POLYGON ((-96.81531 3.93177...
+#> 2 POLYGON ((-96.81531 3.93177...
+#> 3 POLYGON ((-96.81531 3.93177...
+#> 4 POLYGON ((-96.81531 3.93177...
+#> 5 POLYGON ((-96.81531 3.93177...
+#> 6 POLYGON ((-96.81531 3.93177...
+#> 7 POLYGON ((-96.81531 3.93177...
+#> 8 POLYGON ((-96.81531 3.93177...
+#> 9 POLYGON ((-96.81531 3.93177...
+
+mapview::mapview(harvey)
```
+
+
### Reverse (from location to term)
``` r
geocode_rev(c(37, -119))
-#> place_id osm_type osm_id
-#> 1 298122425 relation 396492
-#> display_name
-#> 1 Fresno County, CAL Fire Southern Region, California, United States
-#> county state_district state ISO3166-2-lvl4
-#> 1 Fresno County CAL Fire Southern Region California US-CA
-#> country country_code bb
-#> 1 United States us -120.9192485,-118.3612791,35.9066756,37.586101
+#> # A tibble: 1 × 3
+#> address x y
+#>
+#> 1 NA NA
```
### 2. Consistent queries for domestic (USA) and international boundaries:
@@ -144,31 +187,61 @@ aoi_get(state = "TX", county = "Harris")
``` r
aoi_get(country = "Ukraine")
-#> Simple feature collection with 1 feature and 63 fields
+#> Simple feature collection with 1 feature and 168 fields
#> Geometry type: MULTIPOLYGON
#> Dimension: XY
-#> Bounding box: xmin: 22.08561 ymin: 44.36148 xmax: 40.08079 ymax: 52.33507
-#> CRS: +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0
-#> scalerank featurecla labelrank sovereignt sov_a3 adm0_dif level
-#> 166 1 Admin-0 country 3 Ukraine UKR 0 2
-#> type admin adm0_a3 geou_dif geounit gu_a3 su_dif subunit
-#> 166 Sovereign country Ukraine UKR 0 Ukraine UKR 0 Ukraine
+#> Bounding box: xmin: 22.08561 ymin: 45.29331 xmax: 40.08079 ymax: 52.33507
+#> Geodetic CRS: WGS 84
+#> featurecla scalerank labelrank sovereignt sov_a3 adm0_dif level
+#> 113 Admin-0 country 1 3 Ukraine UKR 0 2
+#> type tlc admin adm0_a3 geou_dif geounit gu_a3 su_dif subunit
+#> 113 Sovereign country 1 Ukraine UKR 0 Ukraine UKR 0 Ukraine
#> su_a3 brk_diff name name_long brk_a3 brk_name brk_group abbrev postal
-#> 166 UKR 0 Ukraine Ukraine UKR Ukraine Ukr. UA
-#> formal_en formal_fr note_adm0 note_brk name_sort name_alt mapcolor7
-#> 166 Ukraine Ukraine 5
-#> mapcolor8 mapcolor9 mapcolor13 pop_est gdp_md_est pop_year lastcensus
-#> 166 1 6 3 45700395 339800 NA 2001
-#> gdp_year economy income_grp wikipedia fips_10
-#> 166 NA 6. Developing region 4. Lower middle income NA
-#> iso_a2 iso_a3 iso_n3 un_a3 wb_a2 wb_a3 woe_id adm0_a3_is adm0_a3_us
-#> 166 UA UKR 804 804 UA UKR NA UKR UKR
+#> 113 UKR 0 Ukraine Ukraine UKR Ukraine Ukr. UA
+#> formal_en formal_fr name_ciawf note_adm0 note_brk name_sort name_alt
+#> 113 Ukraine Ukraine Ukraine
+#> mapcolor7 mapcolor8 mapcolor9 mapcolor13 pop_est pop_rank pop_year gdp_md
+#> 113 5 1 6 3 44385155 15 2019 153781
+#> gdp_year economy income_grp fips_10 iso_a2
+#> 113 2019 6. Developing region 4. Lower middle income UP UA
+#> iso_a2_eh iso_a3 iso_a3_eh iso_n3 iso_n3_eh un_a3 wb_a2 wb_a3 woe_id
+#> 113 UA UKR UKR 804 804 804 UA UKR 23424976
+#> woe_id_eh woe_note adm0_iso adm0_diff adm0_tlc adm0_a3_us
+#> 113 23424976 Exact WOE match as country UKR UKR UKR
+#> adm0_a3_fr adm0_a3_ru adm0_a3_es adm0_a3_cn adm0_a3_tw adm0_a3_in
+#> 113 UKR UKR UKR UKR UKR UKR
+#> adm0_a3_np adm0_a3_pk adm0_a3_de adm0_a3_gb adm0_a3_br adm0_a3_il
+#> 113 UKR UKR UKR UKR UKR UKR
+#> adm0_a3_ps adm0_a3_sa adm0_a3_eg adm0_a3_ma adm0_a3_pt adm0_a3_ar
+#> 113 UKR UKR UKR UKR UKR UKR
+#> adm0_a3_jp adm0_a3_ko adm0_a3_vn adm0_a3_tr adm0_a3_id adm0_a3_pl
+#> 113 UKR UKR UKR UKR UKR UKR
+#> adm0_a3_gr adm0_a3_it adm0_a3_nl adm0_a3_se adm0_a3_bd adm0_a3_ua
+#> 113 UKR UKR UKR UKR UKR UKR
#> adm0_a3_un adm0_a3_wb continent region_un subregion
-#> 166 NA NA Europe Europe Eastern Europe
-#> region_wb name_len long_len abbrev_len tiny homepart
-#> 166 Europe & Central Asia 7 7 4 NA 1
+#> 113 -99 -99 Europe Europe Eastern Europe
+#> region_wb name_len long_len abbrev_len tiny homepart min_zoom
+#> 113 Europe & Central Asia 7 7 4 -99 1 0
+#> min_label max_label label_x label_y ne_id wikidataid name_ar
+#> 113 2.7 7 32.14086 49.72474 1159321345 Q212 أوكرانيا
+#> name_bn name_de name_en name_es name_fa name_fr name_el name_he name_hi
+#> 113 ইউক্রেন Ukraine Ukraine Ucrania اوکراین Ukraine Ουκρανία אוקראינה युक्रेन
+#> name_hu name_id name_it name_ja name_ko name_nl name_pl name_pt
+#> 113 Ukrajna Ukraina Ucraina ウクライナ 우크라이나 Oekraïne Ukraina Ucrânia
+#> name_ru name_sv name_tr name_uk name_ur name_vi name_zh name_zht
+#> 113 Украина Ukraina Ukrayna Україна یوکرین Ukraina 乌克兰 烏克蘭
+#> fclass_iso tlc_diff fclass_tlc fclass_us fclass_fr fclass_ru
+#> 113 Admin-0 country Admin-0 country
+#> fclass_es fclass_cn fclass_tw fclass_in fclass_np fclass_pk fclass_de
+#> 113
+#> fclass_gb fclass_br fclass_il fclass_ps fclass_sa fclass_eg fclass_ma
+#> 113
+#> fclass_pt fclass_ar fclass_jp fclass_ko fclass_vn fclass_tr fclass_id
+#> 113
+#> fclass_pl fclass_gr fclass_it fclass_nl fclass_se fclass_bd fclass_ua
+#> 113
#> geometry
-#> 166 MULTIPOLYGON (((31.786 52.1...
+#> 113 MULTIPOLYGON (((31.78599 52...
```
#### USA and World Regions
@@ -180,8 +253,8 @@ aoi_describe(World_asia)
#> BBox Area: 101752122 [km^2]
#> Centroid: 85.79324 22.51263 [x,y]
#> Diminsions: 7617.139 4536.421 [width, height, in miles]
-#> area: 31270874 [km^2]
-#> Area/BBox Area: 30.7324 [%]
+#> area: 31270884 [km^2]
+#> Area/BBox Area: 30.73241 [%]
USA_south = aoi_get(state = "south")
@@ -200,44 +273,31 @@ aoi_describe(USA_south)
``` r
# 100 square mile region around Longs Peaks
-aoi_get(list("Long Peaks", 10, 10))
-#> Simple feature collection with 1 feature and 0 fields
-#> Geometry type: POLYGON
-#> Dimension: XY
-#> Bounding box: xmin: 101.5569 ymin: 3.069709 xmax: 101.702 ymax: 3.214636
-#> Geodetic CRS: WGS 84
-#> geometry
-#> 1 POLYGON ((101.5569 3.069709...
+aoi_ext("Long Peaks", wh = 10)
+#> xmin ymin xmax ymax
+#> 33.852795 3.789964 33.852975 3.790145
```
#### Location and Diminsions
``` r
# 200 square mile region around 37,-119
-aoi_get(list(37, -119, 20, 10))
-#> Simple feature collection with 1 feature and 0 fields
-#> Geometry type: POLYGON
-#> Dimension: XY
-#> Bounding box: xmin: -119.0907 ymin: 36.85507 xmax: -118.9093 ymax: 37.14493
-#> Geodetic CRS: WGS 84
-#> geometry
-#> 1 POLYGON ((-119.0907 36.8550...
+aoi_ext(xy = c(x = 119, y = 37), wh = c(20, 10))
+#> xmin ymin xmax ymax
+#> 119.00111 37.00024 119.00156 37.00042
```
#### Event and Diminsions
``` r
-# 10,000 square mile region around Normandy Landings
-aoi_get(list("D-day", 100, 100))
-#> Simple feature collection with 1 feature and 0 fields
-#> Geometry type: POLYGON
-#> Dimension: XY
-#> Bounding box: xmin: -73.99623 ymin: 43.66281 xmax: -71.96821 ymax: 45.11209
-#> Geodetic CRS: WGS 84
-#> geometry
-#> 1 POLYGON ((-73.99623 43.6628...
+# 10,000 square meter region around Normandy Landings
+aoi_ext(geo = "white house", wh = 10000, bbox = TRUE) |>
+ st_as_sf() |>
+ aoi_map(returnMap = T)
```
+
+
### 4. View and Draw
**NOTE**: The following functions require leaflet, shiny and
@@ -249,7 +309,7 @@ quickly formatted `leaflet` map (not all that dissimilar from `mapview`
so this may retire).
``` r
-AOI = geocode(location = c("Paris", "Amsterdam", "Prague", "England"), pt = TRUE)
+AOI = geocode(geo = c("Paris", "Amsterdam", "Prague", "England"), pt = TRUE)
aoi_map(AOI, returnMap = TRUE)
```
@@ -281,19 +341,20 @@ The need for AOI’s is rampant in the r-spatial community. AOI plays
nicely with the following non-exhaustive list helping users be to the
meat of their utilities without getting hung up on boundary definition.
-- ggmap
-- opendap.catalog
-- nhdplusTools
-- elevatr
-- terrainr
-- climateR
-- dataRetrivial
-- soilDB
-- nwmTools
-- osmdata
-- FedData
-- hereR
-- Please add more!
+| package |
+|---------------|
+| ggmap |
+| nhdplusTools |
+| elevatr |
+| terrainr |
+| climateR |
+| dataRetrivial |
+| soilDB |
+| nwmTools |
+| FedData |
+| hereR |
+
+Please add more!
### Installation:
@@ -301,11 +362,6 @@ meat of their utilities without getting hung up on boundary definition.
remotes::install_github("mikejohnson51/AOI")
```
-### Resources
-
-See the package [website](https://mikejohnson51.github.io/AOI/)
-vignettes showing the general workflow and functionality.
-
### Support:
AOI has been supported with funds from the [UCAR COMET
diff --git a/_pkgdown.yml b/_pkgdown.yml
new file mode 100644
index 0000000..89ab3f4
--- /dev/null
+++ b/_pkgdown.yml
@@ -0,0 +1,28 @@
+url: ~
+
+template:
+ bootstrap: 5
+ bootswatch: litera
+
+home:
+ title: Generating Area's of Interest
+
+development:
+ mode: auto
+
+authors:
+ footer:
+ roles: [cre, ctb]
+ citation:
+ roles: [cre]
+ sidebar:
+ roles: [cre, ctb, fnd]
+
+articles:
+- title: AOI generation
+ desc: Quick Start
+ contents:
+ - geocoding
+ - fiat
+ - region
+ - example
diff --git a/codecov.yml b/codecov.yml
new file mode 100644
index 0000000..6c6993f
--- /dev/null
+++ b/codecov.yml
@@ -0,0 +1,25 @@
+coverage:
+ status:
+ project:
+ default:
+ target: auto
+ threshold: 1%
+ informational: true
+ patch:
+ default:
+ target: auto
+ threshold: 1%
+ informational: true
+
+comment: false
+
+language: R
+
+sudo: false
+
+cache: packages
+
+after_success:
+
+- Rscript -e 'covr::codecov()'
+
diff --git a/docs/404.html b/docs/404.html
index 11b6eb4..b36f742 100644
--- a/docs/404.html
+++ b/docs/404.html
@@ -4,7 +4,7 @@
-
+
Page not found (404) • AOI
@@ -12,98 +12,88 @@
-
-
-
+
+
+
-
-
+
-
+
+ Skip to contents
-