About rstac

This document will introduce the concepts of the rstac package. rstac is an R client library for STAC that fully supports STAC API v1.0.0 and its earlier versions (>= v0.8.0).

The table shows the functions implemented by the rstac package according to the STAC API endpoints. For each endpoint, rstac has a specialized implementation.

STAC endpoints rstac functions API version
/ stac() >= 0.9.0
/stac stac() < 0.9.0
/collections collections() >= 0.9.0
/collections/{collectionId} collections(collection_id) >= 0.9.0
/collections/{collectionId}/items items() >= 0.9.0
/collections/{collectionId}/items/{itemId} items(feature_id) >= 0.9.0
/search stac_search() >= 0.9.0
/stac/search stac_search() < 0.9.0
/conformance conformance() >= 0.9.0
/collections/{collectionId}/queryables queryables() >= 1.0.0

The rstac package makes the requests explicitly. The rstac pipeline creates the endpoints with function concatenations and then requests them.

Getting started

Let’s start by installing the rstac package:

install.packages("rstac")

Creating queries

This tutorial use the STAC API made available by the Brazil Data Cube (BDC) project. BDC is a research, development, and technological innovation project of the National Institute for Space Research (INPE), Brazil.

Let’s start by creating a query for the BDC catalog.

s_obj <- stac("https://brazildatacube.dpi.inpe.br/stac/")
s_obj
#> ###RSTACQuery
#> - url: https://brazildatacube.dpi.inpe.br/stac/
#> - params:
#> - field(s): version, base_url, endpoint, params, verb, encode

The RSTACQuery object stores the metadata of the created query. This metadata can be accessed as a list element during query creation.

s_obj$base_url
#> [1] "https://brazildatacube.dpi.inpe.br/stac/"

Endpoints are constructed through function concatenations provided by rstac. Some examples are shown below:

s_obj |> 
  collections()
#> ###RSTACQuery
#> - url: https://brazildatacube.dpi.inpe.br/stac/
#> - params:
#> - field(s): version, base_url, endpoint, params, verb, encode
s_obj |> 
  collections("S2-16D-2")
#> ###RSTACQuery
#> - url: https://brazildatacube.dpi.inpe.br/stac/
#> - params:
#>   - collection_id: S2-16D-2
#> - field(s): version, base_url, endpoint, params, verb, encode
s_obj |> 
  collections("S2-16D-2") |>
  items()
#> ###RSTACQuery
#> - url: https://brazildatacube.dpi.inpe.br/stac/
#> - params:
#>   - collection_id: S2-16D-2
#> - field(s): version, base_url, endpoint, params, verb, encode
s_obj |> 
  collections("S2-16D-2") |> 
  items(feature_id = "S2-16D_V2_015011_20190117")
#> ###RSTACQuery
#> - url: https://brazildatacube.dpi.inpe.br/stac/
#> - params:
#>   - collection_id: S2-16D-2
#>   - feature_id: S2-16D_V2_015011_20190117
#> - field(s): version, base_url, endpoint, params, verb, encode
s_obj |> 
  stac_search(collections = c("CB4_64_16D_STK", "S2-16D-2")) |>
  ext_query("bdc:tile" == "022024")
#> ###RSTACQuery
#> - url: https://brazildatacube.dpi.inpe.br/stac/
#> - params:
#>   - collections: CB4_64_16D_STK,S2-16D-2
#>   - query: list(eq = "022024")
#> - field(s): version, base_url, endpoint, params, verb, encode

Making requests

rstac package supports GET and POST HTTP methods. With future updates to the STAC specifications, it is intended to support other methods such as PUT and DELETE. In addition, it is possible to add more configuration options to the request, such as headers (httr::add_headers()) and cookies (httr::set_cookies()). These options are available in the httr package documentation in the config.

HTTP GET: get_request()

s_obj |>
  collections(collection_id = "CB4_64_16D_STK-1") |>
  items() |>
  get_request() 
