I am attempting to download Sentinel 2 data in R using the rsat package which leverages the application programming interface to Copernicus' Dataspace web service. The code to create a region of interest and a time period of inquiry, new_rtoi()
, as well as the code to search Dataspace, rsat_search()
, is really straightforward and intuitive, which I very much appreciate. However, when I make the final call to rsat_download()
, I get the following error:
Ordering on ESPA platform...
Error in (new("refMethodDef", .Data = function (espa_orders, db_path, :
argument "espa_orders" is missing, with no default
I looked through the documentation for the rsat_download()
function, and "espa_orders" is not an argument. I am wondering if this a bug in an internal function. Below is my reproducible example:
library(rsat)
library(terra)
library(sf)
library(tmap)
library(tmaptools)
xmin<-538078.1
xmax<-866945.5
ymin<-773531.3
ymax<-1436377.3
AOI_ext<-ext(xmin, xmax, ymin, ymax)
AOI<-AOI_ext %>% st_bbox() %>% st_as_sfc() %>% st_as_sf(crs=6557)
tmap_mode("view")
tm_shape(AOI)+
tm_polygons(border.col="magenta", alpha=0, col=NA, lwd=2)+
tm_basemap(server = providers$Esri.WorldImagery)
toi<-as.Date("2023-04-27")
db.path <- file.path(tempdir(),"database_test")
ds.path <- file.path(tempdir(),"datasets_test")
if(!dir.exists(db.path)){
dir.create(db.path)
}
if(!dir.exists(ds.path)){
dir.create(ds.path)
}
April<-new_rtoi(name="April_test2", region=AOI, db_path=db_path, rtoi_path = ds_path)
searchit<-rsat_search(region=April, product="S2MSI1C", dates=toi)
rsat_download(searchit, db_path=db_path)
I looked at the source code of rsat_download()
and it looks like this issue arises from unnecessary subsetting of a negated condition for the particular satellite dataset application programming interface. Specifically, the original code filters the application programming interfaces to search like this:
#filter records
usgs <- x[get_api_name(x)%in%"usgs"]
x <- x[!(get_api_name(x)%in%"usgs")]
dataspace <- x[get_api_name(x)%in%"dataspace"]
x <- x[!(get_api_name(x)%in%"dataspace")]
lpdaac <- x[get_api_name(x)%in%"lpdaac"]
x <- x[!(get_api_name(x)%in%"lpdaac")]
if you removed the negated subsets so that the chunk of code looks like this:
dataspace <- x[get_api_name(x)%in%"dataspace"]
usgs <- x[get_api_name(x)%in%"usgs"]
lpdaac <- x[get_api_name(x)%in%"lpdaac"]
you'll get an error specifying that there is no method for get_api_name()
for rtoi
signature. This can be overcome by adding a this call x<-records(x)
at the top of the revised chunk so that it looks like this
x<-records(x)
dataspace <- x[get_api_name(x)%in%"dataspace"]
usgs <- x[get_api_name(x)%in%"usgs"]
lpdaac <- x[get_api_name(x)%in%"lpdaac"]
The full hack to rsat_download()
that worked for me to get around this bug was
rsat_download2<-function(x, db_path, verbose = FALSE, parallel=FALSE, ...) {
require(rsat)
args <- list(...)
if (missing(db_path)){
db_path <- get_database(x)
if(db_path==""){
stop("db_path or global environment database needed for image downloading.")
}
}
# filter records
x<-records(x)
dataspace <- x[get_api_name(x)%in%"dataspace"]
usgs <- x[get_api_name(x)%in%"usgs"]
lpdaac <- x[get_api_name(x)%in%"lpdaac"]
# run download
if(parallel){
functions_list <- list(
list(func = connection$getApi("lpdaac")$download_lpdaac_records,
args = list(lpdaac_records=lpdaac,db_path=db_path,verbose=verbose,...)),
list(func = rsat:::connection$getApi("dataspace")$dataspace_download_records,
args = list(records=dataspace,db_path=db_path,verbose=verbose,...)),
list(func = connection$getApi("usgs")$espa_order_and_download,
args = list(usgs=usgs,db_path=db_path,verbose=verbose,...))
)
null.list <-mclapply(functions_list, function(entry) {
do.call(entry$func, entry$args)
}, mc.cores = 3)
}else{
functions_list <- list(
list(func = rsat:::connection$getApi("usgs")$order_usgs_records,
args = list(espa_orders=usgs,db_path=db_path,verbose=verbose,...)),
list(func = rsat:::connection$getApi("lpdaac")$download_lpdaac_records,
args = list(lpdaac_records=lpdaac,db_path=db_path,verbose=verbose,...)),
list(func = rsat:::connection$getApi("dataspace")$dataspace_download_records,
args = list(records=dataspace,db_path=db_path,verbose=verbose,...)),
list(func = rsat:::connection$getApi("usgs")$download_espa_orders,
args = list(espa.orders=usgs,db_path=db_path,verbose=verbose,...))
)
null.list <- lapply(functions_list, function(entry) {
do.call(entry$func, entry$args)
})
}
}
And here is a working reproducible example with the hacked rsat_download2()
above:
library(rsat)
library(terra)
library(sf)
library(tmap)
library(tmaptools)
xmin<-538078.1
xmax<-866945.5
ymin<-773531.3
ymax<-1436377.3
AOI_ext<-ext(xmin, xmax, ymin, ymax)
AOI<-AOI_ext %>% st_bbox() %>% st_as_sfc() %>% st_as_sf(crs=6557)
tmap_mode("view")
tm_shape(AOI)+
tm_polygons(border.col="magenta", alpha=0, col=NA, lwd=2)+
tm_basemap(server = providers$Esri.WorldImagery)
toi<-as.Date("2023-04-27")
db.path <- file.path(tempdir(),"database_test")
ds.path <- file.path(tempdir(),"datasets_test")
if(!dir.exists(db.path)){
dir.create(db.path)
}
if(!dir.exists(ds.path)){
dir.create(ds.path)
}
April<-new_rtoi(name="April_test2", region=AOI, db_path=db.path, rtoi_path = ds.path)
rsat_search(region=April, product="S2MSI1C", dates=toi)
rsat_download2(April, db_path=db.path)