Skip to content

Commit 43fdd40

Browse files
committed
pretty close to having sp removed on sf_refactor
1 parent 65b9e30 commit 43fdd40

20 files changed

+209
-221
lines changed

DESCRIPTION

-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ Description: Several web services are available that provide access to elevation
2020
and the USGS Elevation Point Query Service <https://nationalmap.gov/epqs/>.
2121
Depends: R (>= 3.5.0)
2222
Imports:
23-
sp,
2423
raster,
2524
httr,
2625
jsonlite,
@@ -40,6 +39,5 @@ Suggests:
4039
knitr,
4140
rmarkdown,
4241
formatR,
43-
rgdal,
4442
progress
4543
VignetteBuilder: knitr

NAMESPACE

-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,3 @@ importFrom(progressr,handlers)
1111
importFrom(progressr,progressor)
1212
importFrom(progressr,with_progress)
1313
importFrom(purrr,map_dbl)
14-
importFrom(sf,st_as_sf)
15-
importFrom(sf,st_crs)
16-
importFrom(sp,wkt)

NEWS.md

+2-1
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ elevatr 1.0.0 (????-??-??)
77
- Terra?!?
88
- gdalio??
99
- slippymath??
10+
- Added API key for OpenTopography
1011

1112

1213
elevatr 0.4.2 (????-??-??)
1314
=============
1415