#> ###STACItemCollection
#> - matched feature(s): 7505
#> - features (10 item(s) / 7495 not fetched):
#>   - CB4_64_16D_STK_v001_021020_2022-08-13_2022-08-28
#>   - CB4_64_16D_STK_v001_021021_2022-08-13_2022-08-28
#>   - CB4_64_16D_STK_v001_021022_2022-08-13_2022-08-28
#>   - CB4_64_16D_STK_v001_021023_2022-08-13_2022-08-28
#>   - CB4_64_16D_STK_v001_018022_2022-08-13_2022-08-28
#>   - CB4_64_16D_STK_v001_021024_2022-08-13_2022-08-28
#>   - CB4_64_16D_STK_v001_021025_2022-08-13_2022-08-28
#>   - CB4_64_16D_STK_v001_021026_2022-08-13_2022-08-28
#>   - CB4_64_16D_STK_v001_021027_2022-08-13_2022-08-28
#>   - CB4_64_16D_STK_v001_021029_2022-08-13_2022-08-28
#> - assets: 
#> BAND13, BAND14, BAND15, BAND16, CLEAROB, CMASK, EVI, NDVI, PROVENANCE, TOTALOB, thumbnail
#> - item's fields: 
#> assets, bbox, collection, geometry, id, links, properties, stac_extensions, stac_version, type

HTTP POST: post_request()

s_obj |>
  stac_search(
    collections = c("CB4_64_16D_STK-1", "S2-16D-2"),
    datetime = "2021-01-01/2021-01-31",
    limit = 400) |>
  post_request()
#> ###STACItemCollection
#> - matched feature(s): 1818
#> - features (400 item(s) / 1418 not fetched):
#>   - CB4_64_16D_STK_v001_017022_2021-01-17_2021-02-01
#>   - CB4_64_16D_STK_v001_017023_2021-01-17_2021-02-01
#>   - CB4_64_16D_STK_v001_018023_2021-01-17_2021-02-01
#>   - CB4_64_16D_STK_v001_018020_2021-01-17_2021-02-01
#>   - CB4_64_16D_STK_v001_018021_2021-01-17_2021-02-01
#>   - CB4_64_16D_STK_v001_018024_2021-01-17_2021-02-01
#>   - CB4_64_16D_STK_v001_018022_2021-01-17_2021-02-01
#>   - CB4_64_16D_STK_v001_019021_2021-01-17_2021-02-01
#>   - CB4_64_16D_STK_v001_019020_2021-01-17_2021-02-01
#>   - CB4_64_16D_STK_v001_019022_2021-01-17_2021-02-01
#>   - ... with 390 more feature(s).
#> - assets: 
#> B01, B02, B03, B04, B05, B06, B07, B08, B09, B11, B12, B8A, BAND13, BAND14, BAND15, BAND16, CLEAROB, CMASK, EVI, NBR, NDVI, PROVENANCE, SCL, TOTALOB, thumbnail
#> - item's fields: 
#> assets, bbox, collection, geometry, id, links, properties, stac_extensions, stac_version, type

Example of providing an additional argument to HTTP verb in a request:

s_obj |> 
  stac_search(collections = c("CB4_64_16D_STK-1", "S2-16D-2")) |>
  post_request(config = c(httr::add_headers("x-api-key" = "MY-KEY")))
#> ###STACItemCollection
#> - matched feature(s): 77540
#> - features (10 item(s) / 77530 not fetched):
#>   - S2-16D_V2_001014_20220930
#>   - S2-16D_V2_002011_20220930
#>   - S2-16D_V2_002012_20220930
#>   - S2-16D_V2_002013_20220930
#>   - S2-16D_V2_002014_20220930
#>   - S2-16D_V2_002015_20220930
#>   - S2-16D_V2_002016_20220930
#>   - S2-16D_V2_003011_20220930
#>   - S2-16D_V2_003012_20220930
#>   - S2-16D_V2_003013_20220930
#> - assets: 
#> B01, B02, B03, B04, B05, B06, B07, B08, B09, B11, B12, B8A, CLEAROB, EVI, NBR, NDVI, PROVENANCE, SCL, TOTALOB, thumbnail
#> - item's fields: 
#> assets, bbox, collection, geometry, id, links, properties, stac_extensions, stac_version, type

