View source: R/dissolve_polygons.R
| dissolve_polygons | R Documentation |
Dissolves (unions) a set of polygons, optionally by group, fills interior holes below a configurable area threshold, and returns clean, valid polygon geometry. Designed for merging catchments, HUC boundaries, or other polygon coverages where sliver gaps and pinhole holes are artifacts rather than real features.
dissolve_polygons(polys, ...)
## S3 method for class 'sf'
dissolve_polygons(
polys,
group_id = NULL,
.fns = NULL,
max_hole_area = Inf,
gap_tolerance = 0,
single_polygon = FALSE,
work_crs = 5070,
...
)
## S3 method for class 'sfc'
dissolve_polygons(
polys,
max_hole_area = Inf,
gap_tolerance = 0,
single_polygon = FALSE,
work_crs = 5070,
...,
groups = NULL
)
polys |
sf data.frame or sfc geometry. Input polygons with POLYGON or
MULTIPOLYGON geometry. When sfc is provided, |
... |
additional arguments passed to methods. |
group_id |
character or NULL. Column name to dissolve by. When NULL, all polygons are dissolved into a single geometry. Ignored for sfc input. Default NULL. |
.fns |
named list of summary functions, or NULL. When non-NULL,
each element name must match a column in |
max_hole_area |
numeric. Maximum hole area (in square meters when
using a projected CRS) below which holes are removed. Use |
gap_tolerance |
numeric. Buffer distance (in CRS units, typically
meters) for the expand-contract step that absorbs sliver gaps between
input polygons. Use |
single_polygon |
logical. If TRUE, extract the largest polygon from each MULTIPOLYGON result, guaranteeing single POLYGON output per row. Default FALSE. |
work_crs |
anything accepted by |
groups |
character or factor vector, or NULL. Optional grouping vector
the same length as |
sf data.frame or sfc (matching input class) with dissolved, hole-filled polygon(s).
For very large inputs (10,000+ polygons), pre-dissolving with
terra::aggregate() may be faster. The geos package is
used automatically when installed for faster union operations.
# Three adjacent squares
p1 <- sf::st_polygon(list(rbind(c(0, 0), c(1, 0), c(1, 1), c(0, 1), c(0, 0))))
p2 <- sf::st_polygon(list(rbind(c(1, 0), c(2, 0), c(2, 1), c(1, 1), c(1, 0))))
p3 <- sf::st_polygon(list(rbind(c(2, 0), c(3, 0), c(3, 1), c(2, 1), c(2, 0))))
polys <- sf::st_sf(
grp = c("a", "a", "b"),
geometry = sf::st_sfc(p1, p2, p3, crs = 5070)
)
# Dissolve all into one polygon
dissolve_polygons(polys, work_crs = NULL)
# Dissolve by group
dissolve_polygons(polys, group_id = "grp", work_crs = NULL)
# sfc input returns sfc
dissolve_polygons(sf::st_geometry(polys), work_crs = NULL)
# Dissolve tributary basins with attribute summarisation
cats <- sf::read_sf(system.file("extdata/walker_cats.gpkg", package = "hydroloom"))
flines <- sf::read_sf(system.file("extdata/walker.gpkg", package = "hydroloom"))
# chosen manually for demonstration
outlets <- c(5329365, 5329313, 5329303)
# Navigate upstream from each outlet to define basins
basins <- navigate_network_dfs(flines, outlets, reset = FALSE, direction = "up")
# Label each catchment with its basin outlet
cats$basin <- NA_character_
for (i in seq_along(basins)) {
cats$basin[cats$featureid %in% unlist(basins[[i]])] <- as.character(outlets[i])
}
cats <- cats[!is.na(cats$basin), ]
# Join stream names for summarisation
cats <- dplyr::left_join(cats,
sf::st_drop_geometry(dplyr::select(flines, COMID, GNIS_NAME)),
by = c("featureid" = "COMID"))
# Most common non-empty name in a group
most_common <- function(x) {
x <- x[!is.na(x) & x != " "]
if (length(x) == 0) return(NA_character_)
names(sort(table(x), decreasing = TRUE))[1]
}
result <- dissolve_polygons(cats, group_id = "basin",
.fns = list(areasqkm = sum, GNIS_NAME = most_common))
dplyr::select(result, basin, GNIS_NAME, areasqkm)
plot(sf::st_geometry(result), col = sf::sf.colors(nrow(result)))
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.