Skip to content

Commit

Permalink
Merge pull request #16 from baslat:polygon-voronoi
Browse files Browse the repository at this point in the history
Polygon-voronoi
  • Loading branch information
baslat authored Aug 23, 2023
2 parents df39254 + b42023f commit 41a73d2
Show file tree
Hide file tree
Showing 6 changed files with 94 additions and 4 deletions.
3 changes: 0 additions & 3 deletions .lintr

This file was deleted.

2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: sak
Title: The Swiss Army Knife of R
Version: 0.9.0
Version: 0.10.0
Authors@R:
person("Bas", "Latcham", , "[email protected]", role = c("aut", "cre"), comment = c(ORCID = "0000-0002-1733-7350"))
Description: This is my personal package of helper functions. Like a Swiss
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export(setup_yaml_megalinter)
export(sg)
export(show_linux_deps)
export(st_intersection_quicker)
export(st_no_overlap)
export(standardise_geo_names)
export(stopwatch)
export(strip_geometry)
Expand Down
4 changes: 4 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# sak 0.10.0

- add `st_no_overlap()` to convert overlapping polygons into voronois

# sak 0.9.0

- adds `ch_add_stacked_labels()` by popular demand
Expand Down
57 changes: 57 additions & 0 deletions R/st_no_overlap.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#' Non-overlapping polygons using Voronoi tesselation
#'
#' This function takes a set of polygons and returns a new set of polygons where
#' the buffer zones of the original polygons do not overlap with each other.
#' This is achieved by calculating the centroids of the polygons, creating a
#' Voronoi tesselation around the centroids, and intersecting the Voronoi zones
#' with the buffer zones of the original polygons. The resulting polygons do not
#' overlap with each other, ensuring that they can be used for further analysis
#' or visualization. Inspired by [this
#' post](https://gis.stackexchange.com/questions/358797/splitting-overlap-between-polygons-and-assign-to-nearest-polygon-using-r)
#'
#' @param polygons A set of polygons with attributes.
#'
#' @return A set of polygons with attributes where the buffer zones of the original polygons do not overlap with each other.
#'
#' @details This function uses the `sf` package to calculate the centroids of
#' the polygons using the `st_centroid` function, and to create a Voronoi
#' tesselation around the centroids using the `st_voronoi` function. The Voronoi
#' zones are then intersected with the buffer zones of the original polygons
#' using the `st_intersection` function. The resulting polygons are returned
#' with their original attributes.
#'
#' @export
st_no_overlap <- function(polygons) {
# silence warning about constant attributes
sf::st_agr(polygons) <- "constant"
orig_crs <- sf::st_crs(polygons)
centroids <- sf::st_centroid(polygons)

# Voronoi tesselation
voronoi_raw <- centroids |>
sf::st_geometry() |>
sf::st_union() |>
# convert to meters crs
sf::st_transform(crs = 3857L) |>
sf::st_voronoi() |>
# convert back to original crs
sf::st_transform(crs = orig_crs) |>
sf::st_collection_extract()

# Put them back in their original order
voronoi <- voronoi_raw[unlist(sf::st_intersects(centroids, voronoi_raw))]

# Keep the attributes
result <- centroids

# Intersect voronoi zones with buffer zones
sf::st_geometry(result) <- purrr::map2(
polygons[["geometry"]],
voronoi,
sf::st_intersection
) |>
sf::st_sfc(crs = orig_crs)

result

}
31 changes: 31 additions & 0 deletions man/st_no_overlap.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 41a73d2

Please sign in to comment.