Accessing the MAAP CMR STAC with R
Authors: Harshini Girish (UAH), Sheyenne Kirkland (UAH), Alex Mandel (DevSeed), Henry Rodman (DevSeed)
Date: December 13, 2024
Description: In this notebook, we’ll use rstac
to search for collections and associated items within the MAAP STAC Catalog.
Run This Notebook
To access and run this tutorial within MAAP’s Algorithm Development Environment (ADE), please refer to the “Getting started with the MAAP” section of our documentation.
Disclaimer: it is highly recommended to run a tutorial within MAAP’s ADE, which already includes packages specific to MAAP, such as maap-py. Running the tutorial outside of the MAAP ADE may lead to errors. Users should work within the “R/Python” workspace.
Additional Resources
-
A resource from NASA Openscapes, showing users how to search for NASA data in R and get authentication using the package
earthdatalogin
. Additionally, it shows users how to find data stored in NASA STACs (SpatioTemporal Asset Catalogs).
rstac: Client Library for SpatioTemporal Asset Catalog
A page with materials for the
rstac
library.
Searching the STAC Catalog (MAAP Docs)
A notebook in the MAAP Docs that shows users how to search the MAAP STAC using Python.
## Install/Load Packages
Let’s install and load the packages necessary for this tutorial.
[ ]:
install.packages("rstac")
library(rstac)
Initializing the MAAP STAC Endpoint
Before beginning, we’ll form a connection to the MAAP STAC endpoint to set up and inspect the STAC endpoint for querying geospatial data.
[224]:
# Define the MAAP STAC endpoint
stac_endpoint <- stac("https://stac.maap-project.org/")
# Display the STAC endpoint metadata
cat("STAC Endpoint Metadata:\n")
print(stac_endpoint)
STAC Endpoint Metadata:
###rstac_query
- url: https://stac.maap-project.org/
- params:
- field(s): version, base_url, endpoint, params, verb, encode
Fetching and Displaying STAC Collections
This code fetches and displays collections from a STAC (SpatioTemporal Asset Catalog) endpoint. It extracts id and title for each collection for further exploration or querying.
[225]:
collections <- stac_endpoint |>
collections() |>
get_request()
# Ensure collections are retrieved
if (length(collections$collections) > 0) {
# Extract collection IDs and titles
collection_info <- lapply(collections$collections, function(x) {
list(id = x$id, title = x$title)
})
# Display the collection information
for (i in seq_along(collection_info)) {
cat("Collection ID:", collection_info[[i]]$id, "\n")
cat("Title:", collection_info[[i]]$title, "\n\n")
}
} else {
cat("No collections found or error retrieving collections.\n")
}
Collection ID: Landsat8_SurfaceReflectance
Title: Landsat 8 Operational Land Imager (OLI) Surface Reflectance Analysis Ready Data (ARD) V1, Peru and Equatorial Western Africa, April 2013-January 2020
Collection ID: Global_PALSAR2_PALSAR_FNF
Title: Global 25m Resolution PALSAR-2/PALSAR Forest/Non-Forest Map
Collection ID: Global_Forest_Change_2000-2017
Title: Global Forest Change 2000-2017
Collection ID: AFRISAR_DLR2
Title: AFRISAR_DLR2
Collection ID: GlobCover_09
Title: GlobCover Global Land Cover Product (2009)
Collection ID: AfriSAR_UAVSAR_KZ
Title: AfriSAR UAVSAR Vertical Wavenumber (KZ) Generated Using NISAR Tools
Collection ID: AfriSAR_UAVSAR_Ungeocoded_Covariance
Title: AfriSAR UAVSAR Ungeocoded Covariance Matrix product Generated Using NISAR Tools
Collection ID: AfriSAR_UAVSAR_Normalization_Area
Title: AfriSAR UAVSAR Normalization Area Generated Using NISAR Tools
Collection ID: AfriSAR_UAVSAR_Geocoded_SLC
Title: AfriSAR UAVSAR Geocoded SLCs Generated Using NISAR Tools
Collection ID: AfriSAR_UAVSAR_Geocoded_Covariance
Title: AfriSAR UAVSAR Geocoded Covariance Matrix product Generated Using NISAR Tools
Collection ID: GlobCover_05_06
Title: GlobCover Global Land Cover Product (2005-06)
Collection ID: GEDI_CalVal_Field_Data
Title: Global Ecosystem Dynamics Investigation (GEDI) Calibration/Validation Field Survey Dataset
Collection ID: AfriSAR_UAVSAR_Coreg_SLC
Title: AfriSAR UAVSAR Coregistered SLCs Generated Using NISAR Tools
Collection ID: GEDI_CalVal_Lidar_Data_Compressed
Title: Global Ecosystem Dynamics Investigation (GEDI) Calibration/Validation Airborne Lidar Dataset (Compressed)
Collection ID: ABoVE_UAVSAR_PALSAR
Title: Arctic-Boreal Vulnerability Experiment Uninhabited Aerial Vehicle Synthetic Aperture Radar Polarimetric SAR
Collection ID: AFRISAR_DLR
Title: AFRISAR_DLR
Collection ID: BIOSAR1
Title: BIOSAR1
Collection ID: GEDI_CalVal_Lidar_Data
Title: Global Ecosystem Dynamics Investigation (GEDI) Calibration/Validation Airborne Lidar Dataset
Collection ID: ICESat2_Boreal_AGB_tindex_average
Title: ICESat2-Boreal Above Ground Biomass T-Index Average
Collection ID: Paraguay_Country_Pilot
Title: Paraguay Country Pilot
Collection ID: ESACCI_Biomass_L4_AGB_V4_100m
Title: ESA CCI Above-Ground Biomass Product Level 4 Version 4
Collection ID: NCEO_Africa_AGB_100m_2017
Title: National Centre for Eath Oberservation (NCEO) Africa Aboveground Woody Biomass (AGB) 2017
Collection ID: SRTMGL1_COD
Title: NASA Shuttle Radar Topography Mission Global 1
Collection ID: GEDI_CalVal_Lidar_COPC
Title: GEDI CalVal Lidar COPC
Collection ID: icesat2-boreal
Title: Gridded Boreal Aboveground Biomass Density c.2020 at 30m resolution
Collection ID: nisar-sim
Title: Simulated NISAR
Collection ID: glad-glclu2020-v2
Title: GLAD: Annual maps of land cover and land use
Collection ID: glad-glclu2020-change-v2
Title: GLAD: Net change of land cover and land use between 2000 and 2020
Assigning and Selecting a STAC Collection ID
This code selects a collection ID from the list of collections retrieved from the STAC catalog. It selects a single collection ID from the fetched collections.
[226]:
# Assign collection ID
if (length(collections$collections) > 0) {
# Choose a specific collection (21st in this example)
collection_id <- collections$collections[[21]]$id
cat("Selected Collection ID:", collection_id, "\n")
} else {
stop("No collections found.")
}
Selected Collection ID: ESACCI_Biomass_L4_AGB_V4_100m
Searching and Retrieving Items from a STAC Collection
This code searches for items in the selected STAC collection using the stac_search() function. It safely handles errors during the query and retrieves the items, printing details such as item IDs, dates, and associated links. If no items are found, it outputs a message indicating so.
[227]:
# Fetch items
items <- stac_endpoint |>
stac_search(collections = collection_id) |>
get_request()
# Print the retrieved items
print(items)
# Process and display item information
if (length(items$features) > 0) {
cat("Found", length(items$features), "items:\n\n")
# Display details of the first few items
for (i in seq_len(min(5, length(items$features)))) {
item <- items$features[[i]]
cat("Item ID:", item$id, "\n")
cat("Date:", item$properties$datetime, "\n")
cat("Links:", paste(sapply(item$links, function(x) x$href), collapse = ", "), "\n\n")
}
} else {
cat("No items found for collection:", collection_id, "\n")
}
###Items
- features (10 item(s)):
- S50W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- S50W070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- S50W060_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- S50W040_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- S50E070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- S50E060_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- S40W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- S40W070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- S40E170_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- S40E160_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- assets: estimates, standard_deviation
- item's fields:
assets, bbox, collection, geometry, id, links, properties, stac_extensions, stac_version, type
Found 10 items:
Item ID: S50W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
Date: 2020-01-01T00:00:00+00:00
Links: NULL, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m, https://stac.maap-project.org/, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m/items/S50W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
Item ID: S50W070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
Date: 2020-01-01T00:00:00+00:00
Links: NULL, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m, https://stac.maap-project.org/, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m/items/S50W070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
Item ID: S50W060_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
Date: 2020-01-01T00:00:00+00:00
Links: NULL, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m, https://stac.maap-project.org/, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m/items/S50W060_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
Item ID: S50W040_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
Date: 2020-01-01T00:00:00+00:00
Links: NULL, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m, https://stac.maap-project.org/, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m/items/S50W040_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
Item ID: S50E070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
Date: 2020-01-01T00:00:00+00:00
Links: NULL, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m, https://stac.maap-project.org/, https://stac.maap-project.org/collections/ESACCI_Biomass_L4_AGB_V4_100m/items/S50E070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
Extracting and Displaying Assets from a STAC Item
This code extracts the assets (downloadable data resources) from the first item in the STAC search results.
[228]:
if (length(items$features) > 0) {
# Extract and display the first item's assets
first_item <- items$features[[1]]
assets <- first_item$assets
print(first_item)
cat("Available assets:\n")
print(names(assets)) # List of asset types
} else {
cat("No items found for collection:", collection_id, "\n")
}
###Item
- id: S50W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0
- collection: ESACCI_Biomass_L4_AGB_V4_100m
- bbox:
xmin: -80.00000, ymin: -60.00000, xmax: -70.00000, ymax: -50.00000
- datetime: 2020-01-01T00:00:00+00:00
- assets: estimates, standard_deviation
- item's fields:
assets, bbox, collection, geometry, id, links, properties, stac_extensions, stac_version, type
Available assets:
[1] "estimates" "standard_deviation"
Listing and Displaying Asset URLs from a STAC Item
This loop iterates through all available assets in the STAC item and prints each asset’s name and its corresponding URL.
[229]:
for (asset_name in names(assets)) {
cat("Asset:", asset_name, "\n")
cat("URL:", assets[[asset_name]]$href, "\n\n")
}
Asset: estimates
URL: s3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S50W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif
Asset: standard_deviation
URL: s3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S50W080_ESACCI-BIOMASS-L4-AGB_SD-MERGED-100m-2020-fv4.0.tif
Performing a Focused Search Using the MAAP STAC API
This code performs a search query and retrieves items from the MAAP STAC. The search is configured with the following parameters:
Collection: Specifies the dataset to search within.
Temporal Range: Filters items within a specific date range.
Bounding Box: Spatially filters items to a defined area of interest.
[230]:
datetime <- "2020-01-01T00:00:00Z/2020-01-31T23:59:59Z" # YYYY-MM-DDTHH:MM:SSZ/YYYY-MM-DDTHH:MM:SSZ
bbox <- c(-74,-57,-18,-5.8)
stac_query <- stac(
stac_endpoint[[2]]
)|>
stac_search(
collections = collection_id,
bbox = bbox,
datetime = datetime
) |>
get_request()
#stac_query
results <- lapply(
stac_query$features,
\(x) data.frame(collection = x$collection, id = x$id, datetime = x$properties$datetime, desc = x$assets$estimates$description)
) |>
do.call(what = rbind)
results
collection | id | datetime | desc |
---|---|---|---|
<chr> | <chr> | <chr> | <chr> |
ESACCI_Biomass_L4_AGB_V4_100m | S50W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0 | 2020-01-01T00:00:00+00:00 | Cloud Optimized GeoTIFF of AGB estimates |
ESACCI_Biomass_L4_AGB_V4_100m | S50W070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0 | 2020-01-01T00:00:00+00:00 | Cloud Optimized GeoTIFF of AGB estimates |
ESACCI_Biomass_L4_AGB_V4_100m | S50W060_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0 | 2020-01-01T00:00:00+00:00 | Cloud Optimized GeoTIFF of AGB estimates |
ESACCI_Biomass_L4_AGB_V4_100m | S50W040_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0 | 2020-01-01T00:00:00+00:00 | Cloud Optimized GeoTIFF of AGB estimates |
ESACCI_Biomass_L4_AGB_V4_100m | S40W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0 | 2020-01-01T00:00:00+00:00 | Cloud Optimized GeoTIFF of AGB estimates |
ESACCI_Biomass_L4_AGB_V4_100m | S40W070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0 | 2020-01-01T00:00:00+00:00 | Cloud Optimized GeoTIFF of AGB estimates |
ESACCI_Biomass_L4_AGB_V4_100m | S30W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0 | 2020-01-01T00:00:00+00:00 | Cloud Optimized GeoTIFF of AGB estimates |
ESACCI_Biomass_L4_AGB_V4_100m | S30W070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0 | 2020-01-01T00:00:00+00:00 | Cloud Optimized GeoTIFF of AGB estimates |
ESACCI_Biomass_L4_AGB_V4_100m | S30W060_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0 | 2020-01-01T00:00:00+00:00 | Cloud Optimized GeoTIFF of AGB estimates |
ESACCI_Biomass_L4_AGB_V4_100m | S20W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0 | 2020-01-01T00:00:00+00:00 | Cloud Optimized GeoTIFF of AGB estimates |
Additionally, we can create a list of hrefs for the COGs (cloud-optimized geotiffs) with the AGB (above-ground biomass) estimates. These are gathered from our focused search in the cell above.
[231]:
# get urls
s3_urls = sapply(stac_query$features, function(x) {x$assets$estimates$href})
s3_urls
- 's3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S50W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif'
- 's3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S50W070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif'
- 's3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S50W060_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif'
- 's3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S50W040_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif'
- 's3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S40W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif'
- 's3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S40W070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif'
- 's3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S30W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif'
- 's3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S30W070_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif'
- 's3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S30W060_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif'
- 's3://nasa-maap-data-store/file-staging/nasa-map/ESACCI_Biomass_L4_AGB_V4_100m_2020/S20W080_ESACCI-BIOMASS-L4-AGB-MERGED-100m-2020-fv4.0.tif'