Skip to content

Commit

Permalink
switched from rlang to checkmate
Browse files Browse the repository at this point in the history
  • Loading branch information
atsyplenkov committed Sep 29, 2024
1 parent d8c0608 commit 6366aba
Show file tree
Hide file tree
Showing 4 changed files with 170 additions and 151 deletions.
28 changes: 19 additions & 9 deletions R/cnt_skeleton.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
#' @param keep numeric, proportion of points to retain (0.05-Inf; default 0.5).
#' See Details.
#' @param method character, either \code{"voronoi"} (default) or
#' \code{"straight"}. See Details.
#' \code{"straight"}, or just the first letter \code{"v"} or \code{"s"}.
#' See Details.
#'
#' @details
#' ## Polygon simplification/densification
Expand Down Expand Up @@ -79,7 +80,8 @@ cnt_skeleton.geos_geometry <-
method = c("voronoi", "straight")) {
# Check input arguments
stopifnot(check_polygons(input))
method <- rlang::arg_match(method)
checkmate::assert_number(keep, lower = 0, upper = 5)
method <- checkmate::matchArg(method, choices = c("voronoi", "straight"))

# Save CRS
crs <- wk::wk_crs(input)
Expand Down Expand Up @@ -114,7 +116,8 @@ cnt_skeleton.sf <-
method = c("voronoi", "straight")) {
# Check input arguments
stopifnot(check_polygons(input))
method <- rlang::arg_match(method)
checkmate::assert_number(keep, lower = 0, upper = 5)
method <- checkmate::matchArg(method, choices = c("voronoi", "straight"))

# Save CRS
crs <- sf::st_crs(input)
Expand Down Expand Up @@ -155,7 +158,8 @@ cnt_skeleton.sfc <-
method = c("voronoi", "straight")) {
# Check input arguments
stopifnot(check_polygons(input))
method <- rlang::arg_match(method)
checkmate::assert_number(keep, lower = 0, upper = 5)
method <- checkmate::matchArg(method, choices = c("voronoi", "straight"))

# Save CRS
crs <- sf::st_crs(input)
Expand Down Expand Up @@ -193,11 +197,12 @@ cnt_skeleton.SpatVector <-
function(input,
keep = 0.5,
method = c("voronoi", "straight")) {
rlang::check_installed("terra")
check_package("terra")

# Check input arguments
stopifnot(check_polygons(input))
method <- rlang::arg_match(method)
checkmate::assert_number(keep, lower = 0, upper = 5)
method <- checkmate::matchArg(method, choices = c("voronoi", "straight"))

# Input attributes
input_data <- terra::as.data.frame(input)
Expand Down Expand Up @@ -244,8 +249,6 @@ cnt_skeleton.SpatVector <-
}
}