Visualization of the documents

Each rstac object is mapped according to the endpoints of the STAC spec. In this way, each object has a different view. The format for viewing objects is in Markdown.

STACCatalog object

s_obj |> 
  get_request()
#> ###STACCatalog
#> - id: bdc
#> - description: Brazil Data Cube Catalog
#> - field(s): description, id, stac_version, links

STACCollection object

s_obj |>
  collections("S2-16D-2") |>
  get_request()
#> ###STACCollection
#> - id: S2-16D-2
#> - title: Sentinel-2 - MSI - Sen2cor - Cube LCF 16 days - v002
#> - description: 
#> This datacube was generated with all available surface reflectance images processed using Sen2cor. The data is provided with 10 meters of spatial resolution, reprojected and cropped to BDC_SM grid Version 2 (BDC_SM V2), considering a temporal compositing function of 16 days using the Least Cloud Cover First (LCF) best pixel approach.
#> - field(s): 
#> id, stac_version, stac_extensions, title, version, deprecated, description, license, properties, extent, bdc:bands_quicklook, bdc:metadata, bdc:grs, bdc:tiles, bdc:composite_function, bdc:type, cube:dimensions, bdc:crs, bdc:temporal_composition, links

STACItem object

s_obj |>
  collections("CB4_64_16D_STK-1") |>
  items(feature_id = "CB4_64_16D_STK_v001_021027_2020-07-11_2020-07-26") |>
  get_request()
#> ###STACItem
#> - id: CB4_64_16D_STK_v001_021027_2020-07-11_2020-07-26
#> - collection: CB4_64_16D_STK-1
#> - bbox: xmin: -54.36897, ymin: -26.94755, xmax: -47.73540, ymax: -22.87350
#> - datetime: 2020-07-11T00:00:00
#> - assets: 
#> BAND13, BAND14, BAND15, BAND16, CLEAROB, CMASK, EVI, NDVI, PROVENANCE, TOTALOB, thumbnail
#> - item's fields: 
#> assets, bbox, collection, geometry, id, links, properties, stac_extensions, stac_version, type

STACItemCollection object

s_obj |> 
  stac_search(collections = c("CB4_64_16D_STK", "S2-16D-2")) |>
  get_request()
#> ###STACItemCollection
#> - matched feature(s): 70035
#> - features (10 item(s) / 70025 not fetched):
#>   - S2-16D_V2_001014_20220930
#>   - S2-16D_V2_002011_20220930
#>   - S2-16D_V2_002012_20220930
#>   - S2-16D_V2_002013_20220930
#>   - S2-16D_V2_002014_20220930
#>   - S2-16D_V2_002015_20220930
#>   - S2-16D_V2_002016_20220930
#>   - S2-16D_V2_003011_20220930
#>   - S2-16D_V2_003012_20220930
#>   - S2-16D_V2_003013_20220930
#> - assets: 
#> B01, B02, B03, B04, B05, B06, B07, B08, B09, B11, B12, B8A, CLEAROB, EVI, NBR, NDVI, PROVENANCE, SCL, TOTALOB, thumbnail
#> - item's fields: 
#> assets, bbox, collection, geometry, id, links, properties, stac_extensions, stac_version, type

Besides, the rstac package provides several auxiliary functions for STACItem and STACItemCollection objects. These auxiliary functions operate at the item or asset level. Functions dedicated to items have the prefix items_. Otherwise, asset-oriented functions have the prefix assets_

Items functions

The STACItemCollection object have some facilitating functions to manipulate/extract information, for example:

  • items_fields(): Lists fields names inside an item.
  • items_filter(): Performs a filter by items according to expressions operating on the properties of a STACItemCollection object.
  • items_fetch(): Performs the pagination of items.
  • items_length(): Returns the number of items in an object.
  • items_matched(): Returns the number of items matching the search criteria.
  • items_assets(): Returns the assets name from STACItemCollection and STACItem objects.

