Skip to content

Commit

Permalink
fixes #2406
Browse files Browse the repository at this point in the history
  • Loading branch information
edzer committed Jun 17, 2024
1 parent afbb1e8 commit 5cdd168
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 3 deletions.
4 changes: 4 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,9 @@ S3method(st_difference,sfc)
S3method(st_difference,sfg)
S3method(st_drop_geometry,default)
S3method(st_drop_geometry,sf)
S3method(st_exterior_ring,sf)
S3method(st_exterior_ring,sfc)
S3method(st_exterior_ring,sfg)
S3method(st_filter,sf)
S3method(st_geometry,sf)
S3method(st_geometry,sfc)
Expand Down Expand Up @@ -447,6 +450,7 @@ export(st_drivers)
export(st_drop_geometry)
export(st_equals)
export(st_equals_exact)
export(st_exterior_ring)
export(st_filter)
export(st_geometry)
export(st_geometry_type)
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# version 1.0-17

* add `st_exterior_ring()` to extract exterior rings (remove holes); #2406

* add `text.sf()`, `text.sfc()`, `points.sf()`, `points.sfc()` to annotate base plots at geometry centroids; #2399

* `st_sf()` no longer strips `tbl` or `tbl_df` class labels; #2378
Expand Down
26 changes: 26 additions & 0 deletions R/geom-transformers.R
Original file line number Diff line number Diff line change
Expand Up @@ -1149,3 +1149,29 @@ st_line_interpolate = function(line, dist, normalized = FALSE) {
st_sfc(CPL_line_interpolate(recycled[[1]], recycled[[2]], normalized),
crs = st_crs(line))
}

#' @export
#' @name geos_unary
st_exterior_ring = function(x, ...) UseMethod("st_exterior_ring")

#' @export
st_exterior_ring.sf = function(x, ...)
st_set_geometry(x, st_exterior_ring(st_geometry(x)))

#' @export
st_exterior_ring.sfg = function(x, ...)
st_exterior_ring(st_sfc(x))[[1]]

#' @export
st_exterior_ring.sfc = function(x, ...) {
stopifnot(all(st_dimension(x, NA_if_empty = FALSE) == 2))
exterior_sfg = function(x) {
if (inherits(x, "MULTIPOLYGON"))
st_multipolygon(lapply(st_cast(st_sfc(x), "POLYGON"), exterior_sfg))
else if (inherits(x, "POLYGON"))
st_polygon(x[1])
else
stop(paste("no exterior_ring method for objects of class", class(x)[1]))
}
st_as_sfc(lapply(x, exterior_sfg), crs = st_crs(x))
}
3 changes: 3 additions & 0 deletions man/geos_unary.Rd

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

18 changes: 18 additions & 0 deletions tests/sfc.R
Original file line number Diff line number Diff line change
Expand Up @@ -340,3 +340,21 @@ out = merge(x, y, all.x=TRUE)
class(out)

st_as_sf(st_sfc(st_point(0:1)))

# st_exterior_ring():
outer = matrix(c(0,0,10,0,10,10,0,10,0,0),ncol=2, byrow=TRUE)
hole1 = matrix(c(1,1,1,2,2,2,2,1,1,1),ncol=2, byrow=TRUE)
hole2 = matrix(c(5,5,5,6,6,6,6,5,5,5),ncol=2, byrow=TRUE)
pts = list(outer, hole1, hole2)
pl1 = st_polygon(pts)
mpl1 = st_multipolygon(list(pl1,pl1+20))

spl1 = st_as_sfc(list(pl1),crs=4326)
smpl1 = st_as_sfc(list(mpl1),crs=4326)

st_exterior_ring(spl1[[1]])
st_exterior_ring(spl1)
st_exterior_ring(st_sf(a = 1, geom = spl1))
st_exterior_ring(smpl1[[1]])
st_exterior_ring(st_sfc(smpl1))
st_exterior_ring(st_sf(a = 1, geom = st_sfc(smpl1)))
52 changes: 49 additions & 3 deletions tests/sfc.Rout.save
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

R version 4.3.3 (2024-02-29) -- "Angel Food Cake"
R version 4.4.0 (2024-04-24) -- "Puppy Cup"
Copyright (C) 2024 The R Foundation for Statistical Computing
Platform: x86_64-pc-linux-gnu (64-bit)
Platform: x86_64-pc-linux-gnu

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Expand Down Expand Up @@ -1086,6 +1086,52 @@ CRS: NA
x
1 POINT (0 1)
>
> # st_exterior_ring():
> outer = matrix(c(0,0,10,0,10,10,0,10,0,0),ncol=2, byrow=TRUE)
> hole1 = matrix(c(1,1,1,2,2,2,2,1,1,1),ncol=2, byrow=TRUE)
> hole2 = matrix(c(5,5,5,6,6,6,6,5,5,5),ncol=2, byrow=TRUE)
> pts = list(outer, hole1, hole2)
> pl1 = st_polygon(pts)
> mpl1 = st_multipolygon(list(pl1,pl1+20))
>
> spl1 = st_as_sfc(list(pl1),crs=4326)
> smpl1 = st_as_sfc(list(mpl1),crs=4326)
>
> st_exterior_ring(spl1[[1]])
POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))
> st_exterior_ring(spl1)
Geometry set for 1 feature
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 0 ymin: 0 xmax: 10 ymax: 10
Geodetic CRS: WGS 84
POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0))
> st_exterior_ring(st_sf(a = 1, geom = spl1))
Simple feature collection with 1 feature and 1 field
Geometry type: POLYGON
Dimension: XY
Bounding box: xmin: 0 ymin: 0 xmax: 10 ymax: 10
Geodetic CRS: WGS 84
a geom
1 1 POLYGON ((0 0, 10 0, 10 10,...
> st_exterior_ring(smpl1[[1]])
MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0)), ((20 20, 30 20, 30 30, 20 30, 20 20)))
> st_exterior_ring(st_sfc(smpl1))
Geometry set for 1 feature
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 0 ymin: 0 xmax: 30 ymax: 30
Geodetic CRS: WGS 84
MULTIPOLYGON (((0 0, 10 0, 10 10, 0 10, 0 0)), ...
> st_exterior_ring(st_sf(a = 1, geom = st_sfc(smpl1)))
Simple feature collection with 1 feature and 1 field
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: 0 ymin: 0 xmax: 30 ymax: 30
Geodetic CRS: WGS 84
a geom
1 1 MULTIPOLYGON (((0 0, 10 0, ...
>
> proc.time()
user system elapsed
5.156 1.454 5.144
5.477 1.381 5.407

0 comments on commit 5cdd168

Please sign in to comment.