diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index c6e34f04..99989ebc 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -11,14 +11,18 @@ name: R-CMD-check jobs: R-CMD-check: runs-on: ubuntu-latest + strategy: + matrix: + R: [ 'release' ] env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} R_KEEP_PKG_SOURCE: yes steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: r-lib/actions/setup-r@v2 with: + r-version: ${{ matrix.R }} use-public-rspm: true - uses: r-lib/actions/setup-r-dependencies@v2 diff --git a/DESCRIPTION b/DESCRIPTION index 1b561ce2..549742f2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: sfnetworks Title: Tidy Geospatial Networks -Version: 0.6.3 +Version: 0.6.4 Authors@R: c(person(given = "Lucas", family = "van der Meer", @@ -63,4 +63,4 @@ VignetteBuilder: ByteCompile: true Encoding: UTF-8 LazyData: true -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 diff --git a/NEWS.md b/NEWS.md index 0c969dd6..b93fc072 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,13 @@ +# sfnetworks v0.6.4 + +### New features + +* The `sfnetwork()` construction function now has an argument `message` which can be set to `FALSE` when the network validity checks should not print informational messages to the console. Refs [#261](https://github.com/luukvdmeer/sfnetworks/issues/261). + +### Maintenance + +* Code and documentation was updated where needed to align with changes in base R and/or package dependencies. No changes to program logic or behavior. + # sfnetworks v0.6.3 ### Bug fixes diff --git a/R/morphers.R b/R/morphers.R index bbe8a207..86f52376 100644 --- a/R/morphers.R +++ b/R/morphers.R @@ -564,7 +564,7 @@ to_spatial_simple = function(x, remove_multiple = TRUE, remove_loops = TRUE, #' @param protect Nodes to be protected from being removed, no matter if they #' are a pseudo node or not. Can be given as a numeric vector containing node #' indices or a character vector containing node names. Can also be a set of -#' geospatial features as object of class code{\link[sf]{sf}} or +#' geospatial features as object of class \code{\link[sf]{sf}} or #' \code{\link[sf]{sfc}}. In that case, for each of these features its nearest #' node in the network will be protected. Defaults to \code{NULL}, meaning that #' none of the nodes is protected. diff --git a/R/sfnetwork.R b/R/sfnetwork.R index 531c6612..889797de 100644 --- a/R/sfnetwork.R +++ b/R/sfnetwork.R @@ -53,6 +53,10 @@ #' your input data meet the requirements, the checks are unnecessary and can be #' turned off to improve performance. #' +#' @param message Should informational messages (those messages that are +#' neither warnings nor errors) be printed when constructing the network? +#' Defaults to \code{TRUE}. +#' #' @param ... Arguments passed on to \code{\link[sf]{st_as_sf}}, if nodes need #' to be converted into an \code{\link[sf]{sf}} object during construction. #' @@ -102,7 +106,7 @@ #' @export sfnetwork = function(nodes, edges = NULL, directed = TRUE, node_key = "name", edges_as_lines = NULL, length_as_weight = FALSE, - force = FALSE, ...) { + force = FALSE, message = TRUE, ...) { # Prepare nodes. # If nodes is not an sf object: # --> Try to convert it to an sf object. @@ -140,12 +144,12 @@ sfnetwork = function(nodes, edges = NULL, directed = TRUE, node_key = "name", # --> Adding additional attributes if requested. if (is.null(edges)) { # Run validity check for nodes only and return the network. - if (! force) require_valid_network_structure(x_sfn, message = TRUE) + if (! force) require_valid_network_structure(x_sfn, message = message) return (x_sfn) } if (edges_as_lines) { # Run validity check before explicitizing edges. - if (! force) require_valid_network_structure(x_sfn, message = TRUE) + if (! force) require_valid_network_structure(x_sfn, message = message) # Add edge geometries if needed. if (edges_are_explicit) { # Edges already have geometries, we don't need to add them. @@ -163,7 +167,7 @@ sfnetwork = function(nodes, edges = NULL, directed = TRUE, node_key = "name", x_sfn = implicitize_edges(x_sfn) } # Run validity check after implicitizing edges. - if (! force) require_valid_network_structure(x_sfn, message = TRUE) + if (! force) require_valid_network_structure(x_sfn, message = message) } if (length_as_weight) { edges = edges_as_sf(x_sfn) diff --git a/R/spatstat.R b/R/spatstat.R index 306e57fb..bee92db2 100644 --- a/R/spatstat.R +++ b/R/spatstat.R @@ -15,7 +15,7 @@ check_spatstat = function(pkg) { ) } else { spst_ver = try(packageVersion("spatstat"), silent = TRUE) - if (!inherits(spst_ver, "try-error") && spst_ver < 2.0-0) { + if (!inherits(spst_ver, "try-error") && spst_ver < "2.0-0") { stop( "You have an old version of spatstat which is incompatible with ", pkg, diff --git a/man/as.linnet.Rd b/man/as.linnet.Rd index ac814f8b..a4c61239 100644 --- a/man/as.linnet.Rd +++ b/man/as.linnet.Rd @@ -5,7 +5,7 @@ \alias{as.linnet.sfnetwork} \title{Convert a sfnetwork into a linnet} \usage{ -\method{as.linnet}{sfnetwork}(X, ...) +as.linnet.sfnetwork(X, ...) } \arguments{ \item{X}{An object of class \code{\link{sfnetwork}} with a projected CRS.} diff --git a/man/sfnetwork.Rd b/man/sfnetwork.Rd index c298868b..39cd8fd5 100644 --- a/man/sfnetwork.Rd +++ b/man/sfnetwork.Rd @@ -12,6 +12,7 @@ sfnetwork( edges_as_lines = NULL, length_as_weight = FALSE, force = FALSE, + message = TRUE, ... ) } @@ -63,6 +64,10 @@ These checks are important, but also time consuming. If you are already sure your input data meet the requirements, the checks are unnecessary and can be turned off to improve performance.} +\item{message}{Should informational messages (those messages that are +neither warnings nor errors) be printed when constructing the network? +Defaults to \code{TRUE}.} + \item{...}{Arguments passed on to \code{\link[sf]{st_as_sf}}, if nodes need to be converted into an \code{\link[sf]{sf}} object during construction.} } diff --git a/man/spatial_morphers.Rd b/man/spatial_morphers.Rd index b1e4c6dd..2ad55187 100644 --- a/man/spatial_morphers.Rd +++ b/man/spatial_morphers.Rd @@ -109,7 +109,7 @@ to \code{TRUE}.} \item{protect}{Nodes to be protected from being removed, no matter if they are a pseudo node or not. Can be given as a numeric vector containing node indices or a character vector containing node names. Can also be a set of -geospatial features as object of class code{\link[sf]{sf}} or +geospatial features as object of class \code{\link[sf]{sf}} or \code{\link[sf]{sfc}}. In that case, for each of these features its nearest node in the network will be protected. Defaults to \code{NULL}, meaning that none of the nodes is protected.} diff --git a/tests/testthat/test_morphers.R b/tests/testthat/test_morphers.R index e8654677..ab583308 100644 --- a/tests/testthat/test_morphers.R +++ b/tests/testthat/test_morphers.R @@ -252,8 +252,8 @@ test_that("morphers return same network when there is no morphing suppressWarnings(ecount(convert(subd_u, to_spatial_subdivision))) ) expect_equal( - is.directed(net_d), - is.directed(convert(net_d, to_spatial_directed)) + is_directed(net_d), + is_directed(convert(net_d, to_spatial_directed)) ) expect_setequal( st_geometry(activate(net_l, "edges")), diff --git a/vignettes/sfn04_routing.Rmd b/vignettes/sfn04_routing.Rmd index 18e46700..11aba01f 100644 --- a/vignettes/sfn04_routing.Rmd +++ b/vignettes/sfn04_routing.Rmd @@ -35,7 +35,7 @@ old_hooks = fansi::set_knit_hooks( Calculating shortest paths between pairs of nodes is a core task in network analysis. The `sfnetworks` package offers wrappers around the path calculation functions of `igraph`, making it easier to use them when working with spatial data and tidyverse packages. This vignette demonstrates their functionality. -In this regard it is important to remember that `sfnetworks` is a general-purpose package for spatial network analysis, not specifically optimized for a single task. If your *only* purpose is many-to-many routing in large networks, there might be other approaches that are faster and fit better to your needs. For example, the [dodgr](https://github.com/ATFutures/dodgr) package was designed for many-to-many routing on large dual-weighted graphs, with its main focus on OpenStreetMap road network data. The [cppRouting](https://github.com/vlarmet/cppRouting) package contains functions to calculate shortest paths and isochrones/isodistances on weighted graphs. When working with OpenStreetMap data, it is also possible to use the interfaces to external routing engines such as [graphhopper](https://github.com/crazycapivara/graphhopper-r), [osrm](https://github.com/riatelab/osrm) and [opentripplanner](https://github.com/ropensci/opentripplanner). The [stplanr](https://github.com/ropensci/stplanr) package for sustainable transport planning lets you use many routing engines from a single interface, through `stplanr::route()`, including routing using local R objects. Of course, all these packages can be happily used *alongside* `sfnetworks`. +In this regard it is important to remember that `sfnetworks` is a general-purpose package for spatial network analysis, not specifically optimized for a single task. If your *only* purpose is many-to-many routing in large networks, there might be other approaches that are faster and fit better to your needs. For example, the [dodgr](https://github.com/UrbanAnalyst/dodgr) package was designed for many-to-many routing on large dual-weighted graphs, with its main focus on OpenStreetMap road network data. The [cppRouting](https://github.com/vlarmet/cppRouting) package contains functions to calculate shortest paths and isochrones/isodistances on weighted graphs. When working with OpenStreetMap data, it is also possible to use the interfaces to external routing engines such as [graphhopper](https://github.com/crazycapivara/graphhopper-r), [osrm](https://github.com/riatelab/osrm) and [opentripplanner](https://github.com/ropensci/opentripplanner). The [stplanr](https://github.com/ropensci/stplanr) package for sustainable transport planning lets you use many routing engines from a single interface, through `stplanr::route()`, including routing using local R objects. Of course, all these packages can be happily used *alongside* `sfnetworks`. ```{r, message=FALSE} library(sfnetworks)