It is interesting to verify the fields of items before filtering:

s_obj |>
  stac_search(
    collections = "CB4_64_16D_STK-1",
    datetime = "2019-01-01/2019-12-31",
    limit = 100) |> 
  post_request() |>
  items_fields(field = "properties")
#>  [1] "bdc:tiles"      "created"        "datetime"       "end_datetime"  
#>  [5] "eo:bands"       "eo:cloud_cover" "eo:gsd"         "instruments"   
#>  [9] "platform"       "start_datetime" "updated"

Let’s filter items that have the percentage of clouds smaller than 10%:

s_obj |>
  stac_search(
    collections = "CB4_64_16D_STK-1",
    datetime = "2019-01-01/2019-12-31",
    limit = 100) |> 
  post_request() |>
  items_filter(properties$`eo:cloud_cover` < 10)
#> ###STACItemCollection
#> - matched feature(s): 1127
#> - features (49 item(s) / 1078 not fetched):
#>   - CB4_64_16D_STK_v001_020025_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_020026_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_020027_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021023_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021024_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021025_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021026_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021027_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_022022_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_022023_2019-12-19_2019-12-31
#>   - ... with 39 more feature(s).
#> - assets: 
#> BAND13, BAND14, BAND15, BAND16, CLEAROB, CMASK, EVI, NDVI, PROVENANCE, TOTALOB, thumbnail
#> - item's fields: 
#> assets, bbox, collection, geometry, id, links, properties, stac_extensions, stac_version, type

Number of items returned in the query (in this case equal to the limit defined as parameter):

s_obj |>
  stac_search(
    collections = "CB4_64_16D_STK-1",
    datetime = "2019-01-01/2019-12-31",
    limit = 100) |> 
  post_request() |>
  items_length()
#> [1] 100

Number of matched items in the query:

s_obj |>
  stac_search(
    collections = "CB4_64_16D_STK-1",
    datetime = "2019-01-01/2019-12-31",
    limit = 100) |>
  post_request() |>
  items_matched()
#> [1] 1127

Paginating all items that were matched in the query:

items_fetched <- s_obj |>
  stac_search(
    collections = "CB4_64_16D_STK-1",
    datetime = "2019-01-01/2019-12-31",
    limit = 500) |>
  post_request() |>
  items_fetch(progress = FALSE)

items_fetched
#> ###STACItemCollection
#> - matched feature(s): 1127
#> - features (1127 item(s) / 0 not fetched):
#>   - CB4_64_16D_STK_v001_020024_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_020025_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_020026_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_020027_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021023_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021024_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021025_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021026_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021027_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_022021_2019-12-19_2019-12-31
#>   - ... with 1117 more feature(s).
#> - assets: 
#> BAND13, BAND14, BAND15, BAND16, CLEAROB, CMASK, EVI, NDVI, PROVENANCE, TOTALOB, thumbnail
#> - item's fields: 
#> assets, bbox, collection, geometry, id, links, properties, stac_extensions, stac_version, type

Note that the 1127 has been recovered:

items_length(items_fetched)
#> [1] 1127

Listing the assets of the retrieved items:

items_assets(items_fetched)
#>  [1] "BAND13"     "BAND14"     "BAND15"     "BAND16"     "CLEAROB"   
#>  [6] "CMASK"      "EVI"        "NDVI"       "PROVENANCE" "TOTALOB"   
#> [11] "thumbnail"

Assets functions

  • assets_download(): Downloads the assets provided by the STAC API.
  • assets_url(): Returns a character vector with each asset href. For the URL you can add the GDAL library drivers for the following schemes:
    • HTTP/HTTPS files;
    • S3 (AWS S3);
    • GS (Google Cloud Storage).
  • assets_select(): Selects the assets of each item by its name.
  • assets_rename(): Rename each asset using a named list or a function.

Listing the assets names of all items:

s_obj |>
  stac_search(
    collections = "CB4_64_16D_STK-1",
    datetime = "2019-01-01/2019-12-31",
    limit = 10) |>
  post_request() |>
  items_assets()