# TODO:
# - Add keep parameter check (should be double and between 0 and 1)
cnt_skeleton_geos <-
function(input,
keep = 0.5) {
Expand Down Expand Up @@ -282,7 +285,14 @@ cnt_skeleton_geos <-
cnt_skeleton_straight <-
function(input,
keep = 0.5) {
rlang::check_installed("raybevel")
check_package("raybevel")

if (keep > 1) {
warning(
"Generating a straight skeleton with
keep > 1 is not recommended and may take a very long time."
)
}

# Simplify or densify or do nothing
if (keep == 1) {
Expand Down
44 changes: 44 additions & 0 deletions R/transformers.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# Inter-class transformers -----------------------------------------------
# Terra to SF transformer
# This function is five time faster than
# st::st_as_sf() due to {wk} package
terra_to_sf <-
function(input) {
spatial_data <-
terra::as.data.frame(input)

if (length(spatial_data) == 0) {
terra::geom(input, wk = TRUE) |>
wk::as_wkt() |>
sf::st_as_sf() |>
sf::st_set_crs(terra::crs(input))
} else {
terra::geom(input, wk = TRUE) |>
wk::as_wkt() |>
sf::st_as_sf() |>
sf::st_set_crs(terra::crs(input)) |>
cbind(terra::as.data.frame(spatial_data))
}
}

# Terra to GEOS transformer
terra_to_geos <-
function(input) {
input |>
sf::st_as_sf() |>
geos::as_geos_geometry()
# input |>
# terra::geom(wkt = TRUE) |>
# geos::as_geos_geometry(crs = sf::st_crs(input))
}

# GEOS to terra transformer
geos_to_terra <-
function(input) {
wk_input <- wk::as_wkt(input)

terra::vect(
as.character(wk_input),
crs = wk::wk_crs(wk_input)$wkt
)
}
107 changes: 107 additions & 0 deletions R/types-check.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Check is package installed
check_package <-
function(package) {
if (!requireNamespace(package, quietly = TRUE)) {
stop(paste(package, "is required but not installed."))
}
}

# Check that all objects share the same class
check_same_class <-
function(obj1, obj2, obj3) {
class1 <- class(obj1)
class2 <- class(obj2)
class3 <- class(obj3)

class_check <-
base::identical(class1, class2) &&
base::identical(class1, class3)

if (!class_check) {
stop("All objects must share the same class.")
}
}

# Get geometry type of the spatial object
get_geom_type <-
function(input) {
if (inherits(input, "sf") || inherits(input, "sfc")) {
sf::st_geometry_type(input, by_geometry = TRUE)
} else if (inherits(input, "SpatVector")) {
terra::geomtype(input)
} else if (inherits(input, "geos_geometry")) {
geos::geos_type(input)
}
}

# Checks for polygon geometries
check_polygons <-
function(input) {
# Check if input is of class 'sf', 'sfc', 'SpatVector', or 'geos_geometry'
if (!inherits(input, c("sf", "sfc", "SpatVector", "geos_geometry"))) {
stop(
"Input is not of
class 'sf', 'sfc', 'SpatVector', or 'geos_geometry'."
)
}

# Check if geometry type is POLYGON
geom_type <- get_geom_type(input)
if (
!all(geom_type %in%
c("POLYGON", "polygons", "polygon", "multipolygon", "MULTIPOLYGON"))
) {
stop("Input does not contain 'POLYGON' or 'MULTIPOLYGON' geometries.")
}

# If checks pass
return(TRUE)
}

# Checks for linestring geometries
check_lines <-
function(input) {
# Check if input is of class 'sf', 'sfc', 'SpatVector', or 'geos_geometry'
if (!inherits(input, c("sf", "sfc", "SpatVector", "geos_geometry"))) {
stop(
"Input skeleton is not of
class 'sf', 'sfc', 'SpatVector', or 'geos_geometry'."
)
}

# Check if geometry type is LINESTRING
geom_type <- get_geom_type(input)
if (
!all(geom_type %in%
c(
"LINESTRING", "lines", "linestring",
"multilinestring", "MULTILINESTRING"
))) {
stop("Input skeleton does not contain 'LINESTRING' geometry.")
}

# If checks pass
return(TRUE)
}

# Checks for points geometries
check_points <-
function(input) {
# Check if input is of class 'sf', 'sfc',
# 'SpatVector', or 'geos_geometry'
if (!inherits(input, c("sf", "sfc", "SpatVector", "geos_geometry"))) {
stop(
"Input point is not of
class 'sf', 'sfc', 'SpatVector', or 'geos_geometry'."
)
}

# Check if geometry type is POINT
geom_type <- get_geom_type(input)
if (!all(geom_type %in% c("POINT", "points", "point"))) {
stop("Input point does not contain 'POINT' geometry.")
}

# If checks pass
return(TRUE)
}
142 changes: 0 additions & 142 deletions R/utils.R
Original file line number Diff line number Diff line change
@@ -1,145 +1,3 @@
# Inter-class transformers -----------------------------------------------
# Terra to SF transformer
# This function is five time faster than
# st::st_as_sf() due to {wk} package
terra_to_sf <-
function(input) {
spatial_data <-
terra::as.data.frame(input)

if (length(spatial_data) == 0) {
terra::geom(input, wk = TRUE) |>
wk::as_wkt() |>
sf::st_as_sf() |>
sf::st_set_crs(terra::crs(input))
} else {
terra::geom(input, wk = TRUE) |>
wk::as_wkt() |>
sf::st_as_sf() |>
sf::st_set_crs(terra::crs(input)) |>
cbind(terra::as.data.frame(spatial_data))
}
}

# Terra to GEOS transformer
terra_to_geos <-
function(input) {
input |>
sf::st_as_sf() |>
geos::as_geos_geometry()
# input |>
# terra::geom(wkt = TRUE) |>
# geos::as_geos_geometry(crs = sf::st_crs(input))
}

# GEOS to terra transformer
geos_to_terra <-
function(input) {
wk_input <- wk::as_wkt(input)

terra::vect(
as.character(wk_input),
crs = wk::wk_crs(wk_input)$wkt
)
}

# Class checks -----------------------------------------------------------
# Check that all objects share the same class
check_same_class <- function(obj1, obj2, obj3) {
class1 <- class(obj1)
class2 <- class(obj2)
class3 <- class(obj3)

class_check <-
base::identical(class1, class2) &&
base::identical(class1, class3)

if (!class_check) {
stop("All objects must share the same class.")
}
}

# Get geometry type of the spatial object
get_geom_type <-
function(input) {
if (inherits(input, "sf") || inherits(input, "sfc")) {
sf::st_geometry_type(input, by_geometry = TRUE)
} else if (inherits(input, "SpatVector")) {
terra::geomtype(input)
} else if (inherits(input, "geos_geometry")) {
geos::geos_type(input)
}
}

# Checks for polygon geometries
check_polygons <- function(input) {
# Check if input is of class 'sf', 'sfc', 'SpatVector', or 'geos_geometry'
if (!inherits(input, c("sf", "sfc", "SpatVector", "geos_geometry"))) {
stop(
"Input is not of
class 'sf', 'sfc', 'SpatVector', or 'geos_geometry'."
)
}

# Check if geometry type is POLYGON
geom_type <- get_geom_type(input)
if (
!all(geom_type %in%
c("POLYGON", "polygons", "polygon", "multipolygon", "MULTIPOLYGON"))
) {
stop("Input does not contain 'POLYGON' or 'MULTIPOLYGON' geometries.")
}

# If checks pass
return(TRUE)
}

# Checks for linestring geometries
check_lines <- function(input) {
# Check if input is of class 'sf', 'sfc', 'SpatVector', or 'geos_geometry'
if (!inherits(input, c("sf", "sfc", "SpatVector", "geos_geometry"))) {
stop(
"Input skeleton is not of
class 'sf', 'sfc', 'SpatVector', or 'geos_geometry'."
)
}

# Check if geometry type is LINESTRING
geom_type <- get_geom_type(input)
if (
!all(geom_type %in%
c(
"LINESTRING", "lines", "linestring",
"multilinestring", "MULTILINESTRING"
))) {
stop("Input skeleton does not contain 'LINESTRING' geometry.")
}

# If checks pass
return(TRUE)
}

# Checks for points geometries
check_points <- function(input) {
# Check if input is of class 'sf', 'sfc',
# 'SpatVector', or 'geos_geometry'
if (!inherits(input, c("sf", "sfc", "SpatVector", "geos_geometry"))) {
stop(
"Input point is not of
class 'sf', 'sfc', 'SpatVector', or 'geos_geometry'."
)
}

# Check if geometry type is POINT
geom_type <- get_geom_type(input)
if (!all(geom_type %in% c("POINT", "points", "point"))) {
stop("Input point does not contain 'POINT' geometry.")
}

# If checks pass
return(TRUE)
}

# Polygon simplifications ------------------------------------------------
# Fast simplification, similiar to {mapshaper} ms_simplify
geos_ms_simplify <-
Expand Down

1 comment on commit 6366aba

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.