diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 1dbac7ff0..da68d3a78 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -8,7 +8,9 @@ on: schedule: - cron: "0 4 * * *" -name: R-CMD-check +name: R-CMD-check.yaml + +permissions: read-all jobs: R-CMD-check: @@ -54,3 +56,4 @@ jobs: - uses: r-lib/actions/check-r-package@v2 with: upload-snapshots: true + build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")' diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 960234cd7..988226098 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -6,7 +6,9 @@ on: pull_request: branches: [main, master] -name: test-coverage +name: test-coverage.yaml + +permissions: read-all jobs: test-coverage: @@ -23,23 +25,32 @@ jobs: - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: any::covr + extra-packages: any::covr, any::xml2 needs: coverage - name: Test coverage run: | - covr::codecov( + cov <- covr::package_coverage( quiet = FALSE, clean = FALSE, install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package") ) + covr::to_cobertura(cov) shell: Rscript {0} + - uses: codecov/codecov-action@v4 + with: + fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }} + file: ./cobertura.xml + plugin: noop + disable_search: true + token: ${{ secrets.CODECOV_TOKEN }} + - name: Show testthat output if: always() run: | ## -------------------------------------------------------------------- - find ${{ runner.temp }}/package -name 'testthat.Rout*' -exec cat '{}' \; || true + find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true shell: bash - name: Upload test results diff --git a/CONDUCT.md b/CONDUCT.md index 52a673e80..b1596bef7 100644 --- a/CONDUCT.md +++ b/CONDUCT.md @@ -22,4 +22,4 @@ opening an issue or contacting one or more of the project maintainers. This Code of Conduct is adapted from the Contributor Covenant (http:contributor-covenant.org), version 1.0.0, available at -http://contributor-covenant.org/version/1/0/0/ +https://www.contributor-covenant.org/version/1/0/0/code-of-conduct/ diff --git a/DESCRIPTION b/DESCRIPTION index aeddd7084..532bd6783 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -136,6 +136,7 @@ Collate: 'wkb.R' 'wkt.R' 'plot.R' + 'geos_binary_pred.R' 'geom-measures.R' 'geom-predicates.R' 'geom-transformers.R' diff --git a/NEWS.md b/NEWS.md index 9206fc31c..2b14e2d4a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -936,7 +936,7 @@ # version 0.5-1 -* add spatial indexes to most binary geometry operations; #394 and http://r-spatial.org/r/2017/06/22/spatial-index.html +* add spatial indexes to most binary geometry operations; #394 and https://r-spatial.org/r/2017/06/22/spatial-index.html * drastically reduce memory footprint of `st_intersection` and similar; #394 diff --git a/PROPOSAL.md b/PROPOSAL.md index e0aec1723..72e708587 100644 --- a/PROPOSAL.md +++ b/PROPOSAL.md @@ -4,7 +4,7 @@ Applicant: [Edzer Pebesma](https://github.com/edzer/), [Institute for Geoinforma Supporting authors: Edzer Pebesma, Roger Bivand, Michael Sumner, Robert Hijmans, Virgilio Gómez-Rubio -[Simple features](https://en.wikipedia.org/wiki/Simple_Features) is an open ([OGC](https://www.ogc.org/standard/sfa/) and [ISO](https://www.iso.org/standard/40114.html)) interface standard for access and manipulation of spatial vector data (points, lines, polygons). It includes a standard [SQL schema](http://www.opengeospatial.org/standards/sfs) that supports storage, retrieval, query and update of feature collections via a SQL interface. All commonly used databases provide this interface. [GeoJSON](https://geojson.org/) is a standard for encoding simple features in JSON, and is used in JavaScript and MongoDB. Well-known-text ([WKT](https://en.wikipedia.org/wiki/Well-known_text)) is a text representation of simple features used often in linked data; well-known-binary ([WKB] (https://en.wikipedia.org/wiki/Well-known_text)) a standard binary representation used in databases. _Simple Feature Access_ defines coordinate reference systems, and makes it easy to move data from longitude-latitude to projections back and forth in a standardized way. +[Simple features](https://en.wikipedia.org/wiki/Simple_Features) is an open ([OGC](https://www.ogc.org/standard/sfa/) and [ISO](https://www.iso.org/standard/40114.html)) interface standard for access and manipulation of spatial vector data (points, lines, polygons). It includes a standard [SQL schema](https://www.ogc.org/standard/sfs/) that supports storage, retrieval, query and update of feature collections via a SQL interface. All commonly used databases provide this interface. [GeoJSON](https://geojson.org/) is a standard for encoding simple features in JSON, and is used in JavaScript and MongoDB. Well-known-text ([WKT](https://en.wikipedia.org/wiki/Well-known_text)) is a text representation of simple features used often in linked data; well-known-binary ([WKB] (https://en.wikipedia.org/wiki/Well-known_text)) a standard binary representation used in databases. _Simple Feature Access_ defines coordinate reference systems, and makes it easy to move data from longitude-latitude to projections back and forth in a standardized way. [GDAL](https://gdal.org/) is an open source C++ library for reading and writing both raster and vector data with more than 225 drivers (supported file formats, data base connectors, web service interfaces). GDAL is used by practically all open source geospatial projects and by many industry products (including ESRI's ArcGIS, ERDAS, and FME). It provides coordinate transformations (built on top of PROJ.4) and geometric operations (e.g. polygon intersections, unions, buffers and distance). Standards for coordinate transformations change over time; such changes are typically adopted directly in GDAL/PROJ.4 but do not easily find their way into R-only packages such as `mapproj`. @@ -16,7 +16,7 @@ Today, 221 CRAN packages depend on, import or link to `sp`, 259 when including _ Off-CRAN package [rgdal2](https://github.com/thk686/rgdal2) is an interface to GDAL 2.0, which uses raw pointers to interface features, but does not import any data in R, using GDAL to handle everything. CRAN Package [wkb](https://cran.r-project.org/package=wkb), contributed by Tibco Software, converts between WKB representations of several simple feature classes and corresponding classes in `sp`, and seems to be needed for Tibco software purposes. ## The problem diff --git a/R/db.R b/R/db.R index 546b66b49..76f8afde7 100644 --- a/R/db.R +++ b/R/db.R @@ -557,6 +557,7 @@ setMethod("dbDataType", c("DBIObject", "sf"), function(dbObj, obj) { #' @param con database connection #' @param x inherits data.frame #' @param classes classes inherited +#' @noRd is_geometry_column <- function(con, x, classes = "") UseMethod("is_geometry_column") #' @export diff --git a/R/geom-predicates.R b/R/geom-predicates.R index 44ad608f3..2c9c8d797 100644 --- a/R/geom-predicates.R +++ b/R/geom-predicates.R @@ -116,26 +116,24 @@ st_relate = function(x, y, pattern = NA_character_, sparse = !is.na(pattern)) { st_geos_binop("relate", x, y, sparse = FALSE) } -#' Geometric binary predicates on pairs of simple feature geometry sets +#' Identify if `x` and `y` share any space #' -#' Geometric binary predicates on pairs of simple feature geometry sets -#' @name geos_binary_pred +#' #' @param x object of class \code{sf}, \code{sfc} or \code{sfg} #' @param y object of class \code{sf}, \code{sfc} or \code{sfg}; if missing, \code{x} is used #' @param sparse logical; should a sparse index list be returned (`TRUE`) or a dense logical matrix? See below. #' @inheritDotParams s2::s2_options -#' @param prepared logical; prepare geometry for `x`, before looping over `y`? See Details. -#' @details If \code{prepared} is \code{TRUE}, and \code{x} contains POINT geometries and \code{y} contains polygons, then the polygon geometries are prepared, rather than the points. #' @return If \code{sparse=FALSE}, \code{st_predicate} (with \code{predicate} e.g. "intersects") returns a dense logical matrix with element \code{i,j} equal to \code{TRUE} when \code{predicate(x[i], y[j])} (e.g., when geometry of feature i and j intersect); if \code{sparse=TRUE}, an object of class \code{\link{sgbp}} is returned, which is a sparse list representation of the same matrix, with list element \code{i} an integer vector with all indices \code{j} for which \code{predicate(x[i],y[j])} is \code{TRUE} (and hence a zero-length integer vector if none of them is \code{TRUE}). From the dense matrix, one can find out if one or more elements intersect by \code{apply(mat, 1, any)}, and from the sparse list by \code{lengths(lst) > 0}, see examples below. #' @details For most predicates, a spatial index is built on argument \code{x}; see \url{https://r-spatial.org/r/2017/06/22/spatial-index.html}. #' Specifically, \code{st_intersects}, \code{st_disjoint}, \code{st_touches} \code{st_crosses}, \code{st_within}, \code{st_contains}, \code{st_contains_properly}, \code{st_overlaps}, \code{st_equals}, \code{st_covers} and \code{st_covered_by} all build spatial indexes for more efficient geometry calculations. \code{st_relate}, \code{st_equals_exact}, and do not; \code{st_is_within_distance} uses a spatial index for geographic coordinates when \code{sf_use_s2()} is true. #' -#' If \code{y} is missing, `st_predicate(x, x)` is effectively called, and a square matrix is returned with diagonal elements `st_predicate(x[i], x[i])`. +#' If \code{y} is missing, `st_(x, x)` is effectively called, and a square matrix is returned with diagonal elements `st_predicate(x[i], x[i])`. #' #' Sparse geometry binary predicate (\code{\link{sgbp}}) lists have the following attributes: \code{region.id} with the \code{row.names} of \code{x} (if any, else \code{1:n}), \code{ncol} with the number of features in \code{y}, and \code{predicate} with the name of the predicate used. #' #' @note For intersection on pairs of simple feature geometries, use #' the function \code{\link{st_intersection}} instead of \code{st_intersects}. +#' @family geometric binary predicates for two spatial objects #' #' @examples #' pts = st_sfc(st_point(c(.5,.5)), st_point(c(1.5, 1.5)), st_point(c(2.5, 2.5))) @@ -147,15 +145,7 @@ st_relate = function(x, y, pattern = NA_character_, sparse = !is.na(pattern)) { #' lengths(lst) > 0 #' # which points fall inside the first polygon? #' st_intersects(pol, pts)[[1]] -#' # remove duplicate geometries: -#' p1 = st_point(0:1) -#' p2 = st_point(2:1) -#' p = st_sf(a = letters[1:8], geom = st_sfc(p1, p1, p2, p1, p1, p2, p2, p1)) -#' st_equals(p) -#' st_equals(p, remove_self = TRUE) -#' (u = st_equals(p, retain_unique = TRUE)) #' # retain the records with unique geometries: -#' p[-unlist(u),] #' @export st_intersects = function(x, y, sparse = TRUE, ...) UseMethod("st_intersects") @@ -188,6 +178,11 @@ st_disjoint = function(x, y = x, sparse = TRUE, prepared = TRUE, ...) { } #' @name geos_binary_pred +#' @inheritParams st_intersects +#' @inheritDotParams s2::s2_options +#' @details If \code{prepared} is \code{TRUE}, and \code{x} contains POINT geometries and \code{y} contains polygons, then the polygon geometries are prepared, rather than the points. + +#' @param prepared logical; prepare geometry for `x`, before looping over `y`? See Details. #' @export st_touches = function(x, y, sparse = TRUE, prepared = TRUE, ...) st_geos_binop("touches", x, y, sparse = sparse, prepared = prepared, ...) @@ -202,18 +197,23 @@ st_crosses = function(x, y, sparse = TRUE, prepared = TRUE, ...) st_within = function(x, y, sparse = TRUE, prepared = TRUE, ...) st_geos_binop("within", x, y, sparse = sparse, prepared = prepared, ...) -#' @name geos_binary_pred +#' Identify if y is within x +#' +#' * `st_contains()` is true if +#' * `st_contains_properly(x, y)` is true if `x` intersects `y`'s interior, but not its edges or exterior; `x` contains `x`, but `x` does not properly contain `x`. #' @param model character; polygon/polyline model; one of #' "open", "semi-open" or "closed"; see Details. #' @details for \code{model}, see https://github.com/r-spatial/s2/issues/32 +#' @inheritParams geos_binary_pred +#' @param ... passed on to [s2::s2_contains()] #' @export +#' @family geometric binary predicates for two spatial objects st_contains = function(x, y, sparse = TRUE, prepared = TRUE, ..., model = "open") st_geos_binop("contains", x, y, sparse = sparse, prepared = prepared, ..., model = model) -#' @name geos_binary_pred +#' @rdname st_contains #' @export -#' @details `st_contains_properly(A,B)` is true if A intersects B's interior, but not its edges or exterior; A contains A, but A does not properly contain A. -#' +#' @details #' See also \link{st_relate} and \url{https://en.wikipedia.org/wiki/DE-9IM} for a more detailed description of the underlying algorithms. st_contains_properly = function(x, y, sparse = TRUE, prepared = TRUE, ...) { if (! prepared) @@ -226,10 +226,32 @@ st_contains_properly = function(x, y, sparse = TRUE, prepared = TRUE, ...) { st_overlaps = function(x, y, sparse = TRUE, prepared = TRUE, ...) st_geos_binop("overlaps", x, y, sparse = sparse, prepared = prepared, ...) -#' @name geos_binary_pred -#' @param retain_unique logical; if `TRUE` (and `y` is missing) return only indexes of points larger than the current index; this can be used to select unique geometries, see examples. This argument can be used for all geometry predicates; see also \link{distinct.sf} to find records where geometries AND attributes are distinct. -#' @param remove_self logical; if `TRUE` (and `y` is missing) return only indexes of geometries different from the current index; this can be used to omit self-intersections; see examples. This argument can be used for all geometry predicates + +#' Verify if geographies are equal +#' +#' * `st_equals()` validate if x and y are equal. +#' * `st_equals_exact()` returns true for two geometries of the same type and their vertices corresponding by index are equal up to a specified tolerance. +#' +#' @inheritParams geos_binary_pred +#' @param retain_unique logical; if `TRUE` (and `y` is missing) return only +#' indexes of points larger than the current index; this can be used to select +#' unique geometries, see examples. This argument can be used for all geometry predicates; +#' see also \link{distinct.sf} to find records where geometries AND attributes are distinct. +#' @param remove_self logical; if `TRUE` (and `y` is missing) return only indexes of geometries different from the current index; this can be used to omit self-intersections; see examples. +#' This argument can be used for all geometry predicates +#' @param ... passed on to [s2::s2_options()] #' @export +#' @family geometric binary predicates for two spatial objects +#' @examples +#' # remove duplicate geometries: +#' p1 = st_point(0:1) +#' p2 = st_point(2:1) +#' p = st_sf(a = letters[1:8], geom = st_sfc(p1, p1, p2, p1, p1, p2, p2, p1)) +#' st_equals(p) +#' st_equals(p, remove_self = TRUE) +#' (u = st_equals(p, retain_unique = TRUE)) +#' # retain the records with unique geometries: +#' p[-unlist(u),] st_equals = function(x, y, sparse = TRUE, prepared = FALSE, ..., retain_unique = FALSE, remove_self = FALSE) { if (prepared) @@ -239,6 +261,9 @@ st_equals = function(x, y, sparse = TRUE, prepared = FALSE, ..., } #' @name geos_binary_pred +#' @param model character; polygon/polyline model; one of +#' `"open"`, `"semi-open"` or `"closed"`; see Details. +#' @details for \code{model}, see https://github.com/r-spatial/s2/issues/32 #' @export st_covers = function(x, y, sparse = TRUE, prepared = TRUE, ..., model = "closed") st_geos_binop("covers", x, y, sparse = sparse, prepared = prepared, ..., model = model) @@ -250,10 +275,9 @@ st_covered_by = function(x, y = x, sparse = TRUE, prepared = TRUE, ..., model = st_geos_binop("covered_by", x, y, sparse = sparse, prepared = prepared, ...) -#' @name geos_binary_pred +#' @rdname st_equals #' @export #' @param par numeric; parameter used for "equals_exact" (margin); -#' @details \code{st_equals_exact} returns true for two geometries of the same type and their vertices corresponding by index are equal up to a specified tolerance. st_equals_exact = function(x, y, par, sparse = TRUE, prepared = FALSE, ...) { if (prepared) stop("prepared geometries not supported for st_equals_exact") diff --git a/R/geos_binary_pred.R b/R/geos_binary_pred.R new file mode 100644 index 000000000..92f1c9e0f --- /dev/null +++ b/R/geos_binary_pred.R @@ -0,0 +1,33 @@ +#' Geometric binary predicates on pairs of simple feature geometry sets +#' +#' @description +#' +#' For most predicates, a spatial index is built on argument `x`; +#' see \url{https://r-spatial.org/r/2017/06/22/spatial-index.html}. +#' +#' If `prepared = TRUE`, `x` contains POINT geometries, and `y` contains polygons, +#' then the polygon geometries are prepared, rather than the points. +#' @name geos_binary_pred +#' @family geometric binary predicates for two spatial objects +#' @param remove_self logical; if `TRUE` (and `y` is missing) return only indexes of geometries different from the current index; this can be used to omit self-intersections; see examples. +#' This argument can be used for all geometry predicates +#' @examples +#' pts = st_sfc(st_point(c(.5,.5)), st_point(c(1.5, 1.5)), st_point(c(2.5, 2.5))) +#' pol = st_polygon(list(rbind(c(0,0), c(2,0), c(2,2), c(0,2), c(0,0)))) +#' (lst = st_intersects(pts, pol)) +#' (mat = st_intersects(pts, pol, sparse = FALSE)) +#' # which points fall inside a polygon? +#' apply(mat, 1, any) +#' lengths(lst) > 0 +#' # which points fall inside the first polygon? +#' st_intersects(pol, pts)[[1]] +#' # remove duplicate geometries: +#' p1 = st_point(0:1) +#' p2 = st_point(2:1) +#' p = st_sf(a = letters[1:8], geom = st_sfc(p1, p1, p2, p1, p1, p2, p2, p1)) +#' st_equals(p) +#' st_equals(p, remove_self = TRUE) +#' (u = st_equals(p, retain_unique = TRUE)) +#' # retain the records with unique geometries: +#' p[-unlist(u),] +NULL diff --git a/R/nearest.R b/R/nearest.R index 3a8728687..848578501 100644 --- a/R/nearest.R +++ b/R/nearest.R @@ -1,12 +1,13 @@ -#' get nearest points between pairs of geometries +#' Get nearest points between pairs of geometries #' #' get nearest points between pairs of geometries -#' @param x object of class \code{sfg}, \code{sfc} or \code{sf} -#' @param y object of class \code{sfg}, \code{sfc} or \code{sf} -#' @param pairwise logical; if \code{FALSE} (default) return nearest points between all pairs, if \code{TRUE}, return nearest points between subsequent pairs. -#' @param ... ignored +#' @param x,y object of class \code{sfg}, \code{sfc} or \code{sf} +#' @param pairwise logical; if \code{FALSE} (default) return nearest points between all pairs, +#' if \code{TRUE}, return nearest points between subsequent pairs. +#' @param ... passed on to methods. Currently, only `pairwise` is implemented. #' @seealso \link{st_nearest_feature} for finding the nearest feature -#' @return an \link{sfc} object with all two-point \code{LINESTRING} geometries of point pairs from the first to the second geometry, of length x * y, with y cycling fastest. See examples for ideas how to convert these to \code{POINT} geometries. +#' @return an \link{sfc} object with all two-point \code{LINESTRING} geometries of point pairs from the first to the second geometry, of length x * y, with y cycling fastest. +#' See examples for ideas how to convert these to \code{POINT} geometries. #' @details in case \code{x} lies inside \code{y}, when using S2, the end points #' are on polygon boundaries, when using GEOS the end point are identical to \code{x}. #' @examples @@ -34,6 +35,7 @@ #' plot(pts[seq(2, 200, 2)], add = TRUE, col = 'green') #' #' @export +#' st_nearest_points = function(x, y, ...) UseMethod("st_nearest_points") #' @export @@ -55,13 +57,13 @@ st_nearest_points.sfc = function(x, y, ..., pairwise = FALSE) { } #' @export -#' @name st_nearest_points +#' @rdname st_nearest_points st_nearest_points.sfg = function(x, y, ...) { st_nearest_points(st_geometry(x), st_geometry(y), ...) } #' @export -#' @name st_nearest_points +#' @rdname st_nearest_points st_nearest_points.sf = function(x, y, ...) { st_nearest_points(st_geometry(x), st_geometry(y), ...) } diff --git a/R/plot.R b/R/plot.R index 32cecc78e..292309e58 100644 --- a/R/plot.R +++ b/R/plot.R @@ -17,11 +17,10 @@ kw_dflt = function(x, key.pos) { } -#' plot sf object -#' -#' plot one or more attributes of an sf object on a map #' Plot sf object #' +#' Plot one or more attributes of an sf object on a map +#' #' @param x object of class sf #' @param y ignored #' @param ... further specifications, see \link{plot_sf} and \link{plot} and details. @@ -63,7 +62,8 @@ kw_dflt = function(x, key.pos) { #' parameter \code{at} can be set to specify where labels are placed along the key; see examples. #' #' The features are plotted in the order as they apppear in the sf object. See examples for when a different plotting order is wanted. -#' +#' +#' @seealso `vignette("sf5")` #' @examples #' nc = st_read(system.file("gpkg/nc.gpkg", package="sf"), quiet = TRUE) #' # plot single attribute, auto-legend: @@ -824,7 +824,7 @@ get_asp = function(bb) { bb2merc = function(x, cls = "ggmap") { # return bbox in the appropriate "web mercator" CRS wgs84 = st_crs(4326) - merc = st_crs(3857) # http://wiki.openstreetmap.org/wiki/EPSG:3857 + merc = st_crs(3857) # https://wiki.openstreetmap.org/wiki/Web_Mercator pts = if (cls == "ggmap") { b = vapply(attr(x, "bb"), c, 0.0) st_sfc(st_point(c(b[2:1])), st_point(c(b[4:3])), crs = wgs84) diff --git a/R/read.R b/R/read.R index 95255d5f1..0d738a2e1 100644 --- a/R/read.R +++ b/R/read.R @@ -626,7 +626,6 @@ write_sf <- function(..., quiet = TRUE, append = FALSE, delete_layer = !append) #' support](https://gdal.org/en/latest/drivers/vector/index.html) #' @return A `data.frame` with driver metadata. #' @export -#' @md #' @examples #' # The following driver lists depend on the GDAL setup and platform used: #' st_drivers() @@ -741,7 +740,8 @@ guess_driver_can_write = function(dns, drv = guess_driver(dns)) { #' Search through the driver table if driver is listed #' @param drv character. Name of driver #' @param drivers data.frame. Table containing driver names and support. Default -#' is from \code{\link{st_drivers}} +#' is from `st_drivers()` +#' @noRd is_driver_available = function(drv, drivers = st_drivers()) { i = match(drv, drivers$name) if (is.na(i)) @@ -758,6 +758,7 @@ is_driver_available = function(drv, drivers = st_drivers()) { #' @param drivers data.frame. Table containing driver names and support. Default #' is from \code{\link{st_drivers}} #' @param operation character. What action to check +#' @noRd is_driver_can = function(drv, drivers = st_drivers(), operation = "write") { stopifnot(operation %in% names(drivers)) i = match(drv, drivers$name) diff --git a/R/sgbp.R b/R/sgbp.R index 59326c059..791730450 100644 --- a/R/sgbp.R +++ b/R/sgbp.R @@ -21,16 +21,22 @@ sgbp = function(x, predicate, region.id, ncol, sparse = TRUE, remove_self = FALS ret } -#' Methods for dealing with sparse geometry binary predicate lists +#' Sparse Geometry Binary Predicate Lists. #' +#' @description #' Methods for dealing with sparse geometry binary predicate lists +#' \code{sgbp} are sparse matrices, stored as a list with integer vectors holding +#' the ordered \code{TRUE} indices of each row. This means that for a dense, +#' \eqn{m \times n}{m x n} matrix \code{Q} and a list \code{L}, +#' if \code{Q[i,j]} is \code{TRUE} then \eqn{j} is an element of \code{L[[i]]}. +#' +#' Reversed: when \eqn{k} is the value of \code{L[[i]][j]}, then \code{Q[i,k]} is \code{TRUE}. #' @name sgbp #' @export #' @param x object of class \code{sgbp} #' @param ... ignored #' @param n integer; maximum number of items to print #' @param max_nb integer; maximum number of neighbours to print for each item -#' @details \code{sgbp} are sparse matrices, stored as a list with integer vectors holding the ordered \code{TRUE} indices of each row. This means that for a dense, \eqn{m \times n}{m x n} matrix \code{Q} and a list \code{L}, if \code{Q[i,j]} is \code{TRUE} then \eqn{j} is an element of \code{L[[i]]}. Reversed: when \eqn{k} is the value of \code{L[[i]][j]}, then \code{Q[i,k]} is \code{TRUE}. print.sgbp = function(x, ..., n = 10, max_nb = 10) { n = min(length(x), n) hd = paste0("Sparse geometry binary predicate list of length ", length(x), ", ", diff --git a/README.md b/README.md index 76b870cd7..a3f04f28d 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ [![R-CMD-check](https://github.com/r-spatial/sf/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/r-spatial/sf/actions/workflows/R-CMD-check.yaml) [![tic-db](https://github.com/r-spatial/sf/actions/workflows/tic-db.yml/badge.svg)](https://github.com/r-spatial/sf/actions/workflows/tic-db.yml) -[![Coverage Status](https://img.shields.io/codecov/c/github/r-spatial/sf/main.svg)](https://app.codecov.io/gh/r-spatial/sf) -[![License](http://img.shields.io/badge/license-GPL%20%28%3E=%202%29-brightgreen.svg?style=flat)](http://www.gnu.org/licenses/gpl-2.0.html) +[![Codecov test coverage](https://codecov.io/gh/r-spatial/sf/graph/badge.svg)](https://app.codecov.io/gh/r-spatial/sf) +[![License](https://img.shields.io/badge/license-GPL%20%28%3E=%202%29-brightgreen.svg?style=flat)](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) [![CRAN](https://www.r-pkg.org/badges/version/sf)](https://cran.r-project.org/package=sf) [![cran checks](https://badges.cranchecks.info/worst/sf.svg)](https://cran.r-project.org/web/checks/check_results_sf.html) [![Downloads](https://cranlogs.r-pkg.org/badges/sf?color=brightgreen)](https://www.r-pkg.org/pkg/sf) @@ -24,9 +24,9 @@ Package sf: * represents natively in R all 17 simple feature types for all dimensions (XY, XYZ, XYM, XYZM) * interfaces to [GEOS](https://libgeos.org) for geometrical operations on projected coordinates, and (through R package [s2](https://cran.r-project.org/package=s2)) to [s2geometry](http://s2geometry.io/) for geometrical operations on ellipsoidal coordinates * interfaces to [GDAL](https://gdal.org/), supporting all driver options, `Date` and `POSIXct` and list-columns -* interfaces to [PRØJ](http://proj.org/) for coordinate reference system conversion and transformation +* interfaces to [PRØJ](https://proj.org/) for coordinate reference system conversion and transformation * uses [well-known-binary](https://en.wikipedia.org/wiki/Well-known_text#Well-known_binary) serialisations written in C++/Rcpp for fast I/O with GDAL and GEOS -* reads from and writes to spatial databases such as [PostGIS](http://postgis.net/) using [DBI](https://cran.r-project.org/package=DBI) +* reads from and writes to spatial databases such as [PostGIS](https://postgis.net/) using [DBI](https://cran.r-project.org/package=DBI) * is extended by * [lwgeom](https://github.com/r-spatial/lwgeom/) for selected liblwgeom/PostGIS functions * [stars](https://github.com/r-spatial/stars/) for raster data, and raster or vector data cubes (spatial time series) diff --git a/_pkgdown.yml b/_pkgdown.yml index 87179ec83..0466dc9ef 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -2,3 +2,46 @@ url: https://r-spatial.github.io/sf/ template: bootstrap: 5 + +reference: + - title: Simple features objects + contents: + - sf + - sfc + - sgbp + - title: Operations + contents: + - starts_with("st_") + - title: Database operators + contents: + - starts_with("db") + - title: Visualize spatial data + desc: > + See more in `vignette("sf5")` + contents: + - plot + - title: sf methods + contents: + - tidyverse + - tibble + - vctrs + - transform.sf + - aggregate.sf + - merge.sf + - summary.sfc + - as + - title: Data objects + contents: + - nc + - title: Other helpers + contents: + - extension_map + - gdal_addo + - gdal_utils + - Ops + - prefix_map + - proj_tools + - rawToHex + - sf_extSoftVersion + - sf_project + diff --git a/configure b/configure index 4838888f7..d080ea784 100755 --- a/configure +++ b/configure @@ -4162,7 +4162,7 @@ if test "$WARN" = "warn" ; then echo "Note: proj/conus not found" echo "No support available in PROJ4 for NAD grid datum transformations" echo "If required, consider re-installing from source with the contents" - echo "of proj-datumgrid-1..zip from http://download.osgeo.org/proj/ in nad/." + echo "of proj-datumgrid-1..zip from https://download.osgeo.org/proj/ in nad/." fi fi # PROJH = no diff --git a/configure.ac b/configure.ac index 77a55224b..70dae38aa 100644 --- a/configure.ac +++ b/configure.ac @@ -621,7 +621,7 @@ if test "$WARN" = "warn" ; then echo "Note: proj/conus not found" echo "No support available in PROJ4 for NAD grid datum transformations" echo "If required, consider re-installing from source with the contents" - echo "of proj-datumgrid-1..zip from http://download.osgeo.org/proj/ in nad/." + echo "of proj-datumgrid-1..zip from https://download.osgeo.org/proj/ in nad/." fi fi # PROJH = no diff --git a/inst/docker/arrow/Dockerfile b/inst/docker/arrow/Dockerfile index 2322d1a7c..877a6c56c 100644 --- a/inst/docker/arrow/Dockerfile +++ b/inst/docker/arrow/Dockerfile @@ -89,7 +89,7 @@ ENV LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH # GEOS: ENV GEOS_VERSION 3.11.0 -RUN wget -q http://download.osgeo.org/geos/geos-${GEOS_VERSION}.tar.bz2 \ +RUN wget -q https://download.osgeo.org/geos/geos-${GEOS_VERSION}.tar.bz2 \ && bzip2 -d geos-*bz2 \ && tar xf geos*tar \ && cd geos* \ @@ -104,7 +104,7 @@ RUN wget -q http://download.osgeo.org/geos/geos-${GEOS_VERSION}.tar.bz2 \ #RUN git clone --depth 1 https://github.com/OSGeo/PROJ.git # https://download.osgeo.org/proj/proj-9.0.0RC1.tar.gz ENV PROJ_VERSION 9.0.1 -RUN wget -q http://download.osgeo.org/proj/proj-${PROJ_VERSION}.tar.gz +RUN wget -q https://download.osgeo.org/proj/proj-${PROJ_VERSION}.tar.gz RUN tar zxvf proj-${PROJ_VERSION}.tar.gz RUN cd proj* \ && ls -l \ @@ -120,7 +120,7 @@ RUN cd proj* \ ENV GDAL_VERSION 3.5.1 ENV GDAL_VERSION_NAME 3.5.1 -RUN wget -q http://download.osgeo.org/gdal/${GDAL_VERSION}/gdal-${GDAL_VERSION_NAME}.tar.gz \ +RUN wget -q https://download.osgeo.org/gdal/${GDAL_VERSION}/gdal-${GDAL_VERSION_NAME}.tar.gz \ && tar -xf gdal-${GDAL_VERSION_NAME}.tar.gz \ && cd gdal* \ && mkdir build \ diff --git a/inst/docker/base/Dockerfile b/inst/docker/base/Dockerfile index 2050347a3..89c3f3a21 100644 --- a/inst/docker/base/Dockerfile +++ b/inst/docker/base/Dockerfile @@ -7,7 +7,7 @@ MAINTAINER "edzerpebesma" edzer.pebesma@uni-muenster.de RUN apt-get update && apt-get install -y software-properties-common RUN add-apt-repository ppa:ubuntugis/ubuntugis-unstable -RUN echo "deb http://cran.rstudio.com/bin/linux/ubuntu xenial/ " >> /etc/apt/sources.list +RUN echo "deb https://cran.rstudio.com/bin/linux/ubuntu xenial/ " >> /etc/apt/sources.list RUN apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9 RUN apt-get update diff --git a/inst/docker/geos/Dockerfile b/inst/docker/geos/Dockerfile index c8b8a3600..2cdc5f813 100644 --- a/inst/docker/geos/Dockerfile +++ b/inst/docker/geos/Dockerfile @@ -74,7 +74,7 @@ RUN cd geos \ && make install #RUN git clone --depth 1 https://github.com/OSGeo/PROJ.git -RUN wget http://download.osgeo.org/proj/proj-8.0.0.tar.gz +RUN wget https://download.osgeo.org/proj/proj-8.0.0.tar.gz RUN tar zxvf proj-8.0.0.tar.gz RUN cd proj-8.0.0 \ && ls -l \ diff --git a/man/geos_binary_pred.Rd b/man/geos_binary_pred.Rd index bf4143697..517f8a549 100644 --- a/man/geos_binary_pred.Rd +++ b/man/geos_binary_pred.Rd @@ -1,24 +1,17 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/geom-predicates.R +% Please edit documentation in R/geos_binary_pred.R, R/geom-predicates.R \name{geos_binary_pred} \alias{geos_binary_pred} -\alias{st_intersects} \alias{st_disjoint} \alias{st_touches} \alias{st_crosses} \alias{st_within} -\alias{st_contains} -\alias{st_contains_properly} \alias{st_overlaps} -\alias{st_equals} \alias{st_covers} \alias{st_covered_by} -\alias{st_equals_exact} \alias{st_is_within_distance} \title{Geometric binary predicates on pairs of simple feature geometry sets} \usage{ -st_intersects(x, y, sparse = TRUE, ...) - st_disjoint(x, y = x, sparse = TRUE, prepared = TRUE, ...) st_touches(x, y, sparse = TRUE, prepared = TRUE, ...) @@ -27,28 +20,12 @@ st_crosses(x, y, sparse = TRUE, prepared = TRUE, ...) st_within(x, y, sparse = TRUE, prepared = TRUE, ...) -st_contains(x, y, sparse = TRUE, prepared = TRUE, ..., model = "open") - -st_contains_properly(x, y, sparse = TRUE, prepared = TRUE, ...) - st_overlaps(x, y, sparse = TRUE, prepared = TRUE, ...) -st_equals( - x, - y, - sparse = TRUE, - prepared = FALSE, - ..., - retain_unique = FALSE, - remove_self = FALSE -) - st_covers(x, y, sparse = TRUE, prepared = TRUE, ..., model = "closed") st_covered_by(x, y = x, sparse = TRUE, prepared = TRUE, ..., model = "closed") -st_equals_exact(x, y, par, sparse = TRUE, prepared = FALSE, ...) - st_is_within_distance(x, y = x, dist, sparse = TRUE, ..., remove_self = FALSE) } \arguments{ @@ -58,6 +35,8 @@ st_is_within_distance(x, y = x, dist, sparse = TRUE, ..., remove_self = FALSE) \item{sparse}{logical; should a sparse index list be returned (\code{TRUE}) or a dense logical matrix? See below.} +\item{prepared}{logical; prepare geometry for \code{x}, before looping over \code{y}? See Details.} + \item{...}{ Arguments passed on to \code{\link[s2:s2_options]{s2::s2_options}} \describe{ @@ -88,46 +67,25 @@ that can used to constrain the output of \code{\link[s2:s2_rebuild]{s2_rebuild() boolean operation.} }} -\item{prepared}{logical; prepare geometry for \code{x}, before looping over \code{y}? See Details.} - \item{model}{character; polygon/polyline model; one of -"open", "semi-open" or "closed"; see Details.} - -\item{retain_unique}{logical; if \code{TRUE} (and \code{y} is missing) return only indexes of points larger than the current index; this can be used to select unique geometries, see examples. This argument can be used for all geometry predicates; see also \link{distinct.sf} to find records where geometries AND attributes are distinct.} - -\item{remove_self}{logical; if \code{TRUE} (and \code{y} is missing) return only indexes of geometries different from the current index; this can be used to omit self-intersections; see examples. This argument can be used for all geometry predicates} - -\item{par}{numeric; parameter used for "equals_exact" (margin);} +\code{"open"}, \code{"semi-open"} or \code{"closed"}; see Details.} \item{dist}{distance threshold; geometry indexes with distances smaller or equal to this value are returned; numeric value or units value having distance units.} -} -\value{ -If \code{sparse=FALSE}, \code{st_predicate} (with \code{predicate} e.g. "intersects") returns a dense logical matrix with element \code{i,j} equal to \code{TRUE} when \code{predicate(x[i], y[j])} (e.g., when geometry of feature i and j intersect); if \code{sparse=TRUE}, an object of class \code{\link{sgbp}} is returned, which is a sparse list representation of the same matrix, with list element \code{i} an integer vector with all indices \code{j} for which \code{predicate(x[i],y[j])} is \code{TRUE} (and hence a zero-length integer vector if none of them is \code{TRUE}). From the dense matrix, one can find out if one or more elements intersect by \code{apply(mat, 1, any)}, and from the sparse list by \code{lengths(lst) > 0}, see examples below. + +\item{remove_self}{logical; if \code{TRUE} (and \code{y} is missing) return only indexes of geometries different from the current index; this can be used to omit self-intersections; see examples. +This argument can be used for all geometry predicates} } \description{ -Geometric binary predicates on pairs of simple feature geometry sets +For most predicates, a spatial index is built on argument \code{x}; +see \url{https://r-spatial.org/r/2017/06/22/spatial-index.html}. + +If \code{prepared = TRUE}, \code{x} contains POINT geometries, and \code{y} contains polygons, +then the polygon geometries are prepared, rather than the points. } \details{ If \code{prepared} is \code{TRUE}, and \code{x} contains POINT geometries and \code{y} contains polygons, then the polygon geometries are prepared, rather than the points. -For most predicates, a spatial index is built on argument \code{x}; see \url{https://r-spatial.org/r/2017/06/22/spatial-index.html}. -Specifically, \code{st_intersects}, \code{st_disjoint}, \code{st_touches} \code{st_crosses}, \code{st_within}, \code{st_contains}, \code{st_contains_properly}, \code{st_overlaps}, \code{st_equals}, \code{st_covers} and \code{st_covered_by} all build spatial indexes for more efficient geometry calculations. \code{st_relate}, \code{st_equals_exact}, and do not; \code{st_is_within_distance} uses a spatial index for geographic coordinates when \code{sf_use_s2()} is true. - -If \code{y} is missing, \code{st_predicate(x, x)} is effectively called, and a square matrix is returned with diagonal elements \code{st_predicate(x[i], x[i])}. - -Sparse geometry binary predicate (\code{\link{sgbp}}) lists have the following attributes: \code{region.id} with the \code{row.names} of \code{x} (if any, else \code{1:n}), \code{ncol} with the number of features in \code{y}, and \code{predicate} with the name of the predicate used. - for \code{model}, see https://github.com/r-spatial/s2/issues/32 - -\code{st_contains_properly(A,B)} is true if A intersects B's interior, but not its edges or exterior; A contains A, but A does not properly contain A. - -See also \link{st_relate} and \url{https://en.wikipedia.org/wiki/DE-9IM} for a more detailed description of the underlying algorithms. - -\code{st_equals_exact} returns true for two geometries of the same type and their vertices corresponding by index are equal up to a specified tolerance. -} -\note{ -For intersection on pairs of simple feature geometries, use -the function \code{\link{st_intersection}} instead of \code{st_intersects}. } \examples{ pts = st_sfc(st_point(c(.5,.5)), st_point(c(1.5, 1.5)), st_point(c(2.5, 2.5))) @@ -149,3 +107,10 @@ st_equals(p, remove_self = TRUE) # retain the records with unique geometries: p[-unlist(u),] } +\seealso{ +Other geometric binary predicates for two spatial objects: +\code{\link{st_contains}()}, +\code{\link{st_equals}()}, +\code{\link{st_intersects}()} +} +\concept{geometric binary predicates for two spatial objects} diff --git a/man/is_driver_available.Rd b/man/is_driver_available.Rd deleted file mode 100644 index dcb2c03c7..000000000 --- a/man/is_driver_available.Rd +++ /dev/null @@ -1,17 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/read.R -\name{is_driver_available} -\alias{is_driver_available} -\title{Check if driver is available} -\usage{ -is_driver_available(drv, drivers = st_drivers()) -} -\arguments{ -\item{drv}{character. Name of driver} - -\item{drivers}{data.frame. Table containing driver names and support. Default -is from \code{\link{st_drivers}}} -} -\description{ -Search through the driver table if driver is listed -} diff --git a/man/is_driver_can.Rd b/man/is_driver_can.Rd deleted file mode 100644 index 7b1bf976c..000000000 --- a/man/is_driver_can.Rd +++ /dev/null @@ -1,20 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/read.R -\name{is_driver_can} -\alias{is_driver_can} -\title{Check if a driver can perform an action} -\usage{ -is_driver_can(drv, drivers = st_drivers(), operation = "write") -} -\arguments{ -\item{drv}{character. Name of driver} - -\item{drivers}{data.frame. Table containing driver names and support. Default -is from \code{\link{st_drivers}}} - -\item{operation}{character. What action to check} -} -\description{ -Search through the driver table to match a driver name with -an action (e.g. \code{"write"}) and check if the action is supported. -} diff --git a/man/is_geometry_column.Rd b/man/is_geometry_column.Rd deleted file mode 100644 index a5e90dca7..000000000 --- a/man/is_geometry_column.Rd +++ /dev/null @@ -1,18 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/db.R -\name{is_geometry_column} -\alias{is_geometry_column} -\title{Check if the columns could be of a coercable type for sf} -\usage{ -is_geometry_column(con, x, classes = "") -} -\arguments{ -\item{con}{database connection} - -\item{x}{inherits data.frame} - -\item{classes}{classes inherited} -} -\description{ -Check if the columns could be of a coercable type for sf -} diff --git a/man/plot.Rd b/man/plot.Rd index 2047566ac..2be55e667 100644 --- a/man/plot.Rd +++ b/man/plot.Rd @@ -20,7 +20,7 @@ \alias{text.sfc} \alias{points.sf} \alias{points.sfc} -\title{plot sf object} +\title{Plot sf object} \usage{ \method{plot}{sf}( x, @@ -260,8 +260,7 @@ or object returned by \link{st_graticule}} \item{of_largest_polygon}{logical, passed on to \link{st_centroid}} } \description{ -plot one or more attributes of an sf object on a map -Plot sf object +Plot one or more attributes of an sf object on a map } \details{ \code{plot.sf} maximally plots \code{max.plot} maps with colors following from attribute columns, @@ -325,3 +324,6 @@ plot(x[order(st_area(x), decreasing = TRUE),], col = 2:5) # plot largest polygon sf.colors(10) text(nc, labels = substring(nc$NAME,1,1)) } +\seealso{ +\code{vignette("sf5")} +} diff --git a/man/sgbp.Rd b/man/sgbp.Rd index 90a744a54..768259066 100644 --- a/man/sgbp.Rd +++ b/man/sgbp.Rd @@ -8,7 +8,7 @@ \alias{dim.sgbp} \alias{Ops.sgbp} \alias{as.data.frame.sgbp} -\title{Methods for dealing with sparse geometry binary predicate lists} +\title{Sparse Geometry Binary Predicate Lists.} \usage{ \method{print}{sgbp}(x, ..., n = 10, max_nb = 10) @@ -37,9 +37,13 @@ } \description{ Methods for dealing with sparse geometry binary predicate lists +\code{sgbp} are sparse matrices, stored as a list with integer vectors holding +the ordered \code{TRUE} indices of each row. This means that for a dense, +\eqn{m \times n}{m x n} matrix \code{Q} and a list \code{L}, +if \code{Q[i,j]} is \code{TRUE} then \eqn{j} is an element of \code{L[[i]]}. + +Reversed: when \eqn{k} is the value of \code{L[[i]][j]}, then \code{Q[i,k]} is \code{TRUE}. } \details{ -\code{sgbp} are sparse matrices, stored as a list with integer vectors holding the ordered \code{TRUE} indices of each row. This means that for a dense, \eqn{m \times n}{m x n} matrix \code{Q} and a list \code{L}, if \code{Q[i,j]} is \code{TRUE} then \eqn{j} is an element of \code{L[[i]]}. Reversed: when \eqn{k} is the value of \code{L[[i]][j]}, then \code{Q[i,k]} is \code{TRUE}. - \code{==} compares only the dimension and index values, not the attributes of two \code{sgbp} object; use \code{identical} to check for equality of everything. } diff --git a/man/st_contains.Rd b/man/st_contains.Rd new file mode 100644 index 000000000..6d74a1f4d --- /dev/null +++ b/man/st_contains.Rd @@ -0,0 +1,43 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/geom-predicates.R +\name{st_contains} +\alias{st_contains} +\alias{st_contains_properly} +\title{Identify if y is within x} +\usage{ +st_contains(x, y, sparse = TRUE, prepared = TRUE, ..., model = "open") + +st_contains_properly(x, y, sparse = TRUE, prepared = TRUE, ...) +} +\arguments{ +\item{x}{object of class \code{sf}, \code{sfc} or \code{sfg}} + +\item{y}{object of class \code{sf}, \code{sfc} or \code{sfg}; if missing, \code{x} is used} + +\item{sparse}{logical; should a sparse index list be returned (\code{TRUE}) or a dense logical matrix? See below.} + +\item{prepared}{logical; prepare geometry for \code{x}, before looping over \code{y}? See Details.} + +\item{...}{passed on to \code{\link[s2:s2_contains]{s2::s2_contains()}}} + +\item{model}{character; polygon/polyline model; one of +"open", "semi-open" or "closed"; see Details.} +} +\description{ +\itemize{ +\item \code{st_contains()} is true if +\item \code{st_contains_properly(x, y)} is true if \code{x} intersects \code{y}'s interior, but not its edges or exterior; \code{x} contains \code{x}, but \code{x} does not properly contain \code{x}. +} +} +\details{ +for \code{model}, see https://github.com/r-spatial/s2/issues/32 + +See also \link{st_relate} and \url{https://en.wikipedia.org/wiki/DE-9IM} for a more detailed description of the underlying algorithms. +} +\seealso{ +Other geometric binary predicates for two spatial objects: +\code{\link{geos_binary_pred}}, +\code{\link{st_equals}()}, +\code{\link{st_intersects}()} +} +\concept{geometric binary predicates for two spatial objects} diff --git a/man/st_equals.Rd b/man/st_equals.Rd new file mode 100644 index 000000000..e802f0e62 --- /dev/null +++ b/man/st_equals.Rd @@ -0,0 +1,64 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/geom-predicates.R +\name{st_equals} +\alias{st_equals} +\alias{st_equals_exact} +\title{Verify if geographies are equal} +\usage{ +st_equals( + x, + y, + sparse = TRUE, + prepared = FALSE, + ..., + retain_unique = FALSE, + remove_self = FALSE +) + +st_equals_exact(x, y, par, sparse = TRUE, prepared = FALSE, ...) +} +\arguments{ +\item{x}{object of class \code{sf}, \code{sfc} or \code{sfg}} + +\item{y}{object of class \code{sf}, \code{sfc} or \code{sfg}; if missing, \code{x} is used} + +\item{sparse}{logical; should a sparse index list be returned (\code{TRUE}) or a dense logical matrix? See below.} + +\item{prepared}{logical; prepare geometry for \code{x}, before looping over \code{y}? See Details.} + +\item{...}{passed on to \code{\link[s2:s2_options]{s2::s2_options()}}} + +\item{retain_unique}{logical; if \code{TRUE} (and \code{y} is missing) return only +indexes of points larger than the current index; this can be used to select +unique geometries, see examples. This argument can be used for all geometry predicates; +see also \link{distinct.sf} to find records where geometries AND attributes are distinct.} + +\item{remove_self}{logical; if \code{TRUE} (and \code{y} is missing) return only indexes of geometries different from the current index; this can be used to omit self-intersections; see examples. +This argument can be used for all geometry predicates} + +\item{par}{numeric; parameter used for "equals_exact" (margin);} +} +\description{ +\itemize{ +\item \code{st_equals()} validate if x and y are equal. +\item \code{st_equals_exact()} returns true for two geometries of the same type and their vertices corresponding by index are equal up to a specified tolerance. +} +} +\examples{ +# remove duplicate geometries: +p1 = st_point(0:1) +p2 = st_point(2:1) +p = st_sf(a = letters[1:8], geom = st_sfc(p1, p1, p2, p1, p1, p2, p2, p1)) +st_equals(p) +st_equals(p, remove_self = TRUE) +(u = st_equals(p, retain_unique = TRUE)) +# retain the records with unique geometries: +p[-unlist(u),] +} +\seealso{ +Other geometric binary predicates for two spatial objects: +\code{\link{geos_binary_pred}}, +\code{\link{st_contains}()}, +\code{\link{st_intersects}()} +} +\concept{geometric binary predicates for two spatial objects} diff --git a/man/st_intersects.Rd b/man/st_intersects.Rd new file mode 100644 index 000000000..f1dba3454 --- /dev/null +++ b/man/st_intersects.Rd @@ -0,0 +1,84 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/geom-predicates.R +\name{st_intersects} +\alias{st_intersects} +\title{Identify if \code{x} and \code{y} share any space} +\usage{ +st_intersects(x, y, sparse = TRUE, ...) +} +\arguments{ +\item{x}{object of class \code{sf}, \code{sfc} or \code{sfg}} + +\item{y}{object of class \code{sf}, \code{sfc} or \code{sfg}; if missing, \code{x} is used} + +\item{sparse}{logical; should a sparse index list be returned (\code{TRUE}) or a dense logical matrix? See below.} + +\item{...}{ + Arguments passed on to \code{\link[s2:s2_options]{s2::s2_options}} + \describe{ + \item{\code{model}}{One of 'open', 'semi-open' (default for polygons), +or 'closed' (default for polylines). See section 'Model'} + \item{\code{snap}}{Use \code{s2_snap_identity()}, \code{s2_snap_distance()}, \code{s2_snap_level()}, +or \code{s2_snap_precision()} to specify how or if coordinate rounding should +occur.} + \item{\code{snap_radius}}{As opposed to the snap function, which specifies +the maximum distance a vertex should move, the snap radius (in radians) sets +the minimum distance between vertices of the output that don't cause vertices +to move more than the distance specified by the snap function. This can be used +to simplify the result of a boolean operation. Use -1 to specify that any +minimum distance is acceptable.} + \item{\code{duplicate_edges}}{Use \code{TRUE} to keep duplicate edges (e.g., duplicate +points).} + \item{\code{edge_type}}{One of 'directed' (default) or 'undirected'.} + \item{\code{validate}}{Use \code{TRUE} to validate the result from the builder.} + \item{\code{polyline_type}}{One of 'path' (default) or 'walk'. If 'walk', +polylines that backtrack are preserved.} + \item{\code{polyline_sibling_pairs}}{One of 'discard' (default) or 'keep'.} + \item{\code{simplify_edge_chains}}{Use \code{TRUE} to remove vertices that are within +\code{snap_radius} of the original vertex.} + \item{\code{split_crossing_edges}}{Use \code{TRUE} to split crossing polyline edges +when creating geometries.} + \item{\code{idempotent}}{Use \code{FALSE} to apply snap even if snapping is not necessary +to satisfy vertex constraints.} + \item{\code{dimensions}}{A combination of 'point', 'polyline', and/or 'polygon' +that can used to constrain the output of \code{\link[s2:s2_rebuild]{s2_rebuild()}} or a +boolean operation.} + }} +} +\value{ +If \code{sparse=FALSE}, \code{st_predicate} (with \code{predicate} e.g. "intersects") returns a dense logical matrix with element \code{i,j} equal to \code{TRUE} when \code{predicate(x[i], y[j])} (e.g., when geometry of feature i and j intersect); if \code{sparse=TRUE}, an object of class \code{\link{sgbp}} is returned, which is a sparse list representation of the same matrix, with list element \code{i} an integer vector with all indices \code{j} for which \code{predicate(x[i],y[j])} is \code{TRUE} (and hence a zero-length integer vector if none of them is \code{TRUE}). From the dense matrix, one can find out if one or more elements intersect by \code{apply(mat, 1, any)}, and from the sparse list by \code{lengths(lst) > 0}, see examples below. +} +\description{ +Identify if \code{x} and \code{y} share any space +} +\details{ +For most predicates, a spatial index is built on argument \code{x}; see \url{https://r-spatial.org/r/2017/06/22/spatial-index.html}. +Specifically, \code{st_intersects}, \code{st_disjoint}, \code{st_touches} \code{st_crosses}, \code{st_within}, \code{st_contains}, \code{st_contains_properly}, \code{st_overlaps}, \code{st_equals}, \code{st_covers} and \code{st_covered_by} all build spatial indexes for more efficient geometry calculations. \code{st_relate}, \code{st_equals_exact}, and do not; \code{st_is_within_distance} uses a spatial index for geographic coordinates when \code{sf_use_s2()} is true. + +If \code{y} is missing, \verb{st_(x, x)} is effectively called, and a square matrix is returned with diagonal elements \code{st_predicate(x[i], x[i])}. + +Sparse geometry binary predicate (\code{\link{sgbp}}) lists have the following attributes: \code{region.id} with the \code{row.names} of \code{x} (if any, else \code{1:n}), \code{ncol} with the number of features in \code{y}, and \code{predicate} with the name of the predicate used. +} +\note{ +For intersection on pairs of simple feature geometries, use +the function \code{\link{st_intersection}} instead of \code{st_intersects}. +} +\examples{ +pts = st_sfc(st_point(c(.5,.5)), st_point(c(1.5, 1.5)), st_point(c(2.5, 2.5))) +pol = st_polygon(list(rbind(c(0,0), c(2,0), c(2,2), c(0,2), c(0,0)))) +(lst = st_intersects(pts, pol)) +(mat = st_intersects(pts, pol, sparse = FALSE)) +# which points fall inside a polygon? +apply(mat, 1, any) +lengths(lst) > 0 +# which points fall inside the first polygon? +st_intersects(pol, pts)[[1]] +# retain the records with unique geometries: +} +\seealso{ +Other geometric binary predicates for two spatial objects: +\code{\link{geos_binary_pred}}, +\code{\link{st_contains}()}, +\code{\link{st_equals}()} +} +\concept{geometric binary predicates for two spatial objects} diff --git a/man/st_nearest_points.Rd b/man/st_nearest_points.Rd index 7fdfdeb1a..3e1f79802 100644 --- a/man/st_nearest_points.Rd +++ b/man/st_nearest_points.Rd @@ -5,7 +5,7 @@ \alias{st_nearest_points.sfc} \alias{st_nearest_points.sfg} \alias{st_nearest_points.sf} -\title{get nearest points between pairs of geometries} +\title{Get nearest points between pairs of geometries} \usage{ st_nearest_points(x, y, ...) @@ -16,16 +16,16 @@ st_nearest_points(x, y, ...) \method{st_nearest_points}{sf}(x, y, ...) } \arguments{ -\item{x}{object of class \code{sfg}, \code{sfc} or \code{sf}} +\item{x, y}{object of class \code{sfg}, \code{sfc} or \code{sf}} -\item{y}{object of class \code{sfg}, \code{sfc} or \code{sf}} +\item{...}{passed on to methods. Currently, only \code{pairwise} is implemented.} -\item{...}{ignored} - -\item{pairwise}{logical; if \code{FALSE} (default) return nearest points between all pairs, if \code{TRUE}, return nearest points between subsequent pairs.} +\item{pairwise}{logical; if \code{FALSE} (default) return nearest points between all pairs, +if \code{TRUE}, return nearest points between subsequent pairs.} } \value{ -an \link{sfc} object with all two-point \code{LINESTRING} geometries of point pairs from the first to the second geometry, of length x * y, with y cycling fastest. See examples for ideas how to convert these to \code{POINT} geometries. +an \link{sfc} object with all two-point \code{LINESTRING} geometries of point pairs from the first to the second geometry, of length x * y, with y cycling fastest. +See examples for ideas how to convert these to \code{POINT} geometries. } \description{ get nearest points between pairs of geometries diff --git a/vignettes/sf1.Rmd b/vignettes/sf1.Rmd index b622784ec..dd0783411 100644 --- a/vignettes/sf1.Rmd +++ b/vignettes/sf1.Rmd @@ -138,7 +138,7 @@ unit](https://CRAN.R-project.org/package=units). # How simple features in R are organized Package `sf` represents simple features as native R objects. -Similar to [PostGIS](http://postgis.net/), all functions and methods +Similar to [PostGIS](https://postgis.net/), all functions and methods in `sf` that operate on spatial data are prefixed by `st_`, which refers to _spatial type_; this makes them easily findable by command-line completion. Simple features are implemented as