r-spatial / sf

Simple Features for R
https://r-spatial.github.io/sf/
Other
1.33k stars 294 forks source link

st_exteriorring function for sf package? #2406

Closed dmkaplan2000 closed 3 months ago

dmkaplan2000 commented 3 months ago

Hi,

I noticed that the sf package does not have a st_exteriorring function as found in postgis, and googling didn't find a standard solution in sf under some other name, so I decided to create a function and wondered if it would be useful to add to sf. The code is:

st_exteriorring = function(geom) {
  require(sf)
  if (inherits(geom,"sf"))
    st_exteriorring(st_geometry(geom))

  if (inherits(geom,"sfc")) {
    g2 = lapply(geom,st_exteriorring)
    g2 = g2 |> st_as_sfc(g2) |> st_set_crs(st_crs(geom))
    return(g2)
  }

  if (inherits(geom,"MULTIPOLYGON")) {
    geom = st_cast(st_as_sfc(list(geom)),"POLYGON",warn=FALSE)
    g2 = lapply(geom,st_exteriorring)
    g2 = g2 |> st_multipolygon()
    return(g2)
  }

  if (inherits(geom,"POLYGON")) {
    return(st_polygon(geom[1]))
  }

  stop("Bad object type. Expected polygon or multipolygon, but got: ",class(geom)[1])
}

An example usage would be:

library(sf)
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)

plot(spl1)
plot(st_exteriorring(spl1))

plot(mpl1)
plot(st_exteriorring(smpl1))

Cheers, David