Skip to content

Commit

Permalink
Devel (v. 1.3.3.9003) RC 1.3.4 (#304)
Browse files Browse the repository at this point in the history
## New functions
- `gdalUtil()`: function used to perform GDAL operations, calling C-based GDAL utilities using `sf::gdal_utils()`, and Python-based ones through system calls (a standalone GDAL environment is request to do it, as it was in previous versions).

## Documentation
- Improve documentation of vignette "Output file structure", including the description of output products.

## New dependency
- **`rgdal`** is now an explicit dependency (this because it is used by **`raster`** but it is not a mandatory dependency).

## Minor changes
- GDAL C-based utilities are called using internal GDAL routines in package **`sf`** (see `gdalUtil()`). This allows reducing the use of external runtime dependencies.
- GDAL messages are suppressed if the suggested dependency **`sys`** is installed (#257).
- The new section of the vignette "Output file documentation" regarding products is linked in the GUI.
## Bug fixes
- Fix #308.
  • Loading branch information
ranghetti authored Apr 22, 2020
1 parent 2f1b1d1 commit 7f0b41b
Show file tree
Hide file tree
Showing 132 changed files with 4,157 additions and 2,464 deletions.
4 changes: 4 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ r_packages:
- RPostgreSQL
- covr

r_github_packages:
- r-spatial/lwgeom
- r-spatial/sf

apt_packages:
- libgdal-dev
- libproj-dev
Expand Down
10 changes: 5 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: sen2r
Type: Package
Title: Find, Download and Process Sentinel-2 Data
Version: 1.3.3.9001
Version: 1.3.4
Authors@R: c(person("Luigi", "Ranghetti",
email = "[email protected]",
role = c("aut", "cre"),
Expand All @@ -23,10 +23,11 @@ BugReports: https://github.com/ranghetti/sen2r/issues
Depends: R (>= 3.5.0)
Imports:
methods,
sf,
stars,
sf (>= 0.9.2),
stars (>= 0.4.1),
data.table,
raster,
rgdal,
XML,
jsonlite,
geojsonio,
Expand All @@ -44,7 +45,6 @@ Imports:
httr,
RcppTOML
Suggests:
rgdal,
spelling,
geojsonlint,
httptest,
Expand All @@ -58,5 +58,5 @@ SystemRequirements: GDAL (>= 2.1.2), PROJ (>= 4.9.1), GEOS (>= 3.4.2),
Cairo, Curl, NetCDF, jq, Protocol Buffers, V8, OpenSSL, Libxml2.
VignetteBuilder: knitr
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.0.2
RoxygenNote: 7.1.0
Language: en-GB
3 changes: 0 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ RUN apt-get update && apt-get install -y \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*

# Install lwgeom from remote (https://github.com/rocker-org/geospatial/issues/17)
RUN R -e "remotes::install_github('r-spatial/lwgeom', dependencies = TRUE)"

# Install the package
RUN R -e "remotes::install_github('ranghetti/sen2r', ref = 'master', dependencies = TRUE)"

Expand Down
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export(check_scihub_login)
export(check_sen2r_deps)
export(comsub)
export(expand_path)
export(gdalUtil)
export(gdal_abs2rel)
export(gdal_rel2abs)
export(gdal_warp)
Expand Down Expand Up @@ -123,6 +124,7 @@ importFrom(raster,values)
importFrom(raster,writeStart)
importFrom(raster,writeStop)
importFrom(raster,writeValues)
importFrom(rgdal,GDALinfo)
importFrom(sf,gdal_crs)
importFrom(sf,gdal_utils)
importFrom(sf,sf_extSoftVersion)
Expand Down
25 changes: 23 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,24 @@
# Version 1.3.4

## New functions
- `gdalUtil()`: function used to perform GDAL operations, calling C-based GDAL utilities using `sf::gdal_utils()`, and Python-based ones through system calls (a standalone GDAL environment is request to do it, as it was in previous versions).

## Documentation
- Improve documentation of vignette "Output file structure", including the description of output products.

## New dependency
- **`rgdal`** is now an explicit dependency (this because it is used by **`raster`** but it is not a mandatory dependency).

## Minor changes
- GDAL C-based utilities are called using internal GDAL routines in package **`sf`** (see `gdalUtil()`). This allows reducing the use of external runtime dependencies.
- GDAL messages are suppressed if the suggested dependency **`sys`** is installed (#257).
- The new section of the vignette "Output file documentation" regarding products is linked in the GUI.

## Bug fixes
- Re-fix #292.
- Fix #308.


# Version 1.3.3

## Major changes
Expand All @@ -12,7 +33,7 @@
- Improve the installation page.

## Bug fixes
- Support for `sf` >= 0.9 (#260)
- Support for **`sf`** >= 0.9 (#260)
- Patch for **`stars`** issue, made to resolve the temporary incompatibility with **`sf`** >= 0.9 (see issue #295)
- Fix #292
- Small improvements
Expand Down Expand Up @@ -283,7 +304,7 @@ First stable release of package **sen2r**! See the announcement [here](https://l
### Bug fixing:
* Fix bug in SciHub login
* Fix maps (tiles were hidden)
* Fix:missing dependency lwgeom
* Fix:missing dependency **`lwgeom`**
* Various fixes (#140, #141, #142, etc.)


Expand Down
10 changes: 0 additions & 10 deletions R/check_gdal.R
Original file line number Diff line number Diff line change
Expand Up @@ -278,11 +278,6 @@ check_gdal <- function(abort = TRUE, gdal_path = NULL, force = FALSE, full_scan
gdal_version <- gdal_versions[1]
bin_ext <- ifelse(Sys.info()["sysname"] == "Windows", ".exe", "")
binpaths$gdalinfo <- normalize_path(file.path(gdal_dir,paste0("gdalinfo",bin_ext)))
binpaths$ogrinfo <- normalize_path(file.path(gdal_dir,paste0("ogrinfo",bin_ext)))
binpaths$gdal_translate <- normalize_path(file.path(gdal_dir,paste0("gdal_translate",bin_ext)))
binpaths$gdalwarp <- normalize_path(file.path(gdal_dir,paste0("gdalwarp",bin_ext)))
binpaths$gdalbuildvrt <- normalize_path(file.path(gdal_dir,paste0("gdalbuildvrt",bin_ext)))
binpaths$gdaldem <- normalize_path(file.path(gdal_dir,paste0("gdaldem",bin_ext)))
if (Sys.info()["sysname"] == "Windows") {
binpaths$python <- normalize_path(file.path(gdal_dir,paste0("python",bin_ext)))
}
Expand All @@ -291,11 +286,6 @@ check_gdal <- function(abort = TRUE, gdal_path = NULL, force = FALSE, full_scan
} else {
normalize_path(file.path(gdal_py_dir,"gdal_calc.py"))
}
binpaths$gdal_polygonize <- if (Sys.info()["sysname"] == "Windows") {
paste0(binpaths$python," ",normalize_path(file.path(gdal_py_dir,"gdal_polygonize.py")))
} else {
normalize_path(file.path(gdal_py_dir,"gdal_polygonize.py"))
}
binpaths$gdal_fillnodata <- if (Sys.info()["sysname"] == "Windows") {
paste0(binpaths$python," ",normalize_path(file.path(gdal_py_dir,"gdal_fillnodata.py")))
} else {
Expand Down
15 changes: 15 additions & 0 deletions R/dontuse.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#' @title Don't use
#' @description Don't use this function.
#' @details This function simply call an `rgdal` function, so to be able to
#' include package `rgdal` among imported dependencies.
#' This is necessary since using `raster` without having `rgdal` installed
#' causes troublings in R 4.
#' @importFrom rgdal GDALinfo
#' @return NULL
dontuse <- function() {
suppressWarnings(GDALinfo(
system.file("extdata/out/S2A2A_20190723_022_Barbellino_SCL_10.tif", package = "sen2r")
))
message("Disobedient.")
invisible(NULL)
}
20 changes: 20 additions & 0 deletions R/expect_equal_crs.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#' @title Compare two non-null CRS
#' @description Internal function: convenience function to compare two non-null
#' CRS in tests without using EPSG (so usable with rgdal >= 1.5).
#' @param crs1 CRS 1 to compare
#' @param crs2 CRS 2 to compare
#' @return `testthat::expect_equal()` output.
#' @importFrom sf st_geometry st_read st_coordinates st_transform
#' @author Luigi Ranghetti, phD (2020) \email{luigi@@ranghetti.info}
#' @note License: GPL 3.0

expect_equal_crs <- function(crs1, crs2) {
ref_vec <- st_geometry(st_read(
system.file("extdata/vector/barbellino.geojson", package = "sen2r"),
quiet = TRUE
))
testthat::expect_equal(
as.integer(st_coordinates(st_transform(ref_vec, crs1))[,c("X","Y")]),
as.integer(st_coordinates(st_transform(ref_vec, crs2))[,c("X","Y")])
)
}
217 changes: 217 additions & 0 deletions R/gdalUtil.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
#' @title Interface to GDAL Python-based utilities
#' @description This accessory function interfaces with GDAL
#' utilities (sen2r must be interfaced with a runtime GDAL
#' environment, see `check_gdal()`).
#' Python-based utilities are always called from a runtime GDAL;
#' C-based ones are called using `sf::gdal_utils()`.
#' @param util Character: one among `"info"`, `"translate"`, `"warp"`,
#' `"demprocessing"` ,`"buildvrt"` (C-based),
#' `"calc"` and `"fillnodata"` (Python-based).
#' Other utilities were not implemented, since they are not used by sen2r.
#' @param source path of input layer(s); for `calc` this can be more than one.
#' @param destination Path of the output layer.
#' @param options Character vector with GDAL options.
#' @param quiet Logical: if TRUE, suppress printing of output for info
#' (this argument is ignored in case package `sys` is not installed).
#' @param formula (for `util = "calc"`) Calculation in `gdalnumeric` syntax using
#' `+`, `-`, `/`, `*`, or any `numpy` array functions (i.e. `log10()`).
#' @param processing Character: processing options for `util = "demprocessing"`.
#' @param colorfilename Character: name of colour file for `util = "demprocessing"`
#' (mandatory if `processing="color-relief"`).
#' @return A logical (invisible) indicating success (i.e., TRUE);
#' in case of failure, an error is raised and FALSE is returned (in case of
#' Python-based utilities).
#' @importFrom sf gdal_utils
#' @export
#' @author Luigi Ranghetti, phD (2020) \email{luigi@@ranghetti.info}
#' @note License: GPL 3.0
#' @examples
#' # Define product names
#' examplename <- system.file(
#' "extdata/out/S2A2A_20190723_022_Barbellino_BOA_10.tif",
#' package = "sen2r"
#' )
#'
#' \donttest{
#' ## gdalinfo
#' out0 <- gdalUtil("info", examplename, quiet = TRUE)
#' message(out0)
#'
#' ## gdal_translate
#' outname1 <- tempfile(fileext = ".tif")
#' gdalUtil(
#' "translate",
#' examplename, outname1,
#' options = c("-tr", "2", "2", "-r", "cubicspline", "-co", "COMPRESS=DEFLATE")
#' )
#' oldpar <- par(mfrow = c(1,2), mar = rep(0,4))
#' image(stars::read_stars(examplename), rgb = c(11,8,4))
#' image(stars::read_stars(outname1), rgb = c(11,8,4))

#'
#' ## gdalwarp
#' outname2 <- tempfile(fileext = ".tif")
#' gdalUtil(
#' "warp",
#' examplename, outname2,
#' options = c("-t_srs", "EPSG:32633", "-co", "COMPRESS=DEFLATE")
#' )
#' oldpar <- par(mfrow = c(1,2), mar = rep(0,4))
#' image(stars::read_stars(examplename), rgb = c(11,8,4))
#' image(stars::read_stars(outname2), rgb = c(11,8,4))
#'
#' ## gdal_calc
#' outname3 <- tempfile(fileext = ".tif")
#' ndvirefname <- system.file(
#' "extdata/out/S2A2A_20190723_022_Barbellino_NDVI_10.tif",
#' package = "sen2r"
#' )
#' gdalUtil(
#' "calc",
#' rep(examplename,2), outname3,
#' formula = "10000*(A.astype(float)-B)/(A+B)",
#' options = c("--A_band", "8", "--B_band", "4", "--type", "Int16")
#' )
#' oldpar <- par(mfrow = c(1,2), mar = rep(0,4))
#' image(stars::read_stars(ndvirefname))
#' image(stars::read_stars(outname3))
#' }



gdalUtil <-function(
util = "info",
source,
destination = character(0),
options = character(0),
quiet = FALSE,
formula = character(0),
processing = character(0),
colorfilename = character(0)
) {

# Check "util"
utils <- c(
"info" = "gdalinfo",
"translate" = "gdal_translate",
"warp" = "gdalwarp",
"demprocessing" = "gdaldem" ,
"buildvrt" = "gdalbuildvrt",
"calc" = "gdal_calc",
"fillnodata" = "gdal_fillnodata"
)
if (!util %in% names(utils)) {
print_message(
type = "error",
"Currently, method '",util,"' is not implemented."
)
}

# Check additional arguments
if (util != "info" && missing(destination)) {
print_message(
type = "error",
"Argument \"destination\" is missing, with no default."
)
}
if (util == "calc" && missing(formula)) {
print_message(
type = "error",
"Argument \"formula\" is required for gdal_calc."
)
}
if (util == "demprocessing" && missing(processing)) {
print_message(
type = "error",
"Argument \"processing\" is required for gdaldem."
)
}
if (util == "demprocessing" && processing == "color-relief" && missing(colorfilename)) {
print_message(
type = "error",
"Argument \"colorfilename\" is required for gdaldem with mode 'color-relief'."
)
}

# Choose the modality to proceed (sf::gdal_utils or system call)
if (util %in% c("calc", "fillnodata")) {

## System call mode

# Load GDAL paths
binpaths <- load_binpaths("gdal")
init_python()

# Normalise paths
source <- normalize_path(source, mustWork = TRUE)
destination <- normalize_path(destination, mustWork = FALSE)

# Define arguments
gdal_args <- if (util %in% c("fillnodata")) {
list(
"sys" = c(options, source, destination),
"base" = paste0(
paste(options, collapse = " ")," ",
source," ",destination
)
)
} else if (util %in% c("calc")) {
list(
"sys" = c(
unlist(lapply(seq_along(source), function(i) {c(paste0("-",LETTERS[i]), source[i])})),
"--outfile", destination,
"--calc", formula,
options
),
"base" = paste0(
paste(paste0("-",LETTERS[seq_along(source)]," \"",source,"\""), collapse = " ")," ",
"--outfile=\"",destination,"\" ",
"--calc=\"",formula,"\" ",
paste(options, collapse = " ")
)
)
}

# use exec_wait if sys is installed, system otherwise
gdal_out <- if (requireNamespace("sys", quietly = TRUE)) {
sel_log_output <- if (quiet) {
tempfile(pattern = "stdout_", fileext = ".txt")
} else {NA}
sys::exec_wait(
binpaths[[utils[util]]],
args = gdal_args$sys,
std_out = sel_log_output
)
} else {
system(
paste(binpaths[[utils[util]]], gdal_args$base),
intern = Sys.info()["sysname"] == "Windows"
)
}
invisible(gdal_out == 0)

# end of system call modality

} else {

## Use gdal_utils()

# Normalise paths
# (use canonical instead than short form to avoid problems with
# ENVI header files)
source <- normalizePath(source, mustWork = TRUE)
destination <- normalizePath(destination, mustWork = FALSE)

gdal_utils(
util = util,
source = source,
destination = destination,
options = options,
quiet = quiet,
processing = processing,
colorfilename = colorfilename
)

}

}
Loading

0 comments on commit 7f0b41b

Please sign in to comment.