Skip to content

Commit bfdb974

Browse files
committed
readme
1 parent 8bd75e1 commit bfdb974

File tree

4 files changed

+133
-91
lines changed

4 files changed

+133
-91
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: blackmarbler
22
Title: Black Marble Data and Statistics
3-
Version: 0.1.2
3+
Version: 0.2.0
44
Authors@R:
55
c(person("Robert", "Marty", , "[email protected]", role = c("aut", "cre"),
66
comment = c(ORCID = "0000-0002-3164-3813")),
@@ -20,7 +20,7 @@ Imports:
2020
purrr,
2121
lubridate,
2222
tidyr,
23-
raster,
23+
terra,
2424
sf,
2525
exactextractr,
2626
stringr,

R/blackmarbler.R

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,6 @@ month_start_day_to_month <- function(x){
4343

4444
month_start_day_to_month <- Vectorize(month_start_day_to_month)
4545

46-
pad2 <- function(x){
47-
if(nchar(x) == 1) out <- paste0("0", x)
48-
if(nchar(x) == 2) out <- paste0(x)
49-
return(out)
50-
}
51-
pad2 <- Vectorize(pad2)
52-
5346
pad3 <- function(x){
5447
if(nchar(x) == 1) out <- paste0("00", x)
5548
if(nchar(x) == 2) out <- paste0("0", x)
@@ -313,12 +306,6 @@ file_to_raster <- function(f,
313306
crs = myCrs,
314307
extent = c(xMin,xMax,yMin,yMax))
315308

316-
#create extents class
317-
#rasExt <- raster::extent(c(xMin,xMax,yMin,yMax))
318-
319-
#assign the extents to the raster
320-
#extent(outr) <- rasExt
321-
322309
#set fill values to NA
323310
outr <- remove_fill_value(outr, variable)
324311

@@ -346,7 +333,7 @@ read_bm_csv <- function(year,
346333
df
347334
},
348335
error = function(e){
349-
warning(paste0("Error with year: ", year, "; day: ", day))
336+
#warning(paste0("Error with year: ", year, "; day: ", day))
350337
data.frame(NULL)
351338
}
352339
)
@@ -382,7 +369,7 @@ create_dataset_name_df <- function(product_id,
382369
}
383370

384371
if(product_id == "VNP46A3"){
385-
param_df <- cross_df(list(year = 2012:year_end,
372+
param_df <- cross_df(list(year = 2012:year_end,
386373
day = c("001", "032", "061", "092", "122", "153", "183", "214", "245", "275", "306", "336",
387374
"060", "091", "121", "152", "182", "213", "244", "274", "305", "335")))
388375
}
@@ -422,10 +409,16 @@ create_dataset_name_df <- function(product_id,
422409
}
423410

424411
#### Create data
425-
files_df <- purrr::map2_dfr(param_df$year,
426-
param_df$day,
427-
read_bm_csv,
428-
product_id)
412+
# files_df <- purrr::map2_dfr(param_df$year,
413+
# param_df$day,
414+
# read_bm_csv,
415+
# product_id)
416+
417+
files_df <- purrr::map2(param_df$year,
418+
param_df$day,
419+
read_bm_csv,
420+
product_id) %>%
421+
bind_rows()
429422

430423
return(files_df)
431424
}
@@ -533,7 +526,7 @@ count_n_obs <- function(values, coverage_fraction) {
533526
#' * `"VNP46A2"`: Daily (corrected)
534527
#' * `"VNP46A3"`: Monthly
535528
#' * `"VNP46A4"`: Annual
536-
#' @param date Date of raster data. Entering one date will produce a raster. Entering multiple dates will produce a raster stack.
529+
#' @param date Date of raster data. Entering one date will produce a `SpatRaster` object. Entering multiple dates will produce a `SpatRaster` object with multiple bands; one band per date.
537530
#' * For `product_id`s `"VNP46A1"` and `"VNP46A2"`, a date (eg, `"2021-10-03"`).
538531
#' * For `product_id` `"VNP46A3"`, a date or year-month (e.g., `"2021-10-01"`, where the day will be ignored, or `"2021-10"`).
539532
#' * For `product_id` `"VNP46A4"`, year or date (e.g., `"2021-10-01"`, where the month and day will be ignored, or `2021`).
@@ -559,15 +552,15 @@ count_n_obs <- function(values, coverage_fraction) {
559552
#' - `1`: Poor-quality, The number of observations used for the composite is less than or equal to 3
560553
#' - `2`: Gap filled NTL based on historical data
561554
#' @param check_all_tiles_exist Check whether all Black Marble nighttime light tiles exist for the region of interest. Sometimes not all tiles are available, so the full region of interest may not be covered. If `TRUE`, skips cases where not all tiles are available. (Default: `TRUE`).
562-
#' @param interpol_na When data for more than one date is downloaded, whether to interpolate `NA` values in rasters using the `raster::approxNA` function. Additional arguments for the `raster::approxNA` function can also be passed into `bm_extract` (eg, `method`, `rule`, `f`, `ties`, `z`, `NA_rule`). (Default: `FALSE`).
555+
#' @param interpol_na When data for more than one date is downloaded, whether to interpolate `NA` values in rasters using the `terra::approximate` function. Additional arguments for the `terra::approximate` function can also be passed into `bm_extract` (eg, `method`, `rule`, `f`, `ties`, `z`, `NA_rule`). (Default: `FALSE`).
563556
#' @param output_location_type Where to produce output; either `memory` or `file`. If `memory`, functions returns a dataframe in R. If `file`, function exports a `.csv` file and returns `NULL`.
564557
#' @param file_dir (If `output_location_type = file`). The directory where data should be exported (default: `NULL`, so the working directory will be used)
565558
#' @param file_prefix (If `output_location_type = file`). Prefix to add to the file to be saved. The file will be saved as the following: `[file_prefix][product_id]_t[date].csv`
566559
#' @param file_skip_if_exists (If `output_location_type = file`). Whether the function should first check wither the file already exists, and to skip downloading or extracting data if the data for that date if the file already exists (default: `TRUE`).
567560
#' @param h5_dir Black Marble data are originally downloaded as `h5` files. If `h5_dir = NULL`, the function downloads to a temporary directory then deletes the directory. If `h5_dir` is set to a path, `h5` files are saved to that directory and not deleted. The function will then check if the needed `h5` file already exists in the directory; if it exists, the function will not re-download the `h5` file.
568561
#' @param quiet Suppress output that show downloading progress and other messages. (Default: `FALSE`).
569562
#'
570-
#' @param ... Additional arguments for `raster::approxNA`, if `interpol_na = TRUE`
563+
#' @param ... Additional arguments for `terra::approximate`, if `interpol_na = TRUE`
571564
#'
572565
#' @return Raster
573566
#'
@@ -628,6 +621,11 @@ bm_extract <- function(roi_sf,
628621
warning("interpol_na ignored. Interpolation only occurs when output_location_type = 'memory'")
629622
}
630623

624+
if(class(roi_sf)[1] == "SpatVector") roi_sf <- roi_sf %>% st_as_sf()
625+
if(!("sf" %in% class(roi_sf))){
626+
stop("roi must be an sf object")
627+
}
628+
631629
# Assign interpolation variables ---------------------------------------------
632630
if(interpol_na == T){
633631
if(!exists("method")) method <- "linear"
@@ -676,13 +674,13 @@ bm_extract <- function(roi_sf,
676674
quiet = quiet,
677675
temp_dir = temp_dir)
678676

679-
bm_r <- raster::approxNA(bm_r,
680-
method = method,
681-
rule = rule,
682-
f = f,
683-
ties = ties,
684-
z = z,
685-
NArule = NArule)
677+
bm_r <- terra::approximate(bm_r,
678+
method = method,
679+
rule = rule,
680+
f = f,
681+
ties = ties,
682+
z = z,
683+
NArule = NArule)
686684

687685
#### Extract
688686
roi_df <- roi_sf %>% st_drop_geometry()
@@ -871,7 +869,7 @@ bm_extract <- function(roi_sf,
871869
#' * `"VNP46A2"`: Daily (corrected)
872870
#' * `"VNP46A3"`: Monthly
873871
#' * `"VNP46A4"`: Annual
874-
#' @param date Date of raster data. Entering one date will produce a raster. Entering multiple dates will produce a raster stack.
872+
#' @param date Date of raster data. Entering one date will produce a `SpatRaster` object. Entering multiple dates will produce a `SpatRaster` object with multiple bands; one band per date.
875873
#' * For `product_id`s `"VNP46A1"` and `"VNP46A2"`, a date (eg, `"2021-10-03"`).
876874
#' * For `product_id` `"VNP46A3"`, a date or year-month (e.g., `"2021-10-01"`, where the day will be ignored, or `"2021-10"`).
877875
#' * For `product_id` `"VNP46A4"`, year or date (e.g., `"2021-10-01"`, where the month and day will be ignored, or `2021`).
@@ -895,15 +893,15 @@ bm_extract <- function(roi_sf,
895893
#' - `1`: Poor-quality, The number of observations used for the composite is less than or equal to 3
896894
#' - `2`: Gap filled NTL based on historical data
897895
#' @param check_all_tiles_exist Check whether all Black Marble nighttime light tiles exist for the region of interest. Sometimes not all tiles are available, so the full region of interest may not be covered. If `TRUE`, skips cases where not all tiles are available. (Default: `TRUE`).
898-
#' @param interpol_na When data for more than one date is downloaded, whether to interpolate `NA` values using the `raster::approxNA` function. Additional arguments for the `raster::approxNA` function can also be passed into `bm_raster` (eg, `method`, `rule`, `f`, `ties`, `z`, `NA_rule`). (Default: `FALSE`).
896+
#' @param interpol_na When data for more than one date is downloaded, whether to interpolate `NA` values using the `terra::approximate` function. Additional arguments for the `terra::approximate` function can also be passed into `bm_raster` (eg, `method`, `rule`, `f`, `ties`, `z`, `NA_rule`). (Default: `FALSE`).
899897
#' @param output_location_type Where to produce output; either `memory` or `file`. If `memory`, functions returns a raster in R. If `file`, function exports a `.tif` file and returns `NULL`.
900898
#' For `output_location_type = file`:
901899
#' @param file_dir The directory where data should be exported (default: `NULL`, so the working directory will be used)
902900
#' @param file_prefix Prefix to add to the file to be saved. The file will be saved as the following: `[file_prefix][product_id]_t[date].tif`
903901
#' @param file_skip_if_exists Whether the function should first check wither the file already exists, and to skip downloading or extracting data if the data for that date if the file already exists (default: `TRUE`).
904902
#' @param h5_dir Black Marble data are originally downloaded as `h5` files. If `h5_dir = NULL`, the function downloads to a temporary directory then deletes the directory. If `h5_dir` is set to a path, `h5` files are saved to that directory and not deleted. The function will then check if the needed `h5` file already exists in the directory; if it exists, the function will not re-download the `h5` file.
905903
#' @param quiet Suppress output that show downloading progress and other messages. (Default: `FALSE`).
906-
#' @param ... Additional arguments for `raster::approxNA`, if `interpol_na = TRUE`
904+
#' @param ... Additional arguments for `terra::approximate`, if `interpol_na = TRUE`
907905
#'
908906
#' @return Raster
909907
#'
@@ -1053,7 +1051,7 @@ bm_raster <- function(roi_sf,
10531051
writeRaster(r, out_path)
10541052

10551053
} else{
1056-
warning(paste0('"', out_path, '" already exists; skipping.\n'))
1054+
message(paste0('"', out_path, '" already exists; skipping.\n'))
10571055
}
10581056

10591057
r_out <- NULL # Saving as tif file, so output from function should be NULL
@@ -1090,20 +1088,20 @@ bm_raster <- function(roi_sf,
10901088
if(length(r_list) == 1){
10911089
r <- r_list[[1]]
10921090
} else if (length(r_list) > 1){
1093-
r <- raster::stack(r_list)
1091+
r <- terra::rast(r_list)
10941092
} else{
10951093
r <- NULL
10961094
}
10971095

10981096
# Interpolate ----------------------------------------------------------------
10991097
if(interpol_na %in% T){
1100-
r <- raster::approxNA(r,
1101-
method = method,
1102-
rule = rule,
1103-
f = f,
1104-
ties = ties,
1105-
z = z,
1106-
NArule = NArule)
1098+
r <- terra::approximate(r,
1099+
method = method,
1100+
rule = rule,
1101+
f = f,
1102+
ties = ties,
1103+
z = z,
1104+
NArule = NArule)
11071105
}
11081106

11091107
unlink(temp_dir, recursive = T)

README.md

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* [Usage](#usage)
1919
* [Setup](#setup)
2020
* [Make raster](#raster)
21-
* [Make raster stack across multiple time periods](#stack)
21+
* [Make raster across multiple time periods](#stack)
2222
* [Make map](#map)
2323
* [Make figure of trends in nighttime lights](#trends)
2424
* [Workflow to update data](#update-data)
@@ -71,8 +71,9 @@ Before downloading and extracting Black Marble data, we first load packages, def
7171
library(blackmarbler)
7272
library(geodata)
7373
library(sf)
74-
library(raster)
74+
library(terra)
7575
library(ggplot2)
76+
library(tidyterra)
7677

7778
#### Define NASA bearer token
7879
bearer <- "BEARER-TOKEN-HERE"
@@ -81,7 +82,7 @@ bearer <- "BEARER-TOKEN-HERE"
8182
# Define region of interest (roi). The roi must be (1) an sf polygon and (2)
8283
# in the WGS84 (epsg:4326) coordinate reference system. Here, we use the
8384
# getData function to load a polygon of Ghana
84-
roi_sf <- gadm(country = "GHA", level=1, path = tempdir()) |> st_as_sf()
85+
roi_sf <- gadm(country = "GHA", level=1, path = tempdir())
8586
```
8687

8788
### Make raster of nighttime lights <a name="raster">
@@ -109,9 +110,9 @@ r_2021 <- bm_raster(roi_sf = roi_sf,
109110
bearer = bearer)
110111
```
111112

112-
### Make raster stack of nighttime lights across multiple time periods <a name="stack">
113+
### Make raster of nighttime lights across multiple time periods <a name="stack">
113114

114-
To extract data for multiple time periods, add multiple time periods to `date`. The function will return a raster stack, where each raster band corresponds to a different date. The below code provides examples getting data across multiple days, months, and years.
115+
To extract data for multiple time periods, add multiple time periods to `date`. The function will return a `SpatRaster` object with multiple bands, where each band corresponds to a different date. The below code provides examples getting data across multiple days, months, and years.
115116

116117
```r
117118
#### Daily data in March 2021
@@ -145,28 +146,20 @@ r <- bm_raster(roi_sf = roi_sf,
145146
bearer = bearer)
146147

147148
#### Prep data
148-
r <- r |> mask(roi_sf)
149-
150-
r_df <- rasterToPoints(r, spatial = TRUE) |> as.data.frame()
151-
names(r_df) <- c("value", "x", "y")
152-
153-
## Remove very low values of NTL; can be considered noise
154-
r_df$value[r_df$value <= 2] <- 0
149+
r <- r |> terraLLmask(roi_sf)
155150

156151
## Distribution is skewed, so log
157-
r_df$value_adj <- log(r_df$value+1)
152+
r[] <- log(r[] + 1)
158153

159154
##### Map
160155
p <- ggplot() +
161-
geom_raster(data = r_df,
162-
aes(x = x, y = y,
163-
fill = value_adj)) +
156+
geom_spatraster(data = r) +
164157
scale_fill_gradient2(low = "black",
165158
mid = "yellow",
166159
high = "red",
167160
midpoint = 4.5) +
168161
labs(title = "Nighttime Lights: October 2021") +
169-
coord_quickmap() +
162+
coord_sf() +
170163
theme_void() +
171164
theme(plot.title = element_text(face = "bold", hjust = 0.5),
172165
legend.position = "none")
@@ -260,7 +253,7 @@ Both functions take the following arguments:
260253
* `"VNP46A3"`: Monthly
261254
* `"VNP46A4"`: Annual
262255

263-
* **date:** Date of raster data. Entering one date will produce a raster. Entering multiple dates will produce a raster stack.
256+
* **date:** Date of raster data. Entering one date will produce a `SpatRaster` object. Entering multiple dates will produce a `SpatRaster` object with multiple bands; one band per date.
264257

265258
* For `product_id`s `"VNP46A1"` and `"VNP46A2"`, a date (eg, `"2021-10-03"`).
266259
* For `product_id` `"VNP46A3"`, a date or year-month (e.g., `"2021-10-01"`, where the day will be ignored, or `"2021-10"`).
@@ -289,7 +282,7 @@ Both functions take the following arguments:
289282
* `2`: Gap filled NTL based on historical data
290283

291284
* **check_all_tiles_exist:** Check whether all Black Marble nighttime light tiles exist for the region of interest. Sometimes not all tiles are available, so the full region of interest may not be covered. If `TRUE`, skips cases where not all tiles are available. (Default: `TRUE`).
292-
* **interpol_na:** When data for more than one date is downloaded, whether to interpolate `NA` values in rasters using the [`raster::approxNA`](https://www.rdocumentation.org/packages/raster/versions/3.6-26/topics/approxNA) function. Additional arguments for the [`raster::approxNA`](https://www.rdocumentation.org/packages/raster/versions/3.6-26/topics/approxNA) function can also be passed into `bm_raster`/`bm_extract` (eg, `method`, `rule`, `f`, `ties`, `z`, `NA_rule`). (Default: `FALSE`).
285+
* **interpol_na:** When data for more than one date is downloaded, whether to interpolate `NA` values in rasters using the [`terra::approximate`](https://www.rdocumentation.org/packages/raster/versions/3.6-26/topics/approxNA) function. Additional arguments for the [`terra::approximate`](https://www.rdocumentation.org/packages/raster/versions/3.6-26/topics/approxNA) function can also be passed into `bm_raster`/`bm_extract` (eg, `method`, `rule`, `f`, `ties`, `z`, `NA_rule`). (Default: `FALSE`).
293286
* **h5_dir:** Black Marble data are originally downloaded as `h5` files. If `h5_dir = NULL`, the function downloads to a temporary directory then deletes the directory. If `h5_dir` is set to a path, `h5` files are saved to that directory and not deleted. The function will then check if the needed `h5` file already exists in the directory; if it exists, the function will not re-download the `h5` file.
294287

295288

@@ -304,7 +297,7 @@ If `output_location_type = "file"`, the following arguments can be used:
304297
* **file_prefix:** Prefix to add to the file to be saved. The file will be saved as the following: `[file_prefix][product_id]_t[date].[tif/Rds]`
305298
* **file_skip_if_exists:** Whether the function should first check wither the file already exists, and to skip downloading or extracting data if the data for that date if the file already exists (default: `TRUE`). If the function is first run with `date = c(2018, 2019, 2020)`, then is later run with `date = c(2018, 2019, 2020, 2021)`, the function will only download/extract data for 2021. Skipping existing files can facilitate re-running the function at a later date to download only more recent data.
306299

307-
* **...:** Additional arguments for [`raster::approxNA`](https://www.rdocumentation.org/packages/raster/versions/3.6-26/topics/approxNA), if `interpol_na = TRUE`
300+
* **...:** Additional arguments for [`terra::approximate`](https://rspatial.github.io/terra/reference/approximate.html), if `interpol_na = TRUE`
308301

309302
### Argument for `bm_extract` only <a name="args-extract">
310303

0 commit comments

Comments
 (0)