1516
# Bug Fixes
1617
- The epqs server was occasionally returning an empty response (see https://github.com/jhollist/elevatr/issues/29) and would error. If that happens now, elevatr will retry up to 5 times (which usually fixes the issue). If still an empty response after 5 tries, NA is returned and a warning is issued indicating what happened.
17-
- Changing future::plans was losing tempfiles on parallel downloads. Moved the change back to serial plan to after creation of raster.
18+
- Changing to future::plans was losing tempfiles on parallel downloads. Moved the change back to serial plan after creation of raster.
1819
- Changed get_tile_xy... Was using ceiling and floor to get need tiles. End result is areas near 180/-180 longitude were trying to grab non-existent tiles. Set all to get floor for tile calc.
1920

2021

R/get_elev_point.R

+3-6
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,6 @@ get_elev_point <- function(locations, prj = NULL, src = c("epqs", "aws"),
7676
overwrite = FALSE, ...){
7777

7878
src <- match.arg(src)
79-
sf_check <- ("sf" %in% class(locations)) | ("sfc" %in% class(locations))
8079

8180
# Check for existing elevation/elev_units columns and overwrite or error
8281
if(!overwrite & any(names(locations) %in% c("elevation", "elev_units"))){
@@ -104,16 +103,15 @@ get_elev_point <- function(locations, prj = NULL, src = c("epqs", "aws"),
104103
}
105104

106105
# Re-project back to original, add in units, and return
107-
locations <- methods::as(sf::st_transform(sf::st_as_sf(locations_prj),
108-
sf::st_crs(locations)), "Spatial")
106+
locations <- sf::st_transform(sf::st_as_sf(locations_prj),
107+
sf::st_crs(locations))
108+
109109
if(is.null(nrow(locations))){
110110
nfeature <- length(locations)
111111
} else {
112112
nfeature <- nrow(locations)
113113
}
114114

115-
#unit_column_name <- make.unique(c(names(locations), "elev_units"))
116-
#unit_column_name <- unit_column_name[!unit_column_name %in% names(locations)]
117115
unit_column_name <- "elev_units"
118116

119117
if(any(names(list(...)) %in% "units")){
@@ -125,7 +123,6 @@ get_elev_point <- function(locations, prj = NULL, src = c("epqs", "aws"),
125123
} else {
126124
locations[[unit_column_name]] <- rep("meters", nfeature)
127125
}
128-
if(sf_check){locations <- sf::st_as_sf(locations)}
129126

130127
if(src == "aws") {
131128
message(paste("Note: Elevation units are in", units))

R/get_elev_raster.R

+13-21
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,16 @@
6363
#' object submitted for \code{locations} argument, and the z argument
6464
#' must be specified by the user.
6565
#' @export
66-
#' @importFrom sp wkt
6766
#' @examples
6867
#' \dontrun{
6968
#' data(lake)
7069
#'
71-
#' loc_df <- data.frame(x = runif(6,min=sp::bbox(lake)[1,1],
72-
#' max=sp::bbox(lake)[1,2]),
73-
#' y = runif(6,min=sp::bbox(lake)[2,1],
74-
#' max=sp::bbox(lake)[2,2]))
75-
#' # Example for PROJ > 5.2.0
76-
#' x <- get_elev_raster(locations = loc_df, prj = sp::wkt(lake) , z=10)
77-
#'
78-
#' # Example for PROJ < 5.2.0
79-
#' x <- get_elev_raster(locations = loc_df, prj = sp::proj4string(lake) , z=10)
80-
70+
#' loc_df <- data.frame(x = runif(6,min=sf::st_bbox(lake)$xmin,
71+
#' max=sf::st_bbox(lake)$xmax),
72+
#' y = runif(6,min=sf::st_bbox(lake)$ymin,
73+
#' max=sf::st_bbox(lake)$ymax))
74+
#'
75+
#' x <- get_elev_raster(locations = loc_df, prj = st_crs(lake) , z=10)
8176
#' x <- get_elev_raster(lake, z = 12)
8277
#' x <- get_elev_raster(lake, src = "gl3", expand = 5000)
8378
#' }
@@ -91,15 +86,11 @@ get_elev_raster <- function(locations, z, prj = NULL,
9186
src <- match.arg(src)
9287
clip <- match.arg(clip)
9388

94-
# Check location type and if sp, set prj. If no prj (for either) then error
89+
# Check location type and if sf, set prj. If no prj (for either) then error
9590
locations <- loc_check(locations,prj)
9691

9792
if(is.null(prj)){
98-
if(attributes(rgdal::getPROJ4VersionInfo())$short > 520){
99-
prj <- sp::wkt(locations)
100-
} else {
101-
prj <- sp::proj4string(locations)
102-
}
93+
prj <- sf::st_crs(locations)
10394
}
10495
#need to check what is going on with PRJ when no prj passed.
10596
# Check download size and provide feedback, stop if too big!
@@ -332,11 +323,12 @@ get_opentopo <- function(locations, src, prj, expand=NULL, ...){
332323
gl1 = "SRTMGL1",
333324
alos = "AW3D30",
334325
srtm15plus = "SRTM15Plus")
326+
335327
url <- paste0(base_url, data_set,
336-
"&west=",min(bbx[1,]),
337-
"&south=",min(bbx[2,]),
338-
"&east=",max(bbx[1,]),
339-
"&north=",max(bbx[2,]),
328+
"&west=",bbx$xmin,
329+
"&south=",bbx$ymin,
330+
"&east=",bbx$xmax,
331+
"&north=",bbx$ymax,
340332
"&outputFormat=GTiff")
341333

342334
message("Downloading OpenTopography DEMs")

R/internal.R

+73-54
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ latlong_to_tilexy <- function(lon_deg, lat_deg, zoom){
1515
#' function to get a data.frame of all xyz tiles to download
1616
#' @keywords internal
1717
get_tilexy <- function(bbx,z){
18-
19-
min_tile <- latlong_to_tilexy(bbx[1,1],bbx[2,1],z)
20-
max_tile <- latlong_to_tilexy(bbx[1,2],bbx[2,2],z)
18+
min_tile <- latlong_to_tilexy(bbx$xmin,bbx$ymin,z)
19+
max_tile <- latlong_to_tilexy(bbx$xmax,bbx$ymax,z)
2120
x_all <- seq(from = floor(min_tile[1]), to = floor(max_tile[1]))
2221
y_all <- seq(from = floor(min_tile[2]), to = floor(max_tile[2]))
2322

@@ -58,21 +57,28 @@ loc_check <- function(locations, prj = NULL){
5857
} else {
5958
nfeature <- nrow(locations)
6059
}
61-
62-
if(any(class(locations)=="data.frame")){
60+
if(all(class(locations)=="data.frame")){
6361
if(is.null(prj) & !any(class(locations) %in% c("sf", "sfc", "sfg"))){
6462
stop("Please supply a valid sf crs via locations or prj.")
6563
}
6664

6765
locations <- sf::st_as_sf(x = locations, coords = c("x", "y"), crs = prj)
6866
locations$elevation <- rep(0, nfeature)
6967

68+
} else if(any(class(locations) %in% c("sf", "sfc", "sfg"))){
69+
70+
sf_crs <- sf::st_crs(locations)
71+
72+
if((is.null(sf_crs) | is.na(sf_crs)) & is.null(prj)){
73+
stop("Please supply an sf object with a valid crs.")
74+
}
75+
7076
} else if(attributes(class(locations)) %in% c("raster")){
7177

7278
raster_crs <- raster::crs(locations)
7379

74-
if((is.null(raster_crs) | is.na(raster_crs)) & is.null(prj)){
75-
stop("Please supply a valid crs via locations or prj.")
80+
if((is.null(raster_crs) | is.na(raster_crs))){
81+
stop("Please supply a valid sf crs via locations or prj.")
7682
}
7783

7884
if(is.null(raster_crs) | is.na(raster_crs)){
@@ -89,21 +95,25 @@ loc_check <- function(locations, prj = NULL){
8995
}
9096
} else if(attributes(class(locations)) %in% c("raster")){
9197

92-
locations <- unique(data.frame(raster::rasterToPoints(locations)))
93-
locations$elevation <- vector("numeric", nrow(locations))
94-
locations <- sf::st_as_sf(x = locations, coords = c("x", "y"),
95-
crs = raster_crs)
98+
if(sum(!is.na(raster::getValues(locations))) == 0){
99+
stop("No distinct points, all values NA.")
100+
} else {
101+
locations <- unique(data.frame(raster::rasterToPoints(locations)))
102+
locations$elevation <- vector("numeric", nrow(locations))
103+
locations <- sf::st_as_sf(x = locations, coords = c("x", "y"),
104+
crs = raster_crs)
105+
}
96106
}
97107
}
98108

99-
#check for long>180
100-
lll <- any(grepl("GEOGCRS",sf::st_crs(prj)) |
101-
grepl("GEODCRS", sf::st_crs(prj)) |
102-
grepl("GEODETICCRS", sf::st_crs(prj)) |
103-
grepl("GEOGRAPHICCRS", sf::st_crs(prj)) |
104-
grepl("longlat", sf::st_crs(prj)) |
105-
grepl("latlong", sf::st_crs(prj)) |
106-
grepl("4326", sf::st_crs(prj)))
109+
#check for long > 180
110+
lll <- any(grepl("^GEOGCRS$",sf::st_crs(prj)$wkt) |
111+
grepl("^GEODCRS$", sf::st_crs(prj)$wkt) |
112+
grepl("^GEODETICCRS$", sf::st_crs(prj)$wkt) |
113+
grepl("^GEOGRAPHICCRS$", sf::st_crs(prj)$wkt) |
114+
grepl("^longlat$", sf::st_crs(prj)$wkt) |
115+
grepl("^latlong$", sf::st_crs(prj)$wkt) |
116+
grepl("^4326$", sf::st_crs(prj)$wkt))
107117
if(lll){
108118
if(any(sf::st_coordinates(locations)[,1]>180)){
109119
stop("The elevatr package requires longitude in a range from -180 to 180.")
@@ -133,7 +143,7 @@ proj_expand <- function(locations,prj,expand){
133143
nfeature <- nrow(locations)
134144
}
135145

136-
if(any(sp::bbox(locations)[2,] == 0) & lll & is.null(expand)){
146+
if(any(sf::st_bbox(locations)[c("ymin","ymax")] == 0) & lll & is.null(expand)){
137147
# Edge case for lat exactly at the equator - was returning NA
138148
expand <- 0.01
139149
} else if(nfeature == 1 & lll & is.null(expand)){
@@ -147,17 +157,16 @@ proj_expand <- function(locations,prj,expand){
147157
mode = "standard")
148158
expand <- as.numeric(expand)
149159
}
150-
151-
#
160+
152161

153162
if(!is.null(expand)){
154-
#bbx <- methods::as(sf::st_buffer(sf::st_as_sf(bbx), expand), "Spatial")
155-
bbx <- sp::bbox(locations) + c(-expand, -expand, expand, expand)
163+
164+
bbx <- sf::st_bbox(locations) + c(-expand, -expand, expand, expand)
156165
} else {
157-
bbx <- sp::bbox(locations)
166+
bbx <- sf::st_bbox(locations)
158167
}
159-
bbx <- bbox_to_sp(bbx, prj = prj)
160-
bbx <- sp::bbox(sp::spTransform(bbx, sp::CRS(ll_geo)))
168+
bbx <- bbox_to_sf(bbx, prj = prj)
169+
bbx <- sf::st_bbox(sf::st_transform(bbx, crs = ll_geo))
161170
bbx
162171

163172
#sf expand - save for later
@@ -173,37 +182,48 @@ proj_expand <- function(locations,prj,expand){
173182
#' @keywords internal
174183
clip_it <- function(rast, loc, expand, clip){
175184

176-
loc_wm <- sp::spTransform(loc, raster::crs(rast))
177-
if(clip == "locations" & !grepl("Points", class(loc_wm))){
185+
loc_wm <- sf::st_transform(loc, crs = raster::crs(rast))
186+
if(clip == "locations" & !grepl("sfc_POINT", class(st_geometry(loc_wm))[1])){
178187
dem <- raster::mask(raster::crop(rast,loc_wm), loc_wm)
179-
} else if(clip == "bbox" | grepl("Points", class(loc_wm))){
188+
} else if(clip == "bbox" | grepl("sfc_POINT", class(st_geometry(loc_wm))[1])){
180189
bbx <- proj_expand(loc_wm, as.character(raster::crs(rast)), expand)
181-
bbx_sp <- sp::spTransform(bbox_to_sp(bbx), raster::crs(rast))
182-
dem <- raster::mask(raster::crop(rast,bbx_sp), bbx_sp)
190+
bbx_sf <- sf::st_transform(bbox_to_sf(bbx), crs = raster::crs(rast))
191+
dem <- raster::mask(raster::crop(rast,bbx_sf), bbx_sf)
183192
}
184193
dem
185194
}
186195

187-
#' Edited from https://github.com/jhollist/quickmapr/blob/master/R/internals.R
196+
# Edited from https://github.com/jhollist/quickmapr/blob/master/R/internals.R
197+
# Assumes geographic projection
198+
# sp bbox to poly
199+
# @param bbx an sp bbox object
200+
# @param prj defaults to "EPSG:4326"
201+
# @keywords internal
202+
# @importFrom sp wkt
203+
#bbox_to_sp <- function(bbox, prj = "EPSG:4326") {
204+
# x <- c(bbox[1, 1], bbox[1, 1], bbox[1, 2], bbox[1, 2], bbox[1, 1])
205+
# y <- c(bbox[2, 1], bbox[2, 2], bbox[2, 2], bbox[2, 1], bbox[2, 1])
206+
# p <- sp::Polygon(cbind(x, y))
207+
# ps <- sp::Polygons(list(p), "p1")
208+
# if(grepl("+proj", prj)){
209+
# sp_bbx <- sp::SpatialPolygons(list(ps), 1L,
210+
# proj4string = sp::CRS(prj))
211+
# } else {
212+
# sp_bbx <- sp::SpatialPolygons(list(ps), 1L,
213+
# proj4string = sp::CRS(SRS_string = prj))
214+
# }
215+
# sp_bbx
216+
#}
217+
188218
#' Assumes geographic projection
189-
#' sp bbox to poly
190-
#' @param bbx an sp bbox object
219+
#' sf bbox to poly
220+
#' @param bbx an sf bbox object
191221
#' @param prj defaults to "EPSG:4326"
192222
#' @keywords internal
193-
#' @importFrom sp wkt
194-
bbox_to_sp <- function(bbox, prj = "EPSG:4326") {
195-
x <- c(bbox[1, 1], bbox[1, 1], bbox[1, 2], bbox[1, 2], bbox[1, 1])
196-
y <- c(bbox[2, 1], bbox[2, 2], bbox[2, 2], bbox[2, 1], bbox[2, 1])
197-
p <- sp::Polygon(cbind(x, y))
198-
ps <- sp::Polygons(list(p), "p1")
199-
if(grepl("+proj", prj)){
200-
sp_bbx <- sp::SpatialPolygons(list(ps), 1L,
201-
proj4string = sp::CRS(prj))
202-
} else {
203-
sp_bbx <- sp::SpatialPolygons(list(ps), 1L,
204-
proj4string = sp::CRS(SRS_string = prj))
205-
}
206-
sp_bbx
223+
bbox_to_sf <- function(bbox, prj = 4326) {
224+
sf_bbx <- sf::st_as_sf(sf::st_as_sfc(bbox))
225+
sf_bbx <- sf::st_transform(sf_bbx, crs = prj)
226+
sf_bbx
207227
}
208228

209229
#' Estimate download size of DEMs
@@ -212,13 +232,12 @@ bbox_to_sp <- function(bbox, prj = "EPSG:4326") {
212232
#' @param src the src
213233
#' @param z zoom level if source is aws
214234
#' @keywords internal
215-
#' @importFrom sp wkt
216235
estimate_raster_size <- function(locations, prj, src, z = NULL){
217236

218-
locations <- bbox_to_sp(sp::bbox(locations),
237+
locations <- bbox_to_sf(sf::st_bbox(locations),
219238
prj = prj)
220239

221-
locations <- sp::spTransform(locations, sp::CRS(SRS_string = "EPSG:4326"))
240+
locations <- sf::st_transform(locations, crs = 4326)
222241
# Estimated cell size (at equator) from zoom level source
223242
# https://github.com/tilezen/joerd/blob/master/docs/data-sources.md#sources-native-resolution
224243
# Each degree at equator = 111319.9 meters
@@ -248,8 +267,8 @@ estimate_raster_size <- function(locations, prj, src, z = NULL){
248267
alos = 0.0002778,
249268
srtm15plus = 0.004165)
250269
}
251-
num_rows <- (sp::bbox(locations)[1, "max"] - sp::bbox(locations)[1, "min"])/res
252-
num_cols <- (sp::bbox(locations)[2, "max"] - sp::bbox(locations)[2, "min"])/res
270+
num_rows <- (sf::st_bbox(locations)$xmax - sf::st_bbox(locations)$xmin)/res
271+
num_cols <- (sf::st_bbox(locations)$ymax - sf::st_bbox(locations)$ymin)/res
253272

254273
num_megabytes <- (num_rows * num_cols * bits)/8388608
255274
num_megabytes

R/sysdata.rda

-98 Bytes
Binary file not shown.

TODO.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
- change prj to crs everywhere
2-
- update documentation and remove all mention of sp stuff and replace with relevant sf
1+
- [ ] change prj to crs everywhere
2+
- [ ] update documentation and remove all mention of sp stuff and replace with relevant sf
3+
- [X] all tests use sf

data/lake.rda

-10.6 KB
Binary file not shown.

data/pt_df.rda

-10 Bytes
Binary file not shown.

data/sf_big.rda

3.29 KB
Binary file not shown.

data/sp_big.rda

-5.12 KB
Binary file not shown.

man/bbox_to_sf.Rd

+19
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/bbox_to_sp.Rd

-21
This file was deleted.

0 commit comments

Comments
 (0)