From 58ed3d53fbe5beb43ee19bf9678d8390fa879f01 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 8 Nov 2023 19:27:55 +0300 Subject: [PATCH 1/2] load-stac implementation --- R/api.R | 1 + R/processes.R | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 138 insertions(+) diff --git a/R/api.R b/R/api.R index ebc49e1..a356117 100644 --- a/R/api.R +++ b/R/api.R @@ -291,6 +291,7 @@ addEndpoint = function() { Session$assignData(landsat_8_l1_c1) # assign processes Session$assignProcess(load_collection) + Session$assignProcess(load_stac) Session$assignProcess(save_result) Session$assignProcess(filter_bands) Session$assignProcess(filter_bbox) diff --git a/R/processes.R b/R/processes.R index 9080c79..606b06a 100644 --- a/R/processes.R +++ b/R/processes.R @@ -209,6 +209,143 @@ load_collection = Process$new( ) +#' load stac +load_stac <- Process$new( + id = "load_stac", + description = "Loads data from a static STAC catalog or a STAC API Collection and returns the data as a processable data cube", + categories = as.array("cubes", "import"), + summary = "Loads data from STAC", + parameters = list( + Parameter$new( + name = "url", + description = "The URL to a static STAC catalog (STAC Item, STAC Collection, or STAC Catalog) or a specific STAC API Collection that allows to filter items and to download assets", + schema = list( + type = "string" + ) + ), + Parameter$new( + name = "spatial_extent", + description = "Limits the data to load from the collection to the specified bounding box", + schema = list( + list( + title = "Bounding box", + type = "object", + subtype = "bounding-box", + properties = list( + east = list( + description = "East (upper right corner, coordinate axis 1).", + type = "number" + ), + west = list( + description = "West lower left corner, coordinate axis 1).", + type = "number" + ), + north = list( + description = "North (upper right corner, coordinate axis 2).", + type = "number" + ), + south = list( + description = "South (lower left corner, coordinate axis 2).", + type = "number" + ) + ), + required = c("east", "west", "south", "north") + ), + list( + title = "GeoJson", + type = "object", + subtype = "geojson" + ), + list( + title = "No filter", + description = "Don't filter spatially. All data is included in the data cube.", + type = "null" + ) + ) + ), + Parameter$new( + name = "temporal_extent", + description = "Limits the data to load from the collection to the specified left-closed temporal interval.", + schema = list( + type = "array", + subtype = "temporal-interval" + ) + ), + Parameter$new( + name = "bands", + description = "Only adds the specified bands into the data cube so that bands that don't match the list of band names are not available.", + schema = list( + type = "array" + ), + optional = TRUE + ), + Parameter$new( + name = "properties", + description = "Limits the data by metadata properties to include only data in the data cube which all given conditions return true for (AND operation).", + schema = list( + type = "array" + ), + optional = TRUE + ) + ), + returns = eo_datacube, + operation = function(url, spatial_extent, temporal_extent, bands = NULL, properties = NULL) { + # Temporal extent preprocess + t0 <- temporal_extent[[1]] + t1 <- temporal_extent[[2]] + duration <- c(t0, t1) + time_range <- paste(duration, collapse = "/") + + # spatial extent for cube view + xmin <- as.numeric(spatial_extent$west) + ymin <- as.numeric(spatial_extent$south) + xmax <- as.numeric(spatial_extent$east) + ymax <- as.numeric(spatial_extent$north) + + # get stac catalog metadata + stacmetadata <- rstac::stac(url) %>% + rstac::get_request() + + stac_base_url <- stacmetadata$links[[4]]$href + id <- stacmetadata$id + + # Connect to STAC API using rstac and get satellite data + stac_object <- rstac::stac(stac_base_url) + items <- stac_object %>% + rstac::stac_search( + collections = id, + bbox = c(xmin, ymin, xmax, ymax), + datetime = time_range, + limit = 10000 + ) %>% + rstac::post_request() %>% + rstac::items_fetch() + + # create image collection from stac items features # , property_filter =function(x) {x[["eo:cloud_cover"]] < 30} + img.col <- gdalcubes::stac_image_collection(items$features) + + # Define cube view with monthly aggregation + v.overview <- gdalcubes::cube_view( + srs = "EPSG:4326", dx = 30, dy = 30, dt = "P1M", + aggregation = "median", resampling = "average", + extent = list( + t0 = t0, t1 = t1, + left = xmin, right = xmax, + top = ymax, bottom = ymin + ) + ) + # gdalcubes creation + cube <- gdalcubes::raster_cube(img.col, v.overview) + + if (!is.null(bands)) { + cube <- gdalcubes::select_bands(cube, bands) + } + message(gdalcubes::as_json(cube)) + return(cube) + } +) + + #' filter bands filter_bands = Process$new( id = "filter_bands", From aa5bd576b14417c123b3c761f77624c499006a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brian=20P=CF=95ndi?= Date: Wed, 8 Nov 2023 17:40:48 +0100 Subject: [PATCH 2/2] Update load_stac --- R/processes.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/processes.R b/R/processes.R index 606b06a..12a0ada 100644 --- a/R/processes.R +++ b/R/processes.R @@ -289,7 +289,7 @@ load_stac <- Process$new( ) ), returns = eo_datacube, - operation = function(url, spatial_extent, temporal_extent, bands = NULL, properties = NULL) { + operation = function(url, spatial_extent, temporal_extent, bands = NULL, properties = NULL, job) { # Temporal extent preprocess t0 <- temporal_extent[[1]] t1 <- temporal_extent[[2]] @@ -971,4 +971,4 @@ save_result = Process$new( job$setOutput(format) return(data) } -) \ No newline at end of file +)