From 866e4198dcc728f0e4a78d05d5ec81457167ec4c Mon Sep 17 00:00:00 2001 From: Michael Sumner Date: Fri, 28 Apr 2023 18:50:52 +1000 Subject: [PATCH] support for wk, various fixes new RC 1.0.5 clarifications doc typo fix tweaks ugh get it right, I think --- DESCRIPTION | 17 +++--- NEWS.md | 13 +++- R/RcppExports.R | 55 +---------------- R/fasterize.R | 93 +++++++++++++++++++++++++++++ R/package.R | 17 ++++-- cran-comments.md | 10 +--- inst/WORDLIST | 13 ++++ man/fasterize-package.Rd | 38 ++++++++++++ man/fasterize.Rd | 22 +++---- src/RcppExports.cpp | 10 ++-- src/check_inputs.cpp | 2 +- src/fasterize.cpp | 53 +--------------- tests/spelling.Rout.save | 25 ++++++++ tests/testthat/test-01-inputcheck.R | 34 +++++++++-- tests/testthat/test-02-fasterize.R | 3 +- tests/testthat/test-05-by.R | 5 +- 16 files changed, 259 insertions(+), 151 deletions(-) create mode 100644 R/fasterize.R create mode 100644 man/fasterize-package.Rd create mode 100644 tests/spelling.Rout.save diff --git a/DESCRIPTION b/DESCRIPTION index f516bf0..7a1fbe5 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: fasterize Title: Fast Polygon to Raster Conversion -Version: 1.0.4.9002 +Version: 1.0.5 Authors@R: c( person("Noam", "Ross", , "ross@ecohealthalliance.org", role = c("aut"), @@ -12,28 +12,29 @@ Authors@R: c( person("EcoHealth Alliance", role="cph"), person("USAID PREDICT", role = "fnd")) Description: Provides a drop-in replacement for rasterize() from the 'raster' - package that takes 'sf'-type objects, and is much faster. There is support - for the main options provided by the rasterize() function, including - setting the field used and background value, and options for + package that takes polygon vector or dataframe objects, and is much faster. + There is support for the main options provided by the rasterize() function, + including setting the field used and background value, and options for aggregating multi-layer rasters. Uses the scan line algorithm attributed to Wylie et al. (1967) . License: MIT + file LICENSE URL: https://github.com/ecohealthalliance/fasterize BugReports: https://github.com/ecohealthalliance/fasterize/issues -RoxygenNote: 7.2.1 -SystemRequirements: C++11 +RoxygenNote: 7.2.3 Suggests: testthat, microbenchmark, knitr, rmarkdown, sf, - spelling + spelling, + geos Depends: R (>= 3.3.0) Imports: Rcpp, - raster (>= 2.8-3) + raster (>= 2.8-3), + wk LinkingTo: Rcpp, RcppArmadillo diff --git a/NEWS.md b/NEWS.md index 711fe9b..61f9ef0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,4 +1,15 @@ -# fasterize dev +# fasterize 1.0.5 + +* Input geometries may now be of type "sfc_GEOMETRY" or other mixed types. Any non polygon + geometry is dropped with a message. + +* 'field' may now be a numeric, integer, or factor vector or (as before) a name of a column in + the input data frame. This means we can `fasterize(vec, r, field = seq_along(vec))` or + `fasterize(df, r, field = seq_len(dim(df)[1L]))` or with any values we like. + +* Now supporting any geometry or dataframe input supported by wk (wkb, wkt, geos, as well as sf). + +* Namespaced documentation fixes thanks to CRAN. * Removed raster raster() method, not needed (raster handles sf now to obtain the 6 numbers and a string). diff --git a/R/RcppExports.R b/R/RcppExports.R index 99d8ac0..51a4130 100644 --- a/R/RcppExports.R +++ b/R/RcppExports.R @@ -1,58 +1,7 @@ # Generated by using Rcpp::compileAttributes() -> do not edit by hand # Generator token: 10BE3573-1514-4C36-9D1C-5A225CD40393 -#' Rasterize an sf object of polygons -#' -#' Rasterize set of polygons -#' -#' This is a high-performance replacement for [raster::rasterize()]. -#' -#' The algorithm is based on the method described in course materials provided -#' by [Wayne O. Cochran](https://labs.wsu.edu/wayne-cochran/). The algorithm -#' is originally attributed to -#' Wylie et al. (1967) \doi{10.1145/1465611.1465619}. -#' -#' @param sf an [sf::sf()] object with a geometry column of POLYGON and/or -#' MULTIPOLYGON objects. -#' @param raster A raster object. Used as a template for the raster output. -#' Can be created with [raster::raster()]. -#' The fasterize package provides a method to create a raster object from -#' an sf object. -#' @param field character. The name of a column in `sf`, -#' providing a value for each of the polygons rasterized. If NULL (default), -#' all polygons will be given a value of 1. -#' @param fun character. The name of a function by which to combine overlapping -#' polygons. Currently takes "sum", "first", "last", "min", "max", "count", or -#' "any". Future versions may include more functions or the ability to pass -#' custom R/C++ functions. If you need to summarize by a different function, -#' use `by=` to get a RasterBrick and then [raster::stackApply()] or -#' [raster::calc()] to summarize. -#' @param background numeric. Value to put in the cells that are not covered by -#' any of the features of x. Default is NA. -#' @param by character. The name of a column in `sf` by which to aggregate -#' layers. If set, fasterize will return a RasterBrick with as many layers -#' as unique values of the `by` column. -#' @return A raster of the same size, extent, resolution and projection as the -#' provided raster template. -#' @references Wylie, C., Romney, G., Evans, D., & Erdahl, A. (1967). -#' Half-tone perspective drawings by computer. Proceedings of the November -#' 14-16, 1967, Fall Joint Computer Conference. AFIPS '67 (Fall). -#' \doi{10.1145/1465611.1465619} -#' @examples -#' library(sf) -#' library(fasterize) -#' p1 <- rbind(c(-180,-20), c(-140,55), c(10, 0), c(-140,-60), c(-180,-20)) -#' hole <- rbind(c(-150,-20), c(-100,-10), c(-110,20), c(-150,-20)) -#' p1 <- list(p1, hole) -#' p2 <- list(rbind(c(-10,0), c(140,60), c(160,0), c(140,-55), c(-10,0))) -#' p3 <- list(rbind(c(-125,0), c(0,60), c(40,5), c(15,-45), c(-125,0))) -#' pols <- st_sf(value = rep(1,3), -#' geometry = st_sfc(lapply(list(p1, p2, p3), st_polygon))) -#' r <- raster(pols, res = 1) -#' r <- fasterize(pols, r, field = "value", fun="sum") -#' plot(r) -#' @export -fasterize <- function(sf, raster, field = NULL, fun = "last", background = NA_real_, by = NULL) { - .Call('_fasterize_fasterize', PACKAGE = 'fasterize', sf, raster, field, fun, background, by) +fasterize_cpp <- function(sf, raster, field = NULL, fun = "last", background = NA_real_, by = NULL) { + .Call('_fasterize_fasterize_cpp', PACKAGE = 'fasterize', sf, raster, field, fun, background, by) } diff --git a/R/fasterize.R b/R/fasterize.R new file mode 100644 index 0000000..ad0a3db --- /dev/null +++ b/R/fasterize.R @@ -0,0 +1,93 @@ +make_sf <- function(x, attr = NULL) { + structure(list(geom = x), names = c("geom"), row.names = seq_len(length(x)), + sf_column = "geom", class = c("sf", "data.frame" )) +} + + +#' Rasterize a vector or dataframe object of polygons +#' +#' Rasterize set of polygons +#' +#' This is a high-performance replacement for [raster::rasterize()]. +#' +#' The algorithm is based on the method described in course materials provided +#' by [Wayne O. Cochran](https://labs.wsu.edu/wayne-cochran/). The algorithm +#' is originally attributed to +#' Wylie et al. (1967) \doi{10.1145/1465611.1465619}. +#' +#' Note that original implementation worked only for sf dataframes of class "sf", but this +#' now works for any polygon vector (sfc, wkt, wkb, geos) or dataframe with a polygon vector +#' supported by the wk package handlers. +#' +#' @param sf a polygon vector or data frame object with a geometry column of POLYGON and/or +#' MULTIPOLYGON (equivalent) objects. +#' @param raster A raster object. Used as a template for the raster output. +#' Can be created with [raster::raster()]. +#' The fasterize package provides a method to create a raster object from +#' an polygon dataset. +#' @param field character (or numeric vector). The name of a column in `sf`, +#' providing a value for each of the polygons rasterized. If NULL (default), +#' all polygons will be given a value of 1. If a numeric vector this value +#' will be used as the value given to the pixel. (No recyling is done). +#' @param fun character. The name of a function by which to combine overlapping +#' polygons. Currently takes "sum", "first", "last", "min", "max", "count", or +#' "any". Future versions may include more functions or the ability to pass +#' custom R/C++ functions. If you need to summarize by a different function, +#' use `by=` to get a RasterBrick and then [raster::stackApply()] or +#' [raster::calc()] to summarize. +#' @param background numeric. Value to put in the cells that are not covered by +#' any of the features of x. Default is NA. +#' @param by character. The name of a column in `sf` by which to aggregate +#' layers. If set, fasterize will return a RasterBrick with as many layers +#' as unique values of the `by` column. +#' @return A raster of the same size, extent, resolution and projection as the +#' provided raster template. +#' @references Wylie, C., Romney, G., Evans, D., & Erdahl, A. (1967). +#' Half-tone perspective drawings by computer. Proceedings of the November +#' 14-16, 1967, Fall Joint Computer Conference. AFIPS '67 (Fall). +#' \doi{10.1145/1465611.1465619} +#' @examples +#' library(sf) +#' library(fasterize) +#' p1 <- rbind(c(-180,-20), c(-140,55), c(10, 0), c(-140,-60), c(-180,-20)) +#' hole <- rbind(c(-150,-20), c(-100,-10), c(-110,20), c(-150,-20)) +#' p1 <- list(p1, hole) +#' p2 <- list(rbind(c(-10,0), c(140,60), c(160,0), c(140,-55), c(-10,0))) +#' p3 <- list(rbind(c(-125,0), c(0,60), c(40,5), c(15,-45), c(-125,0))) +#' pols <- st_sf(value = rep(1,3), +#' geometry = st_sfc(lapply(list(p1, p2, p3), st_polygon))) +#' r <- raster(pols, res = 1) +#' r <- fasterize(pols, r, field = "value", fun="sum") +#' plot(r) +#' @export +fasterize <- function(sf, raster, field = NULL, fun = "last", background = NA_real_, by = NULL) { + + ## check the types up here + types <- wk::wk_meta(sf)$geometry_type + bad <- ! types %in% c(3, 6) + + ## ok so we get geometry from anything wk can handle + geom <- wk::wk_handle(sf, wk::sfc_writer()) + + if (any(bad)) { + if (all(bad)) stop("no polygon geometries to fasterize") + geom <- geom[!bad, ] + message(sprintf("removing %i geometries that are not polygon or multipolygon equivalent", sum(bad))) + } + + + sf1 <- make_sf(geom) + if ( !is.null(field)) { + if (length(field) == 1L) { + sf1[[field]] <- sf[[field]] + } else if (length(field) == dim(sf1)[1L]) { + sf1[["field"]] <- field + field <- "field" + } + } + if (inherits(sf, "data.frame") && !is.null(by)) { + sf1[[by]] <- sf[[by]] + } + fasterize_cpp(sf1, raster, field, fun, background, by) +} + diff --git a/R/package.R b/R/package.R index 9569899..0dd261c 100644 --- a/R/package.R +++ b/R/package.R @@ -1,10 +1,17 @@ -#' Fast sf-to-raster conversion -#' -#' Fast sf-to-raster conversion +#' @keywords internal +#' @aliases fasterize-package +"_PACKAGE" + +## usethis namespace: start +## usethis namespace: end +NULL + +#' Fast polygons-to-raster conversion #' -#' @docType package -#' @name fasterize +#' Fast polygons-to-raster conversion +#' @name fasterize-package + NULL #' @useDynLib fasterize diff --git a/cran-comments.md b/cran-comments.md index 1e5b35b..ebf4471 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,12 +1,8 @@ -## R CMD check results -0 errors | 0 warnings | 0 notes +# fasterize 1.0.5 -* Submitted by new maintainer, Michael Sumner (mdsumner@gmail.com), change from Noam Ross (ross@ecohealthalliance.org) as advised by email. - -* Fixes CRAN warnings on bitwise operator and unused LazyData. - -* Fixes implicit type warnings found with clang. +* Fixes for roxygen namespace documentation and remove specific C++11 requirement. +Thanks! diff --git a/inst/WORDLIST b/inst/WORDLIST index 6e814cf..7350952 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -7,26 +7,39 @@ GEOS IUCN LazyData MULTIPOLYGON +Namespaced +ORCID PROJ RStudio RasterBrick Rasterize Rcpp USAID +Wconversion al +cpp devtools doi ecohealthalliance +edgelist edu et +funder gcc +geos https +md ohi rasterize rasterized rasterizing rasters +respository +terra toolchain ucdavis +uword vetmed +wkb +wkt www diff --git a/man/fasterize-package.Rd b/man/fasterize-package.Rd new file mode 100644 index 0000000..3d4c4ad --- /dev/null +++ b/man/fasterize-package.Rd @@ -0,0 +1,38 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/package.R +\docType{package} +\name{fasterize-package} +\alias{fasterize-package} +\alias{_PACKAGE} +\title{fasterize: Fast Polygon to Raster Conversion} +\description{ +Provides a drop-in replacement for rasterize() from the 'raster' package that takes polygon vector or dataframe objects, and is much faster. There is support for the main options provided by the rasterize() function, including setting the field used and background value, and options for aggregating multi-layer rasters. Uses the scan line algorithm attributed to Wylie et al. (1967) \doi{10.1145/1465611.1465619}. + +Fast polygons-to-raster conversion +} +\seealso{ +Useful links: +\itemize{ + \item \url{https://github.com/ecohealthalliance/fasterize} + \item Report bugs at \url{https://github.com/ecohealthalliance/fasterize/issues} +} + +} +\author{ +\strong{Maintainer}: Michael Sumner \email{mdsumner@gmail.com} (\href{https://orcid.org/0000-0002-2471-7511}{ORCID}) [contributor] + +Authors: +\itemize{ + \item Noam Ross \email{ross@ecohealthalliance.org} (\href{https://orcid.org/0000-0002-2136-0000}{ORCID}) (Original author) +} + +Other contributors: +\itemize{ + \item Jeroen Ooms [contributor] + \item Antoine Stevens [contributor] + \item EcoHealth Alliance [copyright holder] + \item USAID PREDICT [funder] +} + +} +\keyword{internal} diff --git a/man/fasterize.Rd b/man/fasterize.Rd index 95ceaa6..4c457bd 100644 --- a/man/fasterize.Rd +++ b/man/fasterize.Rd @@ -1,9 +1,8 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/RcppExports.R, R/package.R -\docType{package} +% Please edit documentation in R/fasterize.R \name{fasterize} \alias{fasterize} -\title{Rasterize an sf object of polygons} +\title{Rasterize a vector or dataframe object of polygons} \usage{ fasterize( sf, @@ -15,17 +14,18 @@ fasterize( ) } \arguments{ -\item{sf}{an \code{\link[sf:sf]{sf::sf()}} object with a geometry column of POLYGON and/or -MULTIPOLYGON objects.} +\item{sf}{a polygon vector or data frame object with a geometry column of POLYGON and/or +MULTIPOLYGON (equivalent) objects.} \item{raster}{A raster object. Used as a template for the raster output. Can be created with \code{\link[raster:raster]{raster::raster()}}. The fasterize package provides a method to create a raster object from -an sf object.} +an polygon dataset.} -\item{field}{character. The name of a column in \code{sf}, +\item{field}{character (or numeric vector). The name of a column in \code{sf}, providing a value for each of the polygons rasterized. If NULL (default), -all polygons will be given a value of 1.} +all polygons will be given a value of 1. If a numeric vector this value +will be used as the value given to the pixel. (No recyling is done).} \item{fun}{character. The name of a function by which to combine overlapping polygons. Currently takes "sum", "first", "last", "min", "max", "count", or @@ -47,8 +47,6 @@ provided raster template. } \description{ Rasterize set of polygons - -Fast sf-to-raster conversion } \details{ This is a high-performance replacement for \code{\link[raster:rasterize]{raster::rasterize()}}. @@ -57,6 +55,10 @@ The algorithm is based on the method described in course materials provided by \href{https://labs.wsu.edu/wayne-cochran/}{Wayne O. Cochran}. The algorithm is originally attributed to Wylie et al. (1967) \doi{10.1145/1465611.1465619}. + +Note that original implementation worked only for sf dataframes of class "sf", but this +now works for any polygon vector (sfc, wkt, wkb, geos) or dataframe with a polygon vector +supported by the wk package handlers. } \examples{ library(sf) diff --git a/src/RcppExports.cpp b/src/RcppExports.cpp index cb2716d..98c0d14 100644 --- a/src/RcppExports.cpp +++ b/src/RcppExports.cpp @@ -11,9 +11,9 @@ Rcpp::Rostream& Rcpp::Rcout = Rcpp::Rcpp_cout_get(); Rcpp::Rostream& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get(); #endif -// fasterize -Rcpp::S4 fasterize(Rcpp::DataFrame& sf, Rcpp::S4& raster, Rcpp::Nullable field, std::string fun, double background, Rcpp::Nullable by); -RcppExport SEXP _fasterize_fasterize(SEXP sfSEXP, SEXP rasterSEXP, SEXP fieldSEXP, SEXP funSEXP, SEXP backgroundSEXP, SEXP bySEXP) { +// fasterize_cpp +Rcpp::S4 fasterize_cpp(Rcpp::DataFrame& sf, Rcpp::S4& raster, Rcpp::Nullable field, std::string fun, double background, Rcpp::Nullable by); +RcppExport SEXP _fasterize_fasterize_cpp(SEXP sfSEXP, SEXP rasterSEXP, SEXP fieldSEXP, SEXP funSEXP, SEXP backgroundSEXP, SEXP bySEXP) { BEGIN_RCPP Rcpp::RObject rcpp_result_gen; Rcpp::RNGScope rcpp_rngScope_gen; @@ -23,13 +23,13 @@ BEGIN_RCPP Rcpp::traits::input_parameter< std::string >::type fun(funSEXP); Rcpp::traits::input_parameter< double >::type background(backgroundSEXP); Rcpp::traits::input_parameter< Rcpp::Nullable >::type by(bySEXP); - rcpp_result_gen = Rcpp::wrap(fasterize(sf, raster, field, fun, background, by)); + rcpp_result_gen = Rcpp::wrap(fasterize_cpp(sf, raster, field, fun, background, by)); return rcpp_result_gen; END_RCPP } static const R_CallMethodDef CallEntries[] = { - {"_fasterize_fasterize", (DL_FUNC) &_fasterize_fasterize, 6}, + {"_fasterize_fasterize_cpp", (DL_FUNC) &_fasterize_fasterize_cpp, 6}, {NULL, NULL, 0} }; diff --git a/src/check_inputs.cpp b/src/check_inputs.cpp index 6a1d6a9..cb5e95e 100644 --- a/src/check_inputs.cpp +++ b/src/check_inputs.cpp @@ -20,7 +20,7 @@ void check_inputs(Rcpp::DataFrame &sf, polygons = sf[Rcpp::as(sf.attr("sf_column"))]; if(!(Rf_inherits(polygons, "sfc_MULTIPOLYGON") | - Rf_inherits(polygons, "sfc_POLYGON"))) { + Rf_inherits(polygons, "sfc_POLYGON") | Rf_inherits(polygons, "sfc_GEOMETRY"))) { err_msg << "sf geometry must be POLYGON or MULTIPOLYGON" << std::endl; } diff --git a/src/fasterize.cpp b/src/fasterize.cpp index 6c8a0ef..3e1c5cc 100644 --- a/src/fasterize.cpp +++ b/src/fasterize.cpp @@ -9,59 +9,8 @@ // [[Rcpp::plugins(cpp11)] // [[Rcpp::depends(RcppArmadillo)]] -//' Rasterize an sf object of polygons -//' -//' Rasterize set of polygons -//' -//' This is a high-performance replacement for [raster::rasterize()]. -//' -//' The algorithm is based on the method described in course materials provided -//' by [Wayne O. Cochran](https://labs.wsu.edu/wayne-cochran/). The algorithm -//' is originally attributed to -//' Wylie et al. (1967) \doi{10.1145/1465611.1465619}. -//' -//' @param sf an [sf::sf()] object with a geometry column of POLYGON and/or -//' MULTIPOLYGON objects. -//' @param raster A raster object. Used as a template for the raster output. -//' Can be created with [raster::raster()]. -//' The fasterize package provides a method to create a raster object from -//' an sf object. -//' @param field character. The name of a column in `sf`, -//' providing a value for each of the polygons rasterized. If NULL (default), -//' all polygons will be given a value of 1. -//' @param fun character. The name of a function by which to combine overlapping -//' polygons. Currently takes "sum", "first", "last", "min", "max", "count", or -//' "any". Future versions may include more functions or the ability to pass -//' custom R/C++ functions. If you need to summarize by a different function, -//' use `by=` to get a RasterBrick and then [raster::stackApply()] or -//' [raster::calc()] to summarize. -//' @param background numeric. Value to put in the cells that are not covered by -//' any of the features of x. Default is NA. -//' @param by character. The name of a column in `sf` by which to aggregate -//' layers. If set, fasterize will return a RasterBrick with as many layers -//' as unique values of the `by` column. -//' @return A raster of the same size, extent, resolution and projection as the -//' provided raster template. -//' @references Wylie, C., Romney, G., Evans, D., & Erdahl, A. (1967). -//' Half-tone perspective drawings by computer. Proceedings of the November -//' 14-16, 1967, Fall Joint Computer Conference. AFIPS '67 (Fall). -//' \doi{10.1145/1465611.1465619} -//' @examples -//' library(sf) -//' library(fasterize) -//' p1 <- rbind(c(-180,-20), c(-140,55), c(10, 0), c(-140,-60), c(-180,-20)) -//' hole <- rbind(c(-150,-20), c(-100,-10), c(-110,20), c(-150,-20)) -//' p1 <- list(p1, hole) -//' p2 <- list(rbind(c(-10,0), c(140,60), c(160,0), c(140,-55), c(-10,0))) -//' p3 <- list(rbind(c(-125,0), c(0,60), c(40,5), c(15,-45), c(-125,0))) -//' pols <- st_sf(value = rep(1,3), -//' geometry = st_sfc(lapply(list(p1, p2, p3), st_polygon))) -//' r <- raster(pols, res = 1) -//' r <- fasterize(pols, r, field = "value", fun="sum") -//' plot(r) -//' @export // [[Rcpp::export]] -Rcpp::S4 fasterize(Rcpp::DataFrame &sf, +Rcpp::S4 fasterize_cpp(Rcpp::DataFrame &sf, Rcpp::S4 &raster, Rcpp::Nullable field = R_NilValue, std::string fun = "last", diff --git a/tests/spelling.Rout.save b/tests/spelling.Rout.save new file mode 100644 index 0000000..17bf7b4 --- /dev/null +++ b/tests/spelling.Rout.save @@ -0,0 +1,25 @@ + +R version 3.4.1 (2017-06-30) -- "Single Candle" +Copyright (C) 2017 The R Foundation for Statistical Computing +Platform: x86_64-apple-darwin15.6.0 (64-bit) + +R is free software and comes with ABSOLUTELY NO WARRANTY. +You are welcome to redistribute it under certain conditions. +Type 'license()' or 'licence()' for distribution details. + +R is a collaborative project with many contributors. +Type 'contributors()' for more information and +'citation()' on how to cite R or R packages in publications. + +Type 'demo()' for some demos, 'help()' for on-line help, or +'help.start()' for an HTML browser interface to help. +Type 'q()' to quit R. + +> if(requireNamespace('spelling', quietly = TRUE)) ++ spelling::spell_check_test(vignettes = TRUE, error = FALSE, ++ skip_on_cran = TRUE) +All Done! +> +> proc.time() + user system elapsed + 0.372 0.039 0.408 diff --git a/tests/testthat/test-01-inputcheck.R b/tests/testthat/test-01-inputcheck.R index dd45f34..d82a5b0 100644 --- a/tests/testthat/test-01-inputcheck.R +++ b/tests/testthat/test-01-inputcheck.R @@ -1,6 +1,7 @@ context("input checks") suppressPackageStartupMessages(library(sf)) +library(geos) p1 <- rbind(c(-180,-20), c(-140,55), c(10, 0), c(-140,-60), c(-180,-20)) hole <- rbind(c(-150,-20), c(-100,-10), c(-110,20), c(-150,-20)) p1 <- list(p1, hole) @@ -10,18 +11,39 @@ pols <- st_sf(value = c(1,2,3), geometry = st_sfc(lapply(list(p1, p2, p3), st_polygon))) r1 <- raster(pols, res=1) -test_that("fasterize needs class sf", { - pols_err <- pols - class(pols_err) <- "data.frame" - expect_error(fasterize(pols_err, r1), "sf must be of class sf") -}) +## we now accept any wk-handled class +# test_that("fasterize needs class sf", { +# pols_err <- pols +# class(pols_err) <- "data.frame" +# expect_error(fasterize(pols_err, r1), "sf must be of class sf") +# }) + +test_that("fasterize likes wkt/wkb/geos", { + expect_s4_class(fasterize(wk::as_wkt(pols$geometry), r1), "BasicRaster") + expect_s4_class(fasterize(wk::as_wkb(pols$geometry), r1), "BasicRaster") + expect_s4_class(fasterize(geos::as_geos_geometry(pols$geometry), r1), "BasicRaster") +i <- seq_along(pols$geometry) + expect_s4_class(fasterize(data.frame(a = i, g = wk::as_wkt(pols$geometry)), r1), "BasicRaster") + expect_s4_class(fasterize(data.frame(a = i, wk::as_wkb(pols$geometry)), r1), "BasicRaster") + expect_s4_class(fasterize(data.frame(a = i, geos::as_geos_geometry(pols$geometry)), r1), "BasicRaster") + +}) test_that("fasterize needs polygons", { lines <- st_sf(value = c(1,2,3), geometry = st_sfc(lapply(list(p1, p2, p3), function(x) st_linestring(x[[1]])))) expect_error(fasterize(lines, r1), - "sf geometry must be POLYGON or MULTIPOLYGON") + "no polygon geometries to fasterize") + + lines_wkb <- data.frame(value = c(1,2,3), + geometry = wk::as_wkb(sf::st_cast(pols$geometry, "MULTILINESTRING"))) + + expect_error(fasterize(lines_wkb, r1), + "no polygon geometries to fasterize") + + + }) test_that("field value name is in sf object", { diff --git a/tests/testthat/test-02-fasterize.R b/tests/testthat/test-02-fasterize.R index 2fbbbe4..58da7fe 100644 --- a/tests/testthat/test-02-fasterize.R +++ b/tests/testthat/test-02-fasterize.R @@ -15,6 +15,7 @@ test_that("raster sf method works", { expect_s4_class(r, 'RasterLayer') }) + test_that("fasterize works", { r <- raster(pols, res = 1) expect_error(f <- fasterize(pols, r, field = "value", fun="sum"), NA) @@ -73,6 +74,6 @@ test_that("error thrown for malformed polygon", { pols_err <- pols pols_err$geometry[[2]][[1]] <- as.character(pols_err$geometry[[2]][[1]]) expect_error(f <- fasterize(pols_err, r, field = "value", fun="sum"), - "incompatible SEXP; only accepts lists and REALSXPs") + "REAL\\() can only be applied to a 'numeric', not a 'character'") }) diff --git a/tests/testthat/test-05-by.R b/tests/testthat/test-05-by.R index 2cc3a6e..245d289 100644 --- a/tests/testthat/test-05-by.R +++ b/tests/testthat/test-05-by.R @@ -17,16 +17,17 @@ r1 <- raster(pols, res=1) test_that("'by' argument works", { expect_error( - rb <-fasterize(pols, r1, field="value", fun="sum", by ="by_1"),NA) + rb <-fasterize(pols, r1, field="value", fun="sum", by ="by_1"), NA) expect_equal(names(rb), unique(pols$by_1)) expect_equal(ncol(rb@data@values), length(unique(pols$by_1))) }) test_that("'by' layers are equivalent to layers generated separately", { rba <- fasterize(pols, r1, field="value", fun="sum", by ="value") - for(i in nrow(pols)) + for(i in 1:nrow(pols)) { expect_equal(as.raster(rba[[i]]), as.raster(fasterize(pols[i,], r1, field="value", fun="sum"))) + } }) test_that("'by' can handle non-character fields", {