From 7c2da9a34c43e0cc3c888a17738912e8ee311da8 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 20 Oct 2021 12:30:49 -0400 Subject: [PATCH 01/37] Compartmentalize make_manifest --- .gitignore | 2 + DESCRIPTION | 3 +- NAMESPACE | 2 + R/make_manifest.R | 163 +++++++++++++++-------- man/{make_manifest.Rd => unity_crops.Rd} | 14 +- 5 files changed, 124 insertions(+), 60 deletions(-) rename man/{make_manifest.Rd => unity_crops.Rd} (77%) diff --git a/.gitignore b/.gitignore index 94d4d10..f020102 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,5 @@ Meta paper.pdf /doc/ /Meta/ +elevation.tif +ortho.tif diff --git a/DESCRIPTION b/DESCRIPTION index f396355..f9a6f35 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -47,7 +47,8 @@ Suggests: progress, jpeg, tiff, - brio + brio, + unifir Config/testthat/parallel: true Config/testthat/edition: 3 VignetteBuilder: knitr diff --git a/NAMESPACE b/NAMESPACE index 8584de7..9736792 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -20,5 +20,7 @@ export(merge_rasters) export(raster_to_raw_tiles) export(set_bbox_side_length) export(stat_spatial_rgb) +export(transform_elevation) +export(transform_overlay) export(vector_to_overlay) importFrom(grDevices,rgb) diff --git a/R/make_manifest.R b/R/make_manifest.R index 072824b..35ac002 100644 --- a/R/make_manifest.R +++ b/R/make_manifest.R @@ -1,9 +1,10 @@ #' Transform rasters and write manifest file for import into Unity #' -#' This function crops input raster files into smaller square tiles and then +#' These functions crop input raster files into smaller square tiles and then #' converts them into either .png or .raw files which are ready to be imported -#' into the Unity game engine. It also writes a "manifest" file and importer -#' script which may be used to automatically import the tiles into Unity. +#' into the Unity game engine. [make_manifest] also writes a "manifest" file and +#' importer script which may be used to automatically import the tiles into +#' Unity. #' #' @param heightmap File path to the heightmap to transform. #' @param overlay Optionally, file path to the image overlay to transform. @@ -30,28 +31,67 @@ #' } #' } #' +#' +#' @rdname unity_crops #' @export make_manifest <- function(heightmap, overlay = NULL, output_prefix = "import", manifest_path = "terrainr.manifest", importer_path = "import_terrain.cs") { - input_raster <- raster::raster(heightmap) - max_raster <- raster::cellStats(input_raster, "max") - x_tiles <- ceiling(input_raster@ncols / 4097) - y_tiles <- ceiling(input_raster@nrows / 4097) - n_tiles <- x_tiles * y_tiles + manifest <- prep_table(heightmap, + side_length = 4097, + output_prefix = output_prefix, + type = "elevation") + transform_elevation(heightmap = heightmap, + side_length = 4097, + output_prefix = output_prefix) + if (!is.null(overlay)) { + overlay_manifest <- prep_table(heightmap, + side_length = 4097, + output_prefix = output_prefix, + type = "overlay") + manifest$texture <- overlay_manifest$texture + transform_overlay(overlay = overlay, + side_length = 4097, + output_prefix = output_prefix) + } - temptiffs <- NULL - while (length(temptiffs) != n_tiles) { - temptiffs <- unique(vapply( - 1:(n_tiles), - function(x) tempfile(fileext = ".tiff"), - character(1) - )) + utils::write.table(manifest, + manifest_path, + row.names = FALSE, + col.names = FALSE, + sep = "\t", + quote = FALSE + ) + + if (!is.null(importer_path) && !file.exists(importer_path)) { + file.copy( + system.file("import_terrain.cs", package = "terrainr"), + importer_path, + overwrite = TRUE + ) } + return(invisible(manifest_path)) +} + +prep_table <- function(input_raster, + side_length, + output_prefix, + type) { + if (!all.equal(log((side_length - 1), 2), round(log((side_length - 1), 2)))) { + warning("Side lengths must be equal to 2^x + 1 (for x <= 12) for import into Unity.\n", # nolint + "Tiles will still be produced but may not be usable.") + } + input_raster <- raster::raster(input_raster) + max_raster <- raster::cellStats(input_raster, "max") + + x_tiles <- ceiling(input_raster@ncols / side_length) + y_tiles <- ceiling(input_raster@nrows / side_length) + n_tiles <- x_tiles * y_tiles + file_combos <- expand.grid( x = 1:x_tiles, y = 1:y_tiles @@ -71,23 +111,42 @@ make_manifest <- function(heightmap, ) x_tiles <- 0:(x_tiles - 1) - x_tiles <- (x_tiles * 4097) + x_tiles <- (x_tiles * side_length) y_tiles <- 0:(y_tiles - 1) - y_tiles <- (y_tiles * 4097) + y_tiles <- (y_tiles * side_length) - manifest <- data.frame( + output <- data.frame( filename = paste0(sort(file_names), ".raw"), x_pos = -rep(x_tiles, each = length(file_names) / length(x_tiles)), z_pos = rep(y_tiles, length.out = length(file_names)), - x_length = 4097, + x_length = side_length, height = max_raster, - z_length = 4097, - resolution = 4097, - texture = if (is.null(overlay)) "" else paste0(sort(file_names), ".png") + z_length = side_length, + resolution = side_length ) + if (type == "overlay") output$texture <- paste0(sort(file_names), ".png") + output +} +#' @rdname unity_crops +#' @export +transform_elevation <- function(heightmap, + side_length = 4097, + output_prefix = "import") { + + manifest <- prep_table(heightmap, side_length, output_prefix, type = "elevation") + + temptiffs <- NULL + while (length(temptiffs) != nrow(manifest)) { + temptiffs <- unique(vapply( + seq_len(nrow(manifest)), + function(x) tempfile(fileext = ".tiff"), + character(1) + )) + } temptiffs <- crop_tif(heightmap, manifest, temptiffs) + temppngs <- NULL while (length(temppngs) != length(temptiffs)) { temppngs <- unique(vapply( @@ -97,16 +156,16 @@ make_manifest <- function(heightmap, )) } names(temppngs) <- names(temptiffs) - convert_to_png(temptiffs, temppngs, max_raster) + convert_to_png(temptiffs, temppngs, manifest$height[[1]]) mapply( function(x, y) { processing_image <- magick::image_read(x) processing_image <- magick::image_flop(processing_image) processing_image <- magick::image_convert(processing_image, - format = "RGB", - depth = 16, - interlace = "Plane" + format = "RGB", + depth = 16, + interlace = "Plane" ) magick::image_write(processing_image, y) }, @@ -116,23 +175,33 @@ make_manifest <- function(heightmap, unlink(temppngs) - if (!is.null(overlay)) { - input_overlay <- raster::raster(overlay) - max_overlay <- raster::cellStats(input_overlay, "max") - - temptiffs <- NULL - while (length(temptiffs) != n_tiles) { - temptiffs <- unique(vapply( - 1:(n_tiles), - function(x) tempfile(fileext = ".tiff"), - character(1) + return(invisible(names(temppngs))) + +} + +#' @rdname unity_crops +#' @export +transform_overlay <- function(overlay, + side_length = 4097, + output_prefix = "import") { + + manifest <- prep_table(overlay, side_length, output_prefix, type = "overlay") + + temptiffs <- NULL + while (length(temptiffs) != nrow(manifest)) { + temptiffs <- unique(vapply( + seq_len(nrow(manifest)), + function(x) tempfile(fileext = ".tiff"), + character(1) )) } temptiffs <- crop_tif(overlay, manifest, temptiffs, "texture") + temppngs <- NULL temppngs <- names(temptiffs) names(temppngs) <- names(temptiffs) - convert_to_png(temptiffs, temppngs, max_overlay) + convert_to_png(temptiffs, temppngs, manifest$height[[1]]) + mapply( function(x, y) { processing_image <- magick::image_read(x) @@ -143,25 +212,8 @@ make_manifest <- function(heightmap, temppngs, names(temppngs) ) - } - utils::write.table(manifest, - manifest_path, - row.names = FALSE, - col.names = FALSE, - sep = "\t", - quote = FALSE - ) - - if (!is.null(importer_path) && !file.exists(importer_path)) { - file.copy( - system.file("import_terrain.cs", package = "terrainr"), - importer_path, - overwrite = TRUE - ) - } - - return(invisible(manifest_path)) + return(invisible(names(temppngs))) } crop_tif <- function(img, manifest, temptiffs, field = "filename") { @@ -204,6 +256,5 @@ convert_to_png <- function(temptiffs, temptiffs, temppngs ) - unlink(temptiffs) } diff --git a/man/make_manifest.Rd b/man/unity_crops.Rd similarity index 77% rename from man/make_manifest.Rd rename to man/unity_crops.Rd index ff140e6..4e287df 100644 --- a/man/make_manifest.Rd +++ b/man/unity_crops.Rd @@ -2,6 +2,8 @@ % Please edit documentation in R/make_manifest.R \name{make_manifest} \alias{make_manifest} +\alias{transform_elevation} +\alias{transform_overlay} \title{Transform rasters and write manifest file for import into Unity} \usage{ make_manifest( @@ -11,6 +13,10 @@ make_manifest( manifest_path = "terrainr.manifest", importer_path = "import_terrain.cs" ) + +transform_elevation(heightmap, side_length = 4097, output_prefix = "import") + +transform_overlay(overlay, side_length = 4097, output_prefix = "import") } \arguments{ \item{heightmap}{File path to the heightmap to transform.} @@ -28,10 +34,11 @@ to not copy the importer script. Will overwrite any file at the same path.} `manifest_path`, invisibly. } \description{ -This function crops input raster files into smaller square tiles and then +These functions crop input raster files into smaller square tiles and then converts them into either .png or .raw files which are ready to be imported -into the Unity game engine. It also writes a "manifest" file and importer -script which may be used to automatically import the tiles into Unity. +into the Unity game engine. [make_manifest] also writes a "manifest" file and +importer script which may be used to automatically import the tiles into +Unity. } \examples{ \dontrun{ @@ -49,4 +56,5 @@ if (!isTRUE(as.logical(Sys.getenv("CI")))) { } } + } From 4bf6a634e4f531ba236db8895d0d5d6a3f46205e Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 20 Oct 2021 12:46:56 -0400 Subject: [PATCH 02/37] Restyle and document --- DESCRIPTION | 2 +- NEWS.md | 6 +- R/make_manifest.R | 190 ++++++++++++++++++++++++--------------------- man/unity_crops.Rd | 10 ++- 4 files changed, 114 insertions(+), 94 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f9a6f35..f293219 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: terrainr Type: Package Title: Landscape Visualizations in R and 'Unity' -Version: 0.5.0.9002 +Version: 0.6.0 Authors@R: c( person(given = "Michael", family = "Mahoney", diff --git a/NEWS.md b/NEWS.md index 63a112a..543f118 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,11 @@ -# terrainr 0.5.1 +# terrainr 0.6.0 * New features: * A new endpoint, `ecosystems`, has been added to `get_tiles` and `hit_national_map_api`. + * Two new functions, `transform_elevation` and `transform_overlay`, should + now provide raster transformation functions that were possible with + `raster_to_raw_tiles` but not with `make_manifest`. As an added bonus, the + internal code to handle tiling is now dramatically simpler. * Improvements and bug fixes: * `merge_rasters` gains an argument, `overwrite`, which allows you to specify whether or not to overwrite `output_raster` if it exists. Previous diff --git a/R/make_manifest.R b/R/make_manifest.R index 35ac002..917baf8 100644 --- a/R/make_manifest.R +++ b/R/make_manifest.R @@ -7,11 +7,17 @@ #' Unity. #' #' @param heightmap File path to the heightmap to transform. -#' @param overlay Optionally, file path to the image overlay to transform. +#' @param overlay File path to the image overlay to transform. Optional for +#' [make_manifest]. #' @param output_prefix The file path to prefix output tiles with. #' @param manifest_path File path to write the manifest file to. #' @param importer_path File name to write the importer script to. Set to NULL #' to not copy the importer script. Will overwrite any file at the same path. +#' @param side_length Side length, in pixels, of each output tile. If the raster +#' has dimensions not evenly divisible by `side_length`, tiles will be generated +#' with overhanging pieces set to 0 units of elevation or RGB 0 (pure black). +#' Side lengths not equal to 2^x + 1 (for x <= 12) will cause a warning, as +#' tiles must be this size for import into Unity. #' #' @return `manifest_path`, invisibly. #' @@ -31,7 +37,6 @@ #' } #' } #' -#' #' @rdname unity_crops #' @export make_manifest <- function(heightmap, @@ -39,23 +44,28 @@ make_manifest <- function(heightmap, output_prefix = "import", manifest_path = "terrainr.manifest", importer_path = "import_terrain.cs") { - manifest <- prep_table(heightmap, - side_length = 4097, - output_prefix = output_prefix, - type = "elevation") - transform_elevation(heightmap = heightmap, - side_length = 4097, - output_prefix = output_prefix) + side_length = 4097, + output_prefix = output_prefix, + type = "elevation" + ) + transform_elevation( + heightmap = heightmap, + side_length = 4097, + output_prefix = output_prefix + ) if (!is.null(overlay)) { overlay_manifest <- prep_table(heightmap, - side_length = 4097, - output_prefix = output_prefix, - type = "overlay") + side_length = 4097, + output_prefix = output_prefix, + type = "overlay" + ) manifest$texture <- overlay_manifest$texture - transform_overlay(overlay = overlay, - side_length = 4097, - output_prefix = output_prefix) + transform_overlay( + overlay = overlay, + side_length = 4097, + output_prefix = output_prefix + ) } utils::write.table(manifest, @@ -77,64 +87,11 @@ make_manifest <- function(heightmap, return(invisible(manifest_path)) } -prep_table <- function(input_raster, - side_length, - output_prefix, - type) { - if (!all.equal(log((side_length - 1), 2), round(log((side_length - 1), 2)))) { - warning("Side lengths must be equal to 2^x + 1 (for x <= 12) for import into Unity.\n", # nolint - "Tiles will still be produced but may not be usable.") - } - input_raster <- raster::raster(input_raster) - max_raster <- raster::cellStats(input_raster, "max") - - x_tiles <- ceiling(input_raster@ncols / side_length) - y_tiles <- ceiling(input_raster@nrows / side_length) - n_tiles <- x_tiles * y_tiles - - file_combos <- expand.grid( - x = 1:x_tiles, - y = 1:y_tiles - ) - file_names <- mapply( - function(x, y) { - paste0( - output_prefix, - "_", - x, - "_", - y - ) - }, - file_combos$x, - file_combos$y - ) - - x_tiles <- 0:(x_tiles - 1) - x_tiles <- (x_tiles * side_length) - - y_tiles <- 0:(y_tiles - 1) - y_tiles <- (y_tiles * side_length) - - output <- data.frame( - filename = paste0(sort(file_names), ".raw"), - x_pos = -rep(x_tiles, each = length(file_names) / length(x_tiles)), - z_pos = rep(y_tiles, length.out = length(file_names)), - x_length = side_length, - height = max_raster, - z_length = side_length, - resolution = side_length - ) - if (type == "overlay") output$texture <- paste0(sort(file_names), ".png") - output -} - #' @rdname unity_crops #' @export transform_elevation <- function(heightmap, side_length = 4097, output_prefix = "import") { - manifest <- prep_table(heightmap, side_length, output_prefix, type = "elevation") temptiffs <- NULL @@ -163,9 +120,9 @@ transform_elevation <- function(heightmap, processing_image <- magick::image_read(x) processing_image <- magick::image_flop(processing_image) processing_image <- magick::image_convert(processing_image, - format = "RGB", - depth = 16, - interlace = "Plane" + format = "RGB", + depth = 16, + interlace = "Plane" ) magick::image_write(processing_image, y) }, @@ -176,7 +133,6 @@ transform_elevation <- function(heightmap, unlink(temppngs) return(invisible(names(temppngs))) - } #' @rdname unity_crops @@ -184,7 +140,6 @@ transform_elevation <- function(heightmap, transform_overlay <- function(overlay, side_length = 4097, output_prefix = "import") { - manifest <- prep_table(overlay, side_length, output_prefix, type = "overlay") temptiffs <- NULL @@ -193,29 +148,84 @@ transform_overlay <- function(overlay, seq_len(nrow(manifest)), function(x) tempfile(fileext = ".tiff"), character(1) - )) - } - temptiffs <- crop_tif(overlay, manifest, temptiffs, "texture") + )) + } + temptiffs <- crop_tif(overlay, manifest, temptiffs, "texture") + + temppngs <- NULL + temppngs <- names(temptiffs) + names(temppngs) <- names(temptiffs) + convert_to_png(temptiffs, temppngs, manifest$height[[1]]) + + mapply( + function(x, y) { + processing_image <- magick::image_read(x) + processing_image <- magick::image_flip(processing_image) + processing_image <- magick::image_flop(processing_image) + magick::image_write(processing_image, y) + }, + temppngs, + names(temppngs) + ) - temppngs <- NULL - temppngs <- names(temptiffs) - names(temppngs) <- names(temptiffs) - convert_to_png(temptiffs, temppngs, manifest$height[[1]]) + return(invisible(names(temppngs))) +} - mapply( - function(x, y) { - processing_image <- magick::image_read(x) - processing_image <- magick::image_flip(processing_image) - processing_image <- magick::image_flop(processing_image) - magick::image_write(processing_image, y) - }, - temppngs, - names(temppngs) +prep_table <- function(input_raster, + side_length, + output_prefix, + type) { + if (!all.equal(log((side_length - 1), 2), round(log((side_length - 1), 2)))) { + warning( + "Side lengths must be equal to 2^x + 1 (for x <= 12) for import into Unity.\n", # nolint + "Tiles will still be produced but may not be usable." ) + } + input_raster <- raster::raster(input_raster) + max_raster <- raster::cellStats(input_raster, "max") - return(invisible(names(temppngs))) + x_tiles <- ceiling(input_raster@ncols / side_length) + y_tiles <- ceiling(input_raster@nrows / side_length) + n_tiles <- x_tiles * y_tiles + + file_combos <- expand.grid( + x = 1:x_tiles, + y = 1:y_tiles + ) + file_names <- mapply( + function(x, y) { + paste0( + output_prefix, + "_", + x, + "_", + y + ) + }, + file_combos$x, + file_combos$y + ) + + x_tiles <- 0:(x_tiles - 1) + x_tiles <- (x_tiles * side_length) + + y_tiles <- 0:(y_tiles - 1) + y_tiles <- (y_tiles * side_length) + + output <- data.frame( + filename = paste0(sort(file_names), ".raw"), + x_pos = -rep(x_tiles, each = length(file_names) / length(x_tiles)), + z_pos = rep(y_tiles, length.out = length(file_names)), + x_length = side_length, + height = max_raster, + z_length = side_length, + resolution = side_length + ) + if (type == "overlay") output$texture <- paste0(sort(file_names), ".png") + output } + crop_tif <- function(img, manifest, temptiffs, field = "filename") { for (i in seq_len(nrow(manifest))) { # changing this to gdalUtilities causes my computer to crash diff --git a/man/unity_crops.Rd b/man/unity_crops.Rd index 4e287df..334dac6 100644 --- a/man/unity_crops.Rd +++ b/man/unity_crops.Rd @@ -21,7 +21,8 @@ transform_overlay(overlay, side_length = 4097, output_prefix = "import") \arguments{ \item{heightmap}{File path to the heightmap to transform.} -\item{overlay}{Optionally, file path to the image overlay to transform.} +\item{overlay}{File path to the image overlay to transform. Optional for +[make_manifest].} \item{output_prefix}{The file path to prefix output tiles with.} @@ -29,6 +30,12 @@ transform_overlay(overlay, side_length = 4097, output_prefix = "import") \item{importer_path}{File name to write the importer script to. Set to NULL to not copy the importer script. Will overwrite any file at the same path.} + +\item{side_length}{Side length, in pixels, of each output tile. If the raster +has dimensions not evenly divisible by `side_length`, tiles will be generated +with overhanging pieces set to 0 units of elevation or RGB 0 (pure black). +Side lengths not equal to 2^x + 1 (for x <= 12) will cause a warning, as +tiles must be this size for import into Unity.} } \value{ `manifest_path`, invisibly. @@ -56,5 +63,4 @@ if (!isTRUE(as.logical(Sys.getenv("CI")))) { } } - } From 799d0ce9a498ba536f47ca9529b375f530430886 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 20 Oct 2021 13:28:14 -0400 Subject: [PATCH 03/37] First draft of make_unity --- NEWS.md | 3 +++ R/make_manifest.R | 2 +- R/make_unity.R | 65 +++++++++++++++++++++++++++++++++++++++++++++++ codemeta.json | 16 +++++++++--- 4 files changed, 81 insertions(+), 5 deletions(-) create mode 100644 R/make_unity.R diff --git a/NEWS.md b/NEWS.md index 543f118..0fa6dab 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,6 +12,9 @@ versions expected you to pass "-overwrite" to `options`. If a file exists at `output_raster` and `overwrite` is FALSE, `merge_rasters` will throw an error. + * `make_manifest` will now overwrite any file at `importer_path`, in line + with documented behavior. Previous versions would never overwrite + `importer_path`. # terrainr 0.5.0. * New features: diff --git a/R/make_manifest.R b/R/make_manifest.R index 917baf8..4b69cfe 100644 --- a/R/make_manifest.R +++ b/R/make_manifest.R @@ -76,7 +76,7 @@ make_manifest <- function(heightmap, quote = FALSE ) - if (!is.null(importer_path) && !file.exists(importer_path)) { + if (!is.null(importer_path)) { file.copy( system.file("import_terrain.cs", package = "terrainr"), importer_path, diff --git a/R/make_unity.R b/R/make_unity.R new file mode 100644 index 0000000..d9b4612 --- /dev/null +++ b/R/make_unity.R @@ -0,0 +1,65 @@ +make_unity <- function(project, + heightmap, + overlay = NULL, + scene_name = "terrainr_scene") { + + elevation_prefix <- tempfile() + manifest <- prep_table(heightmap, + side_length = 4097, + output_prefix = elevation_prefix, + type = "elevation" + ) + transform_elevation( + heightmap = heightmap, + side_length = 4097, + output_prefix = elevation_prefix + ) + dir.create(project) + lapply( + manifest$filename, + function(x) file.rename(x, file.path(project, basename(x))) + ) + manifest$filename <- basename(manifest$filename) + + if (!is.null(overlay)) { + overlay_prefix <- tempfile() + overlay_manifest <- prep_table(heightmap, + side_length = 4097, + output_prefix = overlay_prefix, + type = "overlay" + ) + manifest$texture <- overlay_manifest$texture + transform_overlay( + overlay = overlay, + side_length = 4097, + output_prefix = overlay_prefix + ) + lapply( + manifest$texture, + function(x) file.rename(x, file.path(project, basename(x))) + ) + } + manifest$texture <- basename(manifest$texture) + + script <- unifir::make_script(project, scene_name = scene_name) + script <- unifir::new_scene(script, "DefaultGameObjects", "Single") + + for (i in seq_len(nrow(manifest))) { + script <- unifir::create_terrain( + script, + heightmap_path = manifest$filename[i], + x_pos = manifest$x_pos[i], + z_pos = manifest$z_pos[i], + width = manifest$x_length[i], + height = manifest$height[i], + length = manifest$z_length[i], + heightmap_resolution = manifest$resolution[i], + texture_path = ifelse(is.null(overlay), "", manifest$texture[i]) + ) + } + + script <- unifir::save_scene(script) + script <- unifir::action(script) + script <- unifir::set_active_scene(script, scene_name) + +} diff --git a/codemeta.json b/codemeta.json index c3d3480..3d49faa 100644 --- a/codemeta.json +++ b/codemeta.json @@ -10,13 +10,13 @@ "codeRepository": "https://github.com/ropensci/terrainr", "issueTracker": "https://github.com/ropensci/terrainr/issues", "license": "https://spdx.org/licenses/MIT", - "version": "0.5.0", + "version": "0.6.0", "programmingLanguage": { "@type": "ComputerLanguage", "name": "R", "url": "https://r-project.org" }, - "runtimePlatform": "R version 4.1.0 (2021-05-18)", + "runtimePlatform": "R version 4.1.1 (2021-08-10)", "author": [ { "@type": "Person", @@ -146,6 +146,11 @@ "url": "https://cran.r-project.org" }, "sameAs": "https://CRAN.R-project.org/package=brio" + }, + { + "@type": "SoftwareApplication", + "identifier": "unifir", + "name": "unifir" } ], "softwareRequirements": [ @@ -271,7 +276,7 @@ ], "releaseNotes": "https://github.com/ropensci/terrainr/blob/master/NEWS.md", "readme": "https://github.com/ropensci/terrainr/blob/main/README.md", - "fileSize": "3245.685KB", + "fileSize": "4047.343KB", "contIntegration": "https://codecov.io/gh/ropensci/terrainr", "developmentStatus": ["https://lifecycle.r-lib.org/articles/stages.html#maturing", "https://www.repostatus.org/#active"], "keywords": [ @@ -323,7 +328,10 @@ } ], "name": "{terrainr}: Landscape Visualizations in R and Unity", - "url": "https://CRAN.R-project.org/package=terrainr" + "identifier": "https://doi.org/10.5281/zenodo.5142763", + "url": "https://CRAN.R-project.org/package=terrainr", + "@id": "https://doi.org/10.5281/zenodo.5142763", + "sameAs": "https://doi.org/10.5281/zenodo.5142763" } ] } From c85d6ab4e65240b42436799cb46b25346fe584e9 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 20 Oct 2021 17:14:03 -0400 Subject: [PATCH 04/37] Acknowledge unifir --- .github/workflows/check.yaml | 1 + .github/workflows/test-coverage.yaml | 1 + README.Rmd | 21 ++++++++++++ README.md | 49 ++++++++++++++++++++-------- 4 files changed, 58 insertions(+), 14 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index c439e47..6e3b47c 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -70,6 +70,7 @@ jobs: - name: Install dependencies run: | + remotes::install_github("mikemahoney218/unifir") remotes::install_deps(dependencies = TRUE) remotes::install_cran("rcmdcheck") shell: Rscript {0} diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index da97669..5ece3ba 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -46,6 +46,7 @@ jobs: - name: Install dependencies run: | install.packages(c("remotes")) + remotes::install_github("mikemahoney218/unifir") remotes::install_deps(dependencies = TRUE) remotes::install_cran("covr") shell: Rscript {0} diff --git a/README.Rmd b/README.Rmd index adb744a..899757e 100644 --- a/README.Rmd +++ b/README.Rmd @@ -22,6 +22,27 @@ knitr::opts_chunk$set( +## This is an experimental build of terrainr + +This feature branch requires the `unifir` package, currently not on CRAN. +If you want to try out the new features in this version -- particularly the new +`make_unity` function -- install `unifir` using the command: + +```{r, eval = FALSE} +# install.packages("remotes") +remotes::install_github("mikemahoney218/unifir") +``` + +Then install this version of `terrainr` using: + +```{r, eval=FALSE} +remotes::install_github("ropensci/terrainr", "unified") +``` + + +Please note that `unifir` is currently very young and subject to change, and the +features in this branch are likely to change with it. + ## Overview terrainr makes it easy to retrieve elevation and base map image tiles for areas diff --git a/README.md b/README.md index 75a3ee7..35e36dc 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,27 @@ Status](https://badges.ropensci.org/416_status.svg)](https://github.com/ropensci +## This is an experimental build of terrainr + +This feature branch requires the `unifir` package, currently not on +CRAN. If you want to try out the new features in this version – +particularly the new `make_unity` function – install `unifir` using the +command: + +``` r +# install.packages("remotes") +remotes::install_github("mikemahoney218/unifir") +``` + +Then install this version of `terrainr` using: + +``` r +remotes::install_github("ropensci/terrainr", "unified") +``` + +Please note that `unifir` is currently very young and subject to change, +and the features in this branch are likely to change with it. + ## Overview terrainr makes it easy to retrieve elevation and base map image tiles @@ -114,7 +135,7 @@ make_manifest(output_tiles$elevation, ``` We can then import these tiles to Unity (following the [Import -Vignette](\(https://docs.ropensci.org/terrainr/articles/unity_instructions.html\))) +Vignette]((https://docs.ropensci.org/terrainr/articles/unity_instructions.html))) to create: @@ -125,46 +146,46 @@ you’ll be more confident that your computer is still churning along and not just stalled out. For more information, check out [the introductory vignette](https://docs.ropensci.org/terrainr//articles/overview.html) and [the guide to importing your data into -Unity\!](https://docs.ropensci.org/terrainr//articles/unity_instructions.html) +Unity!](https://docs.ropensci.org/terrainr//articles/unity_instructions.html) ## Available Datasets The following datasets can currently be downloaded using `get_tiles` or `hit_national_map_api`: - - [3DEPElevation](https://elevation.nationalmap.gov/arcgis/rest/services/3DEPElevation/ImageServer): +- [3DEPElevation](https://elevation.nationalmap.gov/arcgis/rest/services/3DEPElevation/ImageServer): The USGS 3D Elevation Program (3DEP) Bare Earth DEM. - - [USGSNAIPPlus](https://services.nationalmap.gov/arcgis/rest/services/USGSNAIPPlus/MapServer): +- [USGSNAIPPlus](https://services.nationalmap.gov/arcgis/rest/services/USGSNAIPPlus/MapServer): National Agriculture Imagery Program (NAIP) and high resolution orthoimagery (HRO). - - [nhd](https://hydro.nationalmap.gov/arcgis/rest/services/nhd/MapServer): +- [nhd](https://hydro.nationalmap.gov/arcgis/rest/services/nhd/MapServer): A comprehensive set of digital spatial data that encodes information about naturally occurring and constructed bodies of surface water (lakes, ponds, and reservoirs), paths through which water flows (canals, ditches, streams, and rivers), and related entities such as point features (springs, wells, stream gauges, and dams). - - [govunits](https://carto.nationalmap.gov/arcgis/rest/services/govunits/MapServer): +- [govunits](https://carto.nationalmap.gov/arcgis/rest/services/govunits/MapServer): Major civil areas for the Nation, including States or Territories, counties (or equivalents), Federal and Native American areas, congressional districts, minor civil divisions, incorporated places (such as cities and towns), and unincorporated places. - - [contours](https://carto.nationalmap.gov/arcgis/rest/services/contours/MapServer): +- [contours](https://carto.nationalmap.gov/arcgis/rest/services/contours/MapServer): The USGS Elevation Contours service. - - [geonames](https://carto.nationalmap.gov/arcgis/rest/services/geonames/MapServer): +- [geonames](https://carto.nationalmap.gov/arcgis/rest/services/geonames/MapServer): Information about physical and cultural geographic features, geographic areas, and locational entities that are generally recognizable and locatable by name. - - [NHDPlus\_HR](https://hydro.nationalmap.gov/arcgis/rest/services/NHDPlus_HR/MapServer): +- [NHDPlus_HR](https://hydro.nationalmap.gov/arcgis/rest/services/NHDPlus_HR/MapServer): A comprehensive set of digital spatial data comprising a nationally seamless network of stream reaches, elevation-based catchment areas, flow surfaces, and value-added attributes. - - [structures](https://carto.nationalmap.gov/arcgis/rest/services/structures/MapServer): +- [structures](https://carto.nationalmap.gov/arcgis/rest/services/structures/MapServer): The name, function, location, and other core information and characteristics of selected manmade facilities. - - [transportation](https://carto.nationalmap.gov/arcgis/rest/services/transportation/MapServer): +- [transportation](https://carto.nationalmap.gov/arcgis/rest/services/transportation/MapServer): Roads, railroads, trails, airports, and other features associated with the transport of people or commerce. - - [wbd](https://hydro.nationalmap.gov/arcgis/rest/services/wbd/MapServer): +- [wbd](https://hydro.nationalmap.gov/arcgis/rest/services/wbd/MapServer): Hydrologic Unit (HU) polygon boundaries for the United States, Puerto Rico, and the U.S. Virgin Islands. @@ -189,7 +210,7 @@ devtools::install_github("ropensci/terrainr") ``` Be aware that the development version is not stable, and features that -haven’t been published on CRAN may change at any time\! +haven’t been published on CRAN may change at any time! ## Code of Conduct @@ -197,4 +218,4 @@ Please note that this package is released with a [Contributor Code of Conduct](https://ropensci.org/code-of-conduct/). By contributing to this project, you agree to abide by its terms. -[![ropensci\_footer](https://ropensci.org/public_images/github_footer.png)](https://ropensci.org) +[![ropensci_footer](https://ropensci.org/public_images/github_footer.png)](https://ropensci.org) From 707b5cf806fa6b612b9f99eaf9e1a556bf848f2c Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 20 Oct 2021 17:15:23 -0400 Subject: [PATCH 05/37] Link to unifir --- README.Rmd | 8 ++++---- README.md | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/README.Rmd b/README.Rmd index 899757e..c0b73e1 100644 --- a/README.Rmd +++ b/README.Rmd @@ -24,23 +24,23 @@ knitr::opts_chunk$set( ## This is an experimental build of terrainr -This feature branch requires the `unifir` package, currently not on CRAN. +This feature branch requires the [unifir](https://github.com/mikemahoney218/unifir) package, currently not on CRAN. If you want to try out the new features in this version -- particularly the new -`make_unity` function -- install `unifir` using the command: +`make_unity` function -- install unifir using the command: ```{r, eval = FALSE} # install.packages("remotes") remotes::install_github("mikemahoney218/unifir") ``` -Then install this version of `terrainr` using: +Then install this version of terrainr using: ```{r, eval=FALSE} remotes::install_github("ropensci/terrainr", "unified") ``` -Please note that `unifir` is currently very young and subject to change, and the +Please note that unifir is currently very young and subject to change, and the features in this branch are likely to change with it. ## Overview diff --git a/README.md b/README.md index 35e36dc..e6f1f01 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,10 @@ Status](https://badges.ropensci.org/416_status.svg)](https://github.com/ropensci ## This is an experimental build of terrainr -This feature branch requires the `unifir` package, currently not on -CRAN. If you want to try out the new features in this version – -particularly the new `make_unity` function – install `unifir` using the +This feature branch requires the +[unifir](https://github.com/mikemahoney218/unifir) package, currently +not on CRAN. If you want to try out the new features in this version – +particularly the new `make_unity` function – install unifir using the command: ``` r @@ -35,13 +36,13 @@ command: remotes::install_github("mikemahoney218/unifir") ``` -Then install this version of `terrainr` using: +Then install this version of terrainr using: ``` r remotes::install_github("ropensci/terrainr", "unified") ``` -Please note that `unifir` is currently very young and subject to change, +Please note that unifir is currently very young and subject to change, and the features in this branch are likely to change with it. ## Overview From b85f1f67e2d657cc297b1539fd2442e4996b34f3 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Wed, 20 Oct 2021 21:21:24 +0000 Subject: [PATCH 06/37] Re-build README.Rmd --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index e6f1f01..a9e5be7 100644 --- a/README.md +++ b/README.md @@ -136,7 +136,7 @@ make_manifest(output_tiles$elevation, ``` We can then import these tiles to Unity (following the [Import -Vignette]((https://docs.ropensci.org/terrainr/articles/unity_instructions.html))) +Vignette](\(https://docs.ropensci.org/terrainr/articles/unity_instructions.html\))) to create: @@ -147,46 +147,46 @@ you’ll be more confident that your computer is still churning along and not just stalled out. For more information, check out [the introductory vignette](https://docs.ropensci.org/terrainr//articles/overview.html) and [the guide to importing your data into -Unity!](https://docs.ropensci.org/terrainr//articles/unity_instructions.html) +Unity\!](https://docs.ropensci.org/terrainr//articles/unity_instructions.html) ## Available Datasets The following datasets can currently be downloaded using `get_tiles` or `hit_national_map_api`: -- [3DEPElevation](https://elevation.nationalmap.gov/arcgis/rest/services/3DEPElevation/ImageServer): + - [3DEPElevation](https://elevation.nationalmap.gov/arcgis/rest/services/3DEPElevation/ImageServer): The USGS 3D Elevation Program (3DEP) Bare Earth DEM. -- [USGSNAIPPlus](https://services.nationalmap.gov/arcgis/rest/services/USGSNAIPPlus/MapServer): + - [USGSNAIPPlus](https://services.nationalmap.gov/arcgis/rest/services/USGSNAIPPlus/MapServer): National Agriculture Imagery Program (NAIP) and high resolution orthoimagery (HRO). -- [nhd](https://hydro.nationalmap.gov/arcgis/rest/services/nhd/MapServer): + - [nhd](https://hydro.nationalmap.gov/arcgis/rest/services/nhd/MapServer): A comprehensive set of digital spatial data that encodes information about naturally occurring and constructed bodies of surface water (lakes, ponds, and reservoirs), paths through which water flows (canals, ditches, streams, and rivers), and related entities such as point features (springs, wells, stream gauges, and dams). -- [govunits](https://carto.nationalmap.gov/arcgis/rest/services/govunits/MapServer): + - [govunits](https://carto.nationalmap.gov/arcgis/rest/services/govunits/MapServer): Major civil areas for the Nation, including States or Territories, counties (or equivalents), Federal and Native American areas, congressional districts, minor civil divisions, incorporated places (such as cities and towns), and unincorporated places. -- [contours](https://carto.nationalmap.gov/arcgis/rest/services/contours/MapServer): + - [contours](https://carto.nationalmap.gov/arcgis/rest/services/contours/MapServer): The USGS Elevation Contours service. -- [geonames](https://carto.nationalmap.gov/arcgis/rest/services/geonames/MapServer): + - [geonames](https://carto.nationalmap.gov/arcgis/rest/services/geonames/MapServer): Information about physical and cultural geographic features, geographic areas, and locational entities that are generally recognizable and locatable by name. -- [NHDPlus_HR](https://hydro.nationalmap.gov/arcgis/rest/services/NHDPlus_HR/MapServer): + - [NHDPlus\_HR](https://hydro.nationalmap.gov/arcgis/rest/services/NHDPlus_HR/MapServer): A comprehensive set of digital spatial data comprising a nationally seamless network of stream reaches, elevation-based catchment areas, flow surfaces, and value-added attributes. -- [structures](https://carto.nationalmap.gov/arcgis/rest/services/structures/MapServer): + - [structures](https://carto.nationalmap.gov/arcgis/rest/services/structures/MapServer): The name, function, location, and other core information and characteristics of selected manmade facilities. -- [transportation](https://carto.nationalmap.gov/arcgis/rest/services/transportation/MapServer): + - [transportation](https://carto.nationalmap.gov/arcgis/rest/services/transportation/MapServer): Roads, railroads, trails, airports, and other features associated with the transport of people or commerce. -- [wbd](https://hydro.nationalmap.gov/arcgis/rest/services/wbd/MapServer): + - [wbd](https://hydro.nationalmap.gov/arcgis/rest/services/wbd/MapServer): Hydrologic Unit (HU) polygon boundaries for the United States, Puerto Rico, and the U.S. Virgin Islands. @@ -211,7 +211,7 @@ devtools::install_github("ropensci/terrainr") ``` Be aware that the development version is not stable, and features that -haven’t been published on CRAN may change at any time! +haven’t been published on CRAN may change at any time\! ## Code of Conduct @@ -219,4 +219,4 @@ Please note that this package is released with a [Contributor Code of Conduct](https://ropensci.org/code-of-conduct/). By contributing to this project, you agree to abide by its terms. -[![ropensci_footer](https://ropensci.org/public_images/github_footer.png)](https://ropensci.org) +[![ropensci\_footer](https://ropensci.org/public_images/github_footer.png)](https://ropensci.org) From 9cdce1dad700f4b8e497941d6a3e7db0fd3919f1 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Mon, 8 Nov 2021 09:00:11 -0500 Subject: [PATCH 07/37] Pass GITHUB_TOKEN as GITHUB_PAT --- .github/workflows/check.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index 6e3b47c..efcf37d 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -29,6 +29,7 @@ jobs: env: R_REMOTES_NO_ERRORS_FROM_WARNINGS: true RSPM: ${{ matrix.config.rspm }} + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 From 463dfc406fc00e1c36a0e1284a30d20ae7f0d28c Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Thu, 3 Feb 2022 17:50:53 -0500 Subject: [PATCH 08/37] Set scene first --- R/make_unity.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/make_unity.R b/R/make_unity.R index d9b4612..4d6af2f 100644 --- a/R/make_unity.R +++ b/R/make_unity.R @@ -59,7 +59,7 @@ make_unity <- function(project, } script <- unifir::save_scene(script) - script <- unifir::action(script) script <- unifir::set_active_scene(script, scene_name) + script <- unifir::action(script) } From 17e93e7057d1fc6a17b88b5cc5338f026ca3f026 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Thu, 3 Feb 2022 23:46:54 -0500 Subject: [PATCH 09/37] Move off gdalUtils --- DESCRIPTION | 1 - R/make_manifest.R | 19 +++++++++---------- R/raster_to_raw_tiles.R | 13 ++++++------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index baa115a..ab9e78b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -30,7 +30,6 @@ Imports: httr, raster, magick (>= 2.5.0), - gdalUtils, methods, png, sf (>= 1.0-5), diff --git a/R/make_manifest.R b/R/make_manifest.R index 4b69cfe..a2d9df2 100644 --- a/R/make_manifest.R +++ b/R/make_manifest.R @@ -228,16 +228,16 @@ prep_table <- function(input_raster, crop_tif <- function(img, manifest, temptiffs, field = "filename") { for (i in seq_len(nrow(manifest))) { - # changing this to gdalUtilities causes my computer to crash - gdalUtils::gdal_translate(img, temptiffs[[i]], - srcwin = paste0( + sf::gdal_utils( + "translate", + img, + temptiffs[[i]], + options = c( + "-srcwin", -manifest$x_pos[[i]], - ", ", - manifest$z_pos[[i]], - ", ", - manifest$x_length[[i]], - ", ", - manifest$z_length[[i]] + manifest$z_pos[[i]], + manifest$x_length[[i]], + manifest$z_length[[i]] ) ) names(temptiffs)[[i]] <- manifest[[field]][[i]] @@ -251,7 +251,6 @@ convert_to_png <- function(temptiffs, max_val) { mapply( function(x, y) { - # changing this to gdalUtils causes errors sf::gdal_utils( "translate", source = x, diff --git a/R/raster_to_raw_tiles.R b/R/raster_to_raw_tiles.R index 6d8f155..125c51b 100644 --- a/R/raster_to_raw_tiles.R +++ b/R/raster_to_raw_tiles.R @@ -88,15 +88,15 @@ raster_to_raw_tiles <- function(input_file, y_tiles[[j]] )) } # nocov end - # changing this to gdalUtilities causes my computer to crash - gdalUtils::gdal_translate(input_file, temptiffs[[counter]], - srcwin = paste0( + sf::gdal_utils( + "translate", + input_file, + temptiffs[[counter]], + options = c( + "-srcwin", x_tiles[[i]], - ", ", y_tiles[[j]], - ", ", side_length, - ", ", side_length ) ) @@ -132,7 +132,6 @@ raster_to_raw_tiles <- function(input_file, if (requireNamespace("progressr", quietly = TRUE)) { # nocov start p(message = sprintf("Converting tile %s to PNG", x)) } # nocov end - # changing this to gdalUtils causes errors sf::gdal_utils( "translate", source = x, From 64318f87208abb672d160b82bb3e3668b1c88eef Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Fri, 4 Feb 2022 09:19:06 -0500 Subject: [PATCH 10/37] Finish removing gdalUtils --- DESCRIPTION | 1 + R/merge_rasters.R | 118 +++++----------------------------------------- 2 files changed, 14 insertions(+), 105 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index ab9e78b..eb3439f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -29,6 +29,7 @@ Imports: base64enc, httr, raster, + rgdal, magick (>= 2.5.0), methods, png, diff --git a/R/merge_rasters.R b/R/merge_rasters.R index 602d97f..707daaa 100644 --- a/R/merge_rasters.R +++ b/R/merge_rasters.R @@ -90,116 +90,24 @@ merge_rasters_deprecated <- function(input_rasters, warning("Options are not respected when trying to merge rasters with differing numbers of bands") # nolint } - output_list <- vector("list") - output_list$output_raster <- output_raster - - # writeRaster seems to write a .tif if a .tiff is specified, which means - # mosaic_rasters does nothing and you get a useless blank .tif output unless - # you run the function twice. - # this is silly. - # so, we'll work around it if necessary -- do our work in a .tif then rename - # it at the end - if (!grepl("\\.tif", output_raster)) { - stop("Output files must be TIFFs.") - } - - fix_height <- 0 - - if (grepl("\\.tiff$", output_raster)) { - fix_height <- 1 - output_raster <- substr(output_raster, 1, nchar(output_raster) - 1) - } - - input_raster_objects <- lapply(input_rasters, function(x) raster::raster(x)) - - # if some files were downloaded as RGBA and some RGB, mosaic_rasters will fail - # - # so drop the alpha channel if we need to, but only if we need to, because - # this takes a while - if (any(vapply( - input_raster_objects, - function(x) x@file@nbands == 4, - logical(1) - )) && - !all(vapply( - input_raster_objects, - function(x) x@file@nbands == 4, - logical(1) - ))) { - tmprst <- vapply( - seq_along(input_rasters), - function(x) tempfile(fileext = ".tif"), - character(1) - ) - mapply( - function(x, y) { - raster::writeRaster( - raster::stack(x[[1]], - bands = 1:3 - ), - y - ) - }, - input_rasters, - tmprst - ) - input_raster_objects <- lapply(tmprst, function(x) raster::raster(x)) - input_rasters <- tmprst - } - - total_extent <- raster::raster(raster::extent( - min(vapply( - input_raster_objects, - function(x) raster::extent(x)@xmin, - numeric(1) - )), - max(vapply( - input_raster_objects, - function(x) raster::extent(x)@xmax, - numeric(1) - )), - min(vapply( - input_raster_objects, - function(x) raster::extent(x)@ymin, - numeric(1) - )), - max(vapply( - input_raster_objects, - function(x) raster::extent(x)@ymax, - numeric(1) - )) - )) - raster::projection(total_extent) <- raster::projection(input_raster_objects[[1]]) # nolint - - # we're writing an entirely NA raster to file - # raster, like a good package should - # attempts to warn us about this silly thing we're doing - # but we're doing it on purpose, so suppress those warnings - suppressWarnings(raster::writeRaster(total_extent, - output_raster, - overwrite = TRUE - )) - - invisible( - utils::capture.output( - gdalUtils::mosaic_rasters( - gdalfile = input_rasters, - dst_dataset = output_raster - ) - ) + temp_output <- tempfile(fileext = ".vrt") + sf::gdal_utils( + "buildvrt", + input_rasters, + temp_output, + options = c("-addalpha") + ) + sf::gdal_utils( + "warp", + temp_output, + output_raster ) - - if (fix_height) { - file.rename(output_raster, paste0(output_raster, "f")) - } - - if (exists("tmprst")) lapply(tmprst, unlink) message( - "...done.\n", + "\n...done.\n", "The alternate method seems to have worked!\n", "If your merged output looks right, you can ignore the above error.\n" ) - return(output_list) + return(invisible(output_raster)) } From 5a4eff331548f604e57faa623b5221cb6cde3ab8 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Fri, 4 Feb 2022 09:32:49 -0500 Subject: [PATCH 11/37] Ignore Unity code for fast release --- .Rbuildignore | 1 + NEWS.md | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.Rbuildignore b/.Rbuildignore index 87e775b..4df043f 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -34,3 +34,4 @@ methods-in-ecology-and-evolution.csl ^CRAN-RELEASE$ ^CRAN-SUBMISSION$ ^CITATION\.cff$ +R/make_unity.R diff --git a/NEWS.md b/NEWS.md index cf56414..a02c9c2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -18,6 +18,8 @@ * Dependency changes: * `sf` now has a minimum dependency of 1.0-5, to take advantage of an upstream bug fix (relating to `merge_rasters` overwrite) + * `gdalUtils` has been removed from dependencies following CRAN directions + * # terrainr 0.5.0. * New features: From 2f1c47b853464bbe5c9c6607a52d07291ad235ce Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Fri, 4 Feb 2022 09:40:14 -0500 Subject: [PATCH 12/37] Finish updating fallback method --- NEWS.md | 21 ++++++++++++++------- R/merge_rasters.R | 9 +++++---- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/NEWS.md b/NEWS.md index a02c9c2..437e3f0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,25 +1,32 @@ # terrainr 0.6.0 * New features: - * A new endpoint, `ecosystems`, has been added to `get_tiles` and - `hit_national_map_api`. * Two new functions, `transform_elevation` and `transform_overlay`, should now provide raster transformation functions that were possible with `raster_to_raw_tiles` but not with `make_manifest`. As an added bonus, the internal code to handle tiling is now dramatically simpler. +* Improvements and bug fixes: + * `make_manifest` will now overwrite any file at `importer_path`, in line + with documented behavior. Previous versions would never overwrite + `importer_path`. + * `merge_rasters`' fallback method now runs much faster +* Dependency changes: + * `gdalUtils` has been removed from dependencies following CRAN directions + * `rgdal` is now an explicit dependency (had previously been imported via + `gdalUtils`) + +# terrainr 0.5.1 +* New features: + * A new endpoint, `ecosystems`, has been added to `get_tiles` and + `hit_national_map_api`. * Improvements and bug fixes: * `merge_rasters` gains an argument, `overwrite`, which allows you to specify whether or not to overwrite `output_raster` if it exists. Previous versions expected you to pass "-overwrite" to `options`. If a file exists at `output_raster` and `overwrite` is FALSE, `merge_rasters` will throw an error. - * `make_manifest` will now overwrite any file at `importer_path`, in line - with documented behavior. Previous versions would never overwrite - `importer_path`. * Dependency changes: * `sf` now has a minimum dependency of 1.0-5, to take advantage of an upstream bug fix (relating to `merge_rasters` overwrite) - * `gdalUtils` has been removed from dependencies following CRAN directions - * # terrainr 0.5.0. * New features: diff --git a/R/merge_rasters.R b/R/merge_rasters.R index 707daaa..2d3fb99 100644 --- a/R/merge_rasters.R +++ b/R/merge_rasters.R @@ -86,7 +86,8 @@ merge_rasters <- function(input_rasters, merge_rasters_deprecated <- function(input_rasters, output_raster = tempfile(fileext = ".tif"), options = character(0)) { - if (length(options) > 0) { + if (length(options) > 0 || + !(length(options == 1) && options == "-overwrite")) { warning("Options are not respected when trying to merge rasters with differing numbers of bands") # nolint } @@ -94,13 +95,13 @@ merge_rasters_deprecated <- function(input_rasters, sf::gdal_utils( "buildvrt", input_rasters, - temp_output, - options = c("-addalpha") + temp_output ) sf::gdal_utils( "warp", temp_output, - output_raster + output_raster, + options = options ) message( From 8d60cc1d07c631df531b72c345f03f74d95d9812 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Fri, 4 Feb 2022 09:41:05 -0500 Subject: [PATCH 13/37] Don't ignore Unity --- .Rbuildignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.Rbuildignore b/.Rbuildignore index 4df043f..87e775b 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -34,4 +34,3 @@ methods-in-ecology-and-evolution.csl ^CRAN-RELEASE$ ^CRAN-SUBMISSION$ ^CITATION\.cff$ -R/make_unity.R From b0e89be0c4418dddf410c1dc24c7e8f5f23de90a Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 23 Mar 2022 13:50:41 -0400 Subject: [PATCH 14/37] Add make_unity --- .Rbuildignore | 2 +- NAMESPACE | 1 + R/make_unity.R | 46 +++++++++++++++++++++++++++++++++++++--- man/make_unity.Rd | 53 +++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 man/make_unity.Rd diff --git a/.Rbuildignore b/.Rbuildignore index 4df043f..9cc17a1 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -34,4 +34,4 @@ methods-in-ecology-and-evolution.csl ^CRAN-RELEASE$ ^CRAN-SUBMISSION$ ^CITATION\.cff$ -R/make_unity.R + diff --git a/NAMESPACE b/NAMESPACE index 9736792..2e43718 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -16,6 +16,7 @@ export(georeference_overlay) export(get_tiles) export(hit_national_map_api) export(make_manifest) +export(make_unity) export(merge_rasters) export(raster_to_raw_tiles) export(set_bbox_side_length) diff --git a/R/make_unity.R b/R/make_unity.R index 4d6af2f..9bd0265 100644 --- a/R/make_unity.R +++ b/R/make_unity.R @@ -1,7 +1,45 @@ +#' Initialize terrain inside of a Unity project. +#' +#' @param project The directory path of the Unity project to create terrain +#' inside. +#' @param heightmap The file path for the raster to transform into terrain. +#' @param overlay Optionally, a file path for an image overlay to layer on top +#' of the terrain surface. Leave as NULL for no overlay. +#' @param scene_name The name of the Unity scene to create the terrain in. +#' @param action Boolean: Execute the unifir "script" and create the Unity +#' project? If FALSE, returns a non-executed script. +#' +#' @return An object of class "unifir_script", containing either an executed +#' unifir script (if action = TRUE) or a non-executed script object +#' (if action = FALSE). +#' +#' @examples +#' \dontrun{ +#' if (!isTRUE(as.logical(Sys.getenv("CI")))) { +#' simulated_data <- data.frame( +#' id = seq(1, 100, 1), +#' lat = runif(100, 44.04905, 44.17609), +#' lng = runif(100, -74.01188, -73.83493) +#' ) +#' simulated_data <- sf::st_as_sf(simulated_data, coords = c("lng", "lat")) +#' output_files <- get_tiles(simulated_data) +#' temptiff <- tempfile(fileext = ".tif") +#' merge_rasters(output_files["elevation"][[1]], temptiff) +#' make_unity(file.path(tempdir(), "unity"), temptiff) +#' } +#' } +#' +#' @export make_unity <- function(project, heightmap, overlay = NULL, - scene_name = "terrainr_scene") { + scene_name = "terrainr_scene", + action = TRUE) { + + if (!requireNamespace("unifir", quietly = TRUE)) { + stop("make_unity requires the unifir package to work correctly. ", + "Please install unifir to continue.") + } elevation_prefix <- tempfile() manifest <- prep_table(heightmap, @@ -38,8 +76,8 @@ make_unity <- function(project, manifest$texture, function(x) file.rename(x, file.path(project, basename(x))) ) + manifest$texture <- basename(manifest$texture) } - manifest$texture <- basename(manifest$texture) script <- unifir::make_script(project, scene_name = scene_name) script <- unifir::new_scene(script, "DefaultGameObjects", "Single") @@ -60,6 +98,8 @@ make_unity <- function(project, script <- unifir::save_scene(script) script <- unifir::set_active_scene(script, scene_name) - script <- unifir::action(script) + if (action) { + script <- unifir::action(script) + } } diff --git a/man/make_unity.Rd b/man/make_unity.Rd new file mode 100644 index 0000000..f2cfdd5 --- /dev/null +++ b/man/make_unity.Rd @@ -0,0 +1,53 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/make_unity.R +\name{make_unity} +\alias{make_unity} +\title{Initialize terrain inside of a Unity project.} +\usage{ +make_unity( + project, + heightmap, + overlay = NULL, + scene_name = "terrainr_scene", + action = TRUE +) +} +\arguments{ +\item{project}{The directory path of the Unity project to create terrain +inside.} + +\item{heightmap}{The file path for the raster to transform into terrain.} + +\item{overlay}{Optionally, a file path for an image overlay to layer on top +of the terrain surface. Leave as NULL for no overlay.} + +\item{scene_name}{The name of the Unity scene to create the terrain in.} + +\item{action}{Boolean: Execute the unifir "script" and create the Unity +project? If FALSE, returns a non-executed script.} +} +\value{ +An object of class "unifir_script", containing either an executed +unifir script (if action = TRUE) or a non-executed script object +(if action = FALSE). +} +\description{ +Initialize terrain inside of a Unity project. +} +\examples{ +\dontrun{ +if (!isTRUE(as.logical(Sys.getenv("CI")))) { + simulated_data <- data.frame( + id = seq(1, 100, 1), + lat = runif(100, 44.04905, 44.17609), + lng = runif(100, -74.01188, -73.83493) + ) + simulated_data <- sf::st_as_sf(simulated_data, coords = c("lng", "lat")) + output_files <- get_tiles(simulated_data) + temptiff <- tempfile(fileext = ".tif") + merge_rasters(output_files["elevation"][[1]], temptiff) + make_unity(file.path(tempdir(), "unity"), temptiff) +} +} + +} From 51d02334bd953ccbbaf20ba06a6698bcfc3cb09b Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 23 Mar 2022 13:56:35 -0400 Subject: [PATCH 15/37] Style and lint --- R/get_tiles.R | 3 ++- R/hit_api.R | 9 ++++++--- R/make_manifest.R | 13 ++++++++----- R/make_unity.R | 20 ++++++++++---------- R/merge_rasters.R | 4 +--- tests/testthat/test-4-merge_rasters.R | 10 ++++++++-- 6 files changed, 35 insertions(+), 24 deletions(-) diff --git a/R/get_tiles.R b/R/get_tiles.R index cac3426..9d8ada5 100644 --- a/R/get_tiles.R +++ b/R/get_tiles.R @@ -335,7 +335,8 @@ get_tiles_internal <- function(data, for (i in seq_len(x_tiles)) { for (j in seq_len(y_tiles)) { - current_box <- tile_boxes[tile_boxes$x_tiles == i & tile_boxes$y_tiles == j, ] + current_box <- tile_boxes[tile_boxes$x_tiles == i & + tile_boxes$y_tiles == j, ] current_bbox <- data.frame( lat = c(current_box$min_y, current_box$max_y), lng = c(current_box$min_x, current_box$max_x) diff --git a/R/hit_api.R b/R/hit_api.R index 86c4af7..84c99e7 100644 --- a/R/hit_api.R +++ b/R/hit_api.R @@ -199,9 +199,12 @@ hit_national_map_api <- function(bbox, } } else if (counter < 15) { get_href(counter = counter + 1) - } else { - stop("Map server returned error code ", httr::status_code(img_res)) # nocov - } + } else { # nocov start + stop( + "Map server returned error code ", + httr::status_code(img_res) + ) + } # nocov end } body <- get_href() diff --git a/R/make_manifest.R b/R/make_manifest.R index a2d9df2..3a9982a 100644 --- a/R/make_manifest.R +++ b/R/make_manifest.R @@ -92,7 +92,11 @@ make_manifest <- function(heightmap, transform_elevation <- function(heightmap, side_length = 4097, output_prefix = "import") { - manifest <- prep_table(heightmap, side_length, output_prefix, type = "elevation") + manifest <- prep_table(heightmap, + side_length, + output_prefix, + type = "elevation" + ) temptiffs <- NULL while (length(temptiffs) != nrow(manifest)) { @@ -186,7 +190,6 @@ prep_table <- function(input_raster, x_tiles <- ceiling(input_raster@ncols / side_length) y_tiles <- ceiling(input_raster@nrows / side_length) - n_tiles <- x_tiles * y_tiles file_combos <- expand.grid( x = 1:x_tiles, @@ -235,9 +238,9 @@ crop_tif <- function(img, manifest, temptiffs, field = "filename") { options = c( "-srcwin", -manifest$x_pos[[i]], - manifest$z_pos[[i]], - manifest$x_length[[i]], - manifest$z_length[[i]] + manifest$z_pos[[i]], + manifest$x_length[[i]], + manifest$z_length[[i]] ) ) names(temptiffs)[[i]] <- manifest[[field]][[i]] diff --git a/R/make_unity.R b/R/make_unity.R index 9bd0265..134a2e4 100644 --- a/R/make_unity.R +++ b/R/make_unity.R @@ -35,17 +35,18 @@ make_unity <- function(project, overlay = NULL, scene_name = "terrainr_scene", action = TRUE) { - if (!requireNamespace("unifir", quietly = TRUE)) { - stop("make_unity requires the unifir package to work correctly. ", - "Please install unifir to continue.") + stop( + "make_unity requires the unifir package to work correctly. ", + "Please install unifir to continue." + ) } elevation_prefix <- tempfile() manifest <- prep_table(heightmap, - side_length = 4097, - output_prefix = elevation_prefix, - type = "elevation" + side_length = 4097, + output_prefix = elevation_prefix, + type = "elevation" ) transform_elevation( heightmap = heightmap, @@ -62,9 +63,9 @@ make_unity <- function(project, if (!is.null(overlay)) { overlay_prefix <- tempfile() overlay_manifest <- prep_table(heightmap, - side_length = 4097, - output_prefix = overlay_prefix, - type = "overlay" + side_length = 4097, + output_prefix = overlay_prefix, + type = "overlay" ) manifest$texture <- overlay_manifest$texture transform_overlay( @@ -101,5 +102,4 @@ make_unity <- function(project, if (action) { script <- unifir::action(script) } - } diff --git a/R/merge_rasters.R b/R/merge_rasters.R index 2d3fb99..f845092 100644 --- a/R/merge_rasters.R +++ b/R/merge_rasters.R @@ -53,8 +53,6 @@ merge_rasters <- function(input_rasters, options <- c(options, "-overwrite") } - initial_file <- output_raster - if (!force_fallback) { tryCatch( { @@ -87,7 +85,7 @@ merge_rasters_deprecated <- function(input_rasters, output_raster = tempfile(fileext = ".tif"), options = character(0)) { if (length(options) > 0 || - !(length(options == 1) && options == "-overwrite")) { + !(length(options == 1) && options == "-overwrite")) { warning("Options are not respected when trying to merge rasters with differing numbers of bands") # nolint } diff --git a/tests/testthat/test-4-merge_rasters.R b/tests/testthat/test-4-merge_rasters.R index ec6724f..d75c755 100644 --- a/tests/testthat/test-4-merge_rasters.R +++ b/tests/testthat/test-4-merge_rasters.R @@ -116,11 +116,17 @@ test_that("overwrite works as expected", { NA ) expect_warning( - merge_rasters(c(tmptif[[1]], tmptif[[2]]), test_file, options = "-overwrite"), + merge_rasters(c(tmptif[[1]], tmptif[[2]]), + test_file, + options = "-overwrite" + ), NA ) expect_warning( - merge_rasters(c(tmptif[[1]], tmptif[[2]]), test_file, overwrite = TRUE, options = "-overwrite"), + merge_rasters(c(tmptif[[1]], tmptif[[2]]), + test_file, + overwrite = TRUE, options = "-overwrite" + ), NA ) From 4b0dd7205406b90f3e54018b9afa90f814ccbe8b Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 23 Mar 2022 14:08:49 -0400 Subject: [PATCH 16/37] Update CI --- .github/workflows/run-examples.yaml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/run-examples.yaml b/.github/workflows/run-examples.yaml index ceb7b8d..9cfce8a 100644 --- a/.github/workflows/run-examples.yaml +++ b/.github/workflows/run-examples.yaml @@ -43,25 +43,24 @@ jobs: shell: Rscript {0} - name: Cache R packages - if: runner.os != 'Windows' uses: actions/cache@v2 with: path: ${{ env.R_LIBS_USER }} key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }} restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1- - - name: Install system dependencies + - name: Install Linux dependencies if: runner.os == 'Linux' run: | while read -r cmd do eval sudo $cmd done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "20.04"))') + - name: Install dependencies run: | - remotes::install_cran("devtools") + remotes::install_github("mikemahoney218/unifir") remotes::install_deps(dependencies = TRUE) - remotes::install_cran("rcmdcheck") shell: Rscript {0} - name: Check From 95134e7e8ee2dc54c8e2de567b67c5e5475786f4 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 23 Mar 2022 14:17:36 -0400 Subject: [PATCH 17/37] Pass github PAT --- .github/workflows/run-examples.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/run-examples.yaml b/.github/workflows/run-examples.yaml index 9cfce8a..2bf003e 100644 --- a/.github/workflows/run-examples.yaml +++ b/.github/workflows/run-examples.yaml @@ -25,6 +25,7 @@ jobs: env: R_REMOTES_NO_ERRORS_FROM_WARNINGS: true RSPM: ${{ matrix.config.rspm }} + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 From c8b49bd569b410711f28d6dcb7b0b71f850eef1d Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 23 Mar 2022 14:56:17 -0400 Subject: [PATCH 18/37] Return script --- R/make_unity.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/make_unity.R b/R/make_unity.R index 134a2e4..f2497f9 100644 --- a/R/make_unity.R +++ b/R/make_unity.R @@ -102,4 +102,5 @@ make_unity <- function(project, if (action) { script <- unifir::action(script) } + script } From 8dec4c3d7b89034d82bb1ae023bef86c7d440a76 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 23 Mar 2022 22:02:41 -0400 Subject: [PATCH 19/37] Return functional script from make_unity --- R/make_unity.R | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/R/make_unity.R b/R/make_unity.R index f2497f9..17c97a9 100644 --- a/R/make_unity.R +++ b/R/make_unity.R @@ -5,6 +5,8 @@ #' @param heightmap The file path for the raster to transform into terrain. #' @param overlay Optionally, a file path for an image overlay to layer on top #' of the terrain surface. Leave as NULL for no overlay. +#' @param side_length The side length, in map units, for the terrain tiles. +#' Must be equal to 2^x + 1, for any x between 5 and 12. #' @param scene_name The name of the Unity scene to create the terrain in. #' @param action Boolean: Execute the unifir "script" and create the Unity #' project? If FALSE, returns a non-executed script. @@ -33,6 +35,7 @@ make_unity <- function(project, heightmap, overlay = NULL, + side_length = 4097, scene_name = "terrainr_scene", action = TRUE) { if (!requireNamespace("unifir", quietly = TRUE)) { @@ -42,15 +45,22 @@ make_unity <- function(project, ) } + if (!(side_length %in% 2^(5:12) + 1)) { + stop( + "side_length must be equal to a value of 2^x + 1, for any x ", + "between 2 and 5." + ) + } + elevation_prefix <- tempfile() manifest <- prep_table(heightmap, - side_length = 4097, + side_length = side_length, output_prefix = elevation_prefix, type = "elevation" ) transform_elevation( heightmap = heightmap, - side_length = 4097, + side_length = side_length, output_prefix = elevation_prefix ) dir.create(project) @@ -63,14 +73,14 @@ make_unity <- function(project, if (!is.null(overlay)) { overlay_prefix <- tempfile() overlay_manifest <- prep_table(heightmap, - side_length = 4097, + side_length = side_length, output_prefix = overlay_prefix, type = "overlay" ) manifest$texture <- overlay_manifest$texture transform_overlay( overlay = overlay, - side_length = 4097, + side_length = side_length, output_prefix = overlay_prefix ) lapply( @@ -98,7 +108,6 @@ make_unity <- function(project, } script <- unifir::save_scene(script) - script <- unifir::set_active_scene(script, scene_name) if (action) { script <- unifir::action(script) } From ca843f04c5f9337a03fc412e866e9bc432651f8c Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 23 Mar 2022 22:15:48 -0400 Subject: [PATCH 20/37] Document --- man/make_unity.Rd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/man/make_unity.Rd b/man/make_unity.Rd index f2cfdd5..bfd6c08 100644 --- a/man/make_unity.Rd +++ b/man/make_unity.Rd @@ -8,6 +8,7 @@ make_unity( project, heightmap, overlay = NULL, + side_length = 4097, scene_name = "terrainr_scene", action = TRUE ) @@ -21,6 +22,9 @@ inside.} \item{overlay}{Optionally, a file path for an image overlay to layer on top of the terrain surface. Leave as NULL for no overlay.} +\item{side_length}{The side length, in map units, for the terrain tiles. +Must be equal to 2^x + 1, for any x between 5 and 12.} + \item{scene_name}{The name of the Unity scene to create the terrain in.} \item{action}{Boolean: Execute the unifir "script" and create the Unity From 31269a321962c393d22fe4b4cc0893e636c79a35 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Mon, 11 Apr 2022 12:34:07 -0400 Subject: [PATCH 21/37] Swap docs to markdown --- DESCRIPTION | 1 + R/merge_rasters.R | 2 +- man/addbuff.Rd | 22 +++++++++++----------- man/geom_spatial_rgb.Rd | 18 +++++++++--------- man/georeference_overlay.Rd | 10 +++++----- man/merge_rasters.Rd | 12 ++++++------ man/point_from_distance.Rd | 4 ++-- man/raster_to_raw_tiles.Rd | 2 +- man/terrainr_bounding_box.Rd | 8 ++++---- man/unity_crops.Rd | 8 ++++---- 10 files changed, 44 insertions(+), 43 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 2197db7..d56973b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -52,3 +52,4 @@ Suggests: Config/testthat/parallel: true Config/testthat/edition: 3 VignetteBuilder: knitr +Roxygen: list(markdown = TRUE) diff --git a/R/merge_rasters.R b/R/merge_rasters.R index f845092..e493404 100644 --- a/R/merge_rasters.R +++ b/R/merge_rasters.R @@ -2,7 +2,7 @@ #' #' Some functions like [get_tiles] return multiple separate files #' when it can be useful to have a single larger raster instead. This function -#' is a thin wrapper over [sf::gdal_utils(util = "warp")], making it easy to +#' is a thin wrapper over [sf::gdal_utils], making it easy to #' collapse those multiple raster files into a single TIFF. #' #' @param input_rasters A character vector containing the file paths to the diff --git a/man/addbuff.Rd b/man/addbuff.Rd index fddcdbb..546d07b 100644 --- a/man/addbuff.Rd +++ b/man/addbuff.Rd @@ -38,34 +38,34 @@ set_bbox_side_length( ) } \arguments{ -\item{data}{The original data to add a buffer around. Must be either an `sf` -or `Raster` object.} +\item{data}{The original data to add a buffer around. Must be either an \code{sf} +or \code{Raster} object.} \item{distance}{The distance to add or to set side lengths equal to.} \item{distance_unit}{The units of the distance to add to the buffer, passed -to [units::as_units].} +to \link[units:units]{units::as_units}.} -\item{error_crs}{Logical: Should this function error if `data` has no CRS? -If `TRUE`, function errors; if `FALSE`, function quietly assumes EPSG:4326. -If `NULL`, the default, function assumes EPSG:4326 with a warning.} +\item{error_crs}{Logical: Should this function error if \code{data} has no CRS? +If \code{TRUE}, function errors; if \code{FALSE}, function quietly assumes EPSG:4326. +If \code{NULL}, the default, function assumes EPSG:4326 with a warning.} } \value{ -An `sfc` object (from [sf::st_as_sfc]). +An \code{sfc} object (from \link[sf:st_as_sfc]{sf::st_as_sfc}). } \description{ -[add_bbox_buffer] calculates the great circle distance both corners of +\link{add_bbox_buffer} calculates the great circle distance both corners of your bounding box are from the centroid and extends those by a set distance. Due to using Haversine/great circle distance, latitude/longitude calculations will not be exact. -[set_bbox_side_length] is a thin wrapper around [add_bbox_buffer] which sets +\link{set_bbox_side_length} is a thin wrapper around \link{add_bbox_buffer} which sets all sides of the bounding box to (approximately) a specified length. Both of these functions are intended to be used with geographic coordinate systems (data using longitude and latitude for position). For projected -coordinate systems, a more sane approach is to use [sf::st_buffer] to add a -buffer, or combine [sf::st_centroid] with the buffer to set a specific side +coordinate systems, a more sane approach is to use \link[sf:geos_unary]{sf::st_buffer} to add a +buffer, or combine \link[sf:geos_unary]{sf::st_centroid} with the buffer to set a specific side length. } \examples{ diff --git a/man/geom_spatial_rgb.Rd b/man/geom_spatial_rgb.Rd index 29707aa..a185a6b 100644 --- a/man/geom_spatial_rgb.Rd +++ b/man/geom_spatial_rgb.Rd @@ -41,15 +41,15 @@ default), it is combined with the default mapping at the top level of the plot. You must supply \code{mapping} if there is no plot mapping.} \item{data}{The data to be displayed in this layer. In addition to the three -options described in [ggplot2::geom_raster], there are two additional +options described in \link[ggplot2:geom_tile]{ggplot2::geom_raster}, there are two additional methods: -If a `RasterStack` object (see [raster::stack]), this function will coerce +If a \code{RasterStack} object (see \link[raster:stack]{raster::stack}), this function will coerce the stack to a data frame and assume the raster bands are in RGB order (while allowing for, but ignoring, a fourth alpha band). If a length-1 character vector, this function will attempt to load the object -via [raster::stack].} +via \link[raster:stack]{raster::stack}.} \item{stat}{The statistical transformation to use on the data for this layer, as a string.} @@ -88,17 +88,17 @@ that define both data and aesthetics and shouldn't inherit behaviour from the default plot specification, e.g. \code{\link[ggplot2:borders]{borders()}}.} \item{scale}{Integer. Maximum (possible) value in the three channels. -If `NULL`, attempts to infer proper values from data -- if all RGB values +If \code{NULL}, attempts to infer proper values from data -- if all RGB values are <= 1 then 1, <= 255 then 255, and otherwise 65535.} \item{geom}{The geometric object to use display the data} } \description{ -`geom_spatial_rgb` and `stat_spatial_rgb` allow users to plot three-band RGB -rasters in [ggplot2], using these layers as background base maps for other -spatial plotting. Note that unlike [ggplot2::geom_sf], this function does -_not_ force [ggplot2::coord_sf]; for accurate mapping, add -[ggplot2::coord_sf] with a `crs` value matching your input raster as a layer. +\code{geom_spatial_rgb} and \code{stat_spatial_rgb} allow users to plot three-band RGB +rasters in \link{ggplot2}, using these layers as background base maps for other +spatial plotting. Note that unlike \link[ggplot2:ggsf]{ggplot2::geom_sf}, this function does +\emph{not} force \link[ggplot2:ggsf]{ggplot2::coord_sf}; for accurate mapping, add +\link[ggplot2:ggsf]{ggplot2::coord_sf} with a \code{crs} value matching your input raster as a layer. } \examples{ \dontrun{ diff --git a/man/georeference_overlay.Rd b/man/georeference_overlay.Rd index b7f9279..f73ce8d 100644 --- a/man/georeference_overlay.Rd +++ b/man/georeference_overlay.Rd @@ -12,13 +12,13 @@ georeference_overlay( } \arguments{ \item{overlay_file}{The image overlay to georeference. File format will be -detected automatically from file extension; options include `jpeg/jpg`, -`png`, and `tif/tiff`.} +detected automatically from file extension; options include \code{jpeg/jpg}, +\code{png}, and \code{tif/tiff}.} \item{reference_raster}{The raster file to base georeferencing on. The output image will have the same extent and CRS as the reference raster. Accepts both -Raster* objects from the `raster` package or a file readable by -[raster::raster].} +Raster* objects from the \code{raster} package or a file readable by +\link[raster:raster]{raster::raster}.} \item{output_file}{The path to write the georeferenced image file to. Must be a TIFF.} @@ -30,7 +30,7 @@ The file path written to, invisibly. This function georeferences an image overlay based on a reference raster, setting the extent and CRS of the image to those of the raster file. To georeference multiple images and merge them into a single file, see -[merge_rasters]. +\link{merge_rasters}. } \examples{ \dontrun{ diff --git a/man/merge_rasters.Rd b/man/merge_rasters.Rd index 12ffcab..34fd017 100644 --- a/man/merge_rasters.Rd +++ b/man/merge_rasters.Rd @@ -20,12 +20,12 @@ georeferenced rasters you want to use.} to.} \item{options}{Optionally, a character vector of options to be passed -directly to [sf::gdal_utils]. If the fallback is used and any options (other +directly to \link[sf:gdal_utils]{sf::gdal_utils}. If the fallback is used and any options (other than "-overwrite") are specified, this will issue a warning.} -\item{overwrite}{Logical: overwrite `output_raster` if it exists? If FALSE +\item{overwrite}{Logical: overwrite \code{output_raster} if it exists? If FALSE and the file exists, this function will fail with an error. The behavior if -this argument is TRUE and "-overwrite" is passed to `options` directly is +this argument is TRUE and "-overwrite" is passed to \code{options} directly is not stable.} \item{force_fallback}{Logical: if TRUE, uses the much slower fallback method @@ -33,12 +33,12 @@ by default. This is used for testing purposes and is not recommended for use by end users.} } \value{ -`output_raster`, invisibly. +\code{output_raster}, invisibly. } \description{ -Some functions like [get_tiles] return multiple separate files +Some functions like \link{get_tiles} return multiple separate files when it can be useful to have a single larger raster instead. This function -is a thin wrapper over [sf::gdal_utils(util = "warp")], making it easy to +is a thin wrapper over \link[sf:gdal_utils]{sf::gdal_utils}, making it easy to collapse those multiple raster files into a single TIFF. } \examples{ diff --git a/man/point_from_distance.Rd b/man/point_from_distance.Rd index c501895..dd9a5cd 100644 --- a/man/point_from_distance.Rd +++ b/man/point_from_distance.Rd @@ -21,14 +21,14 @@ the original point to apply} \item{azimuth}{A azimuth (in units specified in \code{azimuth_unit}) representing the direction to apply the distance from the original point in} -\item{distance_unit}{A string passed to [convert_distance] +\item{distance_unit}{A string passed to \link{convert_distance} indicating the units of the provided distance.} \item{azimuth_unit}{A string (either \code{degrees} or \code{radians}) indicating the units of the \code{azimuth} argument} } \value{ -An object of class [terrainr_coordinate_pair]. +An object of class \link{terrainr_coordinate_pair}. } \description{ Find latitude and longitude for a certain distance and azimuth from a point. diff --git a/man/raster_to_raw_tiles.Rd b/man/raster_to_raw_tiles.Rd index f245258..c73aca6 100644 --- a/man/raster_to_raw_tiles.Rd +++ b/man/raster_to_raw_tiles.Rd @@ -22,7 +22,7 @@ written to. } \description{ This function has been deprecated as of terrainr 0.5.0 in favor of the new -function, [make_manifest]. While it will be continued to be exported until +function, \link{make_manifest}. While it will be continued to be exported until at least 2022, improvements and bug fixes will only be made to the new function. Please open an issue if any features you relied upon is missing from the new function! diff --git a/man/terrainr_bounding_box.Rd b/man/terrainr_bounding_box.Rd index 74f8268..b10ead7 100644 --- a/man/terrainr_bounding_box.Rd +++ b/man/terrainr_bounding_box.Rd @@ -8,17 +8,17 @@ terrainr_bounding_box(bl, tr, coord_units = "degrees") } \arguments{ \item{bl, tr}{The bottom left (\code{bl}) and top right (\code{tr}) corners of -the bounding box, either as a [terrainr_coordinate_pair] object +the bounding box, either as a \link{terrainr_coordinate_pair} object or a coordinate pair. If the coordinate pair is not named, it is assumed to be in (lat, lng) format; if it is named, the function will attempt to properly identify coordinates.} -\item{coord_units}{Arguments passed to [terrainr_coordinate_pair]. -If \code{bl} and \code{tr} are already [terrainr_coordinate_pair] +\item{coord_units}{Arguments passed to \link{terrainr_coordinate_pair}. +If \code{bl} and \code{tr} are already \link{terrainr_coordinate_pair} objects, these arguments are not used.} } \value{ -An object of class [terrainr_bounding_box]. +An object of class \link{terrainr_bounding_box}. } \description{ In order to simplify code, most \code{terrainr} functions expect a set S4 diff --git a/man/unity_crops.Rd b/man/unity_crops.Rd index 334dac6..3c62866 100644 --- a/man/unity_crops.Rd +++ b/man/unity_crops.Rd @@ -22,7 +22,7 @@ transform_overlay(overlay, side_length = 4097, output_prefix = "import") \item{heightmap}{File path to the heightmap to transform.} \item{overlay}{File path to the image overlay to transform. Optional for -[make_manifest].} +\link{make_manifest}.} \item{output_prefix}{The file path to prefix output tiles with.} @@ -32,18 +32,18 @@ transform_overlay(overlay, side_length = 4097, output_prefix = "import") to not copy the importer script. Will overwrite any file at the same path.} \item{side_length}{Side length, in pixels, of each output tile. If the raster -has dimensions not evenly divisible by `side_length`, tiles will be generated +has dimensions not evenly divisible by \code{side_length}, tiles will be generated with overhanging pieces set to 0 units of elevation or RGB 0 (pure black). Side lengths not equal to 2^x + 1 (for x <= 12) will cause a warning, as tiles must be this size for import into Unity.} } \value{ -`manifest_path`, invisibly. +\code{manifest_path}, invisibly. } \description{ These functions crop input raster files into smaller square tiles and then converts them into either .png or .raw files which are ready to be imported -into the Unity game engine. [make_manifest] also writes a "manifest" file and +into the Unity game engine. \link{make_manifest} also writes a "manifest" file and importer script which may be used to automatically import the tiles into Unity. } From eff20fd289ca0ae299c8f1c62dd1151842c4b670 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Mon, 11 Apr 2022 22:06:42 -0400 Subject: [PATCH 22/37] Fix doc bug --- R/utils.R | 2 +- man/point_from_distance.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/utils.R b/R/utils.R index a1ca1f4..461deb7 100644 --- a/R/utils.R +++ b/R/utils.R @@ -59,7 +59,7 @@ get_centroid <- function(lat, lng) { #' the original point to apply #' @param azimuth A azimuth (in units specified in \code{azimuth_unit}) #' representing the direction to apply the distance from the original point in -#' @param distance_unit A string passed to [convert_distance] +#' @param distance_unit A string passed to convert_distance #' indicating the units of the provided distance. #' @param azimuth_unit A string (either \code{degrees} or \code{radians}) #' indicating the units of the \code{azimuth} argument diff --git a/man/point_from_distance.Rd b/man/point_from_distance.Rd index dd9a5cd..312b8b5 100644 --- a/man/point_from_distance.Rd +++ b/man/point_from_distance.Rd @@ -21,7 +21,7 @@ the original point to apply} \item{azimuth}{A azimuth (in units specified in \code{azimuth_unit}) representing the direction to apply the distance from the original point in} -\item{distance_unit}{A string passed to \link{convert_distance} +\item{distance_unit}{A string passed to convert_distance indicating the units of the provided distance.} \item{azimuth_unit}{A string (either \code{degrees} or \code{radians}) From a8979929b2168818b6228eab36d1823af8880429 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Thu, 28 Apr 2022 12:38:14 -0400 Subject: [PATCH 23/37] Don't error when trying to warn --- R/make_manifest.R | 2 +- tests/testthat/test-1-make_manifest.R | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/R/make_manifest.R b/R/make_manifest.R index 3a9982a..280683c 100644 --- a/R/make_manifest.R +++ b/R/make_manifest.R @@ -179,7 +179,7 @@ prep_table <- function(input_raster, side_length, output_prefix, type) { - if (!all.equal(log((side_length - 1), 2), round(log((side_length - 1), 2)))) { + if (!identical(log((side_length - 1), 2), round(log((side_length - 1), 2)))) { warning( "Side lengths must be equal to 2^x + 1 (for x <= 12) for import into Unity.\n", # nolint "Tiles will still be produced but may not be usable." diff --git a/tests/testthat/test-1-make_manifest.R b/tests/testthat/test-1-make_manifest.R index 7c9c4ac..bb4db38 100644 --- a/tests/testthat/test-1-make_manifest.R +++ b/tests/testthat/test-1-make_manifest.R @@ -28,3 +28,16 @@ test_that("make_manifest reproduces the same tiles", { png::readPNG("testdata/manifest_ort.png") ) }) + +test_that("prep_table warns when expected", { + + expect_warning( + prep_table("testdata/3DEP_gr.tif", + 10, + "import", + type = "elevation" + ), + "Side lengths must be equal" + ) + +}) From 4e09c3dc1a0f27a2b0447488ecf59c1a9b9b0ca2 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Thu, 28 Apr 2022 14:49:07 -0400 Subject: [PATCH 24/37] Fix CI, NEWS --- .github/workflows/run-examples.yaml | 1 + NEWS.md | 9 +++++++++ R/make_unity.R | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/.github/workflows/run-examples.yaml b/.github/workflows/run-examples.yaml index 2bf003e..7450fe0 100644 --- a/.github/workflows/run-examples.yaml +++ b/.github/workflows/run-examples.yaml @@ -60,6 +60,7 @@ jobs: - name: Install dependencies run: | + remotes::install_cran("devtools") remotes::install_github("mikemahoney218/unifir") remotes::install_deps(dependencies = TRUE) shell: Rscript {0} diff --git a/NEWS.md b/NEWS.md index a581565..b9a156b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,12 @@ +# terrainr 0.7.0 +* New features: + * `make_unity` is a new function which uses the new `unifir` package to + automatically create Unity scenes, no clicking necessary. +* Improvements and bug fixes: + * `make_manifest`, `transform_elevation`, and `transform_overlay` no longer + error when providing non-standard side lengths; they now warn as intended. + * Fixed some documentation, unused objects, restyled and removed lints + # terrainr 0.6.1 * Improvements and bug fixes: * The README of version 0.6.0 has a disclaimer at the top stating that the diff --git a/R/make_unity.R b/R/make_unity.R index 17c97a9..0a57b42 100644 --- a/R/make_unity.R +++ b/R/make_unity.R @@ -48,7 +48,7 @@ make_unity <- function(project, if (!(side_length %in% 2^(5:12) + 1)) { stop( "side_length must be equal to a value of 2^x + 1, for any x ", - "between 2 and 5." + "between 5 and 12." ) } From f635d4dc6a932397ea91d639cc0acd7a2677f156 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Mon, 2 May 2022 17:02:52 -0400 Subject: [PATCH 25/37] Don't hog _all_ the spotlight now --- inst/CITATION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inst/CITATION b/inst/CITATION index a43ffbc..1ae3224 100644 --- a/inst/CITATION +++ b/inst/CITATION @@ -15,4 +15,4 @@ bibentry(bibtype = "Article", journal = "Journal of Open Source Software", doi = "10.21105/joss.04060", url = "https://doi.org/10.21105/joss.04060", - textVersion = "Mahoney et al., (2022). terrainr: An R package for creating immersive virtual environments. Journal of Open Source Software, 7(69), 4060, https://doi.org/10.21105/joss.04060") + textVersion = "Mahoney M. J., Beier C. M., and Ackerman, A. C. (2022). terrainr: An R package for creating immersive virtual environments. Journal of Open Source Software, 7(69), 4060, https://doi.org/10.21105/joss.04060") From 2ced3670b221fcbfc4960dea3603b393ffd6c301 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Tue, 3 May 2022 10:41:20 -0400 Subject: [PATCH 26/37] Fix CI --- NEWS.md | 3 +++ R/make_manifest.R | 3 ++- R/merge_rasters.R | 7 ++++--- R/raster_to_raw_tiles.R | 3 ++- 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/NEWS.md b/NEWS.md index b9a156b..ee43e04 100644 --- a/NEWS.md +++ b/NEWS.md @@ -5,6 +5,9 @@ * Improvements and bug fixes: * `make_manifest`, `transform_elevation`, and `transform_overlay` no longer error when providing non-standard side lengths; they now warn as intended. + * `make_manifest`, `transform_elevation`, `transform_overlay`, and + `raster_to_raw_tiles` no longer give warnings about nodata values + being clamped to 0. * Fixed some documentation, unused objects, restyled and removed lints # terrainr 0.6.1 diff --git a/R/make_manifest.R b/R/make_manifest.R index 280683c..36a94cb 100644 --- a/R/make_manifest.R +++ b/R/make_manifest.R @@ -261,7 +261,8 @@ convert_to_png <- function(temptiffs, options = c( "-ot", "UInt16", "-of", "png", - "-scale", "0", max_val, "0", "65535" + "-scale", "0", max_val, "0", "65535", + "-a_nodata", "0" ) ) }, diff --git a/R/merge_rasters.R b/R/merge_rasters.R index e493404..6c33729 100644 --- a/R/merge_rasters.R +++ b/R/merge_rasters.R @@ -84,9 +84,10 @@ merge_rasters <- function(input_rasters, merge_rasters_deprecated <- function(input_rasters, output_raster = tempfile(fileext = ".tif"), options = character(0)) { - if (length(options) > 0 || - !(length(options == 1) && options == "-overwrite")) { - warning("Options are not respected when trying to merge rasters with differing numbers of bands") # nolint + if (length(options) > 0) { + if(!(length(options == 1) && options == "-overwrite")) { + warning("Options are not respected when trying to merge rasters with differing numbers of bands") # nolint + } } temp_output <- tempfile(fileext = ".vrt") diff --git a/R/raster_to_raw_tiles.R b/R/raster_to_raw_tiles.R index 125c51b..b86a2b0 100644 --- a/R/raster_to_raw_tiles.R +++ b/R/raster_to_raw_tiles.R @@ -139,7 +139,8 @@ raster_to_raw_tiles <- function(input_file, options = c( "-ot", "UInt16", "-of", "png", - "-scale", "0", max_raster, "0", "65535" + "-scale", "0", max_raster, "0", "65535", + "-a_nodata", "0" ) ) }, From 119f6f0b6e3054885cdaae4fbab6345582248e1c Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Tue, 3 May 2022 11:55:02 -0400 Subject: [PATCH 27/37] Start removing raster:: --- DESCRIPTION | 1 + NAMESPACE | 2 + NEWS.md | 7 +++ R/add_bbox_buffer.R | 52 +++++++++++++++++---- R/georeference_overlay.R | 23 ++++----- R/get_tiles.R | 46 ++++++++++++++---- R/make_manifest.R | 8 ++-- R/vector_to_overlay.R | 22 ++++----- man/addbuff.Rd | 11 +++++ tests/testthat/test-1-make_manifest.R | 2 +- tests/testthat/test-georeference_overlay.R | 18 ++++--- tests/testthat/testdata/manifest_ort.png | Bin 98364 -> 98435 bytes tests/testthat/testdata/vto_poly.png | Bin 2963 -> 2889 bytes 13 files changed, 132 insertions(+), 60 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index d56973b..a880a8e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -30,6 +30,7 @@ Imports: httr, raster, rgdal, + terra, magick (>= 2.5.0), methods, png, diff --git a/NAMESPACE b/NAMESPACE index 2e43718..d18b0fe 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,12 +1,14 @@ # Generated by roxygen2: do not edit by hand S3method(add_bbox_buffer,Raster) +S3method(add_bbox_buffer,SpatRaster) S3method(add_bbox_buffer,sf) S3method(get_tiles,Raster) S3method(get_tiles,list) S3method(get_tiles,sf) S3method(get_tiles,sfc) S3method(set_bbox_side_length,Raster) +S3method(set_bbox_side_length,SpatRaster) S3method(set_bbox_side_length,sf) export(StatSpatialRGB) export(add_bbox_buffer) diff --git a/NEWS.md b/NEWS.md index ee43e04..fa738f0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,13 @@ * New features: * `make_unity` is a new function which uses the new `unifir` package to automatically create Unity scenes, no clicking necessary. + * Internally, all calls to functions from {raster} have been replaced with + calls to {terra}. This future-proofs the package against any coming + deprecations and takes advantage of newer, faster terra code. + This is not intended to be a breaking change; any methods that previously + took {raster} objects should still work (and silently convert to {terra} + under the hood). If you have any workflows impacted by this change, + please file a bug report! * Improvements and bug fixes: * `make_manifest`, `transform_elevation`, and `transform_overlay` no longer error when providing non-standard side lengths; they now warn as intended. diff --git a/R/add_bbox_buffer.R b/R/add_bbox_buffer.R index b0008dd..830f1ea 100644 --- a/R/add_bbox_buffer.R +++ b/R/add_bbox_buffer.R @@ -126,20 +126,38 @@ add_bbox_buffer.Raster <- function(data, distance, distance_unit = "meters", error_crs = NULL) { - bbox <- raster::extent(data) + + data <- terra::rast(data@file@name) + add_bbox_buffer( + data = data, + distance = distance, + distance_unit = distance_unit, + error_crs = error_crs + ) +} + +#' @rdname addbuff +#' @export +add_bbox_buffer.SpatRaster <- function(data, + distance, + distance_unit = "meters", + error_crs = NULL) { + bbox <- terra::ext(data)@ptr$vector data_sf <- data.frame( - lat = c(bbox@ymin, bbox@ymax), - lng = c(bbox@xmin, bbox@xmax) + lat = c(bbox[[3]], bbox[[4]]), + lng = c(bbox[[1]], bbox[[2]]) ) data_sf <- sf::st_as_sf(data_sf, coords = c("lng", "lat")) data_sf <- sf::st_set_crs(data_sf, sf::st_crs(data)) add_bbox_buffer(data_sf, - distance = distance, - distance_unit = distance_unit, - error_crs = error_crs + distance = distance, + distance_unit = distance_unit, + error_crs = error_crs ) } + + #' @rdname addbuff #' @examples #' @@ -193,10 +211,26 @@ set_bbox_side_length.Raster <- function(data, distance, distance_unit = "meters", error_crs = NULL) { - bbox <- raster::extent(data) + data <- terra::rast(data@file@name) + set_bbox_side_length( + data = data, + distance = distance, + distance_unit = distance_unit, + error_crs = error_crs + ) +} + + +#' @rdname addbuff +#' @export +set_bbox_side_length.SpatRaster <- function(data, + distance, + distance_unit = "meters", + error_crs = NULL) { + bbox <- terra::ext(data)@ptr$vector data_sf <- data.frame( - lat = c(bbox@ymin, bbox@ymax), - lng = c(bbox@xmin, bbox@xmax) + lat = c(bbox[[3]], bbox[[4]]), + lng = c(bbox[[1]], bbox[[2]]) ) data_sf <- sf::st_as_sf(data_sf, coords = c("lng", "lat")) data_sf <- sf::st_set_crs(data_sf, sf::st_crs(data)) diff --git a/R/georeference_overlay.R b/R/georeference_overlay.R index fcd469d..a0bc74a 100644 --- a/R/georeference_overlay.R +++ b/R/georeference_overlay.R @@ -9,9 +9,8 @@ #' detected automatically from file extension; options include `jpeg/jpg`, #' `png`, and `tif/tiff`. #' @param reference_raster The raster file to base georeferencing on. The output -#' image will have the same extent and CRS as the reference raster. Accepts both -#' Raster* objects from the `raster` package or a file readable by -#' [raster::raster]. +#' image will have the same extent and CRS as the reference raster. Accepts +#' anything that can be read by [terra::rast] #' @param output_file The path to write the georeferenced image file to. Must #' be a TIFF. #' @@ -50,6 +49,8 @@ georeference_overlay <- function(overlay_file, stopifnot(grepl("tiff?$", output_file)) file_type <- regmatches(overlay_file, regexpr("\\w*$", overlay_file)) + reference_raster <- terra::rast(reference_raster) + official_names <- c( "jpeg" = "jpg", "tiff" = "tif" @@ -72,18 +73,12 @@ georeference_overlay <- function(overlay_file, "jpeg" = jpeg::readJPEG ) - if (is.character(reference_raster) && length(reference_raster) == 1) { - reference_raster <- raster::raster(reference_raster) - } else { - stopifnot(any(grepl("^Raster", class(reference_raster)))) - } - - # Need image_read in order for brick to correctly detect scale + # Need image_read in order for brick to correctly detect scale # otherwise assumes 8bit - overlay_file <- raster::brick(image_read(overlay_file)) - raster::crs(overlay_file) <- reference_raster@crs - raster::extent(overlay_file) <- reference_raster@extent - raster::writeRaster(overlay_file, output_file) + overlay_file <- terra::rast(image_read(overlay_file)) + terra::crs(overlay_file) <- terra::crs(reference_raster) + terra::ext(overlay_file) <- terra::ext(reference_raster) + terra::writeRaster(overlay_file, output_file) return(invisible(output_file)) } diff --git a/R/get_tiles.R b/R/get_tiles.R index 9d8ada5..b5978f9 100644 --- a/R/get_tiles.R +++ b/R/get_tiles.R @@ -4,8 +4,8 @@ #' tiles, and retrieves data from the USGS National map for each tile. As of #' version 0.5.0, the method for lists has been deprecated. #' -#' @param data An `sf` or `Raster` object; tiles will be downloaded for the full -#' extent of the provided object. +#' @param data An `sf` or `SpatRast` object; tiles will be downloaded for the +#' full extent of the provided object. #' @param output_prefix The file prefix to use when saving tiles. #' @param side_length The length, in meters, of each side of tiles to download. #' If \code{NULL}, defaults to the maximum side length permitted by the least @@ -186,6 +186,31 @@ get_tiles.Raster <- function(data, georeference = TRUE, projected = NULL, ...) { + data <- terra::rast(data) + get_tiles.SpatRast(data, + output_prefix = output_prefix, + side_length = side_length, + resolution = resolution, + services = services, + verbose = verbose, + georeference = georeference, + projected = projected, + ...) + +} + + +#' @rdname get_tiles +#' @export +get_tiles.SpatRast <- function(data, + output_prefix = tempfile(), + side_length = NULL, + resolution = 1, + services = "elevation", + verbose = FALSE, + georeference = TRUE, + projected = NULL, + ...) { dots <- list(...) if (is.null(projected)) { projected <- !sf::st_is_longlat(data) @@ -206,10 +231,10 @@ get_tiles.Raster <- function(data, imageSR <- dots[["imageSR"]] } # nolint - data <- raster::extent(data) + data <- as.vector(terra::ext(data)) data <- data.frame( - lng = c(data@xmin, data@xmax), - lat = c(data@ymin, data@ymax) + lng = c(data[[1]], data[[2]]), + lat = c(data[[3]], data[[4]]) ) data <- sf::st_as_sf(data, coords = c("lng", "lat")) data <- sf::st_bbox(data) @@ -229,6 +254,7 @@ get_tiles.Raster <- function(data, ) } + #' @rdname get_tiles #' @export get_tiles.list <- function(data, @@ -403,19 +429,19 @@ get_tiles_internal <- function(data, } if (georeference && services[[k]] != "3DEPElevation") { - cur_raster <- raster::brick(png::readPNG(cur_path)) - cur_raster@crs <- raster::crs(paste0( + cur_raster <- terra::rast(png::readPNG(cur_path)) + terra::crs(cur_raster) <- paste0( "+init=EPSG:", img_bin$extent$spatialReference$wkid - )) - cur_raster@extent <- raster::extent( + ) + terra::ext(cur_raster) <- c( img_bin$extent$xmin, img_bin$extent$xmax, img_bin$extent$ymin, img_bin$extent$ymax ) - raster::writeRaster(cur_raster, + terra::writeRaster(cur_raster, final_path, overwrite = TRUE ) diff --git a/R/make_manifest.R b/R/make_manifest.R index 36a94cb..c7797ef 100644 --- a/R/make_manifest.R +++ b/R/make_manifest.R @@ -185,11 +185,11 @@ prep_table <- function(input_raster, "Tiles will still be produced but may not be usable." ) } - input_raster <- raster::raster(input_raster) - max_raster <- raster::cellStats(input_raster, "max") + input_raster <- terra::rast(input_raster) + max_raster <- max(terra::global(input_raster, "max")) - x_tiles <- ceiling(input_raster@ncols / side_length) - y_tiles <- ceiling(input_raster@nrows / side_length) + x_tiles <- ceiling(terra::ncol(input_raster) / side_length) + y_tiles <- ceiling(terra::nrow(input_raster) / side_length) file_combos <- expand.grid( x = 1:x_tiles, diff --git a/R/vector_to_overlay.R b/R/vector_to_overlay.R index 403488b..31207f1 100644 --- a/R/vector_to_overlay.R +++ b/R/vector_to_overlay.R @@ -9,7 +9,7 @@ #' @param reference_raster The raster file to produce an overlay for. The output #' overlay will have the same extent and resolution as the input raster. Users #' may provide either a Raster* object or a length 1 character -#' vector containing a path to a file readable by [raster::raster]. +#' vector containing a path to a file readable by [terra::rast]. #' @param output_file The path to save the image overlay to. If `NULL`, saves to #' a tempfile. #' @param transparent The hex code for a color to be made transparent in the @@ -71,11 +71,7 @@ vector_to_overlay <- function(vector_data, stopifnot(any(grepl("^sf", class(vector_data)))) } - if (is.character(reference_raster) && length(reference_raster) == 1) { - reference_raster <- raster::raster(reference_raster) - } else { - stopifnot(any(grepl("^Raster", class(reference_raster)))) - } + reference_raster <- terra::rast(reference_raster) if (is.na(sf::st_crs(vector_data))) { if (is.null(error_crs)) { @@ -115,6 +111,8 @@ vector_to_overlay <- function(vector_data, # quiet R CMD check not appreciating ggplot's NSE... X <- Y <- NULL # nolint + extent <- as.vector(terra::ext(reference_raster)) + output_ggplot <- ggplot2::ggplot( vector_data, ggplot2::aes(x = X, y = Y, group = grouping) @@ -123,15 +121,15 @@ vector_to_overlay <- function(vector_data, ggplot2::scale_x_continuous( expand = c(0, 0), limits = c( - reference_raster@extent@xmin, - reference_raster@extent@xmax + extent[[1]], + extent[[2]] ) ) + ggplot2::scale_y_continuous( expand = c(0, 0), limits = c( - reference_raster@extent@ymin, - reference_raster@extent@ymax + extent[[3]], + extent[[4]] ) ) + ggplot2::theme_void() + @@ -150,8 +148,8 @@ vector_to_overlay <- function(vector_data, ggplot2::ggsave( filename = output_file, plot = output_ggplot, - width = reference_raster@ncols / 72, - height = reference_raster@nrows / 72, + width = terra::ncol(reference_raster) / 72, + height = terra::nrow(reference_raster) / 72, units = "in", dpi = "screen", limitsize = FALSE diff --git a/man/addbuff.Rd b/man/addbuff.Rd index 546d07b..a5956af 100644 --- a/man/addbuff.Rd +++ b/man/addbuff.Rd @@ -5,9 +5,11 @@ \alias{add_bbox_buffer} \alias{add_bbox_buffer.sf} \alias{add_bbox_buffer.Raster} +\alias{add_bbox_buffer.SpatRaster} \alias{set_bbox_side_length} \alias{set_bbox_side_length.sf} \alias{set_bbox_side_length.Raster} +\alias{set_bbox_side_length.SpatRaster} \title{Add a uniform buffer around a bounding box for geographic coordinates} \usage{ add_bbox_buffer(data, distance, distance_unit = "meters", error_crs = NULL) @@ -16,6 +18,8 @@ add_bbox_buffer(data, distance, distance_unit = "meters", error_crs = NULL) \method{add_bbox_buffer}{Raster}(data, distance, distance_unit = "meters", error_crs = NULL) +\method{add_bbox_buffer}{SpatRaster}(data, distance, distance_unit = "meters", error_crs = NULL) + set_bbox_side_length( data, distance, @@ -36,6 +40,13 @@ set_bbox_side_length( distance_unit = "meters", error_crs = NULL ) + +\method{set_bbox_side_length}{SpatRaster}( + data, + distance, + distance_unit = "meters", + error_crs = NULL +) } \arguments{ \item{data}{The original data to add a buffer around. Must be either an \code{sf} diff --git a/tests/testthat/test-1-make_manifest.R b/tests/testthat/test-1-make_manifest.R index bb4db38..ba6ecc0 100644 --- a/tests/testthat/test-1-make_manifest.R +++ b/tests/testthat/test-1-make_manifest.R @@ -24,7 +24,7 @@ test_that("make_manifest reproduces the same tiles", { ) expect_equal( - png::readPNG(outputs_table$V8)[, , 1:3], + png::readPNG(outputs_table$V8), png::readPNG("testdata/manifest_ort.png") ) }) diff --git a/tests/testthat/test-georeference_overlay.R b/tests/testthat/test-georeference_overlay.R index 50c98a6..9afeca9 100644 --- a/tests/testthat/test-georeference_overlay.R +++ b/tests/testthat/test-georeference_overlay.R @@ -12,20 +12,18 @@ test_that("georeference_overlay edge cases work", { }) test_that("georeference_overlay produces the same file twice", { - gr_rst <- raster::raster(georeference_overlay( + gr_rst <- terra::rast(georeference_overlay( "testdata/NAIPPlus.png", "testdata/NAIPPlus_gr.tif", tempfile(fileext = ".tif") )) - gr_rst@file@name <- "" - gr_rst@data@names <- "" - - ref_rst <- raster::raster("testdata/NAIPPlus_gr.tif") - ref_rst@file@name <- "" - ref_rst@data@names <- "" - + ref_rst <- terra::rast("testdata/NAIPPlus_gr.tif") + expect_equal( + terra::crs(gr_rst), + terra::crs(ref_rst) + ) expect_equal( - gr_rst, - ref_rst + as.vector(terra::ext(gr_rst)), + as.vector(terra::ext(ref_rst)) ) }) diff --git a/tests/testthat/testdata/manifest_ort.png b/tests/testthat/testdata/manifest_ort.png index 2723b6d6c1abfdd93534d96eb26f019c738a49f2..94b8dc7aab9feb88906e4319f512a7c7f954c418 100644 GIT binary patch delta 578 zcmdnfz}DQzHX)I(B*-tA0Sxk%u}_>BE6w$cm6@GKQ1lx2t;VLQO^nivv0LXc_9cYw z{hi)v#lT?j=kvdn`%iDVd_m<(07r97UZLiaX;FvNT4l02mUVOpY+1NebJm$@2im3u z2&_`=jL9m)_&hxEMX!h7yNVBNTIstoH7d)}>l6Bml> zG*o?ma{17YGust9S{?>ut;yH(F+cM7Ztvgs;`?Oo?~&!?FIsx_)A>(fTduNATqvRU z@8P2tYhUc0sF1O9!mJ%N&!62pFnitax8{C(wQ71=elAt;_!4Hcaa%^VfJ@d~E}#v% zU*G*sc^6w&SZ{19$oc)+qr1M%KcBkf?^&Gr;6{Y1Fz@8UN6-J{znYY38umH_s6l^4 z`OCv!67R>9|NeP#vi|J$Nw-h7pDZc*aeiy>?$?iZvhUWO>QiQDci*NYB5y^h7Ep`c zmE9L-UY~qk`f$nhkksWra}sw(tr1&&)Z@mD*)KeMO?kt*e@jcW!_B=bhJ#zEYP%m!JLFZ=H%fAHWz0`LR zZShEb_h#bsbM=hkQbxK4rn&~kA%=!lhDKI~=DG$ZRt5$SqF(1s{|}T`!!AFOJ@^tR Oop`$XxvXzlvj+konQyOme{(0aN^W9ue7myPtD|nqnI>)&(|6eXdR5)dT~YrkzJFfXdVGG| zb?dNWyH`b@7x^w@dp+Fp+uHnkm&8xU4|mMdFtHK^nqNQb?!up^FHhb4HR$w{^X_+Z znRnl==0E>E{M+2VjtFVHg0<@}ZM_lS8KL{1vF+d#@yea|qZk+%R7+eVN>UO_QmvAU zQh^kMk%5t+u7RblfklX+iIstcm7%G&fq|8QL7MoJUK9+A+254RSRqzFRxLo&ea4Y~^R5H-fv<#j8{yYNfXvIY#{NC{xLDxovDEb;2aq~&C zfW`G+8Nyuvm2qpni#H#o{Ul9;rR86meA3TWFv{e_=~PKb2Q z*K5SNf3Yv$l_bd9!CR$xrkt56A7w&W+im`>s+@*f* zU6VAJF{b|sADui2Edm`jQf$n4*Wu+YdMbN}A~2zu>F_dJd}mljLmG4)@R)h7E!!hf z18K$yv&p+9z$7kD(~#11aq z61@Ey-NXXHQMCB3$FwSjhPkpbu1()kyGU2?l$yCt4yH&aDde5coV=wHPo#h5J7z1H z&<9Ue-9y%dZu>uvPfwskG1ZJjqlvA!{tK$y2S)71LQaR<$%me)lCKduwcX=lSrT!CtX+|0bFM2N z=}XLxRbM2t*-K&7Aqt&w*j#!HCL!D^goBf3X)uQVJBPR@4wkJ~!es-;Ik(JdnRFL~ z;%6BEaWa`PHFa9jdJvbDNx(V;t_m8b`g`R-m`$_HAFE}%$8B21;hx9F#BiO>53>|n zj_X}*V~5C=Z~bw7%vH+8(d}B#LkE-!PxxKbb({zj;=HG=WZdpTg)R6yG?^Uba}=iO zXWMUs8!e*4v`XfOKA9%KRaL`2!#R0)&QQ)>UiVEWrhGVk7~;dG2+|3qy)~rj)S0}z z=K9JcQ~S6N+|0Fgq~t9NkEx6WFdq=*->|3m<|SMxRIe}jAhyqNaAUX0ezs)&cj#nh z{~wze&A8Vh03&s6Y>f0wF^%cuIF~mqrp(Nr6BpKwYVvg$KWO9rqd9tIF1`kPO1;fp zR8cRt+g!b|?%Xs_xP880oM}QngxA#%<(E~yl#Jot5`>*{L-yY~r^6(hwiCioq$FdM zcSwZA$RqCOj8f5b>g>r?(KAwm;RVU@=q{JdU;&YeKSvMq!Qg-k3u>H-exLM5XHM>i*w4R`8+07wG<_ zcc@eHrCjyzg_wkbA-spHwo?D8UEQY-A7IP@6P>ZMfmFZ>>}4KsW%chGB>Q5w{-cQt zG@k-|qWS}-sm>;KXN=|vtw(`Q@3rtAy{z2Ac0YbT#%lUY?JqsR!CDOsn~Uo*>O6|} zRXd-|)e*Gz_1y&d2fLt!*M^p4f5vt2CUKyTj1w6O{e4&BwBtS6S}=PjEei)DT*E;i zH@5LxN=CZ-Nn?O(}$5Z zA-}-bB~f89xf|q6fK%0-x7yqNS%MF z;)G>cfI4a`(M~`i9rBN~u`ExX!>IPoNGv@DF>)MZ1;LWjjn)wi46}kYo^-=o96@4g z@*m`gCsihuldG`Xm^Zkqn0E)3nS!4&nenxl%p6Yf$qS_6Ohkj=EfM-C7W_0JV1U+| z>2iR^eML5F&#yufH6ssk3PyP|OhjGKF1ulqV4~$k)IxOfAjdf4tdOZnB5V-h-PVl~ z#dr(I?^uD_V@DW!m;VbCjo&G@%zuV*K_{GpG=rdU` zw}*L}5APA4xW=146$`mjd`pMHQFL4`aGdLEY4Gf3biWv`S%>OE9vAL|I zKxlhWN+^=SOpy{#E2SV(eTYLbGFW}Q=ZKUeay$J@WA1bCyM+6^tpqkDnoyRNlyBXj zvIgdA(cc5&&z67E+!%42K7r*06bC(YF^%nH$&| zbrxxH{K491lgXqIE=FKmQQT7$nF#u<+UVqIG@cBn=$S>)YTxhJ*$S48bA!XjURh!5 zA9VJ9NSl-_$zt!nYw_NzZ^KBAEA>aIz-F_NiIiu6OllQu3L12w5ti%LB*9VB=*2=K zfaUJfZDd=O7Ay~Z$77~_;9|+Psn>oDlbJZ+&DGbvrNHt{3`5YS9G>>9l#fw`%7rUs zD!g7MzBGv@>9#jTOsknDeS^mz0*ZL?V@CkjnDsrJS;~w9Y>W3xxE^7Lyl{B$09ye+xxPL_t(|ob8=?Y#h}Yz<;x|USE58?bx+ra+*NW90ixQ zDhNm@M~i4d2odN3EdsT)g_fhVAyh??K+rZ))j~OY3sF!3afm>wqz!>^g;0`^*iP)k zj-A9dj_uvGy|#B>|9ES&cJ`RrdA8TP`;(sRot>HQ+xN};-u2CUe~>3no;-Q-fDJeoI1|u;R-g%J)F7ZrPPU@N5CT>Ke+O11IHd#F5A2ElZ3G%LIHE#+ zHelHh0!{}>7v3A{{}8lpi3+f zq-$%8re@#}&;qn*f6y04k0N9y&jU^Y=10@m=P?7s%6J9%sRjoX>wgjgz6e|gd=3Z$ z?*Wf$^1-uw^SJ`V45S_bI|aNf;9UX7EZnPGz-KLIM&dlWNWj(vvO@xHRw3joGh_(W z=_3Jl1^GUfFE#;J3V7du?1+G`TNQXt24teDbfW?TI0SrGf53i|vKtK75dxgRwZJ(@ ze|#8t5qJ$Kw)!J7fDT}Z20^nI3MfGu@^)l>G&KnLynxmO#cCh}o@P~Py~%tj6R=)D zr&ZZTgv}GOa-8W*nvT>jpwd8|R10`8dcG3bMk=U#fieT290^S1FOsCLPhVUW{p^OOdbX65Kp%4p)hL{@) zVHc@gWVVyaH3fiSz@bXuhb|WzYiq|ppBV^ne{(bCBO|Ir%u13PLW5BOTYyVc34GP( z13(voAGWvit>eeBsk-?rCS^ZDz}dhyu%2HLP2-}Ke=7-V8uvFh^QHcNtGCP=40Y%P zJOKPmg}{$XN+^v)m_Ib6;&xesQA0S8Es6T6RVO>>DJbBzvNG26_EI%GZ0H&@Lma08 zJAu+P^~(v4I~;s_=~8;^b{s-*S$8)Vo;bmh!9m=kqY1AwH6J11Cg4%4%4RzUi;KB! z@nYHwe?Oi6_=4Zh!;OszuQ62tYw#HGeA*i32#W^?`P=^e)cgJ8$99*NGO8th?hP42 zK&61Ig)9wcSk^QL@QjY~P*W3Ec69+TXtS}uq$J__ar+U`9`$+1ZvGnN43@Hpk6ghn z1ixr)rD|k^hihus<#e(<7=M&~JadJd-@O6&e=72+*QZ5WlL%mk+s$sLlN*m7#WqWZ zM{cdFLl=UL2a`;X3puNl@$(9e#l>RnvSp&azFz#-`?x)7}C?Tu>$kgcYr)2os>77PxK8v$T#XD8ky9ivR;lY#*ez9Zp-&_#57Sm3knPmq^V-iW@Ed@!4FuuXI%>lQ6y zcV{Ozx3^OiiA?zJL#LB{B_&+b*_l*^9k>Vhvtr#@Ixql0@g&94p}FYOdHOfJe_mE3 z=oG0WpzCalX8sPhn~*KB7Z<=&m6dGr`8cn)m)cN>0h^6oE*A%iig;nqo|N+J8vI4T zV&HBRww}h+K3rIs^t@Cw7Z{DHX$-#%7<7*UQRy*X?E`$=Fal zdhB+duc(-C?3N=(aHnuf5UnFLf4E1$2f%ZtBqyPxlbe;7J7xGABBf6qqwO`ly*PJ;#U0F%D!OGVNRl~!qjgB>?BDTDBs8S#Tyi#5c z$jp3T-aO1YsMf+lesJok>@Gcd`eT>V$>Y`4mi0X9aImqqmP=Qx;16@>e=0Qs!1p^k za2RyWv8|@$wTTI~mX*;GDua`|eAMd!`rXLWa)C~@DX-|*g^C$dLAtTvNx1xXm zzPWTMjd6y2OT%H#>+NO1f6x%4n#P{eQr>pElV*4_d?O?LW8Xe1Q@Fihn~m*mH=BGu zwtGAbC#iTj8c|6=!S7+rGrl<{txUZ#!Ws_P`VNK&*my6eY zKDK(j1oi0~OkOZF#It+%nrit>=+J5KtdKFDm!_-4lL~yd8IBYde{%ilr&I6uvnmjv zFcP7)sE9W`9(wFk)?ZCZz29%T`8lp>G|u%`$l%+w*x`1wH%{d`)kJ{zTrS>oxu#uq zJW}>-?_P-0yaZA8tBxGl>#Me zWlU!iaW?SGoH<;ve7T`>#|*Jeh2Zxyq}7s1bQTmC>adO(;#uH;6@ed>ma;Q%h`1P; z%CZ4y5CX2i!fRTa%F8WJi)Jff6D0yoF5z;ldwjUjPe2sRu##5WX7jby)7XmA|4;!0W# zqU(+wK+&8ktR4c1@aG5M`4p zg#fT*F8iX9fa1($tjne+BSt!gBK!#>b$p$NH-d6Id1u z^2eqo%5uOMs!9YJ{1f=ORfQ&V+Q0yhH#DRS5S#5-t|Ma6;6dPFD+8e{vbl9l*jg^h$_tWQ4~X8aPl~j9=FY*zNdreL_0vSoCuy_t}k`H$kzWqHj^f2=)4>@I;|zyM zHw1dvW}{!%>5rDO*uVX{PRM2(KPUFM-)^VJe{N6u)Eg-gDmL=C8hDCncxO9P5ir3` zPA-LK_4l(RMct=rkDKe5PTqo@_;#U)SWW zS!W?P_eg{Q@*(4Kn3Cz_=o(OKkxP`GKrU4J0Amr-(FE9lQf2F}NvUT_za!*waxp$uv z=tsUDH`%=gfbGCrv)T{i|9SG{ l$&)8fo;-Q- Date: Tue, 3 May 2022 13:13:19 -0400 Subject: [PATCH 28/37] Remove raster from core code (#45) --- DESCRIPTION | 66 +++++----- NAMESPACE | 1 + NEWS.md | 13 +- R/add_bbox_buffer.R | 7 +- R/geom_spatial_rgb.R | 80 +++++++++--- R/get_tiles.R | 25 ++-- R/raster_to_raw_tiles.R | 137 ++------------------ man/geom_spatial_rgb.Rd | 8 +- man/georeference_overlay.Rd | 5 +- man/get_tiles.Rd | 17 ++- man/vector_to_overlay.Rd | 2 +- tests/testthat/test-1-raster_to_raw_tiles.R | 2 +- tests/testthat/test-geom_spatial_rgb.R | 42 +++--- tests/testthat/test-get_tiles.R | 9 +- tests/testthat/testdata/raster_to_raw_1.png | Bin 99283 -> 99419 bytes 15 files changed, 188 insertions(+), 226 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a880a8e..3a170e5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,56 +1,52 @@ -Package: terrainr Type: Package +Package: terrainr Title: Landscape Visualizations in R and 'Unity' Version: 0.7.0 Authors@R: c( - person(given = "Michael", - family = "Mahoney", - role = c("aut", "cre"), - email = "mike.mahoney.218@gmail.com", + person("Michael", "Mahoney", , "mike.mahoney.218@gmail.com", role = c("aut", "cre"), comment = c(ORCID = "0000-0003-2402-304X")), - person(given = "Mike", - family = "Johnson", - role = c("rev"), - comment = c("Mike reviewed the package (v. 0.2.1) for rOpenSci, see ")), - person(given = "Sydney", - family = "Foks", - role = c("rev"), - comment = c("Sydney reviewed the package (v. 0.2.1) for rOpenSci, see "))) -Description: Functions for the retrieval, manipulation, and visualization of - 'geospatial' data, with an aim towards producing '3D' landscape - visualizations in the 'Unity' '3D' rendering engine. Functions are also - provided for retrieving elevation data and base map tiles from the 'USGS' - National Map . -URL: https://docs.ropensci.org/terrainr/, https://github.com/ropensci/terrainr -BugReports: https://github.com/ropensci/terrainr/issues + person("Mike", "Johnson", role = "rev", + comment = "Mike reviewed the package (v. 0.2.1) for rOpenSci, see "), + person("Sydney", "Foks", role = "rev", + comment = "Sydney reviewed the package (v. 0.2.1) for rOpenSci, see ") + ) +Description: Functions for the retrieval, manipulation, and visualization + of 'geospatial' data, with an aim towards producing '3D' landscape + visualizations in the 'Unity' '3D' rendering engine. Functions are + also provided for retrieving elevation data and base map tiles from + the 'USGS' National Map . License: MIT + file LICENSE -Encoding: UTF-8 +URL: https://docs.ropensci.org/terrainr/, + https://github.com/ropensci/terrainr +BugReports: https://github.com/ropensci/terrainr/issues Imports: base64enc, + ggplot2, + grDevices, httr, - raster, - rgdal, - terra, magick (>= 2.5.0), methods, png, sf (>= 1.0-5), - units, - grDevices, - ggplot2 -RoxygenNote: 7.1.2 + terra, + units Suggests: - testthat, + brio, covr, - progressr, + jpeg, knitr, - rmarkdown, progress, - jpeg, + progressr, + raster, + rgdal, + rmarkdown, + testthat, tiff, - brio, unifir -Config/testthat/parallel: true +VignetteBuilder: + knitr Config/testthat/edition: 3 -VignetteBuilder: knitr +Config/testthat/parallel: true +Encoding: UTF-8 Roxygen: list(markdown = TRUE) +RoxygenNote: 7.1.2 diff --git a/NAMESPACE b/NAMESPACE index d18b0fe..8f037aa 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,6 +4,7 @@ S3method(add_bbox_buffer,Raster) S3method(add_bbox_buffer,SpatRaster) S3method(add_bbox_buffer,sf) S3method(get_tiles,Raster) +S3method(get_tiles,SpatRaster) S3method(get_tiles,list) S3method(get_tiles,sf) S3method(get_tiles,sfc) diff --git a/NEWS.md b/NEWS.md index fa738f0..89954ba 100644 --- a/NEWS.md +++ b/NEWS.md @@ -12,10 +12,17 @@ * Improvements and bug fixes: * `make_manifest`, `transform_elevation`, and `transform_overlay` no longer error when providing non-standard side lengths; they now warn as intended. - * `make_manifest`, `transform_elevation`, `transform_overlay`, and - `raster_to_raw_tiles` no longer give warnings about nodata values + * `make_manifest`, `transform_elevation`, and `transform_overlay` + should no longer give warnings about nodata values in most cases. being clamped to 0. - * Fixed some documentation, unused objects, restyled and removed lints + * Fixed some documentation, unused objects, restyled and removed lints. +* Dependency changes: + * `terra` is now included as an Import (had been recursively imported + through `raster` previously). + * `raster` and `rgdal` are now in Suggests (used temporarily in + `Raster*` methods for `get_tiles` and `add_bbox_buffer`, until the new + version of `raster` hits CRAN + # terrainr 0.6.1 * Improvements and bug fixes: diff --git a/R/add_bbox_buffer.R b/R/add_bbox_buffer.R index 830f1ea..1c72e79 100644 --- a/R/add_bbox_buffer.R +++ b/R/add_bbox_buffer.R @@ -126,8 +126,9 @@ add_bbox_buffer.Raster <- function(data, distance, distance_unit = "meters", error_crs = NULL) { - - data <- terra::rast(data@file@name) + tmp <- tempfile(fileext = ".tiff") + raster::writeRaster(data, tmp) + data <- terra::rast(tmp) add_bbox_buffer( data = data, distance = distance, @@ -142,7 +143,7 @@ add_bbox_buffer.SpatRaster <- function(data, distance, distance_unit = "meters", error_crs = NULL) { - bbox <- terra::ext(data)@ptr$vector + bbox <- as.vector(terra::ext(data)) data_sf <- data.frame( lat = c(bbox[[3]], bbox[[4]]), lng = c(bbox[[1]], bbox[[2]]) diff --git a/R/geom_spatial_rgb.R b/R/geom_spatial_rgb.R index 5664dd6..5b3c793 100644 --- a/R/geom_spatial_rgb.R +++ b/R/geom_spatial_rgb.R @@ -11,12 +11,12 @@ #' options described in [ggplot2::geom_raster], there are two additional #' methods: #' -#' If a `RasterStack` object (see [raster::stack]), this function will coerce -#' the stack to a data frame and assume the raster bands are in RGB order +#' If a `SpatRaster` object (see [terra::rast]), this function will coerce +#' the raster to a data frame and assume the raster bands are in RGB order #' (while allowing for, but ignoring, a fourth alpha band). #' #' If a length-1 character vector, this function will attempt to load the object -#' via [raster::stack]. +#' via [terra::rast]. #' #' @inheritParams ggplot2::geom_raster #' @param scale Integer. Maximum (possible) value in the three channels. @@ -45,7 +45,7 @@ #' merged_ortho <- tempfile(fileext = ".tif") #' merge_rasters(output_tiles[["ortho"]], merged_ortho) #' -#' merged_stack <- raster::stack(merged_ortho) +#' merged_stack <- terra::rast(merged_ortho) #' #' library(ggplot2) #' @@ -142,8 +142,8 @@ geom_spatial_rgb_internal.character <- function(data = NULL, inherit.aes = TRUE, scale = NULL) { stopifnot(length(data) == 1) - data <- raster::stack(data) - geom_spatial_rgb_internal.RasterStack( + data <- terra::rast(data) + geom_spatial_rgb_internal.SpatRaster( data = data, mapping = mapping, stat = stat, @@ -168,13 +168,41 @@ geom_spatial_rgb_internal.RasterStack <- function(data = NULL, show.legend = NA, inherit.aes = TRUE, scale = NULL) { - data <- raster::as.data.frame(data, xy = TRUE) - if (ncol(data) == 5) { + data <- terra::rast(data) + geom_spatial_rgb_internal( + data = data, + mapping = mapping, + stat = stat, + position = position, + na.rm = na.rm, + show.legend = show.legend, + inherit.aes = inherit.aes, + scale = scale, + ... + ) +} + +geom_spatial_rgb_internal.SpatRaster <- function(data = NULL, + mapping = NULL, + stat = "spatialRGB", + position = "identity", + ..., + hjust = 0.5, + vjust = 0.5, + interpolate = FALSE, + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE, + scale = NULL) { + data <- terra::as.data.frame(data, xy = TRUE) + if (terra::ncol(data) == 5) { data <- stats::setNames(data, c("x", "y", "red", "green", "blue")) - } else if (ncol(data) == 6) { + } else if (terra::ncol(data) == 6) { data <- stats::setNames(data, c("x", "y", "red", "green", "blue", "alpha")) } else { - stop("Can't assume band values from ", ncol(data) - 2, " band raster.") + stop("Can't assume band values from ", + terra::ncol(data) - 2, + " band raster.") } geom_spatial_rgb_internal( @@ -302,8 +330,8 @@ stat_spatial_rgb_internal.character <- function(data = NULL, scale = NULL, ...) { stopifnot(length(data) == 1) - data <- raster::stack(data) - stat_spatial_rgb_internal.RasterStack( + data <- terra::rast(data) + stat_spatial_rgb_internal.SpatRaster( data = data, mapping = mapping, geom = geom, @@ -325,13 +353,33 @@ stat_spatial_rgb_internal.RasterStack <- function(data = NULL, inherit.aes = TRUE, scale = NULL, ...) { - data <- raster::as.data.frame(data, xy = TRUE) - if (ncol(data) == 5) { + data <- terra::rast(data) + stat_spatial_rgb_internal( + data = data, mapping = mapping, geom = geom, + position = position, na.rm = na.rm, + show.legend = show.legend, inherit.aes = inherit.aes, + scale = scale, ... + ) +} + +stat_spatial_rgb_internal.SpatRaster <- function(data = NULL, + mapping = NULL, + geom = "raster", + position = "identity", + na.rm = FALSE, + show.legend = FALSE, + inherit.aes = TRUE, + scale = NULL, + ...) { + data <- terra::as.data.frame(data, xy = TRUE) + if (terra::ncol(data) == 5) { data <- stats::setNames(data, c("x", "y", "red", "green", "blue")) - } else if (ncol(data) == 6) { + } else if (terra::ncol(data) == 6) { data <- stats::setNames(data, c("x", "y", "red", "green", "blue", "alpha")) } else { - stop("Can't assume band values from ", ncol(data) - 2, " band raster.") + stop("Can't assume band values from ", + terra::ncol(data) - 2, + " band raster.") } stat_spatial_rgb_internal( diff --git a/R/get_tiles.R b/R/get_tiles.R index b5978f9..49b5260 100644 --- a/R/get_tiles.R +++ b/R/get_tiles.R @@ -186,23 +186,24 @@ get_tiles.Raster <- function(data, georeference = TRUE, projected = NULL, ...) { - data <- terra::rast(data) - get_tiles.SpatRast(data, - output_prefix = output_prefix, - side_length = side_length, - resolution = resolution, - services = services, - verbose = verbose, - georeference = georeference, - projected = projected, - ...) - + tmp <- tempfile(fileext = ".tiff") + raster::writeRaster(data, tmp) + data <- terra::rast(tmp) + get_tiles.SpatRaster(data, + output_prefix = output_prefix, + side_length = side_length, + resolution = resolution, + services = services, + verbose = verbose, + georeference = georeference, + projected = projected, + ...) } #' @rdname get_tiles #' @export -get_tiles.SpatRast <- function(data, +get_tiles.SpatRaster <- function(data, output_prefix = tempfile(), side_length = NULL, resolution = 1, diff --git a/R/raster_to_raw_tiles.R b/R/raster_to_raw_tiles.R index b86a2b0..86da13e 100644 --- a/R/raster_to_raw_tiles.R +++ b/R/raster_to_raw_tiles.R @@ -44,143 +44,22 @@ raster_to_raw_tiles <- function(input_file, side_length = 4097, raw = TRUE) { .Deprecated( - "make_manifest", + "transform_elevation", "terrainr", msg = paste("'raster_to_raw_tiles' is deprecated as of terrainr 0.5.0.", - "Use 'make_manifest' instead.", + "Use 'transform_elevation' instead.", sep = "\n" ) ) - input_raster <- raster::raster(input_file) - max_raster <- raster::cellStats(input_raster, "max") - - x_tiles <- ceiling(input_raster@ncols / side_length) - y_tiles <- ceiling(input_raster@nrows / side_length) - if (requireNamespace("progressr", quietly = TRUE)) { # nocov start - p <- progressr::progressor(steps = x_tiles * y_tiles * 3) - } # nocov end - - temptiffs <- NULL - while (length(temptiffs) != x_tiles * y_tiles) { - temptiffs <- unique(vapply( - 1:(x_tiles * y_tiles), - function(x) tempfile(fileext = ".tiff"), - character(1) - )) - } - - x_tiles <- 0:(x_tiles - 1) - x_tiles <- (x_tiles * side_length) - - y_tiles <- 0:(y_tiles - 1) - y_tiles <- (y_tiles * side_length) - - - counter <- 1 - - for (i in seq_along(x_tiles)) { - for (j in seq_along(y_tiles)) { - if (requireNamespace("progressr", quietly = TRUE)) { # nocov start - p(message = sprintf( - "Cropping tile (%d,%d)", - x_tiles[[i]], - y_tiles[[j]] - )) - } # nocov end - sf::gdal_utils( - "translate", - input_file, - temptiffs[[counter]], - options = c( - "-srcwin", - x_tiles[[i]], - y_tiles[[j]], - side_length, - side_length - ) - ) - names(temptiffs)[[counter]] <- paste0( - output_prefix, - "_", - i, - "_", - j, - ifelse(raw, ".raw", ".png") - ) - counter <- counter + 1 - } - } - - temppngs <- NULL if (raw) { - while (length(temppngs) != length(temptiffs)) { - temppngs <- unique(vapply( - seq_along(temptiffs), - function(x) tempfile(fileext = ".png"), - character(1) - )) - } + transform_elevation(heightmap = input_file, + side_length = side_length, + output_prefix = output_prefix) } else { - temppngs <- names(temptiffs) + transform_overlay(overlay = input_file, + side_length = side_length, + output_prefix = output_prefix) } - names(temppngs) <- names(temptiffs) - - mapply( - function(x, y) { - if (requireNamespace("progressr", quietly = TRUE)) { # nocov start - p(message = sprintf("Converting tile %s to PNG", x)) - } # nocov end - sf::gdal_utils( - "translate", - source = x, - destination = y, - options = c( - "-ot", "UInt16", - "-of", "png", - "-scale", "0", max_raster, "0", "65535", - "-a_nodata", "0" - ) - ) - }, - temptiffs, - temppngs - ) - - unlink(temptiffs) - - mapply( - function(x, y) { - processing_image <- magick::image_read(x) - - if (requireNamespace("progressr", quietly = TRUE)) { # nocov start - if (raw) { - p(message = sprintf("Converting tile %s to RAW", x)) - } else { - p(message = sprintf("Flipping tile %s for Unity", x)) - } - } # nocov end - - if (raw) { - processing_image <- magick::image_flop(processing_image) - processing_image <- magick::image_convert(processing_image, - format = "RGB", - depth = 16, - interlace = "Plane" - ) - } else { - processing_image <- magick::image_flip(processing_image) - processing_image <- magick::image_flop(processing_image) - } - - magick::image_write(processing_image, y) - }, - temppngs, - names(temppngs) - ) - - if (raw) unlink(temppngs) - - return(invisible(names(temppngs))) } diff --git a/man/geom_spatial_rgb.Rd b/man/geom_spatial_rgb.Rd index a185a6b..c734d2f 100644 --- a/man/geom_spatial_rgb.Rd +++ b/man/geom_spatial_rgb.Rd @@ -44,12 +44,12 @@ plot. You must supply \code{mapping} if there is no plot mapping.} options described in \link[ggplot2:geom_tile]{ggplot2::geom_raster}, there are two additional methods: -If a \code{RasterStack} object (see \link[raster:stack]{raster::stack}), this function will coerce -the stack to a data frame and assume the raster bands are in RGB order +If a \code{SpatRaster} object (see \link[terra:rast]{terra::rast}), this function will coerce +the raster to a data frame and assume the raster bands are in RGB order (while allowing for, but ignoring, a fourth alpha band). If a length-1 character vector, this function will attempt to load the object -via \link[raster:stack]{raster::stack}.} +via \link[terra:rast]{terra::rast}.} \item{stat}{The statistical transformation to use on the data for this layer, as a string.} @@ -120,7 +120,7 @@ output_tiles <- get_tiles(simulated_data, merged_ortho <- tempfile(fileext = ".tif") merge_rasters(output_tiles[["ortho"]], merged_ortho) -merged_stack <- raster::stack(merged_ortho) +merged_stack <- terra::rast(merged_ortho) library(ggplot2) diff --git a/man/georeference_overlay.Rd b/man/georeference_overlay.Rd index f73ce8d..9f9fa53 100644 --- a/man/georeference_overlay.Rd +++ b/man/georeference_overlay.Rd @@ -16,9 +16,8 @@ detected automatically from file extension; options include \code{jpeg/jpg}, \code{png}, and \code{tif/tiff}.} \item{reference_raster}{The raster file to base georeferencing on. The output -image will have the same extent and CRS as the reference raster. Accepts both -Raster* objects from the \code{raster} package or a file readable by -\link[raster:raster]{raster::raster}.} +image will have the same extent and CRS as the reference raster. Accepts +anything that can be read by \link[terra:rast]{terra::rast}} \item{output_file}{The path to write the georeferenced image file to. Must be a TIFF.} diff --git a/man/get_tiles.Rd b/man/get_tiles.Rd index 82c95ed..c3191a3 100644 --- a/man/get_tiles.Rd +++ b/man/get_tiles.Rd @@ -5,6 +5,7 @@ \alias{get_tiles.sf} \alias{get_tiles.sfc} \alias{get_tiles.Raster} +\alias{get_tiles.SpatRaster} \alias{get_tiles.list} \title{A user-friendly way to get USGS National Map data tiles for an area} \usage{ @@ -56,6 +57,18 @@ get_tiles( ... ) +\method{get_tiles}{SpatRaster}( + data, + output_prefix = tempfile(), + side_length = NULL, + resolution = 1, + services = "elevation", + verbose = FALSE, + georeference = TRUE, + projected = NULL, + ... +) + \method{get_tiles}{list}( data, output_prefix = tempfile(), @@ -69,8 +82,8 @@ get_tiles( ) } \arguments{ -\item{data}{An \code{sf} or \code{Raster} object; tiles will be downloaded for the full -extent of the provided object.} +\item{data}{An \code{sf} or \code{SpatRast} object; tiles will be downloaded for the +full extent of the provided object.} \item{output_prefix}{The file prefix to use when saving tiles.} diff --git a/man/vector_to_overlay.Rd b/man/vector_to_overlay.Rd index ad10d7c..b0845da 100644 --- a/man/vector_to_overlay.Rd +++ b/man/vector_to_overlay.Rd @@ -21,7 +21,7 @@ character vector containing a path to a file readable by \link[sf:st_read]{sf::r \item{reference_raster}{The raster file to produce an overlay for. The output overlay will have the same extent and resolution as the input raster. Users may provide either a Raster* object or a length 1 character -vector containing a path to a file readable by \link[raster:raster]{raster::raster}.} +vector containing a path to a file readable by \link[terra:rast]{terra::rast}.} \item{output_file}{The path to save the image overlay to. If \code{NULL}, saves to a tempfile.} diff --git a/tests/testthat/test-1-raster_to_raw_tiles.R b/tests/testthat/test-1-raster_to_raw_tiles.R index 38f10fd..406c594 100644 --- a/tests/testthat/test-1-raster_to_raw_tiles.R +++ b/tests/testthat/test-1-raster_to_raw_tiles.R @@ -27,7 +27,7 @@ test_that("raster_to_raw warns about deprecation", { ) expect_equal( - png::readPNG(outputs[[1]])[, , 1:3], + png::readPNG(outputs[[1]]), png::readPNG("testdata/raster_to_raw_1.png") ) }) diff --git a/tests/testthat/test-geom_spatial_rgb.R b/tests/testthat/test-geom_spatial_rgb.R index 502d13e..3342c55 100644 --- a/tests/testthat/test-geom_spatial_rgb.R +++ b/tests/testthat/test-geom_spatial_rgb.R @@ -108,28 +108,40 @@ test_that("all methods of geom_spatial_rgb are equivalent", { ggplot2::geom_sf(data = simulated_data) ggplot2::ggsave(plots[[6]]) - expect_identical( - brio::read_file_raw(plots[[1]]), - brio::read_file_raw(plots[[2]]), + agreement <- sum( + (png::readPNG(plots[[1]]) == png::readPNG(plots[[2]])) / + length(png::readPNG(plots[[1]])) ) - expect_identical( - brio::read_file_raw(plots[[3]]), - brio::read_file_raw(plots[[4]]), + expect_true( + agreement > 0.95 ) - expect_identical( - brio::read_file_raw(plots[[5]]), - brio::read_file_raw(plots[[6]]), + agreement <- sum( + (png::readPNG(plots[[3]]) == png::readPNG(plots[[4]])) / + length(png::readPNG(plots[[1]])) ) - expect_identical( - brio::read_file_raw(plots[[2]]), - brio::read_file_raw(plots[[3]]), + expect_true( + agreement > 0.95 ) - expect_identical( - brio::read_file_raw(plots[[1]]), - brio::read_file_raw(plots[[6]]), + agreement <- sum( + (png::readPNG(plots[[5]]) == png::readPNG(plots[[6]])) / + length(png::readPNG(plots[[6]])) ) + + expect_true( + agreement > 0.95 + ) + + agreement <- sum( + (png::readPNG(plots[[1]]) == png::readPNG(plots[[6]])) / + length(png::readPNG(plots[[1]])) + ) + + expect_true( + agreement > 0.95 + ) + }) diff --git a/tests/testthat/test-get_tiles.R b/tests/testthat/test-get_tiles.R index b8ea44b..62db41d 100644 --- a/tests/testthat/test-get_tiles.R +++ b/tests/testthat/test-get_tiles.R @@ -11,9 +11,14 @@ test_that("raster method is consistent", { test_that("warnings fire appropriately", { skip_on_cran() - tmp_raster <- raster::raster("testdata/merge_rasters_test.tif") + tmp_raster <- terra::rast("testdata/merge_rasters_test.tif") + terra::crs(tmp_raster) <- NA expect_warning( - get_tiles(tmp_raster) + expect_warning( + get_tiles(tmp_raster), + "Assuming geographic CRS" + ), + "Assuming CRS of" ) }) diff --git a/tests/testthat/testdata/raster_to_raw_1.png b/tests/testthat/testdata/raster_to_raw_1.png index e8e8804698618c58f4b012085e5157140df7e328..19f641fde832ad0cd8cbddbe6d8aac219308aef0 100644 GIT binary patch delta 1623 zcmZuyeN@s18?Ci8HPRCqHD|1R`%;PDQ2fBq?92Q_Q~ZpmlwA2Dm0%$VrKuTdSsF*T zR5T!G+8F6l#LlWWrcOz*&@fC%O&oH-i3%vQ`fKOB_n+sld(J)gx%YWw1y+h{R<};B zBOi^3Uhx^}JnNDYoRjVN>Qy$Yz0xl4(qGAG%2`=|fyp?Y(BSA=Rp8X+T`$T&>x&L-jLK}@ zdYE@|?b>UO35wasEMK&|ays1I*WOG&{=3#>%Mft1POHt(tFGu0&L+I8O2S0z9Zj$WBu}qKL4tv8R4jEPG!I_qr z`+ZT%!jmF5<4n+DCX+s`O~%{^aGVNe*3FMLHK?+|;R{P?NvXGcVT1Nv6E)19MPN-? zJ8DKqZ+voUN4ch`a?O71*dJ~Jp+LAm|4{axzd(P2UX#a$sJr;JWyN2Wa5lzX?z~1W zm2nO}+=+MAo>6W=9mU@m4++wf!fu@AT@ZtFWrE508t$I;(6|b$Lm$&f0gQ z2Z3+esi;IB1iOMkrvo!#yRrUpo6MM7Vi&xI9mQDrP2vMPDZ~87rQsS;&4ICu$!GJ; zh0|EckFm{^1}%osGRBR}AZP5-F=ni@cV_0TXL*&1?&6L|g>2*-?VfgeN|Y>qT0!dF z@hTguMypA2^gBWKSW%!u9eKmDF~pd|6LVYIDYC-8)^oHORpHIEu`oa8tecAqTNz@R zmYLvJum6?;6=&++2xzfGhM6gCk~vE@{js;B!J{Y;uZWIdZeXVU& z(j~f|uT)?`>+zMZR;*aHJNRH=On@!+bA%FHlYfXd&bq+i_f_bo=U`fBU1W_SPAq`cjBh{Y(NQ~l#1nu#Ik!@JLtn!^tUkXC_F}@ z$LSVF3>8bydftaQv^|}ACS(s+VjS%;O?QjkslU$t-b++vm)!Ix-3yMWT>C{k&Q-;6 zGcnM>tAThSpPoKe-0a-YGG)0v`Ox`zR<%z|z+3$>hkmgPsGy*&-rr=-lbXl?DniIHAK|oYx?A+;4a&MY$XD5H6 zbz+)jKEKq!4Q20@KNblDOEH>voRFZE%R$BOBeWSidS8?Bdm1bsK635-oqfe7RS;zO z_2Ub{%q~*BwYs=K;o>}E7;Eat?Z_P&|MO*e3U%8YnI}YERDkL+1knrzVhxYOXD91N z3rKi0RddQ*_YtkD{IY|%>Z8|#Y!7Jou|t=h2RssO-Bj-DMLoG=v(~03#i}##ajhZp zd3<|XW;o9yz%lGYtBVFn%juubZ%LL3^f9{~H&@W^_s99OamZz`G5HZM`P<4OKGlr5 zT(in2js1GM$y+WS^3u<~SmpM#>5NX%kqd)|Lm++Svm=Icv;{JUVa)5eBkNtTwv|fx z>UP}hoqR#Q;O!!)He3X@cO=+sTLG z$tfqv1XS_`!tz*w01yZm7C^!PkC^X0PyiBz^n?MPC;-@KC^r3zK_sP|IZge-_CvyG)u$DC3 delta 1451 zcmV;c1yuUmhz8S#29RNqa~BHa3J?z*G?zD0-+`31lmV+?WBd7S^Df{x{&k$BiJdfU z{WM+I#@j&R@m7J>U8s0=;L^(^`rMGhBo6jz(m3LZ8xsdK3vtRdMgpYnh|K{cxX}j* zBs7g5T0F+ank`$~$4Qzrc78eLpFr|quh(DjdH)3;v9a$P1^y2TlOB<=7*mt+^ZTEC z>-XzPRL#CwKi&wTpFZt|Fo?%l2&LXx7Q$ld*PUNvzf2ysH}5{|l`G{+rTKEW)Lf3A z%a&`G^J*4#7Sj3k^R1cuVsbgZo=#6X3X!oFOeW)NwQBZ!7*s+S#)qvCM%{xvgi$=s zLl`s*^$?EJTK87t>#d6$EBUqLsJ$D8^+M%o62f%nTr^udOwOX2d_Q{7d>rj$qe`je z29dEBP=GI~sU(Dx%0YHm->RLg@7*nQ_Oj8PK|D(5+96p?m$FiHBYSb; zhEI|&8b_@U!)Eg=oX^T}A-SAi2s7E`bh1ZVg^j|bqmi)}QD8E@65MJLgP&~I(G9#(AR*EWiSuz8ex+TALD@!)!A>78o%rPXVL7n7HgEB993{Iv6a;~%TjYtw7RwHK<- z_E!4S-LQT#C{)j7GyOt!YIU3q-+A)tc6la0O~={vq@$6s7gb;~ip>y)jlE6?&vvdx z&(yz~eN_K<^nT;B+P^yg%rA%K_+s>G`r5{=^+IxVKXi`TpEtL=;}CjN&8c|4JD)!j zUu!PM7sAW&t;SaTS-uq)CLINlu@_yF@w@tX{I|EqSqSCm;YJ9Bvq9XKOpdLumj20<%d(K~&{v)H)ZRi>Euq&PlZ2d6JxE^X>DkspNcXA$>3T zd-E^tr=39@LUGbjk+Bz7Fd5&S|55ezL2+34@!sn6&8gL+>e9VIDY|*(_VD)d51zYs zRJ{jhP3?KFKwLfQDrOmag?W@Vko3Au)bZ%CsCmjWmu@_I1QLa4djamnJ zAvx|HwFlWwK5T~QwAD|>z2n|#cAD-q2c6ld9F=?HcBoCY3(2T)BYh#cQoER(^!oAV z>-~0!qHtwnE?vwQ(_&tnbQF=X7gtQi&u;!C`e{A9wLciW`EmBAwce|PZ0`?+^|ScN zA5YW%yZeJ-RvgS%%h7gecXQ|V<0wz_wdK}2C? zSl_!_>V>dX+wbm%o$P4+xOb4B-Wjz9@lLjr?Iro0ooss2Ns+M^T`(EH>fUSo_U`MI zH(K9$do{h2eLwqnW1Q`V_ga7Lyqk@)-EiF73!iU1j`lktjJk8lrDUOVDa<5ijq~>_ zwM**&BFfB1KEipD!F*Q0eI65^l zD=;uRFfgeoOAePFgaH>OFfB1KEipD!F*Q0eI65^lD=;uRFfiD4^RfT{002ovPDHLk FV1g>615E$` From acf613504dc74ca95bb5d19adff1f06c72858cfb Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Tue, 3 May 2022 13:40:18 -0400 Subject: [PATCH 29/37] Remove raster:: from tests --- NEWS.md | 8 +++-- tests/testthat/test-1-raster_to_raw_tiles.R | 33 ----------------- tests/testthat/test-2-get_tiles_3dep.R | 14 ++++---- tests/testthat/test-4-merge_rasters.R | 34 +++++++++++------- tests/testthat/test-add_bbox_buffer.R | 2 +- tests/testthat/test-geom_spatial_rgb.R | 4 +-- tests/testthat/test-get_tiles.R | 39 ++++++++++++--------- 7 files changed, 60 insertions(+), 74 deletions(-) delete mode 100644 tests/testthat/test-1-raster_to_raw_tiles.R diff --git a/NEWS.md b/NEWS.md index 89954ba..686a3b0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,8 +21,12 @@ through `raster` previously). * `raster` and `rgdal` are now in Suggests (used temporarily in `Raster*` methods for `get_tiles` and `add_bbox_buffer`, until the new - version of `raster` hits CRAN - + version of `raster` hits CRAN). +* Internal changes: + * `raster_to_raw_tiles` is now a thin wrapper around the functions + `transform_overlay` and `transform_elevation`. It is no longer tested; + it will be removed entirely in the next release (see deprecation notice + in terrainr 0.5.0). # terrainr 0.6.1 * Improvements and bug fixes: diff --git a/tests/testthat/test-1-raster_to_raw_tiles.R b/tests/testthat/test-1-raster_to_raw_tiles.R deleted file mode 100644 index 406c594..0000000 --- a/tests/testthat/test-1-raster_to_raw_tiles.R +++ /dev/null @@ -1,33 +0,0 @@ -test_that("raster_to_raw warns about deprecation", { - # on GitHub, this test fails to find temp files used in the middle of - # raster_to_raw on windows and mac devices - # - # this does not occur on the windows machine I have access to, though I am - # yet to test it on a mac. As such, I believe this may be an issue with the - # GH environment rather than using magick to open a tempfile. - skip_on_os(c("windows", "mac")) - skip_on_cran() - - expect_warning( - raster_to_raw_tiles( - input_file = "testdata/merge_rasters_test.tif", - output_prefix = tempfile(), - side_length = 4097, - raw = FALSE - ) - ) - - outputs <- suppressWarnings( - raster_to_raw_tiles( - input_file = "testdata/merge_rasters_test.tif", - output_prefix = tempfile(), - side_length = 4097, - raw = FALSE - ) - ) - - expect_equal( - png::readPNG(outputs[[1]]), - png::readPNG("testdata/raster_to_raw_1.png") - ) -}) diff --git a/tests/testthat/test-2-get_tiles_3dep.R b/tests/testthat/test-2-get_tiles_3dep.R index 11715c8..c667657 100644 --- a/tests/testthat/test-2-get_tiles_3dep.R +++ b/tests/testthat/test-2-get_tiles_3dep.R @@ -17,14 +17,16 @@ test_that("get_tiles gets the same elevation tiles twice", { expect_equal(length(output_tif), 1) expect_equal(length(output_tif[[1]]), 1) - stored_raster <- raster::raster("testdata/3DEP.tif") - test_raster <- raster::raster(output_tif[[1]]) + stored_raster <- terra::rast("testdata/3DEP.tif") + test_raster <- terra::rast(output_tif[[1]]) - expect_equal(stored_raster@crs, test_raster@crs) - expect_equal(stored_raster@extent, test_raster@extent) + expect_equal(as.vector(terra::crs(stored_raster)), + as.vector(terra::crs(test_raster))) + expect_equal(as.vector(terra::ext(stored_raster)), + as.vector(terra::ext(test_raster))) expect_equal( - raster::cellStats(stored_raster, "max"), - raster::cellStats(test_raster, "max"), + as.vector(terra::global(stored_raster, max)), + as.vector(terra::global(test_raster, max)), tolerance = 0.01 ) }) diff --git a/tests/testthat/test-4-merge_rasters.R b/tests/testthat/test-4-merge_rasters.R index d75c755..667de42 100644 --- a/tests/testthat/test-4-merge_rasters.R +++ b/tests/testthat/test-4-merge_rasters.R @@ -27,15 +27,18 @@ test_that("merge_raster files are identical no matter the filename", { merge_rasters(c(tmptif[[1]], tmptif[[2]]), tmptif[[4]]) expect_equal( - raster::raster(tmptif[[3]])@extent, - raster::raster(tmptif[[4]])@extent + as.vector(terra::ext(terra::rast(tmptif[[3]]))), + as.vector(terra::ext(terra::rast(tmptif[[4]]))) ) - stored_raster <- raster::raster("testdata/merge_dem.tif") - test_raster <- raster::raster(tmptif[[4]]) + stored_raster <- terra::rast("testdata/merge_dem.tif") + test_raster <- terra::rast(tmptif[[4]]) + + expect_equal(as.vector(terra::crs(stored_raster)), + as.vector(terra::crs(test_raster))) + expect_equal(as.vector(terra::ext(stored_raster)), + as.vector(terra::ext(test_raster))) - expect_equal(stored_raster@crs, test_raster@crs) - expect_equal(stored_raster@extent, test_raster@extent) }) test_that("fallback method works", { @@ -71,15 +74,17 @@ test_that("fallback method works", { merge_rasters(c(tmptif[[1]], tmptif[[2]]), tmptif[[4]], force_fallback = TRUE) expect_equal( - raster::raster(tmptif[[3]])@extent, - raster::raster(tmptif[[4]])@extent + as.vector(terra::ext(terra::rast(tmptif[[3]]))), + as.vector(terra::ext(terra::rast(tmptif[[4]]))) ) - stored_raster <- raster::raster("testdata/merge_dem.tif") - test_raster <- raster::raster(tmptif[[4]]) + stored_raster <- terra::rast("testdata/merge_dem.tif") + test_raster <- terra::rast(tmptif[[4]]) - expect_equal(stored_raster@crs, test_raster@crs) - expect_equal(stored_raster@extent, test_raster@extent) + expect_equal(as.vector(terra::crs(stored_raster)), + as.vector(terra::crs(test_raster))) + expect_equal(as.vector(terra::ext(stored_raster)), + as.vector(terra::ext(test_raster))) }) test_that("overwrite works as expected", { @@ -133,6 +138,9 @@ test_that("overwrite works as expected", { merge_rasters(c(tmptif[[2]]), output_raster = test_file, overwrite = TRUE) expect_false( - raster::raster(test_file)@extent == raster::raster(test_copy)@extent + all( + as.vector(terra::ext(terra::rast(test_file))) == + as.vector(terra::ext(terra::rast(test_copy))) + ) ) }) diff --git a/tests/testthat/test-add_bbox_buffer.R b/tests/testthat/test-add_bbox_buffer.R index 314e01f..ba735f4 100644 --- a/tests/testthat/test-add_bbox_buffer.R +++ b/tests/testthat/test-add_bbox_buffer.R @@ -48,7 +48,7 @@ test_that("set_bbox_side_length works within 1%", { tolerance = 8000 * 0.005 ) - tmp_raster <- raster::raster("testdata/merge_rasters_test.tif") + tmp_raster <- terra::rast("testdata/merge_rasters_test.tif") rstr_bbox <- set_bbox_side_length(tmp_raster, 8000) rstr_bbox <- sf::st_bbox(rstr_bbox) diff --git a/tests/testthat/test-geom_spatial_rgb.R b/tests/testthat/test-geom_spatial_rgb.R index 3342c55..75de34a 100644 --- a/tests/testthat/test-geom_spatial_rgb.R +++ b/tests/testthat/test-geom_spatial_rgb.R @@ -17,8 +17,8 @@ test_that("all methods of geom_spatial_rgb are equivalent", { merged_ortho <- tempfile(fileext = ".tif") merge_rasters(output_tiles[["ortho"]], merged_ortho) - test <- raster::stack(merged_ortho) - test_df <- raster::as.data.frame(test, xy = TRUE) + test <- terra::rast(merged_ortho) + test_df <- terra::as.data.frame(test, xy = TRUE) test_df <- setNames(test_df, c("x", "y", "red", "green", "blue")) plots <- vapply(1:6, function(x) tempfile(fileext = ".png"), character(1)) diff --git a/tests/testthat/test-get_tiles.R b/tests/testthat/test-get_tiles.R index 62db41d..8132f22 100644 --- a/tests/testthat/test-get_tiles.R +++ b/tests/testthat/test-get_tiles.R @@ -1,12 +1,14 @@ # Note: Individual data sources also have tests as test-2-get_tiles_.R -test_that("raster method is consistent", { - tmp_raster <- raster::raster("testdata/merge_rasters_test.tif") +test_that("SpatRast method is consistent", { + tmp_raster <- terra::rast("testdata/merge_rasters_test.tif") rstr_tile <- get_tiles(tmp_raster, bboxSR = 4326, imageSR = 4326) - downloaded_raster <- raster::raster(rstr_tile[["elevation"]]) - test_raster <- raster::raster("testdata/raster_tile.tif") - expect_equal(downloaded_raster@crs, test_raster@crs) - expect_equal(downloaded_raster@extent, test_raster@extent) + downloaded_raster <- terra::rast(rstr_tile[["elevation"]]) + test_raster <- terra::rast("testdata/raster_tile.tif") + expect_equal(as.vector(terra::crs(downloaded_raster)), + as.vector(terra::crs(test_raster))) + expect_equal(as.vector(terra::ext(downloaded_raster)), + as.vector(terra::ext(test_raster))) }) test_that("warnings fire appropriately", { @@ -40,14 +42,16 @@ test_that("The deprecated list method still works", { expect_equal(length(output_tif), 1) expect_equal(length(output_tif[[1]]), 1) - stored_raster <- raster::raster("testdata/3DEP.tif") - test_raster <- raster::raster(output_tif[[1]]) + stored_raster <- terra::rast("testdata/3DEP.tif") + test_raster <- terra::rast(output_tif[[1]]) - expect_equal(stored_raster@crs, test_raster@crs) - expect_equal(stored_raster@extent, test_raster@extent) + expect_equal(as.vector(terra::crs(stored_raster)), + as.vector(terra::crs(test_raster))) + expect_equal(as.vector(terra::ext(stored_raster)), + as.vector(terra::ext(test_raster))) expect_equal( - raster::cellStats(stored_raster, "max"), - raster::cellStats(test_raster, "max"), + as.vector(terra::global(stored_raster, max)), + as.vector(terra::global(test_raster, max)), tolerance = 0.01 ) }) @@ -67,13 +71,14 @@ test_that("projected returns are consistent", { dl_loc <- sf::st_transform(dl_loc, 5071) dl_save <- get_tiles(dl_loc) - stored_raster <- suppressWarnings(raster::raster("testdata/projected.tif")) - test_raster <- suppressWarnings(raster::raster(dl_save[[1]])) + stored_raster <- terra::rast("testdata/projected.tif") + test_raster <- terra::rast(dl_save[[1]]) - expect_equal(stored_raster@crs, test_raster@crs) + expect_equal(as.vector(terra::crs(stored_raster)), + as.vector(terra::crs(test_raster))) expect_equal( - raster::cellStats(stored_raster, "max"), - raster::cellStats(test_raster, "max"), + as.vector(terra::global(stored_raster, max)), + as.vector(terra::global(test_raster, max)), tolerance = 0.01 ) }) From e1717cc9162fd12907b3e5c22c693cd30592d2c6 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Tue, 3 May 2022 13:47:43 -0400 Subject: [PATCH 30/37] Clear names --- tests/testthat/test-2-get_tiles_3dep.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-2-get_tiles_3dep.R b/tests/testthat/test-2-get_tiles_3dep.R index c667657..4265f33 100644 --- a/tests/testthat/test-2-get_tiles_3dep.R +++ b/tests/testthat/test-2-get_tiles_3dep.R @@ -25,8 +25,8 @@ test_that("get_tiles gets the same elevation tiles twice", { expect_equal(as.vector(terra::ext(stored_raster)), as.vector(terra::ext(test_raster))) expect_equal( - as.vector(terra::global(stored_raster, max)), - as.vector(terra::global(test_raster, max)), + stats::setNames(as.vector(terra::global(stored_raster, max)), NULL), + stats::setNames(as.vector(terra::global(test_raster, max)), NULL), tolerance = 0.01 ) }) From 37c4bd0f6396e99b29924d397863034838b61779 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Tue, 3 May 2022 14:01:29 -0400 Subject: [PATCH 31/37] Fix CI --- tests/testthat/test-2-get_tiles_3dep.R | 4 ++-- tests/testthat/test-get_tiles.R | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/testthat/test-2-get_tiles_3dep.R b/tests/testthat/test-2-get_tiles_3dep.R index 4265f33..215b359 100644 --- a/tests/testthat/test-2-get_tiles_3dep.R +++ b/tests/testthat/test-2-get_tiles_3dep.R @@ -25,8 +25,8 @@ test_that("get_tiles gets the same elevation tiles twice", { expect_equal(as.vector(terra::ext(stored_raster)), as.vector(terra::ext(test_raster))) expect_equal( - stats::setNames(as.vector(terra::global(stored_raster, max)), NULL), - stats::setNames(as.vector(terra::global(test_raster, max)), NULL), + as.vector(terra::global(stored_raster, max))[[1]], + as.vector(terra::global(test_raster, max))[[1]], tolerance = 0.01 ) }) diff --git a/tests/testthat/test-get_tiles.R b/tests/testthat/test-get_tiles.R index 8132f22..503d10b 100644 --- a/tests/testthat/test-get_tiles.R +++ b/tests/testthat/test-get_tiles.R @@ -77,8 +77,8 @@ test_that("projected returns are consistent", { expect_equal(as.vector(terra::crs(stored_raster)), as.vector(terra::crs(test_raster))) expect_equal( - as.vector(terra::global(stored_raster, max)), - as.vector(terra::global(test_raster, max)), + as.vector(terra::global(stored_raster, max))[[1]], + as.vector(terra::global(test_raster, max))[[1]], tolerance = 0.01 ) }) From 79f7a2068e571d7585d547aa3d4859c6031df9cd Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Tue, 3 May 2022 14:08:44 -0400 Subject: [PATCH 32/37] Fix CI --- tests/testthat/test-get_tiles.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/testthat/test-get_tiles.R b/tests/testthat/test-get_tiles.R index 503d10b..e94eefb 100644 --- a/tests/testthat/test-get_tiles.R +++ b/tests/testthat/test-get_tiles.R @@ -50,8 +50,8 @@ test_that("The deprecated list method still works", { expect_equal(as.vector(terra::ext(stored_raster)), as.vector(terra::ext(test_raster))) expect_equal( - as.vector(terra::global(stored_raster, max)), - as.vector(terra::global(test_raster, max)), + as.vector(terra::global(stored_raster, max))[[1]], + as.vector(terra::global(test_raster, max))[[1]], tolerance = 0.01 ) }) From c9cc91a660e73b25cc35489566797d519b5d513b Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Tue, 3 May 2022 15:23:47 -0400 Subject: [PATCH 33/37] Prep for fast release post-unifir --- README.Rmd | 23 +-------- README.md | 53 ++++++-------------- codemeta.json | 124 ++++++++++++++++++++++++++++------------------- cran-comments.md | 17 ++----- 4 files changed, 95 insertions(+), 122 deletions(-) diff --git a/README.Rmd b/README.Rmd index cfb0085..e0ee1ad 100644 --- a/README.Rmd +++ b/README.Rmd @@ -21,27 +21,6 @@ knitr::opts_chunk$set( -## This is an experimental build of terrainr - -This feature branch requires the [unifir](https://github.com/mikemahoney218/unifir) package, currently not on CRAN. -If you want to try out the new features in this version -- particularly the new -`make_unity` function -- install unifir using the command: - -```{r, eval = FALSE} -# install.packages("remotes") -remotes::install_github("mikemahoney218/unifir") -``` - -Then install this version of terrainr using: - -```{r, eval=FALSE} -remotes::install_github("ropensci/terrainr", "unified") -``` - - -Please note that unifir is currently very young and subject to change, and the -features in this branch are likely to change with it. - ## Overview terrainr makes it easy to retrieve elevation and base map image tiles for areas @@ -158,7 +137,7 @@ https://www.usgs.gov/faqs/how-should-i-cite-datasets-and-services-national-map . To cite terrainr in publications please use: -> Mahoney et al., (2022). terrainr: An R package for creating immersive virtual environments. Journal of Open Source Software, 7(69), 4060, https://doi.org/10.21105/joss.04060 +> Mahoney, M. J., Beier, C. M., and Ackerman, A. C., (2022). terrainr: An R package for creating immersive virtual environments. Journal of Open Source Software, 7(69), 4060, https://doi.org/10.21105/joss.04060 A BibTeX entry for LaTeX users is: diff --git a/README.md b/README.md index b80f76e..3898891 100644 --- a/README.md +++ b/README.md @@ -23,28 +23,6 @@ Status](https://badges.ropensci.org/416_status.svg)](https://github.com/ropensci -## This is an experimental build of terrainr - -This feature branch requires the -[unifir](https://github.com/mikemahoney218/unifir) package, currently -not on CRAN. If you want to try out the new features in this version – -particularly the new `make_unity` function – install unifir using the -command: - -``` r -# install.packages("remotes") -remotes::install_github("mikemahoney218/unifir") -``` - -Then install this version of terrainr using: - -``` r -remotes::install_github("ropensci/terrainr", "unified") -``` - -Please note that unifir is currently very young and subject to change, -and the features in this branch are likely to change with it. - ## Overview terrainr makes it easy to retrieve elevation and base map image tiles @@ -147,7 +125,7 @@ you’ll be more confident that your computer is still churning along and not just stalled out. For more information, check out [the introductory vignette](https://docs.ropensci.org/terrainr//articles/overview.html) and [the guide to importing your data into -Unity\!](https://docs.ropensci.org/terrainr//articles/unity_instructions.html) +Unity!](https://docs.ropensci.org/terrainr//articles/unity_instructions.html) ## Citing terrainr @@ -158,8 +136,9 @@ data products (as downloaded from `get_tiles`) at To cite terrainr in publications please use: -> Mahoney et al., (2022). terrainr: An R package for creating immersive -> virtual environments. Journal of Open Source Software, 7(69), 4060, +> Mahoney, M. J., Beier, C. M., and Ackerman, A. C., (2022). terrainr: +> An R package for creating immersive virtual environments. Journal of +> Open Source Software, 7(69), 4060, > A BibTeX entry for LaTeX users is: @@ -184,39 +163,39 @@ A BibTeX entry for LaTeX users is: The following datasets can currently be downloaded using `get_tiles` or `hit_national_map_api`: - - [3DEPElevation](https://elevation.nationalmap.gov/arcgis/rest/services/3DEPElevation/ImageServer): +- [3DEPElevation](https://elevation.nationalmap.gov/arcgis/rest/services/3DEPElevation/ImageServer): The USGS 3D Elevation Program (3DEP) Bare Earth DEM. - - [USGSNAIPPlus](https://services.nationalmap.gov/arcgis/rest/services/USGSNAIPPlus/MapServer): +- [USGSNAIPPlus](https://services.nationalmap.gov/arcgis/rest/services/USGSNAIPPlus/MapServer): National Agriculture Imagery Program (NAIP) and high resolution orthoimagery (HRO). - - [nhd](https://hydro.nationalmap.gov/arcgis/rest/services/nhd/MapServer): +- [nhd](https://hydro.nationalmap.gov/arcgis/rest/services/nhd/MapServer): A comprehensive set of digital spatial data that encodes information about naturally occurring and constructed bodies of surface water (lakes, ponds, and reservoirs), paths through which water flows (canals, ditches, streams, and rivers), and related entities such as point features (springs, wells, stream gauges, and dams). - - [govunits](https://carto.nationalmap.gov/arcgis/rest/services/govunits/MapServer): +- [govunits](https://carto.nationalmap.gov/arcgis/rest/services/govunits/MapServer): Major civil areas for the Nation, including States or Territories, counties (or equivalents), Federal and Native American areas, congressional districts, minor civil divisions, incorporated places (such as cities and towns), and unincorporated places. - - [contours](https://carto.nationalmap.gov/arcgis/rest/services/contours/MapServer): +- [contours](https://carto.nationalmap.gov/arcgis/rest/services/contours/MapServer): The USGS Elevation Contours service. - - [geonames](https://carto.nationalmap.gov/arcgis/rest/services/geonames/MapServer): +- [geonames](https://carto.nationalmap.gov/arcgis/rest/services/geonames/MapServer): Information about physical and cultural geographic features, geographic areas, and locational entities that are generally recognizable and locatable by name. - - [NHDPlus\_HR](https://hydro.nationalmap.gov/arcgis/rest/services/NHDPlus_HR/MapServer): +- [NHDPlus_HR](https://hydro.nationalmap.gov/arcgis/rest/services/NHDPlus_HR/MapServer): A comprehensive set of digital spatial data comprising a nationally seamless network of stream reaches, elevation-based catchment areas, flow surfaces, and value-added attributes. - - [structures](https://carto.nationalmap.gov/arcgis/rest/services/structures/MapServer): +- [structures](https://carto.nationalmap.gov/arcgis/rest/services/structures/MapServer): The name, function, location, and other core information and characteristics of selected manmade facilities. - - [transportation](https://carto.nationalmap.gov/arcgis/rest/services/transportation/MapServer): +- [transportation](https://carto.nationalmap.gov/arcgis/rest/services/transportation/MapServer): Roads, railroads, trails, airports, and other features associated with the transport of people or commerce. - - [wbd](https://hydro.nationalmap.gov/arcgis/rest/services/wbd/MapServer): +- [wbd](https://hydro.nationalmap.gov/arcgis/rest/services/wbd/MapServer): Hydrologic Unit (HU) polygon boundaries for the United States, Puerto Rico, and the U.S. Virgin Islands. @@ -241,7 +220,7 @@ devtools::install_github("ropensci/terrainr") ``` Be aware that the development version is not stable, and features that -haven’t been published on CRAN may change at any time\! +haven’t been published on CRAN may change at any time! ## Code of Conduct @@ -249,4 +228,4 @@ Please note that this package is released with a [Contributor Code of Conduct](https://ropensci.org/code-of-conduct/). By contributing to this project, you agree to abide by its terms. -[![ropensci\_footer](https://ropensci.org/public_images/github_footer.png)](https://ropensci.org) +[![ropensci_footer](https://ropensci.org/public_images/github_footer.png)](https://ropensci.org) diff --git a/codemeta.json b/codemeta.json index e89f057..5d2a730 100644 --- a/codemeta.json +++ b/codemeta.json @@ -4,7 +4,7 @@ "identifier": "terrainr", "description": "Functions for the retrieval, manipulation, and visualization of 'geospatial' data, with an aim towards producing '3D' landscape visualizations in the 'Unity' '3D' rendering engine. Functions are also provided for retrieving elevation data and base map tiles from the 'USGS' National Map .", "name": "terrainr: Landscape Visualizations in R and 'Unity'", - "relatedLink": "https://docs.ropensci.org/terrainr/", + "relatedLink": ["https://docs.ropensci.org/terrainr/", "https://CRAN.R-project.org/package=terrainr"], "codeRepository": "https://github.com/ropensci/terrainr", "issueTracker": "https://github.com/ropensci/terrainr/issues", "license": "https://spdx.org/licenses/MIT", @@ -14,7 +14,7 @@ "name": "R", "url": "https://r-project.org" }, - "runtimePlatform": "R version 4.1.3 (2022-03-10)", + "runtimePlatform": "R version 4.2.0 (2022-04-22)", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", @@ -42,15 +42,15 @@ "softwareSuggestions": [ { "@type": "SoftwareApplication", - "identifier": "testthat", - "name": "testthat", + "identifier": "brio", + "name": "brio", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=testthat" + "sameAs": "https://CRAN.R-project.org/package=brio" }, { "@type": "SoftwareApplication", @@ -66,15 +66,15 @@ }, { "@type": "SoftwareApplication", - "identifier": "progressr", - "name": "progressr", + "identifier": "jpeg", + "name": "jpeg", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=progressr" + "sameAs": "https://CRAN.R-project.org/package=jpeg" }, { "@type": "SoftwareApplication", @@ -90,63 +90,87 @@ }, { "@type": "SoftwareApplication", - "identifier": "rmarkdown", - "name": "rmarkdown", + "identifier": "progress", + "name": "progress", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=rmarkdown" + "sameAs": "https://CRAN.R-project.org/package=progress" }, { "@type": "SoftwareApplication", - "identifier": "progress", - "name": "progress", + "identifier": "progressr", + "name": "progressr", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=progress" + "sameAs": "https://CRAN.R-project.org/package=progressr" }, { "@type": "SoftwareApplication", - "identifier": "jpeg", - "name": "jpeg", + "identifier": "raster", + "name": "raster", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=jpeg" + "sameAs": "https://CRAN.R-project.org/package=raster" }, { "@type": "SoftwareApplication", - "identifier": "tiff", - "name": "tiff", + "identifier": "rgdal", + "name": "rgdal", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=tiff" + "sameAs": "https://CRAN.R-project.org/package=rgdal" }, { "@type": "SoftwareApplication", - "identifier": "brio", - "name": "brio", + "identifier": "rmarkdown", + "name": "rmarkdown", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=brio" + "sameAs": "https://CRAN.R-project.org/package=rmarkdown" + }, + { + "@type": "SoftwareApplication", + "identifier": "testthat", + "name": "testthat", + "provider": { + "@id": "https://cran.r-project.org", + "@type": "Organization", + "name": "Comprehensive R Archive Network (CRAN)", + "url": "https://cran.r-project.org" + }, + "sameAs": "https://CRAN.R-project.org/package=testthat" + }, + { + "@type": "SoftwareApplication", + "identifier": "tiff", + "name": "tiff", + "provider": { + "@id": "https://cran.r-project.org", + "@type": "Organization", + "name": "Comprehensive R Archive Network (CRAN)", + "url": "https://cran.r-project.org" + }, + "sameAs": "https://CRAN.R-project.org/package=tiff" }, { "@type": "SoftwareApplication", @@ -169,39 +193,32 @@ }, "2": { "@type": "SoftwareApplication", - "identifier": "httr", - "name": "httr", + "identifier": "ggplot2", + "name": "ggplot2", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=httr" + "sameAs": "https://CRAN.R-project.org/package=ggplot2" }, "3": { "@type": "SoftwareApplication", - "identifier": "raster", - "name": "raster", - "provider": { - "@id": "https://cran.r-project.org", - "@type": "Organization", - "name": "Comprehensive R Archive Network (CRAN)", - "url": "https://cran.r-project.org" - }, - "sameAs": "https://CRAN.R-project.org/package=raster" + "identifier": "grDevices", + "name": "grDevices" }, "4": { "@type": "SoftwareApplication", - "identifier": "rgdal", - "name": "rgdal", + "identifier": "httr", + "name": "httr", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=rgdal" + "sameAs": "https://CRAN.R-project.org/package=httr" }, "5": { "@type": "SoftwareApplication", @@ -248,36 +265,31 @@ }, "9": { "@type": "SoftwareApplication", - "identifier": "units", - "name": "units", + "identifier": "terra", + "name": "terra", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=units" + "sameAs": "https://CRAN.R-project.org/package=terra" }, "10": { "@type": "SoftwareApplication", - "identifier": "grDevices", - "name": "grDevices" - }, - "11": { - "@type": "SoftwareApplication", - "identifier": "ggplot2", - "name": "ggplot2", + "identifier": "units", + "name": "units", "provider": { "@id": "https://cran.r-project.org", "@type": "Organization", "name": "Comprehensive R Archive Network (CRAN)", "url": "https://cran.r-project.org" }, - "sameAs": "https://CRAN.R-project.org/package=ggplot2" + "sameAs": "https://CRAN.R-project.org/package=units" }, "SystemRequirements": null }, - "fileSize": "4051.414KB", + "fileSize": "4059.882KB", "citation": [ { "@type": "ScholarlyArticle", @@ -316,5 +328,15 @@ } } } - ] + ], + "releaseNotes": "https://github.com/ropensci/terrainr/blob/master/NEWS.md", + "readme": "https://github.com/ropensci/terrainr/blob/main/README.md", + "contIntegration": ["https://app.codecov.io/gh/ropensci/terrainr", "https://github.com/ropensci/terrainr/actions"], + "developmentStatus": ["https://lifecycle.r-lib.org/articles/stages.html#maturing", "https://www.repostatus.org/#active"], + "review": { + "@type": "Review", + "url": "https://github.com/ropensci/software-review/issues/416", + "provider": "https://ropensci.org" + }, + "keywords": ["r", "r-package", "cran", "terrainr", "rstats", "usgs", "map", "mapping", "national-map", "unity-rendering-engine", "unity", "map-tiles", "progressr", "peer-reviewed", "retrieve-data", "orthoimagery", "dems", "datasets", "nhd"] } diff --git a/cran-comments.md b/cran-comments.md index fbb012a..c363838 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,16 +1,9 @@ -I apologize for the rapid re-submission! -The README of version 0.6.0 has a disclaimer at the top stating that the -package is an experimental build relying on as-of-yet unreleased packages. -This is not true. -This release removes that language. -Otherwise, this release is identical to version 0.6.0. - ## Test environments -* local R installation, R 4.1.2 -* ubuntu 20.04 (on GitHub Actions), R devel, 4.1.2, 4.0.5 -* MacOS X 11.6.3 (on GitHub Actions), R 4.1.2 -* Windows Server 2019 (on GitHub Actions), R 4.1.2 -* win-builder (devel, 4.1.2, 4.0.5) +* local R installation, R release +* ubuntu 20.04 (on GitHub Actions), R devel, release, oldrelease +* MacOS X 11.6.3 (on GitHub Actions), R release +* Windows Server 2019 (on GitHub Actions), R release +* win-builder (devel, release, oldrelease) ## R CMD check results From 003e6fb4b93dd08c2e4872c1258f514edab210be Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Tue, 3 May 2022 19:26:39 +0000 Subject: [PATCH 34/37] Re-build README.Rmd --- README.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 3898891..7bc0221 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,7 @@ you’ll be more confident that your computer is still churning along and not just stalled out. For more information, check out [the introductory vignette](https://docs.ropensci.org/terrainr//articles/overview.html) and [the guide to importing your data into -Unity!](https://docs.ropensci.org/terrainr//articles/unity_instructions.html) +Unity\!](https://docs.ropensci.org/terrainr//articles/unity_instructions.html) ## Citing terrainr @@ -163,39 +163,39 @@ A BibTeX entry for LaTeX users is: The following datasets can currently be downloaded using `get_tiles` or `hit_national_map_api`: -- [3DEPElevation](https://elevation.nationalmap.gov/arcgis/rest/services/3DEPElevation/ImageServer): + - [3DEPElevation](https://elevation.nationalmap.gov/arcgis/rest/services/3DEPElevation/ImageServer): The USGS 3D Elevation Program (3DEP) Bare Earth DEM. -- [USGSNAIPPlus](https://services.nationalmap.gov/arcgis/rest/services/USGSNAIPPlus/MapServer): + - [USGSNAIPPlus](https://services.nationalmap.gov/arcgis/rest/services/USGSNAIPPlus/MapServer): National Agriculture Imagery Program (NAIP) and high resolution orthoimagery (HRO). -- [nhd](https://hydro.nationalmap.gov/arcgis/rest/services/nhd/MapServer): + - [nhd](https://hydro.nationalmap.gov/arcgis/rest/services/nhd/MapServer): A comprehensive set of digital spatial data that encodes information about naturally occurring and constructed bodies of surface water (lakes, ponds, and reservoirs), paths through which water flows (canals, ditches, streams, and rivers), and related entities such as point features (springs, wells, stream gauges, and dams). -- [govunits](https://carto.nationalmap.gov/arcgis/rest/services/govunits/MapServer): + - [govunits](https://carto.nationalmap.gov/arcgis/rest/services/govunits/MapServer): Major civil areas for the Nation, including States or Territories, counties (or equivalents), Federal and Native American areas, congressional districts, minor civil divisions, incorporated places (such as cities and towns), and unincorporated places. -- [contours](https://carto.nationalmap.gov/arcgis/rest/services/contours/MapServer): + - [contours](https://carto.nationalmap.gov/arcgis/rest/services/contours/MapServer): The USGS Elevation Contours service. -- [geonames](https://carto.nationalmap.gov/arcgis/rest/services/geonames/MapServer): + - [geonames](https://carto.nationalmap.gov/arcgis/rest/services/geonames/MapServer): Information about physical and cultural geographic features, geographic areas, and locational entities that are generally recognizable and locatable by name. -- [NHDPlus_HR](https://hydro.nationalmap.gov/arcgis/rest/services/NHDPlus_HR/MapServer): + - [NHDPlus\_HR](https://hydro.nationalmap.gov/arcgis/rest/services/NHDPlus_HR/MapServer): A comprehensive set of digital spatial data comprising a nationally seamless network of stream reaches, elevation-based catchment areas, flow surfaces, and value-added attributes. -- [structures](https://carto.nationalmap.gov/arcgis/rest/services/structures/MapServer): + - [structures](https://carto.nationalmap.gov/arcgis/rest/services/structures/MapServer): The name, function, location, and other core information and characteristics of selected manmade facilities. -- [transportation](https://carto.nationalmap.gov/arcgis/rest/services/transportation/MapServer): + - [transportation](https://carto.nationalmap.gov/arcgis/rest/services/transportation/MapServer): Roads, railroads, trails, airports, and other features associated with the transport of people or commerce. -- [wbd](https://hydro.nationalmap.gov/arcgis/rest/services/wbd/MapServer): + - [wbd](https://hydro.nationalmap.gov/arcgis/rest/services/wbd/MapServer): Hydrologic Unit (HU) polygon boundaries for the United States, Puerto Rico, and the U.S. Virgin Islands. @@ -220,7 +220,7 @@ devtools::install_github("ropensci/terrainr") ``` Be aware that the development version is not stable, and features that -haven’t been published on CRAN may change at any time! +haven’t been published on CRAN may change at any time\! ## Code of Conduct @@ -228,4 +228,4 @@ Please note that this package is released with a [Contributor Code of Conduct](https://ropensci.org/code-of-conduct/). By contributing to this project, you agree to abide by its terms. -[![ropensci_footer](https://ropensci.org/public_images/github_footer.png)](https://ropensci.org) +[![ropensci\_footer](https://ropensci.org/public_images/github_footer.png)](https://ropensci.org) From a35a5efa396ffa603aa5cbe72c32fa5f4fcc71d6 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 4 May 2022 11:07:25 -0400 Subject: [PATCH 35/37] Update vignette --- NEWS.md | 5 ++ R/make_manifest.R | 15 ++++- tests/testthat/testdata/manifest_ort.png | Bin 98435 -> 16801 bytes vignettes/unity_instructions.Rmd | 76 +++++++---------------- 4 files changed, 40 insertions(+), 56 deletions(-) diff --git a/NEWS.md b/NEWS.md index 686a3b0..cc6dd84 100644 --- a/NEWS.md +++ b/NEWS.md @@ -16,6 +16,11 @@ should no longer give warnings about nodata values in most cases. being clamped to 0. * Fixed some documentation, unused objects, restyled and removed lints. + * `transform_overlay` (and by extension, every Unity overlay importer) now + tries to automatically guess the scale of the input raster. Values under + 1 are scaled from 0-1, integers under 255 are scaled 0-255, and integers + under 65535 are scaled 0-65536. The main effect of this is more realistic + coloring when importing terrain. Floats above 1 won't be affected. * Dependency changes: * `terra` is now included as an Import (had been recursively imported through `raster` previously). diff --git a/R/make_manifest.R b/R/make_manifest.R index c7797ef..9195280 100644 --- a/R/make_manifest.R +++ b/R/make_manifest.R @@ -186,7 +186,20 @@ prep_table <- function(input_raster, ) } input_raster <- terra::rast(input_raster) - max_raster <- max(terra::global(input_raster, "max")) + max_raster <- max(terra::global(input_raster, "max", na.rm = TRUE)) + if (type == "overlay") { + if (max_raster < 1) { + max_raster <- 1 + } else if ( + isTRUE(all.equal(as.integer(max_raster), max_raster)) & + max_raster < 255) { + max_raster <- 255 + } else if ( + isTRUE(all.equal(as.integer(max_raster), max_raster)) & + max_raster < 65535) { + max_raster <- 65535 + } + } x_tiles <- ceiling(terra::ncol(input_raster) / side_length) y_tiles <- ceiling(terra::nrow(input_raster) / side_length) diff --git a/tests/testthat/testdata/manifest_ort.png b/tests/testthat/testdata/manifest_ort.png index 94b8dc7aab9feb88906e4319f512a7c7f954c418..7e80557c9bb33e01c77aac80dc356377cdfebf17 100644 GIT binary patch delta 474 zcmZo}WLwzGI6;DwgPDPW;o;+)eG?V!>t_b|gt!9v-76+`ubMUIob@#_Lk(~`i z#};%y-8t{)freYlO0P|;xG%Z7H_z zC{0}zvbyciwx(^16ap)ygGzPsYkWGU`E>MUESb@`yZ`_H|G}b4wLsS~mIV0)GdMiE zkp|)21sKVxNKXXRgfW~(OygZ+<FVdQ&MBb@0Etz@M*si- literal 98435 zcmeI)e@xVM9LMnwa&Q6xM~>J6*R6?7n|WXiBQ38TKdyjX2#iPvr;-N>C_BK^jay(s zhDt0_iIz*yQgLpQB2b39V7ieZ-XS5N@hgxv6oEkKd;Hgmf81cH&(HSVXW!3vpV#~I zdHnsp%hQDiJ3Bt_D1>m#T;qHp}~AWnq(W*VQL{x?{ga0+ez=r^&t^q zLTq0sgegaezoaEoj}Yl9A^wOLB0$>XvE|G2@2-$O*c&6lS4*=rQp)57(qzBxonX!6 z)NqIy{!Lnu8?|A9@-91D`7>_rH=J%taYCz6M{c{>|C5b$8e!T$acW?$^^6Pz5I_I{ z1Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0009ILc&r6X&DplrW&oj_GzaOT7ziMM z00IagfB*srAb4WY%5)(|DYx`fti1qYFe_Px z2LcEnfB*srAbY(W441Q0*~0R#|0009ILKmY**5I_I{1Q0*~0R#|0 z009ILKmdUm6tHC5+E|+bl#}Kl-3- ziFJVnx4Zi;6?C_DmTc>84mKFhd4APBuez<>&e~nTKmY**5I_I{1Q0*~0R#|0009IL zKmY**5I_I{1Q0*~0R(1DVB}5b3YTfpP1}cmZ>$};dRCd6)1gZ`k@`xg|D`*v`49i} z_`$2KdcK2eT4~c@!(jB8Ci`h3#6-vKo|8Q_1xiEZ{zK<>c6Z&nP+UHC*FU^w@y<_k zMoX0;_oIDJe{a~N&?J>OPLnb;Ft%Y}ZN}EDWqxiB!#8fXhGma-YErAeNo=>oc+Yb# zym+}`)U|0{qF;1hn>xU_ipXD#)+>y2q64HfxSeRnG5RWE-Y zn&IPqv^m1jH02i`ugH(gWP*g4@*^3wUT^JOjN z(Z2N^bwh@etEc{;{@+1g-*OLnwx%~buKtD6heMXek3&bYU`JPGmTG?J z7v)~BW!{fS>0PRE&k0Ew=r53Byp4e|#tnL7Lcsd81Zfh!Dqr6vD!(PFWsyEU0Y1I~ rKK@HouLh`8?Xi6+|Jab6x*_p{52xQyAYc8f^`P3oa83DJ@gMySe&VFJ diff --git a/vignettes/unity_instructions.Rmd b/vignettes/unity_instructions.Rmd index f79217c..dbdbd9d 100644 --- a/vignettes/unity_instructions.Rmd +++ b/vignettes/unity_instructions.Rmd @@ -64,62 +64,27 @@ merged_tiles <- zion %>% lapply(merge_rasters) ``` -We've now got our data downloaded! Our next step is to turn it into a data -format we can import into Unity. - -As of terrainr 0.5.0, the way to do this is via the function `make_manifest`. -The first argument to this function is the elevation raster you want to use as -a heightmap -- in our case, `merged_tiles$elevation`. The second argument -optionally takes the image overlay you want to put on top of that heightmap. -In our case, that means everything we need to provide is in the `merged_tiles` -list: - -```{r, eval = FALSE} -make_manifest(merged_tiles$elevation, - merged_tiles$ortho) -``` - -After a moment, this function will spit out a number of files: our heightmap and -overlay tiles, all prefixed with `import_`, a C# file named `import_terrain.cs`, -and a final file named `terrainr.manifest` (note that all of these names can be -changed via arguments to `make_manifest`, but for simplicity's sake I'm using -the default names now). - -```{r, echo = FALSE} -knitr::include_graphics("generated_files.png") -``` - -Now go ahead and open Unity. From the main "Hub" menu, click "New" to create a -new project. Set the project name to whatever you want, then click "Create". - -```{r, echo = FALSE} -knitr::include_graphics("new_unity.jpg") -``` - -Go ahead and move all the files from `make_manifest` into the root directory of -your new Unity project. Then move the `import_terrain.cs` file into the `Assets` -directory inside that folder (but leave everything else in the root directory!). - -Go back to Unity now. A second after you click into the window, you should -notice a "terrainr" menu appear in the top bar. Click that menu, then the only -option in the drop-down. A menu should appear; click "Import" to import your -tiles into Unity. - -```{r, echo = FALSE} -knitr::include_graphics("manifest_import.png") -``` - -The importer menu will disappear, then Unity will take a minute or two to import -all your tiles. Depending on your data, you may see something that looks like -this: - -```{r, echo = FALSE} -knitr::include_graphics("ominous.png") +We've now got our data downloaded! All that's left is to import these tiles into +Unity. + +As of terrainr 0.7.0, the way to do this is via the function `make_unity`. +Assuming you have Unity installed on your computer, we can go ahead and +import our terrain into a brand new project, named `zion`, through the +following: + +```{r eval = FALSE} +make_unity( + project = "zion", + heightmap = merged_tiles$elevation, + overlay = merged_tiles$ortho +) ``` -That's perfectly fine! Right click on the "Scene" window in the middle, and then -press and hold "S" on your keyboard to move the camera back. After a -second, you should see your terrain surface! +This will create a new folder, named `zion`, containing our Unity project. +Open that project in Unity, and then open the scene (either using `Ctrl+O` +or `File -> Open Scene`) named `Scenes/terrainr_scene.unity`. +Double click on one of the terrain tiles and you'll zoom out to see the +entire terrain: ```{r, echo = FALSE} knitr::include_graphics("terrain_surface.jpg") @@ -127,7 +92,8 @@ knitr::include_graphics("terrain_surface.jpg") You can now move around your surface by right clicking on the image and moving around with the W-A-S-D keys on your keyboard. Note that your movement speed -starts off very slow, and then accelerates over time. +starts off very slow, and then accelerates over time (especially if you +press and hold the "shift" key). And ta-da, you have a surface in Unity! You can go ahead and customize the scene further (I'll usually then click on "Directional Light" and change "Render Mode" From 15830a4938ccff3ab39660f4838f8fee6eee3c83 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 4 May 2022 11:23:10 -0400 Subject: [PATCH 36/37] Test make_unity --- R/make_unity.R | 11 ++++++++--- tests/testthat/test-make_unity.R | 30 ++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 tests/testthat/test-make_unity.R diff --git a/R/make_unity.R b/R/make_unity.R index 0a57b42..fb446a2 100644 --- a/R/make_unity.R +++ b/R/make_unity.R @@ -10,6 +10,8 @@ #' @param scene_name The name of the Unity scene to create the terrain in. #' @param action Boolean: Execute the unifir "script" and create the Unity #' project? If FALSE, returns a non-executed script. +#' @param unity The location of the Unity executable to create projects with. +#' By default, will be auto-detected by [unifir::find_unity] #' #' @return An object of class "unifir_script", containing either an executed #' unifir script (if action = TRUE) or a non-executed script object @@ -37,7 +39,8 @@ make_unity <- function(project, overlay = NULL, side_length = 4097, scene_name = "terrainr_scene", - action = TRUE) { + action = TRUE, + unity = find_unity()) { if (!requireNamespace("unifir", quietly = TRUE)) { stop( "make_unity requires the unifir package to work correctly. ", @@ -63,7 +66,7 @@ make_unity <- function(project, side_length = side_length, output_prefix = elevation_prefix ) - dir.create(project) + if (!dir.exists(project)) dir.create(project) lapply( manifest$filename, function(x) file.rename(x, file.path(project, basename(x))) @@ -90,7 +93,9 @@ make_unity <- function(project, manifest$texture <- basename(manifest$texture) } - script <- unifir::make_script(project, scene_name = scene_name) + script <- unifir::make_script(project, + scene_name = scene_name, + unity = unity) script <- unifir::new_scene(script, "DefaultGameObjects", "Single") for (i in seq_len(nrow(manifest))) { diff --git a/tests/testthat/test-make_unity.R b/tests/testthat/test-make_unity.R new file mode 100644 index 0000000..bec4d1d --- /dev/null +++ b/tests/testthat/test-make_unity.R @@ -0,0 +1,30 @@ +test_that("make_unity is stable", { + + Sys.setenv("unifir_debugmode" = TRUE) + + outputs <- make_unity( + file.path(tempdir(), "make_unity"), + "testdata/3DEP_gr.tif", + "testdata/NAIPPlus_gr.tif", + action = FALSE, + unity = unifir::waiver() + ) + + expect_equal( + length(outputs$props), + nrow(outputs$beats) + ) + + expect_equal( + length(outputs$props), + 6 + ) + + expect_match( + outputs$scene_name, + "terrainr_scene" + ) + + Sys.setenv("unifir_debugmode" = "") + +}) From b2c703a47942ebe34bdd384ee48f1e6572c3b831 Mon Sep 17 00:00:00 2001 From: Mike Mahoney Date: Wed, 4 May 2022 11:35:29 -0400 Subject: [PATCH 37/37] Document new argument --- DESCRIPTION | 4 ++-- NAMESPACE | 1 + R/make_unity.R | 2 ++ man/make_unity.Rd | 6 +++++- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3a170e5..1d6e49e 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -29,6 +29,7 @@ Imports: png, sf (>= 1.0-5), terra, + unifir, units Suggests: brio, @@ -41,8 +42,7 @@ Suggests: rgdal, rmarkdown, testthat, - tiff, - unifir + tiff VignetteBuilder: knitr Config/testthat/edition: 3 diff --git a/NAMESPACE b/NAMESPACE index 8f037aa..72cfef1 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -28,3 +28,4 @@ export(transform_elevation) export(transform_overlay) export(vector_to_overlay) importFrom(grDevices,rgb) +importFrom(unifir,find_unity) diff --git a/R/make_unity.R b/R/make_unity.R index fb446a2..ff99d1a 100644 --- a/R/make_unity.R +++ b/R/make_unity.R @@ -17,6 +17,8 @@ #' unifir script (if action = TRUE) or a non-executed script object #' (if action = FALSE). #' +#' @importFrom unifir find_unity +#' #' @examples #' \dontrun{ #' if (!isTRUE(as.logical(Sys.getenv("CI")))) { diff --git a/man/make_unity.Rd b/man/make_unity.Rd index bfd6c08..9ffb9e8 100644 --- a/man/make_unity.Rd +++ b/man/make_unity.Rd @@ -10,7 +10,8 @@ make_unity( overlay = NULL, side_length = 4097, scene_name = "terrainr_scene", - action = TRUE + action = TRUE, + unity = find_unity() ) } \arguments{ @@ -29,6 +30,9 @@ Must be equal to 2^x + 1, for any x between 5 and 12.} \item{action}{Boolean: Execute the unifir "script" and create the Unity project? If FALSE, returns a non-executed script.} + +\item{unity}{The location of the Unity executable to create projects with. +By default, will be auto-detected by \link[unifir:find_unity]{unifir::find_unity}} } \value{ An object of class "unifir_script", containing either an executed