forked from espm-157/nasa-topst-env-justice
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgdalcubes-stac-cog.Rmd
161 lines (116 loc) · 5.34 KB
/
gdalcubes-stac-cog.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
---
title: "Mosaic images using STAC"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Mosaic images using STAC}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
## *WORK IN PROGRESS*
High-resolution satellites generate many snapshot images each with a limited field of view or spatial extent. In order to see a larger area in space, and/or observe changes across space and time, we need to assemble these many snapshots into a mosaic or "data cube" that we can analyze as a cohesive whole.
[EARTHDATA STAC CATALOGS](https://radiantearth.github.io/stac-browser/#/external/cmr.earthdata.nasa.gov/stac/LPCLOUD?.language=en)
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path="img/",
message = FALSE,
warning = FALSE
)
```
```{r setup, message=FALSE}
library(earthdatalogin)
library(rstac)
library(gdalcubes)
gdalcubes_options(parallel = TRUE)
```
### Earth Data Authentication
First let's get EDL authentication out of the way.
For cloud data from almost any other STAC catalog (NOAA, USGS, Planetary Computer, etc), authentication is either unnecessary or already provided by the STAC API, but NASA EDL is special.
```{r}
library(earthdatalogin)
```
We could just use `edl_set_token()` here as usual to set the environmental variable.
This works fine but can problems if we do not remember to `edl_unset_token()` before accessing other non-EDL resources over the http interface.
When using the `gdalcubes` package, we have support for a somewhat nicer, more localized authentication that uses the configuration options instead.
We tell `edl_set_token` not to set the environmental variable globally, but to return
in the header format which we can pass to `gdalcubes_set_gdal_config()`:
```{r}
header <- edl_set_token(set_env_var = FALSE, format = "header")
gdalcubes_set_gdal_config("GDAL_HTTP_HEADERS", header)
```
`earthdatalogin` also includes optional configuration settings for GDAL which can improve performance of cloud-based data access. Set the GDAL environmental variables using `gdal_cloud_config()`
```{r}
gdal_cloud_config()
```
## Search via STAC
We will now use the `rstac` package to search one or more NASA collections for data that falls into our desired bounding
Set a search box in space & time
```{r}
bbox <- c(xmin=-122.5, ymin=37.5, xmax=-122.0, ymax=38)
start <- "2022-01-01"
end <- "2022-06-30"
# Find all assets from the desired catalog:
items <- stac("https://cmr.earthdata.nasa.gov/stac/LPCLOUD") |>
stac_search(collections = "HLSL30.v2.0",
bbox = bbox,
datetime = paste(start,end, sep = "/")) |>
post_request() |>
items_fetch() |>
items_filter(filter_fn = \(x) {x[["eo:cloud_cover"]] < 20})
```
Note that `r length(items$features)` features have matched our search criteria! Each feature represents a 'snapshot' image taken by the satellite as it passes by (this is a harmonized product so actually there's quite a lot of post-processing.) Each feature thus shares the same bounding box, projection, and timestamp, but may consist of many different 'assets', different COG files representing the different spectral bands on the satellite camera instrument. Each feature can potentially include quite extensive metadata about the feature, including details of instrument itself or from post-processing, such as cloud cover. Unfortunately, EarthData's STAC metadata tends to be quite sparse.
## Building a Data Cube
```{r}
# Desired data cube shape & resolution
v = cube_view(srs = "EPSG:4326",
extent = list(t0 = as.character(start),
t1 = as.character(end),
left = bbox[1], right = bbox[3],
top = bbox[4], bottom = bbox[2]),
nx = 512, ny = 512, dt = "P1M")
```
```{r}
# RGB bands + cloud cover mask
col <- stac_image_collection(items$features,
asset_names = c("B02", "B03", "B04", "Fmask"))
```
```{r sf_bay}
# use a cloud mask -- not sure I have this correct
# https://lpdaac.usgs.gov/documents/1326/HLS_User_Guide_V2.pdf
cloud_mask <- image_mask("Fmask", values=1) # mask clouds and cloud shadows
rgb_bands <- c("B04","B03", "B02")
# Here we go! note eval is lazy
raster_cube(col, v, mask=cloud_mask) |>
select_bands(rgb_bands) |>
plot(rgb=1:3)
```
## Scaling up
Same code with larger search box:
```{r}
bbox <- c(xmin=-123, ymin=37, xmax=-121, ymax=39)
start <- "2023-01-01"
end <- "2023-01-31"
items <- stac("https://cmr.earthdata.nasa.gov/stac/LPCLOUD") |>
stac_search(collections = "HLSL30.v2.0",
bbox = c(bbox),
datetime =paste(start,end, sep = "/")) |>
post_request() |>
items_fetch() |>
items_filter(filter_fn = \(x) {x[["eo:cloud_cover"]] < 20})
```
```{r}
view <- cube_view(srs = "EPSG:4326",
extent = list(t0 = as.character(start),
t1 = as.character(end),
left = bbox[1], right = bbox[3],
top = bbox[4], bottom = bbox[2]),
nx = 1024, ny = 1024, dt = "P1M")
assets <- stac_image_collection(items$features,
asset_names = c("B02", "B03", "B04", "Fmask"))
```
```{r scalingup}
raster_cube(assets, view) |>
select_bands(c("B04","B03", "B02")) |>
plot(rgb=1:3)
```