#>  [1] "BAND13"     "BAND14"     "BAND15"     "BAND16"     "CLEAROB"   
#>  [6] "CMASK"      "EVI"        "NDVI"       "PROVENANCE" "TOTALOB"   
#> [11] "thumbnail"

Selecting assets that have names "BAND14" and "NDVI"

selected_assets <- s_obj |>
  stac_search(
    collections = "CB4_64_16D_STK-1",
    datetime = "2019-01-01/2019-12-31",
    limit = 10) |>
  post_request() |>
  assets_select(asset_names = c("BAND14", "NDVI"))
items_assets(selected_assets)
#> [1] "BAND14" "NDVI"

Listing asset urls from the selected bands:

selected_assets |> 
  assets_url()
#>  [1] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/020024/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_020024_2019-12-19_2019-12-31_BAND14.tif"
#>  [2] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/020025/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_020025_2019-12-19_2019-12-31_BAND14.tif"
#>  [3] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/020026/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_020026_2019-12-19_2019-12-31_BAND14.tif"
#>  [4] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/020027/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_020027_2019-12-19_2019-12-31_BAND14.tif"
#>  [5] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/021023/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_021023_2019-12-19_2019-12-31_BAND14.tif"
#>  [6] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/021024/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_021024_2019-12-19_2019-12-31_BAND14.tif"
#>  [7] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/021025/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_021025_2019-12-19_2019-12-31_BAND14.tif"
#>  [8] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/021026/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_021026_2019-12-19_2019-12-31_BAND14.tif"
#>  [9] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/021027/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_021027_2019-12-19_2019-12-31_BAND14.tif"
#> [10] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/022021/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_022021_2019-12-19_2019-12-31_BAND14.tif"
#> [11] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/020024/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_020024_2019-12-19_2019-12-31_NDVI.tif"  
#> [12] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/020025/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_020025_2019-12-19_2019-12-31_NDVI.tif"  
#> [13] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/020026/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_020026_2019-12-19_2019-12-31_NDVI.tif"  
#> [14] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/020027/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_020027_2019-12-19_2019-12-31_NDVI.tif"  
#> [15] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/021023/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_021023_2019-12-19_2019-12-31_NDVI.tif"  
#> [16] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/021024/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_021024_2019-12-19_2019-12-31_NDVI.tif"  
#> [17] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/021025/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_021025_2019-12-19_2019-12-31_NDVI.tif"  
#> [18] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/021026/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_021026_2019-12-19_2019-12-31_NDVI.tif"  
#> [19] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/021027/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_021027_2019-12-19_2019-12-31_NDVI.tif"  
#> [20] "https://brazildatacube.dpi.inpe.br/cubes/composed/CB4_64_16D_STK/v001/022021/2019-12-19_2019-12-31/CB4_64_16D_STK_v001_022021_2019-12-19_2019-12-31_NDVI.tif"

Renaming assets using the pattern <old-name> = <new-name>

renamed_assets <- selected_assets |> 
  assets_rename(BAND14 = "B14")
renamed_assets
#> ###STACItemCollection
#> - matched feature(s): 1127
#> - features (10 item(s) / 1117 not fetched):
#>   - CB4_64_16D_STK_v001_020024_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_020025_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_020026_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_020027_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021023_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021024_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021025_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021026_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_021027_2019-12-19_2019-12-31
#>   - CB4_64_16D_STK_v001_022021_2019-12-19_2019-12-31
#> - assets: B14, NDVI
#> - item's fields: 
#> assets, bbox, collection, geometry, id, links, properties, stac_extensions, stac_version, type

In the assets field of the output it can be seen that the asset’s name has changed. It is also possible to check the asset names using the items_assets() function.

items_assets(renamed_assets)
#> [1] "B14"  "NDVI"

Asset preview

rstac also provides a helper function to plot preview assets (e.g. thumbnail and quicklook).

second_item <- items_fetched$features[[2]]
second_item |>
  assets_url(asset_names = "thumbnail") |>
  preview_plot()